diff --git a/modules/coreboot b/modules/coreboot index 7081fe086..bbb663a84 100644 --- a/modules/coreboot +++ b/modules/coreboot @@ -2,12 +2,12 @@ modules-$(CONFIG_COREBOOT) += coreboot #coreboot_version := git #coreboot_repo := https://github.com/osresearch/coreboot -coreboot_version := 4.8.1 +coreboot_version := 4.9 coreboot_base_dir := coreboot-$(coreboot_version) coreboot_dir := $(coreboot_base_dir)/$(BOARD) coreboot_tar := coreboot-$(coreboot_version).tar.xz coreboot_url := https://www.coreboot.org/releases/$(coreboot_tar) -coreboot_hash := f0ddf4db0628c1fe1e8348c40084d9cbeb5771400c963fd419cda3995b69ad23 +coreboot_hash := 32368d8b3d87a79376e30efd4ed279e90ace9a3d752ea6f98e2efdd18a896a76 # Coreboot builds are specialized on a per-target basis. # The builds are done in a per-target subdirectory @@ -90,7 +90,7 @@ coreboot-blobs_version := $(coreboot_version) coreboot-blobs_tar := coreboot-blobs-$(coreboot-blobs_version).tar.xz coreboot-blobs_dir := coreboot-$(coreboot-blobs_version)/3rdparty/blobs coreboot-blobs_url := https://www.coreboot.org/releases/$(coreboot-blobs_tar) -coreboot-blobs_hash := 18aa509ae3af005a05d7b1e0b0246dc640249c14fc828f5144b6fd20bb10e295 +coreboot-blobs_hash := 2224bceca072abb362627e617a8c9b557385b2b275199f28f0a18ab261d4cb5d ## there is nothing to build for the blobs, this should be ## made easier to make happen diff --git a/patches/coreboot-4.8.1/0007-intel-fsp-fsp2_0-Fix-FSP-2.0-headers-to-match-github.patch b/patches/coreboot-4.8.1/0007-intel-fsp-fsp2_0-Fix-FSP-2.0-headers-to-match-github.patch deleted file mode 100644 index 0a5cda8cf..000000000 --- a/patches/coreboot-4.8.1/0007-intel-fsp-fsp2_0-Fix-FSP-2.0-headers-to-match-github.patch +++ /dev/null @@ -1,43 +0,0 @@ -From 8e7e0e390fcfda226f0d78bfa883ffee12f751a8 Mon Sep 17 00:00:00 2001 -From: Youness Alaoui -Date: Fri, 9 Feb 2018 18:32:51 -0500 -Subject: [PATCH 7/9] intel/fsp/fsp2_0: Fix FSP 2.0 headers to match github - version - -The current FSP 2.0 headers do not match the headers from the official -FSP 2.0 image that was released on github [1]. - -[1] https://github.com/IntelFsp/FSP/tree/Kabylake/KabylakeFspBinPkg - -Change-Id: I233bf7cf6f62e9e1b389d42a09461717a3285f0f -Signed-off-by: Youness Alaoui ---- - src/vendorcode/intel/fsp/fsp2_0/skykabylake/MemInfoHob.h | 5 +---- - 1 file changed, 1 insertion(+), 4 deletions(-) - -diff --git a/src/vendorcode/intel/fsp/fsp2_0/skykabylake/MemInfoHob.h b/src/vendorcode/intel/fsp/fsp2_0/skykabylake/MemInfoHob.h -index 248b4d5ef1..3abc877a19 100644 ---- a/src/vendorcode/intel/fsp/fsp2_0/skykabylake/MemInfoHob.h -+++ b/src/vendorcode/intel/fsp/fsp2_0/skykabylake/MemInfoHob.h -@@ -207,10 +207,6 @@ typedef struct { - UINT8 RevisionId; ///< The PCI revision id of this memory controller. - UINT8 ChannelCount; ///< Number of valid channels that exist on the controller. - CHANNEL_INFO ChannelInfo[MAX_CH]; ///< The following are channel level definitions. -- MRC_TA_TIMING tRd2Rd; ///< Read-to-Read Turn Around Timings -- MRC_TA_TIMING tRd2Wr; ///< Read-to-Write Turn Around Timings -- MRC_TA_TIMING tWr2Rd; ///< Write-to-Read Turn Around Timings -- MRC_TA_TIMING tWr2Wr; ///< Write-to-Write Turn Around Timings - } CONTROLLER_INFO; - - typedef struct { -@@ -228,6 +224,7 @@ typedef struct { - UINT8 ErrorCorrectionType; - - SiMrcVersion Version; -+ UINT32 FreqMax; - BOOLEAN EccSupport; - UINT8 MemoryProfile; - UINT32 TotalPhysicalMemorySize; --- -2.14.3 - diff --git a/patches/coreboot-4.8.1/0009-Add-heads-TPM-measurements-to-Skylake-Kabylake.patch b/patches/coreboot-4.8.1/0009-Add-heads-TPM-measurements-to-Skylake-Kabylake.patch deleted file mode 100644 index 9b3898e72..000000000 --- a/patches/coreboot-4.8.1/0009-Add-heads-TPM-measurements-to-Skylake-Kabylake.patch +++ /dev/null @@ -1,132 +0,0 @@ -diff --git ./src/arch/x86/postcar.c ./src/arch/x86/postcar.c -index 6497b73..485b051 100644 ---- ./src/arch/x86/postcar.c -+++ ./src/arch/x86/postcar.c -@@ -19,6 +19,7 @@ - #include - #include - #include -+#include - #include - - /* -@@ -43,3 +44,11 @@ void main(void) - /* Load and run ramstage. */ - run_ramstage(); - } -+ -+void platform_segment_loaded(uintptr_t start, size_t size, int flags) -+{ -+ if (IS_ENABLED(CONFIG_MEASURED_BOOT) && !(flags & SEG_NO_MEASURE)) { -+ tlcl_measure(2, (const void*) start, size); -+ } -+} -+ -diff --git ./src/drivers/intel/fsp2_0/memory_init.c ./src/drivers/intel/fsp2_0/memory_init.c -index 30987ce..4957bc0 100644 ---- ./src/drivers/intel/fsp2_0/memory_init.c -+++ ./src/drivers/intel/fsp2_0/memory_init.c -@@ -150,10 +150,11 @@ static void do_fsp_post_memory_init(bool s3wake, uint32_t fsp_version) - - /* - * Initialize the TPM, unless the TPM was already initialized -- * in verstage and used to verify romstage. -+ * in verstage and used to verify romstage, or for measured boot. - */ - if (IS_ENABLED(CONFIG_LPC_TPM) && -- !IS_ENABLED(CONFIG_VBOOT_STARTS_IN_BOOTBLOCK)) -+ !IS_ENABLED(CONFIG_VBOOT_STARTS_IN_BOOTBLOCK) && -+ !IS_ENABLED(CONFIG_MEASURED_BOOT)) - init_tpm(s3wake); - } - -@@ -483,8 +484,29 @@ void fsp_memory_init(bool s3wake) - if (status != CB_SUCCESS) - die("Loading FSPM failed!\n"); - -+ if (IS_ENABLED(CONFIG_MEASURED_BOOT) && IS_ENABLED(CONFIG_LPC_TPM)) { -+ // we don't know if we are coming out of a resume -+ // at this point, but want to setup the tpm ASAP -+ init_tpm(0); -+ tlcl_lib_init(); -+ const void * const bootblock = (const void*) 0xFFFFF800; -+ const unsigned bootblock_size = 0x800; -+ tlcl_measure(0, bootblock, bootblock_size); -+ -+ tlcl_measure(1, _romstage, _eromstage - _romstage); -+ } -+ - /* Signal that FSP component has been loaded. */ -+ // Don't measure since it is relocated at this point - prog_segment_loaded(hdr.image_base, hdr.image_size, SEG_FINAL); - - do_fsp_memory_init(&hdr, s3wake, &memmap); - } -+ -+void platform_segment_loaded(uintptr_t start, size_t size, int flags) -+{ -+ if (IS_ENABLED(CONFIG_MEASURED_BOOT) && !(flags & SEG_NO_MEASURE)) { -+ tlcl_measure(1, (const void*) start, size); -+ } -+} -+ -diff --git ./src/drivers/intel/fsp2_0/silicon_init.c ./src/drivers/intel/fsp2_0/silicon_init.c -index bda88d1..49568f6 100644 ---- ./src/drivers/intel/fsp2_0/silicon_init.c -+++ ./src/drivers/intel/fsp2_0/silicon_init.c -@@ -18,6 +18,7 @@ - #include - #include - #include -+#include - #include - #include - #include -@@ -101,6 +102,10 @@ void fsps_load(bool s3wake) - if (rdev_readat(&rdev, dest, 0, size) < 0) - die("Failed to read FSPS!\n"); - -+ if (IS_ENABLED(CONFIG_MEASURED_BOOT)) { -+ tlcl_measure(1, (const void*) dest, size); -+ } -+ - if (fsp_component_relocate((uintptr_t)dest, dest, size) < 0) - die("Unable to relocate FSPS!\n"); - -@@ -115,7 +120,7 @@ void fsps_load(bool s3wake) - stage_cache_add(STAGE_REFCODE, &fsps); - - /* Signal that FSP component has been loaded. */ -- prog_segment_loaded(hdr->image_base, hdr->image_size, SEG_FINAL); -+ prog_segment_loaded(hdr->image_base, hdr->image_size, SEG_FINAL | SEG_NO_MEASURE); - load_done = 1; - } - -diff --git ./src/drivers/pc80/tpm/Makefile.inc ./src/drivers/pc80/tpm/Makefile.inc -index 9d428b5..1d2364f 100644 ---- ./src/drivers/pc80/tpm/Makefile.inc -+++ ./src/drivers/pc80/tpm/Makefile.inc -@@ -3,6 +3,7 @@ ifeq ($(CONFIG_ARCH_X86),y) - verstage-$(CONFIG_LPC_TPM) += tis.c - romstage-$(CONFIG_LPC_TPM) += tis.c - ramstage-$(CONFIG_LPC_TPM) += tis.c -+postcar-$(CONFIG_LPC_TPM) += tis.c - romstage-$(CONFIG_LPC_TPM) += romstage.c - - endif -diff --git ./src/security/tpm/Makefile.inc ./src/security/tpm/Makefile.inc -index 2385635..7ef24cc 100644 ---- ./src/security/tpm/Makefile.inc -+++ ./src/security/tpm/Makefile.inc -@@ -4,6 +4,11 @@ verstage-$(CONFIG_TPM) += tss/tcg-1.2/tss.c - verstage-$(CONFIG_TPM2) += tss/tcg-2.0/tss_marshaling.c - verstage-$(CONFIG_TPM2) += tss/tcg-2.0/tss.c - -+ifeq ($(CONFIG_MEASURED_BOOT),y) -+postcar-$(CONFIG_TPM) += tss/tcg-1.2/tss.c -+postcar-$(CONFIG_TPM) += sha1.c -+endif # CONFIG_MEASURED_BOOT -+ - ifeq ($(CONFIG_VBOOT_SEPARATE_VERSTAGE),y) - romstage-$(CONFIG_TPM) += tss/tcg-1.2/tss.c - romstage-$(CONFIG_TPM2) += tss/tcg-2.0/tss_marshaling.c diff --git a/patches/coreboot-4.8.1/0020-kgpe-d16.patch b/patches/coreboot-4.8.1/0020-kgpe-d16.patch deleted file mode 100644 index 5c719b0db..000000000 --- a/patches/coreboot-4.8.1/0020-kgpe-d16.patch +++ /dev/null @@ -1,152 +0,0 @@ -diff --git ./src/mainboard/asus/kgpe-d16/Kconfig ./src/mainboard/asus/kgpe-d16/Kconfig -index 531ba4f..5227d28 100644 ---- ./src/mainboard/asus/kgpe-d16/Kconfig -+++ ./src/mainboard/asus/kgpe-d16/Kconfig -@@ -28,6 +28,7 @@ config BOARD_SPECIFIC_OPTIONS # dummy - select BOARD_ROMSIZE_KB_2048 - select ENABLE_APIC_EXT_ID - select SPI_FLASH -+ select TPM2 - select MAINBOARD_HAS_LPC_TPM - select HAVE_ACPI_RESUME - select DRIVERS_I2C_W83795 -diff --git ./src/mainboard/asus/kgpe-d16/devicetree.cb ./src/mainboard/asus/kgpe-d16/devicetree.cb -index 9039f6d..0ea4216 100644 ---- ./src/mainboard/asus/kgpe-d16/devicetree.cb -+++ ./src/mainboard/asus/kgpe-d16/devicetree.cb -@@ -217,6 +217,9 @@ chip northbridge/amd/amdfam10/root_complex # Root complex - chip drivers/pc80/tpm - device pnp 4e.0 on end # TPM module - end -+ chip drivers/generic/generic # BMC KCS -+ device pnp ca2.0 on end -+ end - end - device pci 14.4 on # Bridge - device pci 1.0 on end # VGA -diff --git ./src/mainboard/asus/kgpe-d16/dsdt.asl ./src/mainboard/asus/kgpe-d16/dsdt.asl -index 6a25b4d..cfcbc98 100644 ---- ./src/mainboard/asus/kgpe-d16/dsdt.asl -+++ ./src/mainboard/asus/kgpe-d16/dsdt.asl -@@ -50,6 +50,9 @@ DefinitionBlock ( - /* HPET enable */ - Name (HPTE, 0x1) - -+ /* IPMI KCS enable */ -+ Name (KCSE, 0x1) -+ - #include - - /* The _PIC method is called by the OS to choose between interrupt -@@ -485,6 +488,13 @@ DefinitionBlock ( - Name (_HID, EisaId ("PNP0A05")) - Name (_ADR, 0x00140003) - -+ OperationRegion(BMRG, SystemIO, 0xca2, 0x02) /* BMC KCS registers */ -+ Field(BMRG, AnyAcc, NoLock, Preserve) -+ { -+ BMRI, 8, /* Index */ -+ BMRD, 8, /* Data */ -+ } -+ - /* Real Time Clock Device */ - Device(RTC0) { - Name(_HID, EISAID("PNP0B00")) /* AT Real Time Clock (not PIIX4 compatible) */ -@@ -606,6 +616,27 @@ DefinitionBlock ( - }) - } - } -+ -+ Device(KCS1) { /* IPMI KCS */ -+ Name(_HID,EISAID("IPI0001")) /* ASpeed BMC */ -+ Method (_STA, 0, NotSerialized) { -+ If(KCSE) { /* Detection enabled */ -+ If(LNotEqual(BMRD, 0xff)) { -+ Return(0x0f) /* Device present */ -+ } -+ Return(Zero) -+ } -+ Return(Zero) -+ } -+ Method(_CRS, 0) { -+ Return(ResourceTemplate() { -+ IO(Decode16, 0x0ca2, 0x0ca2, 0x01, 0x02) -+ }) -+ } -+ Method (_IFT, 0, NotSerialized) { /* Interface type */ -+ Return(One) /* KCS interface */ -+ } -+ } - } - - /* High Precision Event Timer */ -diff --git ./src/mainboard/asus/kgpe-d16/mainboard.c ./src/mainboard/asus/kgpe-d16/mainboard.c -index 65029d4..8ee3a5e 100644 ---- ./src/mainboard/asus/kgpe-d16/mainboard.c -+++ ./src/mainboard/asus/kgpe-d16/mainboard.c -@@ -70,6 +70,13 @@ static void mainboard_enable(device_t dev) - - set_pcie_dereset(); - /* get_ide_dma66(); */ -+ -+ /* Enable access to the BMC IPMI via KCS */ -+ device_t lpc_sio_dev = dev_find_slot_pnp(0xca2, 0); -+ struct resource *res = new_resource(lpc_sio_dev, 0xca2); -+ res->base = 0xca2; -+ res->size = 1; -+ res->flags = IORESOURCE_IO | IORESOURCE_ASSIGNED | IORESOURCE_FIXED; - } - - /* override the default SATA PHY setup */ -diff --git ./src/mainboard/asus/kgpe-d16/romstage.c ./src/mainboard/asus/kgpe-d16/romstage.c -index 63b93c1..bb4f181 100644 ---- ./src/mainboard/asus/kgpe-d16/romstage.c -+++ ./src/mainboard/asus/kgpe-d16/romstage.c -@@ -88,6 +88,47 @@ static void switch_spd_mux(uint8_t channel) - byte &= ~0xc0; /* Enable SPD mux GPIO output drivers */ - byte |= (channel << 2) & 0xc; /* Set SPD mux GPIOs */ - pci_write_config8(PCI_DEV(0, 0x14, 0), 0x54, byte); -+ -+ /* Temporary AST PCI mapping */ -+ uint32_t base_memory = 0xfc000000; -+ uint32_t memory_limit = 0xfc800000; -+ -+ /* Temporarily enable the SP5100 PCI bridge */ -+ uint16_t prev_sec_cfg = pci_read_config16(PCI_DEV(0, 0x14, 4), 0x04); -+ uint8_t prev_sec_bus = pci_read_config8(PCI_DEV(0, 0x14, 4), 0x19); -+ uint8_t prev_sec_sub_bus = pci_read_config8(PCI_DEV(0, 0x14, 4), 0x1a); -+ uint16_t prev_sec_mem_base = pci_read_config16(PCI_DEV(0, 0x14, 4), 0x20); -+ uint16_t prev_sec_mem_limit = pci_read_config16(PCI_DEV(0, 0x14, 4), 0x22); -+ pci_write_config8(PCI_DEV(0, 0x14, 4), 0x19, 0x01); -+ pci_write_config8(PCI_DEV(0, 0x14, 4), 0x1a, 0xff); -+ pci_write_config16(PCI_DEV(0, 0x14, 4), 0x20, (base_memory >> 20)); -+ pci_write_config16(PCI_DEV(0, 0x14, 4), 0x22, (memory_limit >> 20)); -+ pci_write_config16(PCI_DEV(0, 0x14, 4), 0x04, 0x2); -+ -+ /* Temporarily enable AST BAR1 */ -+ uint32_t prev_ast_cfg = pci_read_config32(PCI_DEV(1, 0x1, 0), 0x04); -+ uint32_t prev_ast_bar1 = pci_read_config32(PCI_DEV(1, 0x1, 0), 0x14); -+ pci_write_config32(PCI_DEV(1, 0x1, 0), 0x14, base_memory); -+ pci_write_config32(PCI_DEV(1, 0x1, 0), 0x04, 0x02100002); -+ -+ /* Use the P2A bridge to set ASpeed SPD mux GPIOs to the same values as the SP5100 */ -+ void* ast_bar1 = (void*)base_memory; -+ write32(ast_bar1 + 0xf004, 0x1e780000); /* Enable access to GPIO controller */ -+ write32(ast_bar1 + 0xf000, 0x1); -+ write32(ast_bar1 + 0x10024, read32(ast_bar1 + 0x10024) | 0x3000); /* Enable SPD mux GPIO output drivers */ -+ write32(ast_bar1 + 0x10020, (read32(ast_bar1 + 0x10020) & ~0x3000) | ((channel & 0x3) << 12)); /* Set SPD mux GPIOs */ -+ write32(ast_bar1 + 0xf000, 0x0); -+ -+ /* Deconfigure AST BAR1 */ -+ pci_write_config32(PCI_DEV(1, 0x1, 0), 0x04, prev_ast_cfg); -+ pci_write_config32(PCI_DEV(1, 0x1, 0), 0x14, prev_ast_bar1); -+ -+ /* Deconfigure SP5100 PCI bridge */ -+ pci_write_config16(PCI_DEV(0, 0x14, 4), 0x04, prev_sec_cfg); -+ pci_write_config16(PCI_DEV(0, 0x14, 4), 0x22, prev_sec_mem_limit); -+ pci_write_config16(PCI_DEV(0, 0x14, 4), 0x20, prev_sec_mem_base); -+ pci_write_config8(PCI_DEV(0, 0x14, 4), 0x1a, prev_sec_sub_bus); -+ pci_write_config8(PCI_DEV(0, 0x14, 4), 0x19, prev_sec_bus); - } - - static const uint8_t spd_addr_fam15[] = { diff --git a/patches/coreboot-4.8.1/0050-buildgcc-Do-not-try-to-install-GCC-if-build-failed.patch b/patches/coreboot-4.8.1/0050-buildgcc-Do-not-try-to-install-GCC-if-build-failed.patch deleted file mode 100644 index 52ee66c6a..000000000 --- a/patches/coreboot-4.8.1/0050-buildgcc-Do-not-try-to-install-GCC-if-build-failed.patch +++ /dev/null @@ -1,44 +0,0 @@ -From 659f40bb348dd2ca02f9483ed2668465177b6a40 Mon Sep 17 00:00:00 2001 -From: Nico Huber -Date: Wed, 23 May 2018 17:06:53 +0200 -Subject: [PATCH 50/59] buildgcc: Do not try to install GCC if build failed - -We didn't bail out if configuring or building of GCC failed but run -`make install` and later steps instead. This resulted in very confusing -logs that concealed the actual error. - -Change-Id: Ia064e0bfd96f0cbad391da3bb19e4dc304d988ff -Signed-off-by: Nico Huber -Reviewed-on: https://review.coreboot.org/26496 -Reviewed-by: Martin Roth -Reviewed-by: Patrick Georgi -Reviewed-by: Paul Menzel -Tested-by: build bot (Jenkins) ---- - util/crossgcc/buildgcc | 8 ++++---- - 1 file changed, 4 insertions(+), 4 deletions(-) - -diff --git a/util/crossgcc/buildgcc b/util/crossgcc/buildgcc -index edcea7ab42..53f9782cb5 100755 ---- a/util/crossgcc/buildgcc -+++ b/util/crossgcc/buildgcc -@@ -751,12 +751,12 @@ build_cross_GCC() { - --with-gmp=$DESTDIR$TARGETDIR --with-mpfr=$DESTDIR$TARGETDIR \ - --with-mpc=$DESTDIR$TARGETDIR \ - --with-pkgversion="coreboot toolchain v$CROSSGCC_VERSION $CROSSGCC_DATE" \ -- || touch .failed -- $MAKE $JOBS CFLAGS_FOR_BUILD="$HOSTCFLAGS" all-gcc || touch .failed -+ && \ -+ $MAKE $JOBS CFLAGS_FOR_BUILD="$HOSTCFLAGS" all-gcc && \ - $MAKE install-gcc DESTDIR=$DESTDIR || touch .failed - -- if [ "$(echo $TARGETARCH | grep -c -- -mingw32)" -eq 0 ]; then -- $MAKE $JOBS CFLAGS_FOR_BUILD="$HOSTCFLAGS" all-target-libgcc || touch .failed -+ if [ ! -f .failed -a "$(echo $TARGETARCH | grep -c -- -mingw32)" -eq 0 ]; then -+ $MAKE $JOBS CFLAGS_FOR_BUILD="$HOSTCFLAGS" all-target-libgcc && \ - $MAKE install-target-libgcc DESTDIR=$DESTDIR || touch .failed - fi - } --- -2.17.1 - diff --git a/patches/coreboot-4.8.1/0051-buildgcc-Update-IASL-to-20180531.patch b/patches/coreboot-4.8.1/0051-buildgcc-Update-IASL-to-20180531.patch deleted file mode 100644 index 729e35490..000000000 --- a/patches/coreboot-4.8.1/0051-buildgcc-Update-IASL-to-20180531.patch +++ /dev/null @@ -1,130 +0,0 @@ -From 46fb8b6f051b1844ef92098119e4ffa12395e26a Mon Sep 17 00:00:00 2001 -From: Iru Cai -Date: Fri, 28 Jul 2017 23:36:25 +0800 -Subject: [PATCH 51/59] buildgcc: Update IASL to 20180531 - -Change-Id: I6c14f3aad59749896816bb8789788fc513e7176f -Signed-off-by: Iru Cai -Signed-off-by: Martin Roth -Reviewed-on: https://review.coreboot.org/21156 -Tested-by: build bot (Jenkins) -Reviewed-by: Nico Huber ---- - util/crossgcc/buildgcc | 6 ++--- - .../patches/acpica-unix2-20161222_iasl.patch | 27 ------------------- - .../patches/acpica-unix2-20180531_iasl.patch | 27 +++++++++++++++++++ - .../sum/acpica-unix2-20161222.tar.gz.cksum | 1 - - .../sum/acpica-unix2-20180531.tar.gz.cksum | 1 + - 5 files changed, 31 insertions(+), 31 deletions(-) - delete mode 100644 util/crossgcc/patches/acpica-unix2-20161222_iasl.patch - create mode 100644 util/crossgcc/patches/acpica-unix2-20180531_iasl.patch - delete mode 100644 util/crossgcc/sum/acpica-unix2-20161222.tar.gz.cksum - create mode 100644 util/crossgcc/sum/acpica-unix2-20180531.tar.gz.cksum - -diff --git a/util/crossgcc/buildgcc b/util/crossgcc/buildgcc -index 53f9782cb5..bbe74eb2b8 100755 ---- a/util/crossgcc/buildgcc -+++ b/util/crossgcc/buildgcc -@@ -18,8 +18,8 @@ - - cd $(dirname $0) - --CROSSGCC_DATE="October 15th, 2017" --CROSSGCC_VERSION="1.50" -+CROSSGCC_DATE="June 3rd, 2018" -+CROSSGCC_VERSION="1.51" - CROSSGCC_COMMIT=$( git describe ) - - # default settings -@@ -42,7 +42,7 @@ GCC_VERSION=6.3.0 - GCC_AUTOCONF_VERSION=2.69 - BINUTILS_VERSION=2.29.1 - GDB_VERSION=8.0 --IASL_VERSION=20161222 -+IASL_VERSION=20180531 - PYTHON_VERSION=3.5.1 - EXPAT_VERSION=2.2.1 - # CLANG version number -diff --git a/util/crossgcc/patches/acpica-unix2-20161222_iasl.patch b/util/crossgcc/patches/acpica-unix2-20161222_iasl.patch -deleted file mode 100644 -index 24bde98a32..0000000000 ---- a/util/crossgcc/patches/acpica-unix2-20161222_iasl.patch -+++ /dev/null -@@ -1,27 +0,0 @@ --diff -Naur acpica-unix2-20161222/source/compiler/asloptions.c acpica-unix2-20161222/source/compiler/asloptions.c ----- acpica-unix2-20161222/source/compiler/asloptions.c --+++ acpica-unix2-20161222/source/compiler/asloptions.c --@@ -100,6 +100,7 @@ -- if (argc < 2) -- { -- printf (ACPI_COMMON_SIGNON (ASL_COMPILER_NAME)); --+ printf ("%s\n", COREBOOT_TOOLCHAIN_VERSION); -- Usage (); -- exit (1); -- } --@@ -130,6 +131,7 @@ -- if (Gbl_DoSignon) -- { -- printf (ACPI_COMMON_SIGNON (ASL_COMPILER_NAME)); --+ printf ("%s\n", COREBOOT_TOOLCHAIN_VERSION); -- if (Gbl_IgnoreErrors) -- { -- printf ("Ignoring all errors, forcing AML file generation\n\n"); --@@ -711,6 +713,7 @@ -- case '^': -- -- printf (ACPI_COMMON_SIGNON (ASL_COMPILER_NAME)); --+ printf ("%s\n", COREBOOT_TOOLCHAIN_VERSION); -- exit (0); -- -- case 'a': -diff --git a/util/crossgcc/patches/acpica-unix2-20180531_iasl.patch b/util/crossgcc/patches/acpica-unix2-20180531_iasl.patch -new file mode 100644 -index 0000000000..fea5cd3c47 ---- /dev/null -+++ b/util/crossgcc/patches/acpica-unix2-20180531_iasl.patch -@@ -0,0 +1,27 @@ -+diff -Naur acpica-unix2-20180531_/source/compiler/asloptions.c acpica-unix2-20180531/source/compiler/asloptions.c > acpica-unix2-20180531_iasl.patch -+--- acpica-unix2-20180531_/source/compiler/asloptions.c -++++ acpica-unix2-20180531/source/compiler/asloptions.c -+@@ -126,6 +126,7 @@ -+ if (Gbl_DoSignon) -+ { -+ printf (ACPI_COMMON_SIGNON (ASL_COMPILER_NAME)); -++ printf ("%s\n", COREBOOT_TOOLCHAIN_VERSION); -+ if (Gbl_IgnoreErrors) -+ { -+ printf ("Ignoring all errors, forcing AML file generation\n\n"); -+@@ -753,6 +754,7 @@ -+ case '^': -+ -+ printf (ACPI_COMMON_SIGNON (ASL_COMPILER_NAME)); -++ printf ("%s\n", COREBOOT_TOOLCHAIN_VERSION); -+ exit (0); -+ -+ case 'a': -+@@ -766,6 +768,7 @@ -+ -+ printf (ACPI_COMMON_SIGNON (ASL_COMPILER_NAME)); -+ printf (ACPI_COMMON_BUILD_TIME); -++ printf ("%s\n", COREBOOT_TOOLCHAIN_VERSION); -+ exit (0); -+ -+ case 'e': -diff --git a/util/crossgcc/sum/acpica-unix2-20161222.tar.gz.cksum b/util/crossgcc/sum/acpica-unix2-20161222.tar.gz.cksum -deleted file mode 100644 -index d857678871..0000000000 ---- a/util/crossgcc/sum/acpica-unix2-20161222.tar.gz.cksum -+++ /dev/null -@@ -1 +0,0 @@ --73e57d4d558c9bc831165c71adbff577b526f256 tarballs/acpica-unix2-20161222.tar.gz -diff --git a/util/crossgcc/sum/acpica-unix2-20180531.tar.gz.cksum b/util/crossgcc/sum/acpica-unix2-20180531.tar.gz.cksum -new file mode 100644 -index 0000000000..700185839a ---- /dev/null -+++ b/util/crossgcc/sum/acpica-unix2-20180531.tar.gz.cksum -@@ -0,0 +1 @@ -+17717140438d506533b4a56e34350749d7b84d6c tarballs/acpica-unix2-20180531.tar.gz --- -2.17.1 - diff --git a/patches/coreboot-4.8.1/0052-crossgcc-Update-to-clang-6.0-cmake-3.11.3.patch b/patches/coreboot-4.8.1/0052-crossgcc-Update-to-clang-6.0-cmake-3.11.3.patch deleted file mode 100644 index 1b2296222..000000000 --- a/patches/coreboot-4.8.1/0052-crossgcc-Update-to-clang-6.0-cmake-3.11.3.patch +++ /dev/null @@ -1,132 +0,0 @@ -From 575f1d7784041461d02c892b4846165dd742654c Mon Sep 17 00:00:00 2001 -From: Martin Roth -Date: Tue, 5 Jun 2018 20:56:29 -0600 -Subject: [PATCH 52/59] crossgcc: Update to clang 6.0 & cmake 3.11.3 - -Change-Id: I1a0db60b527c2f7ffe77743c0d75b78a7c8bc4cc -Signed-off-by: Martin Roth -Reviewed-on: https://review.coreboot.org/26877 -Reviewed-by: Patrick Georgi -Tested-by: build bot (Jenkins) ---- - util/crossgcc/buildgcc | 6 +++--- - util/crossgcc/sum/cfe-4.0.0.src.tar.xz.cksum | 1 - - util/crossgcc/sum/cfe-6.0.0.src.tar.xz.cksum | 1 + - util/crossgcc/sum/clang-tools-extra-4.0.0.src.tar.xz.cksum | 1 - - util/crossgcc/sum/clang-tools-extra-6.0.0.src.tar.xz.cksum | 1 + - util/crossgcc/sum/cmake-3.11.3.tar.gz.cksum | 1 + - util/crossgcc/sum/cmake-3.9.0-rc3.tar.gz.cksum | 1 - - util/crossgcc/sum/compiler-rt-4.0.0.src.tar.xz.cksum | 1 - - util/crossgcc/sum/compiler-rt-6.0.0.src.tar.xz.cksum | 1 + - util/crossgcc/sum/llvm-4.0.0.src.tar.xz.cksum | 1 - - util/crossgcc/sum/llvm-6.0.0.src.tar.xz.cksum | 1 + - 11 files changed, 8 insertions(+), 8 deletions(-) - delete mode 100644 util/crossgcc/sum/cfe-4.0.0.src.tar.xz.cksum - create mode 100644 util/crossgcc/sum/cfe-6.0.0.src.tar.xz.cksum - delete mode 100644 util/crossgcc/sum/clang-tools-extra-4.0.0.src.tar.xz.cksum - create mode 100644 util/crossgcc/sum/clang-tools-extra-6.0.0.src.tar.xz.cksum - create mode 100644 util/crossgcc/sum/cmake-3.11.3.tar.gz.cksum - delete mode 100644 util/crossgcc/sum/cmake-3.9.0-rc3.tar.gz.cksum - delete mode 100644 util/crossgcc/sum/compiler-rt-4.0.0.src.tar.xz.cksum - create mode 100644 util/crossgcc/sum/compiler-rt-6.0.0.src.tar.xz.cksum - delete mode 100644 util/crossgcc/sum/llvm-4.0.0.src.tar.xz.cksum - create mode 100644 util/crossgcc/sum/llvm-6.0.0.src.tar.xz.cksum - -diff --git a/util/crossgcc/buildgcc b/util/crossgcc/buildgcc -index bbe74eb2b8..addc61f186 100755 ---- a/util/crossgcc/buildgcc -+++ b/util/crossgcc/buildgcc -@@ -46,9 +46,9 @@ IASL_VERSION=20180531 - PYTHON_VERSION=3.5.1 - EXPAT_VERSION=2.2.1 - # CLANG version number --CLANG_VERSION=4.0.0 -+CLANG_VERSION=6.0.0 - MAKE_VERSION=4.2.1 --CMAKE_VERSION=3.9.0-rc3 -+CMAKE_VERSION=3.11.3 - - # GCC toolchain archive locations - # These are sanitized by the jenkins toolchain test builder, so if -@@ -69,7 +69,7 @@ CFE_ARCHIVE="https://releases.llvm.org/${CLANG_VERSION}/cfe-${CLANG_VERSION}.src - CRT_ARCHIVE="https://releases.llvm.org/${CLANG_VERSION}/compiler-rt-${CLANG_VERSION}.src.tar.xz" - CTE_ARCHIVE="https://releases.llvm.org/${CLANG_VERSION}/clang-tools-extra-${CLANG_VERSION}.src.tar.xz" - MAKE_ARCHIVE="https://ftpmirror.gnu.org/make/make-${MAKE_VERSION}.tar.bz2" --CMAKE_ARCHIVE="https://cmake.org/files/v3.9/cmake-${CMAKE_VERSION}.tar.gz" -+CMAKE_ARCHIVE="https://cmake.org/files/v3.11/cmake-${CMAKE_VERSION}.tar.gz" - - ALL_ARCHIVES="$GMP_ARCHIVE $MPFR_ARCHIVE $MPC_ARCHIVE \ - $GCC_ARCHIVE $BINUTILS_ARCHIVE $GDB_ARCHIVE $IASL_ARCHIVE \ -diff --git a/util/crossgcc/sum/cfe-4.0.0.src.tar.xz.cksum b/util/crossgcc/sum/cfe-4.0.0.src.tar.xz.cksum -deleted file mode 100644 -index 00a5596878..0000000000 ---- a/util/crossgcc/sum/cfe-4.0.0.src.tar.xz.cksum -+++ /dev/null -@@ -1 +0,0 @@ --e2762800c93d9335781ea6a45af3f80845542ef5 tarballs/cfe-4.0.0.src.tar.xz -diff --git a/util/crossgcc/sum/cfe-6.0.0.src.tar.xz.cksum b/util/crossgcc/sum/cfe-6.0.0.src.tar.xz.cksum -new file mode 100644 -index 0000000000..523445035f ---- /dev/null -+++ b/util/crossgcc/sum/cfe-6.0.0.src.tar.xz.cksum -@@ -0,0 +1 @@ -+4cc7bef72fda70ac5e065ca0ae2d66957abe6f2a tarballs/cfe-6.0.0.src.tar.xz -diff --git a/util/crossgcc/sum/clang-tools-extra-4.0.0.src.tar.xz.cksum b/util/crossgcc/sum/clang-tools-extra-4.0.0.src.tar.xz.cksum -deleted file mode 100644 -index dbf642c461..0000000000 ---- a/util/crossgcc/sum/clang-tools-extra-4.0.0.src.tar.xz.cksum -+++ /dev/null -@@ -1 +0,0 @@ --bdb543c4bb87bd80fe65711114ca0a5c25329ae3 tarballs/clang-tools-extra-4.0.0.src.tar.xz -diff --git a/util/crossgcc/sum/clang-tools-extra-6.0.0.src.tar.xz.cksum b/util/crossgcc/sum/clang-tools-extra-6.0.0.src.tar.xz.cksum -new file mode 100644 -index 0000000000..9fcb8280d1 ---- /dev/null -+++ b/util/crossgcc/sum/clang-tools-extra-6.0.0.src.tar.xz.cksum -@@ -0,0 +1 @@ -+c960a0d565e46e4c4f6976fac389f753076ca72e tarballs/clang-tools-extra-6.0.0.src.tar.xz -diff --git a/util/crossgcc/sum/cmake-3.11.3.tar.gz.cksum b/util/crossgcc/sum/cmake-3.11.3.tar.gz.cksum -new file mode 100644 -index 0000000000..14a4b22c8d ---- /dev/null -+++ b/util/crossgcc/sum/cmake-3.11.3.tar.gz.cksum -@@ -0,0 +1 @@ -+73261a5b7f71abf7277c1d2a418ca3c4cf170c89 tarballs/cmake-3.11.3.tar.gz -diff --git a/util/crossgcc/sum/cmake-3.9.0-rc3.tar.gz.cksum b/util/crossgcc/sum/cmake-3.9.0-rc3.tar.gz.cksum -deleted file mode 100644 -index 809ce3c7ca..0000000000 ---- a/util/crossgcc/sum/cmake-3.9.0-rc3.tar.gz.cksum -+++ /dev/null -@@ -1 +0,0 @@ --d568e74e2e4a1cdeae1820cc2cb36fd2d6afc8fe tarballs/cmake-3.9.0-rc3.tar.gz -diff --git a/util/crossgcc/sum/compiler-rt-4.0.0.src.tar.xz.cksum b/util/crossgcc/sum/compiler-rt-4.0.0.src.tar.xz.cksum -deleted file mode 100644 -index 95da5148ed..0000000000 ---- a/util/crossgcc/sum/compiler-rt-4.0.0.src.tar.xz.cksum -+++ /dev/null -@@ -1 +0,0 @@ --a879b610e427ef3bba482bdc031ae371cabab81e tarballs/compiler-rt-4.0.0.src.tar.xz -diff --git a/util/crossgcc/sum/compiler-rt-6.0.0.src.tar.xz.cksum b/util/crossgcc/sum/compiler-rt-6.0.0.src.tar.xz.cksum -new file mode 100644 -index 0000000000..88186dbf38 ---- /dev/null -+++ b/util/crossgcc/sum/compiler-rt-6.0.0.src.tar.xz.cksum -@@ -0,0 +1 @@ -+5725f19be611034e77196461cdb4989f4258cfa4 tarballs/compiler-rt-6.0.0.src.tar.xz -diff --git a/util/crossgcc/sum/llvm-4.0.0.src.tar.xz.cksum b/util/crossgcc/sum/llvm-4.0.0.src.tar.xz.cksum -deleted file mode 100644 -index 410f95fb1a..0000000000 ---- a/util/crossgcc/sum/llvm-4.0.0.src.tar.xz.cksum -+++ /dev/null -@@ -1 +0,0 @@ --aee4524e2407f9fe5afc6f70c753180b907011d0 tarballs/llvm-4.0.0.src.tar.xz -diff --git a/util/crossgcc/sum/llvm-6.0.0.src.tar.xz.cksum b/util/crossgcc/sum/llvm-6.0.0.src.tar.xz.cksum -new file mode 100644 -index 0000000000..ac079eccf5 ---- /dev/null -+++ b/util/crossgcc/sum/llvm-6.0.0.src.tar.xz.cksum -@@ -0,0 +1 @@ -+f61e0a35feb76644ba160a413ee209dd24c88f47 tarballs/llvm-6.0.0.src.tar.xz --- -2.17.1 - diff --git a/patches/coreboot-4.8.1/0053-src-Get-rid-of-unneeded-whitespace.patch b/patches/coreboot-4.8.1/0053-src-Get-rid-of-unneeded-whitespace.patch deleted file mode 100644 index 97ee389bf..000000000 --- a/patches/coreboot-4.8.1/0053-src-Get-rid-of-unneeded-whitespace.patch +++ /dev/null @@ -1,55 +0,0 @@ -From b0f1988f893bf5f581917816b11e810309955143 Mon Sep 17 00:00:00 2001 -From: Elyes HAOUAS -Date: Sat, 9 Jun 2018 11:59:00 +0200 -Subject: [PATCH 53/59] src: Get rid of unneeded whitespace - -Change-Id: I630d49ab504d9f6e052806b516a600fa41b9a8da -Signed-off-by: Elyes HAOUAS -Reviewed-on: https://review.coreboot.org/26991 -Tested-by: build bot (Jenkins) -Reviewed-by: Patrick Georgi ---- - util/crossgcc/buildgcc | 8 ++++---- - 1 file changed, 4 insertions(+), 4 deletions(-) - -diff --git a/util/crossgcc/buildgcc b/util/crossgcc/buildgcc -index addc61f186..cd8a091989 100755 ---- a/util/crossgcc/buildgcc -+++ b/util/crossgcc/buildgcc -@@ -1191,7 +1191,7 @@ export PATH=$DESTDIR$TARGETDIR/bin:$PATH - - # Download, unpack, patch and build all packages - --printf "Downloading and verifing tarballs ... \n" -+printf "Downloading and verifing tarballs ...\n" - mkdir -p tarballs - for P in $PACKAGES; do - download "$P" || exit "$?" -@@ -1199,21 +1199,21 @@ for P in $PACKAGES; do - done - printf "Downloaded tarballs ... ${green}ok${NC}\n" - --printf "Unpacking and patching ... \n" -+printf "Unpacking and patching ...\n" - for P in $PACKAGES; do - unpack_and_patch $P || exit 1 - done - printf "Unpacked and patched ... ${green}ok${NC}\n" - - if [ -n "$BOOTSTRAPONLY" ]; then -- printf "Building bootstrap compiler only ... \n" -+ printf "Building bootstrap compiler only ...\n" - for pkg in GMP MPFR MPC GCC; do - build_for_host $pkg - done - exit 0 - fi - --printf "Building packages ... \n" -+printf "Building packages ...\n" - for package in $PACKAGES; do - build $package - done --- -2.17.1 - diff --git a/patches/coreboot-4.8.1/0054-util-crossgcc-Allow-building-a-new-gcc-against-new-b.patch b/patches/coreboot-4.8.1/0054-util-crossgcc-Allow-building-a-new-gcc-against-new-b.patch deleted file mode 100644 index 8d46818c1..000000000 --- a/patches/coreboot-4.8.1/0054-util-crossgcc-Allow-building-a-new-gcc-against-new-b.patch +++ /dev/null @@ -1,54 +0,0 @@ -From 095db339f7463b09b52968fa3747aef329c7b83e Mon Sep 17 00:00:00 2001 -From: Patrick Georgi -Date: Tue, 26 Jun 2018 21:00:58 +0200 -Subject: [PATCH 54/59] util/crossgcc: Allow building a new gcc against new - binutils with -D - -With -D, the newly built toolchain isn't installed into $prefix/... -but into $DESTDIR/$prefix/... while being built for $prefix alone. - -This is useful for distributions, but it breaks down when the build -host already has the toolchain installed in $prefix without proper -build isolation (cf. gentoo): - -In such cases libgcc etc are built using the new compiler (as gcc's -build system is smart enough to state the path explicitly), but that -compiler then uses its regular algorithm to determine the path to as, -ld, ... -That makes it use the tools from $prefix, which might differ in formats -(assembly, certain object file flags, ...): nds32le-elf in particular -has rather unstable formats still, and so new compilers can't work -with old binutils. - -The approach to deal with this is to take an unused path that's -specified by gcc's build system ($out/gcc/$arch/$version) and symlink -it to the new toolchain - these explicitly given directories take -precedence over the default search path, and so the new binutils -are used. - -Change-Id: Ia9a262e73f56cd486a2ae07422b598c205a03aed -Signed-off-by: Patrick Georgi -Reviewed-on: https://review.coreboot.org/27241 -Reviewed-by: Martin Roth -Reviewed-by: Stefan Reinauer -Tested-by: build bot (Jenkins) ---- - util/crossgcc/buildgcc | 2 ++ - 1 file changed, 2 insertions(+) - -diff --git a/util/crossgcc/buildgcc b/util/crossgcc/buildgcc -index cd8a091989..ef0c4d5d8f 100755 ---- a/util/crossgcc/buildgcc -+++ b/util/crossgcc/buildgcc -@@ -752,6 +752,8 @@ build_cross_GCC() { - --with-mpc=$DESTDIR$TARGETDIR \ - --with-pkgversion="coreboot toolchain v$CROSSGCC_VERSION $CROSSGCC_DATE" \ - && \ -+ mkdir -p gcc/$TARGETARCH && \ -+ ln -s $DESTDIR$TARGETDIR/$TARGETARCH/bin gcc/$TARGETARCH/$GCC_VERSION && \ - $MAKE $JOBS CFLAGS_FOR_BUILD="$HOSTCFLAGS" all-gcc && \ - $MAKE install-gcc DESTDIR=$DESTDIR || touch .failed - --- -2.17.1 - diff --git a/patches/coreboot-4.8.1/0055-crosgcc-patches-Add-make-patch-for-GLIBC-glob-interf.patch b/patches/coreboot-4.8.1/0055-crosgcc-patches-Add-make-patch-for-GLIBC-glob-interf.patch deleted file mode 100644 index 8a0635f92..000000000 --- a/patches/coreboot-4.8.1/0055-crosgcc-patches-Add-make-patch-for-GLIBC-glob-interf.patch +++ /dev/null @@ -1,46 +0,0 @@ -From 11f8c9d9be8eb492d00b8d7a29614fdc0553387e Mon Sep 17 00:00:00 2001 -From: Martin Roth -Date: Wed, 6 Jun 2018 22:36:14 -0600 -Subject: [PATCH 55/59] crosgcc/patches: Add make patch for GLIBC glob - interface v2 - -Copied from the GNU make repository -author Paul Smith -commit 48c8a116 -configure.ac: Support GLIBC glob interface version 2 - -Change-Id: Id70a2b98dad6349ee56985d8dd6d4f0d87b470e6 -Signed-off-by: Martin Roth -Reviewed-on: https://review.coreboot.org/26939 -Tested-by: build bot (Jenkins) -Reviewed-by: Paul Menzel -Reviewed-by: Patrick Georgi ---- - .../make-4.2.1_gnu_glob_interface_v2.patch | 15 +++++++++++++++ - 1 file changed, 15 insertions(+) - create mode 100644 util/crossgcc/patches/make-4.2.1_gnu_glob_interface_v2.patch - -diff --git a/util/crossgcc/patches/make-4.2.1_gnu_glob_interface_v2.patch b/util/crossgcc/patches/make-4.2.1_gnu_glob_interface_v2.patch -new file mode 100644 -index 0000000000..466d6fdd70 ---- /dev/null -+++ b/util/crossgcc/patches/make-4.2.1_gnu_glob_interface_v2.patch -@@ -0,0 +1,15 @@ -+diff -Naur make-4.2.1/configure.ac make-4.2.1/configure.ac -+--- make-4.2.1/configure.ac -++++ make-4.2.1/configure.ac -+@@ -399,10 +399,9 @@ -+ #include -+ #include -+ -+-#define GLOB_INTERFACE_VERSION 1 -+ #if !defined _LIBC && defined __GNU_LIBRARY__ && __GNU_LIBRARY__ > 1 -+ # include -+-# if _GNU_GLOB_INTERFACE_VERSION == GLOB_INTERFACE_VERSION -++# if _GNU_GLOB_INTERFACE_VERSION == 1 || _GNU_GLOB_INTERFACE_VERSION == 2 -+ gnu glob -+ # endif -+ #endif], --- -2.17.1 - diff --git a/patches/coreboot-4.8.1/0056-util-crossgcc-update-to-gcc-8.1.0-and-binutils-2.30.patch b/patches/coreboot-4.8.1/0056-util-crossgcc-update-to-gcc-8.1.0-and-binutils-2.30.patch deleted file mode 100644 index 81ab35f47..000000000 --- a/patches/coreboot-4.8.1/0056-util-crossgcc-update-to-gcc-8.1.0-and-binutils-2.30.patch +++ /dev/null @@ -1,131728 +0,0 @@ -From b1d26f0e9261ec4070e8561406853fe5bddeb27c Mon Sep 17 00:00:00 2001 -From: Patrick Georgi -Date: Wed, 2 May 2018 17:13:34 +0200 -Subject: [PATCH 56/59] util/crossgcc: update to gcc 8.1.0 and binutils 2.30 - -Also update patches as necessary. - -Change-Id: I1e8074954d5d7a4eff590abb7439e9be7d3762aa -Signed-off-by: Patrick Georgi -Reviewed-on: https://review.coreboot.org/25997 -Reviewed-by: Nico Huber -Tested-by: build bot (Jenkins) ---- - util/crossgcc/buildgcc | 10 +- - ...ld.patch => binutils-2.30_mips-gold.patch} | 0 - .../patches/binutils-2.30_nds32.patch | 25740 ++++++ - ...c.patch => binutils-2.30_no-bfd-doc.patch} | 0 - .../patches/gcc-6.3.0_ada-raise.patch | 11 - - .../patches/gcc-6.3.0_elf_biarch.patch | 87 - - .../crossgcc/patches/gcc-6.3.0_memmodel.patch | 416 - - .../patches/gcc-6.3.0_nds32_ite.patch | 73397 ---------------- - .../crossgcc/patches/gcc-6.3.0_no-p-var.patch | 15 - - .../patches/gcc-6.3.0_pointer_integer.patch | 27 - - util/crossgcc/patches/gcc-6.3.0_riscv.patch | 10521 --- - ...ch => gcc-8.1.0_ada-musl_workaround.patch} | 24 +- - .../crossgcc/patches/gcc-8.1.0_armv6s-m.patch | 64 + - ...-6.3.0_gnat.patch => gcc-8.1.0_gnat.patch} | 2 +- - ....0_libgcc.patch => gcc-8.1.0_libgcc.patch} | 5 +- - .../patches/gcc-8.1.0_nds32_ite.patch | 21164 +++++ - .../crossgcc/sum/binutils-2.29.1.tar.xz.cksum | 1 - - util/crossgcc/sum/binutils-2.30.tar.xz.cksum | 1 + - util/crossgcc/sum/gcc-6.3.0.tar.bz2.cksum | 1 - - util/crossgcc/sum/gcc-8.1.0.tar.xz.cksum | 1 + - 20 files changed, 46993 insertions(+), 84494 deletions(-) - rename util/crossgcc/patches/{binutils-2.29.1_mips-gold.patch => binutils-2.30_mips-gold.patch} (100%) - create mode 100644 util/crossgcc/patches/binutils-2.30_nds32.patch - rename util/crossgcc/patches/{binutils-2.29.1_no-bfd-doc.patch => binutils-2.30_no-bfd-doc.patch} (100%) - delete mode 100644 util/crossgcc/patches/gcc-6.3.0_ada-raise.patch - delete mode 100644 util/crossgcc/patches/gcc-6.3.0_elf_biarch.patch - delete mode 100644 util/crossgcc/patches/gcc-6.3.0_memmodel.patch - delete mode 100644 util/crossgcc/patches/gcc-6.3.0_nds32_ite.patch - delete mode 100644 util/crossgcc/patches/gcc-6.3.0_no-p-var.patch - delete mode 100644 util/crossgcc/patches/gcc-6.3.0_pointer_integer.patch - delete mode 100644 util/crossgcc/patches/gcc-6.3.0_riscv.patch - rename util/crossgcc/patches/{gcc-6.3.0_ada-musl_workaround.patch => gcc-8.1.0_ada-musl_workaround.patch} (79%) - create mode 100644 util/crossgcc/patches/gcc-8.1.0_armv6s-m.patch - rename util/crossgcc/patches/{gcc-6.3.0_gnat.patch => gcc-8.1.0_gnat.patch} (89%) - rename util/crossgcc/patches/{gcc-6.3.0_libgcc.patch => gcc-8.1.0_libgcc.patch} (92%) - create mode 100644 util/crossgcc/patches/gcc-8.1.0_nds32_ite.patch - delete mode 100644 util/crossgcc/sum/binutils-2.29.1.tar.xz.cksum - create mode 100644 util/crossgcc/sum/binutils-2.30.tar.xz.cksum - delete mode 100644 util/crossgcc/sum/gcc-6.3.0.tar.bz2.cksum - create mode 100644 util/crossgcc/sum/gcc-8.1.0.tar.xz.cksum - -diff --git a/util/crossgcc/buildgcc b/util/crossgcc/buildgcc -index ef0c4d5d8f..a9d90572cd 100755 ---- a/util/crossgcc/buildgcc -+++ b/util/crossgcc/buildgcc -@@ -18,8 +18,8 @@ - - cd $(dirname $0) - --CROSSGCC_DATE="June 3rd, 2018" --CROSSGCC_VERSION="1.51" -+CROSSGCC_DATE="June 11th, 2018" -+CROSSGCC_VERSION="1.52" - CROSSGCC_COMMIT=$( git describe ) - - # default settings -@@ -38,9 +38,9 @@ THREADS=1 - GMP_VERSION=6.1.2 - MPFR_VERSION=3.1.5 - MPC_VERSION=1.0.3 --GCC_VERSION=6.3.0 -+GCC_VERSION=8.1.0 - GCC_AUTOCONF_VERSION=2.69 --BINUTILS_VERSION=2.29.1 -+BINUTILS_VERSION=2.30 - GDB_VERSION=8.0 - IASL_VERSION=20180531 - PYTHON_VERSION=3.5.1 -@@ -57,7 +57,7 @@ CMAKE_VERSION=3.11.3 - GMP_ARCHIVE="https://ftpmirror.gnu.org/gmp/gmp-${GMP_VERSION}.tar.xz" - MPFR_ARCHIVE="https://ftpmirror.gnu.org/mpfr/mpfr-${MPFR_VERSION}.tar.xz" - MPC_ARCHIVE="https://ftpmirror.gnu.org/mpc/mpc-${MPC_VERSION}.tar.gz" --GCC_ARCHIVE="https://ftpmirror.gnu.org/gcc/gcc-${GCC_VERSION}/gcc-${GCC_VERSION}.tar.bz2" -+GCC_ARCHIVE="https://ftpmirror.gnu.org/gcc/gcc-${GCC_VERSION}/gcc-${GCC_VERSION}.tar.xz" - BINUTILS_ARCHIVE="https://ftpmirror.gnu.org/binutils/binutils-${BINUTILS_VERSION}.tar.xz" - GDB_ARCHIVE="https://ftpmirror.gnu.org/gdb/gdb-${GDB_VERSION}.tar.xz" - IASL_ARCHIVE="https://acpica.org/sites/acpica/files/acpica-unix2-${IASL_VERSION}.tar.gz" -diff --git a/util/crossgcc/patches/binutils-2.29.1_mips-gold.patch b/util/crossgcc/patches/binutils-2.30_mips-gold.patch -similarity index 100% -rename from util/crossgcc/patches/binutils-2.29.1_mips-gold.patch -rename to util/crossgcc/patches/binutils-2.30_mips-gold.patch -diff --git a/util/crossgcc/patches/binutils-2.30_nds32.patch b/util/crossgcc/patches/binutils-2.30_nds32.patch -new file mode 100644 -index 0000000000..9608265ad2 ---- /dev/null -+++ b/util/crossgcc/patches/binutils-2.30_nds32.patch -@@ -0,0 +1,25740 @@ -+diff --git binutils-2.30/bfd/bfd-in2.h binutils-2.30-nds32/bfd/bfd-in2.h -+index f4b3720b4b..49ac0a3a18 100644 -+--- binutils-2.30/bfd/bfd-in2.h -++++ binutils-2.30-nds32/bfd/bfd-in2.h -+@@ -4137,6 +4137,9 @@ and shift left by 1 for use in lhi.gp, shi.gp... */ -+ and shift left by 0 for use in lbi.gp, sbi.gp... */ -+ BFD_RELOC_NDS32_SDA19S0, -+ -++/* This is a 24-bit reloc for security check sum. */ -++ BFD_RELOC_NDS32_SECURITY_16, -++ -+ /* for PIC */ -+ BFD_RELOC_NDS32_GOT20, -+ BFD_RELOC_NDS32_9_PLTREL, -+@@ -4248,18 +4251,43 @@ This is a 5 bit absolute address. */ -+ -+ /* For TLS. */ -+ BFD_RELOC_NDS32_TPOFF, -++ BFD_RELOC_NDS32_GOTTPOFF, -+ BFD_RELOC_NDS32_TLS_LE_HI20, -+ BFD_RELOC_NDS32_TLS_LE_LO12, -+- BFD_RELOC_NDS32_TLS_LE_ADD, -+- BFD_RELOC_NDS32_TLS_LE_LS, -+- BFD_RELOC_NDS32_GOTTPOFF, -+- BFD_RELOC_NDS32_TLS_IE_HI20, -+- BFD_RELOC_NDS32_TLS_IE_LO12S2, -+- BFD_RELOC_NDS32_TLS_TPOFF, -+ BFD_RELOC_NDS32_TLS_LE_20, -+ BFD_RELOC_NDS32_TLS_LE_15S0, -+ BFD_RELOC_NDS32_TLS_LE_15S1, -+ BFD_RELOC_NDS32_TLS_LE_15S2, -++ BFD_RELOC_NDS32_TLS_LE_ADD, -++ BFD_RELOC_NDS32_TLS_LE_LS, -++ BFD_RELOC_NDS32_TLS_IE_HI20, -++ BFD_RELOC_NDS32_TLS_IE_LO12, -++ BFD_RELOC_NDS32_TLS_IE_LO12S2, -++ BFD_RELOC_NDS32_TLS_IEGP_HI20, -++ BFD_RELOC_NDS32_TLS_IEGP_LO12, -++ BFD_RELOC_NDS32_TLS_IEGP_LO12S2, -++ BFD_RELOC_NDS32_TLS_IEGP_LW, -++ BFD_RELOC_NDS32_TLS_DESC, -++ BFD_RELOC_NDS32_TLS_DESC_HI20, -++ BFD_RELOC_NDS32_TLS_DESC_LO12, -++ BFD_RELOC_NDS32_TLS_DESC_20, -++ BFD_RELOC_NDS32_TLS_DESC_SDA17S2, -++ BFD_RELOC_NDS32_TLS_DESC_ADD, -++ BFD_RELOC_NDS32_TLS_DESC_FUNC, -++ BFD_RELOC_NDS32_TLS_DESC_CALL, -++ BFD_RELOC_NDS32_TLS_DESC_MEM, -++ BFD_RELOC_NDS32_REMOVE, -++ BFD_RELOC_NDS32_GROUP, -++ -++/* Jump-patch table relative relocations. */ -++ BFD_RELOC_NDS32_ICT, -++ BFD_RELOC_NDS32_ICT_HI20, -++ BFD_RELOC_NDS32_ICT_LO12, -++ BFD_RELOC_NDS32_ICT_25PC, -++ BFD_RELOC_NDS32_ICT_LO12S2, -++ -++/* For bug 12566. */ -++ BFD_RELOC_NDS32_LSI, -+ -+ /* This is a 9-bit reloc */ -+ BFD_RELOC_V850_9_PCREL, -+diff --git binutils-2.30/bfd/config.bfd binutils-2.30-nds32/bfd/config.bfd -+index f04a993f06..9aa2fc63a8 100644 -+--- binutils-2.30/bfd/config.bfd -++++ binutils-2.30-nds32/bfd/config.bfd -+@@ -1260,11 +1260,13 @@ case "${targ}" in -+ nds32*le-*-linux*) -+ targ_defvec=nds32_elf32_linux_le_vec -+ targ_selvecs=nds32_elf32_linux_be_vec -++ targ_cflags=-DNDS32_LINUX_TOOLCHAIN -+ ;; -+ -+ nds32*be-*-linux*) -+ targ_defvec=nds32_elf32_linux_be_vec -+ targ_selvecs=nds32_elf32_linux_le_vec -++ targ_cflags=-DNDS32_LINUX_TOOLCHAIN -+ ;; -+ -+ nds32*le-*-*) -+diff --git binutils-2.30/bfd/elf32-nds32.c binutils-2.30-nds32/bfd/elf32-nds32.c -+index 5ceb0a0b26..06be7a24bd 100644 -+--- binutils-2.30/bfd/elf32-nds32.c -++++ binutils-2.30-nds32/bfd/elf32-nds32.c -+@@ -20,6 +20,8 @@ -+ 02110-1301, USA. */ -+ -+ -++#pragma GCC diagnostic ignored "-Wstack-usage=" -++ -+ #include "sysdep.h" -+ #include "bfd.h" -+ #include "bfd_stdint.h" -+@@ -33,6 +35,7 @@ -+ #include "elf32-nds32.h" -+ #include "opcode/cgen.h" -+ #include "../opcodes/nds32-opc.h" -++#include -+ -+ /* Relocation HOWTO functions. */ -+ static bfd_reloc_status_type nds32_elf_ignore_reloc -+@@ -56,36 +59,72 @@ static bfd_reloc_status_type nds32_elf_sda15_reloc -+ static bfd_reloc_status_type nds32_elf_do_9_pcrel_reloc -+ (bfd *, reloc_howto_type *, asection *, bfd_byte *, bfd_vma, -+ asection *, bfd_vma, bfd_vma); -++static void nds32_elf_relocate_hi20 -++ (bfd *, int, Elf_Internal_Rela *, Elf_Internal_Rela *, bfd_byte *, bfd_vma); -++static reloc_howto_type *bfd_elf32_bfd_reloc_type_table_lookup -++ (enum elf_nds32_reloc_type); -++static reloc_howto_type *bfd_elf32_bfd_reloc_type_lookup -++ (bfd *, bfd_reloc_code_real_type); -++ -++/* Target hooks. */ -++static void nds32_info_to_howto_rel -++ (bfd *, arelent *, Elf_Internal_Rela *); -++static void nds32_info_to_howto -++ (bfd *, arelent *, Elf_Internal_Rela *); -++static bfd_boolean nds32_elf_add_symbol_hook -++ (bfd *, struct bfd_link_info *, Elf_Internal_Sym *, const char **, -++ flagword *, asection **, bfd_vma *); -++static bfd_boolean nds32_elf_relocate_section -++ (bfd *, struct bfd_link_info *, bfd *, asection *, bfd_byte *, -++ Elf_Internal_Rela *, Elf_Internal_Sym *, asection **); -++static bfd_boolean nds32_elf_object_p (bfd *); -++static void nds32_elf_final_write_processing (bfd *, bfd_boolean); -++static bfd_boolean nds32_elf_set_private_flags (bfd *, flagword); -++static bfd_boolean nds32_elf_merge_private_bfd_data (bfd *, struct bfd_link_info *); -++static bfd_boolean nds32_elf_print_private_bfd_data (bfd *, void *); -++static bfd_boolean nds32_elf_check_relocs -++ (bfd *, struct bfd_link_info *, asection *, const Elf_Internal_Rela *); -++static asection *nds32_elf_gc_mark_hook -++ (asection *, struct bfd_link_info *, Elf_Internal_Rela *, -++ struct elf_link_hash_entry *, Elf_Internal_Sym *); -++static bfd_boolean nds32_elf_adjust_dynamic_symbol -++ (struct bfd_link_info *, struct elf_link_hash_entry *); -++static bfd_boolean nds32_elf_size_dynamic_sections -++ (bfd *, struct bfd_link_info *); -++static bfd_boolean nds32_elf_create_dynamic_sections -++ (bfd *, struct bfd_link_info *); -++static bfd_boolean nds32_elf_finish_dynamic_sections -++ (bfd *, struct bfd_link_info *info); -++static bfd_boolean nds32_elf_finish_dynamic_symbol -++ (bfd *, struct bfd_link_info *, struct elf_link_hash_entry *, -++ Elf_Internal_Sym *); -++static bfd_boolean nds32_elf_mkobject (bfd *); -+ -+ /* Nds32 helper functions. */ -++static bfd_reloc_status_type nds32_elf_final_sda_base -++ (bfd *, struct bfd_link_info *, bfd_vma *, bfd_boolean); -++static bfd_boolean allocate_dynrelocs (struct elf_link_hash_entry *, void *); -++static bfd_boolean readonly_dynrelocs (struct elf_link_hash_entry *, void *); -++static Elf_Internal_Rela *find_relocs_at_address -++ (Elf_Internal_Rela *, Elf_Internal_Rela *, -++ Elf_Internal_Rela *, enum elf_nds32_reloc_type); -+ static bfd_vma calculate_memory_address -+-(bfd *, Elf_Internal_Rela *, Elf_Internal_Sym *, Elf_Internal_Shdr *); -++ (bfd *, Elf_Internal_Rela *, Elf_Internal_Sym *, Elf_Internal_Shdr *); -+ static int nds32_get_section_contents (bfd *, asection *, -+ bfd_byte **, bfd_boolean); -+-static bfd_boolean nds32_elf_ex9_build_hash_table -+-(bfd *, asection *, struct bfd_link_info *); -+-static bfd_boolean nds32_elf_ex9_itb_base (struct bfd_link_info *); -+-static void nds32_elf_ex9_import_table (struct bfd_link_info *); -+-static void nds32_elf_ex9_finish (struct bfd_link_info *); -+-static void nds32_elf_ex9_reloc_jmp (struct bfd_link_info *); -+-static void nds32_elf_get_insn_with_reg -+- (Elf_Internal_Rela *, uint32_t, uint32_t *); -+ static int nds32_get_local_syms (bfd *, asection *ATTRIBUTE_UNUSED, -+ Elf_Internal_Sym **); -+-static bfd_boolean nds32_elf_ex9_replace_instruction -+- (struct bfd_link_info *, bfd *, asection *); -+-static bfd_boolean nds32_elf_ifc_calc (struct bfd_link_info *, bfd *, -+- asection *); -+-static bfd_boolean nds32_elf_ifc_finish (struct bfd_link_info *); -+-static bfd_boolean nds32_elf_ifc_replace (struct bfd_link_info *); -+-static bfd_boolean nds32_elf_ifc_reloc (void); -+-static bfd_boolean nds32_relax_fp_as_gp -+- (struct bfd_link_info *link_info, bfd *abfd, asection *sec, -+- Elf_Internal_Rela *internal_relocs, Elf_Internal_Rela *irelend, -+- Elf_Internal_Sym *isymbuf); -++static bfd_boolean nds32_relax_fp_as_gp -++ (struct bfd_link_info *, bfd *, asection *, Elf_Internal_Rela *, -++ Elf_Internal_Rela *, Elf_Internal_Sym *); -+ static bfd_boolean nds32_fag_remove_unused_fpbase -+- (bfd *abfd, asection *sec, Elf_Internal_Rela *internal_relocs, -+- Elf_Internal_Rela *irelend); -++ (bfd *, asection *, Elf_Internal_Rela *, Elf_Internal_Rela *); -++static bfd_byte *nds32_elf_get_relocated_section_contents -++ (bfd *, struct bfd_link_info *, struct bfd_link_order *, bfd_byte *, -++ bfd_boolean, asymbol **); -++static void nds32_elf_ict_hash_init (void); -++static void nds32_elf_ict_relocate (bfd *, struct bfd_link_info *); -++static asection* nds32_elf_get_target_section (struct bfd_link_info *, char *); -+ -+ enum -+ { -+@@ -95,13 +134,24 @@ enum -+ MACH_V3M = bfd_mach_n1h_v3m -+ }; -+ -++/* If ABI is set by the option --mabi, without -++ checking the ABI compatible. */ -++static char *output_abi; -++ -+ #define MIN(a, b) ((a) > (b) ? (b) : (a)) -+ #define MAX(a, b) ((a) > (b) ? (a) : (b)) -+ -++/* True if insn is 4byte. */ -++#define INSN_32BIT(insn) ((((insn) & 0x80000000) == 0 ? (TRUE) : (FALSE))) -++ -+ /* The name of the dynamic interpreter. This is put in the .interp -+ section. */ -+ #define ELF_DYNAMIC_INTERPRETER "/usr/lib/ld.so.1" -+ -++#define NDS32_GUARD_SEC_P(flags) ((flags) & SEC_ALLOC \ -++ && (flags) & SEC_LOAD \ -++ && (flags) & SEC_READONLY) -++ -+ /* The nop opcode we use. */ -+ #define NDS32_NOP32 0x40000009 -+ #define NDS32_NOP16 0x9200 -+@@ -113,32 +163,32 @@ enum -+ /* The first entry in a procedure linkage table are reserved, -+ and the initial contents are unimportant (we zero them out). -+ Subsequent entries look like this. */ -+-#define PLT0_ENTRY_WORD0 0x46f00000 /* sethi r15, HI20(.got+4) */ -+-#define PLT0_ENTRY_WORD1 0x58f78000 /* ori r15, r25, LO12(.got+4) */ -+-#define PLT0_ENTRY_WORD2 0x05178000 /* lwi r17, [r15+0] */ -+-#define PLT0_ENTRY_WORD3 0x04f78001 /* lwi r15, [r15+4] */ -+-#define PLT0_ENTRY_WORD4 0x4a003c00 /* jr r15 */ -++#define PLT0_ENTRY_WORD0 0x46f00000 /* sethi r15, HI20(.got+4) */ -++#define PLT0_ENTRY_WORD1 0x58f78000 /* ori r15, r25, LO12(.got+4) */ -++#define PLT0_ENTRY_WORD2 0x05178000 /* lwi r17, [r15+0] */ -++#define PLT0_ENTRY_WORD3 0x04f78001 /* lwi r15, [r15+4] */ -++#define PLT0_ENTRY_WORD4 0x4a003c00 /* jr r15 */ -+ -+ /* $ta is change to $r15 (from $r25). */ -+ #define PLT0_PIC_ENTRY_WORD0 0x46f00000 /* sethi r15, HI20(got[1]@GOT) */ -+-#define PLT0_PIC_ENTRY_WORD1 0x58f78000 /* ori r15, r15, LO12(got[1]@GOT) */ -+-#define PLT0_PIC_ENTRY_WORD2 0x40f7f400 /* add r15, gp, r15 */ -+-#define PLT0_PIC_ENTRY_WORD3 0x05178000 /* lwi r17, [r15+0] */ -+-#define PLT0_PIC_ENTRY_WORD4 0x04f78001 /* lwi r15, [r15+4] */ -+-#define PLT0_PIC_ENTRY_WORD5 0x4a003c00 /* jr r15 */ -+- -+-#define PLT_ENTRY_WORD0 0x46f00000 /* sethi r15, HI20(&got[n+3]) */ -+-#define PLT_ENTRY_WORD1 0x04f78000 /* lwi r15, r15, LO12(&got[n+3]) */ -+-#define PLT_ENTRY_WORD2 0x4a003c00 /* jr r15 */ -+-#define PLT_ENTRY_WORD3 0x45000000 /* movi r16, sizeof(RELA) * n */ -+-#define PLT_ENTRY_WORD4 0x48000000 /* j .plt0. */ -+- -+-#define PLT_PIC_ENTRY_WORD0 0x46f00000 /* sethi r15, HI20(got[n+3]@GOT) */ -+-#define PLT_PIC_ENTRY_WORD1 0x58f78000 /* ori r15, r15, LO12(got[n+3]@GOT) */ -+-#define PLT_PIC_ENTRY_WORD2 0x38febc02 /* lw r15, [gp+r15] */ -+-#define PLT_PIC_ENTRY_WORD3 0x4a003c00 /* jr r15 */ -+-#define PLT_PIC_ENTRY_WORD4 0x45000000 /* movi r16, sizeof(RELA) * n */ -+-#define PLT_PIC_ENTRY_WORD5 0x48000000 /* j .plt0 */ -++#define PLT0_PIC_ENTRY_WORD1 0x58f78000 /* ori r15, r15, LO12(got[1]@GOT) */ -++#define PLT0_PIC_ENTRY_WORD2 0x40f7f400 /* add r15, gp, r15 */ -++#define PLT0_PIC_ENTRY_WORD3 0x05178000 /* lwi r17, [r15+0] */ -++#define PLT0_PIC_ENTRY_WORD4 0x04f78001 /* lwi r15, [r15+4] */ -++#define PLT0_PIC_ENTRY_WORD5 0x4a003c00 /* jr r15 */ -++ -++#define PLT_ENTRY_WORD0 0x46f00000 /* sethi r15, HI20(&got[n+3]) */ -++#define PLT_ENTRY_WORD1 0x04f78000 /* lwi r15, r15, LO12(&got[n+3]) */ -++#define PLT_ENTRY_WORD2 0x4a003c00 /* jr r15 */ -++#define PLT_ENTRY_WORD3 0x45000000 /* movi r16, sizeof(RELA) * n */ -++#define PLT_ENTRY_WORD4 0x48000000 /* j .plt0 */ -++ -++#define PLT_PIC_ENTRY_WORD0 0x46f00000 /* sethi r15, HI20(got[n+3]@GOT) */ -++#define PLT_PIC_ENTRY_WORD1 0x58f78000 /* ori r15, r15, LO12(got[n+3]@GOT) */ -++#define PLT_PIC_ENTRY_WORD2 0x38febc02 /* lw r15, [gp+r15] */ -++#define PLT_PIC_ENTRY_WORD3 0x4a003c00 /* jr r15 */ -++#define PLT_PIC_ENTRY_WORD4 0x45000000 /* movi r16, sizeof(RELA) * n */ -++#define PLT_PIC_ENTRY_WORD5 0x48000000 /* j .plt0 */ -+ -+ /* These are macros used to get the relocation accurate value. */ -+ #define ACCURATE_8BIT_S1 (0x100) -+@@ -160,10 +210,11 @@ enum -+ #define CONSERVATIVE_19BIT (0x40000 - 0x1000) -+ #define CONSERVATIVE_20BIT (0x80000 - 0x1000) -+ -++#define NDS32_ICT_SECTION ".nds32.ict" -++ -+ /* Size of small data/bss sections, used to calculate SDA_BASE. */ -+ static long got_size = 0; -+ static int is_SDA_BASE_set = 0; -+-static int is_ITB_BASE_set = 0; -+ -+ /* Convert ELF-VER in eflags to string for debugging purpose. */ -+ static const char *const nds32_elfver_strtab[] = -+@@ -192,37 +243,108 @@ struct elf_nds32_pcrel_relocs_copied -+ bfd_size_type count; -+ }; -+ -++/* The sh linker needs to keep track of the number of relocs that it -++ decides to copy as dynamic relocs in check_relocs for each symbol. -++ This is so that it can later discard them if they are found to be -++ unnecessary. We store the information in a field extending the -++ regular ELF linker hash table. */ -++ -++struct elf_nds32_dyn_relocs -++{ -++ struct elf_nds32_dyn_relocs *next; -++ -++ /* The input section of the reloc. */ -++ asection *sec; -++ -++ /* Total number of relocs copied for the input section. */ -++ bfd_size_type count; -++ -++ /* Number of pc-relative relocs copied for the input section. */ -++ bfd_size_type pc_count; -++}; -++ -+ /* Nds32 ELF linker hash entry. */ -+ -++enum elf_nds32_tls_type -++{ -++ GOT_UNKNOWN = (0), -++ GOT_NORMAL = (1 << 0), -++ GOT_TLS_LE = (1 << 1), -++ GOT_TLS_IE = (1 << 2), -++ GOT_TLS_IEGP = (1 << 3), -++ GOT_TLS_LD = (1 << 4), -++ GOT_TLS_GD = (1 << 5), -++ GOT_TLS_DESC = (1 << 6), -++}; -++ -+ struct elf_nds32_link_hash_entry -+ { -+ struct elf_link_hash_entry root; -+ -+ /* Track dynamic relocs copied for this symbol. */ -+- struct elf_dyn_relocs *dyn_relocs; -++ struct elf_nds32_dyn_relocs *dyn_relocs; -+ -+ /* For checking relocation type. */ -+-#define GOT_UNKNOWN 0 -+-#define GOT_NORMAL 1 -+-#define GOT_TLS_IE 2 -+- unsigned int tls_type; -++ enum elf_nds32_tls_type tls_type; -++ -++ int offset_to_gp; -++ -++ /* For saving function attribute indirect_call and entry address. */ -++ bfd_boolean indirect_call; -+ }; -+ -+ /* Get the nds32 ELF linker hash table from a link_info structure. */ -+ -+ #define FP_BASE_NAME "_FP_BASE_" -+ static int check_start_export_sym = 0; -+-static size_t ex9_relax_size = 0; /* Save ex9 predicted reducing size. */ -++/* File for exporting indirect call table. */ -++static FILE *ict_file = NULL; -++/* Save object ict model. */ -++static unsigned int ict_model = 0; -++/* True if _INDIRECT_CALL_TABLE_BASE_ is defined. */ -++static bfd_boolean ignore_indirect_call = FALSE; -++/* Be used to set ifc bit in elf header. */ -++static bfd_boolean ifc_flag = FALSE; -++ -++/* Rom-patch symbol hash table. */ -++struct elf_nds32_ict_hash_entry -++{ -++ struct bfd_hash_entry root; -++ struct elf_link_hash_entry *h; -++ unsigned int order; -++}; -++ -++/* Rom-patch hash table. */ -++static struct bfd_hash_table indirect_call_table; -+ -+ /* The offset for executable tls relaxation. */ -+ #define TP_OFFSET 0x0 -+ -++typedef struct -++{ -++ int min_id; -++ int max_id; -++ int count; -++ int bias; -++ int init; -++} elf32_nds32_relax_group_t; -++ -+ struct elf_nds32_obj_tdata -+ { -+ struct elf_obj_tdata root; -+ -+ /* tls_type for each local got entry. */ -+ char *local_got_tls_type; -++ -++ unsigned int hdr_size; -++ -++ /* GOTPLT entries for TLS descriptors. */ -++ bfd_vma *local_tlsdesc_gotent; -++ -++ int* offset_to_gp; -++ -++ /* for R_NDS32_RELAX_GROUP handling. */ -++ elf32_nds32_relax_group_t relax_group; -+ }; -+ -+ #define elf_nds32_tdata(bfd) \ -+@@ -231,6 +353,12 @@ struct elf_nds32_obj_tdata -+ #define elf32_nds32_local_got_tls_type(bfd) \ -+ (elf_nds32_tdata (bfd)->local_got_tls_type) -+ -++#define elf32_nds32_local_gp_offset(bfd) \ -++ (elf_nds32_tdata (bfd)->offset_to_gp) -++ -++#define elf32_nds32_relax_group_ptr(bfd) \ -++ &(elf_nds32_tdata (bfd)->relax_group) -++ -+ #define elf32_nds32_hash_entry(ent) ((struct elf_nds32_link_hash_entry *)(ent)) -+ -+ static bfd_boolean -+@@ -240,68 +368,75 @@ nds32_elf_mkobject (bfd *abfd) -+ NDS32_ELF_DATA); -+ } -+ -++ -+ /* Relocations used for relocation. */ -+-static reloc_howto_type nds32_elf_howto_table[] = -+-{ -++/* NOTE! -++ the index order must be the same with elf_nds32_reloc_type in -++ include/elf/nds32.h -++ */ -++#define HOWTO2(C, R, S, B, P, BI, O, SF, NAME, INPLACE, MASKSRC, MASKDST, PC) \ -++ [C] = HOWTO(C, R, S, B, P, BI, O, SF, NAME, INPLACE, MASKSRC, MASKDST, PC) -++ -++static reloc_howto_type nds32_elf_howto_table[] = { -+ /* This reloc does nothing. */ -+- HOWTO (R_NDS32_NONE, /* type */ -+- 0, /* rightshift */ -+- 3, /* size (0 = byte, 1 = short, 2 = long) */ -+- 0, /* bitsize */ -+- FALSE, /* pc_relative */ -+- 0, /* bitpos */ -+- complain_overflow_dont, /* complain_on_overflow */ -+- bfd_elf_generic_reloc, /* special_function */ -+- "R_NDS32_NONE", /* name */ -+- FALSE, /* partial_inplace */ -+- 0, /* src_mask */ -+- 0, /* dst_mask */ -+- FALSE), /* pcrel_offset */ -++ HOWTO2 (R_NDS32_NONE, /* type */ -++ 0, /* rightshift */ -++ 2, /* size (0 = byte, 1 = short, 2 = long) */ -++ 32, /* bitsize */ -++ FALSE, /* pc_relative */ -++ 0, /* bitpos */ -++ complain_overflow_bitfield,/* complain_on_overflow */ -++ bfd_elf_generic_reloc, /* special_function */ -++ "R_NDS32_NONE", /* name */ -++ FALSE, /* partial_inplace */ -++ 0, /* src_mask */ -++ 0, /* dst_mask */ -++ FALSE), /* pcrel_offset */ -+ -+ /* A 16 bit absolute relocation. */ -+- HOWTO (R_NDS32_16, /* type */ -+- 0, /* rightshift */ -+- 1, /* size (0 = byte, 1 = short, 2 = long) */ -+- 16, /* bitsize */ -+- FALSE, /* pc_relative */ -+- 0, /* bitpos */ -+- complain_overflow_bitfield, /* complain_on_overflow */ -+- nds32_elf_generic_reloc, /* special_function */ -+- "R_NDS32_16", /* name */ -+- FALSE, /* partial_inplace */ -+- 0xffff, /* src_mask */ -+- 0xffff, /* dst_mask */ -+- FALSE), /* pcrel_offset */ -++ HOWTO2 (R_NDS32_16, /* type */ -++ 0, /* rightshift */ -++ 1, /* size (0 = byte, 1 = short, 2 = long) */ -++ 16, /* bitsize */ -++ FALSE, /* pc_relative */ -++ 0, /* bitpos */ -++ complain_overflow_bitfield,/* complain_on_overflow */ -++ nds32_elf_generic_reloc,/* special_function */ -++ "R_NDS32_16", /* name */ -++ FALSE, /* partial_inplace */ -++ 0xffff, /* src_mask */ -++ 0xffff, /* dst_mask */ -++ FALSE), /* pcrel_offset */ -+ -+ /* A 32 bit absolute relocation. */ -+- HOWTO (R_NDS32_32, /* type */ -+- 0, /* rightshift */ -+- 2, /* size (0 = byte, 1 = short, 2 = long) */ -+- 32, /* bitsize */ -+- FALSE, /* pc_relative */ -+- 0, /* bitpos */ -+- complain_overflow_bitfield, /* complain_on_overflow */ -+- nds32_elf_generic_reloc, /* special_function */ -+- "R_NDS32_32", /* name */ -+- FALSE, /* partial_inplace */ -+- 0xffffffff, /* src_mask */ -+- 0xffffffff, /* dst_mask */ -+- FALSE), /* pcrel_offset */ -++ HOWTO2 (R_NDS32_32, /* type */ -++ 0, /* rightshift */ -++ 2, /* size (0 = byte, 1 = short, 2 = long) */ -++ 32, /* bitsize */ -++ FALSE, /* pc_relative */ -++ 0, /* bitpos */ -++ complain_overflow_bitfield,/* complain_on_overflow */ -++ nds32_elf_generic_reloc,/* special_function */ -++ "R_NDS32_32", /* name */ -++ FALSE, /* partial_inplace */ -++ 0xffffffff, /* src_mask */ -++ 0xffffffff, /* dst_mask */ -++ FALSE), /* pcrel_offset */ -+ -+ /* A 20 bit address. */ -+- HOWTO (R_NDS32_20, /* type */ -+- 0, /* rightshift */ -+- 2, /* size (0 = byte, 1 = short, 2 = long) */ -+- 20, /* bitsize */ -+- FALSE, /* pc_relative */ -+- 0, /* bitpos */ -+- complain_overflow_unsigned, /* complain_on_overflow */ -+- nds32_elf_generic_reloc, /* special_function */ -+- "R_NDS32_20", /* name */ -+- FALSE, /* partial_inplace */ -+- 0xfffff, /* src_mask */ -+- 0xfffff, /* dst_mask */ -+- FALSE), /* pcrel_offset */ -++ HOWTO2 (R_NDS32_20, /* type */ -++ 0, /* rightshift */ -++ 2, /* size (0 = byte, 1 = short, 2 = long) */ -++ 20, /* bitsize */ -++ FALSE, /* pc_relative */ -++ 0, /* bitpos */ -++ complain_overflow_unsigned,/* complain_on_overflow */ -++ nds32_elf_generic_reloc,/* special_function */ -++ "R_NDS32_20", /* name */ -++ FALSE, /* partial_inplace */ -++ 0xfffff, /* src_mask */ -++ 0xfffff, /* dst_mask */ -++ FALSE), /* pcrel_offset */ -+ -+ /* An PC Relative 9-bit relocation, shifted by 2. -+ This reloc is complicated because relocations are relative to pc & -4. -+@@ -311,1910 +446,2264 @@ static reloc_howto_type nds32_elf_howto_table[] = -+ Branch relaxing in the assembler can store the addend in the insn, -+ and if bfd_install_relocation gets called the addend may get added -+ again. */ -+- HOWTO (R_NDS32_9_PCREL, /* type */ -+- 1, /* rightshift */ -+- 1, /* size (0 = byte, 1 = short, 2 = long) */ -+- 8, /* bitsize */ -+- TRUE, /* pc_relative */ -+- 0, /* bitpos */ -+- complain_overflow_signed, /* complain_on_overflow */ -+- nds32_elf_9_pcrel_reloc, /* special_function */ -+- "R_NDS32_9_PCREL", /* name */ -+- FALSE, /* partial_inplace */ -+- 0xff, /* src_mask */ -+- 0xff, /* dst_mask */ -+- TRUE), /* pcrel_offset */ -++ HOWTO2 (R_NDS32_9_PCREL, /* type */ -++ 1, /* rightshift */ -++ 1, /* size (0 = byte, 1 = short, 2 = long) */ -++ 8, /* bitsize */ -++ TRUE, /* pc_relative */ -++ 0, /* bitpos */ -++ complain_overflow_signed,/* complain_on_overflow */ -++ nds32_elf_9_pcrel_reloc,/* special_function */ -++ "R_NDS32_9_PCREL", /* name */ -++ FALSE, /* partial_inplace */ -++ 0xff, /* src_mask */ -++ 0xff, /* dst_mask */ -++ TRUE), /* pcrel_offset */ -+ -+ /* A relative 15 bit relocation, right shifted by 1. */ -+- HOWTO (R_NDS32_15_PCREL, /* type */ -+- 1, /* rightshift */ -+- 2, /* size (0 = byte, 1 = short, 2 = long) */ -+- 14, /* bitsize */ -+- TRUE, /* pc_relative */ -+- 0, /* bitpos */ -+- complain_overflow_signed, /* complain_on_overflow */ -+- bfd_elf_generic_reloc, /* special_function */ -+- "R_NDS32_15_PCREL", /* name */ -+- FALSE, /* partial_inplace */ -+- 0x3fff, /* src_mask */ -+- 0x3fff, /* dst_mask */ -+- TRUE), /* pcrel_offset */ -++ HOWTO2 (R_NDS32_15_PCREL, /* type */ -++ 1, /* rightshift */ -++ 2, /* size (0 = byte, 1 = short, 2 = long) */ -++ 14, /* bitsize */ -++ TRUE, /* pc_relative */ -++ 0, /* bitpos */ -++ complain_overflow_signed,/* complain_on_overflow */ -++ bfd_elf_generic_reloc, /* special_function */ -++ "R_NDS32_15_PCREL", /* name */ -++ FALSE, /* partial_inplace */ -++ 0x3fff, /* src_mask */ -++ 0x3fff, /* dst_mask */ -++ TRUE), /* pcrel_offset */ -+ -+ /* A relative 17 bit relocation, right shifted by 1. */ -+- HOWTO (R_NDS32_17_PCREL, /* type */ -+- 1, /* rightshift */ -+- 2, /* size (0 = byte, 1 = short, 2 = long) */ -+- 16, /* bitsize */ -+- TRUE, /* pc_relative */ -+- 0, /* bitpos */ -+- complain_overflow_signed, /* complain_on_overflow */ -+- bfd_elf_generic_reloc, /* special_function */ -+- "R_NDS32_17_PCREL", /* name */ -+- FALSE, /* partial_inplace */ -+- 0xffff, /* src_mask */ -+- 0xffff, /* dst_mask */ -+- TRUE), /* pcrel_offset */ -++ HOWTO2 (R_NDS32_17_PCREL, /* type */ -++ 1, /* rightshift */ -++ 2, /* size (0 = byte, 1 = short, 2 = long) */ -++ 16, /* bitsize */ -++ TRUE, /* pc_relative */ -++ 0, /* bitpos */ -++ complain_overflow_signed,/* complain_on_overflow */ -++ bfd_elf_generic_reloc, /* special_function */ -++ "R_NDS32_17_PCREL", /* name */ -++ FALSE, /* partial_inplace */ -++ 0xffff, /* src_mask */ -++ 0xffff, /* dst_mask */ -++ TRUE), /* pcrel_offset */ -+ -+ /* A relative 25 bit relocation, right shifted by 1. */ -+ /* ??? It's not clear whether this should have partial_inplace set or not. -+ Branch relaxing in the assembler can store the addend in the insn, -+ and if bfd_install_relocation gets called the addend may get added -+ again. */ -+- HOWTO (R_NDS32_25_PCREL, /* type */ -+- 1, /* rightshift */ -+- 2, /* size (0 = byte, 1 = short, 2 = long) */ -+- 24, /* bitsize */ -+- TRUE, /* pc_relative */ -+- 0, /* bitpos */ -+- complain_overflow_signed, /* complain_on_overflow */ -+- bfd_elf_generic_reloc, /* special_function */ -+- "R_NDS32_25_PCREL", /* name */ -+- FALSE, /* partial_inplace */ -+- 0xffffff, /* src_mask */ -+- 0xffffff, /* dst_mask */ -+- TRUE), /* pcrel_offset */ -++ HOWTO2 (R_NDS32_25_PCREL, /* type */ -++ 1, /* rightshift */ -++ 2, /* size (0 = byte, 1 = short, 2 = long) */ -++ 24, /* bitsize */ -++ TRUE, /* pc_relative */ -++ 0, /* bitpos */ -++ complain_overflow_signed,/* complain_on_overflow */ -++ bfd_elf_generic_reloc, /* special_function */ -++ "R_NDS32_25_PCREL", /* name */ -++ FALSE, /* partial_inplace */ -++ 0xffffff, /* src_mask */ -++ 0xffffff, /* dst_mask */ -++ TRUE), /* pcrel_offset */ -+ -+ /* High 20 bits of address when lower 12 is or'd in. */ -+- HOWTO (R_NDS32_HI20, /* type */ -+- 12, /* rightshift */ -+- 2, /* size (0 = byte, 1 = short, 2 = long) */ -+- 20, /* bitsize */ -+- FALSE, /* pc_relative */ -+- 0, /* bitpos */ -+- complain_overflow_dont,/* complain_on_overflow */ -+- nds32_elf_hi20_reloc, /* special_function */ -+- "R_NDS32_HI20", /* name */ -+- FALSE, /* partial_inplace */ -+- 0x000fffff, /* src_mask */ -+- 0x000fffff, /* dst_mask */ -+- FALSE), /* pcrel_offset */ -++ HOWTO2 (R_NDS32_HI20, /* type */ -++ 12, /* rightshift */ -++ 2, /* size (0 = byte, 1 = short, 2 = long) */ -++ 20, /* bitsize */ -++ FALSE, /* pc_relative */ -++ 0, /* bitpos */ -++ complain_overflow_dont,/* complain_on_overflow */ -++ nds32_elf_hi20_reloc, /* special_function */ -++ "R_NDS32_HI20", /* name */ -++ FALSE, /* partial_inplace */ -++ 0x000fffff, /* src_mask */ -++ 0x000fffff, /* dst_mask */ -++ FALSE), /* pcrel_offset */ -+ -+ /* Lower 12 bits of address. */ -+- HOWTO (R_NDS32_LO12S3, /* type */ -+- 3, /* rightshift */ -+- 2, /* size (0 = byte, 1 = short, 2 = long) */ -+- 9, /* bitsize */ -+- FALSE, /* pc_relative */ -+- 0, /* bitpos */ -+- complain_overflow_dont,/* complain_on_overflow */ -+- nds32_elf_lo12_reloc, /* special_function */ -+- "R_NDS32_LO12S3", /* name */ -+- FALSE, /* partial_inplace */ -+- 0x000001ff, /* src_mask */ -+- 0x000001ff, /* dst_mask */ -+- FALSE), /* pcrel_offset */ -++ HOWTO2 (R_NDS32_LO12S3, /* type */ -++ 3, /* rightshift */ -++ 2, /* size (0 = byte, 1 = short, 2 = long) */ -++ 9, /* bitsize */ -++ FALSE, /* pc_relative */ -++ 0, /* bitpos */ -++ complain_overflow_dont,/* complain_on_overflow */ -++ nds32_elf_lo12_reloc, /* special_function */ -++ "R_NDS32_LO12S3", /* name */ -++ FALSE, /* partial_inplace */ -++ 0x000001ff, /* src_mask */ -++ 0x000001ff, /* dst_mask */ -++ FALSE), /* pcrel_offset */ -+ -+ /* Lower 12 bits of address. */ -+- HOWTO (R_NDS32_LO12S2, /* type */ -+- 2, /* rightshift */ -+- 2, /* size (0 = byte, 1 = short, 2 = long) */ -+- 10, /* bitsize */ -+- FALSE, /* pc_relative */ -+- 0, /* bitpos */ -+- complain_overflow_dont,/* complain_on_overflow */ -+- nds32_elf_lo12_reloc, /* special_function */ -+- "R_NDS32_LO12S2", /* name */ -+- FALSE, /* partial_inplace */ -+- 0x000003ff, /* src_mask */ -+- 0x000003ff, /* dst_mask */ -+- FALSE), /* pcrel_offset */ -++ HOWTO2 (R_NDS32_LO12S2, /* type */ -++ 2, /* rightshift */ -++ 2, /* size (0 = byte, 1 = short, 2 = long) */ -++ 10, /* bitsize */ -++ FALSE, /* pc_relative */ -++ 0, /* bitpos */ -++ complain_overflow_dont,/* complain_on_overflow */ -++ nds32_elf_lo12_reloc, /* special_function */ -++ "R_NDS32_LO12S2", /* name */ -++ FALSE, /* partial_inplace */ -++ 0x000003ff, /* src_mask */ -++ 0x000003ff, /* dst_mask */ -++ FALSE), /* pcrel_offset */ -+ -+ /* Lower 12 bits of address. */ -+- HOWTO (R_NDS32_LO12S1, /* type */ -+- 1, /* rightshift */ -+- 2, /* size (0 = byte, 1 = short, 2 = long) */ -+- 11, /* bitsize */ -+- FALSE, /* pc_relative */ -+- 0, /* bitpos */ -+- complain_overflow_dont,/* complain_on_overflow */ -+- nds32_elf_lo12_reloc, /* special_function */ -+- "R_NDS32_LO12S1", /* name */ -+- FALSE, /* partial_inplace */ -+- 0x000007ff, /* src_mask */ -+- 0x000007ff, /* dst_mask */ -+- FALSE), /* pcrel_offset */ -++ HOWTO2 (R_NDS32_LO12S1, /* type */ -++ 1, /* rightshift */ -++ 2, /* size (0 = byte, 1 = short, 2 = long) */ -++ 11, /* bitsize */ -++ FALSE, /* pc_relative */ -++ 0, /* bitpos */ -++ complain_overflow_dont,/* complain_on_overflow */ -++ nds32_elf_lo12_reloc, /* special_function */ -++ "R_NDS32_LO12S1", /* name */ -++ FALSE, /* partial_inplace */ -++ 0x000007ff, /* src_mask */ -++ 0x000007ff, /* dst_mask */ -++ FALSE), /* pcrel_offset */ -+ -+ /* Lower 12 bits of address. */ -+- HOWTO (R_NDS32_LO12S0, /* type */ -+- 0, /* rightshift */ -+- 2, /* size (0 = byte, 1 = short, 2 = long) */ -+- 12, /* bitsize */ -+- FALSE, /* pc_relative */ -+- 0, /* bitpos */ -+- complain_overflow_dont,/* complain_on_overflow */ -+- nds32_elf_lo12_reloc, /* special_function */ -+- "R_NDS32_LO12S0", /* name */ -+- FALSE, /* partial_inplace */ -+- 0x00000fff, /* src_mask */ -+- 0x00000fff, /* dst_mask */ -+- FALSE), /* pcrel_offset */ -++ HOWTO2 (R_NDS32_LO12S0, /* type */ -++ 0, /* rightshift */ -++ 2, /* size (0 = byte, 1 = short, 2 = long) */ -++ 12, /* bitsize */ -++ FALSE, /* pc_relative */ -++ 0, /* bitpos */ -++ complain_overflow_dont,/* complain_on_overflow */ -++ nds32_elf_lo12_reloc, /* special_function */ -++ "R_NDS32_LO12S0", /* name */ -++ FALSE, /* partial_inplace */ -++ 0x00000fff, /* src_mask */ -++ 0x00000fff, /* dst_mask */ -++ FALSE), /* pcrel_offset */ -+ -+ /* Small data area 15 bits offset. */ -+- HOWTO (R_NDS32_SDA15S3, /* type */ -+- 3, /* rightshift */ -+- 2, /* size (0 = byte, 1 = short, 2 = long) */ -+- 15, /* bitsize */ -+- FALSE, /* pc_relative */ -+- 0, /* bitpos */ -+- complain_overflow_signed, /* complain_on_overflow */ -+- nds32_elf_sda15_reloc, /* special_function */ -+- "R_NDS32_SDA15S3", /* name */ -+- FALSE, /* partial_inplace */ -+- 0x00007fff, /* src_mask */ -+- 0x00007fff, /* dst_mask */ -+- FALSE), /* pcrel_offset */ -++ HOWTO2 (R_NDS32_SDA15S3, /* type */ -++ 3, /* rightshift */ -++ 2, /* size (0 = byte, 1 = short, 2 = long) */ -++ 15, /* bitsize */ -++ FALSE, /* pc_relative */ -++ 0, /* bitpos */ -++ complain_overflow_signed,/* complain_on_overflow */ -++ nds32_elf_sda15_reloc, /* special_function */ -++ "R_NDS32_SDA15S3", /* name */ -++ FALSE, /* partial_inplace */ -++ 0x00007fff, /* src_mask */ -++ 0x00007fff, /* dst_mask */ -++ FALSE), /* pcrel_offset */ -+ -+ /* Small data area 15 bits offset. */ -+- HOWTO (R_NDS32_SDA15S2, /* type */ -+- 2, /* rightshift */ -+- 2, /* size (0 = byte, 1 = short, 2 = long) */ -+- 15, /* bitsize */ -+- FALSE, /* pc_relative */ -+- 0, /* bitpos */ -+- complain_overflow_signed, /* complain_on_overflow */ -+- nds32_elf_sda15_reloc, /* special_function */ -+- "R_NDS32_SDA15S2", /* name */ -+- FALSE, /* partial_inplace */ -+- 0x00007fff, /* src_mask */ -+- 0x00007fff, /* dst_mask */ -+- FALSE), /* pcrel_offset */ -++ HOWTO2 (R_NDS32_SDA15S2, /* type */ -++ 2, /* rightshift */ -++ 2, /* size (0 = byte, 1 = short, 2 = long) */ -++ 15, /* bitsize */ -++ FALSE, /* pc_relative */ -++ 0, /* bitpos */ -++ complain_overflow_signed,/* complain_on_overflow */ -++ nds32_elf_sda15_reloc, /* special_function */ -++ "R_NDS32_SDA15S2", /* name */ -++ FALSE, /* partial_inplace */ -++ 0x00007fff, /* src_mask */ -++ 0x00007fff, /* dst_mask */ -++ FALSE), /* pcrel_offset */ -+ -+ /* Small data area 15 bits offset. */ -+- HOWTO (R_NDS32_SDA15S1, /* type */ -+- 1, /* rightshift */ -+- 2, /* size (0 = byte, 1 = short, 2 = long) */ -+- 15, /* bitsize */ -+- FALSE, /* pc_relative */ -+- 0, /* bitpos */ -+- complain_overflow_signed, /* complain_on_overflow */ -+- nds32_elf_sda15_reloc, /* special_function */ -+- "R_NDS32_SDA15S1", /* name */ -+- FALSE, /* partial_inplace */ -+- 0x00007fff, /* src_mask */ -+- 0x00007fff, /* dst_mask */ -+- FALSE), /* pcrel_offset */ -++ HOWTO2 (R_NDS32_SDA15S1, /* type */ -++ 1, /* rightshift */ -++ 2, /* size (0 = byte, 1 = short, 2 = long) */ -++ 15, /* bitsize */ -++ FALSE, /* pc_relative */ -++ 0, /* bitpos */ -++ complain_overflow_signed,/* complain_on_overflow */ -++ nds32_elf_sda15_reloc, /* special_function */ -++ "R_NDS32_SDA15S1", /* name */ -++ FALSE, /* partial_inplace */ -++ 0x00007fff, /* src_mask */ -++ 0x00007fff, /* dst_mask */ -++ FALSE), /* pcrel_offset */ -+ -+ /* Small data area 15 bits offset. */ -+- HOWTO (R_NDS32_SDA15S0, /* type */ -+- 0, /* rightshift */ -+- 2, /* size (0 = byte, 1 = short, 2 = long) */ -+- 15, /* bitsize */ -+- FALSE, /* pc_relative */ -+- 0, /* bitpos */ -+- complain_overflow_signed, /* complain_on_overflow */ -+- nds32_elf_sda15_reloc, /* special_function */ -+- "R_NDS32_SDA15S0", /* name */ -+- FALSE, /* partial_inplace */ -+- 0x00007fff, /* src_mask */ -+- 0x00007fff, /* dst_mask */ -+- FALSE), /* pcrel_offset */ -+- -+- /* GNU extension to record C++ vtable hierarchy */ -+- HOWTO (R_NDS32_GNU_VTINHERIT, /* type */ -+- 0, /* rightshift */ -+- 2, /* size (0 = byte, 1 = short, 2 = long) */ -+- 0, /* bitsize */ -+- FALSE, /* pc_relative */ -+- 0, /* bitpos */ -+- complain_overflow_dont,/* complain_on_overflow */ -+- NULL, /* special_function */ -+- "R_NDS32_GNU_VTINHERIT", /* name */ -+- FALSE, /* partial_inplace */ -+- 0, /* src_mask */ -+- 0, /* dst_mask */ -+- FALSE), /* pcrel_offset */ -+- -+- /* GNU extension to record C++ vtable member usage */ -+- HOWTO (R_NDS32_GNU_VTENTRY, /* type */ -+- 0, /* rightshift */ -+- 2, /* size (0 = byte, 1 = short, 2 = long) */ -+- 0, /* bitsize */ -+- FALSE, /* pc_relative */ -+- 0, /* bitpos */ -+- complain_overflow_dont,/* complain_on_overflow */ -+- _bfd_elf_rel_vtable_reloc_fn, /* special_function */ -+- "R_NDS32_GNU_VTENTRY", /* name */ -+- FALSE, /* partial_inplace */ -+- 0, /* src_mask */ -+- 0, /* dst_mask */ -+- FALSE), /* pcrel_offset */ -++ HOWTO2 (R_NDS32_SDA15S0, /* type */ -++ 0, /* rightshift */ -++ 2, /* size (0 = byte, 1 = short, 2 = long) */ -++ 15, /* bitsize */ -++ FALSE, /* pc_relative */ -++ 0, /* bitpos */ -++ complain_overflow_signed,/* complain_on_overflow */ -++ nds32_elf_sda15_reloc, /* special_function */ -++ "R_NDS32_SDA15S0", /* name */ -++ FALSE, /* partial_inplace */ -++ 0x00007fff, /* src_mask */ -++ 0x00007fff, /* dst_mask */ -++ FALSE), /* pcrel_offset */ -++ -++ /* GNU extension to record C++ vtable hierarchy */ -++ HOWTO2 (R_NDS32_GNU_VTINHERIT,/* type */ -++ 0, /* rightshift */ -++ 2, /* size (0 = byte, 1 = short, 2 = long) */ -++ 0, /* bitsize */ -++ FALSE, /* pc_relative */ -++ 0, /* bitpos */ -++ complain_overflow_dont,/* complain_on_overflow */ -++ NULL, /* special_function */ -++ "R_NDS32_GNU_VTINHERIT",/* name */ -++ FALSE, /* partial_inplace */ -++ 0, /* src_mask */ -++ 0, /* dst_mask */ -++ FALSE), /* pcrel_offset */ -++ -++ /* GNU extension to record C++ vtable member usage */ -++ HOWTO2 (R_NDS32_GNU_VTENTRY, /* type */ -++ 0, /* rightshift */ -++ 2, /* size (0 = byte, 1 = short, 2 = long) */ -++ 0, /* bitsize */ -++ FALSE, /* pc_relative */ -++ 0, /* bitpos */ -++ complain_overflow_dont,/* complain_on_overflow */ -++ _bfd_elf_rel_vtable_reloc_fn,/* special_function */ -++ "R_NDS32_GNU_VTENTRY", /* name */ -++ FALSE, /* partial_inplace */ -++ 0, /* src_mask */ -++ 0, /* dst_mask */ -++ FALSE), /* pcrel_offset */ -+ -+ /* A 16 bit absolute relocation. */ -+- HOWTO (R_NDS32_16_RELA, /* type */ -+- 0, /* rightshift */ -+- 1, /* size (0 = byte, 1 = short, 2 = long) */ -+- 16, /* bitsize */ -+- FALSE, /* pc_relative */ -+- 0, /* bitpos */ -+- complain_overflow_bitfield, /* complain_on_overflow */ -+- bfd_elf_generic_reloc, /* special_function */ -+- "R_NDS32_16_RELA", /* name */ -+- FALSE, /* partial_inplace */ -+- 0xffff, /* src_mask */ -+- 0xffff, /* dst_mask */ -+- FALSE), /* pcrel_offset */ -++ HOWTO2 (R_NDS32_16_RELA, /* type */ -++ 0, /* rightshift */ -++ 1, /* size (0 = byte, 1 = short, 2 = long) */ -++ 16, /* bitsize */ -++ FALSE, /* pc_relative */ -++ 0, /* bitpos */ -++ complain_overflow_bitfield,/* complain_on_overflow */ -++ bfd_elf_generic_reloc, /* special_function */ -++ "R_NDS32_16_RELA", /* name */ -++ FALSE, /* partial_inplace */ -++ 0xffff, /* src_mask */ -++ 0xffff, /* dst_mask */ -++ FALSE), /* pcrel_offset */ -+ -+ /* A 32 bit absolute relocation. */ -+- HOWTO (R_NDS32_32_RELA, /* type */ -+- 0, /* rightshift */ -+- 2, /* size (0 = byte, 1 = short, 2 = long) */ -+- 32, /* bitsize */ -+- FALSE, /* pc_relative */ -+- 0, /* bitpos */ -+- complain_overflow_bitfield, /* complain_on_overflow */ -+- bfd_elf_generic_reloc, /* special_function */ -+- "R_NDS32_32_RELA", /* name */ -+- FALSE, /* partial_inplace */ -+- 0xffffffff, /* src_mask */ -+- 0xffffffff, /* dst_mask */ -+- FALSE), /* pcrel_offset */ -++ HOWTO2 (R_NDS32_32_RELA, /* type */ -++ 0, /* rightshift */ -++ 2, /* size (0 = byte, 1 = short, 2 = long) */ -++ 32, /* bitsize */ -++ FALSE, /* pc_relative */ -++ 0, /* bitpos */ -++ complain_overflow_bitfield,/* complain_on_overflow */ -++ bfd_elf_generic_reloc, /* special_function */ -++ "R_NDS32_32_RELA", /* name */ -++ FALSE, /* partial_inplace */ -++ 0xffffffff, /* src_mask */ -++ 0xffffffff, /* dst_mask */ -++ FALSE), /* pcrel_offset */ -+ -+ /* A 20 bit address. */ -+- HOWTO (R_NDS32_20_RELA, /* type */ -+- 0, /* rightshift */ -+- 2, /* size (0 = byte, 1 = short, 2 = long) */ -+- 20, /* bitsize */ -+- FALSE, /* pc_relative */ -+- 0, /* bitpos */ -+- complain_overflow_signed, /* complain_on_overflow */ -+- bfd_elf_generic_reloc, /* special_function */ -+- "R_NDS32_20_RELA", /* name */ -+- FALSE, /* partial_inplace */ -+- 0xfffff, /* src_mask */ -+- 0xfffff, /* dst_mask */ -+- FALSE), /* pcrel_offset */ -+- -+- HOWTO (R_NDS32_9_PCREL_RELA, /* type */ -+- 1, /* rightshift */ -+- 1, /* size (0 = byte, 1 = short, 2 = long) */ -+- 8, /* bitsize */ -+- TRUE, /* pc_relative */ -+- 0, /* bitpos */ -+- complain_overflow_signed, /* complain_on_overflow */ -+- bfd_elf_generic_reloc, /* special_function */ -+- "R_NDS32_9_PCREL_RELA",/* name */ -+- FALSE, /* partial_inplace */ -+- 0xff, /* src_mask */ -+- 0xff, /* dst_mask */ -+- TRUE), /* pcrel_offset */ -++ HOWTO2 (R_NDS32_20_RELA, /* type */ -++ 0, /* rightshift */ -++ 2, /* size (0 = byte, 1 = short, 2 = long) */ -++ 20, /* bitsize */ -++ FALSE, /* pc_relative */ -++ 0, /* bitpos */ -++ complain_overflow_signed,/* complain_on_overflow */ -++ bfd_elf_generic_reloc, /* special_function */ -++ "R_NDS32_20_RELA", /* name */ -++ FALSE, /* partial_inplace */ -++ 0xfffff, /* src_mask */ -++ 0xfffff, /* dst_mask */ -++ FALSE), /* pcrel_offset */ -++ -++ HOWTO2 (R_NDS32_9_PCREL_RELA, /* type */ -++ 1, /* rightshift */ -++ 1, /* size (0 = byte, 1 = short, 2 = long) */ -++ 8, /* bitsize */ -++ TRUE, /* pc_relative */ -++ 0, /* bitpos */ -++ complain_overflow_signed,/* complain_on_overflow */ -++ bfd_elf_generic_reloc, /* special_function */ -++ "R_NDS32_9_PCREL_RELA",/* name */ -++ FALSE, /* partial_inplace */ -++ 0xff, /* src_mask */ -++ 0xff, /* dst_mask */ -++ TRUE), /* pcrel_offset */ -+ -+ /* A relative 15 bit relocation, right shifted by 1. */ -+- HOWTO (R_NDS32_15_PCREL_RELA, /* type */ -+- 1, /* rightshift */ -+- 2, /* size (0 = byte, 1 = short, 2 = long) */ -+- 14, /* bitsize */ -+- TRUE, /* pc_relative */ -+- 0, /* bitpos */ -+- complain_overflow_signed, /* complain_on_overflow */ -+- bfd_elf_generic_reloc, /* special_function */ -+- "R_NDS32_15_PCREL_RELA", /* name */ -+- FALSE, /* partial_inplace */ -+- 0x3fff, /* src_mask */ -+- 0x3fff, /* dst_mask */ -+- TRUE), /* pcrel_offset */ -++ HOWTO2 (R_NDS32_15_PCREL_RELA,/* type */ -++ 1, /* rightshift */ -++ 2, /* size (0 = byte, 1 = short, 2 = long) */ -++ 14, /* bitsize */ -++ TRUE, /* pc_relative */ -++ 0, /* bitpos */ -++ complain_overflow_signed,/* complain_on_overflow */ -++ bfd_elf_generic_reloc, /* special_function */ -++ "R_NDS32_15_PCREL_RELA",/* name */ -++ FALSE, /* partial_inplace */ -++ 0x3fff, /* src_mask */ -++ 0x3fff, /* dst_mask */ -++ TRUE), /* pcrel_offset */ -+ -+ /* A relative 17 bit relocation, right shifted by 1. */ -+- HOWTO (R_NDS32_17_PCREL_RELA, /* type */ -+- 1, /* rightshift */ -+- 2, /* size (0 = byte, 1 = short, 2 = long) */ -+- 16, /* bitsize */ -+- TRUE, /* pc_relative */ -+- 0, /* bitpos */ -+- complain_overflow_signed, /* complain_on_overflow */ -+- bfd_elf_generic_reloc, /* special_function */ -+- "R_NDS32_17_PCREL_RELA", /* name */ -+- FALSE, /* partial_inplace */ -+- 0xffff, /* src_mask */ -+- 0xffff, /* dst_mask */ -+- TRUE), /* pcrel_offset */ -++ HOWTO2 (R_NDS32_17_PCREL_RELA,/* type */ -++ 1, /* rightshift */ -++ 2, /* size (0 = byte, 1 = short, 2 = long) */ -++ 16, /* bitsize */ -++ TRUE, /* pc_relative */ -++ 0, /* bitpos */ -++ complain_overflow_signed,/* complain_on_overflow */ -++ bfd_elf_generic_reloc, /* special_function */ -++ "R_NDS32_17_PCREL_RELA",/* name */ -++ FALSE, /* partial_inplace */ -++ 0xffff, /* src_mask */ -++ 0xffff, /* dst_mask */ -++ TRUE), /* pcrel_offset */ -+ -+ /* A relative 25 bit relocation, right shifted by 2. */ -+- HOWTO (R_NDS32_25_PCREL_RELA, /* type */ -+- 1, /* rightshift */ -+- 2, /* size (0 = byte, 1 = short, 2 = long) */ -+- 24, /* bitsize */ -+- TRUE, /* pc_relative */ -+- 0, /* bitpos */ -+- complain_overflow_signed, /* complain_on_overflow */ -+- bfd_elf_generic_reloc, /* special_function */ -+- "R_NDS32_25_PCREL_RELA", /* name */ -+- FALSE, /* partial_inplace */ -+- 0xffffff, /* src_mask */ -+- 0xffffff, /* dst_mask */ -+- TRUE), /* pcrel_offset */ -++ HOWTO2 (R_NDS32_25_PCREL_RELA,/* type */ -++ 1, /* rightshift */ -++ 2, /* size (0 = byte, 1 = short, 2 = long) */ -++ 24, /* bitsize */ -++ TRUE, /* pc_relative */ -++ 0, /* bitpos */ -++ complain_overflow_signed,/* complain_on_overflow */ -++ bfd_elf_generic_reloc, /* special_function */ -++ "R_NDS32_25_PCREL_RELA",/* name */ -++ FALSE, /* partial_inplace */ -++ 0xffffff, /* src_mask */ -++ 0xffffff, /* dst_mask */ -++ TRUE), /* pcrel_offset */ -+ -+ /* High 20 bits of address when lower 16 is or'd in. */ -+- HOWTO (R_NDS32_HI20_RELA, /* type */ -+- 12, /* rightshift */ -+- 2, /* size (0 = byte, 1 = short, 2 = long) */ -+- 20, /* bitsize */ -+- FALSE, /* pc_relative */ -+- 0, /* bitpos */ -+- complain_overflow_dont,/* complain_on_overflow */ -+- bfd_elf_generic_reloc, /* special_function */ -+- "R_NDS32_HI20_RELA", /* name */ -+- FALSE, /* partial_inplace */ -+- 0x000fffff, /* src_mask */ -+- 0x000fffff, /* dst_mask */ -+- FALSE), /* pcrel_offset */ -++ HOWTO2 (R_NDS32_HI20_RELA, /* type */ -++ 12, /* rightshift */ -++ 2, /* size (0 = byte, 1 = short, 2 = long) */ -++ 20, /* bitsize */ -++ FALSE, /* pc_relative */ -++ 0, /* bitpos */ -++ complain_overflow_dont,/* complain_on_overflow */ -++ bfd_elf_generic_reloc, /* special_function */ -++ "R_NDS32_HI20_RELA", /* name */ -++ FALSE, /* partial_inplace */ -++ 0x000fffff, /* src_mask */ -++ 0x000fffff, /* dst_mask */ -++ FALSE), /* pcrel_offset */ -+ -+ /* Lower 12 bits of address. */ -+- HOWTO (R_NDS32_LO12S3_RELA, /* type */ -+- 3, /* rightshift */ -+- 2, /* size (0 = byte, 1 = short, 2 = long) */ -+- 9, /* bitsize */ -+- FALSE, /* pc_relative */ -+- 0, /* bitpos */ -+- complain_overflow_dont,/* complain_on_overflow */ -+- bfd_elf_generic_reloc, /* special_function */ -+- "R_NDS32_LO12S3_RELA", /* name */ -+- FALSE, /* partial_inplace */ -+- 0x000001ff, /* src_mask */ -+- 0x000001ff, /* dst_mask */ -+- FALSE), /* pcrel_offset */ -++ HOWTO2 (R_NDS32_LO12S3_RELA, /* type */ -++ 3, /* rightshift */ -++ 2, /* size (0 = byte, 1 = short, 2 = long) */ -++ 9, /* bitsize */ -++ FALSE, /* pc_relative */ -++ 0, /* bitpos */ -++ complain_overflow_dont,/* complain_on_overflow */ -++ bfd_elf_generic_reloc, /* special_function */ -++ "R_NDS32_LO12S3_RELA", /* name */ -++ FALSE, /* partial_inplace */ -++ 0x000001ff, /* src_mask */ -++ 0x000001ff, /* dst_mask */ -++ FALSE), /* pcrel_offset */ -+ -+ /* Lower 12 bits of address. */ -+- HOWTO (R_NDS32_LO12S2_RELA, /* type */ -+- 2, /* rightshift */ -+- 2, /* size (0 = byte, 1 = short, 2 = long) */ -+- 10, /* bitsize */ -+- FALSE, /* pc_relative */ -+- 0, /* bitpos */ -+- complain_overflow_dont,/* complain_on_overflow */ -+- bfd_elf_generic_reloc, /* special_function */ -+- "R_NDS32_LO12S2_RELA", /* name */ -+- FALSE, /* partial_inplace */ -+- 0x000003ff, /* src_mask */ -+- 0x000003ff, /* dst_mask */ -+- FALSE), /* pcrel_offset */ -++ HOWTO2 (R_NDS32_LO12S2_RELA, /* type */ -++ 2, /* rightshift */ -++ 2, /* size (0 = byte, 1 = short, 2 = long) */ -++ 10, /* bitsize */ -++ FALSE, /* pc_relative */ -++ 0, /* bitpos */ -++ complain_overflow_dont,/* complain_on_overflow */ -++ bfd_elf_generic_reloc, /* special_function */ -++ "R_NDS32_LO12S2_RELA", /* name */ -++ FALSE, /* partial_inplace */ -++ 0x000003ff, /* src_mask */ -++ 0x000003ff, /* dst_mask */ -++ FALSE), /* pcrel_offset */ -+ -+ /* Lower 12 bits of address. */ -+- HOWTO (R_NDS32_LO12S1_RELA, /* type */ -+- 1, /* rightshift */ -+- 2, /* size (0 = byte, 1 = short, 2 = long) */ -+- 11, /* bitsize */ -+- FALSE, /* pc_relative */ -+- 0, /* bitpos */ -+- complain_overflow_dont,/* complain_on_overflow */ -+- bfd_elf_generic_reloc, /* special_function */ -+- "R_NDS32_LO12S1_RELA", /* name */ -+- FALSE, /* partial_inplace */ -+- 0x000007ff, /* src_mask */ -+- 0x000007ff, /* dst_mask */ -+- FALSE), /* pcrel_offset */ -++ HOWTO2 (R_NDS32_LO12S1_RELA, /* type */ -++ 1, /* rightshift */ -++ 2, /* size (0 = byte, 1 = short, 2 = long) */ -++ 11, /* bitsize */ -++ FALSE, /* pc_relative */ -++ 0, /* bitpos */ -++ complain_overflow_dont,/* complain_on_overflow */ -++ bfd_elf_generic_reloc, /* special_function */ -++ "R_NDS32_LO12S1_RELA", /* name */ -++ FALSE, /* partial_inplace */ -++ 0x000007ff, /* src_mask */ -++ 0x000007ff, /* dst_mask */ -++ FALSE), /* pcrel_offset */ -+ -+ /* Lower 12 bits of address. */ -+- HOWTO (R_NDS32_LO12S0_RELA, /* type */ -+- 0, /* rightshift */ -+- 2, /* size (0 = byte, 1 = short, 2 = long) */ -+- 12, /* bitsize */ -+- FALSE, /* pc_relative */ -+- 0, /* bitpos */ -+- complain_overflow_dont,/* complain_on_overflow */ -+- bfd_elf_generic_reloc, /* special_function */ -+- "R_NDS32_LO12S0_RELA", /* name */ -+- FALSE, /* partial_inplace */ -+- 0x00000fff, /* src_mask */ -+- 0x00000fff, /* dst_mask */ -+- FALSE), /* pcrel_offset */ -++ HOWTO2 (R_NDS32_LO12S0_RELA, /* type */ -++ 0, /* rightshift */ -++ 2, /* size (0 = byte, 1 = short, 2 = long) */ -++ 12, /* bitsize */ -++ FALSE, /* pc_relative */ -++ 0, /* bitpos */ -++ complain_overflow_dont,/* complain_on_overflow */ -++ bfd_elf_generic_reloc, /* special_function */ -++ "R_NDS32_LO12S0_RELA", /* name */ -++ FALSE, /* partial_inplace */ -++ 0x00000fff, /* src_mask */ -++ 0x00000fff, /* dst_mask */ -++ FALSE), /* pcrel_offset */ -+ -+ /* Small data area 15 bits offset. */ -+- HOWTO (R_NDS32_SDA15S3_RELA, /* type */ -+- 3, /* rightshift */ -+- 2, /* size (0 = byte, 1 = short, 2 = long) */ -+- 15, /* bitsize */ -+- FALSE, /* pc_relative */ -+- 0, /* bitpos */ -+- complain_overflow_signed, /* complain_on_overflow */ -+- bfd_elf_generic_reloc, /* special_function */ -+- "R_NDS32_SDA15S3_RELA",/* name */ -+- FALSE, /* partial_inplace */ -+- 0x00007fff, /* src_mask */ -+- 0x00007fff, /* dst_mask */ -+- FALSE), /* pcrel_offset */ -++ HOWTO2 (R_NDS32_SDA15S3_RELA, /* type */ -++ 3, /* rightshift */ -++ 2, /* size (0 = byte, 1 = short, 2 = long) */ -++ 15, /* bitsize */ -++ FALSE, /* pc_relative */ -++ 0, /* bitpos */ -++ complain_overflow_signed,/* complain_on_overflow */ -++ bfd_elf_generic_reloc, /* special_function */ -++ "R_NDS32_SDA15S3_RELA",/* name */ -++ FALSE, /* partial_inplace */ -++ 0x00007fff, /* src_mask */ -++ 0x00007fff, /* dst_mask */ -++ FALSE), /* pcrel_offset */ -+ -+ /* Small data area 15 bits offset. */ -+- HOWTO (R_NDS32_SDA15S2_RELA, /* type */ -+- 2, /* rightshift */ -+- 2, /* size (0 = byte, 1 = short, 2 = long) */ -+- 15, /* bitsize */ -+- FALSE, /* pc_relative */ -+- 0, /* bitpos */ -+- complain_overflow_signed, /* complain_on_overflow */ -+- bfd_elf_generic_reloc, /* special_function */ -+- "R_NDS32_SDA15S2_RELA",/* name */ -+- FALSE, /* partial_inplace */ -+- 0x00007fff, /* src_mask */ -+- 0x00007fff, /* dst_mask */ -+- FALSE), /* pcrel_offset */ -+- -+- HOWTO (R_NDS32_SDA15S1_RELA, /* type */ -+- 1, /* rightshift */ -+- 2, /* size (0 = byte, 1 = short, 2 = long) */ -+- 15, /* bitsize */ -+- FALSE, /* pc_relative */ -+- 0, /* bitpos */ -+- complain_overflow_signed, /* complain_on_overflow */ -+- bfd_elf_generic_reloc, /* special_function */ -+- "R_NDS32_SDA15S1_RELA",/* name */ -+- FALSE, /* partial_inplace */ -+- 0x00007fff, /* src_mask */ -+- 0x00007fff, /* dst_mask */ -+- FALSE), /* pcrel_offset */ -+- -+- HOWTO (R_NDS32_SDA15S0_RELA, /* type */ -+- 0, /* rightshift */ -+- 2, /* size (0 = byte, 1 = short, 2 = long) */ -+- 15, /* bitsize */ -+- FALSE, /* pc_relative */ -+- 0, /* bitpos */ -+- complain_overflow_signed, /* complain_on_overflow */ -+- bfd_elf_generic_reloc, /* special_function */ -+- "R_NDS32_SDA15S0_RELA",/* name */ -+- FALSE, /* partial_inplace */ -+- 0x00007fff, /* src_mask */ -+- 0x00007fff, /* dst_mask */ -+- FALSE), /* pcrel_offset */ -+- -+- /* GNU extension to record C++ vtable hierarchy */ -+- HOWTO (R_NDS32_RELA_GNU_VTINHERIT, /* type */ -+- 0, /* rightshift */ -+- 2, /* size (0 = byte, 1 = short, 2 = long) */ -+- 0, /* bitsize */ -+- FALSE, /* pc_relative */ -+- 0, /* bitpos */ -+- complain_overflow_dont,/* complain_on_overflow */ -+- NULL, /* special_function */ -+- "R_NDS32_RELA_GNU_VTINHERIT", /* name */ -+- FALSE, /* partial_inplace */ -+- 0, /* src_mask */ -+- 0, /* dst_mask */ -+- FALSE), /* pcrel_offset */ -+- -+- /* GNU extension to record C++ vtable member usage */ -+- HOWTO (R_NDS32_RELA_GNU_VTENTRY, /* type */ -+- 0, /* rightshift */ -+- 2, /* size (0 = byte, 1 = short, 2 = long) */ -+- 0, /* bitsize */ -+- FALSE, /* pc_relative */ -+- 0, /* bitpos */ -+- complain_overflow_dont,/* complain_on_overflow */ -+- _bfd_elf_rel_vtable_reloc_fn, /* special_function */ -+- "R_NDS32_RELA_GNU_VTENTRY", /* name */ -+- FALSE, /* partial_inplace */ -+- 0, /* src_mask */ -+- 0, /* dst_mask */ -+- FALSE), /* pcrel_offset */ -++ HOWTO2 (R_NDS32_SDA15S2_RELA, /* type */ -++ 2, /* rightshift */ -++ 2, /* size (0 = byte, 1 = short, 2 = long) */ -++ 15, /* bitsize */ -++ FALSE, /* pc_relative */ -++ 0, /* bitpos */ -++ complain_overflow_signed,/* complain_on_overflow */ -++ bfd_elf_generic_reloc, /* special_function */ -++ "R_NDS32_SDA15S2_RELA",/* name */ -++ FALSE, /* partial_inplace */ -++ 0x00007fff, /* src_mask */ -++ 0x00007fff, /* dst_mask */ -++ FALSE), /* pcrel_offset */ -++ -++ HOWTO2 (R_NDS32_SDA15S1_RELA, /* type */ -++ 1, /* rightshift */ -++ 2, /* size (0 = byte, 1 = short, 2 = long) */ -++ 15, /* bitsize */ -++ FALSE, /* pc_relative */ -++ 0, /* bitpos */ -++ complain_overflow_signed,/* complain_on_overflow */ -++ bfd_elf_generic_reloc, /* special_function */ -++ "R_NDS32_SDA15S1_RELA",/* name */ -++ FALSE, /* partial_inplace */ -++ 0x00007fff, /* src_mask */ -++ 0x00007fff, /* dst_mask */ -++ FALSE), /* pcrel_offset */ -++ -++ HOWTO2 (R_NDS32_SDA15S0_RELA, /* type */ -++ 0, /* rightshift */ -++ 2, /* size (0 = byte, 1 = short, 2 = long) */ -++ 15, /* bitsize */ -++ FALSE, /* pc_relative */ -++ 0, /* bitpos */ -++ complain_overflow_signed,/* complain_on_overflow */ -++ bfd_elf_generic_reloc, /* special_function */ -++ "R_NDS32_SDA15S0_RELA",/* name */ -++ FALSE, /* partial_inplace */ -++ 0x00007fff, /* src_mask */ -++ 0x00007fff, /* dst_mask */ -++ FALSE), /* pcrel_offset */ -++ -++ /* GNU extension to record C++ vtable hierarchy */ -++ HOWTO2 (R_NDS32_RELA_GNU_VTINHERIT,/* type */ -++ 0, /* rightshift */ -++ 2, /* size (0 = byte, 1 = short, 2 = long) */ -++ 0, /* bitsize */ -++ FALSE, /* pc_relative */ -++ 0, /* bitpos */ -++ complain_overflow_dont,/* complain_on_overflow */ -++ NULL, /* special_function */ -++ "R_NDS32_RELA_GNU_VTINHERIT",/* name */ -++ FALSE, /* partial_inplace */ -++ 0, /* src_mask */ -++ 0, /* dst_mask */ -++ FALSE), /* pcrel_offset */ -++ -++ /* GNU extension to record C++ vtable member usage */ -++ HOWTO2 (R_NDS32_RELA_GNU_VTENTRY,/* type */ -++ 0, /* rightshift */ -++ 2, /* size (0 = byte, 1 = short, 2 = long) */ -++ 0, /* bitsize */ -++ FALSE, /* pc_relative */ -++ 0, /* bitpos */ -++ complain_overflow_dont,/* complain_on_overflow */ -++ _bfd_elf_rel_vtable_reloc_fn,/* special_function */ -++ "R_NDS32_RELA_GNU_VTENTRY",/* name */ -++ FALSE, /* partial_inplace */ -++ 0, /* src_mask */ -++ 0, /* dst_mask */ -++ FALSE), /* pcrel_offset */ -+ -+ /* Like R_NDS32_20, but referring to the GOT table entry for -+ the symbol. */ -+- HOWTO (R_NDS32_GOT20, /* type */ -+- 0, /* rightshift */ -+- 2, /* size (0 = byte, 1 = short, 2 = long) */ -+- 20, /* bitsize */ -+- FALSE, /* pc_relative */ -+- 0, /* bitpos */ -+- complain_overflow_signed, /* complain_on_overflow */ -+- bfd_elf_generic_reloc, /* special_function */ -+- "R_NDS32_GOT20", /* name */ -+- FALSE, /* partial_inplace */ -+- 0xfffff, /* src_mask */ -+- 0xfffff, /* dst_mask */ -+- FALSE), /* pcrel_offset */ -++ HOWTO2 (R_NDS32_GOT20, /* type */ -++ 0, /* rightshift */ -++ 2, /* size (0 = byte, 1 = short, 2 = long) */ -++ 20, /* bitsize */ -++ FALSE, /* pc_relative */ -++ 0, /* bitpos */ -++ complain_overflow_signed,/* complain_on_overflow */ -++ bfd_elf_generic_reloc, /* special_function */ -++ "R_NDS32_GOT20", /* name */ -++ FALSE, /* partial_inplace */ -++ 0xfffff, /* src_mask */ -++ 0xfffff, /* dst_mask */ -++ FALSE), /* pcrel_offset */ -+ -+ /* Like R_NDS32_PCREL, but referring to the procedure linkage table -+ entry for the symbol. */ -+- HOWTO (R_NDS32_25_PLTREL, /* type */ -+- 1, /* rightshift */ -+- 2, /* size (0 = byte, 1 = short, 2 = long) */ -+- 24, /* bitsize */ -+- TRUE, /* pc_relative */ -+- 0, /* bitpos */ -+- complain_overflow_signed, /* complain_on_overflow */ -+- bfd_elf_generic_reloc, /* special_function */ -+- "R_NDS32_25_PLTREL", /* name */ -+- FALSE, /* partial_inplace */ -+- 0xffffff, /* src_mask */ -+- 0xffffff, /* dst_mask */ -+- TRUE), /* pcrel_offset */ -++ HOWTO2 (R_NDS32_25_PLTREL, /* type */ -++ 1, /* rightshift */ -++ 2, /* size (0 = byte, 1 = short, 2 = long) */ -++ 24, /* bitsize */ -++ TRUE, /* pc_relative */ -++ 0, /* bitpos */ -++ complain_overflow_signed,/* complain_on_overflow */ -++ bfd_elf_generic_reloc, /* special_function */ -++ "R_NDS32_25_PLTREL", /* name */ -++ FALSE, /* partial_inplace */ -++ 0xffffff, /* src_mask */ -++ 0xffffff, /* dst_mask */ -++ TRUE), /* pcrel_offset */ -+ -+ /* This is used only by the dynamic linker. The symbol should exist -+ both in the object being run and in some shared library. The -+ dynamic linker copies the data addressed by the symbol from the -+ shared library into the object, because the object being -+ run has to have the data at some particular address. */ -+- HOWTO (R_NDS32_COPY, /* type */ -+- 0, /* rightshift */ -+- 2, /* size (0 = byte, 1 = short, 2 = long) */ -+- 32, /* bitsize */ -+- FALSE, /* pc_relative */ -+- 0, /* bitpos */ -+- complain_overflow_bitfield, /* complain_on_overflow */ -+- bfd_elf_generic_reloc, /* special_function */ -+- "R_NDS32_COPY", /* name */ -+- FALSE, /* partial_inplace */ -+- 0xffffffff, /* src_mask */ -+- 0xffffffff, /* dst_mask */ -+- FALSE), /* pcrel_offset */ -++ HOWTO2 (R_NDS32_COPY, /* type */ -++ 0, /* rightshift */ -++ 2, /* size (0 = byte, 1 = short, 2 = long) */ -++ 32, /* bitsize */ -++ FALSE, /* pc_relative */ -++ 0, /* bitpos */ -++ complain_overflow_bitfield,/* complain_on_overflow */ -++ bfd_elf_generic_reloc, /* special_function */ -++ "R_NDS32_COPY", /* name */ -++ FALSE, /* partial_inplace */ -++ 0xffffffff, /* src_mask */ -++ 0xffffffff, /* dst_mask */ -++ FALSE), /* pcrel_offset */ -+ -+ /* Like R_NDS32_20, but used when setting global offset table -+ entries. */ -+- HOWTO (R_NDS32_GLOB_DAT, /* type */ -+- 0, /* rightshift */ -+- 2, /* size (0 = byte, 1 = short, 2 = long) */ -+- 32, /* bitsize */ -+- FALSE, /* pc_relative */ -+- 0, /* bitpos */ -+- complain_overflow_bitfield, /* complain_on_overflow */ -+- bfd_elf_generic_reloc, /* special_function */ -+- "R_NDS32_GLOB_DAT", /* name */ -+- FALSE, /* partial_inplace */ -+- 0xffffffff, /* src_mask */ -+- 0xffffffff, /* dst_mask */ -+- FALSE), /* pcrel_offset */ -++ HOWTO2 (R_NDS32_GLOB_DAT, /* type */ -++ 0, /* rightshift */ -++ 2, /* size (0 = byte, 1 = short, 2 = long) */ -++ 32, /* bitsize */ -++ FALSE, /* pc_relative */ -++ 0, /* bitpos */ -++ complain_overflow_bitfield,/* complain_on_overflow */ -++ bfd_elf_generic_reloc, /* special_function */ -++ "R_NDS32_GLOB_DAT", /* name */ -++ FALSE, /* partial_inplace */ -++ 0xffffffff, /* src_mask */ -++ 0xffffffff, /* dst_mask */ -++ FALSE), /* pcrel_offset */ -+ -+ /* Marks a procedure linkage table entry for a symbol. */ -+- HOWTO (R_NDS32_JMP_SLOT, /* type */ -+- 0, /* rightshift */ -+- 2, /* size (0 = byte, 1 = short, 2 = long) */ -+- 32, /* bitsize */ -+- FALSE, /* pc_relative */ -+- 0, /* bitpos */ -+- complain_overflow_bitfield, /* complain_on_overflow */ -+- bfd_elf_generic_reloc, /* special_function */ -+- "R_NDS32_JMP_SLOT", /* name */ -+- FALSE, /* partial_inplace */ -+- 0xffffffff, /* src_mask */ -+- 0xffffffff, /* dst_mask */ -+- FALSE), /* pcrel_offset */ -++ HOWTO2 (R_NDS32_JMP_SLOT, /* type */ -++ 0, /* rightshift */ -++ 2, /* size (0 = byte, 1 = short, 2 = long) */ -++ 32, /* bitsize */ -++ FALSE, /* pc_relative */ -++ 0, /* bitpos */ -++ complain_overflow_bitfield,/* complain_on_overflow */ -++ bfd_elf_generic_reloc, /* special_function */ -++ "R_NDS32_JMP_SLOT", /* name */ -++ FALSE, /* partial_inplace */ -++ 0xffffffff, /* src_mask */ -++ 0xffffffff, /* dst_mask */ -++ FALSE), /* pcrel_offset */ -+ -+ /* Used only by the dynamic linker. When the object is run, this -+ longword is set to the load address of the object, plus the -+ addend. */ -+- HOWTO (R_NDS32_RELATIVE, /* type */ -+- 0, /* rightshift */ -+- 2, /* size (0 = byte, 1 = short, 2 = long) */ -+- 32, /* bitsize */ -+- FALSE, /* pc_relative */ -+- 0, /* bitpos */ -+- complain_overflow_bitfield, /* complain_on_overflow */ -+- bfd_elf_generic_reloc, /* special_function */ -+- "R_NDS32_RELATIVE", /* name */ -+- FALSE, /* partial_inplace */ -+- 0xffffffff, /* src_mask */ -+- 0xffffffff, /* dst_mask */ -+- FALSE), /* pcrel_offset */ -+- -+- HOWTO (R_NDS32_GOTOFF, /* type */ -+- 0, /* rightshift */ -+- 2, /* size (0 = byte, 1 = short, 2 = long) */ -+- 20, /* bitsize */ -+- FALSE, /* pc_relative */ -+- 0, /* bitpos */ -+- complain_overflow_signed, /* complain_on_overflow */ -+- bfd_elf_generic_reloc, /* special_function */ -+- "R_NDS32_GOTOFF", /* name */ -+- FALSE, /* partial_inplace */ -+- 0xfffff, /* src_mask */ -+- 0xfffff, /* dst_mask */ -+- FALSE), /* pcrel_offset */ -++ HOWTO2 (R_NDS32_RELATIVE, /* type */ -++ 0, /* rightshift */ -++ 2, /* size (0 = byte, 1 = short, 2 = long) */ -++ 32, /* bitsize */ -++ FALSE, /* pc_relative */ -++ 0, /* bitpos */ -++ complain_overflow_bitfield,/* complain_on_overflow */ -++ bfd_elf_generic_reloc, /* special_function */ -++ "R_NDS32_RELATIVE", /* name */ -++ FALSE, /* partial_inplace */ -++ 0xffffffff, /* src_mask */ -++ 0xffffffff, /* dst_mask */ -++ FALSE), /* pcrel_offset */ -++ -++ HOWTO2 (R_NDS32_GOTOFF, /* type */ -++ 0, /* rightshift */ -++ 2, /* size (0 = byte, 1 = short, 2 = long) */ -++ 20, /* bitsize */ -++ FALSE, /* pc_relative */ -++ 0, /* bitpos */ -++ complain_overflow_signed,/* complain_on_overflow */ -++ bfd_elf_generic_reloc, /* special_function */ -++ "R_NDS32_GOTOFF", /* name */ -++ FALSE, /* partial_inplace */ -++ 0xfffff, /* src_mask */ -++ 0xfffff, /* dst_mask */ -++ FALSE), /* pcrel_offset */ -+ -+ /* An PC Relative 20-bit relocation used when setting PIC offset -+ table register. */ -+- HOWTO (R_NDS32_GOTPC20, /* type */ -+- 0, /* rightshift */ -+- 2, /* size (0 = byte, 1 = short, 2 = long) */ -+- 20, /* bitsize */ -+- TRUE, /* pc_relative */ -+- 0, /* bitpos */ -+- complain_overflow_signed, /* complain_on_overflow */ -+- bfd_elf_generic_reloc, /* special_function */ -+- "R_NDS32_GOTPC20", /* name */ -+- FALSE, /* partial_inplace */ -+- 0xfffff, /* src_mask */ -+- 0xfffff, /* dst_mask */ -+- TRUE), /* pcrel_offset */ -++ HOWTO2 (R_NDS32_GOTPC20, /* type */ -++ 0, /* rightshift */ -++ 2, /* size (0 = byte, 1 = short, 2 = long) */ -++ 20, /* bitsize */ -++ TRUE, /* pc_relative */ -++ 0, /* bitpos */ -++ complain_overflow_signed,/* complain_on_overflow */ -++ bfd_elf_generic_reloc, /* special_function */ -++ "R_NDS32_GOTPC20", /* name */ -++ FALSE, /* partial_inplace */ -++ 0xfffff, /* src_mask */ -++ 0xfffff, /* dst_mask */ -++ TRUE), /* pcrel_offset */ -+ -+ /* Like R_NDS32_HI20, but referring to the GOT table entry for -+ the symbol. */ -+- HOWTO (R_NDS32_GOT_HI20, /* type */ -+- 12, /* rightshift */ -+- 2, /* size (0 = byte, 1 = short, 2 = long) */ -+- 20, /* bitsize */ -+- FALSE, /* pc_relative */ -+- 0, /* bitpos */ -+- complain_overflow_dont,/* complain_on_overflow */ -+- bfd_elf_generic_reloc, /* special_function */ -+- "R_NDS32_GOT_HI20", /* name */ -+- FALSE, /* partial_inplace */ -+- 0x000fffff, /* src_mask */ -+- 0x000fffff, /* dst_mask */ -+- FALSE), /* pcrel_offset */ -+- HOWTO (R_NDS32_GOT_LO12, /* type */ -+- 0, /* rightshift */ -+- 2, /* size (0 = byte, 1 = short, 2 = long) */ -+- 12, /* bitsize */ -+- FALSE, /* pc_relative */ -+- 0, /* bitpos */ -+- complain_overflow_dont,/* complain_on_overflow */ -+- bfd_elf_generic_reloc, /* special_function */ -+- "R_NDS32_GOT_LO12", /* name */ -+- FALSE, /* partial_inplace */ -+- 0x00000fff, /* src_mask */ -+- 0x00000fff, /* dst_mask */ -+- FALSE), /* pcrel_offset */ -++ HOWTO2 (R_NDS32_GOT_HI20, /* type */ -++ 12, /* rightshift */ -++ 2, /* size (0 = byte, 1 = short, 2 = long) */ -++ 20, /* bitsize */ -++ FALSE, /* pc_relative */ -++ 0, /* bitpos */ -++ complain_overflow_dont,/* complain_on_overflow */ -++ bfd_elf_generic_reloc, /* special_function */ -++ "R_NDS32_GOT_HI20", /* name */ -++ FALSE, /* partial_inplace */ -++ 0x000fffff, /* src_mask */ -++ 0x000fffff, /* dst_mask */ -++ FALSE), /* pcrel_offset */ -++ HOWTO2 (R_NDS32_GOT_LO12, /* type */ -++ 0, /* rightshift */ -++ 2, /* size (0 = byte, 1 = short, 2 = long) */ -++ 12, /* bitsize */ -++ FALSE, /* pc_relative */ -++ 0, /* bitpos */ -++ complain_overflow_dont,/* complain_on_overflow */ -++ bfd_elf_generic_reloc, /* special_function */ -++ "R_NDS32_GOT_LO12", /* name */ -++ FALSE, /* partial_inplace */ -++ 0x00000fff, /* src_mask */ -++ 0x00000fff, /* dst_mask */ -++ FALSE), /* pcrel_offset */ -+ -+ /* An PC Relative relocation used when setting PIC offset table register. -+ Like R_NDS32_HI20, but referring to the GOT table entry for -+ the symbol. */ -+- HOWTO (R_NDS32_GOTPC_HI20, /* type */ -+- 12, /* rightshift */ -+- 2, /* size (0 = byte, 1 = short, 2 = long) */ -+- 20, /* bitsize */ -+- FALSE, /* pc_relative */ -+- 0, /* bitpos */ -+- complain_overflow_dont,/* complain_on_overflow */ -+- bfd_elf_generic_reloc, /* special_function */ -+- "R_NDS32_GOTPC_HI20", /* name */ -+- FALSE, /* partial_inplace */ -+- 0x000fffff, /* src_mask */ -+- 0x000fffff, /* dst_mask */ -+- TRUE), /* pcrel_offset */ -+- HOWTO (R_NDS32_GOTPC_LO12, /* type */ -+- 0, /* rightshift */ -+- 2, /* size (0 = byte, 1 = short, 2 = long) */ -+- 12, /* bitsize */ -+- FALSE, /* pc_relative */ -+- 0, /* bitpos */ -+- complain_overflow_dont, /* complain_on_overflow */ -+- bfd_elf_generic_reloc, /* special_function */ -+- "R_NDS32_GOTPC_LO12", /* name */ -+- FALSE, /* partial_inplace */ -+- 0x00000fff, /* src_mask */ -+- 0x00000fff, /* dst_mask */ -+- TRUE), /* pcrel_offset */ -+- -+- HOWTO (R_NDS32_GOTOFF_HI20, /* type */ -+- 12, /* rightshift */ -+- 2, /* size (0 = byte, 1 = short, 2 = long) */ -+- 20, /* bitsize */ -+- FALSE, /* pc_relative */ -+- 0, /* bitpos */ -+- complain_overflow_dont,/* complain_on_overflow */ -+- bfd_elf_generic_reloc, /* special_function */ -+- "R_NDS32_GOTOFF_HI20", /* name */ -+- FALSE, /* partial_inplace */ -+- 0x000fffff, /* src_mask */ -+- 0x000fffff, /* dst_mask */ -+- FALSE), /* pcrel_offset */ -+- HOWTO (R_NDS32_GOTOFF_LO12, /* type */ -+- 0, /* rightshift */ -+- 2, /* size (0 = byte, 1 = short, 2 = long) */ -+- 12, /* bitsize */ -+- FALSE, /* pc_relative */ -+- 0, /* bitpos */ -+- complain_overflow_dont,/* complain_on_overflow */ -+- bfd_elf_generic_reloc, /* special_function */ -+- "R_NDS32_GOTOFF_LO12", /* name */ -+- FALSE, /* partial_inplace */ -+- 0x00000fff, /* src_mask */ -+- 0x00000fff, /* dst_mask */ -+- FALSE), /* pcrel_offset */ -++ HOWTO2 (R_NDS32_GOTPC_HI20, /* type */ -++ 12, /* rightshift */ -++ 2, /* size (0 = byte, 1 = short, 2 = long) */ -++ 20, /* bitsize */ -++ FALSE, /* pc_relative */ -++ 0, /* bitpos */ -++ complain_overflow_dont,/* complain_on_overflow */ -++ bfd_elf_generic_reloc, /* special_function */ -++ "R_NDS32_GOTPC_HI20", /* name */ -++ FALSE, /* partial_inplace */ -++ 0x000fffff, /* src_mask */ -++ 0x000fffff, /* dst_mask */ -++ TRUE), /* pcrel_offset */ -++ HOWTO2 (R_NDS32_GOTPC_LO12, /* type */ -++ 0, /* rightshift */ -++ 2, /* size (0 = byte, 1 = short, 2 = long) */ -++ 12, /* bitsize */ -++ FALSE, /* pc_relative */ -++ 0, /* bitpos */ -++ complain_overflow_dont,/* complain_on_overflow */ -++ bfd_elf_generic_reloc, /* special_function */ -++ "R_NDS32_GOTPC_LO12", /* name */ -++ FALSE, /* partial_inplace */ -++ 0x00000fff, /* src_mask */ -++ 0x00000fff, /* dst_mask */ -++ TRUE), /* pcrel_offset */ -++ -++ HOWTO2 (R_NDS32_GOTOFF_HI20, /* type */ -++ 12, /* rightshift */ -++ 2, /* size (0 = byte, 1 = short, 2 = long) */ -++ 20, /* bitsize */ -++ FALSE, /* pc_relative */ -++ 0, /* bitpos */ -++ complain_overflow_dont,/* complain_on_overflow */ -++ bfd_elf_generic_reloc, /* special_function */ -++ "R_NDS32_GOTOFF_HI20", /* name */ -++ FALSE, /* partial_inplace */ -++ 0x000fffff, /* src_mask */ -++ 0x000fffff, /* dst_mask */ -++ FALSE), /* pcrel_offset */ -++ HOWTO2 (R_NDS32_GOTOFF_LO12, /* type */ -++ 0, /* rightshift */ -++ 2, /* size (0 = byte, 1 = short, 2 = long) */ -++ 12, /* bitsize */ -++ FALSE, /* pc_relative */ -++ 0, /* bitpos */ -++ complain_overflow_dont,/* complain_on_overflow */ -++ bfd_elf_generic_reloc, /* special_function */ -++ "R_NDS32_GOTOFF_LO12", /* name */ -++ FALSE, /* partial_inplace */ -++ 0x00000fff, /* src_mask */ -++ 0x00000fff, /* dst_mask */ -++ FALSE), /* pcrel_offset */ -+ -+ /* Alignment hint for relaxable instruction. This is used with -+ R_NDS32_LABEL as a pair. Relax this instruction from 4 bytes to 2 -+ in order to make next label aligned on word boundary. */ -+- HOWTO (R_NDS32_INSN16, /* type */ -+- 0, /* rightshift */ -+- 2, /* size (0 = byte, 1 = short, 2 = long) */ -+- 32, /* bitsize */ -+- FALSE, /* pc_relative */ -+- 0, /* bitpos */ -+- complain_overflow_dont,/* complain_on_overflow */ -+- nds32_elf_ignore_reloc,/* special_function */ -+- "R_NDS32_INSN16", /* name */ -+- FALSE, /* partial_inplace */ -+- 0x00000fff, /* src_mask */ -+- 0x00000fff, /* dst_mask */ -+- FALSE), /* pcrel_offset */ -++ HOWTO2 (R_NDS32_INSN16, /* type */ -++ 0, /* rightshift */ -++ 2, /* size (0 = byte, 1 = short, 2 = long) */ -++ 32, /* bitsize */ -++ FALSE, /* pc_relative */ -++ 0, /* bitpos */ -++ complain_overflow_dont,/* complain_on_overflow */ -++ nds32_elf_ignore_reloc,/* special_function */ -++ "R_NDS32_INSN16", /* name */ -++ FALSE, /* partial_inplace */ -++ 0x00000fff, /* src_mask */ -++ 0x00000fff, /* dst_mask */ -++ FALSE), /* pcrel_offset */ -+ -+ /* Alignment hint for label. */ -+- HOWTO (R_NDS32_LABEL, /* type */ -+- 0, /* rightshift */ -+- 2, /* size (0 = byte, 1 = short, 2 = long) */ -+- 32, /* bitsize */ -+- FALSE, /* pc_relative */ -+- 0, /* bitpos */ -+- complain_overflow_dont,/* complain_on_overflow */ -+- nds32_elf_ignore_reloc,/* special_function */ -+- "R_NDS32_LABEL", /* name */ -+- FALSE, /* partial_inplace */ -+- 0xffffffff, /* src_mask */ -+- 0xffffffff, /* dst_mask */ -+- FALSE), /* pcrel_offset */ -++ HOWTO2 (R_NDS32_LABEL, /* type */ -++ 0, /* rightshift */ -++ 2, /* size (0 = byte, 1 = short, 2 = long) */ -++ 32, /* bitsize */ -++ FALSE, /* pc_relative */ -++ 0, /* bitpos */ -++ complain_overflow_dont,/* complain_on_overflow */ -++ nds32_elf_ignore_reloc,/* special_function */ -++ "R_NDS32_LABEL", /* name */ -++ FALSE, /* partial_inplace */ -++ 0xffffffff, /* src_mask */ -++ 0xffffffff, /* dst_mask */ -++ FALSE), /* pcrel_offset */ -+ -+ /* Relax hint for unconditional call sequence */ -+- HOWTO (R_NDS32_LONGCALL1, /* type */ -+- 0, /* rightshift */ -+- 2, /* size (0 = byte, 1 = short, 2 = long) */ -+- 32, /* bitsize */ -+- FALSE, /* pc_relative */ -+- 0, /* bitpos */ -+- complain_overflow_dont,/* complain_on_overflow */ -+- nds32_elf_ignore_reloc,/* special_function */ -+- "R_NDS32_LONGCALL1", /* name */ -+- FALSE, /* partial_inplace */ -+- 0xffffffff, /* src_mask */ -+- 0xffffffff, /* dst_mask */ -+- FALSE), /* pcrel_offset */ -++ HOWTO2 (R_NDS32_LONGCALL1, /* type */ -++ 0, /* rightshift */ -++ 2, /* size (0 = byte, 1 = short, 2 = long) */ -++ 32, /* bitsize */ -++ FALSE, /* pc_relative */ -++ 0, /* bitpos */ -++ complain_overflow_dont,/* complain_on_overflow */ -++ nds32_elf_ignore_reloc,/* special_function */ -++ "R_NDS32_LONGCALL1", /* name */ -++ FALSE, /* partial_inplace */ -++ 0xffffffff, /* src_mask */ -++ 0xffffffff, /* dst_mask */ -++ FALSE), /* pcrel_offset */ -+ -+ /* Relax hint for conditional call sequence. */ -+- HOWTO (R_NDS32_LONGCALL2, /* type */ -+- 0, /* rightshift */ -+- 2, /* size (0 = byte, 1 = short, 2 = long) */ -+- 32, /* bitsize */ -+- FALSE, /* pc_relative */ -+- 0, /* bitpos */ -+- complain_overflow_dont,/* complain_on_overflow */ -+- nds32_elf_ignore_reloc,/* special_function */ -+- "R_NDS32_LONGCALL2", /* name */ -+- FALSE, /* partial_inplace */ -+- 0xffffffff, /* src_mask */ -+- 0xffffffff, /* dst_mask */ -+- FALSE), /* pcrel_offset */ -++ HOWTO2 (R_NDS32_LONGCALL2, /* type */ -++ 0, /* rightshift */ -++ 2, /* size (0 = byte, 1 = short, 2 = long) */ -++ 32, /* bitsize */ -++ FALSE, /* pc_relative */ -++ 0, /* bitpos */ -++ complain_overflow_dont,/* complain_on_overflow */ -++ nds32_elf_ignore_reloc,/* special_function */ -++ "R_NDS32_LONGCALL2", /* name */ -++ FALSE, /* partial_inplace */ -++ 0xffffffff, /* src_mask */ -++ 0xffffffff, /* dst_mask */ -++ FALSE), /* pcrel_offset */ -+ -+ /* Relax hint for conditional call sequence. */ -+- HOWTO (R_NDS32_LONGCALL3, /* type */ -+- 0, /* rightshift */ -+- 2, /* size (0 = byte, 1 = short, 2 = long) */ -+- 32, /* bitsize */ -+- FALSE, /* pc_relative */ -+- 0, /* bitpos */ -+- complain_overflow_dont,/* complain_on_overflow */ -+- nds32_elf_ignore_reloc,/* special_function */ -+- "R_NDS32_LONGCALL3", /* name */ -+- FALSE, /* partial_inplace */ -+- 0xffffffff, /* src_mask */ -+- 0xffffffff, /* dst_mask */ -+- FALSE), /* pcrel_offset */ -++ HOWTO2 (R_NDS32_LONGCALL3, /* type */ -++ 0, /* rightshift */ -++ 2, /* size (0 = byte, 1 = short, 2 = long) */ -++ 32, /* bitsize */ -++ FALSE, /* pc_relative */ -++ 0, /* bitpos */ -++ complain_overflow_dont,/* complain_on_overflow */ -++ nds32_elf_ignore_reloc,/* special_function */ -++ "R_NDS32_LONGCALL3", /* name */ -++ FALSE, /* partial_inplace */ -++ 0xffffffff, /* src_mask */ -++ 0xffffffff, /* dst_mask */ -++ FALSE), /* pcrel_offset */ -+ -+ /* Relax hint for unconditional branch sequence. */ -+- HOWTO (R_NDS32_LONGJUMP1, /* type */ -+- 0, /* rightshift */ -+- 2, /* size (0 = byte, 1 = short, 2 = long) */ -+- 32, /* bitsize */ -+- FALSE, /* pc_relative */ -+- 0, /* bitpos */ -+- complain_overflow_dont,/* complain_on_overflow */ -+- nds32_elf_ignore_reloc,/* special_function */ -+- "R_NDS32_LONGJUMP1", /* name */ -+- FALSE, /* partial_inplace */ -+- 0xffffffff, /* src_mask */ -+- 0xffffffff, /* dst_mask */ -+- FALSE), /* pcrel_offset */ -++ HOWTO2 (R_NDS32_LONGJUMP1, /* type */ -++ 0, /* rightshift */ -++ 2, /* size (0 = byte, 1 = short, 2 = long) */ -++ 32, /* bitsize */ -++ FALSE, /* pc_relative */ -++ 0, /* bitpos */ -++ complain_overflow_dont,/* complain_on_overflow */ -++ nds32_elf_ignore_reloc,/* special_function */ -++ "R_NDS32_LONGJUMP1", /* name */ -++ FALSE, /* partial_inplace */ -++ 0xffffffff, /* src_mask */ -++ 0xffffffff, /* dst_mask */ -++ FALSE), /* pcrel_offset */ -+ -+ /* Relax hint for conditional branch sequence. */ -+- HOWTO (R_NDS32_LONGJUMP2, /* type */ -+- 0, /* rightshift */ -+- 2, /* size (0 = byte, 1 = short, 2 = long) */ -+- 32, /* bitsize */ -+- FALSE, /* pc_relative */ -+- 0, /* bitpos */ -+- complain_overflow_dont,/* complain_on_overflow */ -+- nds32_elf_ignore_reloc,/* special_function */ -+- "R_NDS32_LONGJUMP2", /* name */ -+- FALSE, /* partial_inplace */ -+- 0xffffffff, /* src_mask */ -+- 0xffffffff, /* dst_mask */ -+- FALSE), /* pcrel_offset */ -++ HOWTO2 (R_NDS32_LONGJUMP2, /* type */ -++ 0, /* rightshift */ -++ 2, /* size (0 = byte, 1 = short, 2 = long) */ -++ 32, /* bitsize */ -++ FALSE, /* pc_relative */ -++ 0, /* bitpos */ -++ complain_overflow_dont,/* complain_on_overflow */ -++ nds32_elf_ignore_reloc,/* special_function */ -++ "R_NDS32_LONGJUMP2", /* name */ -++ FALSE, /* partial_inplace */ -++ 0xffffffff, /* src_mask */ -++ 0xffffffff, /* dst_mask */ -++ FALSE), /* pcrel_offset */ -+ -+ /* Relax hint for conditional branch sequence. */ -+- HOWTO (R_NDS32_LONGJUMP3, /* type */ -+- 0, /* rightshift */ -+- 2, /* size (0 = byte, 1 = short, 2 = long) */ -+- 32, /* bitsize */ -+- FALSE, /* pc_relative */ -+- 0, /* bitpos */ -+- complain_overflow_dont,/* complain_on_overflow */ -+- nds32_elf_ignore_reloc,/* special_function */ -+- "R_NDS32_LONGJUMP3", /* name */ -+- FALSE, /* partial_inplace */ -+- 0xffffffff, /* src_mask */ -+- 0xffffffff, /* dst_mask */ -+- FALSE), /* pcrel_offset */ -++ HOWTO2 (R_NDS32_LONGJUMP3, /* type */ -++ 0, /* rightshift */ -++ 2, /* size (0 = byte, 1 = short, 2 = long) */ -++ 32, /* bitsize */ -++ FALSE, /* pc_relative */ -++ 0, /* bitpos */ -++ complain_overflow_dont,/* complain_on_overflow */ -++ nds32_elf_ignore_reloc,/* special_function */ -++ "R_NDS32_LONGJUMP3", /* name */ -++ FALSE, /* partial_inplace */ -++ 0xffffffff, /* src_mask */ -++ 0xffffffff, /* dst_mask */ -++ FALSE), /* pcrel_offset */ -+ -+ /* Relax hint for load/store sequence. */ -+- HOWTO (R_NDS32_LOADSTORE, /* type */ -+- 0, /* rightshift */ -+- 2, /* size (0 = byte, 1 = short, 2 = long) */ -+- 32, /* bitsize */ -+- FALSE, /* pc_relative */ -+- 0, /* bitpos */ -+- complain_overflow_dont,/* complain_on_overflow */ -+- nds32_elf_ignore_reloc,/* special_function */ -+- "R_NDS32_LOADSTORE", /* name */ -+- FALSE, /* partial_inplace */ -+- 0xffffffff, /* src_mask */ -+- 0xffffffff, /* dst_mask */ -+- FALSE), /* pcrel_offset */ -++ HOWTO2 (R_NDS32_LOADSTORE, /* type */ -++ 0, /* rightshift */ -++ 2, /* size (0 = byte, 1 = short, 2 = long) */ -++ 32, /* bitsize */ -++ FALSE, /* pc_relative */ -++ 0, /* bitpos */ -++ complain_overflow_dont,/* complain_on_overflow */ -++ nds32_elf_ignore_reloc,/* special_function */ -++ "R_NDS32_LOADSTORE", /* name */ -++ FALSE, /* partial_inplace */ -++ 0xffffffff, /* src_mask */ -++ 0xffffffff, /* dst_mask */ -++ FALSE), /* pcrel_offset */ -+ -+ /* Relax hint for load/store sequence. */ -+- HOWTO (R_NDS32_9_FIXED_RELA, /* type */ -+- 0, /* rightshift */ -+- 1, /* size (0 = byte, 1 = short, 2 = long) */ -+- 16, /* bitsize */ -+- FALSE, /* pc_relative */ -+- 0, /* bitpos */ -+- complain_overflow_dont,/* complain_on_overflow */ -+- nds32_elf_ignore_reloc,/* special_function */ -+- "R_NDS32_9_FIXED_RELA",/* name */ -+- FALSE, /* partial_inplace */ -+- 0x000000ff, /* src_mask */ -+- 0x000000ff, /* dst_mask */ -+- FALSE), /* pcrel_offset */ -++ HOWTO2 (R_NDS32_9_FIXED_RELA, /* type */ -++ 0, /* rightshift */ -++ 1, /* size (0 = byte, 1 = short, 2 = long) */ -++ 16, /* bitsize */ -++ FALSE, /* pc_relative */ -++ 0, /* bitpos */ -++ complain_overflow_dont,/* complain_on_overflow */ -++ nds32_elf_ignore_reloc,/* special_function */ -++ "R_NDS32_9_FIXED_RELA",/* name */ -++ FALSE, /* partial_inplace */ -++ 0x000000ff, /* src_mask */ -++ 0x000000ff, /* dst_mask */ -++ FALSE), /* pcrel_offset */ -+ -+ /* Relax hint for load/store sequence. */ -+- HOWTO (R_NDS32_15_FIXED_RELA, /* type */ -+- 0, /* rightshift */ -+- 2, /* size (0 = byte, 1 = short, 2 = long) */ -+- 32, /* bitsize */ -+- FALSE, /* pc_relative */ -+- 0, /* bitpos */ -+- complain_overflow_dont,/* complain_on_overflow */ -+- nds32_elf_ignore_reloc,/* special_function */ -+- "R_NDS32_15_FIXED_RELA", /* name */ -+- FALSE, /* partial_inplace */ -+- 0x00003fff, /* src_mask */ -+- 0x00003fff, /* dst_mask */ -+- FALSE), /* pcrel_offset */ -++ HOWTO2 (R_NDS32_15_FIXED_RELA,/* type */ -++ 0, /* rightshift */ -++ 2, /* size (0 = byte, 1 = short, 2 = long) */ -++ 32, /* bitsize */ -++ FALSE, /* pc_relative */ -++ 0, /* bitpos */ -++ complain_overflow_dont,/* complain_on_overflow */ -++ nds32_elf_ignore_reloc,/* special_function */ -++ "R_NDS32_15_FIXED_RELA",/* name */ -++ FALSE, /* partial_inplace */ -++ 0x00003fff, /* src_mask */ -++ 0x00003fff, /* dst_mask */ -++ FALSE), /* pcrel_offset */ -+ -+ /* Relax hint for load/store sequence. */ -+- HOWTO (R_NDS32_17_FIXED_RELA, /* type */ -+- 0, /* rightshift */ -+- 2, /* size (0 = byte, 1 = short, 2 = long) */ -+- 32, /* bitsize */ -+- FALSE, /* pc_relative */ -+- 0, /* bitpos */ -+- complain_overflow_dont,/* complain_on_overflow */ -+- nds32_elf_ignore_reloc,/* special_function */ -+- "R_NDS32_17_FIXED_RELA", /* name */ -+- FALSE, /* partial_inplace */ -+- 0x0000ffff, /* src_mask */ -+- 0x0000ffff, /* dst_mask */ -+- FALSE), /* pcrel_offset */ -++ HOWTO2 (R_NDS32_17_FIXED_RELA,/* type */ -++ 0, /* rightshift */ -++ 2, /* size (0 = byte, 1 = short, 2 = long) */ -++ 32, /* bitsize */ -++ FALSE, /* pc_relative */ -++ 0, /* bitpos */ -++ complain_overflow_dont,/* complain_on_overflow */ -++ nds32_elf_ignore_reloc,/* special_function */ -++ "R_NDS32_17_FIXED_RELA",/* name */ -++ FALSE, /* partial_inplace */ -++ 0x0000ffff, /* src_mask */ -++ 0x0000ffff, /* dst_mask */ -++ FALSE), /* pcrel_offset */ -+ -+ /* Relax hint for load/store sequence. */ -+- HOWTO (R_NDS32_25_FIXED_RELA, /* type */ -+- 0, /* rightshift */ -+- 2, /* size (0 = byte, 1 = short, 2 = long) */ -+- 32, /* bitsize */ -+- FALSE, /* pc_relative */ -+- 0, /* bitpos */ -+- complain_overflow_dont,/* complain_on_overflow */ -+- nds32_elf_ignore_reloc,/* special_function */ -+- "R_NDS32_25_FIXED_RELA", /* name */ -+- FALSE, /* partial_inplace */ -+- 0x00ffffff, /* src_mask */ -+- 0x00ffffff, /* dst_mask */ -+- FALSE), /* pcrel_offset */ -++ HOWTO2 (R_NDS32_25_FIXED_RELA,/* type */ -++ 0, /* rightshift */ -++ 2, /* size (0 = byte, 1 = short, 2 = long) */ -++ 32, /* bitsize */ -++ FALSE, /* pc_relative */ -++ 0, /* bitpos */ -++ complain_overflow_dont,/* complain_on_overflow */ -++ nds32_elf_ignore_reloc,/* special_function */ -++ "R_NDS32_25_FIXED_RELA",/* name */ -++ FALSE, /* partial_inplace */ -++ 0x00ffffff, /* src_mask */ -++ 0x00ffffff, /* dst_mask */ -++ FALSE), /* pcrel_offset */ -+ -+ /* High 20 bits of PLT symbol offset relative to PC. */ -+- HOWTO (R_NDS32_PLTREL_HI20, /* type */ -+- 12, /* rightshift */ -+- 2, /* size (0 = byte, 1 = short, 2 = long) */ -+- 20, /* bitsize */ -+- FALSE, /* pc_relative */ -+- 0, /* bitpos */ -+- complain_overflow_dont,/* complain_on_overflow */ -+- bfd_elf_generic_reloc, /* special_function */ -+- "R_NDS32_PLTREL_HI20", /* name */ -+- FALSE, /* partial_inplace */ -+- 0x000fffff, /* src_mask */ -+- 0x000fffff, /* dst_mask */ -+- FALSE), /* pcrel_offset */ -++ HOWTO2 (R_NDS32_PLTREL_HI20, /* type */ -++ 12, /* rightshift */ -++ 2, /* size (0 = byte, 1 = short, 2 = long) */ -++ 20, /* bitsize */ -++ FALSE, /* pc_relative */ -++ 0, /* bitpos */ -++ complain_overflow_dont,/* complain_on_overflow */ -++ bfd_elf_generic_reloc, /* special_function */ -++ "R_NDS32_PLTREL_HI20", /* name */ -++ FALSE, /* partial_inplace */ -++ 0x000fffff, /* src_mask */ -++ 0x000fffff, /* dst_mask */ -++ FALSE), /* pcrel_offset */ -+ -+ /* Low 12 bits of PLT symbol offset relative to PC. */ -+- HOWTO (R_NDS32_PLTREL_LO12, /* type */ -+- 0, /* rightshift */ -+- 2, /* size (0 = byte, 1 = short, 2 = long) */ -+- 12, /* bitsize */ -+- FALSE, /* pc_relative */ -+- 0, /* bitpos */ -+- complain_overflow_dont,/* complain_on_overflow */ -+- bfd_elf_generic_reloc, /* special_function */ -+- "R_NDS32_PLTREL_LO12", /* name */ -+- FALSE, /* partial_inplace */ -+- 0x00000fff, /* src_mask */ -+- 0x00000fff, /* dst_mask */ -+- FALSE), /* pcrel_offset */ -++ HOWTO2 (R_NDS32_PLTREL_LO12, /* type */ -++ 0, /* rightshift */ -++ 2, /* size (0 = byte, 1 = short, 2 = long) */ -++ 12, /* bitsize */ -++ FALSE, /* pc_relative */ -++ 0, /* bitpos */ -++ complain_overflow_dont,/* complain_on_overflow */ -++ bfd_elf_generic_reloc, /* special_function */ -++ "R_NDS32_PLTREL_LO12", /* name */ -++ FALSE, /* partial_inplace */ -++ 0x00000fff, /* src_mask */ -++ 0x00000fff, /* dst_mask */ -++ FALSE), /* pcrel_offset */ -+ -+ /* High 20 bits of PLT symbol offset relative to GOT (GP). */ -+- HOWTO (R_NDS32_PLT_GOTREL_HI20, /* type */ -+- 12, /* rightshift */ -+- 2, /* size (0 = byte, 1 = short, 2 = long) */ -+- 20, /* bitsize */ -+- FALSE, /* pc_relative */ -+- 0, /* bitpos */ -+- complain_overflow_dont,/* complain_on_overflow */ -+- bfd_elf_generic_reloc, /* special_function */ -+- "R_NDS32_PLT_GOTREL_HI20", /* name */ -+- FALSE, /* partial_inplace */ -+- 0x000fffff, /* src_mask */ -+- 0x000fffff, /* dst_mask */ -+- FALSE), /* pcrel_offset */ -++ HOWTO2 (R_NDS32_PLT_GOTREL_HI20, /* type */ -++ 12, /* rightshift */ -++ 2, /* size (0 = byte, 1 = short, 2 = long) */ -++ 20, /* bitsize */ -++ FALSE, /* pc_relative */ -++ 0, /* bitpos */ -++ complain_overflow_dont,/* complain_on_overflow */ -++ bfd_elf_generic_reloc, /* special_function */ -++ "R_NDS32_PLT_GOTREL_HI20",/* name */ -++ FALSE, /* partial_inplace */ -++ 0x000fffff, /* src_mask */ -++ 0x000fffff, /* dst_mask */ -++ FALSE), /* pcrel_offset */ -+ -+ /* Low 12 bits of PLT symbol offset relative to GOT (GP). */ -+- HOWTO (R_NDS32_PLT_GOTREL_LO12, /* type */ -+- 0, /* rightshift */ -+- 2, /* size (0 = byte, 1 = short, 2 = long) */ -+- 12, /* bitsize */ -+- FALSE, /* pc_relative */ -+- 0, /* bitpos */ -+- complain_overflow_dont,/* complain_on_overflow */ -+- bfd_elf_generic_reloc, /* special_function */ -+- "R_NDS32_PLT_GOTREL_LO12", /* name */ -+- FALSE, /* partial_inplace */ -+- 0x00000fff, /* src_mask */ -+- 0x00000fff, /* dst_mask */ -+- FALSE), /* pcrel_offset */ -++ HOWTO2 (R_NDS32_PLT_GOTREL_LO12,/* type */ -++ 0, /* rightshift */ -++ 2, /* size (0 = byte, 1 = short, 2 = long) */ -++ 12, /* bitsize */ -++ FALSE, /* pc_relative */ -++ 0, /* bitpos */ -++ complain_overflow_dont,/* complain_on_overflow */ -++ bfd_elf_generic_reloc, /* special_function */ -++ "R_NDS32_PLT_GOTREL_LO12",/* name */ -++ FALSE, /* partial_inplace */ -++ 0x00000fff, /* src_mask */ -++ 0x00000fff, /* dst_mask */ -++ FALSE), /* pcrel_offset */ -+ -+ /* Small data area 12 bits offset. */ -+- HOWTO (R_NDS32_SDA12S2_DP_RELA, /* type */ -+- 2, /* rightshift */ -+- 2, /* size (0 = byte, 1 = short, 2 = long) */ -+- 12, /* bitsize */ -+- FALSE, /* pc_relative */ -+- 0, /* bitpos */ -+- complain_overflow_signed, /* complain_on_overflow */ -+- bfd_elf_generic_reloc, /* special_function */ -+- "R_NDS32_SDA12S2_DP_RELA", /* name */ -+- FALSE, /* partial_inplace */ -+- 0x00000fff, /* src_mask */ -+- 0x00000fff, /* dst_mask */ -+- FALSE), /* pcrel_offset */ -++ HOWTO2 (R_NDS32_SDA12S2_DP_RELA,/* type */ -++ 2, /* rightshift */ -++ 2, /* size (0 = byte, 1 = short, 2 = long) */ -++ 12, /* bitsize */ -++ FALSE, /* pc_relative */ -++ 0, /* bitpos */ -++ complain_overflow_signed,/* complain_on_overflow */ -++ bfd_elf_generic_reloc, /* special_function */ -++ "R_NDS32_SDA12S2_DP_RELA",/* name */ -++ FALSE, /* partial_inplace */ -++ 0x00000fff, /* src_mask */ -++ 0x00000fff, /* dst_mask */ -++ FALSE), /* pcrel_offset */ -+ -+ /* Small data area 12 bits offset. */ -+- HOWTO (R_NDS32_SDA12S2_SP_RELA, /* type */ -+- 2, /* rightshift */ -+- 2, /* size (0 = byte, 1 = short, 2 = long) */ -+- 12, /* bitsize */ -+- FALSE, /* pc_relative */ -+- 0, /* bitpos */ -+- complain_overflow_signed, /* complain_on_overflow */ -+- bfd_elf_generic_reloc, /* special_function */ -+- "R_NDS32_SDA12S2_SP_RELA", /* name */ -+- FALSE, /* partial_inplace */ -+- 0x00000fff, /* src_mask */ -+- 0x00000fff, /* dst_mask */ -+- FALSE), /* pcrel_offset */ -++ HOWTO2 (R_NDS32_SDA12S2_SP_RELA,/* type */ -++ 2, /* rightshift */ -++ 2, /* size (0 = byte, 1 = short, 2 = long) */ -++ 12, /* bitsize */ -++ FALSE, /* pc_relative */ -++ 0, /* bitpos */ -++ complain_overflow_signed,/* complain_on_overflow */ -++ bfd_elf_generic_reloc, /* special_function */ -++ "R_NDS32_SDA12S2_SP_RELA",/* name */ -++ FALSE, /* partial_inplace */ -++ 0x00000fff, /* src_mask */ -++ 0x00000fff, /* dst_mask */ -++ FALSE), /* pcrel_offset */ -+ /* Lower 12 bits of address. */ -+ -+- HOWTO (R_NDS32_LO12S2_DP_RELA, /* type */ -+- 2, /* rightshift */ -+- 2, /* size (0 = byte, 1 = short, 2 = long) */ -+- 10, /* bitsize */ -+- FALSE, /* pc_relative */ -+- 0, /* bitpos */ -+- complain_overflow_dont,/* complain_on_overflow */ -+- bfd_elf_generic_reloc, /* special_function */ -+- "R_NDS32_LO12S2_DP_RELA", /* name */ -+- FALSE, /* partial_inplace */ -+- 0x000003ff, /* src_mask */ -+- 0x000003ff, /* dst_mask */ -+- FALSE), /* pcrel_offset */ -++ HOWTO2 (R_NDS32_LO12S2_DP_RELA, /* type */ -++ 2, /* rightshift */ -++ 2, /* size (0 = byte, 1 = short, 2 = long) */ -++ 10, /* bitsize */ -++ FALSE, /* pc_relative */ -++ 0, /* bitpos */ -++ complain_overflow_dont,/* complain_on_overflow */ -++ bfd_elf_generic_reloc, /* special_function */ -++ "R_NDS32_LO12S2_DP_RELA",/* name */ -++ FALSE, /* partial_inplace */ -++ 0x000003ff, /* src_mask */ -++ 0x000003ff, /* dst_mask */ -++ FALSE), /* pcrel_offset */ -+ -+ /* Lower 12 bits of address. */ -+- HOWTO (R_NDS32_LO12S2_SP_RELA,/* type */ -+- 2, /* rightshift */ -+- 2, /* size (0 = byte, 1 = short, 2 = long) */ -+- 10, /* bitsize */ -+- FALSE, /* pc_relative */ -+- 0, /* bitpos */ -+- complain_overflow_dont,/* complain_on_overflow */ -+- bfd_elf_generic_reloc, /* special_function */ -+- "R_NDS32_LO12S2_SP_RELA", /* name */ -+- FALSE, /* partial_inplace */ -+- 0x000003ff, /* src_mask */ -+- 0x000003ff, /* dst_mask */ -+- FALSE), /* pcrel_offset */ -++ HOWTO2 (R_NDS32_LO12S2_SP_RELA,/* type */ -++ 2, /* rightshift */ -++ 2, /* size (0 = byte, 1 = short, 2 = long) */ -++ 10, /* bitsize */ -++ FALSE, /* pc_relative */ -++ 0, /* bitpos */ -++ complain_overflow_dont,/* complain_on_overflow */ -++ bfd_elf_generic_reloc, /* special_function */ -++ "R_NDS32_LO12S2_SP_RELA",/* name */ -++ FALSE, /* partial_inplace */ -++ 0x000003ff, /* src_mask */ -++ 0x000003ff, /* dst_mask */ -++ FALSE), /* pcrel_offset */ -+ /* Lower 12 bits of address. Special identity for or case. */ -+- HOWTO (R_NDS32_LO12S0_ORI_RELA, /* type */ -+- 0, /* rightshift */ -+- 2, /* size (0 = byte, 1 = short, 2 = long) */ -+- 12, /* bitsize */ -+- FALSE, /* pc_relative */ -+- 0, /* bitpos */ -+- complain_overflow_dont,/* complain_on_overflow */ -+- bfd_elf_generic_reloc, /* special_function */ -+- "R_NDS32_LO12S0_ORI_RELA", /* name */ -+- FALSE, /* partial_inplace */ -+- 0x00000fff, /* src_mask */ -+- 0x00000fff, /* dst_mask */ -+- FALSE), /* pcrel_offset */ -++ HOWTO2 (R_NDS32_LO12S0_ORI_RELA,/* type */ -++ 0, /* rightshift */ -++ 2, /* size (0 = byte, 1 = short, 2 = long) */ -++ 12, /* bitsize */ -++ FALSE, /* pc_relative */ -++ 0, /* bitpos */ -++ complain_overflow_dont,/* complain_on_overflow */ -++ bfd_elf_generic_reloc, /* special_function */ -++ "R_NDS32_LO12S0_ORI_RELA",/* name */ -++ FALSE, /* partial_inplace */ -++ 0x00000fff, /* src_mask */ -++ 0x00000fff, /* dst_mask */ -++ FALSE), /* pcrel_offset */ -+ /* Small data area 19 bits offset. */ -+- HOWTO (R_NDS32_SDA16S3_RELA, /* type */ -+- 3, /* rightshift */ -+- 2, /* size (0 = byte, 1 = short, 2 = long) */ -+- 16, /* bitsize */ -+- FALSE, /* pc_relative */ -+- 0, /* bitpos */ -+- complain_overflow_signed, /* complain_on_overflow */ -+- bfd_elf_generic_reloc, /* special_function */ -+- "R_NDS32_SDA16S3_RELA",/* name */ -+- FALSE, /* partial_inplace */ -+- 0x0000ffff, /* src_mask */ -+- 0x0000ffff, /* dst_mask */ -+- FALSE), /* pcrel_offset */ -++ HOWTO2 (R_NDS32_SDA16S3_RELA, /* type */ -++ 3, /* rightshift */ -++ 2, /* size (0 = byte, 1 = short, 2 = long) */ -++ 16, /* bitsize */ -++ FALSE, /* pc_relative */ -++ 0, /* bitpos */ -++ complain_overflow_signed,/* complain_on_overflow */ -++ bfd_elf_generic_reloc, /* special_function */ -++ "R_NDS32_SDA16S3_RELA",/* name */ -++ FALSE, /* partial_inplace */ -++ 0x0000ffff, /* src_mask */ -++ 0x0000ffff, /* dst_mask */ -++ FALSE), /* pcrel_offset */ -+ -+ /* Small data area 15 bits offset. */ -+- HOWTO (R_NDS32_SDA17S2_RELA, /* type */ -+- 2, /* rightshift */ -+- 2, /* size (0 = byte, 1 = short, 2 = long) */ -+- 17, /* bitsize */ -+- FALSE, /* pc_relative */ -+- 0, /* bitpos */ -+- complain_overflow_signed, /* complain_on_overflow */ -+- bfd_elf_generic_reloc, /* special_function */ -+- "R_NDS32_SDA17S2_RELA",/* name */ -+- FALSE, /* partial_inplace */ -+- 0x0001ffff, /* src_mask */ -+- 0x0001ffff, /* dst_mask */ -+- FALSE), /* pcrel_offset */ -+- -+- HOWTO (R_NDS32_SDA18S1_RELA, /* type */ -+- 1, /* rightshift */ -+- 2, /* size (0 = byte, 1 = short, 2 = long) */ -+- 18, /* bitsize */ -+- FALSE, /* pc_relative */ -+- 0, /* bitpos */ -+- complain_overflow_signed, /* complain_on_overflow */ -+- bfd_elf_generic_reloc, /* special_function */ -+- "R_NDS32_SDA18S1_RELA",/* name */ -+- FALSE, /* partial_inplace */ -+- 0x0003ffff, /* src_mask */ -+- 0x0003ffff, /* dst_mask */ -+- FALSE), /* pcrel_offset */ -+- -+- HOWTO (R_NDS32_SDA19S0_RELA, /* type */ -+- 0, /* rightshift */ -+- 2, /* size (0 = byte, 1 = short, 2 = long) */ -+- 19, /* bitsize */ -+- FALSE, /* pc_relative */ -+- 0, /* bitpos */ -+- complain_overflow_signed, /* complain_on_overflow */ -+- bfd_elf_generic_reloc, /* special_function */ -+- "R_NDS32_SDA19S0_RELA",/* name */ -+- FALSE, /* partial_inplace */ -+- 0x0007ffff, /* src_mask */ -+- 0x0007ffff, /* dst_mask */ -+- FALSE), /* pcrel_offset */ -+- HOWTO (R_NDS32_DWARF2_OP1_RELA, /* type */ -+- 0, /* rightshift */ -+- 0, /* size (0 = byte, 1 = short, 2 = long) */ -+- 8, /* bitsize */ -+- FALSE, /* pc_relative */ -+- 0, /* bitpos */ -+- complain_overflow_dont,/* complain_on_overflow */ -+- nds32_elf_ignore_reloc,/* special_function */ -+- "R_NDS32_DWARF2_OP1_RELA", /* name */ -+- FALSE, /* partial_inplace */ -+- 0xff, /* src_mask */ -+- 0xff, /* dst_mask */ -+- FALSE), /* pcrel_offset */ -+- HOWTO (R_NDS32_DWARF2_OP2_RELA, /* type */ -+- 0, /* rightshift */ -+- 1, /* size (0 = byte, 1 = short, 2 = long) */ -+- 16, /* bitsize */ -+- FALSE, /* pc_relative */ -+- 0, /* bitpos */ -+- complain_overflow_dont,/* complain_on_overflow */ -+- nds32_elf_ignore_reloc,/* special_function */ -+- "R_NDS32_DWARF2_OP2_RELA", /* name */ -+- FALSE, /* partial_inplace */ -+- 0xffff, /* src_mask */ -+- 0xffff, /* dst_mask */ -+- FALSE), /* pcrel_offset */ -+- HOWTO (R_NDS32_DWARF2_LEB_RELA, /* type */ -+- 0, /* rightshift */ -+- 2, /* size (0 = byte, 1 = short, 2 = long) */ -+- 32, /* bitsize */ -+- FALSE, /* pc_relative */ -+- 0, /* bitpos */ -+- complain_overflow_dont,/* complain_on_overflow */ -+- nds32_elf_ignore_reloc,/* special_function */ -+- "R_NDS32_DWARF2_LEB_RELA", /* name */ -+- FALSE, /* partial_inplace */ -+- 0xffffffff, /* src_mask */ -+- 0xffffffff, /* dst_mask */ -+- FALSE), /* pcrel_offset */ -+- HOWTO (R_NDS32_UPDATE_TA_RELA,/* type */ -+- 0, /* rightshift */ -+- 1, /* size (0 = byte, 1 = short, 2 = long) */ -+- 16, /* bitsize */ -+- FALSE, /* pc_relative */ -+- 0, /* bitpos */ -+- complain_overflow_dont,/* complain_on_overflow */ -+- nds32_elf_ignore_reloc,/* special_function */ -+- "R_NDS32_UPDATE_TA_RELA", /* name */ -+- FALSE, /* partial_inplace */ -+- 0xffff, /* src_mask */ -+- 0xffff, /* dst_mask */ -+- FALSE), /* pcrel_offset */ -++ HOWTO2 (R_NDS32_SDA17S2_RELA, /* type */ -++ 2, /* rightshift */ -++ 2, /* size (0 = byte, 1 = short, 2 = long) */ -++ 17, /* bitsize */ -++ FALSE, /* pc_relative */ -++ 0, /* bitpos */ -++ complain_overflow_signed,/* complain_on_overflow */ -++ bfd_elf_generic_reloc, /* special_function */ -++ "R_NDS32_SDA17S2_RELA",/* name */ -++ FALSE, /* partial_inplace */ -++ 0x0001ffff, /* src_mask */ -++ 0x0001ffff, /* dst_mask */ -++ FALSE), /* pcrel_offset */ -++ -++ HOWTO2 (R_NDS32_SDA18S1_RELA, /* type */ -++ 1, /* rightshift */ -++ 2, /* size (0 = byte, 1 = short, 2 = long) */ -++ 18, /* bitsize */ -++ FALSE, /* pc_relative */ -++ 0, /* bitpos */ -++ complain_overflow_signed,/* complain_on_overflow */ -++ bfd_elf_generic_reloc, /* special_function */ -++ "R_NDS32_SDA18S1_RELA",/* name */ -++ FALSE, /* partial_inplace */ -++ 0x0003ffff, /* src_mask */ -++ 0x0003ffff, /* dst_mask */ -++ FALSE), /* pcrel_offset */ -++ -++ HOWTO2 (R_NDS32_SDA19S0_RELA, /* type */ -++ 0, /* rightshift */ -++ 2, /* size (0 = byte, 1 = short, 2 = long) */ -++ 19, /* bitsize */ -++ FALSE, /* pc_relative */ -++ 0, /* bitpos */ -++ complain_overflow_signed,/* complain_on_overflow */ -++ bfd_elf_generic_reloc, /* special_function */ -++ "R_NDS32_SDA19S0_RELA",/* name */ -++ FALSE, /* partial_inplace */ -++ 0x0007ffff, /* src_mask */ -++ 0x0007ffff, /* dst_mask */ -++ FALSE), /* pcrel_offset */ -++ HOWTO2 (R_NDS32_DWARF2_OP1_RELA,/* type */ -++ 0, /* rightshift */ -++ 0, /* size (0 = byte, 1 = short, 2 = long) */ -++ 8, /* bitsize */ -++ FALSE, /* pc_relative */ -++ 0, /* bitpos */ -++ complain_overflow_dont,/* complain_on_overflow */ -++ nds32_elf_ignore_reloc,/* special_function */ -++ "R_NDS32_DWARF2_OP1_RELA",/* name */ -++ FALSE, /* partial_inplace */ -++ 0xff, /* src_mask */ -++ 0xff, /* dst_mask */ -++ FALSE), /* pcrel_offset */ -++ HOWTO2 (R_NDS32_DWARF2_OP2_RELA,/* type */ -++ 0, /* rightshift */ -++ 1, /* size (0 = byte, 1 = short, 2 = long) */ -++ 16, /* bitsize */ -++ FALSE, /* pc_relative */ -++ 0, /* bitpos */ -++ complain_overflow_dont,/* complain_on_overflow */ -++ nds32_elf_ignore_reloc,/* special_function */ -++ "R_NDS32_DWARF2_OP2_RELA",/* name */ -++ FALSE, /* partial_inplace */ -++ 0xffff, /* src_mask */ -++ 0xffff, /* dst_mask */ -++ FALSE), /* pcrel_offset */ -++ HOWTO2 (R_NDS32_DWARF2_LEB_RELA,/* type */ -++ 0, /* rightshift */ -++ 2, /* size (0 = byte, 1 = short, 2 = long) */ -++ 32, /* bitsize */ -++ FALSE, /* pc_relative */ -++ 0, /* bitpos */ -++ complain_overflow_dont,/* complain_on_overflow */ -++ nds32_elf_ignore_reloc,/* special_function */ -++ "R_NDS32_DWARF2_LEB_RELA",/* name */ -++ FALSE, /* partial_inplace */ -++ 0xffffffff, /* src_mask */ -++ 0xffffffff, /* dst_mask */ -++ FALSE), /* pcrel_offset */ -++ HOWTO2 (R_NDS32_UPDATE_TA_RELA,/* type */ -++ 0, /* rightshift */ -++ 1, /* size (0 = byte, 1 = short, 2 = long) */ -++ 16, /* bitsize */ -++ FALSE, /* pc_relative */ -++ 0, /* bitpos */ -++ complain_overflow_dont,/* complain_on_overflow */ -++ nds32_elf_ignore_reloc,/* special_function */ -++ "R_NDS32_UPDATE_TA_RELA",/* name */ -++ FALSE, /* partial_inplace */ -++ 0xffff, /* src_mask */ -++ 0xffff, /* dst_mask */ -++ FALSE), /* pcrel_offset */ -+ /* Like R_NDS32_PCREL, but referring to the procedure linkage table -+ entry for the symbol. */ -+- HOWTO (R_NDS32_9_PLTREL, /* type */ -+- 1, /* rightshift */ -+- 1, /* size (0 = byte, 1 = short, 2 = long) */ -+- 8, /* bitsize */ -+- TRUE, /* pc_relative */ -+- 0, /* bitpos */ -+- complain_overflow_signed, /* complain_on_overflow */ -+- bfd_elf_generic_reloc, /* special_function */ -+- "R_NDS32_9_PLTREL", /* name */ -+- FALSE, /* partial_inplace */ -+- 0xff, /* src_mask */ -+- 0xff, /* dst_mask */ -+- TRUE), /* pcrel_offset */ -++ HOWTO2 (R_NDS32_9_PLTREL, /* type */ -++ 1, /* rightshift */ -++ 1, /* size (0 = byte, 1 = short, 2 = long) */ -++ 8, /* bitsize */ -++ TRUE, /* pc_relative */ -++ 0, /* bitpos */ -++ complain_overflow_signed,/* complain_on_overflow */ -++ bfd_elf_generic_reloc, /* special_function */ -++ "R_NDS32_9_PLTREL", /* name */ -++ FALSE, /* partial_inplace */ -++ 0xff, /* src_mask */ -++ 0xff, /* dst_mask */ -++ TRUE), /* pcrel_offset */ -+ /* Low 20 bits of PLT symbol offset relative to GOT (GP). */ -+- HOWTO (R_NDS32_PLT_GOTREL_LO20, /* type */ -+- 0, /* rightshift */ -+- 2, /* size (0 = byte, 1 = short, 2 = long) */ -+- 20, /* bitsize */ -+- FALSE, /* pc_relative */ -+- 0, /* bitpos */ -+- complain_overflow_dont,/* complain_on_overflow */ -+- bfd_elf_generic_reloc, /* special_function */ -+- "R_NDS32_PLT_GOTREL_LO20", /* name */ -+- FALSE, /* partial_inplace */ -+- 0x000fffff, /* src_mask */ -+- 0x000fffff, /* dst_mask */ -+- FALSE), /* pcrel_offset */ -+- /* low 15 bits of PLT symbol offset relative to GOT (GP) */ -+- HOWTO (R_NDS32_PLT_GOTREL_LO15, /* type */ -+- 0, /* rightshift */ -+- 2, /* size (0 = byte, 1 = short, 2 = long) */ -+- 15, /* bitsize */ -+- FALSE, /* pc_relative */ -+- 0, /* bitpos */ -+- complain_overflow_dont,/* complain_on_overflow */ -+- bfd_elf_generic_reloc, /* special_function */ -+- "R_NDS32_PLT_GOTREL_LO15", /* name */ -+- FALSE, /* partial_inplace */ -+- 0x00007fff, /* src_mask */ -+- 0x00007fff, /* dst_mask */ -+- FALSE), /* pcrel_offset */ -++ HOWTO2 (R_NDS32_PLT_GOTREL_LO20,/* type */ -++ 0, /* rightshift */ -++ 2, /* size (0 = byte, 1 = short, 2 = long) */ -++ 20, /* bitsize */ -++ FALSE, /* pc_relative */ -++ 0, /* bitpos */ -++ complain_overflow_dont,/* complain_on_overflow */ -++ bfd_elf_generic_reloc, /* special_function */ -++ "R_NDS32_PLT_GOTREL_LO20",/* name */ -++ FALSE, /* partial_inplace */ -++ 0x000fffff, /* src_mask */ -++ 0x000fffff, /* dst_mask */ -++ FALSE), /* pcrel_offset */ -++ /* low 15 bits of PLT symbol offset relative to GOT (GP) */ -++ HOWTO2 (R_NDS32_PLT_GOTREL_LO15,/* type */ -++ 0, /* rightshift */ -++ 2, /* size (0 = byte, 1 = short, 2 = long) */ -++ 15, /* bitsize */ -++ FALSE, /* pc_relative */ -++ 0, /* bitpos */ -++ complain_overflow_dont,/* complain_on_overflow */ -++ bfd_elf_generic_reloc, /* special_function */ -++ "R_NDS32_PLT_GOTREL_LO15",/* name */ -++ FALSE, /* partial_inplace */ -++ 0x00007fff, /* src_mask */ -++ 0x00007fff, /* dst_mask */ -++ FALSE), /* pcrel_offset */ -+ /* Low 19 bits of PLT symbol offset relative to GOT (GP). */ -+- HOWTO (R_NDS32_PLT_GOTREL_LO19, /* type */ -+- 0, /* rightshift */ -+- 2, /* size (0 = byte, 1 = short, 2 = long) */ -+- 19, /* bitsize */ -+- FALSE, /* pc_relative */ -+- 0, /* bitpos */ -+- complain_overflow_dont,/* complain_on_overflow */ -+- bfd_elf_generic_reloc, /* special_function */ -+- "R_NDS32_PLT_GOTREL_LO19", /* name */ -+- FALSE, /* partial_inplace */ -+- 0x0007ffff, /* src_mask */ -+- 0x0007ffff, /* dst_mask */ -+- FALSE), /* pcrel_offset */ -+- HOWTO (R_NDS32_GOT_LO15, /* type */ -+- 0, /* rightshift */ -+- 2, /* size (0 = byte, 1 = short, 2 = long) */ -+- 15, /* bitsize */ -+- FALSE, /* pc_relative */ -+- 0, /* bitpos */ -+- complain_overflow_dont,/* complain_on_overflow */ -+- bfd_elf_generic_reloc, /* special_function */ -+- "R_NDS32_GOT_LO15", /* name */ -+- FALSE, /* partial_inplace */ -+- 0x00007fff, /* src_mask */ -+- 0x00007fff, /* dst_mask */ -+- FALSE), /* pcrel_offset */ -+- HOWTO (R_NDS32_GOT_LO19, /* type */ -+- 0, /* rightshift */ -+- 2, /* size (0 = byte, 1 = short, 2 = long) */ -+- 19, /* bitsize */ -+- FALSE, /* pc_relative */ -+- 0, /* bitpos */ -+- complain_overflow_dont,/* complain_on_overflow */ -+- bfd_elf_generic_reloc, /* special_function */ -+- "R_NDS32_GOT_LO19", /* name */ -+- FALSE, /* partial_inplace */ -+- 0x0007ffff, /* src_mask */ -+- 0x0007ffff, /* dst_mask */ -+- FALSE), /* pcrel_offset */ -+- HOWTO (R_NDS32_GOTOFF_LO15, /* type */ -+- 0, /* rightshift */ -+- 2, /* size (0 = byte, 1 = short, 2 = long) */ -+- 15, /* bitsize */ -+- FALSE, /* pc_relative */ -+- 0, /* bitpos */ -+- complain_overflow_dont,/* complain_on_overflow */ -+- bfd_elf_generic_reloc, /* special_function */ -+- "R_NDS32_GOTOFF_LO15", /* name */ -+- FALSE, /* partial_inplace */ -+- 0x00007fff, /* src_mask */ -+- 0x00007fff, /* dst_mask */ -+- FALSE), /* pcrel_offset */ -+- HOWTO (R_NDS32_GOTOFF_LO19, /* type */ -+- 0, /* rightshift */ -+- 2, /* size (0 = byte, 1 = short, 2 = long) */ -+- 19, /* bitsize */ -+- FALSE, /* pc_relative */ -+- 0, /* bitpos */ -+- complain_overflow_dont,/* complain_on_overflow */ -+- bfd_elf_generic_reloc, /* special_function */ -+- "R_NDS32_GOTOFF_LO19", /* name */ -+- FALSE, /* partial_inplace */ -+- 0x0007ffff, /* src_mask */ -+- 0x0007ffff, /* dst_mask */ -+- FALSE), /* pcrel_offset */ -++ HOWTO2 (R_NDS32_PLT_GOTREL_LO19,/* type */ -++ 0, /* rightshift */ -++ 2, /* size (0 = byte, 1 = short, 2 = long) */ -++ 19, /* bitsize */ -++ FALSE, /* pc_relative */ -++ 0, /* bitpos */ -++ complain_overflow_dont,/* complain_on_overflow */ -++ bfd_elf_generic_reloc, /* special_function */ -++ "R_NDS32_PLT_GOTREL_LO19",/* name */ -++ FALSE, /* partial_inplace */ -++ 0x0007ffff, /* src_mask */ -++ 0x0007ffff, /* dst_mask */ -++ FALSE), /* pcrel_offset */ -++ HOWTO2 (R_NDS32_GOT_LO15, /* type */ -++ 0, /* rightshift */ -++ 2, /* size (0 = byte, 1 = short, 2 = long) */ -++ 15, /* bitsize */ -++ FALSE, /* pc_relative */ -++ 0, /* bitpos */ -++ complain_overflow_dont,/* complain_on_overflow */ -++ bfd_elf_generic_reloc, /* special_function */ -++ "R_NDS32_GOT_LO15", /* name */ -++ FALSE, /* partial_inplace */ -++ 0x00007fff, /* src_mask */ -++ 0x00007fff, /* dst_mask */ -++ FALSE), /* pcrel_offset */ -++ HOWTO2 (R_NDS32_GOT_LO19, /* type */ -++ 0, /* rightshift */ -++ 2, /* size (0 = byte, 1 = short, 2 = long) */ -++ 19, /* bitsize */ -++ FALSE, /* pc_relative */ -++ 0, /* bitpos */ -++ complain_overflow_dont,/* complain_on_overflow */ -++ bfd_elf_generic_reloc, /* special_function */ -++ "R_NDS32_GOT_LO19", /* name */ -++ FALSE, /* partial_inplace */ -++ 0x0007ffff, /* src_mask */ -++ 0x0007ffff, /* dst_mask */ -++ FALSE), /* pcrel_offset */ -++ HOWTO2 (R_NDS32_GOTOFF_LO15, /* type */ -++ 0, /* rightshift */ -++ 2, /* size (0 = byte, 1 = short, 2 = long) */ -++ 15, /* bitsize */ -++ FALSE, /* pc_relative */ -++ 0, /* bitpos */ -++ complain_overflow_dont,/* complain_on_overflow */ -++ bfd_elf_generic_reloc, /* special_function */ -++ "R_NDS32_GOTOFF_LO15", /* name */ -++ FALSE, /* partial_inplace */ -++ 0x00007fff, /* src_mask */ -++ 0x00007fff, /* dst_mask */ -++ FALSE), /* pcrel_offset */ -++ HOWTO2 (R_NDS32_GOTOFF_LO19, /* type */ -++ 0, /* rightshift */ -++ 2, /* size (0 = byte, 1 = short, 2 = long) */ -++ 19, /* bitsize */ -++ FALSE, /* pc_relative */ -++ 0, /* bitpos */ -++ complain_overflow_dont,/* complain_on_overflow */ -++ bfd_elf_generic_reloc, /* special_function */ -++ "R_NDS32_GOTOFF_LO19", /* name */ -++ FALSE, /* partial_inplace */ -++ 0x0007ffff, /* src_mask */ -++ 0x0007ffff, /* dst_mask */ -++ FALSE), /* pcrel_offset */ -+ /* GOT 15 bits offset. */ -+- HOWTO (R_NDS32_GOT15S2_RELA, /* type */ -+- 2, /* rightshift */ -+- 2, /* size (0 = byte, 1 = short, 2 = long) */ -+- 15, /* bitsize */ -+- FALSE, /* pc_relative */ -+- 0, /* bitpos */ -+- complain_overflow_signed, /* complain_on_overflow */ -+- bfd_elf_generic_reloc, /* special_function */ -+- "R_NDS32_GOT15S2_RELA",/* name */ -+- FALSE, /* partial_inplace */ -+- 0x00007fff, /* src_mask */ -+- 0x00007fff, /* dst_mask */ -+- FALSE), /* pcrel_offset */ -++ HOWTO2 (R_NDS32_GOT15S2_RELA, /* type */ -++ 2, /* rightshift */ -++ 2, /* size (0 = byte, 1 = short, 2 = long) */ -++ 15, /* bitsize */ -++ FALSE, /* pc_relative */ -++ 0, /* bitpos */ -++ complain_overflow_signed,/* complain_on_overflow */ -++ bfd_elf_generic_reloc, /* special_function */ -++ "R_NDS32_GOT15S2_RELA",/* name */ -++ FALSE, /* partial_inplace */ -++ 0x00007fff, /* src_mask */ -++ 0x00007fff, /* dst_mask */ -++ FALSE), /* pcrel_offset */ -+ /* GOT 17 bits offset. */ -+- HOWTO (R_NDS32_GOT17S2_RELA, /* type */ -+- 2, /* rightshift */ -+- 2, /* size (0 = byte, 1 = short, 2 = long) */ -+- 17, /* bitsize */ -+- FALSE, /* pc_relative */ -+- 0, /* bitpos */ -+- complain_overflow_signed, /* complain_on_overflow */ -+- bfd_elf_generic_reloc, /* special_function */ -+- "R_NDS32_GOT17S2_RELA",/* name */ -+- FALSE, /* partial_inplace */ -+- 0x0001ffff, /* src_mask */ -+- 0x0001ffff, /* dst_mask */ -+- FALSE), /* pcrel_offset */ -++ HOWTO2 (R_NDS32_GOT17S2_RELA, /* type */ -++ 2, /* rightshift */ -++ 2, /* size (0 = byte, 1 = short, 2 = long) */ -++ 17, /* bitsize */ -++ FALSE, /* pc_relative */ -++ 0, /* bitpos */ -++ complain_overflow_signed,/* complain_on_overflow */ -++ bfd_elf_generic_reloc, /* special_function */ -++ "R_NDS32_GOT17S2_RELA",/* name */ -++ FALSE, /* partial_inplace */ -++ 0x0001ffff, /* src_mask */ -++ 0x0001ffff, /* dst_mask */ -++ FALSE), /* pcrel_offset */ -+ /* A 5 bit address. */ -+- HOWTO (R_NDS32_5_RELA, /* type */ -+- 0, /* rightshift */ -+- 1, /* size (0 = byte, 1 = short, 2 = long) */ -+- 5, /* bitsize */ -+- FALSE, /* pc_relative */ -+- 0, /* bitpos */ -+- complain_overflow_signed, /* complain_on_overflow */ -+- bfd_elf_generic_reloc, /* special_function */ -+- "R_NDS32_5_RELA", /* name */ -+- FALSE, /* partial_inplace */ -+- 0x1f, /* src_mask */ -+- 0x1f, /* dst_mask */ -+- FALSE), /* pcrel_offset */ -+- HOWTO (R_NDS32_10_UPCREL_RELA,/* type */ -+- 1, /* rightshift */ -+- 1, /* size (0 = byte, 1 = short, 2 = long) */ -+- 9, /* bitsize */ -+- TRUE, /* pc_relative */ -+- 0, /* bitpos */ -+- complain_overflow_unsigned, /* complain_on_overflow */ -+- bfd_elf_generic_reloc, /* special_function */ -+- "R_NDS32_10_UPCREL_RELA", /* name */ -+- FALSE, /* partial_inplace */ -+- 0x1ff, /* src_mask */ -+- 0x1ff, /* dst_mask */ -+- TRUE), /* pcrel_offset */ -+- HOWTO (R_NDS32_SDA_FP7U2_RELA,/* type */ -+- 2, /* rightshift */ -+- 1, /* size (0 = byte, 1 = short, 2 = long) */ -+- 7, /* bitsize */ -+- FALSE, /* pc_relative */ -+- 0, /* bitpos */ -+- complain_overflow_unsigned, /* complain_on_overflow */ -+- bfd_elf_generic_reloc, /* special_function */ -+- "R_NDS32_SDA_FP7U2_RELA", /* name */ -+- FALSE, /* partial_inplace */ -+- 0x0000007f, /* src_mask */ -+- 0x0000007f, /* dst_mask */ -+- FALSE), /* pcrel_offset */ -+- HOWTO (R_NDS32_WORD_9_PCREL_RELA, /* type */ -+- 1, /* rightshift */ -+- 2, /* size (0 = byte, 1 = short, 2 = long) */ -+- 8, /* bitsize */ -+- TRUE, /* pc_relative */ -+- 0, /* bitpos */ -+- complain_overflow_signed, /* complain_on_overflow */ -+- bfd_elf_generic_reloc, /* special_function */ -+- "R_NDS32_WORD_9_PCREL_RELA", /* name */ -+- FALSE, /* partial_inplace */ -+- 0xff, /* src_mask */ -+- 0xff, /* dst_mask */ -+- TRUE), /* pcrel_offset */ -+- HOWTO (R_NDS32_25_ABS_RELA, /* type */ -+- 1, /* rightshift */ -+- 2, /* size (0 = byte, 1 = short, 2 = long) */ -+- 24, /* bitsize */ -+- FALSE, /* pc_relative */ -+- 0, /* bitpos */ -+- complain_overflow_dont,/* complain_on_overflow */ -+- bfd_elf_generic_reloc, /* special_function */ -+- "R_NDS32_25_ABS_RELA", /* name */ -+- FALSE, /* partial_inplace */ -+- 0xffffff, /* src_mask */ -+- 0xffffff, /* dst_mask */ -+- FALSE), /* pcrel_offset */ -++ HOWTO2 (R_NDS32_5_RELA, /* type */ -++ 0, /* rightshift */ -++ 1, /* size (0 = byte, 1 = short, 2 = long) */ -++ 5, /* bitsize */ -++ FALSE, /* pc_relative */ -++ 0, /* bitpos */ -++ complain_overflow_signed,/* complain_on_overflow */ -++ bfd_elf_generic_reloc, /* special_function */ -++ "R_NDS32_5_RELA", /* name */ -++ FALSE, /* partial_inplace */ -++ 0x1f, /* src_mask */ -++ 0x1f, /* dst_mask */ -++ FALSE), /* pcrel_offset */ -++ HOWTO2 (R_NDS32_10_UPCREL_RELA,/* type */ -++ 1, /* rightshift */ -++ 1, /* size (0 = byte, 1 = short, 2 = long) */ -++ 9, /* bitsize */ -++ TRUE, /* pc_relative */ -++ 0, /* bitpos */ -++ complain_overflow_unsigned,/* complain_on_overflow */ -++ bfd_elf_generic_reloc, /* special_function */ -++ "R_NDS32_10_UPCREL_RELA",/* name */ -++ FALSE, /* partial_inplace */ -++ 0x1ff, /* src_mask */ -++ 0x1ff, /* dst_mask */ -++ TRUE), /* pcrel_offset */ -++ HOWTO2 (R_NDS32_SDA_FP7U2_RELA,/* type */ -++ 2, /* rightshift */ -++ 1, /* size (0 = byte, 1 = short, 2 = long) */ -++ 7, /* bitsize */ -++ FALSE, /* pc_relative */ -++ 0, /* bitpos */ -++ complain_overflow_unsigned,/* complain_on_overflow */ -++ bfd_elf_generic_reloc, /* special_function */ -++ "R_NDS32_SDA_FP7U2_RELA",/* name */ -++ FALSE, /* partial_inplace */ -++ 0x0000007f, /* src_mask */ -++ 0x0000007f, /* dst_mask */ -++ FALSE), /* pcrel_offset */ -++ HOWTO2 (R_NDS32_WORD_9_PCREL_RELA,/* type */ -++ 1, /* rightshift */ -++ 2, /* size (0 = byte, 1 = short, 2 = long) */ -++ 8, /* bitsize */ -++ TRUE, /* pc_relative */ -++ 0, /* bitpos */ -++ complain_overflow_signed,/* complain_on_overflow */ -++ bfd_elf_generic_reloc, /* special_function */ -++ "R_NDS32_WORD_9_PCREL_RELA",/* name */ -++ FALSE, /* partial_inplace */ -++ 0xff, /* src_mask */ -++ 0xff, /* dst_mask */ -++ TRUE), /* pcrel_offset */ -++ HOWTO2 (R_NDS32_25_ABS_RELA, /* type */ -++ 1, /* rightshift */ -++ 2, /* size (0 = byte, 1 = short, 2 = long) */ -++ 24, /* bitsize */ -++ FALSE, /* pc_relative */ -++ 0, /* bitpos */ -++ complain_overflow_dont,/* complain_on_overflow */ -++ bfd_elf_generic_reloc, /* special_function */ -++ "R_NDS32_25_ABS_RELA", /* name */ -++ FALSE, /* partial_inplace */ -++ 0xffffff, /* src_mask */ -++ 0xffffff, /* dst_mask */ -++ FALSE), /* pcrel_offset */ -+ -+ /* A relative 17 bit relocation for ifc, right shifted by 1. */ -+- HOWTO (R_NDS32_17IFC_PCREL_RELA, /* type */ -+- 1, /* rightshift */ -+- 2, /* size (0 = byte, 1 = short, 2 = long) */ -+- 16, /* bitsize */ -+- TRUE, /* pc_relative */ -+- 0, /* bitpos */ -+- complain_overflow_signed, /* complain_on_overflow */ -+- bfd_elf_generic_reloc, /* special_function */ -+- "R_NDS32_17IFC_PCREL_RELA", /* name */ -+- FALSE, /* partial_inplace */ -+- 0xffff, /* src_mask */ -+- 0xffff, /* dst_mask */ -+- TRUE), /* pcrel_offset */ -++ HOWTO2 (R_NDS32_17IFC_PCREL_RELA,/* type */ -++ 1, /* rightshift */ -++ 2, /* size (0 = byte, 1 = short, 2 = long) */ -++ 16, /* bitsize */ -++ TRUE, /* pc_relative */ -++ 0, /* bitpos */ -++ complain_overflow_signed,/* complain_on_overflow */ -++ bfd_elf_generic_reloc, /* special_function */ -++ "R_NDS32_17IFC_PCREL_RELA",/* name */ -++ FALSE, /* partial_inplace */ -++ 0xffff, /* src_mask */ -++ 0xffff, /* dst_mask */ -++ TRUE), /* pcrel_offset */ -+ -+ /* A relative unsigned 10 bit relocation for ifc, right shifted by 1. */ -+- HOWTO (R_NDS32_10IFCU_PCREL_RELA, /* type */ -+- 1, /* rightshift */ -+- 1, /* size (0 = byte, 1 = short, 2 = long) */ -+- 9, /* bitsize */ -+- TRUE, /* pc_relative */ -+- 0, /* bitpos */ -+- complain_overflow_unsigned, /* complain_on_overflow */ -+- bfd_elf_generic_reloc, /* special_function */ -+- "R_NDS32_10IFCU_PCREL_RELA", /* name */ -+- FALSE, /* partial_inplace */ -+- 0x1ff, /* src_mask */ -+- 0x1ff, /* dst_mask */ -+- TRUE), /* pcrel_offset */ -+- -+- /* Like R_NDS32_HI20, but referring to the TLS entry for the symbol. */ -+- HOWTO (R_NDS32_TLS_LE_HI20, /* type */ -+- 12, /* rightshift */ -+- 2, /* size (0 = byte, 1 = short, 2 = long) */ -+- 20, /* bitsize */ -+- FALSE, /* pc_relative */ -+- 0, /* bitpos */ -+- complain_overflow_dont, /* complain_on_overflow */ -+- bfd_elf_generic_reloc, /* special_function */ -+- "R_NDS32_TLS_LE_HI20", /* name */ -+- FALSE, /* partial_inplace */ -+- 0x000fffff, /* src_mask */ -+- 0x000fffff, /* dst_mask */ -+- FALSE), /* pcrel_offset */ -+- HOWTO (R_NDS32_TLS_LE_LO12, /* type */ -+- 0, /* rightshift */ -+- 2, /* size (0 = byte, 1 = short, 2 = long) */ -+- 12, /* bitsize */ -+- FALSE, /* pc_relative */ -+- 0, /* bitpos */ -+- complain_overflow_dont, /* complain_on_overflow */ -+- bfd_elf_generic_reloc, /* special_function */ -+- "R_NDS32_TLS_LE_LO12", /* name */ -+- FALSE, /* partial_inplace */ -+- 0x00000fff, /* src_mask */ -+- 0x00000fff, /* dst_mask */ -+- FALSE), /* pcrel_offset */ -+- -+- /* Like R_NDS32_HI20, but referring to the TLS entry for the symbol. */ -+- HOWTO (R_NDS32_TLS_IE_HI20, /* type */ -+- 12, /* rightshift */ -+- 2, /* size (0 = byte, 1 = short, 2 = long) */ -+- 20, /* bitsize */ -+- FALSE, /* pc_relative */ -+- 0, /* bitpos */ -+- complain_overflow_dont, /* complain_on_overflow */ -+- bfd_elf_generic_reloc, /* special_function */ -+- "R_NDS32_TLS_IE_HI20", /* name */ -+- FALSE, /* partial_inplace */ -+- 0x000fffff, /* src_mask */ -+- 0x000fffff, /* dst_mask */ -+- FALSE), /* pcrel_offset */ -+- HOWTO (R_NDS32_TLS_IE_LO12S2, /* type */ -+- 2, /* rightshift */ -+- 2, /* size (0 = byte, 1 = short, 2 = long) */ -+- 10, /* bitsize */ -+- FALSE, /* pc_relative */ -+- 0, /* bitpos */ -+- complain_overflow_dont, /* complain_on_overflow */ -+- bfd_elf_generic_reloc, /* special_function */ -+- "R_NDS32_TLS_IE_LO12S2", /* name */ -+- FALSE, /* partial_inplace */ -+- 0x000003ff, /* src_mask */ -+- 0x000003ff, /* dst_mask */ -+- FALSE), /* pcrel_offset */ -+- /* Mark a TLS IE entry in GOT. */ -+- HOWTO (R_NDS32_TLS_TPOFF, /* type */ -+- 0, /* rightshift */ -+- 2, /* size (0 = byte, 1 = short, 2 = long) */ -+- 32, /* bitsize */ -+- FALSE, /* pc_relative */ -+- 0, /* bitpos */ -+- complain_overflow_bitfield, /* complain_on_overflow */ -+- bfd_elf_generic_reloc, /* special_function */ -+- "R_NDS32_TLS_TPOFF", /* name */ -+- FALSE, /* partial_inplace */ -+- 0xffffffff, /* src_mask */ -+- 0xffffffff, /* dst_mask */ -+- FALSE), /* pcrel_offset */ -+- /* A 20 bit address. */ -+- HOWTO (R_NDS32_TLS_LE_20, /* type */ -+- 0, /* rightshift */ -+- 2, /* size (0 = byte, 1 = short, 2 = long) */ -+- 20, /* bitsize */ -+- FALSE, /* pc_relative */ -+- 0, /* bitpos */ -+- complain_overflow_signed, /* complain_on_overflow */ -+- bfd_elf_generic_reloc, /* special_function */ -+- "R_NDS32_TLS_LE_20", /* name */ -+- FALSE, /* partial_inplace */ -+- 0xfffff, /* src_mask */ -+- 0xfffff, /* dst_mask */ -+- FALSE), /* pcrel_offset */ -+- HOWTO (R_NDS32_TLS_LE_15S0, /* type */ -+- 0, /* rightshift */ -+- 2, /* size (0 = byte, 1 = short, 2 = long) */ -+- 15, /* bitsize */ -+- FALSE, /* pc_relative */ -+- 0, /* bitpos */ -+- complain_overflow_signed, /* complain_on_overflow */ -+- bfd_elf_generic_reloc, /* special_function */ -+- "R_NDS32_TLS_LE_15S0", /* name */ -+- FALSE, /* partial_inplace */ -+- 0x7fff, /* src_mask */ -+- 0x7fff, /* dst_mask */ -+- FALSE), /* pcrel_offset */ -+- HOWTO (R_NDS32_TLS_LE_15S1, /* type */ -+- 1, /* rightshift */ -+- 2, /* size (0 = byte, 1 = short, 2 = long) */ -+- 15, /* bitsize */ -+- FALSE, /* pc_relative */ -+- 0, /* bitpos */ -+- complain_overflow_signed, /* complain_on_overflow */ -+- bfd_elf_generic_reloc, /* special_function */ -+- "R_NDS32_TLS_LE_15S1", /* name */ -+- FALSE, /* partial_inplace */ -+- 0x7fff, /* src_mask */ -+- 0x7fff, /* dst_mask */ -+- FALSE), /* pcrel_offset */ -+- HOWTO (R_NDS32_TLS_LE_15S2, /* type */ -+- 2, /* rightshift */ -+- 2, /* size (0 = byte, 1 = short, 2 = long) */ -+- 15, /* bitsize */ -+- FALSE, /* pc_relative */ -+- 0, /* bitpos */ -+- complain_overflow_signed, /* complain_on_overflow */ -+- bfd_elf_generic_reloc, /* special_function */ -+- "R_NDS32_TLS_LE_15S2", /* name */ -+- FALSE, /* partial_inplace */ -+- 0x7fff, /* src_mask */ -+- 0x7fff, /* dst_mask */ -+- FALSE), /* pcrel_offset */ -++ HOWTO2 (R_NDS32_10IFCU_PCREL_RELA,/* type */ -++ 1, /* rightshift */ -++ 1, /* size (0 = byte, 1 = short, 2 = long) */ -++ 9, /* bitsize */ -++ TRUE, /* pc_relative */ -++ 0, /* bitpos */ -++ complain_overflow_unsigned,/* complain_on_overflow */ -++ bfd_elf_generic_reloc, /* special_function */ -++ "R_NDS32_10IFCU_PCREL_RELA",/* name */ -++ FALSE, /* partial_inplace */ -++ 0x1ff, /* src_mask */ -++ 0x1ff, /* dst_mask */ -++ TRUE), /* pcrel_offset */ -+ -+ /* Relax hint for unconditional call sequence */ -+- HOWTO (R_NDS32_LONGCALL4, /* type */ -+- 0, /* rightshift */ -+- 2, /* size (0 = byte, 1 = short, 2 = long) */ -+- 32, /* bitsize */ -+- FALSE, /* pc_relative */ -+- 0, /* bitpos */ -+- complain_overflow_dont, /* complain_on_overflow */ -+- nds32_elf_ignore_reloc, /* special_function */ -+- "R_NDS32_LONGCALL4", /* name */ -+- FALSE, /* partial_inplace */ -+- 0xffffffff, /* src_mask */ -+- 0xffffffff, /* dst_mask */ -+- FALSE), /* pcrel_offset */ -++ HOWTO2 (R_NDS32_LONGCALL4, /* type */ -++ 0, /* rightshift */ -++ 2, /* size (0 = byte, 1 = short, 2 = long) */ -++ 32, /* bitsize */ -++ FALSE, /* pc_relative */ -++ 0, /* bitpos */ -++ complain_overflow_dont,/* complain_on_overflow */ -++ nds32_elf_ignore_reloc,/* special_function */ -++ "R_NDS32_LONGCALL4", /* name */ -++ FALSE, /* partial_inplace */ -++ 0xffffffff, /* src_mask */ -++ 0xffffffff, /* dst_mask */ -++ FALSE), /* pcrel_offset */ -+ -+ /* Relax hint for conditional call sequence. */ -+- HOWTO (R_NDS32_LONGCALL5, /* type */ -+- 0, /* rightshift */ -+- 2, /* size (0 = byte, 1 = short, 2 = long) */ -+- 32, /* bitsize */ -+- FALSE, /* pc_relative */ -+- 0, /* bitpos */ -+- complain_overflow_dont, /* complain_on_overflow */ -+- nds32_elf_ignore_reloc, /* special_function */ -+- "R_NDS32_LONGCALL5", /* name */ -+- FALSE, /* partial_inplace */ -+- 0xffffffff, /* src_mask */ -+- 0xffffffff, /* dst_mask */ -+- FALSE), /* pcrel_offset */ -++ HOWTO2 (R_NDS32_LONGCALL5, /* type */ -++ 0, /* rightshift */ -++ 2, /* size (0 = byte, 1 = short, 2 = long) */ -++ 32, /* bitsize */ -++ FALSE, /* pc_relative */ -++ 0, /* bitpos */ -++ complain_overflow_dont,/* complain_on_overflow */ -++ nds32_elf_ignore_reloc,/* special_function */ -++ "R_NDS32_LONGCALL5", /* name */ -++ FALSE, /* partial_inplace */ -++ 0xffffffff, /* src_mask */ -++ 0xffffffff, /* dst_mask */ -++ FALSE), /* pcrel_offset */ -+ -+ /* Relax hint for conditional call sequence. */ -+- HOWTO (R_NDS32_LONGCALL6, /* type */ -+- 0, /* rightshift */ -+- 2, /* size (0 = byte, 1 = short, 2 = long) */ -+- 32, /* bitsize */ -+- FALSE, /* pc_relative */ -+- 0, /* bitpos */ -+- complain_overflow_dont, /* complain_on_overflow */ -+- nds32_elf_ignore_reloc, /* special_function */ -+- "R_NDS32_LONGCALL6", /* name */ -+- FALSE, /* partial_inplace */ -+- 0xffffffff, /* src_mask */ -+- 0xffffffff, /* dst_mask */ -+- FALSE), /* pcrel_offset */ -++ HOWTO2 (R_NDS32_LONGCALL6, /* type */ -++ 0, /* rightshift */ -++ 2, /* size (0 = byte, 1 = short, 2 = long) */ -++ 32, /* bitsize */ -++ FALSE, /* pc_relative */ -++ 0, /* bitpos */ -++ complain_overflow_dont,/* complain_on_overflow */ -++ nds32_elf_ignore_reloc,/* special_function */ -++ "R_NDS32_LONGCALL6", /* name */ -++ FALSE, /* partial_inplace */ -++ 0xffffffff, /* src_mask */ -++ 0xffffffff, /* dst_mask */ -++ FALSE), /* pcrel_offset */ -+ -+ /* Relax hint for unconditional branch sequence. */ -+- HOWTO (R_NDS32_LONGJUMP4, /* type */ -+- 0, /* rightshift */ -+- 2, /* size (0 = byte, 1 = short, 2 = long) */ -+- 32, /* bitsize */ -+- FALSE, /* pc_relative */ -+- 0, /* bitpos */ -+- complain_overflow_dont, /* complain_on_overflow */ -+- nds32_elf_ignore_reloc, /* special_function */ -+- "R_NDS32_LONGJUMP4", /* name */ -+- FALSE, /* partial_inplace */ -+- 0xffffffff, /* src_mask */ -+- 0xffffffff, /* dst_mask */ -+- FALSE), /* pcrel_offset */ -++ HOWTO2 (R_NDS32_LONGJUMP4, /* type */ -++ 0, /* rightshift */ -++ 2, /* size (0 = byte, 1 = short, 2 = long) */ -++ 32, /* bitsize */ -++ FALSE, /* pc_relative */ -++ 0, /* bitpos */ -++ complain_overflow_dont,/* complain_on_overflow */ -++ nds32_elf_ignore_reloc,/* special_function */ -++ "R_NDS32_LONGJUMP4", /* name */ -++ FALSE, /* partial_inplace */ -++ 0xffffffff, /* src_mask */ -++ 0xffffffff, /* dst_mask */ -++ FALSE), /* pcrel_offset */ -+ -+ /* Relax hint for conditional branch sequence. */ -+- HOWTO (R_NDS32_LONGJUMP5, /* type */ -+- 0, /* rightshift */ -+- 2, /* size (0 = byte, 1 = short, 2 = long) */ -+- 32, /* bitsize */ -+- FALSE, /* pc_relative */ -+- 0, /* bitpos */ -+- complain_overflow_dont, /* complain_on_overflow */ -+- nds32_elf_ignore_reloc, /* special_function */ -+- "R_NDS32_LONGJUMP5", /* name */ -+- FALSE, /* partial_inplace */ -+- 0xffffffff, /* src_mask */ -+- 0xffffffff, /* dst_mask */ -+- FALSE), /* pcrel_offset */ -++ HOWTO2 (R_NDS32_LONGJUMP5, /* type */ -++ 0, /* rightshift */ -++ 2, /* size (0 = byte, 1 = short, 2 = long) */ -++ 32, /* bitsize */ -++ FALSE, /* pc_relative */ -++ 0, /* bitpos */ -++ complain_overflow_dont,/* complain_on_overflow */ -++ nds32_elf_ignore_reloc,/* special_function */ -++ "R_NDS32_LONGJUMP5", /* name */ -++ FALSE, /* partial_inplace */ -++ 0xffffffff, /* src_mask */ -++ 0xffffffff, /* dst_mask */ -++ FALSE), /* pcrel_offset */ -+ -+ /* Relax hint for conditional branch sequence. */ -+- HOWTO (R_NDS32_LONGJUMP6, /* type */ -+- 0, /* rightshift */ -+- 2, /* size (0 = byte, 1 = short, 2 = long) */ -+- 32, /* bitsize */ -+- FALSE, /* pc_relative */ -+- 0, /* bitpos */ -+- complain_overflow_dont, /* complain_on_overflow */ -+- nds32_elf_ignore_reloc, /* special_function */ -+- "R_NDS32_LONGJUMP6", /* name */ -+- FALSE, /* partial_inplace */ -+- 0xffffffff, /* src_mask */ -+- 0xffffffff, /* dst_mask */ -+- FALSE), /* pcrel_offset */ -++ HOWTO2 (R_NDS32_LONGJUMP6, /* type */ -++ 0, /* rightshift */ -++ 2, /* size (0 = byte, 1 = short, 2 = long) */ -++ 32, /* bitsize */ -++ FALSE, /* pc_relative */ -++ 0, /* bitpos */ -++ complain_overflow_dont,/* complain_on_overflow */ -++ nds32_elf_ignore_reloc,/* special_function */ -++ "R_NDS32_LONGJUMP6", /* name */ -++ FALSE, /* partial_inplace */ -++ 0xffffffff, /* src_mask */ -++ 0xffffffff, /* dst_mask */ -++ FALSE), /* pcrel_offset */ -+ -+ /* Relax hint for conditional branch sequence. */ -+- HOWTO (R_NDS32_LONGJUMP7, /* type */ -+- 0, /* rightshift */ -+- 2, /* size (0 = byte, 1 = short, 2 = long) */ -+- 32, /* bitsize */ -+- FALSE, /* pc_relative */ -+- 0, /* bitpos */ -+- complain_overflow_dont, /* complain_on_overflow */ -+- nds32_elf_ignore_reloc, /* special_function */ -+- "R_NDS32_LONGJUMP7", /* name */ -+- FALSE, /* partial_inplace */ -+- 0xffffffff, /* src_mask */ -+- 0xffffffff, /* dst_mask */ -+- FALSE), /* pcrel_offset */ -++ HOWTO2 (R_NDS32_LONGJUMP7, /* type */ -++ 0, /* rightshift */ -++ 2, /* size (0 = byte, 1 = short, 2 = long) */ -++ 32, /* bitsize */ -++ FALSE, /* pc_relative */ -++ 0, /* bitpos */ -++ complain_overflow_dont,/* complain_on_overflow */ -++ nds32_elf_ignore_reloc,/* special_function */ -++ "R_NDS32_LONGJUMP7", /* name */ -++ FALSE, /* partial_inplace */ -++ 0xffffffff, /* src_mask */ -++ 0xffffffff, /* dst_mask */ -++ FALSE), /* pcrel_offset */ -++ -++ /* Check sum value for security. */ -++ HOWTO2 (R_NDS32_SECURITY_16, /* type */ -++ 0, /* rightshift */ -++ 2, /* size (0 = byte, 1 = short, 2 = long) */ -++ 16, /* bitsize */ -++ FALSE, /* pc_relative */ -++ 5, /* bitpos */ -++ complain_overflow_dont,/* complain_on_overflow */ -++ bfd_elf_generic_reloc, /* special_function */ -++ "R_NDS32_SECURITY_16", /* name */ -++ FALSE, /* partial_inplace */ -++ 0x1fffe0, /* src_mask */ -++ 0x1fffe0, /* dst_mask */ -++ TRUE), /* pcrel_offset */ -++ -++ /* TLS LE TP offset relocation */ -++ HOWTO2 (R_NDS32_TLS_TPOFF, /* type */ -++ 0, /* rightshift */ -++ 2, /* size (0 = byte, 1 = short, 2 = long) */ -++ 32, /* bitsize */ -++ FALSE, /* pc_relative */ -++ 0, /* bitpos */ -++ complain_overflow_bitfield,/* complain_on_overflow */ -++ bfd_elf_generic_reloc, /* special_function */ -++ "R_NDS32_TLS_TPOFF", /* name */ -++ FALSE, /* partial_inplace */ -++ 0xffffffff, /* src_mask */ -++ 0xffffffff, /* dst_mask */ -++ FALSE), /* pcrel_offset */ -++ -++ /* Like R_NDS32_HI20, but referring to the TLS LE entry for the symbol. */ -++ HOWTO2 (R_NDS32_TLS_LE_HI20, /* type */ -++ 12, /* rightshift */ -++ 2, /* size (0 = byte, 1 = short, 2 = long) */ -++ 20, /* bitsize */ -++ FALSE, /* pc_relative */ -++ 0, /* bitpos */ -++ complain_overflow_dont,/* complain_on_overflow */ -++ bfd_elf_generic_reloc, /* special_function */ -++ "R_NDS32_TLS_LE_HI20", /* name */ -++ FALSE, /* partial_inplace */ -++ 0x000fffff, /* src_mask */ -++ 0x000fffff, /* dst_mask */ -++ FALSE), /* pcrel_offset */ -++ HOWTO2 (R_NDS32_TLS_LE_LO12, /* type */ -++ 0, /* rightshift */ -++ 2, /* size (0 = byte, 1 = short, 2 = long) */ -++ 12, /* bitsize */ -++ FALSE, /* pc_relative */ -++ 0, /* bitpos */ -++ complain_overflow_dont,/* complain_on_overflow */ -++ bfd_elf_generic_reloc, /* special_function */ -++ "R_NDS32_TLS_LE_LO12", /* name */ -++ FALSE, /* partial_inplace */ -++ 0x00000fff, /* src_mask */ -++ 0x00000fff, /* dst_mask */ -++ FALSE), /* pcrel_offset */ -++ -++ /* A 20 bit address. */ -++ HOWTO2 (R_NDS32_TLS_LE_20, /* type */ -++ 0, /* rightshift */ -++ 2, /* size (0 = byte, 1 = short, 2 = long) */ -++ 20, /* bitsize */ -++ FALSE, /* pc_relative */ -++ 0, /* bitpos */ -++ complain_overflow_signed,/* complain_on_overflow */ -++ bfd_elf_generic_reloc, /* special_function */ -++ "R_NDS32_TLS_LE_20", /* name */ -++ FALSE, /* partial_inplace */ -++ 0xfffff, /* src_mask */ -++ 0xfffff, /* dst_mask */ -++ FALSE), /* pcrel_offset */ -++ HOWTO2 (R_NDS32_TLS_LE_15S0, /* type */ -++ 0, /* rightshift */ -++ 2, /* size (0 = byte, 1 = short, 2 = long) */ -++ 15, /* bitsize */ -++ FALSE, /* pc_relative */ -++ 0, /* bitpos */ -++ complain_overflow_signed,/* complain_on_overflow */ -++ bfd_elf_generic_reloc, /* special_function */ -++ "R_NDS32_TLS_LE_15S0", /* name */ -++ FALSE, /* partial_inplace */ -++ 0x7fff, /* src_mask */ -++ 0x7fff, /* dst_mask */ -++ FALSE), /* pcrel_offset */ -++ HOWTO2 (R_NDS32_TLS_LE_15S1, /* type */ -++ 1, /* rightshift */ -++ 2, /* size (0 = byte, 1 = short, 2 = long) */ -++ 15, /* bitsize */ -++ FALSE, /* pc_relative */ -++ 0, /* bitpos */ -++ complain_overflow_signed,/* complain_on_overflow */ -++ bfd_elf_generic_reloc, /* special_function */ -++ "R_NDS32_TLS_LE_15S1", /* name */ -++ FALSE, /* partial_inplace */ -++ 0x7fff, /* src_mask */ -++ 0x7fff, /* dst_mask */ -++ FALSE), /* pcrel_offset */ -++ HOWTO2 (R_NDS32_TLS_LE_15S2, /* type */ -++ 2, /* rightshift */ -++ 2, /* size (0 = byte, 1 = short, 2 = long) */ -++ 15, /* bitsize */ -++ FALSE, /* pc_relative */ -++ 0, /* bitpos */ -++ complain_overflow_signed,/* complain_on_overflow */ -++ bfd_elf_generic_reloc, /* special_function */ -++ "R_NDS32_TLS_LE_15S2", /* name */ -++ FALSE, /* partial_inplace */ -++ 0x7fff, /* src_mask */ -++ 0x7fff, /* dst_mask */ -++ FALSE), /* pcrel_offset */ -++ -++ /* Like R_NDS32_HI20, but referring to the TLS IE entry for the symbol. */ -++ HOWTO2 (R_NDS32_TLS_IE_HI20, /* type */ -++ 12, /* rightshift */ -++ 2, /* size (0 = byte, 1 = short, 2 = long) */ -++ 20, /* bitsize */ -++ FALSE, /* pc_relative */ -++ 0, /* bitpos */ -++ complain_overflow_dont,/* complain_on_overflow */ -++ bfd_elf_generic_reloc, /* special_function */ -++ "R_NDS32_TLS_IE_HI20", /* name */ -++ FALSE, /* partial_inplace */ -++ 0x000fffff, /* src_mask */ -++ 0x000fffff, /* dst_mask */ -++ FALSE), /* pcrel_offset */ -++ HOWTO2 (R_NDS32_TLS_IE_LO12, /* type */ -++ 0, /* rightshift */ -++ 2, /* size (0 = byte, 1 = short, 2 = long) */ -++ 12, /* bitsize */ -++ FALSE, /* pc_relative */ -++ 0, /* bitpos */ -++ complain_overflow_dont,/* complain_on_overflow */ -++ bfd_elf_generic_reloc, /* special_function */ -++ "R_NDS32_TLS_IE_LO12", /* name */ -++ FALSE, /* partial_inplace */ -++ 0x00000fff, /* src_mask */ -++ 0x00000fff, /* dst_mask */ -++ FALSE), /* pcrel_offset */ -++ HOWTO2 (R_NDS32_TLS_IE_LO12S2,/* type */ -++ 2, /* rightshift */ -++ 2, /* size (0 = byte, 1 = short, 2 = long) */ -++ 10, /* bitsize */ -++ FALSE, /* pc_relative */ -++ 0, /* bitpos */ -++ complain_overflow_dont,/* complain_on_overflow */ -++ bfd_elf_generic_reloc, /* special_function */ -++ "R_NDS32_TLS_IE_LO12S2",/* name */ -++ FALSE, /* partial_inplace */ -++ 0x000003ff, /* src_mask */ -++ 0x000003ff, /* dst_mask */ -++ FALSE), /* pcrel_offset */ -++ -++ /* Like R_NDS32_HI20, but referring to the TLS IE (PIE) entry for the symbol. */ -++ HOWTO2 (R_NDS32_TLS_IEGP_HI20,/* type */ -++ 12, /* rightshift */ -++ 2, /* size (0 = byte, 1 = short, 2 = long) */ -++ 20, /* bitsize */ -++ FALSE, /* pc_relative */ -++ 0, /* bitpos */ -++ complain_overflow_dont,/* complain_on_overflow */ -++ bfd_elf_generic_reloc, /* special_function */ -++ "R_NDS32_TLS_IEGP_HI20",/* name */ -++ FALSE, /* partial_inplace */ -++ 0x000fffff, /* src_mask */ -++ 0x000fffff, /* dst_mask */ -++ FALSE), /* pcrel_offset */ -++ -++ HOWTO2 (R_NDS32_TLS_IEGP_LO12,/* type */ -++ 0, /* rightshift */ -++ 2, /* size (0 = byte, 1 = short, 2 = long) */ -++ 12, /* bitsize */ -++ FALSE, /* pc_relative */ -++ 0, /* bitpos */ -++ complain_overflow_dont,/* complain_on_overflow */ -++ bfd_elf_generic_reloc, /* special_function */ -++ "R_NDS32_TLS_IEGP_LO12",/* name */ -++ FALSE, /* partial_inplace */ -++ 0x00000fff, /* src_mask */ -++ 0x00000fff, /* dst_mask */ -++ FALSE), /* pcrel_offset */ -++ -++ HOWTO2 (R_NDS32_TLS_IEGP_LO12S2,/* type */ -++ 2, /* rightshift */ -++ 2, /* size (0 = byte, 1 = short, 2 = long) */ -++ 10, /* bitsize */ -++ FALSE, /* pc_relative */ -++ 0, /* bitpos */ -++ complain_overflow_dont,/* complain_on_overflow */ -++ bfd_elf_generic_reloc, /* special_function */ -++ "R_NDS32_TLS_IEGP_LO12S2",/* name */ -++ FALSE, /* partial_inplace */ -++ 0x000003ff, /* src_mask */ -++ 0x000003ff, /* dst_mask */ -++ FALSE), /* pcrel_offset */ -++ -++ /* TLS description relocation */ -++ HOWTO2 (R_NDS32_TLS_DESC, /* type */ -++ 12, /* rightshift */ -++ 2, /* size (0 = byte, 1 = short, 2 = long) */ -++ 20, /* bitsize */ -++ FALSE, /* pc_relative */ -++ 0, /* bitpos */ -++ complain_overflow_dont,/* complain_on_overflow */ -++ nds32_elf_hi20_reloc, /* special_function */ -++ "R_NDS32_TLS_DESC_HI20",/* name */ -++ FALSE, /* partial_inplace */ -++ 0x000fffff, /* src_mask */ -++ 0x000fffff, /* dst_mask */ -++ FALSE), /* pcrel_offset */ -++ -++ /* TLS GD/LD description offset high part. */ -++ HOWTO2 (R_NDS32_TLS_DESC_HI20,/* type */ -++ 12, /* rightshift */ -++ 2, /* size (0 = byte, 1 = short, 2 = long) */ -++ 20, /* bitsize */ -++ FALSE, /* pc_relative */ -++ 0, /* bitpos */ -++ complain_overflow_dont,/* complain_on_overflow */ -++ nds32_elf_hi20_reloc, /* special_function */ -++ "R_NDS32_TLS_DESC_HI20",/* name */ -++ FALSE, /* partial_inplace */ -++ 0x000fffff, /* src_mask */ -++ 0x000fffff, /* dst_mask */ -++ FALSE), /* pcrel_offset */ -++ /* TLS GD/LD description offset low part. */ -++ HOWTO2 (R_NDS32_TLS_DESC_LO12,/* type */ -++ 0, /* rightshift */ -++ 2, /* size (0 = byte, 1 = short, 2 = long) */ -++ 12, /* bitsize */ -++ FALSE, /* pc_relative */ -++ 0, /* bitpos */ -++ complain_overflow_dont,/* complain_on_overflow */ -++ nds32_elf_lo12_reloc, /* special_function */ -++ "R_NDS32_TLS_DESC_LO12",/* name */ -++ FALSE, /* partial_inplace */ -++ 0x00000fff, /* src_mask */ -++ 0x00000fff, /* dst_mask */ -++ FALSE), /* pcrel_offset */ -++ -++ /* TLS GD/LD description offset set (movi). */ -++ HOWTO2 (R_NDS32_TLS_DESC_20, /* type */ -++ 0, /* rightshift */ -++ 2, /* size (0 = byte, 1 = short, 2 = long) */ -++ 20, /* bitsize */ -++ FALSE, /* pc_relative */ -++ 0, /* bitpos */ -++ complain_overflow_signed,/* complain_on_overflow */ -++ bfd_elf_generic_reloc, /* special_function */ -++ "R_NDS32_TLS_DESC_20", /* name */ -++ FALSE, /* partial_inplace */ -++ 0x000fffff, /* src_mask */ -++ 0x000fffff, /* dst_mask */ -++ FALSE), /* pcrel_offset */ -++ -++ /* TLS GD/LD description offset set (lwi.gp). */ -++ HOWTO2 (R_NDS32_TLS_DESC_SDA17S2,/* type */ -++ 2, /* rightshift */ -++ 2, /* size (0 = byte, 1 = short, 2 = long) */ -++ 17, /* bitsize */ -++ FALSE, /* pc_relative */ -++ 0, /* bitpos */ -++ complain_overflow_signed,/* complain_on_overflow */ -++ bfd_elf_generic_reloc, /* special_function */ -++ "R_NDS32_TLS_DESC_SDA17S2",/* name */ -++ FALSE, /* partial_inplace */ -++ 0x0001ffff, /* src_mask */ -++ 0x0001ffff, /* dst_mask */ -++ FALSE), /* pcrel_offset */ -++ -++ /* Jump-patch table relocations. */ -++ /* High 20 bits of jump-patch table address. */ -++ HOWTO2 (R_NDS32_ICT_HI20, /* type */ -++ 12, /* rightshift */ -++ 2, /* size (0 = byte, 1 = short, 2 = long) */ -++ 20, /* bitsize */ -++ FALSE, /* pc_relative */ -++ 0, /* bitpos */ -++ complain_overflow_dont,/* complain_on_overflow */ -++ bfd_elf_generic_reloc, /* special_function */ -++ "R_NDS32_ICT_HI20", /* name */ -++ FALSE, /* partial_inplace */ -++ 0x000fffff, /* src_mask */ -++ 0x000fffff, /* dst_mask */ -++ FALSE), /* pcrel_offset */ -++ /* Lower 12 bits of jump-patch table address. */ -++ HOWTO2 (R_NDS32_ICT_LO12,/* type */ -++ 0, /* rightshift */ -++ 2, /* size (0 = byte, 1 = short, 2 = long) */ -++ 12, /* bitsize */ -++ FALSE, /* pc_relative */ -++ 0, /* bitpos */ -++ complain_overflow_dont,/* complain_on_overflow */ -++ bfd_elf_generic_reloc, /* special_function */ -++ "R_NDS32_ICT_LO12",/* name */ -++ FALSE, /* partial_inplace */ -++ 0x00000fff, /* src_mask */ -++ 0x00000fff, /* dst_mask */ -++ FALSE), /* pcrel_offset */ -++ HOWTO2 (R_NDS32_ICT_LO12S2,/* type */ -++ 2, /* rightshift */ -++ 2, /* size (0 = byte, 1 = short, 2 = long) */ -++ 10, /* bitsize */ -++ FALSE, /* pc_relative */ -++ 0, /* bitpos */ -++ complain_overflow_dont,/* complain_on_overflow */ -++ bfd_elf_generic_reloc, /* special_function */ -++ "R_NDS32_ICT_LO12S2",/* name */ -++ FALSE, /* partial_inplace */ -++ 0x000003ff, /* src_mask */ -++ 0x000003ff, /* dst_mask */ -++ FALSE), /* pcrel_offset */ -++ -++ /* A relative 25 bit relocation, right shifted by 2. */ -++ HOWTO2 (R_NDS32_ICT_25PC,/* type */ -++ 1, /* rightshift */ -++ 2, /* size (0 = byte, 1 = short, 2 = long) */ -++ 24, /* bitsize */ -++ TRUE, /* pc_relative */ -++ 0, /* bitpos */ -++ complain_overflow_signed,/* complain_on_overflow */ -++ bfd_elf_generic_reloc, /* special_function */ -++ "R_NDS32_ICT_25PC",/* name */ -++ FALSE, /* partial_inplace */ -++ 0xffffff, /* src_mask */ -++ 0xffffff, /* dst_mask */ -++ TRUE), /* pcrel_offset */ -+ }; -+ -+ /* Relocations used for relaxation. */ -+-static reloc_howto_type nds32_elf_relax_howto_table[] = -+-{ -+- HOWTO (R_NDS32_RELAX_ENTRY, /* type */ -+- 0, /* rightshift */ -+- 2, /* size (0 = byte, 1 = short, 2 = long) */ -+- 32, /* bitsize */ -+- FALSE, /* pc_relative */ -+- 0, /* bitpos */ -+- complain_overflow_dont,/* complain_on_overflow */ -+- nds32_elf_ignore_reloc,/* special_function */ -+- "R_NDS32_RELAX_ENTRY", /* name */ -+- FALSE, /* partial_inplace */ -+- 0xffffffff, /* src_mask */ -+- 0xffffffff, /* dst_mask */ -+- FALSE), /* pcrel_offset */ -+- HOWTO (R_NDS32_GOT_SUFF, /* type */ -+- 0, /* rightshift */ -+- 2, /* size (0 = byte, 1 = short, 2 = long) */ -+- 32, /* bitsize */ -+- FALSE, /* pc_relative */ -+- 0, /* bitpos */ -+- complain_overflow_dont,/* complain_on_overflow */ -+- nds32_elf_ignore_reloc,/* special_function */ -+- "R_NDS32_GOT_SUFF", /* name */ -+- FALSE, /* partial_inplace */ -+- 0xffffffff, /* src_mask */ -+- 0xffffffff, /* dst_mask */ -+- FALSE), /* pcrel_offset */ -+- HOWTO (R_NDS32_GOTOFF_SUFF, /* type */ -+- 0, /* rightshift */ -+- 2, /* size (0 = byte, 1 = short, 2 = long) */ -+- 32, /* bitsize */ -+- FALSE, /* pc_relative */ -+- 0, /* bitpos */ -+- complain_overflow_bitfield, /* complain_on_overflow */ -+- nds32_elf_ignore_reloc,/* special_function */ -+- "R_NDS32_GOTOFF_SUFF", /* name */ -+- FALSE, /* partial_inplace */ -+- 0xffffffff, /* src_mask */ -+- 0xffffffff, /* dst_mask */ -+- FALSE), /* pcrel_offset */ -+- HOWTO (R_NDS32_PLT_GOT_SUFF, /* type */ -+- 0, /* rightshift */ -+- 2, /* size (0 = byte, 1 = short, 2 = long) */ -+- 32, /* bitsize */ -+- FALSE, /* pc_relative */ -+- 0, /* bitpos */ -+- complain_overflow_dont,/* complain_on_overflow */ -+- nds32_elf_ignore_reloc,/* special_function */ -+- "R_NDS32_PLT_GOT_SUFF",/* name */ -+- FALSE, /* partial_inplace */ -+- 0xffffffff, /* src_mask */ -+- 0xffffffff, /* dst_mask */ -+- FALSE), /* pcrel_offset */ -+- HOWTO (R_NDS32_MULCALL_SUFF, /* type */ -+- 0, /* rightshift */ -+- 2, /* size (0 = byte, 1 = short, 2 = long) */ -+- 32, /* bitsize */ -+- FALSE, /* pc_relative */ -+- 0, /* bitpos */ -+- complain_overflow_dont,/* complain_on_overflow */ -+- nds32_elf_ignore_reloc,/* special_function */ -+- "R_NDS32_MULCALL_SUFF",/* name */ -+- FALSE, /* partial_inplace */ -+- 0xffffffff, /* src_mask */ -+- 0xffffffff, /* dst_mask */ -+- FALSE), /* pcrel_offset */ -+- HOWTO (R_NDS32_PTR, /* type */ -+- 0, /* rightshift */ -+- 2, /* size (0 = byte, 1 = short, 2 = long) */ -+- 32, /* bitsize */ -+- FALSE, /* pc_relative */ -+- 0, /* bitpos */ -+- complain_overflow_dont,/* complain_on_overflow */ -+- nds32_elf_ignore_reloc,/* special_function */ -+- "R_NDS32_PTR", /* name */ -+- FALSE, /* partial_inplace */ -+- 0xffffffff, /* src_mask */ -+- 0xffffffff, /* dst_mask */ -+- FALSE), /* pcrel_offset */ -+- HOWTO (R_NDS32_PTR_COUNT, /* type */ -+- 0, /* rightshift */ -+- 2, /* size (0 = byte, 1 = short, 2 = long) */ -+- 32, /* bitsize */ -+- FALSE, /* pc_relative */ -+- 0, /* bitpos */ -+- complain_overflow_dont,/* complain_on_overflow */ -+- nds32_elf_ignore_reloc,/* special_function */ -+- "R_NDS32_PTR_COUNT", /* name */ -+- FALSE, /* partial_inplace */ -+- 0xffffffff, /* src_mask */ -+- 0xffffffff, /* dst_mask */ -+- FALSE), /* pcrel_offset */ -+- HOWTO (R_NDS32_PTR_RESOLVED, /* type */ -+- 0, /* rightshift */ -+- 2, /* size (0 = byte, 1 = short, 2 = long) */ -+- 32, /* bitsize */ -+- FALSE, /* pc_relative */ -+- 0, /* bitpos */ -+- complain_overflow_dont,/* complain_on_overflow */ -+- nds32_elf_ignore_reloc,/* special_function */ -+- "R_NDS32_PTR_RESOLVED",/* name */ -+- FALSE, /* partial_inplace */ -+- 0xffffffff, /* src_mask */ -+- 0xffffffff, /* dst_mask */ -+- FALSE), /* pcrel_offset */ -+- HOWTO (R_NDS32_PLTBLOCK, /* type */ -+- 0, /* rightshift */ -+- 2, /* size (0 = byte, 1 = short, 2 = long) */ -+- 32, /* bitsize */ -+- FALSE, /* pc_relative */ -+- 0, /* bitpos */ -+- complain_overflow_dont,/* complain_on_overflow */ -+- nds32_elf_ignore_reloc,/* special_function */ -+- "R_NDS32_PLTBLOCK", /* name */ -+- FALSE, /* partial_inplace */ -+- 0xffffffff, /* src_mask */ -+- 0xffffffff, /* dst_mask */ -+- FALSE), /* pcrel_offset */ -+- HOWTO (R_NDS32_RELAX_REGION_BEGIN, /* type */ -+- 0, /* rightshift */ -+- 2, /* size (0 = byte, 1 = short, 2 = long) */ -+- 32, /* bitsize */ -+- FALSE, /* pc_relative */ -+- 0, /* bitpos */ -+- complain_overflow_dont,/* complain_on_overflow */ -+- nds32_elf_ignore_reloc,/* special_function */ -+- "R_NDS32_RELAX_REGION_BEGIN", /* name */ -+- FALSE, /* partial_inplace */ -+- 0xffffffff, /* src_mask */ -+- 0xffffffff, /* dst_mask */ -+- FALSE), /* pcrel_offset */ -+- HOWTO (R_NDS32_RELAX_REGION_END, /* type */ -+- 0, /* rightshift */ -+- 2, /* size (0 = byte, 1 = short, 2 = long) */ -+- 32, /* bitsize */ -+- FALSE, /* pc_relative */ -+- 0, /* bitpos */ -+- complain_overflow_dont,/* complain_on_overflow */ -+- nds32_elf_ignore_reloc,/* special_function */ -+- "R_NDS32_RELAX_REGION_END", /* name */ -+- FALSE, /* partial_inplace */ -+- 0xffffffff, /* src_mask */ -+- 0xffffffff, /* dst_mask */ -+- FALSE), /* pcrel_offset */ -+- HOWTO (R_NDS32_MINUEND, /* type */ -+- 0, /* rightshift */ -+- 2, /* size (0 = byte, 1 = short, 2 = long) */ -+- 32, /* bitsize */ -+- FALSE, /* pc_relative */ -+- 0, /* bitpos */ -+- complain_overflow_dont,/* complain_on_overflow */ -+- nds32_elf_ignore_reloc,/* special_function */ -+- "R_NDS32_MINUEND", /* name */ -+- FALSE, /* partial_inplace */ -+- 0xffffffff, /* src_mask */ -+- 0xffffffff, /* dst_mask */ -+- FALSE), /* pcrel_offset */ -+- HOWTO (R_NDS32_SUBTRAHEND, /* type */ -+- 0, /* rightshift */ -+- 2, /* size (0 = byte, 1 = short, 2 = long) */ -+- 32, /* bitsize */ -+- FALSE, /* pc_relative */ -+- 0, /* bitpos */ -+- complain_overflow_dont,/* complain_on_overflow */ -+- nds32_elf_ignore_reloc,/* special_function */ -+- "R_NDS32_SUBTRAHEND", /* name */ -+- FALSE, /* partial_inplace */ -+- 0xffffffff, /* src_mask */ -+- 0xffffffff, /* dst_mask */ -+- FALSE), /* pcrel_offset */ -+- HOWTO (R_NDS32_DIFF8, /* type */ -+- 0, /* rightshift */ -+- 0, /* size (0 = byte, 1 = short, 2 = long) */ -+- 8, /* bitsize */ -+- FALSE, /* pc_relative */ -+- 0, /* bitpos */ -+- complain_overflow_dont,/* complain_on_overflow */ -+- nds32_elf_ignore_reloc,/* special_function */ -+- "R_NDS32_DIFF8", /* name */ -+- FALSE, /* partial_inplace */ -+- 0x000000ff, /* src_mask */ -+- 0x000000ff, /* dst_mask */ -+- FALSE), /* pcrel_offset */ -+- HOWTO (R_NDS32_DIFF16, /* type */ -+- 0, /* rightshift */ -+- 1, /* size (0 = byte, 1 = short, 2 = long) */ -+- 16, /* bitsize */ -+- FALSE, /* pc_relative */ -+- 0, /* bitpos */ -+- complain_overflow_dont,/* complain_on_overflow */ -+- nds32_elf_ignore_reloc,/* special_function */ -+- "R_NDS32_DIFF16", /* name */ -+- FALSE, /* partial_inplace */ -+- 0x0000ffff, /* src_mask */ -+- 0x0000ffff, /* dst_mask */ -+- FALSE), /* pcrel_offset */ -+- HOWTO (R_NDS32_DIFF32, /* type */ -+- 0, /* rightshift */ -+- 2, /* size (0 = byte, 1 = short, 2 = long) */ -+- 32, /* bitsize */ -+- FALSE, /* pc_relative */ -+- 0, /* bitpos */ -+- complain_overflow_dont,/* complain_on_overflow */ -+- nds32_elf_ignore_reloc,/* special_function */ -+- "R_NDS32_DIFF32", /* name */ -+- FALSE, /* partial_inplace */ -+- 0xffffffff, /* src_mask */ -+- 0xffffffff, /* dst_mask */ -+- FALSE), /* pcrel_offset */ -+- HOWTO (R_NDS32_DIFF_ULEB128, /* type */ -+- 0, /* rightshift */ -+- 0, /* size (0 = byte, 1 = short, 2 = long) */ -+- 0, /* bitsize */ -+- FALSE, /* pc_relative */ -+- 0, /* bitpos */ -+- complain_overflow_dont,/* complain_on_overflow */ -+- nds32_elf_ignore_reloc,/* special_function */ -+- "R_NDS32_DIFF_ULEB128",/* name */ -+- FALSE, /* partial_inplace */ -+- 0xffffffff, /* src_mask */ -+- 0xffffffff, /* dst_mask */ -+- FALSE), /* pcrel_offset */ -+- HOWTO (R_NDS32_DATA, /* type */ -+- 0, /* rightshift */ -+- 2, /* size (0 = byte, 1 = short, 2 = long) */ -+- 32, /* bitsize */ -+- FALSE, /* pc_relative */ -+- 0, /* bitpos */ -+- complain_overflow_dont,/* complain_on_overflow */ -+- nds32_elf_ignore_reloc,/* special_function */ -+- "R_NDS32_DATA", /* name */ -+- FALSE, /* partial_inplace */ -+- 0xffffffff, /* src_mask */ -+- 0xffffffff, /* dst_mask */ -+- FALSE), /* pcrel_offset */ -+- HOWTO (R_NDS32_TRAN, /* type */ -+- 0, /* rightshift */ -+- 2, /* size (0 = byte, 1 = short, 2 = long) */ -+- 32, /* bitsize */ -+- FALSE, /* pc_relative */ -+- 0, /* bitpos */ -+- complain_overflow_dont,/* complain_on_overflow */ -+- nds32_elf_ignore_reloc,/* special_function */ -+- "R_NDS32_TRAN", /* name */ -+- FALSE, /* partial_inplace */ -+- 0xffffffff, /* src_mask */ -+- 0xffffffff, /* dst_mask */ -+- FALSE), /* pcrel_offset */ -+- HOWTO (R_NDS32_TLS_LE_ADD, /* type */ -+- 0, /* rightshift */ -+- 2, /* size (0 = byte, 1 = short, 2 = long) */ -+- 32, /* bitsize */ -+- FALSE, /* pc_relative */ -+- 0, /* bitpos */ -+- complain_overflow_dont, /* complain_on_overflow */ -+- nds32_elf_ignore_reloc, /* special_function */ -+- "R_NDS32_TLS_LE_ADD", /* name */ -+- FALSE, /* partial_inplace */ -+- 0xffffffff, /* src_mask */ -+- 0xffffffff, /* dst_mask */ -+- FALSE), /* pcrel_offset */ -+- HOWTO (R_NDS32_TLS_LE_LS, /* type */ -+- 0, /* rightshift */ -+- 2, /* size (0 = byte, 1 = short, 2 = long) */ -+- 32, /* bitsize */ -+- FALSE, /* pc_relative */ -+- 0, /* bitpos */ -+- complain_overflow_dont, /* complain_on_overflow */ -+- nds32_elf_ignore_reloc, /* special_function */ -+- "R_NDS32_TLS_LE_LS", /* name */ -+- FALSE, /* partial_inplace */ -+- 0xffffffff, /* src_mask */ -+- 0xffffffff, /* dst_mask */ -+- FALSE), /* pcrel_offset */ -+- HOWTO (R_NDS32_EMPTY, /* type */ -+- 0, /* rightshift */ -+- 2, /* size (0 = byte, 1 = short, 2 = long) */ -+- 32, /* bitsize */ -+- FALSE, /* pc_relative */ -+- 0, /* bitpos */ -+- complain_overflow_dont, /* complain_on_overflow */ -+- nds32_elf_ignore_reloc, /* special_function */ -+- "R_NDS32_EMPTY", /* name */ -+- FALSE, /* partial_inplace */ -+- 0xffffffff, /* src_mask */ -+- 0xffffffff, /* dst_mask */ -+- FALSE), /* pcrel_offset */ -++#define HOWTO3(C, R, S, B, P, BI, O, SF, NAME, INPLACE, MASKSRC, MASKDST, PC) \ -++ [C-R_NDS32_RELAX_ENTRY] = HOWTO(C, R, S, B, P, BI, O, SF, NAME, INPLACE, MASKSRC, MASKDST, PC) -++ -++static reloc_howto_type nds32_elf_relax_howto_table[] = { -++ HOWTO3 (R_NDS32_RELAX_ENTRY, /* type */ -++ 0, /* rightshift */ -++ 2, /* size (0 = byte, 1 = short, 2 = long) */ -++ 32, /* bitsize */ -++ FALSE, /* pc_relative */ -++ 0, /* bitpos */ -++ complain_overflow_dont,/* complain_on_overflow */ -++ nds32_elf_ignore_reloc,/* special_function */ -++ "R_NDS32_RELAX_ENTRY", /* name */ -++ FALSE, /* partial_inplace */ -++ 0xffffffff, /* src_mask */ -++ 0xffffffff, /* dst_mask */ -++ FALSE), /* pcrel_offset */ -++ HOWTO3 (R_NDS32_GOT_SUFF, /* type */ -++ 0, /* rightshift */ -++ 2, /* size (0 = byte, 1 = short, 2 = long) */ -++ 32, /* bitsize */ -++ FALSE, /* pc_relative */ -++ 0, /* bitpos */ -++ complain_overflow_dont,/* complain_on_overflow */ -++ nds32_elf_ignore_reloc,/* special_function */ -++ "R_NDS32_GOT_SUFF", /* name */ -++ FALSE, /* partial_inplace */ -++ 0xffffffff, /* src_mask */ -++ 0xffffffff, /* dst_mask */ -++ FALSE), /* pcrel_offset */ -++ HOWTO3 (R_NDS32_GOTOFF_SUFF, /* type */ -++ 0, /* rightshift */ -++ 2, /* size (0 = byte, 1 = short, 2 = long) */ -++ 32, /* bitsize */ -++ FALSE, /* pc_relative */ -++ 0, /* bitpos */ -++ complain_overflow_bitfield,/* complain_on_overflow */ -++ nds32_elf_ignore_reloc,/* special_function */ -++ "R_NDS32_GOTOFF_SUFF", /* name */ -++ FALSE, /* partial_inplace */ -++ 0xffffffff, /* src_mask */ -++ 0xffffffff, /* dst_mask */ -++ FALSE), /* pcrel_offset */ -++ HOWTO3 (R_NDS32_PLT_GOT_SUFF, /* type */ -++ 0, /* rightshift */ -++ 2, /* size (0 = byte, 1 = short, 2 = long) */ -++ 32, /* bitsize */ -++ FALSE, /* pc_relative */ -++ 0, /* bitpos */ -++ complain_overflow_dont,/* complain_on_overflow */ -++ nds32_elf_ignore_reloc,/* special_function */ -++ "R_NDS32_PLT_GOT_SUFF",/* name */ -++ FALSE, /* partial_inplace */ -++ 0xffffffff, /* src_mask */ -++ 0xffffffff, /* dst_mask */ -++ FALSE), /* pcrel_offset */ -++ HOWTO3 (R_NDS32_MULCALL_SUFF, /* type */ -++ 0, /* rightshift */ -++ 2, /* size (0 = byte, 1 = short, 2 = long) */ -++ 32, /* bitsize */ -++ FALSE, /* pc_relative */ -++ 0, /* bitpos */ -++ complain_overflow_dont,/* complain_on_overflow */ -++ nds32_elf_ignore_reloc,/* special_function */ -++ "R_NDS32_MULCALL_SUFF",/* name */ -++ FALSE, /* partial_inplace */ -++ 0xffffffff, /* src_mask */ -++ 0xffffffff, /* dst_mask */ -++ FALSE), /* pcrel_offset */ -++ HOWTO3 (R_NDS32_PTR, /* type */ -++ 0, /* rightshift */ -++ 2, /* size (0 = byte, 1 = short, 2 = long) */ -++ 32, /* bitsize */ -++ FALSE, /* pc_relative */ -++ 0, /* bitpos */ -++ complain_overflow_dont,/* complain_on_overflow */ -++ nds32_elf_ignore_reloc,/* special_function */ -++ "R_NDS32_PTR", /* name */ -++ FALSE, /* partial_inplace */ -++ 0xffffffff, /* src_mask */ -++ 0xffffffff, /* dst_mask */ -++ FALSE), /* pcrel_offset */ -++ HOWTO3 (R_NDS32_PTR_COUNT, /* type */ -++ 0, /* rightshift */ -++ 2, /* size (0 = byte, 1 = short, 2 = long) */ -++ 32, /* bitsize */ -++ FALSE, /* pc_relative */ -++ 0, /* bitpos */ -++ complain_overflow_dont,/* complain_on_overflow */ -++ nds32_elf_ignore_reloc,/* special_function */ -++ "R_NDS32_PTR_COUNT", /* name */ -++ FALSE, /* partial_inplace */ -++ 0xffffffff, /* src_mask */ -++ 0xffffffff, /* dst_mask */ -++ FALSE), /* pcrel_offset */ -++ HOWTO3 (R_NDS32_PTR_RESOLVED, /* type */ -++ 0, /* rightshift */ -++ 2, /* size (0 = byte, 1 = short, 2 = long) */ -++ 32, /* bitsize */ -++ FALSE, /* pc_relative */ -++ 0, /* bitpos */ -++ complain_overflow_dont,/* complain_on_overflow */ -++ nds32_elf_ignore_reloc,/* special_function */ -++ "R_NDS32_PTR_RESOLVED",/* name */ -++ FALSE, /* partial_inplace */ -++ 0xffffffff, /* src_mask */ -++ 0xffffffff, /* dst_mask */ -++ FALSE), /* pcrel_offset */ -++ HOWTO3 (R_NDS32_PLTBLOCK, /* type */ -++ 0, /* rightshift */ -++ 2, /* size (0 = byte, 1 = short, 2 = long) */ -++ 32, /* bitsize */ -++ FALSE, /* pc_relative */ -++ 0, /* bitpos */ -++ complain_overflow_dont,/* complain_on_overflow */ -++ nds32_elf_ignore_reloc,/* special_function */ -++ "R_NDS32_PLTBLOCK", /* name */ -++ FALSE, /* partial_inplace */ -++ 0xffffffff, /* src_mask */ -++ 0xffffffff, /* dst_mask */ -++ FALSE), /* pcrel_offset */ -++ HOWTO3 (R_NDS32_RELAX_REGION_BEGIN,/* type */ -++ 0, /* rightshift */ -++ 2, /* size (0 = byte, 1 = short, 2 = long) */ -++ 32, /* bitsize */ -++ FALSE, /* pc_relative */ -++ 0, /* bitpos */ -++ complain_overflow_dont,/* complain_on_overflow */ -++ nds32_elf_ignore_reloc,/* special_function */ -++ "R_NDS32_RELAX_REGION_BEGIN",/* name */ -++ FALSE, /* partial_inplace */ -++ 0xffffffff, /* src_mask */ -++ 0xffffffff, /* dst_mask */ -++ FALSE), /* pcrel_offset */ -++ HOWTO3 (R_NDS32_RELAX_REGION_END,/* type */ -++ 0, /* rightshift */ -++ 2, /* size (0 = byte, 1 = short, 2 = long) */ -++ 32, /* bitsize */ -++ FALSE, /* pc_relative */ -++ 0, /* bitpos */ -++ complain_overflow_dont,/* complain_on_overflow */ -++ nds32_elf_ignore_reloc,/* special_function */ -++ "R_NDS32_RELAX_REGION_END",/* name */ -++ FALSE, /* partial_inplace */ -++ 0xffffffff, /* src_mask */ -++ 0xffffffff, /* dst_mask */ -++ FALSE), /* pcrel_offset */ -++ HOWTO3 (R_NDS32_MINUEND, /* type */ -++ 0, /* rightshift */ -++ 2, /* size (0 = byte, 1 = short, 2 = long) */ -++ 32, /* bitsize */ -++ FALSE, /* pc_relative */ -++ 0, /* bitpos */ -++ complain_overflow_dont,/* complain_on_overflow */ -++ nds32_elf_ignore_reloc,/* special_function */ -++ "R_NDS32_MINUEND", /* name */ -++ FALSE, /* partial_inplace */ -++ 0xffffffff, /* src_mask */ -++ 0xffffffff, /* dst_mask */ -++ FALSE), /* pcrel_offset */ -++ HOWTO3 (R_NDS32_SUBTRAHEND, /* type */ -++ 0, /* rightshift */ -++ 2, /* size (0 = byte, 1 = short, 2 = long) */ -++ 32, /* bitsize */ -++ FALSE, /* pc_relative */ -++ 0, /* bitpos */ -++ complain_overflow_dont,/* complain_on_overflow */ -++ nds32_elf_ignore_reloc,/* special_function */ -++ "R_NDS32_SUBTRAHEND", /* name */ -++ FALSE, /* partial_inplace */ -++ 0xffffffff, /* src_mask */ -++ 0xffffffff, /* dst_mask */ -++ FALSE), /* pcrel_offset */ -++ HOWTO3 (R_NDS32_DIFF8, /* type */ -++ 0, /* rightshift */ -++ 0, /* size (0 = byte, 1 = short, 2 = long) */ -++ 8, /* bitsize */ -++ FALSE, /* pc_relative */ -++ 0, /* bitpos */ -++ complain_overflow_dont,/* complain_on_overflow */ -++ nds32_elf_ignore_reloc,/* special_function */ -++ "R_NDS32_DIFF8", /* name */ -++ FALSE, /* partial_inplace */ -++ 0x000000ff, /* src_mask */ -++ 0x000000ff, /* dst_mask */ -++ FALSE), /* pcrel_offset */ -++ HOWTO3 (R_NDS32_DIFF16, /* type */ -++ 0, /* rightshift */ -++ 1, /* size (0 = byte, 1 = short, 2 = long) */ -++ 16, /* bitsize */ -++ FALSE, /* pc_relative */ -++ 0, /* bitpos */ -++ complain_overflow_dont,/* complain_on_overflow */ -++ nds32_elf_ignore_reloc,/* special_function */ -++ "R_NDS32_DIFF16", /* name */ -++ FALSE, /* partial_inplace */ -++ 0x0000ffff, /* src_mask */ -++ 0x0000ffff, /* dst_mask */ -++ FALSE), /* pcrel_offset */ -++ HOWTO3 (R_NDS32_DIFF32, /* type */ -++ 0, /* rightshift */ -++ 2, /* size (0 = byte, 1 = short, 2 = long) */ -++ 32, /* bitsize */ -++ FALSE, /* pc_relative */ -++ 0, /* bitpos */ -++ complain_overflow_dont,/* complain_on_overflow */ -++ nds32_elf_ignore_reloc,/* special_function */ -++ "R_NDS32_DIFF32", /* name */ -++ FALSE, /* partial_inplace */ -++ 0xffffffff, /* src_mask */ -++ 0xffffffff, /* dst_mask */ -++ FALSE), /* pcrel_offset */ -++ HOWTO3 (R_NDS32_DIFF_ULEB128, /* type */ -++ 0, /* rightshift */ -++ 0, /* size (0 = byte, 1 = short, 2 = long) */ -++ 0, /* bitsize */ -++ FALSE, /* pc_relative */ -++ 0, /* bitpos */ -++ complain_overflow_dont,/* complain_on_overflow */ -++ nds32_elf_ignore_reloc,/* special_function */ -++ "R_NDS32_DIFF_ULEB128",/* name */ -++ FALSE, /* partial_inplace */ -++ 0xffffffff, /* src_mask */ -++ 0xffffffff, /* dst_mask */ -++ FALSE), /* pcrel_offset */ -++ HOWTO3 (R_NDS32_DATA, /* type */ -++ 0, /* rightshift */ -++ 2, /* size (0 = byte, 1 = short, 2 = long) */ -++ 32, /* bitsize */ -++ FALSE, /* pc_relative */ -++ 0, /* bitpos */ -++ complain_overflow_dont,/* complain_on_overflow */ -++ nds32_elf_ignore_reloc,/* special_function */ -++ "R_NDS32_DATA", /* name */ -++ FALSE, /* partial_inplace */ -++ 0xffffffff, /* src_mask */ -++ 0xffffffff, /* dst_mask */ -++ FALSE), /* pcrel_offset */ -++ HOWTO3 (R_NDS32_TRAN, /* type */ -++ 0, /* rightshift */ -++ 2, /* size (0 = byte, 1 = short, 2 = long) */ -++ 32, /* bitsize */ -++ FALSE, /* pc_relative */ -++ 0, /* bitpos */ -++ complain_overflow_dont,/* complain_on_overflow */ -++ nds32_elf_ignore_reloc,/* special_function */ -++ "R_NDS32_TRAN", /* name */ -++ FALSE, /* partial_inplace */ -++ 0xffffffff, /* src_mask */ -++ 0xffffffff, /* dst_mask */ -++ FALSE), /* pcrel_offset */ -++ HOWTO3 (R_NDS32_EMPTY, /* type */ -++ 0, /* rightshift */ -++ 2, /* size (0 = byte, 1 = short, 2 = long) */ -++ 32, /* bitsize */ -++ FALSE, /* pc_relative */ -++ 0, /* bitpos */ -++ complain_overflow_dont,/* complain_on_overflow */ -++ nds32_elf_ignore_reloc,/* special_function */ -++ "R_NDS32_EMPTY", /* name */ -++ FALSE, /* partial_inplace */ -++ 0xffffffff, /* src_mask */ -++ 0xffffffff, /* dst_mask */ -++ FALSE), /* pcrel_offset */ -++ -++ HOWTO3 (R_NDS32_TLS_LE_ADD, /* type */ -++ 0, /* rightshift */ -++ 2, /* size (0 = byte, 1 = short, 2 = long) */ -++ 32, /* bitsize */ -++ FALSE, /* pc_relative */ -++ 0, /* bitpos */ -++ complain_overflow_dont,/* complain_on_overflow */ -++ nds32_elf_ignore_reloc,/* special_function */ -++ "R_NDS32_TLS_LE_ADD", /* name */ -++ FALSE, /* partial_inplace */ -++ 0xffffffff, /* src_mask */ -++ 0xffffffff, /* dst_mask */ -++ FALSE), /* pcrel_offset */ -++ HOWTO3 (R_NDS32_TLS_LE_LS, /* type */ -++ 0, /* rightshift */ -++ 2, /* size (0 = byte, 1 = short, 2 = long) */ -++ 32, /* bitsize */ -++ FALSE, /* pc_relative */ -++ 0, /* bitpos */ -++ complain_overflow_dont,/* complain_on_overflow */ -++ nds32_elf_ignore_reloc,/* special_function */ -++ "R_NDS32_TLS_LE_LS", /* name */ -++ FALSE, /* partial_inplace */ -++ 0xffffffff, /* src_mask */ -++ 0xffffffff, /* dst_mask */ -++ FALSE), /* pcrel_offset */ -++ -++ HOWTO3 (R_NDS32_TLS_IEGP_LW, /* type */ -++ 0, /* rightshift */ -++ 2, /* size (0 = byte, 1 = short, 2 = long) */ -++ 32, /* bitsize */ -++ FALSE, /* pc_relative */ -++ 0, /* bitpos */ -++ complain_overflow_dont,/* complain_on_overflow */ -++ nds32_elf_ignore_reloc,/* special_function */ -++ "R_NDS32_TLS_IEGP_LW", /* name */ -++ FALSE, /* partial_inplace */ -++ 0xffffffff, /* src_mask */ -++ 0xffffffff, /* dst_mask */ -++ FALSE), /* pcrel_offset */ -++ -++ /* TLS GD/LD description address base addition. */ -++ HOWTO3 (R_NDS32_TLS_DESC_ADD, /* type */ -++ 0, /* rightshift */ -++ 2, /* size (0 = byte, 1 = short, 2 = long) */ -++ 32, /* bitsize */ -++ FALSE, /* pc_relative */ -++ 0, /* bitpos */ -++ complain_overflow_dont,/* complain_on_overflow */ -++ nds32_elf_ignore_reloc,/* special_function */ -++ "R_NDS32_TLS_DESC_ADD",/* name */ -++ FALSE, /* partial_inplace */ -++ 0xffffffff, /* src_mask */ -++ 0xffffffff, /* dst_mask */ -++ FALSE), /* pcrel_offset */ -++ -++ /* TLS GD/LD description function load. */ -++ HOWTO3 (R_NDS32_TLS_DESC_FUNC,/* type */ -++ 0, /* rightshift */ -++ 2, /* size (0 = byte, 1 = short, 2 = long) */ -++ 32, /* bitsize */ -++ FALSE, /* pc_relative */ -++ 0, /* bitpos */ -++ complain_overflow_dont,/* complain_on_overflow */ -++ nds32_elf_ignore_reloc,/* special_function */ -++ "R_NDS32_TLS_DESC_FUNC",/* name */ -++ FALSE, /* partial_inplace */ -++ 0xffffffff, /* src_mask */ -++ 0xffffffff, /* dst_mask */ -++ FALSE), /* pcrel_offset */ -++ -++ /* TLS DESC resolve function call. */ -++ HOWTO3 (R_NDS32_TLS_DESC_CALL,/* type */ -++ 0, /* rightshift */ -++ 2, /* size (0 = byte, 1 = short, 2 = long) */ -++ 32, /* bitsize */ -++ FALSE, /* pc_relative */ -++ 0, /* bitpos */ -++ complain_overflow_dont,/* complain_on_overflow */ -++ nds32_elf_ignore_reloc,/* special_function */ -++ "R_NDS32_TLS_DESC_CALL",/* name */ -++ FALSE, /* partial_inplace */ -++ 0xffffffff, /* src_mask */ -++ 0xffffffff, /* dst_mask */ -++ FALSE), /* pcrel_offset */ -++ -++ /* TLS DESC variable access. */ -++ HOWTO3 (R_NDS32_TLS_DESC_MEM, /* type */ -++ 0, /* rightshift */ -++ 2, /* size (0 = byte, 1 = short, 2 = long) */ -++ 32, /* bitsize */ -++ FALSE, /* pc_relative */ -++ 0, /* bitpos */ -++ complain_overflow_dont,/* complain_on_overflow */ -++ nds32_elf_ignore_reloc,/* special_function */ -++ "R_NDS32_TLS_DESC_MEM",/* name */ -++ FALSE, /* partial_inplace */ -++ 0xffffffff, /* src_mask */ -++ 0xffffffff, /* dst_mask */ -++ FALSE), /* pcrel_offset */ -++ -++ /* TLS GD/LD description mark (@tlsdec). */ -++ HOWTO3 (R_NDS32_RELAX_REMOVE, /* type */ -++ 0, /* rightshift */ -++ 2, /* size (0 = byte, 1 = short, 2 = long) */ -++ 32, /* bitsize */ -++ FALSE, /* pc_relative */ -++ 0, /* bitpos */ -++ complain_overflow_dont,/* complain_on_overflow */ -++ nds32_elf_ignore_reloc,/* special_function */ -++ "R_NDS32_REMOVE", /* name */ -++ FALSE, /* partial_inplace */ -++ 0xffffffff, /* src_mask */ -++ 0xffffffff, /* dst_mask */ -++ FALSE), /* pcrel_offset */ -++ -++ /* TLS GD/LD description mark (@tlsdec). */ -++ HOWTO3 (R_NDS32_RELAX_GROUP, /* type */ -++ 0, /* rightshift */ -++ 2, /* size (0 = byte, 1 = short, 2 = long) */ -++ 32, /* bitsize */ -++ FALSE, /* pc_relative */ -++ 0, /* bitpos */ -++ complain_overflow_dont,/* complain_on_overflow */ -++ nds32_elf_ignore_reloc,/* special_function */ -++ "R_NDS32_GROUP", /* name */ -++ FALSE, /* partial_inplace */ -++ 0xffffffff, /* src_mask */ -++ 0xffffffff, /* dst_mask */ -++ FALSE), /* pcrel_offset */ -++ -++ /* LA and FLSI relaxation. */ -++ HOWTO3 (R_NDS32_LSI, /* type */ -++ 0, /* rightshift */ -++ 2, /* size (0 = byte, 1 = short, 2 = long) */ -++ 32, /* bitsize */ -++ FALSE, /* pc_relative */ -++ 0, /* bitpos */ -++ complain_overflow_dont,/* complain_on_overflow */ -++ nds32_elf_ignore_reloc,/* special_function */ -++ "R_NDS32_LSI", /* name */ -++ FALSE, /* partial_inplace */ -++ 0xffffffff, /* src_mask */ -++ 0xffffffff, /* dst_mask */ -++ FALSE), /* pcrel_offset */ -+ }; -+- -+ -++ -++static unsigned long dl_tlsdesc_lazy_trampoline[] = -++{ -++ 0x46200000, /* sethi $r2,#0x0 */ -++ 0x58210000, /* ori $r2,$r2,#0x0 */ -++ 0x40217400, /* add $r2,$r2,$gp */ -++ 0x04210000, /* lwi $r2,[$r2+#0x0] */ -++ 0x46300000, /* sethi $r3,#0x0 */ -++ 0x58318000, /* ori $r3,$r3,#0x0 */ -++ 0x4031f400, /* add $r3,$r3,$gp */ -++ 0x4a000800, /* jr $r2 */ -++}; -++ -++/* === code === */ -++ -++static void -++nds32_put_trampoline (void *contents, const unsigned long *template, -++ unsigned count) -++{ -++ unsigned ix; -++ -++ for (ix = 0; ix != count; ix++) -++ { -++ unsigned long insn = template[ix]; -++ bfd_putb32 (insn, (char *) contents + ix * 4); -++ } -++} -++ -+ /* nds32_insertion_sort sorts an array with nmemb elements of size size. -+ This prototype is the same as qsort (). */ -+ -+@@ -2224,7 +2713,7 @@ nds32_insertion_sort (void *base, size_t nmemb, size_t size, -+ { -+ char *ptr = (char *) base; -+ int i, j; -+- char *tmp = xmalloc (size); -++ char *tmp = alloca (size); -+ -+ /* If i is less than j, i is inserted before j. -+ -+@@ -2248,7 +2737,6 @@ nds32_insertion_sort (void *base, size_t nmemb, size_t size, -+ memmove (ptr + (j + 1) * size, ptr + j * size, (i - j) * size); -+ memcpy (ptr + j * size, tmp, size); -+ } -+- free (tmp); -+ } -+ -+ /* Sort relocation by r_offset. -+@@ -2277,14 +2765,13 @@ compar_reloc (const void *lhs, const void *rhs) -+ } -+ -+ /* Functions listed below are only used for old relocs. -+- * nds32_elf_9_pcrel_reloc -+- * nds32_elf_do_9_pcrel_reloc -+- * nds32_elf_hi20_reloc -+- * nds32_elf_relocate_hi20 -+- * nds32_elf_lo12_reloc -+- * nds32_elf_sda15_reloc -+- * nds32_elf_generic_reloc -+- */ -++ nds32_elf_9_pcrel_reloc -++ nds32_elf_do_9_pcrel_reloc -++ nds32_elf_hi20_reloc -++ nds32_elf_relocate_hi20 -++ nds32_elf_lo12_reloc -++ nds32_elf_sda15_reloc -++ nds32_elf_generic_reloc */ -+ -+ /* Handle the R_NDS32_9_PCREL & R_NDS32_9_PCREL_RELA reloc. */ -+ -+@@ -2705,8 +3192,7 @@ struct nds32_reloc_map_entry -+ unsigned char elf_reloc_val; -+ }; -+ -+-static const struct nds32_reloc_map_entry nds32_reloc_map[] = -+-{ -++static const struct nds32_reloc_map_entry nds32_reloc_map[] = { -+ {BFD_RELOC_NONE, R_NDS32_NONE}, -+ {BFD_RELOC_16, R_NDS32_16_RELA}, -+ {BFD_RELOC_32, R_NDS32_32_RELA}, -+@@ -2765,6 +3251,7 @@ static const struct nds32_reloc_map_entry nds32_reloc_map[] = -+ {BFD_RELOC_NDS32_LONGJUMP5, R_NDS32_LONGJUMP5}, -+ {BFD_RELOC_NDS32_LONGJUMP6, R_NDS32_LONGJUMP6}, -+ {BFD_RELOC_NDS32_LONGJUMP7, R_NDS32_LONGJUMP7}, -++ {BFD_RELOC_NDS32_SECURITY_16, R_NDS32_SECURITY_16}, -+ {BFD_RELOC_NDS32_LOADSTORE, R_NDS32_LOADSTORE}, -+ {BFD_RELOC_NDS32_9_FIXED, R_NDS32_9_FIXED_RELA}, -+ {BFD_RELOC_NDS32_15_FIXED, R_NDS32_15_FIXED_RELA}, -+@@ -2822,15 +3309,52 @@ static const struct nds32_reloc_map_entry nds32_reloc_map[] = -+ {BFD_RELOC_NDS32_TLS_LE_LS, R_NDS32_TLS_LE_LS}, -+ {BFD_RELOC_NDS32_TLS_IE_HI20, R_NDS32_TLS_IE_HI20}, -+ {BFD_RELOC_NDS32_TLS_IE_LO12S2, R_NDS32_TLS_IE_LO12S2}, -+- {BFD_RELOC_NDS32_TLS_TPOFF, R_NDS32_TLS_TPOFF}, -+ {BFD_RELOC_NDS32_TLS_LE_20, R_NDS32_TLS_LE_20}, -+ {BFD_RELOC_NDS32_TLS_LE_15S0, R_NDS32_TLS_LE_15S0}, -+ {BFD_RELOC_NDS32_TLS_LE_15S1, R_NDS32_TLS_LE_15S1}, -+ {BFD_RELOC_NDS32_TLS_LE_15S2, R_NDS32_TLS_LE_15S2}, -++ -++ {BFD_RELOC_NDS32_TLS_DESC, R_NDS32_TLS_DESC}, -++ {BFD_RELOC_NDS32_TLS_DESC_HI20, R_NDS32_TLS_DESC_HI20}, -++ {BFD_RELOC_NDS32_TLS_DESC_LO12, R_NDS32_TLS_DESC_LO12}, -++ {BFD_RELOC_NDS32_TLS_DESC_ADD, R_NDS32_TLS_DESC_ADD}, -++ {BFD_RELOC_NDS32_TLS_DESC_FUNC, R_NDS32_TLS_DESC_FUNC}, -++ {BFD_RELOC_NDS32_TLS_DESC_CALL, R_NDS32_TLS_DESC_CALL}, -++ {BFD_RELOC_NDS32_TLS_DESC_MEM, R_NDS32_TLS_DESC_MEM}, -++ {BFD_RELOC_NDS32_TLS_DESC_20, R_NDS32_TLS_DESC_20}, -++ {BFD_RELOC_NDS32_TLS_DESC_SDA17S2, R_NDS32_TLS_DESC_SDA17S2}, -++ {BFD_RELOC_NDS32_TLS_IE_LO12, R_NDS32_TLS_IE_LO12}, -++ {BFD_RELOC_NDS32_TLS_IEGP_HI20, R_NDS32_TLS_IEGP_HI20}, -++ {BFD_RELOC_NDS32_TLS_IEGP_LO12, R_NDS32_TLS_IEGP_LO12}, -++ {BFD_RELOC_NDS32_TLS_IEGP_LO12S2, R_NDS32_TLS_IEGP_LO12S2}, -++ {BFD_RELOC_NDS32_TLS_IEGP_LW, R_NDS32_TLS_IEGP_LW}, -++ -++ {BFD_RELOC_NDS32_REMOVE, R_NDS32_RELAX_REMOVE}, -++ {BFD_RELOC_NDS32_GROUP, R_NDS32_RELAX_GROUP}, -++ -++ {BFD_RELOC_NDS32_ICT_HI20, R_NDS32_ICT_HI20}, -++ {BFD_RELOC_NDS32_ICT_LO12, R_NDS32_ICT_LO12}, -++ {BFD_RELOC_NDS32_ICT_25PC, R_NDS32_ICT_25PC}, -++ {BFD_RELOC_NDS32_ICT_LO12S2, R_NDS32_ICT_LO12S2}, -++ -++ {BFD_RELOC_NDS32_LSI, R_NDS32_LSI}, -+ }; -+ -+ /* Patch tag. */ -+ -++/* Reserve space for COUNT dynamic relocations in relocation selection -++ SRELOC. */ -++ -++static inline void -++elf32_nds32_allocate_dynrelocs (struct bfd_link_info *info, asection *sreloc, -++ bfd_size_type count) -++{ -++ BFD_ASSERT (elf_hash_table (info)->dynamic_sections_created); -++ if (sreloc == NULL) -++ abort (); -++ sreloc->size += sizeof (Elf32_External_Rela) * count; -++} -++ -+ static reloc_howto_type * -+ bfd_elf32_bfd_reloc_name_lookup (bfd *abfd ATTRIBUTE_UNUSED, -+ const char *r_name) -+@@ -2860,6 +3384,13 @@ bfd_elf32_bfd_reloc_type_table_lookup (enum elf_nds32_reloc_type code) -+ } -+ else -+ { -++ if ((size_t) (code - R_NDS32_RELAX_ENTRY) >= -++ ARRAY_SIZE (nds32_elf_relax_howto_table)) -++ { -++ int i = code; -++ i += 1; -++ } -++ -+ BFD_ASSERT ((size_t) (code - R_NDS32_RELAX_ENTRY) -+ < ARRAY_SIZE (nds32_elf_relax_howto_table)); -+ return &nds32_elf_relax_howto_table[code - R_NDS32_RELAX_ENTRY]; -+@@ -2876,7 +3407,7 @@ bfd_elf32_bfd_reloc_type_lookup (bfd *abfd ATTRIBUTE_UNUSED, -+ { -+ if (nds32_reloc_map[i].bfd_reloc_val == code) -+ return bfd_elf32_bfd_reloc_type_table_lookup -+- (nds32_reloc_map[i].elf_reloc_val); -++ (nds32_reloc_map[i].elf_reloc_val); -+ } -+ -+ return NULL; -+@@ -2897,6 +3428,8 @@ nds32_info_to_howto_rel (bfd *abfd ATTRIBUTE_UNUSED, arelent *cache_ptr, -+ _bfd_error_handler (_("%B: invalid NDS32 reloc number: %d"), abfd, r_type); -+ r_type = 0; -+ } -++ -++ BFD_ASSERT (ELF32_R_TYPE (dst->r_info) <= R_NDS32_GNU_VTENTRY); -+ cache_ptr->howto = bfd_elf32_bfd_reloc_type_table_lookup (r_type); -+ } -+ -+@@ -2922,29 +3455,29 @@ nds32_elf_grok_prstatus (bfd *abfd, Elf_Internal_Note *note) -+ switch (note->descsz) -+ { -+ case 0x114: -+- /* Linux/NDS32 32-bit, ABI1 */ -++ /* Linux/NDS32 32-bit, ABI1 */ -+ -+- /* pr_cursig */ -++ /* pr_cursig */ -+ elf_tdata (abfd)->core->signal = bfd_get_16 (abfd, note->descdata + 12); -+ -+- /* pr_pid */ -++ /* pr_pid */ -+ elf_tdata (abfd)->core->pid = bfd_get_32 (abfd, note->descdata + 24); -+ -+- /* pr_reg */ -++ /* pr_reg */ -+ offset = 72; -+ size = 200; -+ break; -+ -+ case 0xfc: -+- /* Linux/NDS32 32-bit */ -++ /* Linux/NDS32 32-bit */ -+ -+- /* pr_cursig */ -++ /* pr_cursig */ -+ elf_tdata (abfd)->core->signal = bfd_get_16 (abfd, note->descdata + 12); -+ -+- /* pr_pid */ -++ /* pr_pid */ -+ elf_tdata (abfd)->core->pid = bfd_get_32 (abfd, note->descdata + 24); -+ -+- /* pr_reg */ -++ /* pr_reg */ -+ offset = 72; -+ size = 176; -+ break; -+@@ -2964,7 +3497,7 @@ nds32_elf_grok_psinfo (bfd *abfd, Elf_Internal_Note *note) -+ switch (note->descsz) -+ { -+ case 124: -+- /* Linux/NDS32 */ -++ /* Linux/NDS32 */ -+ -+ /* __kernel_uid_t, __kernel_gid_t are short on NDS32 platform. */ -+ elf_tdata (abfd)->core->program = -+@@ -3097,20 +3630,20 @@ nds32_elf_final_sda_base (bfd *output_bfd, struct bfd_link_info *info, -+ struct elf_nds32_link_hash_table *table; -+ struct bfd_link_hash_entry *h, *h2; -+ long unsigned int total = 0; -++ asection *first = NULL, *final = NULL, *temp; -++ bfd_vma sda_base = 0; -+ -+ h = bfd_link_hash_lookup (info->hash, "_SDA_BASE_", FALSE, FALSE, TRUE); -+ if (!h || (h->type != bfd_link_hash_defined && h->type != bfd_link_hash_defweak)) -+ { -+- asection *first = NULL, *final = NULL, *temp; -+- bfd_vma sda_base; -+ /* The first section must be 4-byte aligned to promise _SDA_BASE_ being -+ 4 byte-aligned. Therefore, it has to set the first section ".data" -+ 4 byte-aligned. */ -+ static const char sec_name[SDA_SECTION_NUM][10] = -+- { -+- ".data", ".got", ".sdata_d", ".sdata_w", ".sdata_h", ".sdata_b", -+- ".sbss_b", ".sbss_h", ".sbss_w", ".sbss_d" -+- }; -++ { -++ ".data", ".got", ".sdata_d", ".sdata_w", ".sdata_h", ".sdata_b", -++ ".sbss_b", ".sbss_h", ".sbss_w", ".sbss_d" -++ }; -+ size_t i = 0; -+ -+ if (output_bfd->sections == NULL) -+@@ -3120,7 +3653,7 @@ nds32_elf_final_sda_base (bfd *output_bfd, struct bfd_link_info *info, -+ } -+ -+ /* Get the first and final section. */ -+- while (i < sizeof (sec_name) / sizeof (sec_name [0])) -++ while (i < ARRAY_SIZE (sec_name)) -+ { -+ temp = bfd_get_section_by_name (output_bfd, sec_name[i]); -+ if (temp && !first && (temp->size != 0 || temp->rawsize != 0)) -+@@ -3162,7 +3695,7 @@ nds32_elf_final_sda_base (bfd *output_bfd, struct bfd_link_info *info, -+ -+ /* Find the section sda_base located. */ -+ i = 0; -+- while (i < sizeof (sec_name) / sizeof (sec_name [0])) -++ while (i < ARRAY_SIZE (sec_name)) -+ { -+ final = bfd_get_section_by_name (output_bfd, sec_name[i]); -+ if (final && (final->size != 0 || final->rawsize != 0) -+@@ -3177,17 +3710,44 @@ nds32_elf_final_sda_base (bfd *output_bfd, struct bfd_link_info *info, -+ } -+ else -+ { -+- /* There is not any data section in output bfd, and set _SDA_BASE_ in -+- first output section. */ -+- first = output_bfd->sections; -+- while (first && first->size == 0 && first->rawsize == 0) -+- first = first->next; -++ /* If there is not any default data section in output bfd, try to find -++ the first data section. If no data section be found, just simplily -++ choose the first output section. */ -++ temp = output_bfd->sections; -++ while (temp) -++ { -++ if (temp->flags & SEC_ALLOC -++ && (((temp->flags & SEC_DATA) -++ && ((temp->flags & SEC_READONLY) == 0)) -++ || (temp->flags & SEC_LOAD) == 0) -++ && (temp->size != 0 || temp->rawsize != 0)) -++ { -++ if (!first) -++ first = temp; -++ final = temp; -++ } -++ temp = temp->next; -++ } -++ -++ /* There is no data or bss section. */ -++ if (!first || (first->size == 0 && first->rawsize == 0)) -++ { -++ first = output_bfd->sections; -++ while (first && first->size == 0 && first->rawsize == 0) -++ first = first->next; -++ } -++ -++ /* There is no concrete section. */ -+ if (!first) -+ { -+ *psb = elf_gp (output_bfd); -+ return bfd_reloc_ok; -+ } -+- sda_base = first->vma + first->rawsize; -++ -++ if (final && (final->vma + final->rawsize - first->vma) <= 0x4000) -++ sda_base = final->vma / 2 + final->rawsize / 2 + first->vma / 2; -++ else -++ sda_base = first->vma + 0x2000; -+ } -+ -+ sda_base -= first->vma; -+@@ -3201,24 +3761,34 @@ nds32_elf_final_sda_base (bfd *output_bfd, struct bfd_link_info *info, -+ -+ sda_rela_sec = first; -+ -+- table = nds32_elf_hash_table (info); -+- relax_fp_as_gp = table->relax_fp_as_gp; -+- if (relax_fp_as_gp) -+- { -+- h2 = bfd_link_hash_lookup (info->hash, FP_BASE_NAME, -+- FALSE, FALSE, FALSE); -+- /* Define a weak FP_BASE_NAME here to prevent the undefined symbol. -+- And set FP equal to SDA_BASE to do relaxation for -+- la $fp, _FP_BASE_. */ -+- if (!_bfd_generic_link_add_one_symbol -+- (info, output_bfd, FP_BASE_NAME, BSF_GLOBAL | BSF_WEAK, -+- first, (bfd_vma) sda_base, (const char *) NULL, -+- FALSE, get_elf_backend_data (output_bfd)->collect, &h2)) -+- return FALSE; -+- } -+ } -+ -+- if (add_symbol) -++ /* Set _FP_BASE_ to _SDA_BASE_. */ -++ table = nds32_elf_hash_table (info); -++ relax_fp_as_gp = table->relax_fp_as_gp; -++ h2 = bfd_link_hash_lookup (info->hash, FP_BASE_NAME, FALSE, FALSE, FALSE); -++ /* _SDA_BASE_ is difined in linker script. */ -++ if (!first) -++ { -++ first = h->u.def.section; -++ sda_base = h->u.def.value; -++ } -++ -++ if (relax_fp_as_gp && h2 -++ && (h2->type == bfd_link_hash_undefweak -++ || h2->type == bfd_link_hash_undefined)) -++ { -++ /* Define a weak FP_BASE_NAME here to prevent the undefined symbol. -++ And set FP equal to SDA_BASE to do relaxation for -++ la $fp, _FP_BASE_. */ -++ if (!_bfd_generic_link_add_one_symbol -++ (info, output_bfd, FP_BASE_NAME, BSF_GLOBAL | BSF_WEAK, -++ first, sda_base, (const char *) NULL, -++ FALSE, get_elf_backend_data (output_bfd)->collect, &h2)) -++ return FALSE; -++ } -++ -++ if (add_symbol == TRUE) -+ { -+ if (h) -+ { -+@@ -3275,6 +3845,8 @@ nds32_elf_link_hash_newfunc (struct bfd_hash_entry *entry, -+ eh = (struct elf_nds32_link_hash_entry *) ret; -+ eh->dyn_relocs = NULL; -+ eh->tls_type = GOT_UNKNOWN; -++ eh->offset_to_gp = 0; -++ eh->indirect_call = FALSE; -+ } -+ -+ return (struct bfd_hash_entry *) ret; -+@@ -3303,22 +3875,61 @@ nds32_elf_link_hash_table_create (bfd *abfd) -+ return NULL; -+ } -+ -++ ret->sdynbss = NULL; -++ ret->srelbss = NULL; -++ ret->sym_ld_script = NULL; -++ -+ return &ret->root.root; -+ } -+ -++/* Create .got, .gotplt, and .rela.got sections in DYNOBJ, and set up -++ shortcuts to them in our hash table. */ -++ -++static bfd_boolean -++create_got_section (bfd *dynobj, struct bfd_link_info *info) -++{ -++ struct elf_link_hash_table *ehtab; -++ -++ if (!_bfd_elf_create_got_section (dynobj, info)) -++ return FALSE; -++ -++ ehtab = elf_hash_table (info); -++ ehtab->sgot = bfd_get_section_by_name (dynobj, ".got"); -++ ehtab->sgotplt = bfd_get_section_by_name (dynobj, ".got.plt"); -++ if (!ehtab->sgot || !ehtab->sgotplt) -++ abort (); -++ -++ /* _bfd_elf_create_got_section will create it for us. */ -++ ehtab->srelgot = bfd_get_section_by_name (dynobj, ".rela.got"); -++ if (ehtab->srelgot == NULL -++ || !bfd_set_section_flags (dynobj, ehtab->srelgot, -++ (SEC_ALLOC | SEC_LOAD | SEC_HAS_CONTENTS -++ | SEC_IN_MEMORY | SEC_LINKER_CREATED -++ | SEC_READONLY)) -++ || !bfd_set_section_alignment (dynobj, ehtab->srelgot, 2)) -++ return FALSE; -++ -++ return TRUE; -++} -++ -+ /* Create dynamic sections when linking against a dynamic object. */ -+ -+ static bfd_boolean -+ nds32_elf_create_dynamic_sections (bfd *abfd, struct bfd_link_info *info) -+ { -++ struct elf_link_hash_table *ehtab; -+ struct elf_nds32_link_hash_table *htab; -+ flagword flags, pltflags; -+ register asection *s; -+ const struct elf_backend_data *bed; -+ int ptralign = 2; /* 32-bit */ -++ const char *secname; -++ char *relname; -++ flagword secflags; -++ asection *sec; -+ -+ bed = get_elf_backend_data (abfd); -+- -++ ehtab = elf_hash_table (info); -+ htab = nds32_elf_hash_table (info); -+ -+ /* We need to create .plt, .rel[a].plt, .got, .got.plt, .dynbss, and -+@@ -3335,7 +3946,7 @@ nds32_elf_create_dynamic_sections (bfd *abfd, struct bfd_link_info *info) -+ pltflags |= SEC_READONLY; -+ -+ s = bfd_make_section (abfd, ".plt"); -+- htab->root.splt = s; -++ ehtab->splt = s; -+ if (s == NULL -+ || !bfd_set_section_flags (abfd, s, pltflags) -+ || !bfd_set_section_alignment (abfd, s, bed->plt_alignment)) -+@@ -3364,40 +3975,33 @@ nds32_elf_create_dynamic_sections (bfd *abfd, struct bfd_link_info *info) -+ -+ s = bfd_make_section (abfd, -+ bed->default_use_rela_p ? ".rela.plt" : ".rel.plt"); -+- htab->root.srelplt = s; -++ ehtab->srelplt = s; -+ if (s == NULL -+ || !bfd_set_section_flags (abfd, s, flags | SEC_READONLY) -+ || !bfd_set_section_alignment (abfd, s, ptralign)) -+ return FALSE; -+ -+- if (htab->root.sgot == NULL && !_bfd_elf_create_got_section (abfd, info)) -++ if (ehtab->sgot == NULL && !create_got_section (abfd, info)) -+ return FALSE; -+ -+- { -+- const char *secname; -+- char *relname; -+- flagword secflags; -+- asection *sec; -+- -+- for (sec = abfd->sections; sec; sec = sec->next) -+- { -+- secflags = bfd_get_section_flags (abfd, sec); -+- if ((secflags & (SEC_DATA | SEC_LINKER_CREATED)) -+- || ((secflags & SEC_HAS_CONTENTS) != SEC_HAS_CONTENTS)) -+- continue; -+- secname = bfd_get_section_name (abfd, sec); -+- relname = (char *) bfd_malloc ((bfd_size_type) strlen (secname) + 6); -+- strcpy (relname, ".rela"); -+- strcat (relname, secname); -+- if (bfd_get_section_by_name (abfd, secname)) -+- continue; -+- s = bfd_make_section (abfd, relname); -+- if (s == NULL -+- || !bfd_set_section_flags (abfd, s, flags | SEC_READONLY) -+- || !bfd_set_section_alignment (abfd, s, ptralign)) -+- return FALSE; -+- } -+- } -++ for (sec = abfd->sections; sec; sec = sec->next) -++ { -++ secflags = bfd_get_section_flags (abfd, sec); -++ if ((secflags & (SEC_DATA | SEC_LINKER_CREATED)) -++ || ((secflags & SEC_HAS_CONTENTS) != SEC_HAS_CONTENTS)) -++ continue; -++ secname = bfd_get_section_name (abfd, sec); -++ relname = (char *) bfd_malloc ((bfd_size_type) strlen (secname) + 6); -++ strcpy (relname, ".rela"); -++ strcat (relname, secname); -++ if (bfd_get_section_by_name (abfd, secname)) -++ continue; -++ s = bfd_make_section (abfd, relname); -++ if (s == NULL -++ || !bfd_set_section_flags (abfd, s, flags | SEC_READONLY) -++ || !bfd_set_section_alignment (abfd, s, ptralign)) -++ return FALSE; -++ } -+ -+ if (bed->want_dynbss) -+ { -+@@ -3453,8 +4057,8 @@ nds32_elf_copy_indirect_symbol (struct bfd_link_info *info, -+ { -+ if (edir->dyn_relocs != NULL) -+ { -+- struct elf_dyn_relocs **pp; -+- struct elf_dyn_relocs *p; -++ struct elf_nds32_dyn_relocs **pp; -++ struct elf_nds32_dyn_relocs *p; -+ -+ if (ind->root.type == bfd_link_hash_indirect) -+ abort (); -+@@ -3463,7 +4067,7 @@ nds32_elf_copy_indirect_symbol (struct bfd_link_info *info, -+ list. Merge any entries against the same section. */ -+ for (pp = &eind->dyn_relocs; (p = *pp) != NULL;) -+ { -+- struct elf_dyn_relocs *q; -++ struct elf_nds32_dyn_relocs *q; -+ -+ for (q = edir->dyn_relocs; q != NULL; q = q->next) -+ if (q->sec == p->sec) -+@@ -3483,25 +4087,18 @@ nds32_elf_copy_indirect_symbol (struct bfd_link_info *info, -+ eind->dyn_relocs = NULL; -+ } -+ -+- _bfd_elf_link_hash_copy_indirect (info, dir, ind); -+-} -+- -+-/* Find dynamic relocs for H that apply to read-only sections. */ -+- -+-static asection * -+-readonly_dynrelocs (struct elf_link_hash_entry *h) -+-{ -+- struct elf_dyn_relocs *p; -+- -+- for (p = elf32_nds32_hash_entry (h)->dyn_relocs; p != NULL; p = p->next) -++ if (ind->root.type == bfd_link_hash_indirect) -+ { -+- asection *s = p->sec->output_section; -+- -+- if (s != NULL && (s->flags & SEC_READONLY) != 0) -+- return p->sec; -++ if (dir->got.refcount <= 0) -++ { -++ edir->tls_type = eind->tls_type; -++ eind->tls_type = GOT_UNKNOWN; -++ } -+ } -+- return NULL; -++ -++ _bfd_elf_link_hash_copy_indirect (info, dir, ind); -+ } -++ -+ -+ /* Adjust a symbol defined by a dynamic object and referenced by a -+ regular object. The current definition is in some section of the -+@@ -3514,6 +4111,8 @@ nds32_elf_adjust_dynamic_symbol (struct bfd_link_info *info, -+ struct elf_link_hash_entry *h) -+ { -+ struct elf_nds32_link_hash_table *htab; -++ struct elf_nds32_link_hash_entry *eh; -++ struct elf_nds32_dyn_relocs *p; -+ bfd *dynobj; -+ asection *s; -+ unsigned int power_of_two; -+@@ -3558,7 +4157,8 @@ nds32_elf_adjust_dynamic_symbol (struct bfd_link_info *info, -+ if (h->is_weakalias) -+ { -+ struct elf_link_hash_entry *def = weakdef (h); -+- BFD_ASSERT (def->root.type == bfd_link_hash_defined); -++ BFD_ASSERT (def->root.type == bfd_link_hash_defined -++ || def->root.type == bfd_link_hash_defweak); -+ h->root.u.def.section = def->root.u.def.section; -+ h->root.u.def.value = def->root.u.def.value; -+ return TRUE; -+@@ -3580,15 +4180,24 @@ nds32_elf_adjust_dynamic_symbol (struct bfd_link_info *info, -+ return TRUE; -+ -+ /* If -z nocopyreloc was given, we won't generate them either. */ -+- if (0 && info->nocopyreloc) -++ if (info->nocopyreloc) -+ { -+ h->non_got_ref = 0; -+ return TRUE; -+ } -+ -+- /* If we don't find any dynamic relocs in read-only sections, then -+- we'll be keeping the dynamic relocs and avoiding the copy reloc. */ -+- if (0 && !readonly_dynrelocs (h)) -++ eh = (struct elf_nds32_link_hash_entry *) h; -++ for (p = eh->dyn_relocs; p != NULL; p = p->next) -++ { -++ s = p->sec->output_section; -++ if (s != NULL && (s->flags & (SEC_READONLY | SEC_HAS_CONTENTS)) != 0) -++ break; -++ } -++ -++ /* If we didn't find any dynamic relocs in sections which needs the -++ copy reloc, then we'll be keeping the dynamic relocs and avoiding -++ the copy reloc. */ -++ if (p == NULL) -+ { -+ h->non_got_ref = 0; -+ return TRUE; -+@@ -3653,25 +4262,31 @@ static bfd_boolean -+ allocate_dynrelocs (struct elf_link_hash_entry *h, void *inf) -+ { -+ struct bfd_link_info *info; -++ struct elf_link_hash_table *ehtab; -+ struct elf_nds32_link_hash_table *htab; -+ struct elf_nds32_link_hash_entry *eh; -+- struct elf_dyn_relocs *p; -++ struct elf_nds32_dyn_relocs *p; -+ -+ if (h->root.type == bfd_link_hash_indirect) -+ return TRUE; -+ -++ /* When warning symbols are created, they **replace** the "real" -++ entry in the hash table, thus we never get to see the real -++ symbol in a hash traversal. So look at it now. */ -+ if (h->root.type == bfd_link_hash_warning) -+- /* When warning symbols are created, they **replace** the "real" -+- entry in the hash table, thus we never get to see the real -+- symbol in a hash traversal. So look at it now. */ -+ h = (struct elf_link_hash_entry *) h->root.u.i.link; -+ -++ eh = (struct elf_nds32_link_hash_entry *) h; -++ -+ info = (struct bfd_link_info *) inf; -++ ehtab = elf_hash_table (info); -+ htab = nds32_elf_hash_table (info); -++ if (htab == NULL) -++ return FALSE; -+ -+- eh = (struct elf_nds32_link_hash_entry *) h; -+- -+- if (htab->root.dynamic_sections_created && h->plt.refcount > 0) -++ if ((htab->root.dynamic_sections_created || h->type == STT_GNU_IFUNC) -++ && h->plt.refcount > 0 -++ && !(bfd_link_pie (info) && h->def_regular)) -+ { -+ /* Make sure this symbol is output as a dynamic symbol. -+ Undefined weak syms won't yet be marked as dynamic. */ -+@@ -3683,7 +4298,7 @@ allocate_dynrelocs (struct elf_link_hash_entry *h, void *inf) -+ -+ if (WILL_CALL_FINISH_DYNAMIC_SYMBOL (1, bfd_link_pic (info), h)) -+ { -+- asection *s = htab->root.splt; -++ asection *s = ehtab->splt; -+ -+ /* If this is the first .plt entry, make room for the special -+ first entry. */ -+@@ -3708,10 +4323,12 @@ allocate_dynrelocs (struct elf_link_hash_entry *h, void *inf) -+ -+ /* We also need to make an entry in the .got.plt section, which -+ will be placed in the .got section by the linker script. */ -+- htab->root.sgotplt->size += 4; -++ ehtab->sgotplt->size += 4; -+ -+ /* We also need to make an entry in the .rel.plt section. */ -+- htab->root.srelplt->size += sizeof (Elf32_External_Rela); -++ ehtab->srelplt->size += sizeof (Elf32_External_Rela); -++ if (htab->tls_desc_trampoline) -++ htab->next_tls_desc_index++; -+ } -+ else -+ { -+@@ -3727,7 +4344,7 @@ allocate_dynrelocs (struct elf_link_hash_entry *h, void *inf) -+ -+ if (h->got.refcount > 0) -+ { -+- asection *s; -++ asection *sgot; -+ bfd_boolean dyn; -+ int tls_type = elf32_nds32_hash_entry (h)->tls_type; -+ -+@@ -3739,22 +4356,44 @@ allocate_dynrelocs (struct elf_link_hash_entry *h, void *inf) -+ return FALSE; -+ } -+ -+- s = htab->root.sgot; -+- h->got.offset = s->size; -++ sgot = elf_hash_table (info)->sgot; -++ h->got.offset = sgot->size; -+ -+ if (tls_type == GOT_UNKNOWN) -+ abort (); -+- else if (tls_type == GOT_NORMAL -+- || tls_type == GOT_TLS_IE) -+- /* Need a GOT slot. */ -+- s->size += 4; -++ -++ /* Non-TLS symbols, and TLS_IE need one GOT slot. */ -++ if (tls_type & (GOT_NORMAL | GOT_TLS_IE | GOT_TLS_IEGP)) -++ sgot->size += 4; -++ else -++ { -++ /* TLS_DESC, TLS_GD, and TLS_LD need 2 consecutive GOT slots. */ -++ if (tls_type & GOT_TLS_DESC) -++ sgot->size += 8; -++ } -+ -+ dyn = htab->root.dynamic_sections_created; -++ -+ if (WILL_CALL_FINISH_DYNAMIC_SYMBOL (dyn, bfd_link_pic (info), h)) -+- htab->root.srelgot->size += sizeof (Elf32_External_Rela); -++ { -++ if (tls_type == GOT_TLS_DESC && htab->tls_desc_trampoline) -++ { -++ /* TLS_DESC with trampoline needs a relocation slot -++ within .rela.plt. */ -++ htab->num_tls_desc++; -++ ehtab->srelplt->size += sizeof (Elf32_External_Rela); -++ htab->tls_trampoline = -1; -++ } -++ else -++ { -++ /* other relocations, including TLS_DESC without trampoline, need -++ a relocation slot within .rela.got. */ -++ ehtab->srelgot->size += sizeof (Elf32_External_Rela); -++ } -++ } -+ } -+ else -+- h->got.offset = (bfd_vma) - 1; -++ h->got.offset = (bfd_vma) -1; -+ -+ if (eh->dyn_relocs == NULL) -+ return TRUE; -+@@ -3769,7 +4408,7 @@ allocate_dynrelocs (struct elf_link_hash_entry *h, void *inf) -+ { -+ if (h->def_regular && (h->forced_local || info->symbolic)) -+ { -+- struct elf_dyn_relocs **pp; -++ struct elf_nds32_dyn_relocs **pp; -+ -+ for (pp = &eh->dyn_relocs; (p = *pp) != NULL;) -+ { -+@@ -3810,7 +4449,7 @@ allocate_dynrelocs (struct elf_link_hash_entry *h, void *inf) -+ -+ eh->dyn_relocs = NULL; -+ -+- keep:; -++keep:; -+ } -+ -+ /* Finally, allocate space. */ -+@@ -3823,29 +4462,50 @@ allocate_dynrelocs (struct elf_link_hash_entry *h, void *inf) -+ return TRUE; -+ } -+ -+-/* Set DF_TEXTREL if we find any dynamic relocs that apply to -+- read-only sections. */ -++/* Add relocation REL to the end of relocation section SRELOC. */ -++ -++static void -++elf32_nds32_add_dynreloc (bfd *output_bfd, -++ struct bfd_link_info *info ATTRIBUTE_UNUSED, -++ asection *sreloc, Elf_Internal_Rela *rel) -++{ -++ bfd_byte *loc; -++ if (sreloc == NULL) -++ abort (); -++ -++ loc = sreloc->contents; -++ loc += sreloc->reloc_count++ * sizeof (Elf32_External_Rela); -++ if (sreloc->reloc_count * sizeof (Elf32_External_Rela) > sreloc->size) -++ abort (); -++ -++ bfd_elf32_swap_reloca_out (output_bfd, rel, loc); -++} -++ -++/* Find any dynamic relocs that apply to read-only sections. */ -+ -+ static bfd_boolean -+-maybe_set_textrel (struct elf_link_hash_entry *h, void *info_p) -++readonly_dynrelocs (struct elf_link_hash_entry *h, void *inf) -+ { -+- asection *sec; -++ struct elf_nds32_link_hash_entry *eh; -++ struct elf_nds32_dyn_relocs *p; -+ -+- if (h->root.type == bfd_link_hash_indirect) -+- return TRUE; -++ if (h->root.type == bfd_link_hash_warning) -++ h = (struct elf_link_hash_entry *) h->root.u.i.link; -+ -+- sec = readonly_dynrelocs (h); -+- if (sec != NULL) -++ eh = (struct elf_nds32_link_hash_entry *) h; -++ for (p = eh->dyn_relocs; p != NULL; p = p->next) -+ { -+- struct bfd_link_info *info = (struct bfd_link_info *) info_p; -++ asection *s = p->sec->output_section; -++ -++ if (s != NULL && (s->flags & SEC_READONLY) != 0) -++ { -++ struct bfd_link_info *info = (struct bfd_link_info *) inf; -+ -+- info->flags |= DF_TEXTREL; -+- info->callbacks->minfo -+- (_("%B: dynamic relocation against `%T' in read-only section `%A'\n"), -+- sec->owner, h->root.root.string, sec); -++ info->flags |= DF_TEXTREL; -+ -+- /* Not an error, just cut short the traversal. */ -+- return FALSE; -++ /* Not an error, just cut short the traversal. */ -++ return FALSE; -++ } -+ } -+ return TRUE; -+ } -+@@ -3856,20 +4516,24 @@ static bfd_boolean -+ nds32_elf_size_dynamic_sections (bfd *output_bfd ATTRIBUTE_UNUSED, -+ struct bfd_link_info *info) -+ { -+- struct elf_nds32_link_hash_table *htab; -+ bfd *dynobj; -+ asection *s; -++ bfd_boolean plt; -+ bfd_boolean relocs; -+ bfd *ibfd; -++ struct elf_nds32_link_hash_table *htab; -+ -+ htab = nds32_elf_hash_table (info); -+- dynobj = htab->root.dynobj; -++ if (htab == NULL) -++ return FALSE; -++ -++ dynobj = elf_hash_table (info)->dynobj; -+ BFD_ASSERT (dynobj != NULL); -+ -+- if (htab->root.dynamic_sections_created) -++ if (elf_hash_table (info)->dynamic_sections_created) -+ { -+ /* Set the contents of the .interp section to the interpreter. */ -+- if (bfd_link_executable (info) && !info->nointerp) -++ if (bfd_link_executable (info)) -+ { -+ s = bfd_get_section_by_name (dynobj, ".interp"); -+ BFD_ASSERT (s != NULL); -+@@ -3886,16 +4550,19 @@ nds32_elf_size_dynamic_sections (bfd *output_bfd ATTRIBUTE_UNUSED, -+ bfd_signed_vma *end_local_got; -+ bfd_size_type locsymcount; -+ Elf_Internal_Shdr *symtab_hdr; -+- asection *srel; -++ asection *sgot; -++ char *local_tls_type; -++ unsigned long symndx; -++ bfd_vma *local_tlsdesc_gotent; -+ -+ if (bfd_get_flavour (ibfd) != bfd_target_elf_flavour) -+ continue; -+ -+ for (s = ibfd->sections; s != NULL; s = s->next) -+ { -+- struct elf_dyn_relocs *p; -++ struct elf_nds32_dyn_relocs *p; -+ -+- for (p = ((struct elf_dyn_relocs *) -++ for (p = ((struct elf_nds32_dyn_relocs *) -+ elf_section_data (s)->local_dynrel); -+ p != NULL; p = p->next) -+ { -+@@ -3909,8 +4576,8 @@ nds32_elf_size_dynamic_sections (bfd *output_bfd ATTRIBUTE_UNUSED, -+ } -+ else if (p->count != 0) -+ { -+- srel = elf_section_data (p->sec)->sreloc; -+- srel->size += p->count * sizeof (Elf32_External_Rela); -++ asection *sreloc = elf_section_data (p->sec)->sreloc; -++ sreloc->size += p->count * sizeof (Elf32_External_Rela); -+ if ((p->sec->output_section->flags & SEC_READONLY) != 0) -+ info->flags |= DF_TEXTREL; -+ } -+@@ -3924,19 +4591,57 @@ nds32_elf_size_dynamic_sections (bfd *output_bfd ATTRIBUTE_UNUSED, -+ symtab_hdr = &elf_tdata (ibfd)->symtab_hdr; -+ locsymcount = symtab_hdr->sh_info; -+ end_local_got = local_got + locsymcount; -+- s = htab->root.sgot; -+- srel = htab->root.srelgot; -+- for (; local_got < end_local_got; ++local_got) -++ sgot = elf_hash_table (info)->sgot; -++ local_tls_type = elf32_nds32_local_got_tls_type (ibfd); -++ local_tlsdesc_gotent = elf32_nds32_local_tlsdesc_gotent (ibfd); -++ for (symndx = 0; local_got < end_local_got; -++ ++local_got, ++local_tls_type, ++local_tlsdesc_gotent, ++symndx) -+ { -+ if (*local_got > 0) -+ { -+- *local_got = s->size; -+- s->size += 4; -+- if (bfd_link_pic (info)) -+- srel->size += sizeof (Elf32_External_Rela); -++ int num_of_got_entry_needed = 0; -++ *local_got = sgot->size; -++ *local_tlsdesc_gotent = sgot->size; -++ -++ /* TLS_NORMAL, and TLS_IE need one slot in .got. */ -++ if (*local_tls_type & (GOT_NORMAL | GOT_TLS_IE | GOT_TLS_IEGP)) -++ num_of_got_entry_needed = 1; -++ /* TLS_GD, TLS_LD, and TLS_DESC need an 8-byte structure in the GOT. */ -++ else if (*local_tls_type & GOT_TLS_DESC) -++ num_of_got_entry_needed = 2; -++ -++ sgot->size += (num_of_got_entry_needed << 2); -++ -++ /* non-relax-able TLS_DESCs need a slot in .rela.plt. -++ others need a slot in .rela.got. */ -++ if (*local_tls_type == GOT_TLS_DESC) -++ { -++ if (bfd_link_pic (info)) -++ { -++ if (htab->tls_desc_trampoline) -++ { -++ htab->num_tls_desc++; -++ htab->root.srelplt->size += sizeof (Elf32_External_Rela); -++ htab->tls_trampoline = -1; -++ } -++ else -++ htab->root.srelgot->size += sizeof (Elf32_External_Rela); -++ } -++ else -++ { -++ /* TLS_DESC -> TLS_LE */ -++ } -++ } -++ else -++ { -++ htab->root.srelgot->size += sizeof (Elf32_External_Rela); -++ } -+ } -+ else -+- *local_got = (bfd_vma) - 1; -++ { -++ *local_got = (bfd_vma) -1; -++ *local_tlsdesc_gotent = (bfd_vma) -1; -++ } -+ } -+ } -+ -+@@ -3944,8 +4649,36 @@ nds32_elf_size_dynamic_sections (bfd *output_bfd ATTRIBUTE_UNUSED, -+ sym dynamic relocs. */ -+ elf_link_hash_traverse (&htab->root, allocate_dynrelocs, (void *) info); -+ -++ /* For every jump slot reserved in the sgotplt, reloc_count is -++ incremented. However, when we reserve space for TLS descriptors, -++ it's not incremented, so in order to compute the space reserved -++ for them, it suffices to multiply the reloc count by the jump -++ slot size. */ -++ if (htab->tls_desc_trampoline && htab->root.srelplt) -++ htab->sgotplt_jump_table_size = elf32_nds32_compute_jump_table_size (htab); -++ -++ if (htab->tls_trampoline) -++ { -++ htab->tls_trampoline = htab->root.splt->size; -++ -++ /* If we're not using lazy TLS relocations, don't generate the -++ PLT and GOT entries they require. */ -++ if (!(info->flags & DF_BIND_NOW)) -++ { -++ htab->dt_tlsdesc_got = htab->root.sgot->size; -++ htab->root.sgot->size += 4; -++ -++ htab->dt_tlsdesc_plt = htab->root.splt->size; -++ htab->root.splt->size += 4 * ARRAY_SIZE (dl_tlsdesc_lazy_trampoline); -++ } -++ } -++ -+ /* We now have determined the sizes of the various dynamic sections. -+ Allocate memory for them. */ -++ /* The check_relocs and adjust_dynamic_symbol entry points have -++ determined the sizes of the various dynamic sections. Allocate -++ memory for them. */ -++ plt = FALSE; -+ relocs = FALSE; -+ for (s = dynobj->sections; s != NULL; s = s->next) -+ { -+@@ -3956,18 +4689,19 @@ nds32_elf_size_dynamic_sections (bfd *output_bfd ATTRIBUTE_UNUSED, -+ { -+ /* Strip this section if we don't need it; see the -+ comment below. */ -++ plt = s->size != 0; -+ } -+- else if (s == htab->root.sgot) -++ else if (s == elf_hash_table (info)->sgot) -+ { -+ got_size += s->size; -+ } -+- else if (s == htab->root.sgotplt) -++ else if (s == elf_hash_table (info)->sgotplt) -+ { -+ got_size += s->size; -+ } -+ else if (strncmp (bfd_get_section_name (dynobj, s), ".rela", 5) == 0) -+ { -+- if (s->size != 0 && s != htab->root.srelplt) -++ if (s->size != 0 && s != elf_hash_table (info)->srelplt) -+ relocs = TRUE; -+ -+ /* We use the reloc_count field as a counter if we need -+@@ -4013,16 +4747,15 @@ nds32_elf_size_dynamic_sections (bfd *output_bfd ATTRIBUTE_UNUSED, -+ must add the entries now so that we get the correct size for -+ the .dynamic section. The DT_DEBUG entry is filled in by the -+ dynamic linker and used by the debugger. */ -+-#define add_dynamic_entry(TAG, VAL) \ -+- _bfd_elf_add_dynamic_entry (info, TAG, VAL) -++#define add_dynamic_entry(TAG, VAL) _bfd_elf_add_dynamic_entry (info, TAG, VAL) -+ -+- if (!bfd_link_pic (info)) -++ if (bfd_link_executable (info)) -+ { -+ if (!add_dynamic_entry (DT_DEBUG, 0)) -+ return FALSE; -+ } -+ -+- if (htab->root.splt->size != 0) -++ if (elf_hash_table (info)->splt->size != 0) -+ { -+ if (!add_dynamic_entry (DT_PLTGOT, 0) -+ || !add_dynamic_entry (DT_PLTRELSZ, 0) -+@@ -4031,6 +4764,14 @@ nds32_elf_size_dynamic_sections (bfd *output_bfd ATTRIBUTE_UNUSED, -+ return FALSE; -+ } -+ -++ if (htab->tls_desc_trampoline && plt) -++ { -++ if (htab->dt_tlsdesc_plt -++ && (!add_dynamic_entry (DT_TLSDESC_PLT, 0) -++ || !add_dynamic_entry (DT_TLSDESC_GOT, 0))) -++ return FALSE; -++ } -++ -+ if (relocs) -+ { -+ if (!add_dynamic_entry (DT_RELA, 0) -+@@ -4041,7 +4782,7 @@ nds32_elf_size_dynamic_sections (bfd *output_bfd ATTRIBUTE_UNUSED, -+ /* If any dynamic relocs apply to a read-only section, -+ then we need a DT_TEXTREL entry. */ -+ if ((info->flags & DF_TEXTREL) == 0) -+- elf_link_hash_traverse (&htab->root, maybe_set_textrel, -++ elf_link_hash_traverse (&htab->root, readonly_dynrelocs, -+ (void *) info); -+ -+ if ((info->flags & DF_TEXTREL) != 0) -+@@ -4076,10 +4817,11 @@ nds32_relocate_contents (reloc_howto_type *howto, bfd *input_bfd, -+ switch (size) -+ { -+ default: -++ case 0: -++ case 1: -++ case 8: -+ abort (); -+ break; -+- case 0: -+- return bfd_reloc_ok; -+ case 2: -+ x = bfd_getb16 (location); -+ break; -+@@ -4297,9 +5039,9 @@ nds32_elf_output_symbol_hook (struct bfd_link_info *info, -+ else -+ source = input_sec->owner->filename; -+ -+- fprintf (sym_ld_script, "\t%s = 0x%08lx;\t /* %s */\n", -++ fprintf (sym_ld_script, "\t%s = 0x%08lx;\t /* %s */\n", -+ h->root.root.string, -+- (long) (h->root.u.def.value -++ (h->root.u.def.value -+ + h->root.u.def.section->output_section->vma -+ + h->root.u.def.section->output_offset), source); -+ } -+@@ -4340,59 +5082,252 @@ nds32_elf_output_symbol_hook (struct bfd_link_info *info, -+ section, which means that the addend must be adjusted -+ accordingly. */ -+ -++/* Return the base VMA address which should be subtracted from real addresses -++ when resolving @dtpoff relocation. -++ This is PT_TLS segment p_vaddr. */ -++ -++/* Return the relocation value for @tpoff relocation -++ if STT_TLS virtual address is ADDRESS. */ -++ -++/* Return the relocation value for @gottpoff relocation -++ if STT_TLS virtual address is ADDRESS. */ -+ static bfd_vma -+-dtpoff_base (struct bfd_link_info *info) -++gottpoff (struct bfd_link_info *info, bfd_vma address) -+ { -++ bfd_vma tp_base; -++ bfd_vma tp_offset; -++ -+ /* If tls_sec is NULL, we should have signalled an error already. */ -+ if (elf_hash_table (info)->tls_sec == NULL) -+ return 0; -+- return elf_hash_table (info)->tls_sec->vma; -+-} -+- -+-static bfd_boolean -+-nds32_elf_relocate_section (bfd * output_bfd ATTRIBUTE_UNUSED, -+- struct bfd_link_info * info, -+- bfd * input_bfd, -+- asection * input_section, -+- bfd_byte * contents, -+- Elf_Internal_Rela * relocs, -+- Elf_Internal_Sym * local_syms, -+- asection ** local_sections) -+-{ -+- Elf_Internal_Shdr *symtab_hdr; -+- struct elf_link_hash_entry **sym_hashes; -+- Elf_Internal_Rela *rel, *relend; -+- bfd_boolean ret = TRUE; /* Assume success. */ -+- int align = 0; -+- bfd_reloc_status_type r; -+- const char *errmsg = NULL; -+- bfd_vma gp; -+- struct elf_nds32_link_hash_table *htab; -+- bfd *dynobj; -+- bfd_vma *local_got_offsets; -+- asection *sgot, *splt, *sreloc; -+- bfd_vma high_address; -+- struct elf_nds32_link_hash_table *table; -+- int eliminate_gc_relocs; -+- bfd_vma fpbase_addr; -+ -+- symtab_hdr = &elf_tdata (input_bfd)->symtab_hdr; -+- sym_hashes = elf_sym_hashes (input_bfd); -+- htab = nds32_elf_hash_table (info); -+- high_address = bfd_get_section_limit (input_bfd, input_section); -++ tp_base = elf_hash_table (info)->tls_sec->vma; -++ tp_offset = address - tp_base; -+ -+- dynobj = htab->root.dynobj; -+- local_got_offsets = elf_local_got_offsets (input_bfd); -++ return tp_offset; -++} -+ -+- sgot = htab->root.sgot; -+- splt = htab->root.splt; -+- sreloc = NULL; -++/* Move all SECURITY_16 to the final one for each instruction. */ -+ -+- rel = relocs; -++static void -++nds32_elf_crc_adjust_reloc (Elf_Internal_Rela *relocs, -++ Elf_Internal_Rela *relend) -++{ -++ Elf_Internal_Rela *rel, *crc_rel = NULL; -++ Elf_Internal_Rela rel_temp; -++ -++ for (rel = relocs; rel < relend; rel++) -++ { -++ if (crc_rel && crc_rel->r_offset == rel->r_offset) -++ { -++ memcpy (&rel_temp, rel, sizeof (Elf_Internal_Rela)); -++ memcpy (rel, crc_rel, sizeof (Elf_Internal_Rela)); -++ memcpy (crc_rel, &rel_temp, sizeof (Elf_Internal_Rela)); -++ crc_rel = rel; -++ } -++ else if (ELF32_R_TYPE (rel->r_info) == R_NDS32_SECURITY_16) -++ { -++ crc_rel = rel; -++ continue; -++ } -++ } -++} -++ -++static bfd_boolean -++patch_tls_desc_to_ie (bfd_byte *contents, Elf_Internal_Rela *rel, bfd *ibfd) -++{ -++ /* TLS_GD/TLS_LD model #1 -++ 46 00 00 00 sethi $r0,#0x0 -++ 58 00 00 00 ori $r0,$r0,#0x0 -++ 40 00 74 00 add $r0,$r0,$gp -++ 04 10 00 00 lwi $r1,[$r0+#0x0] -++ 4b e0 04 01 jral $lp,$r1 */ -++ -++ /* TLS_GD/TLS_LD model #2 -++ 46 00 00 00 sethi $r0,#0x0 -++ 58 00 00 00 ori $r0,$r0,#0x0 -++ 38 10 74 02 lw $r1,[$r0+($gp<<#0x0)] <= TODO: not necessary $r1 register allocation -++ 40 00 74 00 add $r0,$r0,$gp -++ 4b e0 04 01 jral $lp,$r1 */ -++ -++ /* TLS_IE model (non-PIC) -++ 46 00 00 00 sethi $r0,#0x0 -++ 04 00 00 00 lwi $r0,[$r0+#0x0] -++ 38 00 64 02 lw $r0,[$r0+($r25<<#0x0)] */ -++ -++ /* TLS_IE model (PIC) -++ 46 00 00 00 sethi $r0,#0x0 -++ 58 00 00 00 ori $r0,$r0,#0x0 -++ 38 00 74 02 lw $r0,[$r0+($gp<<#0x0)] -++ 38 00 64 02 lw $r0,[$r0+($r25<<#0x0)] */ -++ -++ /* TLS_GD_TO_IE model -++ 46 00 00 00 sethi $r0,#0x0 -++ 58 00 00 00 ori $r0,$r0,#0x0 -++ 40 00 74 00 add $r0,$rM,$gp -++ 04 00 00 01 lwi $r0,[$r0+#0x4] -++ 40 00 64 00 add $r0,$r0,$r25 */ -++ -++ bfd_boolean rz = FALSE; -++ -++ typedef struct -++ { -++ uint32_t opcode; -++ uint32_t mask; -++ } pat_t; -++ -++ uint32_t patch[3] = -++ { -++ 0x40007400, /* add $r0,$rM,$gp */ -++ 0x04000001, /* lwi $r0,[$r0+#0x4] */ -++ 0x40006400, /* add $r0,$r0,$r25 */ -++ }; -++ -++ pat_t mode0[3] = -++ { -++ { 0x40000000, 0xfe0003ff }, -++ { 0x04000000, 0xfe000000 }, -++ { 0x4be00001, 0xffff83ff }, -++ }; -++ -++ pat_t mode1[3] = -++ { -++ { 0x38007402, 0xfe007fff }, -++ { 0x40007400, 0xfe007fff }, -++ { 0x4be00001, 0xffff83ff }, -++ }; -++ -++ unsigned char *p = contents + rel->r_offset; -++ -++ uint32_t insn; -++ uint32_t regidx = 0; -++ insn = bfd_getb32 (p); -++ if (INSN_SETHI == (0xfe0fffffu & insn)) -++ { -++ regidx = 0x1f & (insn >> 20); -++ p += 4; -++ } -++ -++ insn = bfd_getb32 (p); -++ if (INSN_ORI == (0xfe007fffu & insn)) -++ { -++ regidx = 0x1f & (insn >> 20); -++ p += 4; -++ } -++ -++ if (patch[2] == bfd_getb32 (p + 8)) /* character instruction */ -++ { -++ /* already patched? */ -++ if ((patch[0] == (0xfff07fffu & bfd_getb32 (p + 0))) && -++ (patch[1] == bfd_getb32 (p + 4))) -++ rz = TRUE; -++ } -++ else if (mode0[0].opcode == (mode0[0].mask & bfd_getb32 (p + 0))) -++ { -++ if ((mode0[1].opcode == (mode0[1].mask & bfd_getb32 (p + 4))) && -++ (mode0[2].opcode == (mode0[2].mask & bfd_getb32 (p + 8)))) -++ { -++ bfd_putb32 (patch[0] | (regidx << 15), p + 0); -++ bfd_putb32 (patch[1], p + 4); -++ bfd_putb32 (patch[2], p + 8); -++ rz = TRUE; -++ } -++ } -++ else if (mode1[0].opcode == (mode1[0].mask & bfd_getb32 (p + 0))) -++ { -++ if ((mode1[1].opcode == (mode1[1].mask & bfd_getb32 (p + 4))) && -++ (mode1[2].opcode == (mode1[2].mask & bfd_getb32 (p + 8)))) -++ { -++ bfd_putb32 (patch[0] | (regidx << 15), p + 0); -++ bfd_putb32 (patch[1], p + 4); -++ bfd_putb32 (patch[2], p + 8); -++ rz = TRUE; -++ } -++ } -++ -++ if (!rz) -++ { -++ printf ("%s: %s @ 0x%08x\n", __func__, ibfd->filename, -++ (int) rel->r_offset); -++ BFD_ASSERT(0); /* unsupported pattern */ -++ } -++ -++ return rz; -++} -++ -++static enum elf_nds32_tls_type -++get_tls_type (enum elf_nds32_reloc_type r_type, struct elf_link_hash_entry *h); -++ -++static unsigned int -++ones32 (register unsigned int x) -++{ -++ /* 32-bit recursive reduction using SWAR... -++ but first step is mapping 2-bit values -++ into sum of 2 1-bit values in sneaky way. */ -++ x -= ((x >> 1) & 0x55555555); -++ x = (((x >> 2) & 0x33333333) + (x & 0x33333333)); -++ x = (((x >> 4) + x) & 0x0f0f0f0f); -++ x += (x >> 8); -++ x += (x >> 16); -++ return (x & 0x0000003f); -++} -++ -++static unsigned int -++fls (register unsigned int x) -++{ -++ return ffs (x & (-x)); -++} -++ -++#define nds32_elf_local_tlsdesc_gotent(bfd) \ -++ (elf_nds32_tdata (bfd)->local_tlsdesc_gotent) -++ -++static bfd_boolean -++nds32_elf_relocate_section (bfd *output_bfd ATTRIBUTE_UNUSED, -++ struct bfd_link_info *info, bfd *input_bfd, -++ asection *input_section, bfd_byte *contents, -++ Elf_Internal_Rela *relocs, -++ Elf_Internal_Sym *local_syms, -++ asection **local_sections) -++{ -++ Elf_Internal_Shdr *symtab_hdr; -++ struct elf_link_hash_entry **sym_hashes; -++ Elf_Internal_Rela *rel, *relend; -++ bfd_boolean ret = TRUE; /* Assume success. */ -++ int align = 0; -++ bfd_reloc_status_type r; -++ const char *errmsg = NULL; -++ bfd_vma gp; -++ struct elf_link_hash_table *ehtab; -++ struct elf_nds32_link_hash_table *htab; -++ bfd *dynobj; -++ bfd_vma *local_got_offsets; -++ asection *sgot, *splt, *sreloc; -++ bfd_vma high_address; -++ struct elf_nds32_link_hash_table *table; -++ int eliminate_gc_relocs; -++ bfd_vma fpbase_addr; -++ Elf_Internal_Rela *crc_rel = NULL; -++ -++ symtab_hdr = &elf_tdata (input_bfd)->symtab_hdr; -++ sym_hashes = elf_sym_hashes (input_bfd); -++ ehtab = elf_hash_table (info); -++ htab = nds32_elf_hash_table (info); -++ high_address = bfd_get_section_limit (input_bfd, input_section); -++ -++ dynobj = htab->root.dynobj; -++ local_got_offsets = elf_local_got_offsets (input_bfd); -++ -++ sgot = ehtab->sgot; -++ splt = ehtab->splt; -++ sreloc = NULL; -++ -++ rel = relocs; -+ relend = relocs + input_section->reloc_count; -+ -+ table = nds32_elf_hash_table (info); -+ eliminate_gc_relocs = table->eliminate_gc_relocs; -++ -++ /* explain _SDA_BASE_ */ -+ /* By this time, we can adjust the value of _SDA_BASE_. */ -+ if ((!bfd_link_relocatable (info))) -+ { -+@@ -4402,40 +5337,37 @@ nds32_elf_relocate_section (bfd * output_bfd ATTRIBUTE_UNUSED, -+ return FALSE; -+ } -+ -+- if (is_ITB_BASE_set == 0) -+- { -+- /* Set the _ITB_BASE_. */ -+- if (!nds32_elf_ex9_itb_base (info)) -+- { -+- _bfd_error_handler (_("%B: error: Cannot set _ITB_BASE_"), -+- output_bfd); -+- bfd_set_error (bfd_error_bad_value); -+- } -+- } -+- -+- if (table->target_optimize & NDS32_RELAX_JUMP_IFC_ON) -+- if (!nds32_elf_ifc_reloc ()) -+- _bfd_error_handler (_("error: IFC relocation error.")); -++#ifdef NDS32_LINUX_TOOLCHAIN -++ /* Do TLS model conversion once at first. */ -++ nds32_elf_unify_tls_model (input_bfd, input_section, contents, info); -++#endif -+ -+- /* Relocation for .ex9.itable. */ -+- if (table->target_optimize & NDS32_RELAX_EX9_ON -+- || (table->ex9_import_file && table->update_ex9_table)) -+- nds32_elf_ex9_reloc_jmp (info); -++ if (indirect_call_table.count > 0) -++ nds32_elf_ict_relocate (output_bfd, info); -+ -+ /* Use gp as fp to prevent truncated fit. Because in relaxation time -+ the fp value is set as gp, and it has be reverted for instruction -+ setting fp. */ -+ fpbase_addr = elf_gp (output_bfd); -+ -++ /* Move all SECURITY_16 to the final one for each instruction. */ -++ nds32_elf_crc_adjust_reloc (relocs, relend); -++ -++ /* Deal with (dynamic) relocations. */ -+ for (rel = relocs; rel < relend; rel++) -+ { -+ enum elf_nds32_reloc_type r_type; -+ reloc_howto_type *howto = NULL; -+ unsigned long r_symndx; -+ struct elf_link_hash_entry *h = NULL; -++ struct bfd_link_hash_entry *h2; -+ Elf_Internal_Sym *sym = NULL; -+ asection *sec; -+ bfd_vma relocation; -++ struct elf_nds32_ict_hash_entry *entry; -++ bfd_vma relocation_sym = 0xdeadbeef; -++ Elf_Internal_Rela *lorel; -++ bfd_vma off; -+ -+ /* We can't modify r_addend here as elf_link_input_bfd has an assert to -+ ensure it's zero (we use REL relocs, not RELA). Therefore this -+@@ -4463,12 +5395,17 @@ nds32_elf_relocate_section (bfd * output_bfd ATTRIBUTE_UNUSED, -+ || r_type == R_NDS32_RELA_GNU_VTINHERIT -+ || (r_type >= R_NDS32_INSN16 && r_type <= R_NDS32_25_FIXED_RELA) -+ || r_type == R_NDS32_DATA -+- || r_type == R_NDS32_TRAN -+- || (r_type >= R_NDS32_LONGCALL4 && r_type <= R_NDS32_LONGJUMP7)) -++ || r_type == R_NDS32_TRAN) -+ continue; -+ -+- /* If we enter the fp-as-gp region. Resolve the address -+- of best fp-base. */ -++ /* Save security beginning. */ -++ if (r_type == R_NDS32_SECURITY_16 && crc_rel == NULL) -++ { -++ crc_rel = rel; -++ continue; -++ } -++ -++ /* If we enter the fp-as-gp region. Resolve the address of best fp-base. */ -+ if (ELF32_R_TYPE (rel->r_info) == R_NDS32_RELAX_REGION_BEGIN -+ && (rel->r_addend & R_NDS32_RELAX_REGION_OMIT_FP_FLAG)) -+ { -+@@ -4485,9 +5422,13 @@ nds32_elf_relocate_section (bfd * output_bfd ATTRIBUTE_UNUSED, -+ fpbase_addr = elf_gp (output_bfd); -+ } -+ -+- if (((r_type >= R_NDS32_DWARF2_OP1_RELA -+- && r_type <= R_NDS32_DWARF2_LEB_RELA) -+- || r_type >= R_NDS32_RELAX_ENTRY) && !bfd_link_relocatable (info)) -++ /* Skip the relocations used for relaxation. */ -++ /* Fix ticket-11832, we have to update LONGCALL and LONGJUMP -++ relocations when generating the relocatable files. */ -++ if (!bfd_link_relocatable (info) -++ && (r_type >= R_NDS32_RELAX_ENTRY -++ || (r_type >= R_NDS32_LONGCALL4 -++ && r_type <= R_NDS32_LONGJUMP7))) -+ continue; -+ -+ howto = bfd_elf32_bfd_reloc_type_table_lookup (r_type); -+@@ -4506,10 +5447,26 @@ nds32_elf_relocate_section (bfd * output_bfd ATTRIBUTE_UNUSED, -+ -+ relocation = _bfd_elf_rela_local_sym (output_bfd, sym, &sec, rel); -+ addend = rel->r_addend; -++ -++ /* keep symbol location for static TLS_IE GOT entry */ -++ relocation_sym = relocation; -++ if (bfd_link_relocatable (info)) -++ { -++ /* This is a relocatable link. We don't have to change -++ anything, unless the reloc is against a section symbol, -++ in which case we have to adjust according to where the -++ section symbol winds up in the output section. */ -++ if (sym != NULL && ELF_ST_TYPE (sym->st_info) == STT_SECTION) -++ rel->r_addend += sec->output_offset + sym->st_value; -++ -++ continue; -++ } -+ } -+ else -+ { -+ /* External symbol. */ -++ if (bfd_link_relocatable (info)) -++ continue; -+ bfd_boolean warned, ignored, unresolved_reloc; -+ int symndx = r_symndx - symtab_hdr->sh_info; -+ -+@@ -4518,10 +5475,27 @@ nds32_elf_relocate_section (bfd * output_bfd ATTRIBUTE_UNUSED, -+ relocation, unresolved_reloc, warned, -+ ignored); -+ -++ /* keep symbol location for static TLS_IE GOT entry */ -++ relocation_sym = relocation; -++ -+ /* la $fp, _FP_BASE_ is per-function (region). -+ Handle it specially. */ -+ switch ((int) r_type) -+ { -++ case R_NDS32_HI20_RELA: -++ case R_NDS32_LO12S0_RELA: -++ if (strcmp (elf_sym_hashes (input_bfd)[symndx]->root.root.string, -++ FP_BASE_NAME) == 0) -++ { -++ if (!bfd_link_pie (info)) -++ { -++ _bfd_error_handler -++ ("%pB: warning: _FP_BASE_ setting insns relaxation failed.", -++ input_bfd); -++ } -++ relocation = fpbase_addr; -++ break; -++ } -+ case R_NDS32_SDA19S0_RELA: -+ case R_NDS32_SDA15S0_RELA: -+ case R_NDS32_20_RELA: -+@@ -4532,19 +5506,6 @@ nds32_elf_relocate_section (bfd * output_bfd ATTRIBUTE_UNUSED, -+ break; -+ } -+ } -+- -+- } -+- -+- if (bfd_link_relocatable (info)) -+- { -+- /* This is a relocatable link. We don't have to change -+- anything, unless the reloc is against a section symbol, -+- in which case we have to adjust according to where the -+- section symbol winds up in the output section. */ -+- if (sym != NULL && ELF_ST_TYPE (sym->st_info) == STT_SECTION) -+- rel->r_addend += sec->output_offset + sym->st_value; -+- -+- continue; -+ } -+ -+ /* Sanity check the address. */ -+@@ -4554,16 +5515,14 @@ nds32_elf_relocate_section (bfd * output_bfd ATTRIBUTE_UNUSED, -+ goto check_reloc; -+ } -+ -+- if ((r_type >= R_NDS32_DWARF2_OP1_RELA -+- && r_type <= R_NDS32_DWARF2_LEB_RELA) -+- || r_type >= R_NDS32_RELAX_ENTRY) -++ if (r_type >= R_NDS32_RELAX_ENTRY) -+ continue; -+ -+ switch ((int) r_type) -+ { -+ case R_NDS32_GOTOFF: -+ /* Relocation is relative to the start of the global offset -+- table (for ld24 rx, #uimm24), e.g. access at label+addend -++ table (for ld24 rx, #uimm24), e.g. access at label + addend -+ -+ ld24 rx. #label@GOTOFF + addend -+ sub rx, r12. */ -+@@ -4605,12 +5564,18 @@ nds32_elf_relocate_section (bfd * output_bfd ATTRIBUTE_UNUSED, -+ case R_NDS32_PLT_GOTREL_LO15: -+ case R_NDS32_PLT_GOTREL_LO19: -+ case R_NDS32_PLT_GOTREL_LO20: -+- if (h == NULL || h->forced_local || h->plt.offset == (bfd_vma) - 1) -++ if (h == NULL -++ || h->forced_local -++ || h->plt.offset == (bfd_vma) -1 -++ || (bfd_link_pie (info) && h->def_regular)) -+ { -++ /* TODO: find better checking to optimize PIE PLT relocations. */ -+ /* We didn't make a PLT entry for this symbol. This -+ happens when statically linking PIC code, or when -+ using -Bsymbolic. */ -+- relocation -= elf_gp (output_bfd); -++ if (h) -++ h->plt.offset = (bfd_vma) -1; /* cancel PLT trampoline. */ -++ relocation -= elf_gp(output_bfd); -+ break; -+ } -+ -+@@ -4661,21 +5626,18 @@ nds32_elf_relocate_section (bfd * output_bfd ATTRIBUTE_UNUSED, -+ -+ case R_NDS32_GOTPC_HI20: -+ case R_NDS32_GOTPC_LO12: -+- { -+- /* .got(_GLOBAL_OFFSET_TABLE_) - pc relocation -+- bl .+4 -+- seth rx,#high(_GLOBAL_OFFSET_TABLE_) -+- or3 rx,rx,#low(_GLOBAL_OFFSET_TABLE_ +4) -+- or -+- bl .+4 -+- seth rx,#shigh(_GLOBAL_OFFSET_TABLE_) -+- add3 rx,rx,#low(_GLOBAL_OFFSET_TABLE_ +4) -+- */ -+- relocation = elf_gp (output_bfd); -+- relocation -= (input_section->output_section->vma -+- + input_section->output_offset + rel->r_offset); -+- break; -+- } -++ /* .got(_GLOBAL_OFFSET_TABLE_) - pc relocation -++ bl .+4 -++ seth rx,#high(_GLOBAL_OFFSET_TABLE_) -++ or3 rx,rx,#low(_GLOBAL_OFFSET_TABLE_ +4) -++ or -++ bl .+4 -++ seth rx,#shigh(_GLOBAL_OFFSET_TABLE_) -++ add3 rx,rx,#low(_GLOBAL_OFFSET_TABLE_ +4) */ -++ relocation = elf_gp (output_bfd); -++ relocation -= (input_section->output_section->vma -++ + input_section->output_offset + rel->r_offset); -++ break; -+ -+ case R_NDS32_GOT20: -+ /* Fall through. */ -+@@ -4687,17 +5649,14 @@ nds32_elf_relocate_section (bfd * output_bfd ATTRIBUTE_UNUSED, -+ offset table. */ -+ BFD_ASSERT (sgot != NULL); -+ -+- if (h != NULL) -++ if (h != NULL) /* External symbol */ -+ { -+ bfd_boolean dyn; -+- bfd_vma off; -+ -+ off = h->got.offset; -+ BFD_ASSERT (off != (bfd_vma) - 1); -+ dyn = htab->root.dynamic_sections_created; -+- if (!WILL_CALL_FINISH_DYNAMIC_SYMBOL (dyn, -+- bfd_link_pic (info), -+- h) -++ if (!WILL_CALL_FINISH_DYNAMIC_SYMBOL (dyn, bfd_link_pic (info), h) -+ || (bfd_link_pic (info) -+ && (info->symbolic -+ || h->dynindx == -1 -+@@ -4707,28 +5666,27 @@ nds32_elf_relocate_section (bfd * output_bfd ATTRIBUTE_UNUSED, -+ -Bsymbolic link and the symbol is defined -+ locally, or the symbol was forced to be local -+ because of a version file. We must initialize -+- this entry in the global offset table. Since the -++ this entry in the global offset table. Since the -+ offset must always be a multiple of 4, we use the -+ least significant bit to record whether we have -+ initialized it already. -+ -+ When doing a dynamic link, we create a .rela.got -+- relocation entry to initialize the value. This -++ relocation entry to initialize the value. This -+ is done in the finish_dynamic_symbol routine. */ -+- if ((off & 1) != 0) -++ if ((off & 1) != 0) /* clear LSB */ -+ off &= ~1; -+ else -+ { -+ bfd_put_32 (output_bfd, relocation, sgot->contents + off); -+- h->got.offset |= 1; -++ h->got.offset |= 1; /* mark initialized */ -+ } -+ } -+ relocation = sgot->output_section->vma + sgot->output_offset + off -+- - elf_gp (output_bfd); -++ - elf_gp (output_bfd); -+ } -+- else -++ else /* Local symbol */ -+ { -+- bfd_vma off; -+ bfd_byte *loc; -+ -+ BFD_ASSERT (local_got_offsets != NULL -+@@ -4736,10 +5694,10 @@ nds32_elf_relocate_section (bfd * output_bfd ATTRIBUTE_UNUSED, -+ -+ off = local_got_offsets[r_symndx]; -+ -+- /* The offset must always be a multiple of 4. We use -++ /* The offset must always be a multiple of 4. We use -+ the least significant bit to record whether we have -+ already processed this entry. */ -+- if ((off & 1) != 0) -++ if ((off & 1) != 0) /* clear LSB */ -+ off &= ~1; -+ else -+ { -+@@ -4752,7 +5710,7 @@ nds32_elf_relocate_section (bfd * output_bfd ATTRIBUTE_UNUSED, -+ -+ /* We need to generate a R_NDS32_RELATIVE reloc -+ for the dynamic linker. */ -+- srelgot = htab->root.srelgot; -++ srelgot = bfd_get_section_by_name (dynobj, ".rela.got"); -+ BFD_ASSERT (srelgot != NULL); -+ -+ outrel.r_offset = (elf_gp (output_bfd) -+@@ -4768,11 +5726,57 @@ nds32_elf_relocate_section (bfd * output_bfd ATTRIBUTE_UNUSED, -+ local_got_offsets[r_symndx] |= 1; -+ } -+ relocation = sgot->output_section->vma + sgot->output_offset + off -+- - elf_gp (output_bfd); -++ - elf_gp (output_bfd); -+ } -+ -+ break; -+ -++ case R_NDS32_25_PCREL_RELA: -++ case R_NDS32_HI20_RELA: -++ case R_NDS32_LO12S0_RELA: -++ case R_NDS32_LO12S2_RELA: -++ /* Merge normal and indirect call functions. */ -++ if (!ignore_indirect_call && h -++ && elf32_nds32_hash_entry (h)->indirect_call) -++ { -++ if (ict_model == R_NDS32_RELAX_ENTRY_ICT_LARGE) -++ { -++ _bfd_error_handler -++ (_("%pB: Error: there are mixed indirect call function in" -++ " ICT large model\'%s\'\n"), -++ input_bfd, h->root.root.string); -++ bfd_set_error (bfd_error_bad_value); -++ return FALSE; -++ } -++ else -++ _bfd_error_handler -++ (_("%pB: Warning: there are mixed indirect call function" -++ " \'%s\'\n"), input_bfd, h->root.root.string); -++ -++ entry = (struct elf_nds32_ict_hash_entry*) -++ bfd_hash_lookup (&indirect_call_table, h->root.root.string, -++ FALSE, FALSE); -++ if (!entry) -++ { -++ _bfd_error_handler -++ (_("%pB %pA: internal error indirect call relocation " -++ "0x%lx without hash.\n"), -++ input_bfd, sec, rel->r_offset); -++ bfd_set_error (bfd_error_bad_value); -++ return FALSE; -++ } -++ -++ h2 = bfd_link_hash_lookup (info->hash, -++ "_INDIRECT_CALL_TABLE_BASE_", -++ FALSE, FALSE, FALSE); -++ relocation = ((h2->u.def.value -++ + h2->u.def.section->output_section->vma -++ + h2->u.def.section->output_offset) -++ + (entry->order * 4)); -++ break; -++ } -++ -++ /* Fall through. */ -+ case R_NDS32_16_RELA: -+ case R_NDS32_20_RELA: -+ case R_NDS32_5_RELA: -+@@ -4782,14 +5786,10 @@ nds32_elf_relocate_section (bfd * output_bfd ATTRIBUTE_UNUSED, -+ case R_NDS32_10_UPCREL_RELA: -+ case R_NDS32_15_PCREL_RELA: -+ case R_NDS32_17_PCREL_RELA: -+- case R_NDS32_25_PCREL_RELA: -+- case R_NDS32_HI20_RELA: -+ case R_NDS32_LO12S3_RELA: -+- case R_NDS32_LO12S2_RELA: -+ case R_NDS32_LO12S2_DP_RELA: -+ case R_NDS32_LO12S2_SP_RELA: -+ case R_NDS32_LO12S1_RELA: -+- case R_NDS32_LO12S0_RELA: -+ case R_NDS32_LO12S0_ORI_RELA: -+ if (bfd_link_pic (info) && r_symndx != 0 -+ && (input_section->flags & SEC_ALLOC) != 0 -+@@ -4863,15 +5863,37 @@ nds32_elf_relocate_section (bfd * output_bfd ATTRIBUTE_UNUSED, -+ become local. */ -+ if (h == NULL -+ || ((info->symbolic || h->dynindx == -1) -+- && h->def_regular)) -++ && h->def_regular) -++ || (bfd_link_pie (info) && h->def_regular)) -+ { -+ relocate = TRUE; -+ outrel.r_info = ELF32_R_INFO (0, R_NDS32_RELATIVE); -+ outrel.r_addend = relocation + rel->r_addend; -++ if (h) -++ { -++ h->plt.offset = (bfd_vma) -1; /* cancel PLT trampoline. */ -++ -++ BFD_ASSERT (sgot != NULL); -++ /* If we did not allocate got entry for the symbol, we can not -++ fill the nonexistent got entry. */ -++ if (h->got.offset != (bfd_vma) -1 && (h->got.offset & 1) == 0) -++ { -++ bfd_put_32 (output_bfd, outrel.r_addend, -++ sgot->contents + h->got.offset); -++ } -++ } -+ } -+ else -+ { -+- BFD_ASSERT (h->dynindx != -1); -++ if (h->dynindx == -1) -++ { -++ _bfd_error_handler -++ (_("%pB: relocation %s against `%s' can not be used when" -++ "making a shared object; recompile with -fPIC"), -++ input_bfd, nds32_elf_howto_table[r_type].name, h->root.root.string); -++ bfd_set_error (bfd_error_bad_value); -++ return FALSE; -++ } -+ outrel.r_info = ELF32_R_INFO (h->dynindx, r_type); -+ outrel.r_addend = rel->r_addend; -+ } -+@@ -4895,8 +5917,8 @@ nds32_elf_relocate_section (bfd * output_bfd ATTRIBUTE_UNUSED, -+ if (bfd_link_pic (info)) -+ { -+ _bfd_error_handler -+- (_("%B: warning: cannot deal R_NDS32_25_ABS_RELA in shared " -+- "mode."), input_bfd); -++ (_("%s: warning: cannot deal R_NDS32_25_ABS_RELA in shared mode."), -++ bfd_get_filename (input_bfd)); -+ return FALSE; -+ } -+ break; -+@@ -4908,123 +5930,115 @@ nds32_elf_relocate_section (bfd * output_bfd ATTRIBUTE_UNUSED, -+ goto check_reloc; -+ -+ case R_NDS32_HI20: -++ /* We allow an arbitrary number of HI20 relocs before the -++ LO12 reloc. This permits GCC to emit the HI and LO relocs -++ itself. */ -++ for (lorel = rel + 1; -++ (lorel < relend -++ && ELF32_R_TYPE (lorel->r_info) == R_NDS32_HI20); lorel++) -++ continue; -++ if (lorel < relend -++ && (ELF32_R_TYPE (lorel->r_info) == R_NDS32_LO12S3 -++ || ELF32_R_TYPE (lorel->r_info) == R_NDS32_LO12S2 -++ || ELF32_R_TYPE (lorel->r_info) == R_NDS32_LO12S1 -++ || ELF32_R_TYPE (lorel->r_info) == R_NDS32_LO12S0)) -+ { -+- Elf_Internal_Rela *lorel; -+- -+- /* We allow an arbitrary number of HI20 relocs before the -+- LO12 reloc. This permits gcc to emit the HI and LO relocs -+- itself. */ -+- for (lorel = rel + 1; -+- (lorel < relend -+- && ELF32_R_TYPE (lorel->r_info) == R_NDS32_HI20); lorel++) -+- continue; -+- if (lorel < relend -+- && (ELF32_R_TYPE (lorel->r_info) == R_NDS32_LO12S3 -+- || ELF32_R_TYPE (lorel->r_info) == R_NDS32_LO12S2 -+- || ELF32_R_TYPE (lorel->r_info) == R_NDS32_LO12S1 -+- || ELF32_R_TYPE (lorel->r_info) == R_NDS32_LO12S0)) -+- { -+- nds32_elf_relocate_hi20 (input_bfd, r_type, rel, lorel, -+- contents, relocation + addend); -+- r = bfd_reloc_ok; -+- } -+- else -+- r = _bfd_final_link_relocate (howto, input_bfd, input_section, -+- contents, offset, relocation, -+- addend); -++ nds32_elf_relocate_hi20 (input_bfd, r_type, rel, lorel, -++ contents, relocation + addend); -++ r = bfd_reloc_ok; -+ } -++ else -++ r = _bfd_final_link_relocate (howto, input_bfd, input_section, -++ contents, offset, relocation, -++ addend); -+ -+ goto check_reloc; -+ -+ case R_NDS32_GOT17S2_RELA: -+ case R_NDS32_GOT15S2_RELA: -++ BFD_ASSERT (sgot != NULL); -++ -++ if (h != NULL) -+ { -+- bfd_vma off; -++ bfd_boolean dyn; -+ -+- BFD_ASSERT (sgot != NULL); -++ off = h->got.offset; -++ BFD_ASSERT (off != (bfd_vma) - 1); -+ -+- if (h != NULL) -++ dyn = htab->root.dynamic_sections_created; -++ if (!WILL_CALL_FINISH_DYNAMIC_SYMBOL -++ (dyn, bfd_link_pic (info), h) || (bfd_link_pic (info) -++ && (info->symbolic -++ || h->dynindx == -1 -++ || h->forced_local) -++ && h->def_regular)) -+ { -+- bfd_boolean dyn; -+- -+- off = h->got.offset; -+- BFD_ASSERT (off != (bfd_vma) - 1); -+- -+- dyn = htab->root.dynamic_sections_created; -+- if (!WILL_CALL_FINISH_DYNAMIC_SYMBOL -+- (dyn, bfd_link_pic (info), h) -+- || (bfd_link_pic (info) -+- && (info->symbolic -+- || h->dynindx == -1 -+- || h->forced_local) -+- && h->def_regular)) -++ /* This is actually a static link, or it is a -++ -Bsymbolic link and the symbol is defined -++ locally, or the symbol was forced to be local -++ because of a version file. We must initialize -++ this entry in the global offset table. Since the -++ offset must always be a multiple of 4, we use the -++ least significant bit to record whether we have -++ initialized it already. -++ -++ When doing a dynamic link, we create a .rela.got -++ relocation entry to initialize the value. This -++ is done in the finish_dynamic_symbol routine. */ -++ if ((off & 1) != 0) -++ off &= ~1; -++ else -+ { -+- /* This is actually a static link, or it is a -+- -Bsymbolic link and the symbol is defined -+- locally, or the symbol was forced to be local -+- because of a version file. We must initialize -+- this entry in the global offset table. Since the -+- offset must always be a multiple of 4, we use the -+- least significant bit to record whether we have -+- initialized it already. -+- -+- When doing a dynamic link, we create a .rela.got -+- relocation entry to initialize the value. This -+- is done in the finish_dynamic_symbol routine. */ -+- if ((off & 1) != 0) -+- off &= ~1; -+- else -+- { -+- bfd_put_32 (output_bfd, relocation, -+- sgot->contents + off); -+- h->got.offset |= 1; -+- } -++ bfd_put_32 (output_bfd, relocation, -++ sgot->contents + off); -++ h->got.offset |= 1; -+ } -+ } -+- else -+- { -+- bfd_byte *loc; -++ } -++ else -++ { -++ bfd_byte *loc; -+ -+- BFD_ASSERT (local_got_offsets != NULL -+- && local_got_offsets[r_symndx] != (bfd_vma) - 1); -++ BFD_ASSERT (local_got_offsets != NULL -++ && local_got_offsets[r_symndx] != (bfd_vma) - 1); -+ -+- off = local_got_offsets[r_symndx]; -++ off = local_got_offsets[r_symndx]; -+ -+- /* The offset must always be a multiple of 4. We use -+- the least significant bit to record whether we have -+- already processed this entry. */ -+- if ((off & 1) != 0) -+- off &= ~1; -+- else -++ /* The offset must always be a multiple of 4. We use -++ the least significant bit to record whether we have -++ already processed this entry. */ -++ if ((off & 1) != 0) -++ off &= ~1; -++ else -++ { -++ bfd_put_32 (output_bfd, relocation, sgot->contents + off); -++ -++ if (bfd_link_pic (info)) -+ { -+- bfd_put_32 (output_bfd, relocation, sgot->contents + off); -++ asection *srelgot; -++ Elf_Internal_Rela outrel; -+ -+- if (bfd_link_pic (info)) -+- { -+- asection *srelgot; -+- Elf_Internal_Rela outrel; -+- -+- /* We need to generate a R_NDS32_RELATIVE reloc -+- for the dynamic linker. */ -+- srelgot = htab->root.srelgot; -+- BFD_ASSERT (srelgot != NULL); -+- -+- outrel.r_offset = (elf_gp (output_bfd) -+- + sgot->output_offset + off); -+- outrel.r_info = ELF32_R_INFO (0, R_NDS32_RELATIVE); -+- outrel.r_addend = relocation; -+- loc = srelgot->contents; -+- loc += -+- srelgot->reloc_count * sizeof (Elf32_External_Rela); -+- bfd_elf32_swap_reloca_out (output_bfd, &outrel, loc); -+- ++srelgot->reloc_count; -+- } -+- local_got_offsets[r_symndx] |= 1; -++ /* We need to generate a R_NDS32_RELATIVE reloc -++ for the dynamic linker. */ -++ srelgot = bfd_get_section_by_name (dynobj, ".rela.got"); -++ BFD_ASSERT (srelgot != NULL); -++ -++ outrel.r_offset = (elf_gp (output_bfd) -++ + sgot->output_offset + off); -++ outrel.r_info = ELF32_R_INFO (0, R_NDS32_RELATIVE); -++ outrel.r_addend = relocation; -++ loc = srelgot->contents; -++ loc += -++ srelgot->reloc_count * sizeof (Elf32_External_Rela); -++ bfd_elf32_swap_reloca_out (output_bfd, &outrel, loc); -++ ++srelgot->reloc_count; -+ } -++ local_got_offsets[r_symndx] |= 1; -+ } -+- relocation = sgot->output_section->vma + sgot->output_offset + off -+- - elf_gp (output_bfd); -+ } -++ relocation = sgot->output_section->vma + sgot->output_offset + off -++ - elf_gp (output_bfd); -++ -+ if (relocation & align) -+ { -+ /* Incorrect alignment. */ -+@@ -5060,50 +6074,48 @@ nds32_elf_relocate_section (bfd * output_bfd ATTRIBUTE_UNUSED, -+ case R_NDS32_SDA19S0_RELA: -+ case R_NDS32_SDA15S0_RELA: -+ case R_NDS32_SDA15S0: -+- { -+- align = 0x0; -++ align = 0x0; -+ handle_sda: -+- BFD_ASSERT (sec != NULL); -++ BFD_ASSERT (sec != NULL); -+ -+- /* If the symbol is in the abs section, the out_bfd will be null. -+- This happens when the relocation has a symbol@GOTOFF. */ -+- r = nds32_elf_final_sda_base (output_bfd, info, &gp, FALSE); -+- if (r != bfd_reloc_ok) -+- { -+- _bfd_error_handler -+- (_("%B: warning: relocate SDA_BASE failed."), input_bfd); -+- ret = FALSE; -+- goto check_reloc; -+- } -++ /* If the symbol is in the abs section, the out_bfd will be null. -++ This happens when the relocation has a symbol@GOTOFF. */ -++ r = nds32_elf_final_sda_base (output_bfd, info, &gp, FALSE); -++ if (r != bfd_reloc_ok) -++ { -++ _bfd_error_handler -++ (_("%B: warning: relocate SDA_BASE failed."), input_bfd); -++ ret = FALSE; -++ goto check_reloc; -++ } -+ -+- /* At this point `relocation' contains the object's -+- address. */ -+- if (r_type == R_NDS32_SDA_FP7U2_RELA) -+- { -+- relocation -= fpbase_addr; -+- } -+- else -+- relocation -= gp; -+- /* Now it contains the offset from _SDA_BASE_. */ -++ /* At this point `relocation' contains the object's -++ address. */ -++ if (r_type == R_NDS32_SDA_FP7U2_RELA) -++ { -++ relocation -= fpbase_addr; -++ } -++ else -++ relocation -= gp; -++ /* Now it contains the offset from _SDA_BASE_. */ -+ -+- /* Make sure alignment is correct. */ -++ /* Make sure alignment is correct. */ -+ -+- if (relocation & align) -+- { -+- /* Incorrect alignment. */ -+- _bfd_error_handler -+- /* xgettext:c-format */ -+- (_("%B(%A): warning: unaligned small data access of type %d."), -+- input_bfd, input_section, r_type); -+- ret = FALSE; -+- goto check_reloc; -+- } -++ if (relocation & align) -++ { -++ /* Incorrect alignment. */ -++ _bfd_error_handler -++ (_("%B(%A): warning: unaligned small data access of type %d."), -++ input_bfd, input_section, r_type); -++ ret = FALSE; -++ goto check_reloc; -+ } -+ -+ break; -+ case R_NDS32_17IFC_PCREL_RELA: -+ case R_NDS32_10IFCU_PCREL_RELA: -+- /* do nothing */ -++ ifc_flag = TRUE; -++ /* do nothing */ -+ break; -+ -+ case R_NDS32_TLS_LE_HI20: -+@@ -5112,28 +6124,38 @@ handle_sda: -+ case R_NDS32_TLS_LE_15S0: -+ case R_NDS32_TLS_LE_15S1: -+ case R_NDS32_TLS_LE_15S2: -++ /* TODO: we do not have garbage collection for got entries. -++ IE to LE may have one empty entry, and DESC to LE may -++ have two. */ -+ if (elf_hash_table (info)->tls_sec != NULL) -+ relocation -= (elf_hash_table (info)->tls_sec->vma + TP_OFFSET); -+ break; -+ case R_NDS32_TLS_IE_HI20: -+ case R_NDS32_TLS_IE_LO12S2: -++ case R_NDS32_TLS_DESC_HI20: -++ case R_NDS32_TLS_DESC_LO12: -++ case R_NDS32_TLS_IE_LO12: -++ case R_NDS32_TLS_IEGP_HI20: -++ case R_NDS32_TLS_IEGP_LO12: -++ case R_NDS32_TLS_IEGP_LO12S2: -+ { -+ /* Relocation is to the entry for this symbol in the global -+ offset table. */ -+- unsigned int tls_type; -++ enum elf_nds32_tls_type tls_type, org_tls_type, eff_tls_type; -+ asection *srelgot; -+ Elf_Internal_Rela outrel; -+- bfd_vma off; -+ bfd_byte *loc; -+ int indx = 0; -+ -++ eff_tls_type = org_tls_type = get_tls_type (r_type, h); -++ -+ BFD_ASSERT (sgot != NULL); -+ if (h != NULL) -+ { -+ bfd_boolean dyn; -+ -+ off = h->got.offset; -+- BFD_ASSERT (off != (bfd_vma) - 1); -++ BFD_ASSERT (off != (bfd_vma) -1); -+ dyn = htab->root.dynamic_sections_created; -+ tls_type = ((struct elf_nds32_link_hash_entry *) h)->tls_type; -+ if (WILL_CALL_FINISH_DYNAMIC_SYMBOL (dyn, bfd_link_pic (info), h) -+@@ -5143,64 +6165,184 @@ handle_sda: -+ } -+ else -+ { -+- /* Never happen currently. */ -+ BFD_ASSERT (local_got_offsets != NULL -+ && local_got_offsets[r_symndx] != (bfd_vma) - 1); -+ -+ off = local_got_offsets[r_symndx]; -+- -+ tls_type = elf32_nds32_local_got_tls_type (input_bfd)[r_symndx]; -+ } -++ -+ relocation = sgot->output_section->vma + sgot->output_offset + off; -+ -+- if (r_type == R_NDS32_TLS_IE_LO12S2) -+- break; -++ if (1 < ones32 (tls_type)) -++ { -++ eff_tls_type = 1 << (fls (tls_type) - 1); -++ /* TLS model shall be handled in nds32_elf_unify_tls_model () */ -++ -++ /* TLS model X -> LE is not implement yet! -++ * workaround here! */ -++ if (eff_tls_type == GOT_TLS_LE) -++ { -++ eff_tls_type = 1 << (fls (tls_type ^ eff_tls_type) - 1); -++ } -++ } -+ -+ /* The offset must always be a multiple of 4. We use -+ the least significant bit to record whether we have -+ already processed this entry. */ -+- if ((off & 1) != 0) -+- off &= ~1; -++ bfd_boolean need_relocs = FALSE; -++ srelgot = ehtab->srelgot; -++ if ((bfd_link_pic (info) || indx != 0) -++ && (h == NULL || ELF_ST_VISIBILITY (h->other) == STV_DEFAULT -++ || h->root.type != bfd_link_hash_undefweak)) -++ { -++ need_relocs = TRUE; -++ BFD_ASSERT (srelgot != NULL); -++ } -++ -++ if (off & 1) -++ { -++ off &= ~1; -++ relocation &= ~1; -++ -++ if (eff_tls_type & GOT_TLS_DESC) -++ { -++ relocation -= elf_gp (output_bfd); -++ if ((R_NDS32_TLS_DESC_HI20 == r_type) && (!need_relocs)) -++ { -++ /* TLS model shall be converted */ -++ BFD_ASSERT(0); -++ } -++ } -++ else if (eff_tls_type & GOT_TLS_IEGP) -++ { -++ relocation -= elf_gp (output_bfd); -++ } -++ } -+ else -+ { -+- bfd_boolean need_relocs = FALSE; -+- srelgot = htab->root.srelgot; -+- if ((bfd_link_pic (info) || indx != 0) -+- && (h == NULL -+- || ELF_ST_VISIBILITY (h->other) == STV_DEFAULT -+- || h->root.type != bfd_link_hash_undefweak)) -++ if ((eff_tls_type & GOT_TLS_LE) && (tls_type ^ eff_tls_type)) -+ { -+- need_relocs = TRUE; -+- BFD_ASSERT (srelgot != NULL); -++ /* TLS model workaround shall be applied */ -++ BFD_ASSERT(0); -+ } -+- if (tls_type & GOT_TLS_IE) -++ else if (eff_tls_type & (GOT_TLS_IE | GOT_TLS_IEGP)) -+ { -++ if (eff_tls_type & GOT_TLS_IEGP) -++ relocation -= elf_gp(output_bfd); -++ -+ if (need_relocs) -+ { -+- if (h->dynindx == 0) -+- outrel.r_addend = relocation - dtpoff_base (info); -++ if (indx == 0) -++ outrel.r_addend = gottpoff (info, relocation_sym); -+ else -+ outrel.r_addend = 0; -+ outrel.r_offset = (sgot->output_section->vma -+- + sgot->output_offset -+- + off); -+- outrel.r_info = -+- ELF32_R_INFO (h->dynindx, R_NDS32_TLS_TPOFF); -+- -+- loc = srelgot->contents; -+- loc += -+- srelgot->reloc_count * sizeof (Elf32_External_Rela); -+- bfd_elf32_swap_reloca_out (output_bfd, &outrel, loc); -+- ++srelgot->reloc_count; -++ + sgot->output_offset + off); -++ outrel.r_info = ELF32_R_INFO (indx, R_NDS32_TLS_TPOFF); -++ -++ elf32_nds32_add_dynreloc (output_bfd, info, srelgot, -++ &outrel); -+ } -+ else -+- bfd_put_32 (output_bfd, h->root.u.def.value - TP_OFFSET, -+- sgot->contents + off); -++ { -++ bfd_put_32 (output_bfd, gottpoff (info, relocation_sym), -++ sgot->contents + off); -++ } -++ } -++ else if (eff_tls_type & GOT_TLS_DESC) -++ { -++ relocation -= elf_gp (output_bfd); -++ if (need_relocs) -++ { -++ if (indx == 0) -++ outrel.r_addend = gottpoff (info, relocation_sym); -++ else -++ outrel.r_addend = 0; -++ outrel.r_offset = (sgot->output_section->vma -++ + sgot->output_offset + off); -++ outrel.r_info = ELF32_R_INFO (indx, R_NDS32_TLS_DESC); -++ -++ if (htab->tls_desc_trampoline) -++ { -++ asection *srelplt; -++ srelplt = ehtab->srelplt; -++ loc = srelplt->contents; -++ loc += htab->next_tls_desc_index++ * sizeof (Elf32_External_Rela); -++ BFD_ASSERT (loc + sizeof (Elf32_External_Rela) -++ <= srelplt->contents + srelplt->size); -++ -++ bfd_elf32_swap_reloca_out (output_bfd, &outrel, loc); -++ } -++ else -++ { -++ loc = srelgot->contents; -++ loc += srelgot->reloc_count * sizeof (Elf32_External_Rela); -++ bfd_elf32_swap_reloca_out (output_bfd, &outrel, loc); -++ ++srelgot->reloc_count; -++ } -++ } -++ else -++ { -++ /* feed me! */ -++ bfd_put_32 (output_bfd, 0xdeadbeef, -++ sgot->contents + off); -++ bfd_put_32 (output_bfd, gottpoff (info, relocation_sym), -++ sgot->contents + off + 4); -++ patch_tls_desc_to_ie (contents, rel, input_bfd); -++ BFD_ASSERT(0); -++ } -++ } -++ else -++ { -++ /* TLS model workaround shall be applied */ -++ BFD_ASSERT(0); -+ } -++ -++ if (h != NULL) -++ h->got.offset |= 1; -++ else -++ local_got_offsets[r_symndx] |= 1; -+ } -+ } -+- break; -++ break; -++ -++ case R_NDS32_SECURITY_16: -++ relocation = 0; -++ crc_rel->r_addend = NDS32_SECURITY_NONE; -++ r = nds32_elf_final_link_relocate (howto, input_bfd, -++ input_section, contents, -++ crc_rel->r_offset, relocation, -++ crc_rel->r_addend); -++ crc_rel = NULL; -++ goto check_reloc; -++ break; -++ /* DON'T fall through. */ -++ case R_NDS32_ICT_HI20: -++ case R_NDS32_ICT_LO12: -++ case R_NDS32_ICT_25PC: -++ case R_NDS32_ICT_LO12S2: -++ entry = (struct elf_nds32_ict_hash_entry*) -++ bfd_hash_lookup (&indirect_call_table, h->root.root.string, -++ FALSE, FALSE); -++ if (!entry) -++ { -++ _bfd_error_handler -++ (_("%pB %pA: internal error indirect call relocation " -++ "0x%lx without hash.\n"), -++ input_bfd, sec, rel->r_offset); -++ bfd_set_error (bfd_error_bad_value); -++ return FALSE; -++ } -+ -++ h2 = bfd_link_hash_lookup (info->hash, -++ "_INDIRECT_CALL_TABLE_BASE_", -++ FALSE, FALSE, FALSE); -++ relocation = ((h2->u.def.value -++ + h2->u.def.section->output_section->vma -++ + h2->u.def.section->output_offset) -++ + (entry->order * 4)); -++ break; -+ /* DON'T fall through. */ -+ -+ default: -+@@ -5275,6 +6417,12 @@ handle_sda: -+ case R_NDS32_TLS_LE_15S0: -+ case R_NDS32_TLS_LE_15S1: -+ case R_NDS32_TLS_LE_15S2: -++ case R_NDS32_TLS_DESC_HI20: -++ case R_NDS32_TLS_DESC_LO12: -++ case R_NDS32_TLS_IE_LO12: -++ case R_NDS32_TLS_IEGP_HI20: -++ case R_NDS32_TLS_IEGP_LO12: -++ case R_NDS32_TLS_IEGP_LO12S2: -+ /* Instruction related relocs must handle endian properly. */ -+ /* NOTE: PIC IS NOT HANDLE YET; DO IT LATER. */ -+ r = nds32_elf_final_link_relocate (howto, input_bfd, -+@@ -5283,6 +6431,15 @@ handle_sda: -+ rel->r_addend); -+ break; -+ -++ case R_NDS32_ICT_HI20: -++ case R_NDS32_ICT_LO12: -++ case R_NDS32_ICT_25PC: -++ case R_NDS32_ICT_LO12S2: -++ r = nds32_elf_final_link_relocate (howto, input_bfd, input_section, -++ contents, rel->r_offset, -++ relocation, 0); -++ break; -++ -+ default: -+ /* All other relocs can use default handler. */ -+ r = _bfd_final_link_relocate (howto, input_bfd, input_section, -+@@ -5314,6 +6471,17 @@ check_reloc: -+ switch (r) -+ { -+ case bfd_reloc_overflow: -++ if (r_type == R_NDS32_17IFC_PCREL_RELA) -++ { -++ _bfd_error_handler -++ (_("\n%pB: (%pA+0x%x): The IFC optimization range exceeded.\n" -++ "Please turn off the IFC optimization (-mno-ifc) when " -++ "compiling the file %s.\n"), -++ input_bfd, sec, (int) rel->r_offset, -++ h->root.u.def.section->owner->filename); -++ bfd_set_error (bfd_error_bad_value); -++ } -++ -+ (*info->callbacks->reloc_overflow) -+ (info, (h ? &h->root : NULL), name, howto->name, -+ (bfd_vma) 0, input_bfd, input_section, offset); -+@@ -5340,14 +6508,18 @@ check_reloc: -+ errmsg = _("internal error: unknown error"); -+ /* Fall through. */ -+ -+- common_error: -+- (*info->callbacks->warning) (info, errmsg, name, input_bfd, -+- input_section, offset); -++common_error: -++ (*info->callbacks->warning) -++ (info, errmsg, name, input_bfd, input_section, offset); -+ break; -+ } -+ } -+ } -+ -++ /* Resotre header size to avoid overflow load. */ -++ if (elf_nds32_tdata (input_bfd)->hdr_size != 0) -++ symtab_hdr->sh_size = elf_nds32_tdata (input_bfd)->hdr_size; -++ -+ return ret; -+ } -+ -+@@ -5356,12 +6528,15 @@ check_reloc: -+ -+ static bfd_boolean -+ nds32_elf_finish_dynamic_symbol (bfd *output_bfd, struct bfd_link_info *info, -+- struct elf_link_hash_entry *h, Elf_Internal_Sym *sym) -++ struct elf_link_hash_entry *h, -++ Elf_Internal_Sym *sym) -+ { -+- struct elf_nds32_link_hash_table *htab; -++ struct elf_link_hash_table *ehtab; -++ struct elf_nds32_link_hash_entry *hent; -+ bfd_byte *loc; -+ -+- htab = nds32_elf_hash_table (info); -++ ehtab = elf_hash_table (info); -++ hent = (struct elf_nds32_link_hash_entry *) h; -+ -+ if (h->plt.offset != (bfd_vma) - 1) -+ { -+@@ -5379,9 +6554,9 @@ nds32_elf_finish_dynamic_symbol (bfd *output_bfd, struct bfd_link_info *info, -+ -+ BFD_ASSERT (h->dynindx != -1); -+ -+- splt = htab->root.splt; -+- sgot = htab->root.sgotplt; -+- srela = htab->root.srelplt; -++ splt = ehtab->splt; -++ sgot = ehtab->sgotplt; -++ srela = ehtab->srelplt; -+ BFD_ASSERT (splt != NULL && sgot != NULL && srela != NULL); -+ -+ /* Get the index in the procedure linkage table which -+@@ -5417,7 +6592,7 @@ nds32_elf_finish_dynamic_symbol (bfd *output_bfd, struct bfd_link_info *info, -+ bfd_putb32 (insn, splt->contents + h->plt.offset + 12); -+ -+ insn = PLT_ENTRY_WORD4 -+- + (((unsigned int) ((-(h->plt.offset + 16)) >> 1)) & 0xffffff); -++ + (((unsigned int) ((-(h->plt.offset + 16)) >> 1)) & 0xffffff); -+ bfd_putb32 (insn, splt->contents + h->plt.offset + 16); -+ local_plt_offset = 12; -+ } -+@@ -5428,9 +6603,8 @@ nds32_elf_finish_dynamic_symbol (bfd *output_bfd, struct bfd_link_info *info, -+ long offset; -+ -+ /* FIXME, sda_base is 65536, it will damage opcode. */ -+- /* insn = PLT_PIC_ENTRY_WORD0 + (((got_offset - sda_base) >> 2) & 0x7fff); */ -+ offset = sgot->output_section->vma + sgot->output_offset + got_offset -+- - elf_gp (output_bfd); -++ - elf_gp (output_bfd); -+ insn = PLT_PIC_ENTRY_WORD0 + ((offset >> 12) & 0xfffff); -+ bfd_putb32 (insn, splt->contents + h->plt.offset); -+ -+@@ -5479,18 +6653,18 @@ nds32_elf_finish_dynamic_symbol (bfd *output_bfd, struct bfd_link_info *info, -+ } -+ } -+ -+- if (h->got.offset != (bfd_vma) - 1) -++ if ((h->got.offset != (bfd_vma) -1) && (hent->tls_type == GOT_NORMAL)) -+ { -+ asection *sgot; -+- asection *srela; -++ asection *srelagot; -+ Elf_Internal_Rela rela; -+ -+ /* This symbol has an entry in the global offset table. -+ Set it up. */ -+ -+- sgot = htab->root.sgot; -+- srela = htab->root.srelgot; -+- BFD_ASSERT (sgot != NULL && srela != NULL); -++ sgot = ehtab->sgot; -++ srelagot = ehtab->srelgot; -++ BFD_ASSERT (sgot != NULL && srelagot != NULL); -+ -+ rela.r_offset = (sgot->output_section->vma -+ + sgot->output_offset + (h->got.offset & ~1)); -+@@ -5500,14 +6674,24 @@ nds32_elf_finish_dynamic_symbol (bfd *output_bfd, struct bfd_link_info *info, -+ the symbol was forced to be local because of a version file. -+ The entry in the global offset table will already have been -+ initialized in the relocate_section function. */ -+- if (bfd_link_pic (info) -+- && (info->symbolic -+- || h->dynindx == -1 || h->forced_local) && h->def_regular) -++ if ((bfd_link_pic (info) -++ && (info->symbolic || h->dynindx == -1 || h->forced_local) -++ && h->def_regular) -++ || (bfd_link_pie (info) && h->def_regular)) -+ { -+ rela.r_info = ELF32_R_INFO (0, R_NDS32_RELATIVE); -+ rela.r_addend = (h->root.u.def.value -+- + h->root.u.def.section->output_section->vma -+- + h->root.u.def.section->output_offset); -++ + h->root.u.def.section->output_section->vma -++ + h->root.u.def.section->output_offset); -++ -++ /* FIXME: cancel PLT trampoline, too late ?? */ -++ /* h->plt.offset = (bfd_vma) -1; */ -++ -++ if ((h->got.offset & 1) == 0) -++ { -++ bfd_put_32 (output_bfd, rela.r_addend, -++ sgot->contents + h->got.offset); -++ } -+ } -+ else -+ { -+@@ -5518,10 +6702,11 @@ nds32_elf_finish_dynamic_symbol (bfd *output_bfd, struct bfd_link_info *info, -+ rela.r_addend = 0; -+ } -+ -+- loc = srela->contents; -+- loc += srela->reloc_count * sizeof (Elf32_External_Rela); -++ loc = srelagot->contents; -++ loc += srelagot->reloc_count * sizeof (Elf32_External_Rela); -+ bfd_elf32_swap_reloca_out (output_bfd, &rela, loc); -+- ++srela->reloc_count; -++ ++srelagot->reloc_count; -++ BFD_ASSERT (loc < (srelagot->contents + srelagot->size)); -+ } -+ -+ if (h->needs_copy) -+@@ -5563,23 +6748,32 @@ nds32_elf_finish_dynamic_symbol (bfd *output_bfd, struct bfd_link_info *info, -+ static bfd_boolean -+ nds32_elf_finish_dynamic_sections (bfd *output_bfd, struct bfd_link_info *info) -+ { -+- struct elf_nds32_link_hash_table *htab; -+ bfd *dynobj; -+ asection *sdyn; -+- asection *sgot; -++ asection *sgotplt; -++ struct elf_link_hash_table *ehtab; -++ struct elf_nds32_link_hash_table *htab; -+ -++ ehtab = elf_hash_table (info); -+ htab = nds32_elf_hash_table (info); -+- dynobj = htab->root.dynobj; -++ if (htab == NULL) -++ return FALSE; -++ -++ dynobj = elf_hash_table (info)->dynobj; -+ -+- sgot = htab->root.sgotplt; -++ sgotplt = ehtab->sgotplt; -++ /* A broken linker script might have discarded the dynamic sections. -++ Catch this here so that we do not seg-fault later on. */ -++ if (sgotplt != NULL && bfd_is_abs_section (sgotplt->output_section)) -++ return FALSE; -+ sdyn = bfd_get_section_by_name (dynobj, ".dynamic"); -+ -+- if (htab->root.dynamic_sections_created) -++ if (elf_hash_table (info)->dynamic_sections_created) -+ { -+ asection *splt; -+ Elf32_External_Dyn *dyncon, *dynconend; -+ -+- BFD_ASSERT (sgot != NULL && sdyn != NULL); -++ BFD_ASSERT (sgotplt != NULL && sdyn != NULL); -+ -+ dyncon = (Elf32_External_Dyn *) sdyn->contents; -+ dynconend = (Elf32_External_Dyn *) (sdyn->contents + sdyn->size); -+@@ -5597,25 +6791,60 @@ nds32_elf_finish_dynamic_sections (bfd *output_bfd, struct bfd_link_info *info) -+ break; -+ -+ case DT_PLTGOT: -+- s = htab->root.sgotplt; -++ /* name = ".got"; */ -++ s = ehtab->sgot->output_section; -+ goto get_vma; -+ case DT_JMPREL: -+- s = htab->root.srelplt; -+- get_vma: -+- dyn.d_un.d_ptr = s->output_section->vma + s->output_offset; -++ s = ehtab->srelplt->output_section; -++get_vma: -++ BFD_ASSERT (s != NULL); -++ dyn.d_un.d_ptr = s->vma; -+ bfd_elf32_swap_dyn_out (output_bfd, &dyn, dyncon); -+ break; -+ -+ case DT_PLTRELSZ: -+- s = htab->root.srelplt; -++ s = ehtab->srelplt->output_section; -++ BFD_ASSERT (s != NULL); -+ dyn.d_un.d_val = s->size; -+ bfd_elf32_swap_dyn_out (output_bfd, &dyn, dyncon); -+ break; -++ -++ case DT_RELASZ: -++ /* My reading of the SVR4 ABI indicates that the -++ procedure linkage table relocs (DT_JMPREL) should be -++ included in the overall relocs (DT_RELA). This is -++ what Solaris does. However, UnixWare can not handle -++ that case. Therefore, we override the DT_RELASZ entry -++ here to make it not include the JMPREL relocs. Since -++ the linker script arranges for .rela.plt to follow all -++ other relocation sections, we don't have to worry -++ about changing the DT_RELA entry. */ -++ if (ehtab->srelplt != NULL) -++ { -++ s = ehtab->srelplt->output_section; -++ dyn.d_un.d_val -= s->size; -++ } -++ bfd_elf32_swap_dyn_out (output_bfd, &dyn, dyncon); -++ break; -++ -++ case DT_TLSDESC_PLT: -++ s = htab->root.splt; -++ dyn.d_un.d_ptr = (s->output_section->vma + s->output_offset -++ + htab->dt_tlsdesc_plt); -++ bfd_elf32_swap_dyn_out (output_bfd, &dyn, dyncon); -++ break; -++ -++ case DT_TLSDESC_GOT: -++ s = htab->root.sgot; -++ dyn.d_un.d_ptr = (s->output_section->vma + s->output_offset -++ + htab->dt_tlsdesc_got); -++ bfd_elf32_swap_dyn_out (output_bfd, &dyn, dyncon); -++ break; -+ } -+ } -+ -+ /* Fill in the first entry in the procedure linkage table. */ -+- splt = htab->root.splt; -++ splt = ehtab->splt; -+ if (splt && splt->size > 0) -+ { -+ if (bfd_link_pic (info)) -+@@ -5624,13 +6853,11 @@ nds32_elf_finish_dynamic_sections (bfd *output_bfd, struct bfd_link_info *info) -+ long offset; -+ -+ /* FIXME, sda_base is 65536, it will damage opcode. */ -+- /* insn = PLT_PIC_ENTRY_WORD0 + (((got_offset - sda_base) >> 2) & 0x7fff); */ -+- offset = sgot->output_section->vma + sgot->output_offset + 4 -+- - elf_gp (output_bfd); -++ offset = sgotplt->output_section->vma + sgotplt->output_offset + 4 -++ - elf_gp (output_bfd); -+ insn = PLT0_PIC_ENTRY_WORD0 | ((offset >> 12) & 0xfffff); -+ bfd_putb32 (insn, splt->contents); -+ -+- /* insn = PLT0_PIC_ENTRY_WORD0 | (((8 - sda_base) >> 2) & 0x7fff) ; */ -+ /* here has a typo? */ -+ insn = PLT0_PIC_ENTRY_WORD1 | (offset & 0xfff); -+ bfd_putb32 (insn, splt->contents + 4); -+@@ -5652,8 +6879,8 @@ nds32_elf_finish_dynamic_sections (bfd *output_bfd, struct bfd_link_info *info) -+ unsigned long insn; -+ unsigned long addr; -+ -+- /* addr = .got + 4 */ -+- addr = sgot->output_section->vma + sgot->output_offset + 4; -++ /* addr = .got + 4 */ -++ addr = sgotplt->output_section->vma + sgotplt->output_offset + 4; -+ insn = PLT0_ENTRY_WORD0 | ((addr >> 12) & 0xfffff); -+ bfd_putb32 (insn, splt->contents); -+ -+@@ -5673,21 +6900,48 @@ nds32_elf_finish_dynamic_sections (bfd *output_bfd, struct bfd_link_info *info) -+ elf_section_data (splt->output_section)->this_hdr.sh_entsize = -+ PLT_ENTRY_SIZE; -+ } -++ -++ if (htab->dt_tlsdesc_plt) -++ { -++ /* Calculate addresses. */ -++ asection *sgot = sgot = ehtab->sgot; -++ bfd_vma pltgot = sgotplt->output_section->vma -++ + sgotplt->output_offset; -++ bfd_vma tlsdesc_got = sgot->output_section->vma + sgot->output_offset -++ + htab->dt_tlsdesc_got; -++ -++ /* Get GP offset. */ -++ pltgot -= elf_gp (output_bfd) - 4; /* PLTGOT[1] */ -++ tlsdesc_got -= elf_gp (output_bfd); -++ -++ /* Do relocation. */ -++ dl_tlsdesc_lazy_trampoline[0] += ((1 << 20) - 1) & (tlsdesc_got >> 12); -++ dl_tlsdesc_lazy_trampoline[1] += 0xfff & tlsdesc_got; -++ dl_tlsdesc_lazy_trampoline[4] += ((1 << 20) - 1) & (pltgot >> 12); -++ dl_tlsdesc_lazy_trampoline[5] += 0xfff & pltgot; -++ -++ /* TODO: relaxation. */ -++ -++ /* Insert .plt. */ -++ nds32_put_trampoline (splt->contents + htab->dt_tlsdesc_plt, -++ dl_tlsdesc_lazy_trampoline, -++ ARRAY_SIZE (dl_tlsdesc_lazy_trampoline)); -++ } -+ } -+ -+ /* Fill in the first three entries in the global offset table. */ -+- if (sgot && sgot->size > 0) -++ if (sgotplt && sgotplt->size > 0) -+ { -+ if (sdyn == NULL) -+- bfd_put_32 (output_bfd, (bfd_vma) 0, sgot->contents); -++ bfd_put_32 (output_bfd, (bfd_vma) 0, sgotplt->contents); -+ else -+ bfd_put_32 (output_bfd, -+ sdyn->output_section->vma + sdyn->output_offset, -+- sgot->contents); -+- bfd_put_32 (output_bfd, (bfd_vma) 0, sgot->contents + 4); -+- bfd_put_32 (output_bfd, (bfd_vma) 0, sgot->contents + 8); -++ sgotplt->contents); -++ bfd_put_32 (output_bfd, (bfd_vma) 0, sgotplt->contents + 4); -++ bfd_put_32 (output_bfd, (bfd_vma) 0, sgotplt->contents + 8); -+ -+- elf_section_data (sgot->output_section)->this_hdr.sh_entsize = 4; -++ elf_section_data (sgotplt->output_section)->this_hdr.sh_entsize = 4; -+ } -+ -+ return TRUE; -+@@ -5738,6 +6992,7 @@ nds32_elf_final_write_processing (bfd *abfd, -+ { -+ unsigned long val; -+ static unsigned int cur_mach = 0; -++ unsigned int i; -+ -+ if (bfd_mach_n1 != bfd_get_mach (abfd)) -+ { -+@@ -5771,6 +7026,36 @@ nds32_elf_final_write_processing (bfd *abfd, -+ -+ elf_elfheader (abfd)->e_flags &= ~EF_NDS_ARCH; -+ elf_elfheader (abfd)->e_flags |= val; -++ if (ifc_flag) -++ elf_elfheader (abfd)->e_flags |= E_NDS32_HAS_IFC_INST ; -++ -++ if (ict_file) -++ { -++ fprintf (ict_file, ".section " NDS32_ICT_SECTION ", \"ax\"\n"); -++ if (ict_model == R_NDS32_RELAX_ENTRY_ICT_LARGE) -++ fprintf (ict_file, ".ict_model\tlarge\n"); -++ else -++ fprintf (ict_file, ".ict_model\tsmall\n"); -++ fprintf (ict_file, ".globl _INDIRECT_CALL_TABLE_BASE_\n" -++ "_INDIRECT_CALL_TABLE_BASE_:\n"); -++ /* Output rom patch entries. */ -++ indirect_call_table.frozen = 1; -++ for (i = 0; i < indirect_call_table.size; i++) -++ { -++ struct bfd_hash_entry *p; -++ struct elf_nds32_ict_hash_entry *entry; -++ -++ for (p = indirect_call_table.table[i]; p != NULL; p = p->next) -++ { -++ entry = (struct elf_nds32_ict_hash_entry *) p; -++ if (ict_model == R_NDS32_RELAX_ENTRY_ICT_LARGE) -++ fprintf (ict_file, "\t.word\t%s\n", entry->root.string); -++ else -++ fprintf (ict_file, "\tj\t%s\n", entry->root.string); -++ } -++ } -++ indirect_call_table.frozen = 0; -++ } -+ } -+ -+ /* Function to keep NDS32 specific file flags. */ -+@@ -5856,13 +7141,27 @@ nds32_check_vec_size (bfd *ibfd) -+ return TRUE; -+ } -+ -++static unsigned int -++nds32_elf_force_to_set_output_abi (char *str) -++{ -++ flagword flags; -++ -++ if (strcmp (str, "AABI") == 0) -++ flags = E_NDS_ABI_AABI; -++ else if (strcmp (str, "V2FP+") == 0) -++ flags = E_NDS_ABI_V2FP_PLUS; -++ else -++ flags = 0; -++ -++ return flags; -++} -++ -+ /* Merge backend specific data from an object file to the output -+ object file when linking. */ -+ -+ static bfd_boolean -+ nds32_elf_merge_private_bfd_data (bfd *ibfd, struct bfd_link_info *info) -+ { -+- bfd *obfd = info->output_bfd; -+ flagword out_flags; -+ flagword in_flags; -+ flagword out_16regs; -+@@ -5873,6 +7172,7 @@ nds32_elf_merge_private_bfd_data (bfd *ibfd, struct bfd_link_info *info) -+ flagword in_version; -+ flagword out_fpu_config; -+ flagword in_fpu_config; -++ bfd *obfd = info->output_bfd; -+ -+ /* TODO: Revise to use object-attributes instead. */ -+ if (!nds32_check_vec_size (ibfd)) -+@@ -5891,135 +7191,171 @@ nds32_elf_merge_private_bfd_data (bfd *ibfd, struct bfd_link_info *info) -+ return FALSE; -+ } -+ -+- in_version = elf_elfheader (ibfd)->e_flags & EF_NDS32_ELF_VERSION; -+- if (in_version == E_NDS32_ELF_VER_1_2) -+- { -+- _bfd_error_handler -+- (_("%B: warning: Older version of object file encountered, " -+- "Please recompile with current tool chain."), ibfd); -+- } -+- -+- /* We may need to merge V1 and V2 arch object files to V2. */ -+- if ((elf_elfheader (ibfd)->e_flags & EF_NDS_ARCH) -+- != (elf_elfheader (obfd)->e_flags & EF_NDS_ARCH)) -++ /* [Bug 11585] [Ticket 7067] -B option in objcopy cannot work as expected. -++ e_flags = 0 shall be treat as generic one. -++ no checking, and no merging. */ -++ if (elf_elfheader (ibfd)->e_flags) -+ { -+- /* Need to convert version. */ -+- if ((elf_elfheader (ibfd)->e_flags & EF_NDS_ARCH) -+- == E_NDS_ARCH_STAR_RESERVED) -++ in_version = elf_elfheader (ibfd)->e_flags & EF_NDS32_ELF_VERSION; -++ if (in_version == E_NDS32_ELF_VER_1_2) -+ { -+- elf_elfheader (obfd)->e_flags = elf_elfheader (ibfd)->e_flags; -++ _bfd_error_handler -++ (_("%pB: warning: Older version of object file encountered, " -++ "Please recompile with current tool chain."), ibfd); -+ } -+- else if ((elf_elfheader (obfd)->e_flags & EF_NDS_ARCH) == E_NDS_ARCH_STAR_V0_9 -+- || (elf_elfheader (ibfd)->e_flags & EF_NDS_ARCH) -+- > (elf_elfheader (obfd)->e_flags & EF_NDS_ARCH)) -++ -++ if (output_abi != NULL) -+ { -+- elf_elfheader (obfd)->e_flags = -+- convert_e_flags (elf_elfheader (obfd)->e_flags, -+- (elf_elfheader (ibfd)->e_flags & EF_NDS_ARCH)); -++ elf_elfheader (ibfd)->e_flags &= ~(EF_NDS_ABI); -++ elf_elfheader (ibfd)->e_flags -++ |= nds32_elf_force_to_set_output_abi (output_abi); -++ elf_elfheader (obfd)->e_flags &= ~(EF_NDS_ABI); -++ elf_elfheader (obfd)->e_flags -++ |= nds32_elf_force_to_set_output_abi (output_abi); -+ } -+- else -++ -++ /* We may need to merge V1 and V2 arch object files to V2. */ -++ if ((elf_elfheader (ibfd)->e_flags & EF_NDS_ARCH) -++ != (elf_elfheader (obfd)->e_flags & EF_NDS_ARCH)) -+ { -+- elf_elfheader (ibfd)->e_flags = -+- convert_e_flags (elf_elfheader (ibfd)->e_flags, -+- (elf_elfheader (obfd)->e_flags & EF_NDS_ARCH)); -+- } -+- } -+- -+- /* Extract some flags. */ -+- in_flags = elf_elfheader (ibfd)->e_flags -+- & (~(E_NDS32_HAS_REDUCED_REGS | EF_NDS32_ELF_VERSION -+- | E_NDS32_HAS_NO_MAC_INST | E_NDS32_FPU_REG_CONF)); -+- -+- /* The following flags need special treatment. */ -+- in_16regs = elf_elfheader (ibfd)->e_flags & E_NDS32_HAS_REDUCED_REGS; -+- in_no_mac = elf_elfheader (ibfd)->e_flags & E_NDS32_HAS_NO_MAC_INST; -+- in_fpu_config = elf_elfheader (ibfd)->e_flags & E_NDS32_FPU_REG_CONF; -+- -+- /* Extract some flags. */ -+- out_flags = elf_elfheader (obfd)->e_flags -+- & (~(E_NDS32_HAS_REDUCED_REGS | EF_NDS32_ELF_VERSION -+- | E_NDS32_HAS_NO_MAC_INST | E_NDS32_FPU_REG_CONF)); -+- -+- /* The following flags need special treatment. */ -+- out_16regs = elf_elfheader (obfd)->e_flags & E_NDS32_HAS_REDUCED_REGS; -+- out_no_mac = elf_elfheader (obfd)->e_flags & E_NDS32_HAS_NO_MAC_INST; -+- out_fpu_config = elf_elfheader (obfd)->e_flags & E_NDS32_FPU_REG_CONF; -+- out_version = elf_elfheader (obfd)->e_flags & EF_NDS32_ELF_VERSION; -+- if (!elf_flags_init (obfd)) -+- { -+- /* If the input is the default architecture then do not -+- bother setting the flags for the output architecture, -+- instead allow future merges to do this. If no future -+- merges ever set these flags then they will retain their -+- unitialised values, which surprise surprise, correspond -+- to the default values. */ -+- if (bfd_get_arch_info (ibfd)->the_default) -+- return TRUE; -++ /* Need to convert version. */ -++ if ((elf_elfheader (ibfd)->e_flags & EF_NDS_ARCH) -++ == E_NDS_ARCH_STAR_RESERVED) -++ { -++ elf_elfheader (obfd)->e_flags = elf_elfheader (ibfd)->e_flags; -++ } -++ else if ((elf_elfheader (ibfd)->e_flags & EF_NDS_ARCH) -++ == E_NDS_ARCH_STAR_V3_M -++ && (elf_elfheader (obfd)->e_flags & EF_NDS_ARCH) -++ == E_NDS_ARCH_STAR_V3_0) -++ { -++ elf_elfheader (ibfd)->e_flags = -++ (elf_elfheader (ibfd)->e_flags & (~EF_NDS_ARCH)) -++ | E_NDS_ARCH_STAR_V3_0; -++ } -++ else if ((elf_elfheader (obfd)->e_flags & EF_NDS_ARCH) -++ == E_NDS_ARCH_STAR_V0_9 -++ || (elf_elfheader (ibfd)->e_flags & EF_NDS_ARCH) -++ > (elf_elfheader (obfd)->e_flags & EF_NDS_ARCH)) -++ { -++ elf_elfheader (obfd)->e_flags = -++ convert_e_flags (elf_elfheader (obfd)->e_flags, -++ (elf_elfheader (ibfd)->e_flags & EF_NDS_ARCH)); -++ } -++ else -++ { -++ elf_elfheader (ibfd)->e_flags = -++ convert_e_flags (elf_elfheader (ibfd)->e_flags, -++ (elf_elfheader (obfd)->e_flags & EF_NDS_ARCH)); -++ } -++ } -+ -+- elf_flags_init (obfd) = TRUE; -+- elf_elfheader (obfd)->e_flags = elf_elfheader (ibfd)->e_flags; -++ /* Extract some flags. */ -++ in_flags = elf_elfheader (ibfd)->e_flags -++ & (~(E_NDS32_HAS_REDUCED_REGS | EF_NDS32_ELF_VERSION -++ | E_NDS32_HAS_NO_MAC_INST | E_NDS32_FPU_REG_CONF)); -++ -++ /* The following flags need special treatment. */ -++ in_16regs = elf_elfheader (ibfd)->e_flags & E_NDS32_HAS_REDUCED_REGS; -++ in_no_mac = elf_elfheader (ibfd)->e_flags & E_NDS32_HAS_NO_MAC_INST; -++ in_fpu_config = elf_elfheader (ibfd)->e_flags & E_NDS32_FPU_REG_CONF; -++ -++ /* Extract some flags. */ -++ out_flags = elf_elfheader (obfd)->e_flags -++ & (~(E_NDS32_HAS_REDUCED_REGS | EF_NDS32_ELF_VERSION -++ | E_NDS32_HAS_NO_MAC_INST | E_NDS32_FPU_REG_CONF)); -++ -++ /* The following flags need special treatment. */ -++ out_16regs = elf_elfheader (obfd)->e_flags & E_NDS32_HAS_REDUCED_REGS; -++ out_no_mac = elf_elfheader (obfd)->e_flags & E_NDS32_HAS_NO_MAC_INST; -++ out_fpu_config = elf_elfheader (obfd)->e_flags & E_NDS32_FPU_REG_CONF; -++ out_version = elf_elfheader (obfd)->e_flags & EF_NDS32_ELF_VERSION; -++ if (!elf_flags_init (obfd)) -++ { -++ /* If the input is the default architecture then do not -++ bother setting the flags for the output architecture, -++ instead allow future merges to do this. If no future -++ merges ever set these flags then they will retain their -++ unitialised values, which surprise surprise, correspond -++ to the default values. */ -++ if (bfd_get_arch_info (ibfd)->the_default) -++ return TRUE; -+ -+- if (bfd_get_arch (obfd) == bfd_get_arch (ibfd) -+- && bfd_get_arch_info (obfd)->the_default) -+- { -+- return bfd_set_arch_mach (obfd, bfd_get_arch (ibfd), -+- bfd_get_mach (ibfd)); -++ elf_flags_init (obfd) = TRUE; -++ elf_elfheader (obfd)->e_flags = elf_elfheader (ibfd)->e_flags; -++ -++ if (bfd_get_arch (obfd) == bfd_get_arch (ibfd) -++ && bfd_get_arch_info (obfd)->the_default) -++ { -++ return bfd_set_arch_mach (obfd, bfd_get_arch (ibfd), -++ bfd_get_mach (ibfd)); -++ } -++ -++ return TRUE; -+ } -+ -+- return TRUE; -+- } -++ /* Check flag compatibility. */ -++ if ((in_flags & EF_NDS_ABI) != (out_flags & EF_NDS_ABI)) -++ { -++ asection *section = NULL; -++ bfd_byte *contents = NULL; -++ section = bfd_get_section_by_name (ibfd, ".note.v2abi_compatible"); -++ if (section) -++ bfd_get_full_section_contents (ibfd, section, &contents); -+ -+- /* Check flag compatibility. */ -+- if ((in_flags & EF_NDS_ABI) != (out_flags & EF_NDS_ABI)) -+- { -+- _bfd_error_handler -+- (_("%B: error: ABI mismatch with previous modules."), ibfd); -++ /* Only enable v3f/v3s toolchain to link v2abi compatible objects. */ -++ if ((contents == NULL) -++ || bfd_getb32 (contents) != 1 -++ || (out_flags & EF_NDS_ABI) != E_NDS_ABI_V2FP_PLUS) -++ { -++ _bfd_error_handler -++ (_("%pB: error: ABI mismatch with previous modules."), ibfd); -+ -+- bfd_set_error (bfd_error_bad_value); -+- return FALSE; -+- } -++ bfd_set_error (bfd_error_bad_value); -++ return FALSE; -++ } -++ } -+ -+- if ((in_flags & EF_NDS_ARCH) != (out_flags & EF_NDS_ARCH)) -+- { -+- if (((in_flags & EF_NDS_ARCH) != E_N1_ARCH)) -++ if ((in_flags & EF_NDS_ARCH) != (out_flags & EF_NDS_ARCH)) -+ { -+- _bfd_error_handler -+- (_("%B: error: Instruction set mismatch with previous modules."), ibfd); -++ if (((in_flags & EF_NDS_ARCH) != E_N1_ARCH)) -++ { -++ _bfd_error_handler -++ (_("%B: error: Instruction set mismatch with previous modules."), ibfd); -+ -+- bfd_set_error (bfd_error_bad_value); -+- return FALSE; -++ bfd_set_error (bfd_error_bad_value); -++ return FALSE; -++ } -+ } -+- } -+ -+- /* When linking with V1.2 and V1.3 objects together the output is V1.2. -+- and perf ext1 and DIV are mergerd to perf ext1. */ -+- if (in_version == E_NDS32_ELF_VER_1_2 || out_version == E_NDS32_ELF_VER_1_2) -+- { -+- elf_elfheader (obfd)->e_flags = -+- (in_flags & (~(E_NDS32_HAS_EXT_INST | E_NDS32_HAS_DIV_INST))) -+- | (out_flags & (~(E_NDS32_HAS_EXT_INST | E_NDS32_HAS_DIV_INST))) -+- | (((in_flags & (E_NDS32_HAS_EXT_INST | E_NDS32_HAS_DIV_INST))) -+- ? E_NDS32_HAS_EXT_INST : 0) -+- | (((out_flags & (E_NDS32_HAS_EXT_INST | E_NDS32_HAS_DIV_INST))) -+- ? E_NDS32_HAS_EXT_INST : 0) -+- | (in_16regs & out_16regs) | (in_no_mac & out_no_mac) -+- | ((in_version > out_version) ? out_version : in_version); -+- } -+- else -+- { -+- if (in_version != out_version) -+- _bfd_error_handler -+- /* xgettext:c-format */ -+- (_("%B: warning: Incompatible elf-versions %s and %s."), -+- ibfd, nds32_elfver_strtab[out_version], -+- nds32_elfver_strtab[in_version]); -++ /* When linking with V1.2 and V1.3 objects together the output is V1.2. -++ and perf ext1 and DIV are mergerd to perf ext1. */ -++ if (in_version == E_NDS32_ELF_VER_1_2 || out_version == E_NDS32_ELF_VER_1_2) -++ { -++ elf_elfheader (obfd)->e_flags = -++ (in_flags & (~(E_NDS32_HAS_EXT_INST | E_NDS32_HAS_DIV_INST))) -++ | (out_flags & (~(E_NDS32_HAS_EXT_INST | E_NDS32_HAS_DIV_INST))) -++ | (((in_flags & (E_NDS32_HAS_EXT_INST | E_NDS32_HAS_DIV_INST))) -++ ? E_NDS32_HAS_EXT_INST : 0) -++ | (((out_flags & (E_NDS32_HAS_EXT_INST | E_NDS32_HAS_DIV_INST))) -++ ? E_NDS32_HAS_EXT_INST : 0) -++ | (in_16regs & out_16regs) | (in_no_mac & out_no_mac) -++ | ((in_version > out_version) ? out_version : in_version); -++ } -++ else -++ { -++ if (in_version != out_version) -++ _bfd_error_handler -++ (_("%B: warning: Incompatible elf-versions %s and %s."), ibfd, -++ nds32_elfver_strtab[out_version], -++ nds32_elfver_strtab[in_version]); -+ -+- elf_elfheader (obfd)->e_flags = in_flags | out_flags -+- | (in_16regs & out_16regs) | (in_no_mac & out_no_mac) -+- | (in_fpu_config > out_fpu_config ? in_fpu_config : out_fpu_config) -+- | (in_version > out_version ? out_version : in_version); -++ elf_elfheader (obfd)->e_flags = in_flags | out_flags -++ | (in_16regs & out_16regs) | (in_no_mac & out_no_mac) -++ | (in_fpu_config > out_fpu_config ? in_fpu_config : out_fpu_config) -++ | (in_version > out_version ? out_version : in_version); -++ } -+ } -+- -+ return TRUE; -+ } -+ -+@@ -6081,6 +7417,79 @@ nds32_elf_gc_mark_hook (asection *sec, struct bfd_link_info *info, -+ return _bfd_elf_gc_mark_hook (sec, info, rel, h, sym); -+ } -+ -++static enum elf_nds32_tls_type -++get_tls_type (enum elf_nds32_reloc_type r_type, -++ struct elf_link_hash_entry *h ATTRIBUTE_UNUSED) -++{ -++ enum elf_nds32_tls_type tls_type; -++ switch (r_type) -++ { -++ case R_NDS32_TLS_LE_HI20: -++ case R_NDS32_TLS_LE_LO12: -++ tls_type = GOT_TLS_LE; -++ break; -++ case R_NDS32_TLS_IE_HI20: -++ case R_NDS32_TLS_IE_LO12S2: -++ case R_NDS32_TLS_IE_LO12: -++ tls_type = GOT_TLS_IE; -++ break; -++ case R_NDS32_TLS_IEGP_HI20: -++ case R_NDS32_TLS_IEGP_LO12: -++ case R_NDS32_TLS_IEGP_LO12S2: -++ tls_type = GOT_TLS_IEGP; -++ break; -++ case R_NDS32_TLS_DESC_HI20: -++ case R_NDS32_TLS_DESC_LO12: -++ case R_NDS32_TLS_DESC_ADD: -++ case R_NDS32_TLS_DESC_FUNC: -++ case R_NDS32_TLS_DESC_CALL: -++ tls_type = GOT_TLS_DESC; -++ break; -++ default: -++ tls_type = GOT_NORMAL; -++ break; -++ } -++ return tls_type; -++} -++ -++/* Ensure that we have allocated bookkeeping structures for ABFD's local -++ symbols. */ -++ -++static bfd_boolean -++elf32_nds32_allocate_local_sym_info (bfd *abfd) -++{ -++ if (elf_local_got_refcounts (abfd) == NULL) -++ { -++ bfd_size_type num_syms; -++ bfd_size_type size; -++ char *data; -++ -++ num_syms = elf_tdata (abfd)->symtab_hdr.sh_info; -++ /* This space is for got_refcounts, got_tls_type, tlsdesc_gotent, and -++ gp_offset. The details can refer to struct elf_nds32_obj_tdata. */ -++ size = num_syms * (sizeof (bfd_signed_vma) + sizeof (char) -++ + sizeof (bfd_vma) + sizeof (int) -++ + sizeof (bfd_boolean) + sizeof (bfd_vma)); -++ data = bfd_zalloc (abfd, size); -++ if (data == NULL) -++ return FALSE; -++ -++ elf_local_got_refcounts (abfd) = (bfd_signed_vma *) data; -++ data += num_syms * sizeof (bfd_signed_vma); -++ -++ elf32_nds32_local_got_tls_type (abfd) = (char *) data; -++ data += num_syms * sizeof (char); -++ -++ elf32_nds32_local_tlsdesc_gotent (abfd) = (bfd_vma *) data; -++ data += num_syms * sizeof (bfd_vma); -++ -++ elf32_nds32_local_gp_offset (abfd) = (int *) data; -++ data += num_syms * sizeof (int); -++ } -++ -++ return TRUE; -++} -++ -+ /* Look through the relocs for a section during the first phase. -+ Since we don't do .gots or .plts, we just need to consider the -+ virtual table relocs for gc. */ -+@@ -6093,21 +7502,17 @@ nds32_elf_check_relocs (bfd *abfd, struct bfd_link_info *info, -+ struct elf_link_hash_entry **sym_hashes, **sym_hashes_end; -+ const Elf_Internal_Rela *rel; -+ const Elf_Internal_Rela *rel_end; -++ struct elf_link_hash_table *ehtab; -+ struct elf_nds32_link_hash_table *htab; -+ bfd *dynobj; -+ asection *sreloc = NULL; -+ -++ /* No need for relocation if relocatable already. */ -+ if (bfd_link_relocatable (info)) -+- return TRUE; -+- -+- /* Don't do anything special with non-loaded, non-alloced sections. -+- In particular, any relocs in such sections should not affect GOT -+- and PLT reference counting (ie. we don't allow them to create GOT -+- or PLT entries), there's no possibility or desire to optimize TLS -+- relocs, and there's not much point in propagating relocs to shared -+- libs that the dynamic linker won't relocate. */ -+- if ((sec->flags & SEC_ALLOC) == 0) -+- return TRUE; -++ { -++ elf32_nds32_check_relax_group (abfd, sec); -++ return TRUE; -++ } -+ -+ symtab_hdr = &elf_tdata (abfd)->symtab_hdr; -+ sym_hashes = elf_sym_hashes (abfd); -+@@ -6116,6 +7521,7 @@ nds32_elf_check_relocs (bfd *abfd, struct bfd_link_info *info, -+ if (!elf_bad_symtab (abfd)) -+ sym_hashes_end -= symtab_hdr->sh_info; -+ -++ ehtab = elf_hash_table (info); -+ htab = nds32_elf_hash_table (info); -+ dynobj = htab->root.dynobj; -+ -+@@ -6125,7 +7531,8 @@ nds32_elf_check_relocs (bfd *abfd, struct bfd_link_info *info, -+ enum elf_nds32_reloc_type r_type; -+ struct elf_link_hash_entry *h; -+ unsigned long r_symndx; -+- int tls_type, old_tls_type; -++ enum elf_nds32_tls_type tls_type, old_tls_type; -++ struct elf_nds32_ict_hash_entry *entry; -+ -+ r_symndx = ELF32_R_SYM (rel->r_info); -+ r_type = ELF32_R_TYPE (rel->r_info); -+@@ -6139,10 +7546,11 @@ nds32_elf_check_relocs (bfd *abfd, struct bfd_link_info *info, -+ h = (struct elf_link_hash_entry *) h->root.u.i.link; -+ } -+ -+- /* Some relocs require a global offset table. We create -+- got section here, since these relocation need got section -+- and it is not created yet. */ -+- if (htab->root.sgot == NULL) -++ /* create .got section if necessary -++ Some relocs require a global offset table. We create -++ got section here, since these relocation need a got section -++ and if it is not created yet. */ -++ if (ehtab->sgot == NULL) -+ { -+ switch (r_type) -+ { -+@@ -6162,10 +7570,16 @@ nds32_elf_check_relocs (bfd *abfd, struct bfd_link_info *info, -+ case R_NDS32_GOTPC_LO12: -+ case R_NDS32_GOT20: -+ case R_NDS32_TLS_IE_HI20: -++ case R_NDS32_TLS_IE_LO12: -+ case R_NDS32_TLS_IE_LO12S2: -++ case R_NDS32_TLS_IEGP_HI20: -++ case R_NDS32_TLS_IEGP_LO12: -++ case R_NDS32_TLS_IEGP_LO12S2: -++ case R_NDS32_TLS_DESC_HI20: -++ case R_NDS32_TLS_DESC_LO12: -+ if (dynobj == NULL) -+ htab->root.dynobj = dynobj = abfd; -+- if (!_bfd_elf_create_got_section (dynobj, info)) -++ if (!create_got_section (dynobj, info)) -+ return FALSE; -+ break; -+ -+@@ -6174,59 +7588,54 @@ nds32_elf_check_relocs (bfd *abfd, struct bfd_link_info *info, -+ } -+ } -+ -++ /* Check relocation type. */ -+ switch ((int) r_type) -+ { -++ case R_NDS32_TLS_LE_HI20: -++ case R_NDS32_TLS_LE_LO12: -+ case R_NDS32_GOT_HI20: -+ case R_NDS32_GOT_LO12: -+ case R_NDS32_GOT_LO15: -+ case R_NDS32_GOT_LO19: -+ case R_NDS32_GOT20: -+ case R_NDS32_TLS_IE_HI20: -++ case R_NDS32_TLS_IE_LO12: -+ case R_NDS32_TLS_IE_LO12S2: -+- switch (r_type) -+- { -+- case R_NDS32_TLS_IE_HI20: -+- case R_NDS32_TLS_IE_LO12S2: -+- tls_type = GOT_TLS_IE; -+- break; -+- default: -+- tls_type = GOT_NORMAL; -+- break; -+- } -+- if (h != NULL) -++ case R_NDS32_TLS_IEGP_HI20: -++ case R_NDS32_TLS_IEGP_LO12: -++ case R_NDS32_TLS_IEGP_LO12S2: -++ case R_NDS32_TLS_DESC_HI20: -++ case R_NDS32_TLS_DESC_LO12: -++ tls_type = get_tls_type (r_type, h); -++ if (h) -+ { -++ if (tls_type != GOT_TLS_LE) -++ h->got.refcount += 1; -+ old_tls_type = elf32_nds32_hash_entry (h)->tls_type; -+- h->got.refcount += 1; -+ } -+ else -+ { -+- bfd_signed_vma *local_got_refcounts; -+- -+- /* This is a global offset table entry for a local -+- symbol. */ -+- local_got_refcounts = elf_local_got_refcounts (abfd); -+- if (local_got_refcounts == NULL) -+- { -+- bfd_size_type size; -++ /* This is a global offset table entry for a local symbol. */ -++ if (!elf32_nds32_allocate_local_sym_info (abfd)) -++ return FALSE; -+ -+- size = symtab_hdr->sh_info; -+- size *= sizeof (bfd_signed_vma); -+- local_got_refcounts = (bfd_signed_vma *) bfd_zalloc (abfd, size); -+- if (local_got_refcounts == NULL) -+- return FALSE; -+- elf_local_got_refcounts (abfd) = local_got_refcounts; -+- } -+- local_got_refcounts[r_symndx] += 1; -++ BFD_ASSERT (r_symndx < symtab_hdr->sh_info); -++ if (tls_type != GOT_TLS_LE) -++ elf_local_got_refcounts (abfd)[r_symndx] += 1; -+ old_tls_type = elf32_nds32_local_got_tls_type (abfd)[r_symndx]; -+ } -+ -+- /* We will already have issued an error message if there -++ /* We would already issued an error message if there -+ is a TLS/non-TLS mismatch, based on the symbol -+- type. So just combine any TLS types needed. */ -++ type. So just combine any TLS types needed. */ -+ if (old_tls_type != GOT_UNKNOWN && old_tls_type != GOT_NORMAL -+ && tls_type != GOT_NORMAL) -+ tls_type |= old_tls_type; -+ -++ /* DESC to IE/IEGP if link to executable */ -++ if ((tls_type & (GOT_TLS_DESC | GOT_TLS_IEGP)) && (bfd_link_executable (info))) -++ tls_type |= (bfd_link_pie (info) ? GOT_TLS_IEGP : GOT_TLS_IE); -++ -+ if (old_tls_type != tls_type) -+ { -+ if (h != NULL) -+@@ -6235,6 +7644,7 @@ nds32_elf_check_relocs (bfd *abfd, struct bfd_link_info *info, -+ elf32_nds32_local_got_tls_type (abfd)[r_symndx] = tls_type; -+ } -+ break; -++ -+ case R_NDS32_9_PLTREL: -+ case R_NDS32_25_PLTREL: -+ case R_NDS32_PLTREL_HI20: -+@@ -6244,19 +7654,20 @@ nds32_elf_check_relocs (bfd *abfd, struct bfd_link_info *info, -+ case R_NDS32_PLT_GOTREL_LO15: -+ case R_NDS32_PLT_GOTREL_LO19: -+ case R_NDS32_PLT_GOTREL_LO20: -+- -+- /* This symbol requires a procedure linkage table entry. We -+- actually build the entry in adjust_dynamic_symbol, -++ /* This symbol requires a procedure linkage table entry. -++ We actually build the entry in adjust_dynamic_symbol, -+ because this might be a case of linking PIC code without -+ linking in any dynamic objects, in which case we don't -+ need to generate a procedure linkage table after all. */ -+ -+ /* If this is a local symbol, we resolve it directly without -+ creating a procedure linkage table entry. */ -++ /* explain: continue v.s. break here following: */ -+ if (h == NULL) -+ continue; -+ -+- if (h->forced_local) -++ if (h->forced_local -++ || (bfd_link_pie (info) && h->def_regular)) -+ break; -+ -+ elf32_nds32_hash_entry (h)->tls_type = GOT_NORMAL; -+@@ -6330,8 +7741,8 @@ nds32_elf_check_relocs (bfd *abfd, struct bfd_link_info *info, -+ && (h->root.type == bfd_link_hash_defweak -+ || !h->def_regular))) -+ { -+- struct elf_dyn_relocs *p; -+- struct elf_dyn_relocs **head; -++ struct elf_nds32_dyn_relocs *p; -++ struct elf_nds32_dyn_relocs **head; -+ -+ if (dynobj == NULL) -+ htab->root.dynobj = dynobj = abfd; -+@@ -6380,7 +7791,6 @@ nds32_elf_check_relocs (bfd *abfd, struct bfd_link_info *info, -+ else -+ { -+ asection *s; -+- void *vpp; -+ -+ Elf_Internal_Sym *isym; -+ isym = bfd_sym_from_r_symndx (&htab->sym_cache, abfd, r_symndx); -+@@ -6392,15 +7802,15 @@ nds32_elf_check_relocs (bfd *abfd, struct bfd_link_info *info, -+ if (s == NULL) -+ return FALSE; -+ -+- vpp = &elf_section_data (s)->local_dynrel; -+- head = (struct elf_dyn_relocs **) vpp; -++ head = ((struct elf_nds32_dyn_relocs **) -++ &elf_section_data (s)->local_dynrel); -+ } -+ -+ p = *head; -+ if (p == NULL || p->sec != sec) -+ { -+ bfd_size_type amt = sizeof (*p); -+- p = (struct elf_dyn_relocs *) bfd_alloc (dynobj, amt); -++ p = (struct elf_nds32_dyn_relocs *) bfd_alloc (dynobj, amt); -+ if (p == NULL) -+ return FALSE; -+ p->next = *head; -+@@ -6411,19 +7821,98 @@ nds32_elf_check_relocs (bfd *abfd, struct bfd_link_info *info, -+ } -+ -+ p->count += 1; -++ -++ /* FIXME: Since eh_frame is readonly, R_NDS32_32_RELA -++ reloc for eh_frame will cause shared library has -++ TEXTREL entry in the dynamic section. This lead glibc -++ testsuites to failure (bug-13092) and cause kernel fail -++ (bug-11819). I think the best solution is to replace -++ absolute reloc with pc relative reloc in the eh_frame. -++ To do that, we need to support the following issues: -++ -++ === For GCC === -++ * gcc/config/nds32/nds32.h: Define -++ ASM_PREFERRED_EH_DATA_FORMAT to encode DW_EH_PE_pcrel -++ and DW_EH_PE_sdata4 into DWARF exception header when -++ option have '-fpic'. -++ -++ === For binutils === -++ * bfd/: Define new reloc R_NDS32_32_PCREL_RELA. -++ * gas/config/tc-nds32.h: Define DIFF_EXPR_OK. This -++ may break our nds DIFF mechanism, therefore, we -++ must disable all linker relaxations to ensure -++ correctness. -++ * gas/config/tc-nds32.c (nds32_apply_fix): Replace -++ R_NDS32_32_RELA with R_NDS32_32_PCREL_RELA, and -++ do the necessary modification. -++ -++ Unfortunately, it still have some problems for nds32 -++ to support pc relative reloc in the eh_frame. So I use -++ another solution to fix this issue. -++ -++ However, I find that ld always emit TEXTREL marker for -++ R_NDS32_NONE relocs in rel.dyn. These none relocs are -++ correspond to R_NDS32_32_RELA for .eh_frame section. -++ It means that we always reserve redundant entries of rel.dyn -++ for these relocs which actually do nothing in dynamic linker. -++ -++ Therefore, we regard these relocs as pc relative relocs -++ here and increase the pc_count. */ -+ if (ELF32_R_TYPE (rel->r_info) == R_NDS32_25_PCREL_RELA -+ || ELF32_R_TYPE (rel->r_info) == R_NDS32_15_PCREL_RELA -+- || ELF32_R_TYPE (rel->r_info) == R_NDS32_17_PCREL_RELA) -++ || ELF32_R_TYPE (rel->r_info) == R_NDS32_17_PCREL_RELA -++ || (r_type == R_NDS32_32_RELA -++ && strcmp (sec->name, ".eh_frame") == 0)) -+ p->pc_count += 1; -+ } -+ break; -+ -+- /* This relocation describes the C++ object vtable hierarchy. -+- Reconstruct it for later use during GC. */ -+- case R_NDS32_RELA_GNU_VTINHERIT: -+- case R_NDS32_GNU_VTINHERIT: -+- if (!bfd_elf_gc_record_vtinherit (abfd, sec, h, rel->r_offset)) -+- return FALSE; -++ /* Merge jump-patch table symbol here. */ -++ case R_NDS32_ICT_HI20: -++ case R_NDS32_ICT_LO12: -++ case R_NDS32_ICT_25PC: -++ if (rel->r_addend != 0) -++ { -++ _bfd_error_handler -++ (_("%pB %s: Error: Rom-patch relocation offset: 0x%lx " -++ "with addend 0x%lx\n"), -++ abfd, sec->name, rel->r_offset, rel->r_addend); -++ bfd_set_error (bfd_error_bad_value); -++ return FALSE; -++ } -++ -++ if (h) -++ { -++ elf32_nds32_hash_entry (h)->indirect_call = TRUE; -++ entry = (struct elf_nds32_ict_hash_entry *) -++ bfd_hash_lookup (&indirect_call_table, h->root.root.string, -++ TRUE, TRUE); -++ entry->h = h; -++ if (entry == NULL) -++ { -++ _bfd_error_handler -++ (_("%pB: failed creating indirect call %s hash table\n"), -++ abfd, h->root.root.string); -++ bfd_set_error (bfd_error_bad_value); -++ return FALSE; -++ } -++ } -++ else -++ { -++ /* Rom-patch functions cannot be local. */ -++ _bfd_error_handler -++ (_("%pB: indirect call relocation with local symbol.\n"), abfd); -++ bfd_set_error (bfd_error_bad_value); -++ return FALSE; -++ } -++ break; -++ -++ /* This relocation describes the C++ object vtable hierarchy. -++ Reconstruct it for later use during GC. */ -++ case R_NDS32_RELA_GNU_VTINHERIT: -++ case R_NDS32_GNU_VTINHERIT: -++ if (!bfd_elf_gc_record_vtinherit (abfd, sec, h, rel->r_offset)) -++ return FALSE; -+ break; -+ -+ /* This relocation describes which C++ vtable entries are actually -+@@ -6436,6 +7925,18 @@ nds32_elf_check_relocs (bfd *abfd, struct bfd_link_info *info, -+ if (!bfd_elf_gc_record_vtentry (abfd, sec, h, rel->r_addend)) -+ return FALSE; -+ break; -++ case R_NDS32_RELAX_ENTRY: -++ if (ict_model == 0) -++ ict_model = rel->r_addend & R_NDS32_RELAX_ENTRY_ICT_MASK; -++ else if (ict_model != (rel->r_addend & R_NDS32_RELAX_ENTRY_ICT_MASK) -++ && (rel->r_addend & R_NDS32_RELAX_ENTRY_ICT_MASK) != 0) -++ { -++ _bfd_error_handler -++ (_("%pB Error: mixed ict model objects.\n"), abfd); -++ bfd_set_error (bfd_error_bad_value); -++ return FALSE; -++ } -++ break; -+ } -+ } -+ -+@@ -6464,8 +7965,7 @@ write_uleb128 (bfd_byte *p, unsigned int val) -+ -+ static bfd_signed_vma -+ calculate_offset (bfd *abfd, asection *sec, Elf_Internal_Rela *irel, -+- Elf_Internal_Sym *isymbuf, Elf_Internal_Shdr *symtab_hdr, -+- int *pic_ext_target) -++ Elf_Internal_Sym *isymbuf, Elf_Internal_Shdr *symtab_hdr) -+ { -+ bfd_signed_vma foff; -+ bfd_vma symval, addend; -+@@ -6494,7 +7994,6 @@ calculate_offset (bfd *abfd, asection *sec, Elf_Internal_Rela *irel, -+ { -+ unsigned long indx; -+ struct elf_link_hash_entry *h; -+- bfd *owner; -+ -+ /* An external symbol. */ -+ indx = ELF32_R_SYM (irel->r_info) - symtab_hdr->sh_info; -+@@ -6507,9 +8006,6 @@ calculate_offset (bfd *abfd, asection *sec, Elf_Internal_Rela *irel, -+ symbol. Just ignore it--it will be caught by the -+ regular reloc processing. */ -+ return 0; -+- owner = h->root.u.def.section->owner; -+- if (owner && (elf_elfheader (owner)->e_flags & E_NDS32_HAS_PIC)) -+- *pic_ext_target = 1; -+ -+ if (h->root.u.def.section->flags & SEC_MERGE) -+ { -+@@ -6563,15 +8059,15 @@ calculate_plt_memory_address (bfd *abfd, struct bfd_link_info *link_info, -+ { -+ unsigned long indx; -+ struct elf_link_hash_entry *h; -+- struct elf_nds32_link_hash_table *htab; -++ struct elf_link_hash_table *ehtab; -+ asection *splt; -+ -+ /* An external symbol. */ -+ indx = ELF32_R_SYM (irel->r_info) - symtab_hdr->sh_info; -+ h = elf_sym_hashes (abfd)[indx]; -+ BFD_ASSERT (h != NULL); -+- htab = nds32_elf_hash_table (link_info); -+- splt = htab->root.splt; -++ ehtab = elf_hash_table (link_info); -++ splt = ehtab->splt; -+ -+ while (h->root.type == bfd_link_hash_indirect -+ || h->root.type == bfd_link_hash_warning) -+@@ -6582,8 +8078,8 @@ calculate_plt_memory_address (bfd *abfd, struct bfd_link_info *link_info, -+ if (h->root.type != bfd_link_hash_defined -+ && h->root.type != bfd_link_hash_defweak) -+ /* This appears to be a reference to an undefined -+- * symbol. Just ignore it--it will be caught by the -+- * regular reloc processing. */ -++ symbol. Just ignore it--it will be caught by the -++ regular reloc processing. */ -+ return 0; -+ symval = (h->root.u.def.value -+ + h->root.u.def.section->output_section->vma -+@@ -6620,7 +8116,7 @@ nds32_convert_32_to_16_alu1 (bfd *abfd, uint32_t insn, uint16_t *pinsn16, -+ int *pinsn_type) -+ { -+ uint16_t insn16 = 0; -+- int insn_type = 0; -++ int insn_type; -+ unsigned long mach = bfd_get_mach (abfd); -+ -+ if (N32_SH5 (insn) != 0) -+@@ -6919,8 +8415,7 @@ nds32_convert_32_to_16 (bfd *abfd, uint32_t insn, uint16_t *pinsn16, -+ else if (N32_IS_RT4 (insn) && N32_RT5 (insn) == N32_RA5 (insn) -+ && N32_IMM15S (insn) > -32) -+ { -+- insn16 = N16_TYPE45 (SUBI45, N32_RT54 (insn), -+- 0 - N32_IMM15S (insn)); -++ insn16 = N16_TYPE45 (SUBI45, N32_RT54 (insn), 0 - N32_IMM15S (insn)); -+ insn_type = NDS32_INSN_SUBI45; -+ } -+ else if (mach >= MACH_V2 && N32_RT5 (insn) == REG_SP -+@@ -6981,7 +8476,7 @@ nds32_convert_32_to_16 (bfd *abfd, uint32_t insn, uint16_t *pinsn16, -+ -+ if (__builtin_popcount (imm15u) == 1) -+ { -+- /* BMSKI33 */ -++ /* BMSKI33 */ -+ int imm3u = __builtin_ctz (imm15u); -+ -+ insn16 = N16_BFMI333 (BMSKI33, N32_RT5 (insn), imm3u); -+@@ -6989,7 +8484,7 @@ nds32_convert_32_to_16 (bfd *abfd, uint32_t insn, uint16_t *pinsn16, -+ } -+ else if (imm15u != 0 && __builtin_popcount (imm15u + 1) == 1) -+ { -+- /* FEXTI33 */ -++ /* FEXTI33 */ -+ int imm3u = __builtin_ctz (imm15u + 1) - 1; -+ -+ insn16 = N16_BFMI333 (FEXTI33, N32_RT5 (insn), imm3u); -+@@ -7150,7 +8645,7 @@ nds32_convert_32_to_16 (bfd *abfd, uint32_t insn, uint16_t *pinsn16, -+ -+ if ((insn & N32_BIT (14)) == 0) -+ { -+- /* N32_BR1_BEQ */ -++ /* N32_BR1_BEQ */ -+ if (N32_IS_RT3 (insn) && N32_RA5 (insn) == REG_R5 -+ && N32_RT5 (insn) != REG_R5) -+ insn16 = N16_TYPE38 (BEQS38, N32_RT5 (insn), N32_IMM14S (insn)); -+@@ -7162,7 +8657,7 @@ nds32_convert_32_to_16 (bfd *abfd, uint32_t insn, uint16_t *pinsn16, -+ } -+ else -+ { -+- /* N32_BR1_BNE */ -++ /* N32_BR1_BNE */ -+ if (N32_IS_RT3 (insn) && N32_RA5 (insn) == REG_R5 -+ && N32_RT5 (insn) != REG_R5) -+ insn16 = N16_TYPE38 (BNES38, N32_RT5 (insn), N32_IMM14S (insn)); -+@@ -7183,8 +8678,7 @@ nds32_convert_32_to_16 (bfd *abfd, uint32_t insn, uint16_t *pinsn16, -+ insn16 = N16_TYPE38 (BEQZ38, N32_RT5 (insn), N32_IMM16S (insn)); -+ insn_type = NDS32_INSN_BEQZ38; -+ } -+- else if (N32_RT5 (insn) == REG_R15 -+- && IS_WITHIN_S (N32_IMM16S (insn), 8)) -++ else if (N32_RT5 (insn) == REG_R15 && IS_WITHIN_S (N32_IMM16S (insn), 8)) -+ { -+ insn16 = N16_TYPE8 (BEQZS8, N32_IMM16S (insn)); -+ insn_type = NDS32_INSN_BEQZS8; -+@@ -7197,16 +8691,15 @@ nds32_convert_32_to_16 (bfd *abfd, uint32_t insn, uint16_t *pinsn16, -+ insn16 = N16_TYPE38 (BNEZ38, N32_RT5 (insn), N32_IMM16S (insn)); -+ insn_type = NDS32_INSN_BNEZ38; -+ } -+- else if (N32_RT5 (insn) == REG_R15 -+- && IS_WITHIN_S (N32_IMM16S (insn), 8)) -++ else if (N32_RT5 (insn) == REG_R15 && IS_WITHIN_S (N32_IMM16S (insn), 8)) -+ { -+ insn16 = N16_TYPE8 (BNEZS8, N32_IMM16S (insn)); -+ insn_type = NDS32_INSN_BNEZS8; -+ } -+ break; -+ -+- case N32_BR2_IFCALL: -+- if (IS_WITHIN_U (N32_IMM16S (insn), 9)) -++ case N32_BR2_SOP0: -++ if (__GF (insn, 20, 5) == 0 && IS_WITHIN_U (N32_IMM16S (insn), 9)) -+ { -+ insn16 = N16_TYPE9 (IFCALL9, N32_IMM16S (insn)); -+ insn_type = NDS32_INSN_IFCALL9; -+@@ -7218,7 +8711,7 @@ nds32_convert_32_to_16 (bfd *abfd, uint32_t insn, uint16_t *pinsn16, -+ case N32_OP6_JI: -+ if ((insn & N32_BIT (24)) == 0) -+ { -+- /* N32_JI_J */ -++ /* N32_JI_J */ -+ if (IS_WITHIN_S (N32_IMM24S (insn), 8)) -+ { -+ insn16 = N16_TYPE8 (J8, N32_IMM24S (insn)); -+@@ -7236,19 +8729,19 @@ nds32_convert_32_to_16 (bfd *abfd, uint32_t insn, uint16_t *pinsn16, -+ case N32_JREG_JR: -+ if (N32_JREG_HINT (insn) == 0) -+ { -+- /* jr */ -++ /* jr */ -+ insn16 = N16_TYPE5 (JR5, N32_RB5 (insn)); -+ insn_type = NDS32_INSN_JR5; -+ } -+ else if (N32_JREG_HINT (insn) == 1) -+ { -+- /* ret */ -++ /* ret */ -+ insn16 = N16_TYPE5 (RET5, N32_RB5 (insn)); -+ insn_type = NDS32_INSN_RET5; -+ } -+ else if (N32_JREG_HINT (insn) == 3) -+ { -+- /* ifret = mov55 $sp, $sp */ -++ /* ifret = mov55 $sp, $sp */ -+ insn16 = N16_TYPE55 (MOV55, REG_SP, REG_SP); -+ insn_type = NDS32_INSN_IFRET; -+ } -+@@ -7347,184 +8840,162 @@ nds32_convert_16_to_32 (bfd *abfd, uint16_t insn16, uint32_t *pinsn) -+ -+ switch (__GF (insn16, 9, 6)) -+ { -+- case 0x4: /* add45 */ -+- insn = N32_ALU1 (ADD, N16_RT4 (insn16), N16_RT4 (insn16), -+- N16_RA5 (insn16)); -++ case 0x4: /* add45 */ -++ insn = N32_ALU1 (ADD, N16_RT4 (insn16), N16_RT4 (insn16), N16_RA5 (insn16)); -+ goto done; -+- case 0x5: /* sub45 */ -+- insn = N32_ALU1 (SUB, N16_RT4 (insn16), N16_RT4 (insn16), -+- N16_RA5 (insn16)); -++ case 0x5: /* sub45 */ -++ insn = N32_ALU1 (SUB, N16_RT4 (insn16), N16_RT4 (insn16), N16_RA5 (insn16)); -+ goto done; -+- case 0x6: /* addi45 */ -+- insn = N32_TYPE2 (ADDI, N16_RT4 (insn16), N16_RT4 (insn16), -+- N16_IMM5U (insn16)); -++ case 0x6: /* addi45 */ -++ insn = N32_TYPE2 (ADDI, N16_RT4 (insn16), N16_RT4 (insn16), N16_IMM5U (insn16)); -+ goto done; -+- case 0x7: /* subi45 */ -+- insn = N32_TYPE2 (ADDI, N16_RT4 (insn16), N16_RT4 (insn16), -+- -N16_IMM5U (insn16)); -++ case 0x7: /* subi45 */ -++ insn = N32_TYPE2 (ADDI, N16_RT4 (insn16), N16_RT4 (insn16), -N16_IMM5U (insn16)); -+ goto done; -+- case 0x8: /* srai45 */ -+- insn = N32_ALU1 (SRAI, N16_RT4 (insn16), N16_RT4 (insn16), -+- N16_IMM5U (insn16)); -++ case 0x8: /* srai45 */ -++ insn = N32_ALU1 (SRAI, N16_RT4 (insn16), N16_RT4 (insn16), N16_IMM5U (insn16)); -+ goto done; -+- case 0x9: /* srli45 */ -+- insn = N32_ALU1 (SRLI, N16_RT4 (insn16), N16_RT4 (insn16), -+- N16_IMM5U (insn16)); -++ case 0x9: /* srli45 */ -++ insn = N32_ALU1 (SRLI, N16_RT4 (insn16), N16_RT4 (insn16), N16_IMM5U (insn16)); -+ goto done; -+- case 0xa: /* slli333 */ -+- insn = N32_ALU1 (SLLI, N16_RT3 (insn16), N16_RA3 (insn16), -+- N16_IMM3U (insn16)); -++ -++ case 0xa: /* slli333 */ -++ insn = N32_ALU1 (SLLI, N16_RT3 (insn16), N16_RA3 (insn16), N16_IMM3U (insn16)); -+ goto done; -+- case 0xc: /* add333 */ -+- insn = N32_ALU1 (ADD, N16_RT3 (insn16), N16_RA3 (insn16), -+- N16_RB3 (insn16)); -++ case 0xc: /* add333 */ -++ insn = N32_ALU1 (ADD, N16_RT3 (insn16), N16_RA3 (insn16), N16_RB3 (insn16)); -+ goto done; -+- case 0xd: /* sub333 */ -+- insn = N32_ALU1 (SUB, N16_RT3 (insn16), N16_RA3 (insn16), -+- N16_RB3 (insn16)); -++ case 0xd: /* sub333 */ -++ insn = N32_ALU1 (SUB, N16_RT3 (insn16), N16_RA3 (insn16), N16_RB3 (insn16)); -+ goto done; -+- case 0xe: /* addi333 */ -+- insn = N32_TYPE2 (ADDI, N16_RT3 (insn16), N16_RA3 (insn16), -+- N16_IMM3U (insn16)); -++ case 0xe: /* addi333 */ -++ insn = N32_TYPE2 (ADDI, N16_RT3 (insn16), N16_RA3 (insn16), N16_IMM3U (insn16)); -+ goto done; -+- case 0xf: /* subi333 */ -+- insn = N32_TYPE2 (ADDI, N16_RT3 (insn16), N16_RA3 (insn16), -+- -N16_IMM3U (insn16)); -++ case 0xf: /* subi333 */ -++ insn = N32_TYPE2 (ADDI, N16_RT3 (insn16), N16_RA3 (insn16), -N16_IMM3U (insn16)); -+ goto done; -+- case 0x10: /* lwi333 */ -+- insn = N32_TYPE2 (LWI, N16_RT3 (insn16), N16_RA3 (insn16), -+- N16_IMM3U (insn16)); -++ -++ case 0x10: /* lwi333 */ -++ insn = N32_TYPE2 (LWI, N16_RT3 (insn16), N16_RA3 (insn16), N16_IMM3U (insn16)); -+ goto done; -+- case 0x12: /* lhi333 */ -+- insn = N32_TYPE2 (LHI, N16_RT3 (insn16), N16_RA3 (insn16), -+- N16_IMM3U (insn16)); -++ case 0x12: /* lhi333 */ -++ insn = N32_TYPE2 (LHI, N16_RT3 (insn16), N16_RA3 (insn16), N16_IMM3U (insn16)); -+ goto done; -+- case 0x13: /* lbi333 */ -+- insn = N32_TYPE2 (LBI, N16_RT3 (insn16), N16_RA3 (insn16), -+- N16_IMM3U (insn16)); -++ case 0x13: /* lbi333 */ -++ insn = N32_TYPE2 (LBI, N16_RT3 (insn16), N16_RA3 (insn16), N16_IMM3U (insn16)); -+ goto done; -+- case 0x11: /* lwi333.bi */ -+- insn = N32_TYPE2 (LWI_BI, N16_RT3 (insn16), N16_RA3 (insn16), -+- N16_IMM3U (insn16)); -++ case 0x11: /* lwi333.bi */ -++ insn = N32_TYPE2 (LWI_BI, N16_RT3 (insn16), N16_RA3 (insn16), N16_IMM3U (insn16)); -+ goto done; -+- case 0x14: /* swi333 */ -+- insn = N32_TYPE2 (SWI, N16_RT3 (insn16), N16_RA3 (insn16), -+- N16_IMM3U (insn16)); -++ case 0x14: /* swi333 */ -++ insn = N32_TYPE2 (SWI, N16_RT3 (insn16), N16_RA3 (insn16), N16_IMM3U (insn16)); -+ goto done; -+- case 0x16: /* shi333 */ -+- insn = N32_TYPE2 (SHI, N16_RT3 (insn16), N16_RA3 (insn16), -+- N16_IMM3U (insn16)); -++ case 0x16: /* shi333 */ -++ insn = N32_TYPE2 (SHI, N16_RT3 (insn16), N16_RA3 (insn16), N16_IMM3U (insn16)); -+ goto done; -+- case 0x17: /* sbi333 */ -+- insn = N32_TYPE2 (SBI, N16_RT3 (insn16), N16_RA3 (insn16), -+- N16_IMM3U (insn16)); -++ case 0x17: /* sbi333 */ -++ insn = N32_TYPE2 (SBI, N16_RT3 (insn16), N16_RA3 (insn16), N16_IMM3U (insn16)); -+ goto done; -+- case 0x15: /* swi333.bi */ -+- insn = N32_TYPE2 (SWI_BI, N16_RT3 (insn16), N16_RA3 (insn16), -+- N16_IMM3U (insn16)); -++ case 0x15: /* swi333.bi */ -++ insn = N32_TYPE2 (SWI_BI, N16_RT3 (insn16), N16_RA3 (insn16), N16_IMM3U (insn16)); -+ goto done; -+- case 0x18: /* addri36.sp */ -+- insn = N32_TYPE2 (ADDI, N16_RT3 (insn16), REG_SP, -+- N16_IMM6U (insn16) << 2); -++ -++ case 0x18: /* addri36.sp */ -++ insn = N32_TYPE2 (ADDI, N16_RT3 (insn16), REG_SP, N16_IMM6U (insn16) << 2); -+ goto done; -+- case 0x19: /* lwi45.fe */ -+- insn = N32_TYPE2 (LWI, N16_RT4 (insn16), REG_R8, -+- (N16_IMM5U (insn16) - 32)); -++ -++ case 0x19: /* lwi45.fe */ -++ insn = N32_TYPE2 (LWI, N16_RT4 (insn16), REG_R8, (N16_IMM5U (insn16) - 32)); -+ goto done; -+- case 0x1a: /* lwi450 */ -++ case 0x1a: /* lwi450 */ -+ insn = N32_TYPE2 (LWI, N16_RT4 (insn16), N16_RA5 (insn16), 0); -+ goto done; -+- case 0x1b: /* swi450 */ -++ case 0x1b: /* swi450 */ -+ insn = N32_TYPE2 (SWI, N16_RT4 (insn16), N16_RA5 (insn16), 0); -+ goto done; -+ -+- /* These are r15 implied instructions. */ -+- case 0x30: /* slts45 */ -++ /* These are r15 implied instructions. */ -++ case 0x30: /* slts45 */ -+ insn = N32_ALU1 (SLTS, REG_TA, N16_RT4 (insn16), N16_RA5 (insn16)); -+ goto done; -+- case 0x31: /* slt45 */ -++ case 0x31: /* slt45 */ -+ insn = N32_ALU1 (SLT, REG_TA, N16_RT4 (insn16), N16_RA5 (insn16)); -+ goto done; -+- case 0x32: /* sltsi45 */ -++ case 0x32: /* sltsi45 */ -+ insn = N32_TYPE2 (SLTSI, REG_TA, N16_RT4 (insn16), N16_IMM5U (insn16)); -+ goto done; -+- case 0x33: /* slti45 */ -++ case 0x33: /* slti45 */ -+ insn = N32_TYPE2 (SLTI, REG_TA, N16_RT4 (insn16), N16_IMM5U (insn16)); -+ goto done; -+- case 0x34: /* beqzs8, bnezs8 */ -++ case 0x34: /* beqzs8, bnezs8 */ -+ if (insn16 & N32_BIT (8)) -+ insn = N32_BR2 (BNEZ, REG_TA, N16_IMM8S (insn16)); -+ else -+ insn = N32_BR2 (BEQZ, REG_TA, N16_IMM8S (insn16)); -+ goto done; -+ -+- case 0x35: /* break16, ex9.it */ -++ case 0x35: /* break16, ex9.it */ -+ /* Only consider range of v3 break16. */ -+ insn = N32_TYPE0 (MISC, (N16_IMM5U (insn16) << 5) | N32_MISC_BREAK); -+ goto done; -+ -+- case 0x3c: /* ifcall9 */ -+- insn = N32_BR2 (IFCALL, 0, N16_IMM9U (insn16)); -++ case 0x3c: /* ifcall9 */ -++ insn = N32_BR2 (SOP0, 0, N16_IMM9U (insn16)); -+ goto done; -+- case 0x3d: /* movpi45 */ -++ case 0x3d: /* movpi45 */ -+ insn = N32_TYPE1 (MOVI, N16_RT4 (insn16), N16_IMM5U (insn16) + 16); -+ goto done; -+ -+- case 0x3f: /* MISC33 */ -++ case 0x3f: /* MISC33 */ -+ switch (insn16 & 0x7) -+ { -+- case 2: /* neg33 */ -++ case 2: /* neg33 */ -+ insn = N32_TYPE2 (SUBRI, N16_RT3 (insn16), N16_RA3 (insn16), 0); -+ break; -+- case 3: /* not33 */ -+- insn = N32_ALU1 (NOR, N16_RT3 (insn16), N16_RA3 (insn16), -+- N16_RA3 (insn16)); -++ case 3: /* not33 */ -++ insn = N32_ALU1 (NOR, N16_RT3 (insn16), N16_RA3 (insn16), N16_RA3 (insn16)); -+ break; -+- case 4: /* mul33 */ -+- insn = N32_ALU2 (MUL, N16_RT3 (insn16), N16_RT3 (insn16), -+- N16_RA3 (insn16)); -++ case 4: /* mul33 */ -++ insn = N32_ALU2 (MUL, N16_RT3 (insn16), N16_RT3 (insn16), N16_RA3 (insn16)); -+ break; -+- case 5: /* xor33 */ -+- insn = N32_ALU1 (XOR, N16_RT3 (insn16), N16_RT3 (insn16), -+- N16_RA3 (insn16)); -++ case 5: /* xor33 */ -++ insn = N32_ALU1 (XOR, N16_RT3 (insn16), N16_RT3 (insn16), N16_RA3 (insn16)); -+ break; -+- case 6: /* and33 */ -+- insn = N32_ALU1 (AND, N16_RT3 (insn16), N16_RT3 (insn16), -+- N16_RA3 (insn16)); -++ case 6: /* and33 */ -++ insn = N32_ALU1 (AND, N16_RT3 (insn16), N16_RT3 (insn16), N16_RA3 (insn16)); -+ break; -+- case 7: /* or33 */ -+- insn = N32_ALU1 (OR, N16_RT3 (insn16), N16_RT3 (insn16), -+- N16_RA3 (insn16)); -++ case 7: /* or33 */ -++ insn = N32_ALU1 (OR, N16_RT3 (insn16), N16_RT3 (insn16), N16_RA3 (insn16)); -+ break; -+ } -+ goto done; -+ -+- case 0xb: -++ case 0xb: /* ... */ -+ switch (insn16 & 0x7) -+ { -+- case 0: /* zeb33 */ -++ case 0: /* zeb33 */ -+ insn = N32_TYPE2 (ANDI, N16_RT3 (insn16), N16_RA3 (insn16), 0xff); -+ break; -+- case 1: /* zeh33 */ -++ case 1: /* zeh33 */ -+ insn = N32_ALU1 (ZEH, N16_RT3 (insn16), N16_RA3 (insn16), 0); -+ break; -+- case 2: /* seb33 */ -++ case 2: /* seb33 */ -+ insn = N32_ALU1 (SEB, N16_RT3 (insn16), N16_RA3 (insn16), 0); -+ break; -+- case 3: /* seh33 */ -++ case 3: /* seh33 */ -+ insn = N32_ALU1 (SEH, N16_RT3 (insn16), N16_RA3 (insn16), 0); -+ break; -+- case 4: /* xlsb33 */ -++ case 4: /* xlsb33 */ -+ insn = N32_TYPE2 (ANDI, N16_RT3 (insn16), N16_RA3 (insn16), 1); -+ break; -+- case 5: /* x11b33 */ -++ case 5: /* x11b33 */ -+ insn = N32_TYPE2 (ANDI, N16_RT3 (insn16), N16_RA3 (insn16), 0x7ff); -+ break; -+- case 6: /* bmski33 */ -++ case 6: /* bmski33 */ -+ insn = N32_TYPE2 (ANDI, N16_RT3 (insn16), N16_RT3 (insn16), -+ 1 << __GF (insn16, 3, 3)); -+ break; -+- case 7: /* fexti33 */ -++ case 7: /* fexti33 */ -+ insn = N32_TYPE2 (ANDI, N16_RT3 (insn16), N16_RT3 (insn16), -+ (1 << (__GF (insn16, 3, 3) + 1)) - 1); -+ break; -+@@ -7534,70 +9005,70 @@ nds32_convert_16_to_32 (bfd *abfd, uint16_t insn16, uint32_t *pinsn) -+ -+ switch (__GF (insn16, 10, 5)) -+ { -+- case 0x0: /* mov55 or ifret16 */ -++ case 0x0: /* mov55 or ifret16 */ -+ if (mach >= MACH_V3 && N16_RT5 (insn16) == REG_SP -+ && N16_RT5 (insn16) == N16_RA5 (insn16)) -+- insn = N32_JREG (JR, 0, 0, 0, 3); -++ insn = N32_JREG (JR, 0, 0, 0, 3); -+ else -+- insn = N32_TYPE2 (ADDI, N16_RT5 (insn16), N16_RA5 (insn16), 0); -++ insn = N32_TYPE2 (ADDI, N16_RT5 (insn16), N16_RA5 (insn16), 0); -+ goto done; -+- case 0x1: /* movi55 */ -++ case 0x1: /* movi55 */ -+ insn = N32_TYPE1 (MOVI, N16_RT5 (insn16), N16_IMM5S (insn16)); -+ goto done; -+- case 0x1b: /* addi10s (V2) */ -++ case 0x1b: /* addi10s (V2) */ -+ insn = N32_TYPE2 (ADDI, REG_SP, REG_SP, N16_IMM10S (insn16)); -+ goto done; -+ } -+ -+ switch (__GF (insn16, 11, 4)) -+ { -+- case 0x7: /* lwi37.fp/swi37.fp */ -+- if (insn16 & N32_BIT (7)) /* swi37.fp */ -++ case 0x7: /* lwi37.fp/swi37.fp */ -++ if (insn16 & N32_BIT (7)) /* swi37.fp */ -+ insn = N32_TYPE2 (SWI, N16_RT38 (insn16), REG_FP, N16_IMM7U (insn16)); -+- else /* lwi37.fp */ -++ else /* lwi37.fp */ -+ insn = N32_TYPE2 (LWI, N16_RT38 (insn16), REG_FP, N16_IMM7U (insn16)); -+ goto done; -+- case 0x8: /* beqz38 */ -++ case 0x8: /* beqz38 */ -+ insn = N32_BR2 (BEQZ, N16_RT38 (insn16), N16_IMM8S (insn16)); -+ goto done; -+- case 0x9: /* bnez38 */ -++ case 0x9: /* bnez38 */ -+ insn = N32_BR2 (BNEZ, N16_RT38 (insn16), N16_IMM8S (insn16)); -+ goto done; -+- case 0xa: /* beqs38/j8, implied r5 */ -++ case 0xa: /* beqs38/j8, implied r5 */ -+ if (N16_RT38 (insn16) == 5) -+ insn = N32_JI (J, N16_IMM8S (insn16)); -+ else -+ insn = N32_BR1 (BEQ, N16_RT38 (insn16), REG_R5, N16_IMM8S (insn16)); -+ goto done; -+- case 0xb: /* bnes38 and others */ -++ case 0xb: /* bnes38 and others */ -+ if (N16_RT38 (insn16) == 5) -+ { -+ switch (__GF (insn16, 5, 3)) -+ { -+- case 0: /* jr5 */ -++ case 0: /* jr5 */ -+ insn = N32_JREG (JR, 0, N16_RA5 (insn16), 0, 0); -+ break; -+- case 4: /* ret5 */ -++ case 4: /* ret5 */ -+ insn = N32_JREG (JR, 0, N16_RA5 (insn16), 0, 1); -+ break; -+- case 1: /* jral5 */ -++ case 1: /* jral5 */ -+ insn = N32_JREG (JRAL, REG_LP, N16_RA5 (insn16), 0, 0); -+ break; -+- case 2: /* ex9.it imm5 */ -++ case 2: /* ex9.it imm5 */ -+ /* ex9.it had no 32-bit variantl. */ -+ break; -+- case 5: /* add5.pc */ -++ case 5: /* add5.pc */ -+ /* add5.pc had no 32-bit variantl. */ -+ break; -+ } -+ } -+- else /* bnes38 */ -++ else /* bnes38 */ -+ insn = N32_BR1 (BNE, N16_RT38 (insn16), REG_R5, N16_IMM8S (insn16)); -+ goto done; -+- case 0xe: /* lwi37/swi37 */ -+- if (insn16 & (1 << 7)) /* swi37.sp */ -++ case 0xe: /* lwi37/swi37 */ -++ if (insn16 & (1 << 7)) /* swi37.sp */ -+ insn = N32_TYPE2 (SWI, N16_RT38 (insn16), REG_SP, N16_IMM7U (insn16)); -+- else /* lwi37.sp */ -++ else /* lwi37.sp */ -+ insn = N32_TYPE2 (LWI, N16_RT38 (insn16), REG_SP, N16_IMM7U (insn16)); -+ goto done; -+ } -+@@ -7650,19 +9121,19 @@ turn_insn_to_sda_access (uint32_t insn, bfd_signed_vma type, uint32_t *pinsn) -+ switch (N32_OP6 (insn)) -+ { -+ case N32_OP6_LBI: -+- /* lbi.gp */ -++ /* lbi.gp */ -+ oinsn = N32_TYPE1 (LBGP, N32_RT5 (insn), 0); -+ break; -+ case N32_OP6_LBSI: -+- /* lbsi.gp */ -++ /* lbsi.gp */ -+ oinsn = N32_TYPE1 (LBGP, N32_RT5 (insn), N32_BIT (19)); -+ break; -+ case N32_OP6_SBI: -+- /* sbi.gp */ -++ /* sbi.gp */ -+ oinsn = N32_TYPE1 (SBGP, N32_RT5 (insn), 0); -+ break; -+ case N32_OP6_ORI: -+- /* addi.gp */ -++ /* addi.gp */ -+ oinsn = N32_TYPE1 (SBGP, N32_RT5 (insn), N32_BIT (19)); -+ break; -+ } -+@@ -7672,15 +9143,15 @@ turn_insn_to_sda_access (uint32_t insn, bfd_signed_vma type, uint32_t *pinsn) -+ switch (N32_OP6 (insn)) -+ { -+ case N32_OP6_LHI: -+- /* lhi.gp */ -++ /* lhi.gp */ -+ oinsn = N32_TYPE1 (HWGP, N32_RT5 (insn), 0); -+ break; -+ case N32_OP6_LHSI: -+- /* lhsi.gp */ -++ /* lhsi.gp */ -+ oinsn = N32_TYPE1 (HWGP, N32_RT5 (insn), N32_BIT (18)); -+ break; -+ case N32_OP6_SHI: -+- /* shi.gp */ -++ /* shi.gp */ -+ oinsn = N32_TYPE1 (HWGP, N32_RT5 (insn), N32_BIT (19)); -+ break; -+ } -+@@ -7690,11 +9161,11 @@ turn_insn_to_sda_access (uint32_t insn, bfd_signed_vma type, uint32_t *pinsn) -+ switch (N32_OP6 (insn)) -+ { -+ case N32_OP6_LWI: -+- /* lwi.gp */ -++ /* lwi.gp */ -+ oinsn = N32_TYPE1 (HWGP, N32_RT5 (insn), __MF (6, 17, 3)); -+ break; -+ case N32_OP6_SWI: -+- /* swi.gp */ -++ /* swi.gp */ -+ oinsn = N32_TYPE1 (HWGP, N32_RT5 (insn), __MF (7, 17, 3)); -+ break; -+ } -+@@ -7835,7 +9306,7 @@ calculate_got_memory_address (bfd *abfd, struct bfd_link_info *link_info, -+ bfd_vma *local_got_offsets; -+ /* Get the value of the symbol referred to by the reloc. */ -+ struct elf_link_hash_entry *h; -+- struct elf_nds32_link_hash_table *htab = nds32_elf_hash_table (link_info); -++ struct elf_link_hash_table *ehtab = elf_hash_table (link_info); -+ -+ /* An external symbol. */ -+ symndx = ELF32_R_SYM (irel->r_info) - symtab_hdr->sh_info; -+@@ -7847,18 +9318,13 @@ calculate_got_memory_address (bfd *abfd, struct bfd_link_info *link_info, -+ if (symndx >= 0) -+ { -+ BFD_ASSERT (h != NULL); -+- return (htab->root.sgot->output_section->vma -+- + htab->root.sgot->output_offset -+- + h->got.offset); -+- } -+- else -+- { -+- local_got_offsets = elf_local_got_offsets (abfd); -+- BFD_ASSERT (local_got_offsets != NULL); -+- return (htab->root.sgot->output_section->vma -+- + htab->root.sgot->output_offset -+- + local_got_offsets[ELF32_R_SYM (irel->r_info)]); -++ return ehtab->sgot->output_section->vma + ehtab->sgot->output_offset -++ + h->got.offset; -+ } -++ local_got_offsets = elf_local_got_offsets (abfd); -++ BFD_ASSERT (local_got_offsets != NULL); -++ return ehtab->sgot->output_section->vma + ehtab->sgot->output_offset -++ + local_got_offsets[ELF32_R_SYM (irel->r_info)]; -+ -+ /* The _GLOBAL_OFFSET_TABLE_ may be undefweak(or should be?). */ -+ /* The check of h->root.type is passed. */ -+@@ -7899,7 +9365,6 @@ is_convert_32_to_16 (bfd *abfd, asection *sec, -+ bfd_vma mem_addr; -+ uint32_t insn = 0; -+ Elf_Internal_Rela *pc_rel; -+- int pic_ext_target = 0; -+ Elf_Internal_Shdr *symtab_hdr; -+ Elf_Internal_Sym *isymbuf = NULL; -+ int convert_type; -+@@ -7938,8 +9403,7 @@ is_convert_32_to_16 (bfd *abfd, asection *sec, -+ || ELF32_R_TYPE (pc_rel->r_info) == R_NDS32_25_PCREL_RELA -+ || ELF32_R_TYPE (pc_rel->r_info) == R_NDS32_25_PLTREL) -+ { -+- off = calculate_offset (abfd, sec, pc_rel, isymbuf, symtab_hdr, -+- &pic_ext_target); -++ off = calculate_offset (abfd, sec, pc_rel, isymbuf, symtab_hdr); -+ if (off >= ACCURATE_8BIT_S1 || off < -ACCURATE_8BIT_S1 -+ || off == 0) -+ return FALSE; -+@@ -7948,10 +9412,8 @@ is_convert_32_to_16 (bfd *abfd, asection *sec, -+ else if (ELF32_R_TYPE (pc_rel->r_info) == R_NDS32_20_RELA) -+ { -+ /* movi => movi55 */ -+- mem_addr = calculate_memory_address (abfd, pc_rel, isymbuf, -+- symtab_hdr); -+- /* mem_addr is unsigned, but the value should -+- be between [-16, 15]. */ -++ mem_addr = calculate_memory_address (abfd, pc_rel, isymbuf, symtab_hdr); -++ /* mem_addr is unsigned, but the value should be between [-16, 15]. */ -+ if ((mem_addr + 0x10) >> 5) -+ return FALSE; -+ break; -+@@ -7980,14 +9442,12 @@ is_convert_32_to_16 (bfd *abfd, asection *sec, -+ || ((ELF32_R_TYPE (pc_rel->r_info) > R_NDS32_LOADSTORE) -+ && (ELF32_R_TYPE (pc_rel->r_info) < R_NDS32_DWARF2_OP1_RELA))) -+ { -+- /* Prevent unresolved addi instruction translate -+- to addi45 or addi333. */ -++ /* Prevent unresolved addi instruction translate to addi45 or addi333. */ -+ return FALSE; -+ } -+ else if ((ELF32_R_TYPE (pc_rel->r_info) == R_NDS32_17IFC_PCREL_RELA)) -+ { -+- off = calculate_offset (abfd, sec, pc_rel, isymbuf, symtab_hdr, -+- &pic_ext_target); -++ off = calculate_offset (abfd, sec, pc_rel, isymbuf, symtab_hdr); -+ if (off >= ACCURATE_U9BIT_S1 || off <= 0) -+ return FALSE; -+ break; -+@@ -8085,7 +9545,7 @@ static Elf_Internal_Rela * -+ find_relocs_at_address_addr (Elf_Internal_Rela *reloc, -+ Elf_Internal_Rela *relocs, -+ Elf_Internal_Rela *irelend, -+- enum elf_nds32_reloc_type reloc_type, -++ unsigned char reloc_type, -+ bfd_vma offset_p) -+ { -+ Elf_Internal_Rela *rel_t = NULL; -+@@ -8281,8 +9741,9 @@ insert_nds32_elf_blank (nds32_elf_blank_t **blank_p, bfd_vma addr, bfd_vma len) -+ -+ if (addr < blank_t->offset + blank_t->size) -+ { -+- if (addr > blank_t->offset + blank_t->size) -+- blank_t->size = addr - blank_t->offset; -++ /* Extend the origin blank. */ -++ if (addr + len > blank_t->offset + blank_t->size) -++ blank_t->size = addr + len - blank_t->offset; -+ } -+ else -+ { -+@@ -8414,7 +9875,7 @@ nds32_elf_relax_delete_blanks (bfd *abfd, asection *sec, -+ -+ /* Relocations MUST be kept in memory, because relaxation adjust them. */ -+ internal_relocs = _bfd_elf_link_read_relocs (abfd, sect, NULL, NULL, -+- TRUE /* keep_memory */); -++ TRUE /* keep_memory */); -+ irelend = internal_relocs + sect->reloc_count; -+ -+ blank_t = blank_head; -+@@ -8436,7 +9897,7 @@ nds32_elf_relax_delete_blanks (bfd *abfd, asection *sec, -+ unsigned long val = 0; -+ unsigned long mask; -+ long before, between; -+- long offset = 0; -++ long offset; -+ -+ switch (ELF32_R_TYPE (irel->r_info)) -+ { -+@@ -8468,28 +9929,23 @@ nds32_elf_relax_delete_blanks (bfd *abfd, asection *sec, -+ -- before ---| ***************** -+ --------------------- between ---| -+ -+- We only care how much data are relax between DIFF, -+- marked as ***. */ -++ We only care how much data are relax between DIFF, marked as ***. */ -+ -+ before = get_nds32_elf_blank_total (&blank_t, irel->r_addend, 0); -+- between = get_nds32_elf_blank_total (&blank_t, -+- irel->r_addend + offset, 0); -++ between = get_nds32_elf_blank_total (&blank_t, irel->r_addend + offset, 0); -+ if (between == before) -+ goto done_adjust_diff; -+ -+ switch (ELF32_R_TYPE (irel->r_info)) -+ { -+ case R_NDS32_DIFF8: -+- bfd_put_8 (abfd, offset - (between - before), -+- contents + irel->r_offset); -++ bfd_put_8 (abfd, offset - (between - before), contents + irel->r_offset); -+ break; -+ case R_NDS32_DIFF16: -+- bfd_put_16 (abfd, offset - (between - before), -+- contents + irel->r_offset); -++ bfd_put_16 (abfd, offset - (between - before), contents + irel->r_offset); -+ break; -+ case R_NDS32_DIFF32: -+- bfd_put_32 (abfd, offset - (between - before), -+- contents + irel->r_offset); -++ bfd_put_32 (abfd, offset - (between - before), contents + irel->r_offset); -+ break; -+ } -+ } -+@@ -8501,12 +9957,10 @@ nds32_elf_relax_delete_blanks (bfd *abfd, asection *sec, -+ unsigned long before, between; -+ bfd_byte *endp, *p; -+ -+- val = _bfd_read_unsigned_leb128 (abfd, contents + irel->r_offset, -+- &len); -++ val = _bfd_read_unsigned_leb128 (abfd, contents + irel->r_offset, &len); -+ -+ before = get_nds32_elf_blank_total (&blank_t, irel->r_addend, 0); -+- between = get_nds32_elf_blank_total (&blank_t, -+- irel->r_addend + val, 0); -++ between = get_nds32_elf_blank_total (&blank_t, irel->r_addend + val, 0); -+ if (between == before) -+ goto done_adjust_diff; -+ -+@@ -8523,16 +9977,14 @@ done_adjust_diff: -+ if (sec == sect) -+ { -+ raddr = irel->r_offset; -+- irel->r_offset -= get_nds32_elf_blank_total (&blank_t2, -+- irel->r_offset, 1); -++ irel->r_offset -= get_nds32_elf_blank_total (&blank_t2, irel->r_offset, 1); -+ -+ if (ELF32_R_TYPE (irel->r_info) == R_NDS32_NONE) -+ continue; -+ if (blank_t2 && blank_t2->next -+- && (blank_t2->offset > raddr -+- || blank_t2->next->offset <= raddr)) -+- _bfd_error_handler -+- (_("%B: Error: search_nds32_elf_blank reports wrong node\n"), abfd); -++ && (blank_t2->offset > raddr || blank_t2->next->offset <= raddr)) -++ _bfd_error_handler (_("%B: %s\n"), abfd, -++ "Error: search_nds32_elf_blank reports wrong node"); -+ -+ /* Mark reloc in deleted portion as NONE. -+ For some relocs like R_NDS32_LABEL that doesn't modify the -+@@ -8584,11 +10036,9 @@ done_adjust_diff: -+ isym->st_value -= ahead; -+ -+ /* Adjust function size. */ -+- if (ELF32_ST_TYPE (isym->st_info) == STT_FUNC -+- && isym->st_size > 0) -+- isym->st_size -= -+- get_nds32_elf_blank_total -+- (&blank_t, orig_addr + isym->st_size, 0) - ahead; -++ if (ELF32_ST_TYPE (isym->st_info) == STT_FUNC && isym->st_size > 0) -++ isym->st_size -= get_nds32_elf_blank_total -++ (&blank_t, orig_addr + isym->st_size, 0) - ahead; -+ } -+ } -+ } -+@@ -8617,9 +10067,8 @@ done_adjust_diff: -+ -+ /* Adjust function size. */ -+ if (sym_hash->type == STT_FUNC) -+- sym_hash->size -= -+- get_nds32_elf_blank_total -+- (&blank_t, orig_addr + sym_hash->size, 0) - ahead; -++ sym_hash->size -= get_nds32_elf_blank_total -++ (&blank_t, orig_addr + sym_hash->size, 0) - ahead; -+ -+ } -+ } -+@@ -8743,7 +10192,7 @@ relax_range_measurement (bfd *abfd) -+ bfd_vma align; -+ static int decide_relax_range = 0; -+ int i; -+- int range_number = sizeof (sdata_init_range) / sizeof (sdata_init_range[0]); -++ int range_number = ARRAY_SIZE (sdata_init_range); -+ -+ if (decide_relax_range) -+ return; -+@@ -8789,11 +10238,7 @@ relax_range_measurement (bfd *abfd) -+ #define IS_OPTIMIZE(addend) ((addend) & 0x40000000) -+ #define IS_16BIT_ON(addend) ((addend) & 0x20000000) -+ -+-static const char * unrecognized_reloc_msg = -+- /* xgettext:c-format */ -+- N_("%B: warning: %s points to unrecognized reloc at %#Lx"); -+- -+-/* Relax LONGCALL1 relocation for nds32_elf_relax_section. */ -++/* Relax LONGCALL1 relocation for nds32_elf_relax_section.*/ -+ -+ static bfd_boolean -+ nds32_elf_relax_longcall1 (bfd *abfd, asection *sec, Elf_Internal_Rela *irel, -+@@ -8803,19 +10248,19 @@ nds32_elf_relax_longcall1 (bfd *abfd, asection *sec, Elf_Internal_Rela *irel, -+ { -+ /* There are 3 variations for LONGCALL1 -+ case 4-4-2; 16-bit on, optimize off or optimize for space -+- sethi ta, hi20(symbol) ; LONGCALL1/HI20 -++ sethi ta, hi20(symbol) ; LONGCALL1/HI20 -+ ori ta, ta, lo12(symbol) ; LO12S0 -+- jral5 ta ; -++ jral5 ta ; -+ -+ case 4-4-4; 16-bit off, optimize don't care -+- sethi ta, hi20(symbol) ; LONGCALL1/HI20 -++ sethi ta, hi20(symbol) ; LONGCALL1/HI20 -+ ori ta, ta, lo12(symbol) ; LO12S0 -+- jral ta ; -++ jral ta ; -+ -+ case 4-4-4; 16-bit on, optimize for speed -+- sethi ta, hi20(symbol) ; LONGCALL1/HI20 -++ sethi ta, hi20(symbol) ; LONGCALL1/HI20 -+ ori ta, ta, lo12(symbol) ; LO12S0 -+- jral ta ; -++ jral ta ; -+ Check code for -mlong-calls output. */ -+ -+ /* Get the reloc for the address from which the register is -+@@ -8826,7 +10271,6 @@ nds32_elf_relax_longcall1 (bfd *abfd, asection *sec, Elf_Internal_Rela *irel, -+ int seq_len; /* Original length of instruction sequence. */ -+ uint32_t insn; -+ Elf_Internal_Rela *hi_irelfn, *lo_irelfn, *irelend; -+- int pic_ext_target = 0; -+ bfd_signed_vma foff; -+ uint16_t insn16; -+ -+@@ -8843,21 +10287,21 @@ nds32_elf_relax_longcall1 (bfd *abfd, asection *sec, Elf_Internal_Rela *irel, -+ -+ if (hi_irelfn == irelend || lo_irelfn == irelend) -+ { -+- _bfd_error_handler (unrecognized_reloc_msg, abfd, "R_NDS32_LONGCALL1", -+- irel->r_offset); -++ _bfd_error_handler -++ ("%B: warning: R_NDS32_LONGCALL1 points to unrecognized " -++ "reloc at 0x%lx.", abfd, (long) irel->r_offset); -+ return FALSE; -+ } -+ -+ /* Get the value of the symbol referred to by the reloc. */ -+- foff = calculate_offset (abfd, sec, hi_irelfn, isymbuf, symtab_hdr, -+- &pic_ext_target); -++ foff = calculate_offset (abfd, sec, hi_irelfn, isymbuf, symtab_hdr); -+ -+ /* This condition only happened when symbol is undefined. */ -+- if (pic_ext_target || foff == 0 || foff < -CONSERVATIVE_24BIT_S1 -++ if (foff == 0 || foff < -CONSERVATIVE_24BIT_S1 -+ || foff >= CONSERVATIVE_24BIT_S1) -+ return FALSE; -+ -+- /* Relax to: jal symbol; 25_PCREL */ -++ /* Relax to: jal symbol; 25_PCREL */ -+ /* For simplicity of coding, we are going to modify the section -+ contents, the section relocs, and the BFD symbol table. We -+ must tell the rest of the code not to free up this -+@@ -8894,7 +10338,7 @@ nds32_elf_relax_longcall1 (bfd *abfd, asection *sec, Elf_Internal_Rela *irel, -+ } -+ -+ #define CONVERT_CONDITION_CALL(insn) (((insn) & 0xffff0000) ^ 0x90000) -+-/* Relax LONGCALL2 relocation for nds32_elf_relax_section. */ -++/* Relax LONGCALL2 relocation for nds32_elf_relax_section.*/ -+ -+ static bfd_boolean -+ nds32_elf_relax_longcall2 (bfd *abfd, asection *sec, Elf_Internal_Rela *irel, -+@@ -8904,7 +10348,7 @@ nds32_elf_relax_longcall2 (bfd *abfd, asection *sec, Elf_Internal_Rela *irel, -+ { -+ /* bltz rt, .L1 ; LONGCALL2 -+ jal symbol ; 25_PCREL -+- .L1: */ -++ .L1: */ -+ -+ /* Get the reloc for the address from which the register is -+ being loaded. This reloc will tell us which function is -+@@ -8913,7 +10357,6 @@ nds32_elf_relax_longcall2 (bfd *abfd, asection *sec, Elf_Internal_Rela *irel, -+ bfd_vma laddr; -+ uint32_t insn; -+ Elf_Internal_Rela *i1_irelfn, *cond_irelfn, *irelend; -+- int pic_ext_target = 0; -+ bfd_signed_vma foff; -+ -+ irelend = internal_relocs + sec->reloc_count; -+@@ -8924,23 +10367,23 @@ nds32_elf_relax_longcall2 (bfd *abfd, asection *sec, Elf_Internal_Rela *irel, -+ -+ if (i1_irelfn == irelend) -+ { -+- _bfd_error_handler (unrecognized_reloc_msg, abfd, "R_NDS32_LONGCALL2", -+- irel->r_offset); -++ _bfd_error_handler -++ ("%B: warning: R_NDS32_LONGCALL2 points to unrecognized " -++ "reloc at 0x%lx.", abfd, (long) irel->r_offset); -+ return FALSE; -+ } -+ -+ insn = bfd_getb32 (contents + laddr); -+ -+ /* Get the value of the symbol referred to by the reloc. */ -+- foff = calculate_offset (abfd, sec, i1_irelfn, isymbuf, symtab_hdr, -+- &pic_ext_target); -++ foff = calculate_offset (abfd, sec, i1_irelfn, isymbuf, symtab_hdr); -+ -+ if (foff == 0 || foff < -CONSERVATIVE_16BIT_S1 -+ || foff >= CONSERVATIVE_16BIT_S1) -+ return FALSE; -+ -+ /* Relax to bgezal rt, label ; 17_PCREL -+- or bltzal rt, label ; 17_PCREL */ -++ or bltzal rt, label ; 17_PCREL */ -+ -+ /* Convert to complimentary conditional call. */ -+ insn = CONVERT_CONDITION_CALL (insn); -+@@ -8974,7 +10417,7 @@ nds32_elf_relax_longcall2 (bfd *abfd, asection *sec, Elf_Internal_Rela *irel, -+ return TRUE; -+ } -+ -+-/* Relax LONGCALL3 relocation for nds32_elf_relax_section. */ -++/* Relax LONGCALL3 relocation for nds32_elf_relax_section.*/ -+ -+ static bfd_boolean -+ nds32_elf_relax_longcall3 (bfd *abfd, asection *sec, Elf_Internal_Rela *irel, -+@@ -8984,25 +10427,25 @@ nds32_elf_relax_longcall3 (bfd *abfd, asection *sec, Elf_Internal_Rela *irel, -+ { -+ /* There are 3 variations for LONGCALL3 -+ case 4-4-4-2; 16-bit on, optimize off or optimize for space -+- bltz rt, $1 ; LONGCALL3 -+- sethi ta, hi20(symbol) ; HI20 -++ bltz rt, $1 ; LONGCALL3 -++ sethi ta, hi20(symbol) ; HI20 -+ ori ta, ta, lo12(symbol) ; LO12S0 -+- jral5 ta ; -++ jral5 ta ; -+ $1 -+ -+ case 4-4-4-4; 16-bit off, optimize don't care -+- bltz rt, $1 ; LONGCALL3 -+- sethi ta, hi20(symbol) ; HI20 -++ bltz rt, $1 ; LONGCALL3 -++ sethi ta, hi20(symbol) ; HI20 -+ ori ta, ta, lo12(symbol) ; LO12S0 -+- jral ta ; -++ jral ta ; -+ $1 -+ -+ case 4-4-4-4; 16-bit on, optimize for speed -+- bltz rt, $1 ; LONGCALL3 -+- sethi ta, hi20(symbol) ; HI20 -++ bltz rt, $1 ; LONGCALL3 -++ sethi ta, hi20(symbol) ; HI20 -+ ori ta, ta, lo12(symbol) ; LO12S0 -+- jral ta ; -+- $1 */ -++ jral ta ; -++ $1 */ -+ -+ /* Get the reloc for the address from which the register is -+ being loaded. This reloc will tell us which function is -+@@ -9012,7 +10455,6 @@ nds32_elf_relax_longcall3 (bfd *abfd, asection *sec, Elf_Internal_Rela *irel, -+ int seq_len; /* Original length of instruction sequence. */ -+ uint32_t insn; -+ Elf_Internal_Rela *hi_irelfn, *lo_irelfn, *cond_irelfn, *irelend; -+- int pic_ext_target = 0; -+ bfd_signed_vma foff; -+ uint16_t insn16; -+ -+@@ -9030,16 +10472,16 @@ nds32_elf_relax_longcall3 (bfd *abfd, asection *sec, Elf_Internal_Rela *irel, -+ -+ if (hi_irelfn == irelend || lo_irelfn == irelend) -+ { -+- _bfd_error_handler (unrecognized_reloc_msg, abfd, "R_NDS32_LONGCALL3", -+- irel->r_offset); -++ _bfd_error_handler -++ ("%B: warning: R_NDS32_LONGCALL3 points to unrecognized " -++ "reloc at 0x%lx.", abfd, (long) irel->r_offset); -+ return FALSE; -+ } -+ -+ /* Get the value of the symbol referred to by the reloc. */ -+- foff = calculate_offset (abfd, sec, hi_irelfn, isymbuf, symtab_hdr, -+- &pic_ext_target); -++ foff = calculate_offset (abfd, sec, hi_irelfn, isymbuf, symtab_hdr); -+ -+- if (pic_ext_target || foff == 0 || foff < -CONSERVATIVE_24BIT_S1 -++ if (foff == 0 || foff < -CONSERVATIVE_24BIT_S1 -+ || foff >= CONSERVATIVE_24BIT_S1) -+ return FALSE; -+ -+@@ -9047,7 +10489,7 @@ nds32_elf_relax_longcall3 (bfd *abfd, asection *sec, Elf_Internal_Rela *irel, -+ if (foff >= -CONSERVATIVE_16BIT_S1 && foff < CONSERVATIVE_16BIT_S1) -+ { -+ /* Relax to bgezal rt, label ; 17_PCREL -+- or bltzal rt, label ; 17_PCREL */ -++ or bltzal rt, label ; 17_PCREL */ -+ -+ /* Convert to complimentary conditional call. */ -+ insn = CONVERT_CONDITION_CALL (insn); -+@@ -9112,7 +10554,7 @@ nds32_elf_relax_longcall3 (bfd *abfd, asection *sec, Elf_Internal_Rela *irel, -+ return TRUE; -+ } -+ -+-/* Relax LONGJUMP1 relocation for nds32_elf_relax_section. */ -++/* Relax LONGJUMP1 relocation for nds32_elf_relax_section.*/ -+ -+ static bfd_boolean -+ nds32_elf_relax_longjump1 (bfd *abfd, asection *sec, Elf_Internal_Rela *irel, -+@@ -9122,19 +10564,19 @@ nds32_elf_relax_longjump1 (bfd *abfd, asection *sec, Elf_Internal_Rela *irel, -+ { -+ /* There are 3 variations for LONGJUMP1 -+ case 4-4-2; 16-bit bit on, optimize off or optimize for space -+- sethi ta, hi20(symbol) ; LONGJUMP1/HI20 -+- ori ta, ta, lo12(symbol) ; LO12S0 -+- jr5 ta ; -++ sethi ta, hi20(symbol) ; LONGJUMP1/HI20 -++ ori ta, ta, lo12(symbol) ; LO12S0 -++ jr5 ta ; -+ -+ case 4-4-4; 16-bit off, optimize don't care -+- sethi ta, hi20(symbol) ; LONGJUMP1/HI20 -+- ori ta, ta, lo12(symbol) ; LO12S0 -+- jr ta ; -++ sethi ta, hi20(symbol) ; LONGJUMP1/HI20 -++ ori ta, ta, lo12(symbol) ; LO12S0 -++ jr ta ; -+ -+ case 4-4-4; 16-bit on, optimize for speed -+- sethi ta, hi20(symbol) ; LONGJUMP1/HI20 -+- ori ta, ta, lo12(symbol) ; LO12S0 -+- jr ta ; */ -++ sethi ta, hi20(symbol) ; LONGJUMP1/HI20 -++ ori ta, ta, lo12(symbol) ; LO12S0 -++ jr ta ; */ -+ -+ /* Get the reloc for the address from which the register is -+ being loaded. This reloc will tell us which function is -+@@ -9145,7 +10587,6 @@ nds32_elf_relax_longjump1 (bfd *abfd, asection *sec, Elf_Internal_Rela *irel, -+ int insn16_on; /* 16-bit on/off. */ -+ uint32_t insn; -+ Elf_Internal_Rela *hi_irelfn, *lo_irelfn, *irelend; -+- int pic_ext_target = 0; -+ bfd_signed_vma foff; -+ uint16_t insn16; -+ unsigned long reloc; -+@@ -9164,23 +10605,23 @@ nds32_elf_relax_longjump1 (bfd *abfd, asection *sec, Elf_Internal_Rela *irel, -+ R_NDS32_LO12S0_ORI_RELA, laddr + 4); -+ if (hi_irelfn == irelend || lo_irelfn == irelend) -+ { -+- _bfd_error_handler (unrecognized_reloc_msg, abfd, "R_NDS32_LONGJUMP1", -+- irel->r_offset); -++ _bfd_error_handler -++ ("%B: warning: R_NDS32_LONGJUMP1 points to unrecognized " -++ "reloc at 0x%lx.", abfd, (long) irel->r_offset); -+ return FALSE; -+ } -+ -+ /* Get the value of the symbol referred to by the reloc. */ -+- foff = calculate_offset (abfd, sec, hi_irelfn, isymbuf, symtab_hdr, -+- &pic_ext_target); -++ foff = calculate_offset (abfd, sec, hi_irelfn, isymbuf, symtab_hdr); -+ -+- if (pic_ext_target || foff == 0 || foff >= CONSERVATIVE_24BIT_S1 -++ if (foff == 0 || foff >= CONSERVATIVE_24BIT_S1 -+ || foff < -CONSERVATIVE_24BIT_S1) -+ return FALSE; -+ -+ if (insn16_on && foff >= -ACCURATE_8BIT_S1 -+ && foff < ACCURATE_8BIT_S1 && (seq_len & 0x2)) -+ { -+- /* j8 label */ -++ /* j8 label */ -+ /* 16-bit on, but not optimized for speed. */ -+ reloc = R_NDS32_9_PCREL_RELA; -+ insn16 = INSN_J8; -+@@ -9191,7 +10632,7 @@ nds32_elf_relax_longjump1 (bfd *abfd, asection *sec, Elf_Internal_Rela *irel, -+ } -+ else -+ { -+- /* j label */ -++ /* j label */ -+ reloc = R_NDS32_25_PCREL_RELA; -+ insn = INSN_J; -+ bfd_putb32 (insn, contents + irel->r_offset); -+@@ -9275,14 +10716,14 @@ nds32_elf_convert_branch (uint16_t insn16, uint32_t insn, -+ switch ((insn16 & 0xf000) >> 12) -+ { -+ case 0xc: -+- /* beqz38 or bnez38 */ -++ /* beqz38 or bnez38 */ -+ comp_insn16 = (insn16 ^ 0x0800) & 0xff00; -+ comp_insn = (comp_insn16 & 0x0800) ? INSN_BNEZ : INSN_BEQZ; -+ comp_insn |= ((comp_insn16 & 0x0700) >> 8) << 20; -+ break; -+ -+ case 0xd: -+- /* beqs38 or bnes38 */ -++ /* beqs38 or bnes38 */ -+ comp_insn16 = (insn16 ^ 0x0800) & 0xff00; -+ comp_insn = (comp_insn16 & 0x0800) ? INSN_BNE : INSN_BEQ; -+ comp_insn |= (((comp_insn16 & 0x0700) >> 8) << 20) -+@@ -9290,7 +10731,7 @@ nds32_elf_convert_branch (uint16_t insn16, uint32_t insn, -+ break; -+ -+ case 0xe: -+- /* beqzS8 or bnezS8 */ -++ /* beqzS8 or bnezS8 */ -+ comp_insn16 = (insn16 ^ 0x0100) & 0xff00; -+ comp_insn = (comp_insn16 & 0x0100) ? INSN_BNEZ : INSN_BEQZ; -+ comp_insn |= REG_R15 << 20; -+@@ -9306,7 +10747,7 @@ nds32_elf_convert_branch (uint16_t insn16, uint32_t insn, -+ *re_insn16 = comp_insn16; -+ } -+ -+-/* Relax LONGJUMP2 relocation for nds32_elf_relax_section. */ -++/* Relax LONGJUMP2 relocation for nds32_elf_relax_section.*/ -+ -+ static bfd_boolean -+ nds32_elf_relax_longjump2 (bfd *abfd, asection *sec, Elf_Internal_Rela *irel, -+@@ -9329,7 +10770,7 @@ nds32_elf_relax_longjump2 (bfd *abfd, asection *sec, Elf_Internal_Rela *irel, -+ case 4-4; 1st insn convertible, 16-bit on, optimize for speed -+ bne rt, ra, $1 ; LONGJUMP2 -+ j label ; 25_PCREL -+- $1: */ -++ $1: */ -+ -+ /* Get the reloc for the address from which the register is -+ being loaded. This reloc will tell us which function is -+@@ -9338,7 +10779,7 @@ nds32_elf_relax_longjump2 (bfd *abfd, asection *sec, Elf_Internal_Rela *irel, -+ bfd_vma laddr; -+ int seq_len; /* Original length of instruction sequence. */ -+ Elf_Internal_Rela *i2_irelfn, *cond_irelfn, *irelend; -+- int pic_ext_target = 0, first_size; -++ int first_size; -+ unsigned int i; -+ bfd_signed_vma foff; -+ uint32_t insn, re_insn = 0; -+@@ -9359,7 +10800,7 @@ nds32_elf_relax_longjump2 (bfd *abfd, asection *sec, Elf_Internal_Rela *irel, -+ irelend, R_NDS32_25_PCREL_RELA, -+ laddr + first_size); -+ -+- for (i = 0; i < sizeof (checked_types) / sizeof(checked_types[0]); i++) -++ for (i = 0; i < ARRAY_SIZE (checked_types); i++) -+ { -+ cond_irelfn = -+ find_relocs_at_address_addr (irel, internal_relocs, irelend, -+@@ -9370,16 +10811,16 @@ nds32_elf_relax_longjump2 (bfd *abfd, asection *sec, Elf_Internal_Rela *irel, -+ -+ if (i2_irelfn == irelend || cond_irelfn == irelend) -+ { -+- _bfd_error_handler (unrecognized_reloc_msg, abfd, "R_NDS32_LONGJUMP2", -+- irel->r_offset); -++ _bfd_error_handler -++ ("%B: warning: R_NDS32_LONGJUMP2 points to unrecognized " -++ "reloc at 0x%lx.", abfd, (long) irel->r_offset); -+ return FALSE; -+ } -+ -+ /* Get the value of the symbol referred to by the reloc. */ -+ foff = -+- calculate_offset (abfd, sec, i2_irelfn, isymbuf, symtab_hdr, -+- &pic_ext_target); -+- if (pic_ext_target || foff == 0 || foff < -CONSERVATIVE_16BIT_S1 -++ calculate_offset (abfd, sec, i2_irelfn, isymbuf, symtab_hdr); -++ if (foff == 0 || foff < -CONSERVATIVE_16BIT_S1 -+ || foff >= CONSERVATIVE_16BIT_S1) -+ return FALSE; -+ -+@@ -9422,7 +10863,7 @@ nds32_elf_relax_longjump2 (bfd *abfd, asection *sec, Elf_Internal_Rela *irel, -+ && (foff >= -(ACCURATE_14BIT_S1 - first_size) -+ && foff < ACCURATE_14BIT_S1 - first_size)) -+ { -+- /* beqs label ; 15_PCREL */ -++ /* beqs label ; 15_PCREL */ -+ bfd_putb32 (re_insn, contents + irel->r_offset); -+ *insn_len = 4; -+ reloc = R_NDS32_15_PCREL_RELA; -+@@ -9432,7 +10873,7 @@ nds32_elf_relax_longjump2 (bfd *abfd, asection *sec, Elf_Internal_Rela *irel, -+ && foff >= -CONSERVATIVE_16BIT_S1 -+ && foff < CONSERVATIVE_16BIT_S1) -+ { -+- /* beqz label ; 17_PCREL */ -++ /* beqz label ; 17_PCREL */ -+ bfd_putb32 (re_insn, contents + irel->r_offset); -+ *insn_len = 4; -+ reloc = R_NDS32_17_PCREL_RELA; -+@@ -9465,7 +10906,7 @@ nds32_elf_relax_longjump2 (bfd *abfd, asection *sec, Elf_Internal_Rela *irel, -+ return TRUE; -+ } -+ -+-/* Relax LONGJUMP3 relocation for nds32_elf_relax_section. */ -++/* Relax LONGJUMP3 relocation for nds32_elf_relax_section.*/ -+ -+ static bfd_boolean -+ nds32_elf_relax_longjump3 (bfd *abfd, asection *sec, Elf_Internal_Rela *irel, -+@@ -9476,42 +10917,42 @@ nds32_elf_relax_longjump3 (bfd *abfd, asection *sec, Elf_Internal_Rela *irel, -+ /* There are 5 variations for LONGJUMP3 -+ case 1: 2-4-4-2; 1st insn convertible, 16-bit on, -+ optimize off or optimize for space -+- bnes38 rt, ra, $1 ; LONGJUMP3 -+- sethi ta, hi20(symbol) ; HI20 -++ bnes38 rt, ra, $1 ; LONGJUMP3 -++ sethi ta, hi20(symbol) ; HI20 -+ ori ta, ta, lo12(symbol) ; LO12S0 -+- jr5 ta ; -+- $1: ; -++ jr5 ta ; -++ $1: ; -+ -+ case 2: 2-4-4-2; 1st insn convertible, 16-bit on, optimize for speed -+- bnes38 rt, ra, $1 ; LONGJUMP3 -+- sethi ta, hi20(symbol) ; HI20 -++ bnes38 rt, ra, $1 ; LONGJUMP3 -++ sethi ta, hi20(symbol) ; HI20 -+ ori ta, ta, lo12(symbol) ; LO12S0 -+- jr5 ta ; -+- $1: ; LABEL -++ jr5 ta ; -++ $1: ; LABEL -+ -+ case 3: 4-4-4-2; 1st insn not convertible, 16-bit on, -+ optimize off or optimize for space -+- bne rt, ra, $1 ; LONGJUMP3 -+- sethi ta, hi20(symbol) ; HI20 -++ bne rt, ra, $1 ; LONGJUMP3 -++ sethi ta, hi20(symbol) ; HI20 -+ ori ta, ta, lo12(symbol) ; LO12S0 -+- jr5 ta ; -+- $1: ; -++ jr5 ta ; -++ $1: ; -+ -+ case 4: 4-4-4-4; 1st insn don't care, 16-bit off, optimize don't care -+ 16-bit off if no INSN16 -+- bne rt, ra, $1 ; LONGJUMP3 -+- sethi ta, hi20(symbol) ; HI20 -++ bne rt, ra, $1 ; LONGJUMP3 -++ sethi ta, hi20(symbol) ; HI20 -+ ori ta, ta, lo12(symbol) ; LO12S0 -+- jr ta ; -+- $1: ; -++ jr ta ; -++ $1: ; -+ -+ case 5: 4-4-4-4; 1st insn not convertible, 16-bit on, optimize for speed -+ 16-bit off if no INSN16 -+- bne rt, ra, $1 ; LONGJUMP3 -+- sethi ta, hi20(symbol) ; HI20 -++ bne rt, ra, $1 ; LONGJUMP3 -++ sethi ta, hi20(symbol) ; HI20 -+ ori ta, ta, lo12(symbol) ; LO12S0 -+- jr ta ; -+- $1: ; LABEL */ -++ jr ta ; -++ $1: ; LABEL */ -+ -+ /* Get the reloc for the address from which the register is -+ being loaded. This reloc will tell us which function is -+@@ -9523,7 +10964,7 @@ nds32_elf_relax_longjump3 (bfd *abfd, asection *sec, Elf_Internal_Rela *irel, -+ bfd_vma laddr; -+ int seq_len; /* Original length of instruction sequence. */ -+ Elf_Internal_Rela *hi_irelfn, *lo_irelfn, *cond_irelfn, *irelend; -+- int pic_ext_target = 0, first_size; -++ int first_size; -+ unsigned int i; -+ bfd_signed_vma foff; -+ uint32_t insn, re_insn = 0; -+@@ -9551,7 +10992,7 @@ nds32_elf_relax_longjump3 (bfd *abfd, asection *sec, Elf_Internal_Rela *irel, -+ R_NDS32_LO12S0_ORI_RELA, -+ laddr + first_size + 4); -+ -+- for (i = 0; i < sizeof (checked_types) / sizeof (checked_types[0]); i++) -++ for (i = 0; i < ARRAY_SIZE (checked_types); i++) -+ { -+ cond_irelfn = -+ find_relocs_at_address_addr (irel, internal_relocs, irelend, -+@@ -9562,16 +11003,16 @@ nds32_elf_relax_longjump3 (bfd *abfd, asection *sec, Elf_Internal_Rela *irel, -+ -+ if (hi_irelfn == irelend || lo_irelfn == irelend || cond_irelfn == irelend) -+ { -+- _bfd_error_handler (unrecognized_reloc_msg, abfd, "R_NDS32_LONGJUMP3", -+- irel->r_offset); -++ _bfd_error_handler -++ ("%B: warning: R_NDS32_LONGJUMP3 points to unrecognized " -++ "reloc at 0x%lx.", abfd, (long) irel->r_offset); -+ return FALSE; -+ } -+ -+ /* Get the value of the symbol referred to by the reloc. */ -+- foff = calculate_offset (abfd, sec, hi_irelfn, isymbuf, symtab_hdr, -+- &pic_ext_target); -++ foff = calculate_offset (abfd, sec, hi_irelfn, isymbuf, symtab_hdr); -+ -+- if (pic_ext_target || foff == 0 || foff < -CONSERVATIVE_24BIT_S1 -++ if (foff == 0 || foff < -CONSERVATIVE_24BIT_S1 -+ || foff >= CONSERVATIVE_24BIT_S1) -+ return FALSE; -+ -+@@ -9624,7 +11065,7 @@ nds32_elf_relax_longjump3 (bfd *abfd, asection *sec, Elf_Internal_Rela *irel, -+ && (foff >= -(ACCURATE_14BIT_S1 - first_size) -+ && foff < ACCURATE_14BIT_S1 - first_size)) -+ { -+- /* beqs label ; 15_PCREL */ -++ /* beqs label ; 15_PCREL */ -+ bfd_putb32 (re_insn, contents + irel->r_offset); -+ *insn_len = 4; -+ reloc = R_NDS32_15_PCREL_RELA; -+@@ -9635,7 +11076,7 @@ nds32_elf_relax_longjump3 (bfd *abfd, asection *sec, Elf_Internal_Rela *irel, -+ && foff >= -CONSERVATIVE_16BIT_S1 -+ && foff < CONSERVATIVE_16BIT_S1) -+ { -+- /* beqz label ; 17_PCREL */ -++ /* beqz label ; 17_PCREL */ -+ bfd_putb32 (re_insn, contents + irel->r_offset); -+ *insn_len = 4; -+ reloc = R_NDS32_17_PCREL_RELA; -+@@ -9661,7 +11102,7 @@ nds32_elf_relax_longjump3 (bfd *abfd, asection *sec, Elf_Internal_Rela *irel, -+ case 4-4; 1st insn convertible, 16-bit on, optimize for speed -+ bne rt, ra, $1 ; LONGJUMP2 -+ j label ; 25_PCREL -+- $1 */ -++ $1 */ -+ -+ /* Offset for first instruction. */ -+ -+@@ -9711,7 +11152,7 @@ nds32_elf_relax_longjump3 (bfd *abfd, asection *sec, Elf_Internal_Rela *irel, -+ return TRUE; -+ } -+ -+-/* Relax LONGCALL4 relocation for nds32_elf_relax_section. */ -++/* Relax LONGCALL4 relocation for nds32_elf_relax_section.*/ -+ -+ static bfd_boolean -+ nds32_elf_relax_longcall4 (bfd *abfd, asection *sec, Elf_Internal_Rela *irel, -+@@ -9728,7 +11169,6 @@ nds32_elf_relax_longcall4 (bfd *abfd, asection *sec, Elf_Internal_Rela *irel, -+ uint32_t insn; -+ Elf_Internal_Rela *hi_irel, *ptr_irel, *insn_irel, *em_irel, *call_irel; -+ Elf_Internal_Rela *irelend; -+- int pic_ext_target = 0; -+ bfd_signed_vma foff; -+ -+ irelend = internal_relocs + sec->reloc_count; -+@@ -9742,21 +11182,21 @@ nds32_elf_relax_longcall4 (bfd *abfd, asection *sec, Elf_Internal_Rela *irel, -+ -+ if (hi_irel == irelend) -+ { -+- _bfd_error_handler (unrecognized_reloc_msg, abfd, "R_NDS32_LONGCALL4", -+- irel->r_offset); -++ _bfd_error_handler -++ ("%B: warning: R_NDS32_LONGCALL4 points to unrecognized " -++ "reloc at 0x%lx.", abfd, (long) irel->r_offset); -+ return FALSE; -+ } -+ -+ /* Get the value of the symbol referred to by the reloc. */ -+- foff = calculate_offset (abfd, sec, hi_irel, isymbuf, symtab_hdr, -+- &pic_ext_target); -++ foff = calculate_offset (abfd, sec, hi_irel, isymbuf, symtab_hdr); -+ -+ /* This condition only happened when symbol is undefined. */ -+- if (pic_ext_target || foff == 0 || foff < -CONSERVATIVE_24BIT_S1 -++ if (foff == 0 || foff < -CONSERVATIVE_24BIT_S1 -+ || foff >= CONSERVATIVE_24BIT_S1) -+ return FALSE; -+ -+- /* Relax to: jal symbol; 25_PCREL */ -++ /* Relax to: jal symbol; 25_PCREL */ -+ /* For simplicity of coding, we are going to modify the section -+ contents, the section relocs, and the BFD symbol table. We -+ must tell the rest of the code not to free up this -+@@ -9772,8 +11212,9 @@ nds32_elf_relax_longcall4 (bfd *abfd, asection *sec, Elf_Internal_Rela *irel, -+ -+ if (ptr_irel == irelend || em_irel == irelend) -+ { -+- _bfd_error_handler (unrecognized_reloc_msg, abfd, "R_NDS32_LONGCALL4", -+- irel->r_offset); -++ _bfd_error_handler -++ ("%B: warning: R_NDS32_LONGCALL4 points to unrecognized " -++ "reloc at 0x%lx.", abfd, (long) irel->r_offset); -+ return FALSE; -+ } -+ /* Check these is enough space to insert jal in R_NDS32_EMPTY. */ -+@@ -9812,7 +11253,7 @@ nds32_elf_relax_longcall4 (bfd *abfd, asection *sec, Elf_Internal_Rela *irel, -+ return TRUE; -+ } -+ -+-/* Relax LONGCALL5 relocation for nds32_elf_relax_section. */ -++/* Relax LONGCALL5 relocation for nds32_elf_relax_section.*/ -+ -+ static bfd_boolean -+ nds32_elf_relax_longcall5 (bfd *abfd, asection *sec, Elf_Internal_Rela *irel, -+@@ -9828,7 +11269,6 @@ nds32_elf_relax_longcall5 (bfd *abfd, asection *sec, Elf_Internal_Rela *irel, -+ bfd_vma laddr; -+ uint32_t insn; -+ Elf_Internal_Rela *cond_irel, *irelend; -+- int pic_ext_target = 0; -+ bfd_signed_vma foff; -+ -+ irelend = internal_relocs + sec->reloc_count; -+@@ -9843,21 +11283,21 @@ nds32_elf_relax_longcall5 (bfd *abfd, asection *sec, Elf_Internal_Rela *irel, -+ R_NDS32_25_PCREL_RELA, irel->r_addend); -+ if (cond_irel == irelend) -+ { -+- _bfd_error_handler (unrecognized_reloc_msg, abfd, "R_NDS32_LONGCALL5", -+- irel->r_offset); -++ _bfd_error_handler -++ ("%B: warning: R_NDS32_LONGCALL5 points to unrecognized " -++ "reloc at 0x%lx.", abfd, (long) irel->r_offset); -+ return FALSE; -+ } -+ -+ /* Get the value of the symbol referred to by the reloc. */ -+- foff = calculate_offset (abfd, sec, cond_irel, isymbuf, symtab_hdr, -+- &pic_ext_target); -++ foff = calculate_offset (abfd, sec, cond_irel, isymbuf, symtab_hdr); -+ -+ if (foff == 0 || foff < -CONSERVATIVE_16BIT_S1 -+ || foff >= CONSERVATIVE_16BIT_S1) -+ return FALSE; -+ -+ /* Relax to bgezal rt, label ; 17_PCREL -+- or bltzal rt, label ; 17_PCREL */ -++ or bltzal rt, label ; 17_PCREL */ -+ -+ /* Convert to complimentary conditional call. */ -+ insn = CONVERT_CONDITION_CALL (insn); -+@@ -9889,7 +11329,7 @@ nds32_elf_relax_longcall5 (bfd *abfd, asection *sec, Elf_Internal_Rela *irel, -+ return TRUE; -+ } -+ -+-/* Relax LONGCALL6 relocation for nds32_elf_relax_section. */ -++/* Relax LONGCALL6 relocation for nds32_elf_relax_section.*/ -+ -+ static bfd_boolean -+ nds32_elf_relax_longcall6 (bfd *abfd, asection *sec, Elf_Internal_Rela *irel, -+@@ -9907,7 +11347,6 @@ nds32_elf_relax_longcall6 (bfd *abfd, asection *sec, Elf_Internal_Rela *irel, -+ bfd_vma laddr; -+ uint32_t insn; -+ Elf_Internal_Rela *em_irel, *cond_irel, *irelend; -+- int pic_ext_target = 0; -+ bfd_signed_vma foff; -+ -+ irelend = internal_relocs + sec->reloc_count; -+@@ -9921,16 +11360,16 @@ nds32_elf_relax_longcall6 (bfd *abfd, asection *sec, Elf_Internal_Rela *irel, -+ -+ if (em_irel == irelend) -+ { -+- _bfd_error_handler (unrecognized_reloc_msg, abfd, "R_NDS32_LONGCALL6", -+- irel->r_offset); -++ _bfd_error_handler -++ ("%B: warning: R_NDS32_LONGCALL6 points to unrecognized " -++ "reloc at 0x%lx.", abfd, (long) irel->r_offset); -+ return FALSE; -+ } -+ -+ /* Get the value of the symbol referred to by the reloc. */ -+- foff = calculate_offset (abfd, sec, em_irel, isymbuf, symtab_hdr, -+- &pic_ext_target); -++ foff = calculate_offset (abfd, sec, em_irel, isymbuf, symtab_hdr); -+ -+- if (pic_ext_target || foff == 0 || foff < -CONSERVATIVE_24BIT_S1 -++ if (foff == 0 || foff < -CONSERVATIVE_24BIT_S1 -+ || foff >= CONSERVATIVE_24BIT_S1) -+ return FALSE; -+ -+@@ -9943,7 +11382,7 @@ nds32_elf_relax_longcall6 (bfd *abfd, asection *sec, Elf_Internal_Rela *irel, -+ if (foff >= -CONSERVATIVE_16BIT_S1 && foff < CONSERVATIVE_16BIT_S1) -+ { -+ /* Relax to bgezal rt, label ; 17_PCREL -+- or bltzal rt, label ; 17_PCREL */ -++ or bltzal rt, label ; 17_PCREL */ -+ -+ /* Convert to complimentary conditional call. */ -+ *insn_len = 0; -+@@ -9959,8 +11398,9 @@ nds32_elf_relax_longcall6 (bfd *abfd, asection *sec, Elf_Internal_Rela *irel, -+ R_NDS32_PTR_RESOLVED, irel->r_addend); -+ if (cond_irel == irelend) -+ { -+- _bfd_error_handler (unrecognized_reloc_msg, abfd, -+- "R_NDS32_LONGCALL6", irel->r_offset); -++ _bfd_error_handler -++ ("%B: warning: R_NDS32_LONGCALL6 points to unrecognized " -++ "reloc at 0x%lx.", abfd, (long) irel->r_offset); -+ return FALSE; -+ } -+ cond_irel->r_addend = 1; -+@@ -10008,8 +11448,9 @@ nds32_elf_relax_longcall6 (bfd *abfd, asection *sec, Elf_Internal_Rela *irel, -+ R_NDS32_PTR_RESOLVED, irel->r_addend); -+ if (cond_irel == irelend) -+ { -+- _bfd_error_handler (unrecognized_reloc_msg, abfd, -+- "R_NDS32_LONGCALL6", irel->r_offset); -++ _bfd_error_handler -++ ("%B: warning: R_NDS32_LONGCALL6 points to unrecognized " -++ "reloc at 0x%lx.", abfd, (long) irel->r_offset); -+ return FALSE; -+ } -+ cond_irel->r_addend = 1; -+@@ -10024,7 +11465,7 @@ nds32_elf_relax_longcall6 (bfd *abfd, asection *sec, Elf_Internal_Rela *irel, -+ return TRUE; -+ } -+ -+-/* Relax LONGJUMP4 relocation for nds32_elf_relax_section. */ -++/* Relax LONGJUMP4 relocation for nds32_elf_relax_section.*/ -+ -+ static bfd_boolean -+ nds32_elf_relax_longjump4 (bfd *abfd, asection *sec, Elf_Internal_Rela *irel, -+@@ -10041,7 +11482,6 @@ nds32_elf_relax_longjump4 (bfd *abfd, asection *sec, Elf_Internal_Rela *irel, -+ int seq_len; /* Original length of instruction sequence. */ -+ uint32_t insn; -+ Elf_Internal_Rela *hi_irel, *ptr_irel, *em_irel, *call_irel, *irelend; -+- int pic_ext_target = 0; -+ bfd_signed_vma foff; -+ -+ irelend = internal_relocs + sec->reloc_count; -+@@ -10058,21 +11498,21 @@ nds32_elf_relax_longjump4 (bfd *abfd, asection *sec, Elf_Internal_Rela *irel, -+ -+ if (hi_irel == irelend) -+ { -+- _bfd_error_handler (unrecognized_reloc_msg, abfd, "R_NDS32_LONGJUMP4", -+- irel->r_offset); -++ _bfd_error_handler -++ ("%B: warning: R_NDS32_LONGJUMP4 points to unrecognized " -++ "reloc at 0x%lx.", abfd, (long) irel->r_offset); -+ return FALSE; -+ } -+ -+ /* Get the value of the symbol referred to by the reloc. */ -+- foff = calculate_offset (abfd, sec, hi_irel, isymbuf, symtab_hdr, -+- &pic_ext_target); -++ foff = calculate_offset (abfd, sec, hi_irel, isymbuf, symtab_hdr); -+ -+- if (pic_ext_target || foff == 0 || foff >= CONSERVATIVE_24BIT_S1 -++ if (foff == 0 || foff >= CONSERVATIVE_24BIT_S1 -+ || foff < -CONSERVATIVE_24BIT_S1) -+ return FALSE; -+ -+ /* Convert it to "j label", it may be converted to j8 in the final -+- pass of relaxation. Therefore, we do not consider this currently. */ -++ pass of relaxation. Therefore, we do not consider this currently.*/ -+ ptr_irel = find_relocs_at_address_addr (irel, internal_relocs, irelend, -+ R_NDS32_PTR_RESOLVED, irel->r_addend); -+ em_irel = find_relocs_at_address_addr (irel, internal_relocs, irelend, -+@@ -10080,8 +11520,9 @@ nds32_elf_relax_longjump4 (bfd *abfd, asection *sec, Elf_Internal_Rela *irel, -+ -+ if (ptr_irel == irelend || em_irel == irelend) -+ { -+- _bfd_error_handler (unrecognized_reloc_msg, abfd, "R_NDS32_LONGJUMP4", -+- irel->r_offset); -++ _bfd_error_handler -++ ("%B: warning: R_NDS32_LONGJUMP4 points to unrecognized " -++ "reloc at 0x%lx.", abfd, (long) irel->r_offset); -+ return FALSE; -+ } -+ -+@@ -10109,7 +11550,7 @@ nds32_elf_relax_longjump4 (bfd *abfd, asection *sec, Elf_Internal_Rela *irel, -+ return TRUE; -+ } -+ -+-/* Relax LONGJUMP5 relocation for nds32_elf_relax_section. */ -++/* Relax LONGJUMP5 relocation for nds32_elf_relax_section.*/ -+ -+ static bfd_boolean -+ nds32_elf_relax_longjump5 (bfd *abfd, asection *sec, Elf_Internal_Rela *irel, -+@@ -10131,7 +11572,6 @@ nds32_elf_relax_longjump5 (bfd *abfd, asection *sec, Elf_Internal_Rela *irel, -+ -+ bfd_vma laddr; -+ Elf_Internal_Rela *cond_irel, *irelend; -+- int pic_ext_target = 0; -+ unsigned int i; -+ bfd_signed_vma foff; -+ uint32_t insn, re_insn = 0; -+@@ -10154,16 +11594,16 @@ nds32_elf_relax_longjump5 (bfd *abfd, asection *sec, Elf_Internal_Rela *irel, -+ R_NDS32_25_PCREL_RELA, irel->r_addend); -+ if (cond_irel == irelend) -+ { -+- _bfd_error_handler (unrecognized_reloc_msg, abfd, "R_NDS32_LONGJUMP5", -+- irel->r_offset); -++ _bfd_error_handler -++ ("%B: warning: R_NDS32_LONGJUMP5 points to unrecognized " -++ "reloc at 0x%lx.", abfd, (long) irel->r_offset); -+ return FALSE; -+ } -+ -+ /* Get the value of the symbol referred to by the reloc. */ -+- foff = calculate_offset (abfd, sec, cond_irel, isymbuf, symtab_hdr, -+- &pic_ext_target); -++ foff = calculate_offset (abfd, sec, cond_irel, isymbuf, symtab_hdr); -+ -+- if (pic_ext_target || foff == 0 || foff < -CONSERVATIVE_16BIT_S1 -++ if (foff == 0 || foff < -CONSERVATIVE_16BIT_S1 -+ || foff >= CONSERVATIVE_16BIT_S1) -+ return FALSE; -+ -+@@ -10208,7 +11648,7 @@ nds32_elf_relax_longjump5 (bfd *abfd, asection *sec, Elf_Internal_Rela *irel, -+ -+ /* Clean relocations. */ -+ irel->r_info = ELF32_R_INFO (ELF32_R_SYM (irel->r_info), R_NDS32_NONE); -+- for (i = 0; i < sizeof (checked_types) / sizeof (checked_types[0]); i++) -++ for (i = 0; i < ARRAY_SIZE (checked_types); i++) -+ { -+ cond_irel = find_relocs_at_address_addr (irel, internal_relocs, irelend, -+ checked_types[i], laddr); -+@@ -10234,7 +11674,7 @@ nds32_elf_relax_longjump5 (bfd *abfd, asection *sec, Elf_Internal_Rela *irel, -+ return TRUE; -+ } -+ -+-/* Relax LONGJUMP6 relocation for nds32_elf_relax_section. */ -++/* Relax LONGJUMP6 relocation for nds32_elf_relax_section.*/ -+ -+ static bfd_boolean -+ nds32_elf_relax_longjump6 (bfd *abfd, asection *sec, Elf_Internal_Rela *irel, -+@@ -10265,7 +11705,6 @@ nds32_elf_relax_longjump6 (bfd *abfd, asection *sec, Elf_Internal_Rela *irel, -+ int reloc_off = 0, cond_removed = 0; -+ bfd_vma laddr; -+ Elf_Internal_Rela *cond_irel, *em_irel, *irelend, *insn_irel; -+- int pic_ext_target = 0; -+ unsigned int i; -+ bfd_signed_vma foff; -+ uint32_t insn, re_insn = 0; -+@@ -10283,16 +11722,16 @@ nds32_elf_relax_longjump6 (bfd *abfd, asection *sec, Elf_Internal_Rela *irel, -+ -+ if (em_irel == irelend) -+ { -+- _bfd_error_handler (unrecognized_reloc_msg, abfd, "R_NDS32_LONGJUMP6", -+- irel->r_offset); -++ _bfd_error_handler -++ ("%B: warning: R_NDS32_LONGJUMP6 points to unrecognized " -++ "reloc at 0x%lx.", abfd, (long) irel->r_offset); -+ return FALSE; -+ } -+ -+ /* Get the value of the symbol referred to by the reloc. */ -+- foff = calculate_offset (abfd, sec, em_irel, isymbuf, symtab_hdr, -+- &pic_ext_target); -++ foff = calculate_offset (abfd, sec, em_irel, isymbuf, symtab_hdr); -+ -+- if (pic_ext_target || foff == 0 || foff < -CONSERVATIVE_24BIT_S1 -++ if (foff == 0 || foff < -CONSERVATIVE_24BIT_S1 -+ || foff >= CONSERVATIVE_24BIT_S1) -+ return FALSE; -+ -+@@ -10318,7 +11757,7 @@ nds32_elf_relax_longjump6 (bfd *abfd, asection *sec, Elf_Internal_Rela *irel, -+ if (N32_OP6 (re_insn) == N32_OP6_BR1 -+ && (foff >= -CONSERVATIVE_14BIT_S1 && foff < CONSERVATIVE_14BIT_S1)) -+ { -+- /* beqs label ; 15_PCREL */ -++ /* beqs label ; 15_PCREL */ -+ bfd_putb32 (re_insn, contents + em_irel->r_offset); -+ reloc = R_NDS32_15_PCREL_RELA; -+ cond_removed = 1; -+@@ -10326,7 +11765,7 @@ nds32_elf_relax_longjump6 (bfd *abfd, asection *sec, Elf_Internal_Rela *irel, -+ else if (N32_OP6 (re_insn) == N32_OP6_BR2 -+ && foff >= -CONSERVATIVE_16BIT_S1 && foff < CONSERVATIVE_16BIT_S1) -+ { -+- /* beqz label ; 17_PCREL */ -++ /* beqz label ; 17_PCREL */ -+ bfd_putb32 (re_insn, contents + em_irel->r_offset); -+ reloc = R_NDS32_17_PCREL_RELA; -+ cond_removed = 1; -+@@ -10383,7 +11822,7 @@ nds32_elf_relax_longjump6 (bfd *abfd, asection *sec, Elf_Internal_Rela *irel, -+ /* Clear relocations. */ -+ irel->r_info = ELF32_R_INFO (ELF32_R_SYM (irel->r_info), R_NDS32_NONE); -+ -+- for (i = 0; i < sizeof (checked_types) / sizeof (checked_types[0]); i++) -++ for (i = 0; i < ARRAY_SIZE (checked_types); i++) -+ { -+ cond_irel = -+ find_relocs_at_address_addr (irel, internal_relocs, irelend, -+@@ -10415,7 +11854,7 @@ nds32_elf_relax_longjump6 (bfd *abfd, asection *sec, Elf_Internal_Rela *irel, -+ return TRUE; -+ } -+ -+-/* Relax LONGJUMP7 relocation for nds32_elf_relax_section. */ -++/* Relax LONGJUMP7 relocation for nds32_elf_relax_section.*/ -+ -+ static bfd_boolean -+ nds32_elf_relax_longjump7 (bfd *abfd, asection *sec, Elf_Internal_Rela *irel, -+@@ -10435,7 +11874,6 @@ nds32_elf_relax_longjump7 (bfd *abfd, asection *sec, Elf_Internal_Rela *irel, -+ -+ bfd_vma laddr; -+ Elf_Internal_Rela *cond_irel, *irelend, *insn_irel; -+- int pic_ext_target = 0; -+ bfd_signed_vma foff; -+ uint32_t insn, re_insn = 0; -+ uint16_t insn16; -+@@ -10453,16 +11891,16 @@ nds32_elf_relax_longjump7 (bfd *abfd, asection *sec, Elf_Internal_Rela *irel, -+ R_NDS32_15_PCREL_RELA, irel->r_addend); -+ if (cond_irel == irelend) -+ { -+- _bfd_error_handler (unrecognized_reloc_msg, abfd, "R_NDS32_LONGJUMP7", -+- irel->r_offset); -++ _bfd_error_handler -++ ("%B: warning: R_NDS32_LONGJUMP7 points to unrecognized " -++ "reloc at 0x%lx.", abfd, (long) irel->r_offset); -+ return FALSE; -+ } -+ -+ /* Get the value of the symbol referred to by the reloc. */ -+- foff = calculate_offset (abfd, sec, cond_irel, isymbuf, symtab_hdr, -+- &pic_ext_target); -++ foff = calculate_offset (abfd, sec, cond_irel, isymbuf, symtab_hdr); -+ -+- if (pic_ext_target || foff == 0 || foff < -CONSERVATIVE_8BIT_S1 -++ if (foff == 0 || foff < -CONSERVATIVE_8BIT_S1 -+ || foff >= CONSERVATIVE_8BIT_S1) -+ return FALSE; -+ -+@@ -10516,6 +11954,123 @@ nds32_elf_relax_longjump7 (bfd *abfd, asection *sec, Elf_Internal_Rela *irel, -+ return TRUE; -+ } -+ -++/* Record the offset to gp, and check if it changed after relaxing. -++ If the offset is fixed or the offset is near enough, try to relax -++ the pattern. This is avoid truncated to fit when relaxing fixed -++ address symbol. Ex: _stack. */ -++static bfd_boolean -++nds32_elf_relax_guard (bfd_vma *access_addr, bfd_vma local_sda, asection *sec, -++ Elf_Internal_Rela *irel, bfd_boolean *again, -++ bfd_boolean init, -++ struct elf_nds32_link_hash_table *table, -++ Elf_Internal_Sym *isymbuf, Elf_Internal_Shdr *symtab_hdr) -++ -++{ -++ /* The default linker script value. */ -++ int offset_to_gp; -++ static bfd_boolean sec_pass = FALSE; -++ static asection *first_sec = NULL, *sym_sec; -++ /* Record the number of instructions which may be removed. */ -++ static int count = 0, record_count; -++ Elf_Internal_Sym *isym; -++ struct elf_link_hash_entry *h = NULL; -++ int indx; -++ unsigned long r_symndx; -++ bfd *abfd = sec->owner; -++ static bfd_vma record_sda = 0; -++ int sda_offset = 0; -++ -++ /* Force doing relaxation when hyper-relax is high. */ -++ if (table->hyper_relax == 2) -++ return TRUE; -++ -++ /* Record the first section to get the round. */ -++ if (init) -++ { -++ if (!first_sec) -++ first_sec = sec; -++ else if (first_sec == sec) -++ { -++ record_count = count; -++ count = 0; -++ sec_pass = TRUE; -++ } -++ -++ if (!sec_pass) -++ *again = TRUE; -++ -++ return TRUE; -++ } -++ -++ if (record_sda == 0) -++ record_sda = local_sda; -++ else if (local_sda > record_sda) -++ /* In normal case, SDA is fixed or smaller except there is -++ DATA_SEGMENT_ALIGN in linker script.*/ -++ sda_offset = local_sda - record_sda; -++ -++ /* Although we doesn't delete all instructions here, counting all of -++ them to be conservative. */ -++ count++; -++ -++ r_symndx = ELF32_R_SYM (irel->r_info); -++ /* Global symbols. */ -++ if (r_symndx >= symtab_hdr->sh_info) -++ { -++ indx = ELF32_R_SYM (irel->r_info) - symtab_hdr->sh_info; -++ h = elf_sym_hashes (abfd)[indx]; -++ sym_sec = h->root.u.def.section; -++ if (NDS32_GUARD_SEC_P (sym_sec->flags) -++ || bfd_is_abs_section (sym_sec)) -++ { -++ /* Forbid doing relaxation when hyper-relax is low. */ -++ if (table->hyper_relax == 0) -++ return FALSE; -++ -++ offset_to_gp = *access_addr - local_sda; -++ if (elf32_nds32_hash_entry (h)->offset_to_gp == 0) -++ elf32_nds32_hash_entry (h)->offset_to_gp = offset_to_gp; -++ else if (abs (elf32_nds32_hash_entry (h)->offset_to_gp) -++ < abs (offset_to_gp) - sda_offset) -++ { -++ if (*access_addr >= local_sda) -++ *access_addr += (record_count * 4); -++ else -++ *access_addr -= (record_count * 4); -++ } -++ return sec_pass; -++ } -++ } -++ else -++ { -++ if (!elf32_nds32_allocate_local_sym_info (abfd)) -++ return FALSE; -++ isym = isymbuf + r_symndx; -++ -++ sym_sec = bfd_section_from_elf_index (abfd, isym->st_shndx); -++ if (NDS32_GUARD_SEC_P (sym_sec->flags)) -++ { -++ /* Forbid doing relaxation when hyper-relax is low. */ -++ if (table->hyper_relax == 0) -++ return FALSE; -++ -++ offset_to_gp = *access_addr - local_sda; -++ if (elf32_nds32_local_gp_offset (abfd)[r_symndx] == 0) -++ elf32_nds32_local_gp_offset (abfd)[r_symndx] = offset_to_gp; -++ else if (abs (elf32_nds32_local_gp_offset (abfd)[r_symndx]) -++ < abs (offset_to_gp) - sda_offset) -++ { -++ if (*access_addr >= local_sda) -++ *access_addr += (record_count * 4); -++ else -++ *access_addr -= (record_count * 4); -++ } -++ return sec_pass; -++ } -++ } -++ -++ return TRUE; -++} -+ #define GET_LOADSTORE_RANGE(addend) (((addend) >> 8) & 0x3f) -+ -+ /* Relax LOADSTORE relocation for nds32_elf_relax_section. */ -+@@ -10525,21 +12080,24 @@ nds32_elf_relax_loadstore (struct bfd_link_info *link_info, bfd *abfd, -+ asection *sec, Elf_Internal_Rela *irel, -+ Elf_Internal_Rela *internal_relocs, int *insn_len, -+ bfd_byte *contents, Elf_Internal_Sym *isymbuf, -+- Elf_Internal_Shdr *symtab_hdr, int load_store_relax) -++ Elf_Internal_Shdr *symtab_hdr, int load_store_relax, -++ struct elf_nds32_link_hash_table *table) -+ { -+- int eliminate_sethi = 0, range_type; -+- unsigned int i; -++ int eliminate_sethi = 0, range_type, i; -+ bfd_vma local_sda, laddr; -+ int seq_len; /* Original length of instruction sequence. */ -+ uint32_t insn; -+ Elf_Internal_Rela *hi_irelfn = NULL, *irelend; -+ bfd_vma access_addr = 0; -+ bfd_vma range_l = 0, range_h = 0; /* Upper/lower bound. */ -++ struct elf_link_hash_entry *h = NULL; -++ int indx; -+ enum elf_nds32_reloc_type checked_types[] = -+ { R_NDS32_HI20_RELA, R_NDS32_GOT_HI20, -+ R_NDS32_GOTPC_HI20, R_NDS32_GOTOFF_HI20, -+ R_NDS32_PLTREL_HI20, R_NDS32_PLT_GOTREL_HI20, -+- R_NDS32_TLS_LE_HI20 -++ R_NDS32_TLS_LE_HI20, R_NDS32_TLS_IE_HI20, -++ R_NDS32_TLS_IEGP_HI20, R_NDS32_TLS_DESC_HI20 -+ }; -+ -+ irelend = internal_relocs + sec->reloc_count; -+@@ -10548,7 +12106,7 @@ nds32_elf_relax_loadstore (struct bfd_link_info *link_info, bfd *abfd, -+ *insn_len = seq_len; -+ -+ /* Get the high part relocation. */ -+- for (i = 0; i < ARRAY_SIZE (checked_types); i++) -++ for (i = 0; (unsigned) i < ARRAY_SIZE (checked_types); i++) -+ { -+ hi_irelfn = find_relocs_at_address_addr (irel, internal_relocs, irelend, -+ checked_types[i], laddr); -+@@ -10558,9 +12116,12 @@ nds32_elf_relax_loadstore (struct bfd_link_info *link_info, bfd *abfd, -+ -+ if (hi_irelfn == irelend) -+ { -+- _bfd_error_handler (unrecognized_reloc_msg, abfd, "R_NDS32_LOADSTORE", -+- irel->r_offset); -+- return FALSE; -++ /* Not R_NDS32_HI20_RELA. */ -++ if (i != 0) -++ _bfd_error_handler -++ ("%B: warning: R_NDS32_LOADSTORE points to unrecognized " -++ "reloc at 0x%lx.", abfd, (long) irel->r_offset); -++ return FALSE; -+ } -+ -+ range_type = GET_LOADSTORE_RANGE (irel->r_addend); -+@@ -10574,39 +12135,41 @@ nds32_elf_relax_loadstore (struct bfd_link_info *link_info, bfd *abfd, -+ access_addr = -+ calculate_memory_address (abfd, hi_irelfn, isymbuf, symtab_hdr); -+ -+- if (range_type == NDS32_LOADSTORE_IMM) -++ if (ELF32_R_SYM (hi_irelfn->r_info) >= symtab_hdr->sh_info) -+ { -+- struct elf_link_hash_entry *h = NULL; -+- int indx; -+- -+- if (ELF32_R_SYM (hi_irelfn->r_info) >= symtab_hdr->sh_info) -+- { -+- indx = ELF32_R_SYM (hi_irelfn->r_info) - symtab_hdr->sh_info; -+- h = elf_sym_hashes (abfd)[indx]; -+- } -++ indx = ELF32_R_SYM (hi_irelfn->r_info) - symtab_hdr->sh_info; -++ h = elf_sym_hashes (abfd)[indx]; -++ } -+ -++ /* Try movi. */ -++ if (range_type == NDS32_LOADSTORE_IMM) -++ { -+ if ((access_addr < CONSERVATIVE_20BIT) -+ && (!h || (h && strcmp (h->root.root.string, FP_BASE_NAME) != 0))) -+ { -+ eliminate_sethi = 1; -+ break; -+ } -++ } -+ -+- /* This is avoid to relax symbol address which is fixed -+- relocations. Ex: _stack. */ -+- if (h && bfd_is_abs_section (h->root.u.def.section)) -+- return FALSE; -++ if (h && strcmp (h->root.root.string, FP_BASE_NAME) == 0) -++ { -++ eliminate_sethi = 1; -++ break; -+ } -++ else if (!nds32_elf_relax_guard (&access_addr, local_sda, sec, hi_irelfn, -++ NULL, FALSE, table, isymbuf, symtab_hdr)) -++ return FALSE; -+ -+ if (!load_store_relax) -+ return FALSE; -+ -+ /* Case for set gp register. */ -+ if (N32_RT5 (insn) == REG_GP) -+- break; -++ return FALSE; -+ -+ if (range_type == NDS32_LOADSTORE_FLOAT_S -+- || range_type == NDS32_LOADSTORE_FLOAT_D) -++ || range_type == NDS32_LOADSTORE_FLOAT_S) -+ { -+ range_l = sdata_range[0][0]; -+ range_h = sdata_range[0][1]; -+@@ -10618,57 +12181,6 @@ nds32_elf_relax_loadstore (struct bfd_link_info *link_info, bfd *abfd, -+ } -+ break; -+ -+- case R_NDS32_GOT_HI20: -+- access_addr = -+- calculate_got_memory_address (abfd, link_info, hi_irelfn, symtab_hdr); -+- -+- /* If this symbol is not in .got, the return value will be -1. -+- Since the gp value is set to SDA_BASE but not GLOBAL_OFFSET_TABLE, -+- a negative offset is allowed. */ -+- if ((bfd_signed_vma) (access_addr - local_sda) < CONSERVATIVE_20BIT -+- && (bfd_signed_vma) (access_addr - local_sda) >= -CONSERVATIVE_20BIT) -+- eliminate_sethi = 1; -+- break; -+- -+- case R_NDS32_PLT_GOTREL_HI20: -+- access_addr = calculate_plt_memory_address (abfd, link_info, isymbuf, -+- hi_irelfn, symtab_hdr); -+- -+- if ((bfd_signed_vma) (access_addr - local_sda) < CONSERVATIVE_20BIT -+- && (bfd_signed_vma) (access_addr - local_sda) >= -CONSERVATIVE_20BIT) -+- eliminate_sethi = 1; -+- break; -+- -+- case R_NDS32_GOTOFF_HI20: -+- access_addr = -+- calculate_memory_address (abfd, hi_irelfn, isymbuf, symtab_hdr); -+- -+- if ((bfd_signed_vma) (access_addr - local_sda) < CONSERVATIVE_20BIT -+- && (bfd_signed_vma) (access_addr - local_sda) >= -CONSERVATIVE_20BIT) -+- eliminate_sethi = 1; -+- break; -+- -+- case R_NDS32_GOTPC_HI20: -+- /* The access_addr must consider r_addend of hi_irel. */ -+- access_addr = sec->output_section->vma + sec->output_offset -+- + irel->r_offset + hi_irelfn->r_addend; -+- -+- if ((bfd_signed_vma) (local_sda - access_addr) < CONSERVATIVE_20BIT -+- && (bfd_signed_vma) (local_sda - access_addr) >= -CONSERVATIVE_20BIT) -+- eliminate_sethi = 1; -+- break; -+- -+- case R_NDS32_TLS_LE_HI20: -+- access_addr = -+- calculate_memory_address (abfd, hi_irelfn, isymbuf, symtab_hdr); -+- BFD_ASSERT (elf_hash_table (link_info)->tls_sec != NULL); -+- access_addr -= (elf_hash_table (link_info)->tls_sec->vma + TP_OFFSET); -+- if ((range_type == NDS32_LOADSTORE_IMM) -+- && (bfd_signed_vma) (access_addr) < CONSERVATIVE_20BIT -+- && (bfd_signed_vma) (access_addr) >= -CONSERVATIVE_20BIT) -+- eliminate_sethi = 1; -+- break; -+- -+ default: -+ return FALSE; -+ } -+@@ -10683,17 +12195,20 @@ nds32_elf_relax_loadstore (struct bfd_link_info *link_info, bfd *abfd, -+ irel->r_info = -+ ELF32_R_INFO (ELF32_R_SYM (irel->r_info), R_NDS32_NONE); -+ *insn_len = 0; -++ return TRUE; -+ } -+- return TRUE; -++ -++ return FALSE; -+ } -+ -+-/* Relax LO12 relocation for nds32_elf_relax_section. */ -++/* Relax LO12 relocation for nds32_elf_relax_section.*/ -+ -+ static void -+ nds32_elf_relax_lo12 (struct bfd_link_info *link_info, bfd *abfd, -+ asection *sec, Elf_Internal_Rela *irel, -+ Elf_Internal_Rela *internal_relocs, bfd_byte *contents, -+- Elf_Internal_Sym *isymbuf, Elf_Internal_Shdr *symtab_hdr) -++ Elf_Internal_Sym *isymbuf, Elf_Internal_Shdr *symtab_hdr, -++ struct elf_nds32_link_hash_table *table) -+ { -+ uint32_t insn; -+ bfd_vma local_sda, laddr; -+@@ -10723,6 +12238,7 @@ nds32_elf_relax_lo12 (struct bfd_link_info *link_info, bfd *abfd, -+ h = elf_sym_hashes (abfd)[indx]; -+ } -+ -++ /* Try movi. */ -+ if (N32_OP6 (insn) == N32_OP6_ORI && access_addr < CONSERVATIVE_20BIT -+ && (!h || (h && strcmp (h->root.root.string, FP_BASE_NAME) != 0))) -+ { -+@@ -10731,13 +12247,14 @@ nds32_elf_relax_lo12 (struct bfd_link_info *link_info, bfd *abfd, -+ insn = N32_TYPE1 (MOVI, N32_RT5 (insn), 0); -+ bfd_putb32 (insn, contents + laddr); -+ } -+- /* This is avoid to relax symbol address which is fixed -+- relocations. Ex: _stack. */ -+- else if (N32_OP6 (insn) == N32_OP6_ORI -+- && h && bfd_is_abs_section (h->root.u.def.section)) -+- return; -+ else -+ { -++ if (h && strcmp (h->root.root.string, FP_BASE_NAME) == 0) -++ { /* Fall through. */ } -++ else if (!nds32_elf_relax_guard (&access_addr, local_sda, sec, irel, NULL, -++ FALSE, table, isymbuf, symtab_hdr)) -++ return; -++ -+ range_l = sdata_range[1][0]; -+ range_h = sdata_range[1][1]; -+ switch (ELF32_R_TYPE (irel->r_info)) -+@@ -10768,7 +12285,8 @@ nds32_elf_relax_lo12 (struct bfd_link_info *link_info, bfd *abfd, -+ /* There are range_h and range_l because linker has to promise -+ all sections move cross one page together. */ -+ if ((local_sda <= access_addr && (access_addr - local_sda) < range_h) -+- || (local_sda > access_addr && (local_sda - access_addr) <= range_l)) -++ || (local_sda > access_addr && (local_sda - access_addr) <= range_l) -++ || (h && strcmp (h->root.root.string, FP_BASE_NAME) == 0)) -+ { -+ if (N32_OP6 (insn) == N32_OP6_ORI && N32_RT5 (insn) == REG_GP) -+ { -+@@ -10790,7 +12308,6 @@ nds32_elf_relax_lo12 (struct bfd_link_info *link_info, bfd *abfd, -+ if (irelfn != irelend && reloc != R_NDS32_SDA17S2_RELA) -+ irelfn->r_info = -+ ELF32_R_INFO (ELF32_R_SYM (irelfn->r_info), R_NDS32_NONE); -+- -+ } -+ } -+ return; -+@@ -10798,7 +12315,7 @@ nds32_elf_relax_lo12 (struct bfd_link_info *link_info, bfd *abfd, -+ -+ /* Relax low part of PIC instruction pattern. */ -+ -+-static void -++ATTRIBUTE_UNUSED static void -+ nds32_elf_relax_piclo12 (struct bfd_link_info *link_info, bfd *abfd, -+ asection *sec, Elf_Internal_Rela *irel, -+ bfd_byte *contents, Elf_Internal_Sym *isymbuf, -+@@ -10855,7 +12372,7 @@ nds32_elf_relax_piclo12 (struct bfd_link_info *link_info, bfd *abfd, -+ -+ /* Relax low part of LE TLS instruction pattern. */ -+ -+-static void -++ATTRIBUTE_UNUSED static void -+ nds32_elf_relax_letlslo12 (struct bfd_link_info *link_info, bfd *abfd, -+ Elf_Internal_Rela *irel, -+ bfd_byte *contents, Elf_Internal_Sym *isymbuf, -+@@ -10885,7 +12402,7 @@ nds32_elf_relax_letlslo12 (struct bfd_link_info *link_info, bfd *abfd, -+ -+ /* Relax LE TLS calculate address instruction pattern. */ -+ -+-static void -++ATTRIBUTE_UNUSED static void -+ nds32_elf_relax_letlsadd (struct bfd_link_info *link_info, bfd *abfd, -+ asection *sec, Elf_Internal_Rela *irel, -+ Elf_Internal_Rela *internal_relocs, -+@@ -10893,9 +12410,9 @@ nds32_elf_relax_letlsadd (struct bfd_link_info *link_info, bfd *abfd, -+ Elf_Internal_Shdr *symtab_hdr, bfd_boolean *again) -+ { -+ /* Local TLS non-pic -+- sethi ta, hi20(symbol@tpoff) ; TLS_LE_HI20 -++ sethi ta, hi20(symbol@tpoff) ; TLS_LE_HI20 -+ ori ta, ta, lo12(symbol@tpoff) ; TLS_LE_LO12 -+- add ra, ta, tp ; TLS_LE_ADD */ -++ add ra, ta, tp ; TLS_LE_ADD */ -+ -+ uint32_t insn; -+ bfd_vma laddr; -+@@ -10931,14 +12448,13 @@ nds32_elf_relax_letlsadd (struct bfd_link_info *link_info, bfd *abfd, -+ -+ /* Relax LE TLS load store instruction pattern. */ -+ -+-static void -++ATTRIBUTE_UNUSED static void -+ nds32_elf_relax_letlsls (struct bfd_link_info *link_info, bfd *abfd, -+ asection *sec, Elf_Internal_Rela *irel, -+ Elf_Internal_Rela *internal_relocs, -+ bfd_byte *contents, Elf_Internal_Sym *isymbuf, -+ Elf_Internal_Shdr *symtab_hdr, bfd_boolean *again) -+ { -+- -+ uint32_t insn; -+ bfd_vma laddr; -+ bfd_signed_vma foff; -+@@ -10970,7 +12486,6 @@ nds32_elf_relax_letlsls (struct bfd_link_info *link_info, bfd *abfd, -+ success = 1; -+ break; -+ } -+- /* Fall through. */ -+ case (N32_OP6_MEM << 8) | N32_MEM_LH: -+ case (N32_OP6_MEM << 8) | N32_MEM_SH: -+ case (N32_OP6_MEM << 8) | N32_MEM_LHS: -+@@ -10985,7 +12500,6 @@ nds32_elf_relax_letlsls (struct bfd_link_info *link_info, bfd *abfd, -+ success = 1; -+ break; -+ } -+- /* Fall through. */ -+ case (N32_OP6_MEM << 8) | N32_MEM_LW: -+ case (N32_OP6_MEM << 8) | N32_MEM_SW: -+ /* The range is +/-64k. */ -+@@ -10999,7 +12513,6 @@ nds32_elf_relax_letlsls (struct bfd_link_info *link_info, bfd *abfd, -+ success = 1; -+ break; -+ } -+- /* Fall through. */ -+ default: -+ break; -+ } -+@@ -11032,8 +12545,9 @@ nds32_elf_relax_ptr (bfd *abfd, asection *sec, Elf_Internal_Rela *irel, -+ -+ if (re_irel == irelend) -+ { -+- _bfd_error_handler (unrecognized_reloc_msg, abfd, "R_NDS32_PTR", -+- irel->r_offset); -++ _bfd_error_handler -++ ("%B: warning: R_NDS32_PTR points to unrecognized reloc at 0x%lx.", -++ abfd, (long) irel->r_offset); -+ return FALSE; -+ } -+ -+@@ -11068,7 +12582,7 @@ nds32_elf_relax_ptr (bfd *abfd, asection *sec, Elf_Internal_Rela *irel, -+ -+ /* Relax PLT_GOT_SUFF relocation for nds32_elf_relax_section. */ -+ -+-static void -++ATTRIBUTE_UNUSED static void -+ nds32_elf_relax_pltgot_suff (struct bfd_link_info *link_info, bfd *abfd, -+ asection *sec, Elf_Internal_Rela *irel, -+ Elf_Internal_Rela *internal_relocs, -+@@ -11123,7 +12637,7 @@ nds32_elf_relax_pltgot_suff (struct bfd_link_info *link_info, bfd *abfd, -+ return; -+ irel->r_info = ELF32_R_INFO (ELF32_R_SYM (irel->r_info), -+ R_NDS32_PLT_GOTREL_LO19); -+- /* addi.gp */ -++ /* addi.gp */ -+ insn = N32_TYPE1 (SBGP, N32_RT5 (insn), N32_BIT (19)); -+ } -+ else if (N32_OP6 (insn) == N32_OP6_JREG -+@@ -11153,7 +12667,7 @@ nds32_elf_relax_pltgot_suff (struct bfd_link_info *link_info, bfd *abfd, -+ -+ /* Relax GOT_SUFF relocation for nds32_elf_relax_section. */ -+ -+-static void -++ATTRIBUTE_UNUSED static void -+ nds32_elf_relax_got_suff (struct bfd_link_info *link_info, bfd *abfd, -+ asection *sec, Elf_Internal_Rela *irel, -+ Elf_Internal_Rela *internal_relocs, -+@@ -11200,7 +12714,7 @@ nds32_elf_relax_got_suff (struct bfd_link_info *link_info, bfd *abfd, -+ -+ /* Relax PLT_GOT_SUFF relocation for nds32_elf_relax_section. */ -+ -+-static void -++ATTRIBUTE_UNUSED static void -+ nds32_elf_relax_gotoff_suff (struct bfd_link_info *link_info, bfd *abfd, -+ asection *sec, Elf_Internal_Rela *irel, -+ Elf_Internal_Rela *internal_relocs, -+@@ -11303,6 +12817,85 @@ nds32_elf_relax_gotoff_suff (struct bfd_link_info *link_info, bfd *abfd, -+ -+ } -+ -++/* Relax LWC relocation for nds32_elf_relax_section. */ -++ -++static void -++nds32_elf_relax_flsi (struct bfd_link_info *link_info, bfd *abfd, -++ asection *sec, Elf_Internal_Rela *irel, -++ Elf_Internal_Rela *internal_relocs, -++ bfd_byte *contents, Elf_Internal_Sym *isymbuf, -++ Elf_Internal_Shdr *symtab_hdr, bfd_boolean *again) -++{ -++ /* Pattern for bug-12566 -++ sethi ra, hi20(symbol) ; HI20/LOADSTORE -++ ori ra, ra, lo12(symbol) ; LO12S0/PTR/PTR/.../INSN16 -++ flsi fsa, [ra + offset1] ; LSI/PTR_RESOLVED/INSN16 -++ flsi fsb, [ra + offset2] ; LSI/PTR_RESOLVED/INSN16 -++ ... */ -++ -++ uint32_t insn; -++ bfd_vma local_sda, laddr; -++ unsigned long reloc; -++ bfd_vma access_addr, flsi_offset; -++ bfd_vma range_l = 0, range_h = 0; /* Upper/lower bound. */ -++ Elf_Internal_Rela *irelend, *re_irel; -++ unsigned int opcode; -++ -++ irelend = internal_relocs + sec->reloc_count; -++ laddr = irel->r_offset; -++ insn = bfd_getb32 (contents + laddr); -++ -++ if ((insn & 0x80000000) || !is_sda_access_insn (insn)) -++ return; -++ -++ /* Can not do relaxation for bi format. */ -++ if ((insn & 0x1000)) -++ return; -++ -++ /* Only deal with flsi, fssi, fldi, fsdi, so far. */ -++ opcode = N32_OP6 (insn); -++ if ((opcode == N32_OP6_LWC) || (opcode == N32_OP6_SWC)) -++ reloc = R_NDS32_SDA12S2_SP_RELA; -++ else if ((opcode == N32_OP6_LDC) || (opcode == N32_OP6_SDC)) -++ reloc = R_NDS32_SDA12S2_DP_RELA; -++ else -++ return; -++ -++ re_irel = find_relocs_at_address (irel, internal_relocs, irelend, -++ R_NDS32_PTR_RESOLVED); -++ if (re_irel == irelend) -++ { -++ _bfd_error_handler -++ ("%pB: warning: R_NDS32_LSI has no R_NDS32_PTR_RESOLVED at 0x%lx.", -++ abfd, (long) irel->r_offset); -++ return; -++ } -++ -++ /* For SDA base relative relaxation. */ -++ nds32_elf_final_sda_base (sec->output_section->owner, link_info, -++ &local_sda, FALSE); -++ access_addr = calculate_memory_address (abfd, irel, isymbuf, symtab_hdr); -++ flsi_offset = (insn & 0xfff) << 2; -++ access_addr += flsi_offset; -++ range_l = sdata_range[0][0]; -++ range_h = sdata_range[0][1]; -++ -++ if ((local_sda <= access_addr && (access_addr - local_sda) < range_h) -++ || (local_sda > access_addr && (local_sda - access_addr) <= range_l)) -++ { -++ /* Turn flsi instruction into sda access format. */ -++ insn = (insn & 0x7ff07000) | (REG_GP << 15); -++ -++ /* Add relocation type to flsi. */ -++ irel->r_info = ELF32_R_INFO (ELF32_R_SYM (irel->r_info), reloc); -++ irel->r_addend += flsi_offset; -++ bfd_putb32 (insn, contents + re_irel->r_offset); -++ -++ re_irel->r_addend |= 1; -++ *again = TRUE; -++ } -++} -++ -+ static bfd_boolean -+ nds32_relax_adjust_label (bfd *abfd, asection *sec, -+ Elf_Internal_Rela *internal_relocs, -+@@ -11387,9 +12980,11 @@ nds32_relax_adjust_label (bfd *abfd, asection *sec, -+ { -+ /* Remove all LABEL relocation from label_rel to tmp_rel -+ including relocations with same offset as tmp_rel. */ -+- for (tmp2_rel = label_rel; tmp2_rel < tmp_rel -+- || tmp2_rel->r_offset == tmp_rel->r_offset; tmp2_rel++) -++ for (tmp2_rel = label_rel; tmp2_rel < tmp_rel; tmp2_rel++) -+ { -++ if (tmp2_rel->r_offset == tmp_rel->r_offset) -++ break; -++ -+ if (ELF32_R_TYPE (tmp2_rel->r_info) == R_NDS32_LABEL -+ && tmp2_rel->r_addend < 2) -+ tmp2_rel->r_info = -+@@ -11416,7 +13011,8 @@ nds32_relax_adjust_label (bfd *abfd, asection *sec, -+ We may convert a 16-bit instruction right before a label to -+ 32-bit, in order to align the label if necessary -+ all reloc entries has been sorted by r_offset. */ -+- for (irel = internal_relocs; irel < irelend; irel++) -++ for (irel = internal_relocs; -++ irel < irelend && irel->r_offset < sec->size; irel++) -+ { -+ if (ELF32_R_TYPE (irel->r_info) != R_NDS32_INSN16 -+ && ELF32_R_TYPE (irel->r_info) != R_NDS32_LABEL) -+@@ -11568,118 +13164,6 @@ nds32_relax_adjust_label (bfd *abfd, asection *sec, -+ return TRUE; -+ } -+ -+-/* Pick relaxation round. */ -+- -+-static int -+-nds32_elf_pick_relax (bfd_boolean init, asection *sec, bfd_boolean *again, -+- struct elf_nds32_link_hash_table *table, -+- struct bfd_link_info *link_info) -+-{ -+- static asection *final_sec, *first_sec = NULL; -+- static bfd_boolean normal_again = FALSE; -+- static bfd_boolean set = FALSE; -+- static bfd_boolean first = TRUE; -+- int round_table[] = { -+- NDS32_RELAX_NORMAL_ROUND, -+- NDS32_RELAX_JUMP_IFC_ROUND, -+- NDS32_RELAX_EX9_BUILD_ROUND, -+- NDS32_RELAX_EX9_REPLACE_ROUND, -+- }; -+- static int pass = 0; -+- static int relax_round; -+- -+- /* The new round. */ -+- if (init && first_sec == sec) -+- { -+- set = TRUE; -+- normal_again = FALSE; -+- } -+- -+- if (first) -+- { -+- /* Run an empty run to get the final section. */ -+- relax_round = NDS32_RELAX_EMPTY_ROUND; -+- -+- /* It has to enter relax again because we can -+- not make sure what the final turn is. */ -+- *again = TRUE; -+- -+- first = FALSE; -+- first_sec = sec; -+- } -+- -+- if (!set) -+- { -+- /* Not reenter yet. */ -+- final_sec = sec; -+- return relax_round; -+- } -+- -+- relax_round = round_table[pass]; -+- -+- if (!init && relax_round == NDS32_RELAX_NORMAL_ROUND && *again) -+- normal_again = TRUE; -+- -+- if (!init && final_sec == sec) -+- { -+- switch (relax_round) -+- { -+- case NDS32_RELAX_NORMAL_ROUND: -+- if (!normal_again) -+- { -+- /* Normal relaxation done. */ -+- if (table->target_optimize & NDS32_RELAX_JUMP_IFC_ON) -+- { -+- pass++; -+- *again = TRUE; -+- } -+- else if (table->target_optimize & NDS32_RELAX_EX9_ON) -+- { -+- pass += 2; /* NDS32_RELAX_EX9_BUILD_ROUND */ -+- *again = TRUE; -+- } -+- else if (table->ex9_import_file) -+- { -+- /* Import ex9 table. */ -+- if (table->update_ex9_table) -+- pass += 2; /* NDS32_RELAX_EX9_BUILD_ROUND */ -+- else -+- pass += 3; /* NDS32_RELAX_EX9_REPLACE_ROUND */ -+- nds32_elf_ex9_import_table (link_info); -+- *again = TRUE; -+- } -+- } -+- break; -+- case NDS32_RELAX_JUMP_IFC_ROUND: -+- if (!nds32_elf_ifc_finish (link_info)) -+- _bfd_error_handler (_("error: Jump IFC Fail.")); -+- if (table->target_optimize & NDS32_RELAX_EX9_ON) -+- { -+- pass++; -+- *again = TRUE; -+- } -+- break; -+- case NDS32_RELAX_EX9_BUILD_ROUND: -+- nds32_elf_ex9_finish (link_info); -+- pass++; -+- *again = TRUE; -+- break; -+- case NDS32_RELAX_EX9_REPLACE_ROUND: -+- if (table->target_optimize & NDS32_RELAX_JUMP_IFC_ON) -+- { -+- /* Do jump IFC optimization again. */ -+- if (!nds32_elf_ifc_finish (link_info)) -+- _bfd_error_handler (_("error: Jump IFC Fail.")); -+- } -+- break; -+- default: -+- break; -+- } -+- } -+- -+- return relax_round; -+-} -+- -+ static bfd_boolean -+ nds32_elf_relax_section (bfd *abfd, asection *sec, -+ struct bfd_link_info *link_info, bfd_boolean *again) -+@@ -11697,26 +13181,25 @@ nds32_elf_relax_section (bfd *abfd, asection *sec, -+ uint32_t insn; -+ uint16_t insn16; -+ -+- /* Target dependnet option. */ -++ /* Target dependent option. */ -+ struct elf_nds32_link_hash_table *table; -+ int load_store_relax; -+- int relax_round; -+ -+ relax_blank_list = NULL; -+- -+ *again = FALSE; -+ -+ /* Nothing to do for -+- * relocatable link or -+- * non-relocatable section or -+- * non-code section or -+- * empty content or -+- * no reloc entry. */ -++ relocatable link or -++ non-relocatable section or -++ non-code section or -++ empty content or -++ no reloc entry. */ -+ if (bfd_link_relocatable (link_info) -+ || (sec->flags & SEC_RELOC) == 0 -+- || (sec->flags & SEC_EXCLUDE) != 0 -++ || (sec->flags & SEC_EXCLUDE) == 1 -+ || (sec->flags & SEC_CODE) == 0 -+- || sec->size == 0) -++ || sec->size == 0 -++ || sec->reloc_count == 0) -+ return TRUE; -+ -+ /* 09.12.11 Workaround. */ -+@@ -11725,44 +13208,14 @@ nds32_elf_relax_section (bfd *abfd, asection *sec, -+ if (sec->alignment_power > 2) -+ return TRUE; -+ -++#ifdef NDS32_LINUX_TOOLCHAIN -++ /* Do TLS model conversion once at first. */ -++ nds32_elf_unify_tls_model (abfd, sec, contents, link_info); -++#endif -++ -+ /* The optimization type to do. */ -+ -+ table = nds32_elf_hash_table (link_info); -+- relax_round = nds32_elf_pick_relax (TRUE, sec, again, table, link_info); -+- switch (relax_round) -+- { -+- case NDS32_RELAX_JUMP_IFC_ROUND: -+- /* Here is the entrance of ifc jump relaxation. */ -+- if (!nds32_elf_ifc_calc (link_info, abfd, sec)) -+- return FALSE; -+- nds32_elf_pick_relax (FALSE, sec, again, table, link_info); -+- return TRUE; -+- -+- case NDS32_RELAX_EX9_BUILD_ROUND: -+- /* Here is the entrance of ex9 relaxation. There are two pass of -+- ex9 relaxation. The one is to traverse all instructions and build -+- the hash table. The other one is to compare instructions and replace -+- it by ex9.it. */ -+- if (!nds32_elf_ex9_build_hash_table (abfd, sec, link_info)) -+- return FALSE; -+- nds32_elf_pick_relax (FALSE, sec, again, table, link_info); -+- return TRUE; -+- -+- case NDS32_RELAX_EX9_REPLACE_ROUND: -+- if (!nds32_elf_ex9_replace_instruction (link_info, abfd, sec)) -+- return FALSE; -+- return TRUE; -+- -+- case NDS32_RELAX_EMPTY_ROUND: -+- nds32_elf_pick_relax (FALSE, sec, again, table, link_info); -+- return TRUE; -+- -+- case NDS32_RELAX_NORMAL_ROUND: -+- default: -+- if (sec->reloc_count == 0) -+- return TRUE; -+- break; -+- } -+ -+ /* The begining of general relaxation. */ -+ -+@@ -11775,20 +13228,10 @@ nds32_elf_relax_section (bfd *abfd, asection *sec, -+ relax_range_measurement (abfd); -+ } -+ -+- if (is_ITB_BASE_set == 0) -+- { -+- /* Set the _ITB_BASE_. */ -+- if (!nds32_elf_ex9_itb_base (link_info)) -+- { -+- _bfd_error_handler (_("%B: error: Cannot set _ITB_BASE_"), abfd); -+- bfd_set_error (bfd_error_bad_value); -+- } -+- } -+- -+ symtab_hdr = &elf_tdata (abfd)->symtab_hdr; -+ /* Relocations MUST be kept in memory, because relaxation adjust them. */ -+ internal_relocs = _bfd_elf_link_read_relocs (abfd, sec, NULL, NULL, -+- TRUE /* keep_memory */); -++ TRUE /* keep_memory */); -+ if (internal_relocs == NULL) -+ goto error_return; -+ -+@@ -11802,10 +13245,7 @@ nds32_elf_relax_section (bfd *abfd, asection *sec, -+ if (ELF32_R_TYPE (irel->r_info) == R_NDS32_RELAX_ENTRY) -+ { -+ if (irel->r_addend & R_NDS32_RELAX_ENTRY_DISABLE_RELAX_FLAG) -+- { -+- nds32_elf_pick_relax (FALSE, sec, again, table, link_info); -+- return TRUE; -+- } -++ return TRUE; -+ -+ if (irel->r_addend & R_NDS32_RELAX_ENTRY_OPTIMIZE_FLAG) -+ optimize = 1; -+@@ -11888,7 +13328,8 @@ nds32_elf_relax_section (bfd *abfd, asection *sec, -+ || ELF32_R_TYPE (irel->r_info) == R_NDS32_17IFC_PCREL_RELA -+ || ELF32_R_TYPE (irel->r_info) == R_NDS32_TLS_LE_LO12 -+ || ELF32_R_TYPE (irel->r_info) == R_NDS32_TLS_LE_ADD -+- || ELF32_R_TYPE (irel->r_info) == R_NDS32_TLS_LE_LS) -++ || ELF32_R_TYPE (irel->r_info) == R_NDS32_TLS_LE_LS -++ || ELF32_R_TYPE (irel->r_info) == R_NDS32_LSI) -+ seq_len = 0; -+ else -+ continue; -+@@ -11967,71 +13408,41 @@ nds32_elf_relax_section (bfd *abfd, asection *sec, -+ removed = nds32_elf_relax_loadstore (link_info, abfd, sec, irel, -+ internal_relocs, &insn_len, -+ contents, isymbuf, symtab_hdr, -+- load_store_relax); -++ load_store_relax, table); -+ break; -+ case R_NDS32_LO12S0_RELA: -+ case R_NDS32_LO12S1_RELA: -++ case R_NDS32_LO12S2_RELA: -+ case R_NDS32_LO12S2_DP_RELA: -+ case R_NDS32_LO12S2_SP_RELA: -+- case R_NDS32_LO12S2_RELA: -+ /* Relax for low part. */ -+ nds32_elf_relax_lo12 (link_info, abfd, sec, irel, internal_relocs, -+- contents, isymbuf, symtab_hdr); -++ contents, isymbuf, symtab_hdr, table); -+ -+ /* It is impossible to delete blank, so just continue. */ -+ continue; -++ case R_NDS32_PTR: -++ removed = nds32_elf_relax_ptr (abfd, sec, irel, internal_relocs, -++ &insn_len, &seq_len, contents); -++ break; -++ case R_NDS32_LSI: -++ nds32_elf_relax_flsi (link_info, abfd, sec, irel, internal_relocs, -++ contents, isymbuf, symtab_hdr, again); -++ continue; -+ case R_NDS32_GOT_LO12: -+ case R_NDS32_GOTOFF_LO12: -+ case R_NDS32_PLTREL_LO12: -+ case R_NDS32_PLT_GOTREL_LO12: -+ case R_NDS32_GOTPC_LO12: -+- /* Relax for PIC gp-relative low part. */ -+- nds32_elf_relax_piclo12 (link_info, abfd, sec, irel, contents, -+- isymbuf, symtab_hdr); -+- -+- /* It is impossible to delete blank, so just continue. */ -+- continue; -+ case R_NDS32_TLS_LE_LO12: -+- /* Relax for LE TLS low part. */ -+- nds32_elf_relax_letlslo12 (link_info, abfd, irel, contents, -+- isymbuf, symtab_hdr); -+- -+- /* It is impossible to delete blank, so just continue. */ -+- continue; -+ case R_NDS32_TLS_LE_ADD: -+- nds32_elf_relax_letlsadd (link_info, abfd, sec, irel, internal_relocs, -+- contents, isymbuf, symtab_hdr, again); -+- /* It is impossible to delete blank, so just continue. */ -+- continue; -+ case R_NDS32_TLS_LE_LS: -+- nds32_elf_relax_letlsls (link_info, abfd, sec, irel, internal_relocs, -+- contents, isymbuf, symtab_hdr, again); -+- continue; -+- case R_NDS32_PTR: -+- removed = nds32_elf_relax_ptr (abfd, sec, irel, internal_relocs, -+- &insn_len, &seq_len, contents); -+- break; -+ case R_NDS32_PLT_GOT_SUFF: -+- nds32_elf_relax_pltgot_suff (link_info, abfd, sec, irel, -+- internal_relocs, contents, -+- isymbuf, symtab_hdr, again); -+- /* It is impossible to delete blank, so just continue. */ -+- continue; -+ case R_NDS32_GOT_SUFF: -+- nds32_elf_relax_got_suff (link_info, abfd, sec, irel, -+- internal_relocs, contents, -+- symtab_hdr, again); -+- /* It is impossible to delete blank, so just continue. */ -+- continue; -+ case R_NDS32_GOTOFF_SUFF: -+- nds32_elf_relax_gotoff_suff (link_info, abfd, sec, irel, -+- internal_relocs, contents, -+- isymbuf, symtab_hdr, again); -+- /* It is impossible to delete blank, so just continue. */ -+ continue; -+ default: -+ continue; -+- -+ } -+ if (removed && seq_len - insn_len > 0) -+ { -+@@ -12051,7 +13462,7 @@ nds32_elf_relax_section (bfd *abfd, asection *sec, -+ irelend, isymbuf)) -+ goto error_return; -+ -+- if (!*again) -++ if (*again == FALSE) -+ { -+ if (!nds32_fag_remove_unused_fpbase (abfd, sec, internal_relocs, -+ irelend)) -+@@ -12059,9 +13470,7 @@ nds32_elf_relax_section (bfd *abfd, asection *sec, -+ } -+ } -+ -+- nds32_elf_pick_relax (FALSE, sec, again, table, link_info); -+- -+- if (!*again) -++ if (*again == FALSE) -+ { -+ if (!nds32_relax_adjust_label (abfd, sec, internal_relocs, contents, -+ &relax_blank_list, optimize, opt_size)) -+@@ -12078,15 +13487,15 @@ nds32_elf_relax_section (bfd *abfd, asection *sec, -+ relax_blank_list = NULL; -+ } -+ -+- if (!*again) -++ if (*again == FALSE) -+ { -+ /* Closing the section, so we don't relax it anymore. */ -+ bfd_vma sec_size_align; -+ Elf_Internal_Rela *tmp_rel; -+ -+ /* Pad to alignment boundary. Only handle current section alignment. */ -+- sec_size_align = (sec->size + (~((-1U) << sec->alignment_power))) -+- & ((-1U) << sec->alignment_power); -++ sec_size_align = (sec->size + (~((bfd_vma)(-1) << sec->alignment_power))) -++ & ((bfd_vma)(-1) << sec->alignment_power); -+ if ((sec_size_align - sec->size) & 0x2) -+ { -+ insn16 = NDS32_NOP16; -+@@ -12128,8 +13537,7 @@ error_return: -+ goto finish; -+ } -+ -+-static struct bfd_elf_special_section const nds32_elf_special_sections[] = -+-{ -++static struct bfd_elf_special_section const nds32_elf_special_sections[] = { -+ {".sdata", 6, -2, SHT_PROGBITS, SHF_ALLOC + SHF_WRITE}, -+ {".sbss", 5, -2, SHT_NOBITS, SHF_ALLOC + SHF_WRITE}, -+ {NULL, 0, 0, 0, 0} -+@@ -12182,14 +13590,14 @@ bfd_elf32_nds32_set_target_option (struct bfd_link_info *link_info, -+ int eliminate_gc_relocs, -+ FILE * sym_ld_script, int load_store_relax, -+ int target_optimize, int relax_status, -+- int relax_round, FILE * ex9_export_file, -+- FILE * ex9_import_file, -+- int update_ex9_table, int ex9_limit, -+- bfd_boolean ex9_loop_aware, -+- bfd_boolean ifc_loop_aware) -++ int relax_round, int hyper_relax, -++ int tls_desc_trampoline, char *abi) -+ { -+ struct elf_nds32_link_hash_table *table; -+ -++ /* Initialize indirect call hash table. */ -++ nds32_elf_ict_hash_init (); -++ -+ table = nds32_elf_hash_table (link_info); -+ if (table == NULL) -+ return; -+@@ -12201,12 +13609,81 @@ bfd_elf32_nds32_set_target_option (struct bfd_link_info *link_info, -+ table->target_optimize = target_optimize; -+ table->relax_status = relax_status; -+ table->relax_round = relax_round; -+- table->ex9_export_file = ex9_export_file; -+- table->ex9_import_file = ex9_import_file; -+- table->update_ex9_table = update_ex9_table; -+- table->ex9_limit = ex9_limit; -+- table->ex9_loop_aware = ex9_loop_aware; -+- table->ifc_loop_aware = ifc_loop_aware; -++ table->hyper_relax = hyper_relax; -++ table->tls_desc_trampoline = tls_desc_trampoline; -++ output_abi = abi; -++} -++ -++void -++bfd_elf32_nds32_append_section (struct bfd_link_info *link_info, bfd *abfd) -++{ -++ asection *itable; -++ struct bfd_link_hash_entry *h; -++ unsigned int i, count = 0; -++ -++ /* Count number of indirect call function. */ -++ indirect_call_table.frozen = 1; -++ for (i = 0; i < indirect_call_table.size; i++) -++ { -++ struct bfd_hash_entry *p; -++ struct elf_nds32_ict_hash_entry *entry; -++ -++ for (p = indirect_call_table.table[i]; p != NULL; p = p->next) -++ { -++ entry = (struct elf_nds32_ict_hash_entry *) p; -++ entry->order = count; -++ count++; -++ } -++ } -++ indirect_call_table.frozen = 0; -++ -++ if (count) -++ { -++ h = bfd_link_hash_lookup (link_info->hash, "_INDIRECT_CALL_TABLE_BASE_", -++ FALSE, FALSE, FALSE); -++ if (h && (h->type == bfd_link_hash_defined -++ || h->type == bfd_link_hash_defweak -++ || h->type == bfd_link_hash_common)) -++ { -++ _bfd_error_handler (_("Warning: _INDIRECT_CALL_TABLE_BASE_ has already" -++ "be defined. All ICT suffix is ignored.")); -++ ignore_indirect_call = TRUE; -++ return; -++ } -++ -++ if (ict_model == R_NDS32_RELAX_ENTRY_ICT_LARGE) -++ itable = bfd_make_section_with_flags (abfd, NDS32_ICT_SECTION, -++ SEC_DATA | SEC_ALLOC | SEC_LOAD -++ | SEC_HAS_CONTENTS | SEC_READONLY -++ | SEC_IN_MEMORY | SEC_KEEP -++ | SEC_RELOC); -++ else -++ itable = bfd_make_section_with_flags (abfd, NDS32_ICT_SECTION, -++ SEC_CODE | SEC_ALLOC | SEC_LOAD -++ | SEC_HAS_CONTENTS | SEC_READONLY -++ | SEC_IN_MEMORY | SEC_KEEP -++ | SEC_RELOC); -++ if (itable) -++ { -++ itable->gc_mark = 1; -++ itable->alignment_power = 2; -++ itable->size = count * 4; -++ itable->contents = bfd_zalloc (abfd, itable->size); -++ -++ /* Add a symbol in the head of .nds32.ict to objdump clearly. */ -++ h = bfd_link_hash_lookup (link_info->hash, -++ "_INDIRECT_CALL_TABLE_BASE_", -++ FALSE, FALSE, FALSE); -++ _bfd_generic_link_add_one_symbol -++ (link_info, link_info->output_bfd, "_INDIRECT_CALL_TABLE_BASE_", -++ BSF_GLOBAL | BSF_WEAK, itable, 0, (const char *) NULL, FALSE, -++ get_elf_backend_data (link_info->output_bfd)->collect, &h); -++ } -++ -++ ict_file = fopen ("nds32_ict.s", FOPEN_WT); -++ if(ict_file == NULL) -++ _bfd_error_handler (_("Warning: Fail to build nds32_ict.s.")); -++ } -+ } -+ -+ /* These functions and data-structures are used for fp-as-gp -+@@ -12394,7 +13871,7 @@ nds32_fag_find_base (struct nds32_fag *head, struct nds32_fag **bestpp) -+ -+ static bfd_boolean -+ nds32_fag_mark_relax (struct bfd_link_info *link_info, -+- bfd *abfd, struct nds32_fag *best_fag, -++ asection *sec, struct nds32_fag *best_fag, -+ Elf_Internal_Rela *internal_relocs, -+ Elf_Internal_Rela *irelend) -+ { -+@@ -12402,7 +13879,7 @@ nds32_fag_mark_relax (struct bfd_link_info *link_info, -+ bfd_vma best_fpbase, gp; -+ bfd *output_bfd; -+ -+- output_bfd = abfd->sections->output_section->owner; -++ output_bfd = sec->output_section->owner; -+ nds32_elf_final_sda_base (output_bfd, link_info, &gp, FALSE); -+ best_fpbase = best_fag->addr; -+ -+@@ -12525,7 +14002,6 @@ nds32_relax_fp_as_gp (struct bfd_link_info *link_info, -+ { -+ /* Begin of the region. */ -+ if (begin_rel) -+- /* xgettext:c-format */ -+ _bfd_error_handler (_("%B: Nested OMIT_FP in %A."), abfd, sec); -+ -+ begin_rel = irel; -+@@ -12544,7 +14020,6 @@ nds32_relax_fp_as_gp (struct bfd_link_info *link_info, -+ -+ if (begin_rel == NULL) -+ { -+- /* xgettext:c-format */ -+ _bfd_error_handler (_("%B: Unmatched OMIT_FP in %A."), abfd, sec); -+ continue; -+ } -+@@ -12557,7 +14032,7 @@ nds32_relax_fp_as_gp (struct bfd_link_info *link_info, -+ -+ /* Check if it is worth, and FP_BASE is near enough to SDA_BASE. */ -+ if (accu < FAG_THRESHOLD -+- || !nds32_fag_mark_relax (link_info, abfd, best_fag, -++ || !nds32_fag_mark_relax (link_info, sec, best_fag, -+ internal_relocs, irelend)) -+ { -+ /* Not worth to do fp-as-gp. */ -+@@ -12811,9 +14286,9 @@ nds32_elf_get_relocated_section_contents (bfd *abfd, -+ case bfd_reloc_dangerous: -+ BFD_ASSERT (error_message != NULL); -+ (*link_info->callbacks->reloc_dangerous) -+- (link_info, error_message, -+- input_bfd, input_section, (*parent)->address); -+- break; -++ (link_info, error_message, input_bfd, input_section, -++ (*parent)->address); -++ break; -+ case bfd_reloc_overflow: -+ (*link_info->callbacks->reloc_overflow) -+ (link_info, NULL, -+@@ -12827,9 +14302,8 @@ nds32_elf_get_relocated_section_contents (bfd *abfd, -+ complete binaries. Do not abort, but issue an error -+ message instead. */ -+ link_info->callbacks->einfo -+- /* xgettext:c-format */ -+ (_("%X%P: %B(%A): relocation \"%R\" goes out of range\n"), -+- abfd, input_section, * parent); -++ abfd, input_section, *parent); -+ goto error_return; -+ -+ default: -+@@ -12847,745 +14321,807 @@ error_return: -+ free (reloc_vector); -+ return NULL; -+ } -+- -+-/* Link-time IFC relaxation. -+- In this optimization, we chains jump instructions -+- of the same destination with ifcall. */ -+ -++/* Check target symbol. */ -+ -+-/* List to save jal and j relocation. */ -+-struct elf_nds32_ifc_symbol_entry -++static bfd_boolean -++nds32_elf_is_target_special_symbol (bfd *abfd ATTRIBUTE_UNUSED, asymbol *sym) -+ { -+- asection *sec; -+- struct elf_link_hash_entry *h; -+- struct elf_nds32_ifc_irel_list *irel_head; -+- unsigned long insn; -+- int times; -+- int enable; /* Apply ifc. */ -+- int ex9_enable; /* Apply ifc after ex9. */ -+- struct elf_nds32_ifc_symbol_entry *next; -+-}; -++ if (!sym || !sym->name || sym->name[0] != '$') -++ return FALSE; -++ return TRUE; -++} -+ -+-struct elf_nds32_ifc_irel_list -++/* nds32 find maybe function sym. Ignore target special symbol -++ first, and then go the general function. */ -++ -++static bfd_size_type -++nds32_elf_maybe_function_sym (const asymbol *sym, asection *sec, -++ bfd_vma *code_off) -+ { -+- Elf_Internal_Rela *irel; -+- asection *sec; -+- bfd_vma addr; -+- /* If this is set, then it is the last instruction for -+- ifc-chain, so it must be keep for the actual branching. */ -+- int keep; -+- struct elf_nds32_ifc_irel_list *next; -+-}; -++ if (nds32_elf_is_target_special_symbol (NULL, (asymbol *) sym)) -++ return 0; -+ -+-static struct elf_nds32_ifc_symbol_entry *ifc_symbol_head = NULL; -++ return _bfd_elf_maybe_function_sym (sym, sec, code_off); -++} -+ -+-/* Insert symbol of jal and j for ifc. */ -++ -++/* Do TLS model conversion. */ -+ -+-static void -+-nds32_elf_ifc_insert_symbol (asection *sec, -+- struct elf_link_hash_entry *h, -+- Elf_Internal_Rela *irel, -+- unsigned long insn) -++typedef struct relax_group_list_t -+ { -+- struct elf_nds32_ifc_symbol_entry *ptr = ifc_symbol_head; -++ Elf_Internal_Rela *relo; -++ struct relax_group_list_t *next; -++ struct relax_group_list_t *next_sibling; -++ int id; -++} relax_group_list_t; -+ -+- /* Check there is target of existing entry the same as the new one. */ -+- while (ptr != NULL) -+- { -+- if (((h == NULL && ptr->sec == sec -+- && ELF32_R_SYM (ptr->irel_head->irel->r_info) == ELF32_R_SYM (irel->r_info) -+- && ptr->irel_head->irel->r_addend == irel->r_addend) -+- || h != NULL) -+- && ptr->h == h -+- && ptr->insn == insn) -+- { -+- /* The same target exist, so insert into list. */ -+- struct elf_nds32_ifc_irel_list *irel_list = ptr->irel_head; -++int -++list_insert (relax_group_list_t *pHead, Elf_Internal_Rela *pElem); -+ -+- while (irel_list->next != NULL) -+- irel_list = irel_list->next; -+- irel_list->next = bfd_malloc (sizeof (struct elf_nds32_ifc_irel_list)); -+- irel_list = irel_list->next; -+- irel_list->irel = irel; -+- irel_list->keep = 1; -++int -++list_insert_sibling (relax_group_list_t *pNode, Elf_Internal_Rela *pElem); -+ -+- if (h == NULL) -+- irel_list->sec = NULL; -+- else -+- irel_list->sec = sec; -+- irel_list->next = NULL; -+- return; -+- } -+- if (ptr->next == NULL) -+- break; -+- ptr = ptr->next; -+- } -++void -++dump_chain (relax_group_list_t *pHead); -+ -+- /* There is no same target entry, so build a new one. */ -+- if (ifc_symbol_head == NULL) -+- { -+- ifc_symbol_head = bfd_malloc (sizeof (struct elf_nds32_ifc_symbol_entry)); -+- ptr = ifc_symbol_head; -+- } -+- else -++int -++list_insert (relax_group_list_t *pHead, Elf_Internal_Rela *pElem) -++{ -++ relax_group_list_t *pNext = pHead; -++ -++ /* find place */ -++ while (pNext->next) -+ { -+- ptr->next = bfd_malloc (sizeof (struct elf_nds32_ifc_symbol_entry)); -+- ptr = ptr->next; -++ if (pNext->next->id > (int) pElem->r_addend) -++ break; -++ -++ pNext = pNext->next; -+ } -+ -+- ptr->h = h; -+- ptr->irel_head = bfd_malloc (sizeof (struct elf_nds32_ifc_irel_list)); -+- ptr->irel_head->irel = irel; -+- ptr->insn = insn; -+- ptr->irel_head->keep = 1; -++ /* insert node */ -++ relax_group_list_t *pNew = bfd_malloc (sizeof (relax_group_list_t)); -++ if (!pNew) -++ return FALSE; -++ -++ relax_group_list_t *tmp = pNext->next; -++ pNext->next = pNew; -+ -+- if (h == NULL) -+- { -+- /* Local symbols. */ -+- ptr->sec = sec; -+- ptr->irel_head->sec = NULL; -+- } -+- else -+- { -+- /* Global symbol. */ -+- ptr->sec = NULL; -+- ptr->irel_head->sec = sec; -+- } -++ pNew->id = pElem->r_addend; -++ pNew->relo = pElem; -++ pNew->next = tmp; -++ pNew->next_sibling = NULL; -+ -+- ptr->irel_head->next = NULL; -+- ptr->times = 0; -+- ptr->enable = 0; -+- ptr->ex9_enable = 0; -+- ptr->next = NULL; -++ return TRUE; -+ } -+ -+-/* Gather all jal and j instructions. */ -+- -+-static bfd_boolean -+-nds32_elf_ifc_calc (struct bfd_link_info *info, -+- bfd *abfd, asection *sec) -++int -++list_insert_sibling (relax_group_list_t *pNode, Elf_Internal_Rela *pElem) -+ { -+- Elf_Internal_Rela *internal_relocs; -+- Elf_Internal_Rela *irelend; -+- Elf_Internal_Rela *irel; -+- Elf_Internal_Shdr *symtab_hdr; -+- bfd_byte *contents = NULL; -+- uint32_t insn, insn_with_reg; -+- unsigned long r_symndx; -+- struct elf_link_hash_entry *h; -+- struct elf_link_hash_entry **sym_hashes = elf_sym_hashes (abfd); -+- struct elf_nds32_link_hash_table *table; -+- bfd_boolean ifc_loop_aware; -++ relax_group_list_t *pNext = pNode; -+ -+- internal_relocs = _bfd_elf_link_read_relocs (abfd, sec, NULL, NULL, -+- TRUE /* keep_memory */); -+- irelend = internal_relocs + sec->reloc_count; -+- symtab_hdr = &elf_tdata (abfd)->symtab_hdr; -++ /* find place */ -++ while (pNext->next_sibling) -++ { -++ pNext = pNext->next_sibling; -++ } -++ -++ /* insert node */ -++ relax_group_list_t *pNew = bfd_malloc (sizeof (relax_group_list_t)); -++ if (!pNew) -++ return FALSE; -+ -+- /* Check if the object enable ifc. */ -+- irel = find_relocs_at_address (internal_relocs, internal_relocs, irelend, -+- R_NDS32_RELAX_ENTRY); -++ relax_group_list_t *tmp = pNext->next_sibling; -++ pNext->next_sibling = pNew; -+ -+- if (irel == NULL -+- || irel >= irelend -+- || ELF32_R_TYPE (irel->r_info) != R_NDS32_RELAX_ENTRY -+- || (ELF32_R_TYPE (irel->r_info) == R_NDS32_RELAX_ENTRY -+- && !(irel->r_addend & R_NDS32_RELAX_ENTRY_IFC_FLAG))) -+- return TRUE; -++ pNew->id = -1; -++ pNew->relo = pElem; -++ pNew->next = NULL; -++ pNew->next_sibling = tmp; -+ -+- if (!nds32_get_section_contents (abfd, sec, &contents, TRUE)) -+- return FALSE; -++ return TRUE; -++} -+ -+- table = nds32_elf_hash_table (info); -+- ifc_loop_aware = table->ifc_loop_aware; -+- while (irel != NULL && irel < irelend) -++void -++dump_chain (relax_group_list_t *pHead) -++{ -++ relax_group_list_t *pNext = pHead->next; -++ while (pNext) -+ { -+- /* Traverse all relocation and gather all of them to build the list. */ -+- -+- if (ELF32_R_TYPE (irel->r_info) == R_NDS32_RELAX_REGION_BEGIN) -++ printf("group %d @ 0x%08x", pNext->id, (unsigned)pNext->relo->r_offset); -++ relax_group_list_t *pNextSib = pNext->next_sibling; -++ while (pNextSib) -+ { -+- if (ifc_loop_aware == 1 -+- && (irel->r_addend & R_NDS32_RELAX_REGION_INNERMOST_LOOP_FLAG) != 0) -+- { -+- /* Check the region if loop or not. If it is true and -+- ifc-loop-aware is true, ignore the region till region end. */ -+- while (irel != NULL -+- && irel < irelend -+- && (ELF32_R_TYPE (irel->r_info) != R_NDS32_RELAX_REGION_END -+- || (irel->r_addend & R_NDS32_RELAX_REGION_INNERMOST_LOOP_FLAG) != 0)) -+- irel++; -+- } -++ printf(", %d", (unsigned) ELF32_R_TYPE (pNextSib->relo->r_info)); -++ pNextSib = pNextSib->next_sibling; -+ } -++ pNext = pNext->next; -++ printf("\n"); -++ } -++} -++ -++/* check R_NDS32_RELAX_GROUP of each section. -++ there might be multiple sections in one object file. */ -++int -++elf32_nds32_check_relax_group (bfd *abfd, asection *asec) -++{ -++ elf32_nds32_relax_group_t *relax_group_ptr = -++ elf32_nds32_relax_group_ptr (abfd); -++ -++ int min_id = relax_group_ptr->min_id; -++ int max_id = relax_group_ptr->max_id; -++ -++ Elf_Internal_Rela *rel; -++ Elf_Internal_Rela *relend; -++ Elf_Internal_Rela *relocs; -++ enum elf_nds32_reloc_type rtype; -++ -++ do -++ { -++ /* Relocations MUST be kept in memory, because relaxation adjust them. */ -++ relocs = _bfd_elf_link_read_relocs (abfd, asec, NULL, NULL, -++ TRUE /* keep_memory */); -++ if (relocs == NULL) -++ break; -+ -+- if (ELF32_R_TYPE (irel->r_info) == R_NDS32_25_PCREL_RELA) -++ /* check R_NDS32_RELAX_GROUP */ -++ relend = relocs + asec->reloc_count; -++ for (rel = relocs; rel < relend; rel++) -+ { -+- insn = bfd_getb32 (contents + irel->r_offset); -+- nds32_elf_get_insn_with_reg (irel, insn, &insn_with_reg); -+- r_symndx = ELF32_R_SYM (irel->r_info); -+- if (r_symndx < symtab_hdr->sh_info) -+- { -+- /* Local symbol. */ -+- nds32_elf_ifc_insert_symbol (sec, NULL, irel, insn_with_reg); -+- } -+- else -+- { -+- /* External symbol. */ -+- h = sym_hashes[r_symndx - symtab_hdr->sh_info]; -+- nds32_elf_ifc_insert_symbol (sec, h, irel, insn_with_reg); -+- } -++ int id; -++ rtype = ELF32_R_TYPE (rel->r_info); -++ if (rtype != R_NDS32_RELAX_GROUP) -++ continue; -++ -++ id = rel->r_addend; -++ if (id < min_id) -++ min_id = id; -++ else if (id > max_id) -++ max_id = id; -+ } -+- irel++; -+ } -+- return TRUE; -++ while (FALSE); -++ -++ if ((relocs != NULL) && (elf_section_data (asec)->relocs != relocs)) -++ free (relocs); -++ -++ if ((min_id != relax_group_ptr->min_id) -++ || (max_id != relax_group_ptr->max_id)) -++ { -++ relax_group_ptr->count = max_id - min_id + 1; -++ BFD_ASSERT(min_id <= relax_group_ptr->min_id); -++ relax_group_ptr->min_id = min_id; -++ BFD_ASSERT(max_id >= relax_group_ptr->max_id); -++ relax_group_ptr->max_id = max_id; -++ } -++ -++ return relax_group_ptr->count; -+ } -+ -+-/* Determine whether j and jal should be substituted. */ -++/* Reorder RELAX_GROUP ID when command line option '-r' is applied. */ -++/* TODO: find a way to free me. */ -++struct section_id_list_t *relax_group_section_id_list = NULL; -+ -+-static void -+-nds32_elf_ifc_filter (struct bfd_link_info *info) -++struct section_id_list_t * -++elf32_nds32_lookup_section_id (int id, struct section_id_list_t **lst_ptr) -+ { -+- struct elf_nds32_ifc_symbol_entry *ptr = ifc_symbol_head; -+- struct elf_nds32_ifc_irel_list *irel_ptr = NULL; -+- struct elf_nds32_ifc_irel_list *irel_keeper = NULL; -+- struct elf_nds32_link_hash_table *table; -+- int target_optimize; -+- bfd_vma address; -++ struct section_id_list_t *result = NULL; -++ struct section_id_list_t *lst = *lst_ptr; -+ -+- table = nds32_elf_hash_table (info); -+- target_optimize = table->target_optimize; -+- while (ptr) -++ if (NULL == lst) -++ { -++ result = (struct section_id_list_t *) calloc ( -++ 1, sizeof (struct section_id_list_t)); -++ BFD_ASSERT (result); /* feed me */ -++ result->id = id; -++ *lst_ptr = result; -++ } -++ else -+ { -+- irel_ptr = ptr->irel_head; -+- if (ptr->h == NULL) -++ struct section_id_list_t *cur = lst; -++ struct section_id_list_t *prv = NULL; -++ struct section_id_list_t *sec = NULL; -++ while (cur) -+ { -+- /* Local symbol. */ -+- irel_keeper = irel_ptr; -+- while (irel_ptr && irel_ptr->next) -++ if (cur->id < id) -+ { -+- /* Check there is jump target can be used. */ -+- if ((irel_ptr->next->irel->r_offset -+- - irel_keeper->irel->r_offset) > 1022) -+- irel_keeper = irel_ptr->next; -+- else -+- { -+- ptr->enable = 1; -+- irel_ptr->keep = 0; -+- } -+- irel_ptr = irel_ptr->next; -++ prv = cur; -++ cur = cur->next; -++ continue; -+ } -+- } -+- else -+- { -+- /* Global symbol. */ -+- /* We have to get the absolute address and decide -+- whether to keep it or not. */ -+- while (irel_ptr) -++ -++ if (cur->id > id) -+ { -+- address = (irel_ptr->irel->r_offset -+- + irel_ptr->sec->output_section->vma -+- + irel_ptr->sec->output_offset); -+- irel_ptr->addr = address; -+- irel_ptr = irel_ptr->next; -++ cur = NULL; /* to insert after prv */ -++ sec = cur; /* in case prv == NULL */ -+ } -+ -+- irel_ptr = ptr->irel_head; -+- while (irel_ptr) -+- { -+- /* Sort by address. */ -+- struct elf_nds32_ifc_irel_list *irel_dest = irel_ptr; -+- struct elf_nds32_ifc_irel_list *irel_temp = irel_ptr; -+- struct elf_nds32_ifc_irel_list *irel_ptr_prev = NULL; -+- struct elf_nds32_ifc_irel_list *irel_dest_prev = NULL; -+- -+- /* Get the smallest one. */ -+- while (irel_temp->next) -+- { -+- if (irel_temp->next->addr < irel_dest->addr) -+- { -+- irel_dest_prev = irel_temp; -+- irel_dest = irel_temp->next; -+- } -+- irel_temp = irel_temp->next; -+- } -++ break; -++ } -+ -+- if (irel_dest != irel_ptr) -+- { -+- if (irel_ptr_prev) -+- irel_ptr_prev->next = irel_dest; -+- if (irel_dest_prev) -+- irel_dest_prev->next = irel_ptr; -+- irel_temp = irel_ptr->next; -+- irel_ptr->next = irel_dest->next; -+- irel_dest->next = irel_temp; -+- } -+- irel_ptr_prev = irel_ptr; -+- irel_ptr = irel_ptr->next; -++ if (NULL == cur) -++ { -++ /* insert after prv */ -++ result = (struct section_id_list_t *) calloc ( -++ 1, sizeof (struct section_id_list_t)); -++ BFD_ASSERT (result); /* feed me */ -++ result->id = id; -++ if (NULL != prv) -++ { -++ result->next = prv->next; -++ prv->next = result; -+ } -+- -+- irel_ptr = ptr->irel_head; -+- irel_keeper = irel_ptr; -+- while (irel_ptr && irel_ptr->next) -++ else -+ { -+- if ((irel_ptr->next->addr - irel_keeper->addr) > 1022) -+- irel_keeper = irel_ptr->next; -+- else -+- { -+- ptr->enable = 1; -+- irel_ptr->keep = 0; -+- } -+- irel_ptr = irel_ptr->next; -++ *lst_ptr = result; -++ result->next = sec; -+ } -+ } -+- -+- /* Ex9 enable. Reserve it for ex9. */ -+- if ((target_optimize & NDS32_RELAX_EX9_ON) -+- && ptr->irel_head != irel_keeper) -+- ptr->enable = 0; -+- ptr = ptr->next; -+ } -+-} -+ -+-/* Determine whether j and jal should be substituted after ex9 done. */ -++ return result; -++} -+ -+-static void -+-nds32_elf_ifc_filter_after_ex9 (void) -++int -++elf32_nds32_unify_relax_group (bfd *abfd, asection *asec) -+ { -+- struct elf_nds32_ifc_symbol_entry *ptr = ifc_symbol_head; -+- struct elf_nds32_ifc_irel_list *irel_ptr = NULL; -++ static int next_relax_group_bias = 0; -+ -+- while (ptr) -++ elf32_nds32_relax_group_t *relax_group_ptr = -++ elf32_nds32_relax_group_ptr (abfd); -++ -++ bfd_boolean result = TRUE; -++ Elf_Internal_Rela *rel; -++ Elf_Internal_Rela *relend; -++ Elf_Internal_Rela *relocs = NULL; -++ enum elf_nds32_reloc_type rtype; -++ struct section_id_list_t *node = NULL; -++ int count = 0; -++ -++ do -+ { -+- if (ptr->enable == 0) -++ if (0 == relax_group_ptr->count) -++ break; -++ -++ /* check if this section has handled */ -++ node = elf32_nds32_lookup_section_id (asec->id, &relax_group_section_id_list); -++ if (NULL == node) -++ break; /* hit, the section id has handled. */ -++ -++ /* Relocations MUST be kept in memory, because relaxation adjust them. */ -++ relocs = _bfd_elf_link_read_relocs (abfd, asec, NULL, NULL, -++ TRUE /* keep_memory */); -++ if (relocs == NULL) -+ { -+- /* Check whether ifc is applied or not. */ -+- irel_ptr = ptr->irel_head; -+- ptr->ex9_enable = 1; -+- while (irel_ptr) -+- { -+- if (ELF32_R_TYPE (irel_ptr->irel->r_info) == R_NDS32_TRAN) -+- { -+- /* Ex9 already. */ -+- ptr->ex9_enable = 0; -+- break; -+- } -+- irel_ptr = irel_ptr->next; -+- } -++ BFD_ASSERT (0); /* feed me */ -++ break; -+ } -+- ptr = ptr->next; -+- } -+-} -+- -+-/* Wrapper to do ifc relaxation. */ -+ -+-bfd_boolean -+-nds32_elf_ifc_finish (struct bfd_link_info *info) -+-{ -+- int relax_status; -+- struct elf_nds32_link_hash_table *table; -++ /* allocate group id bias for this bfd! */ -++ if (0 == relax_group_ptr->init) -++ { -++ relax_group_ptr->bias = next_relax_group_bias; -++ next_relax_group_bias += relax_group_ptr->count; -++ relax_group_ptr->init = 1; -++ } -+ -+- table = nds32_elf_hash_table (info); -+- relax_status = table->relax_status; -++ /* reorder relax group groups */ -++ relend = relocs + asec->reloc_count; -++ for (rel = relocs; rel < relend; rel++) -++ { -++ rtype = ELF32_R_TYPE(rel->r_info); -++ if (rtype != R_NDS32_RELAX_GROUP) -++ continue; -+ -+- if (!(relax_status & NDS32_RELAX_JUMP_IFC_DONE)) -+- nds32_elf_ifc_filter (info); -+- else -+- nds32_elf_ifc_filter_after_ex9 (); -++ /* change it */ -++ rel->r_addend += relax_group_ptr->bias; -++ /* debugging count */ -++ count++; -++ } -++ } -++ while (FALSE); -+ -+- if (!nds32_elf_ifc_replace (info)) -+- return FALSE; -++ if (relocs != NULL && elf_section_data (asec)->relocs != relocs) -++ free (relocs); -+ -+- if (table) -+- table->relax_status |= NDS32_RELAX_JUMP_IFC_DONE; -+- return TRUE; -++ return result; -+ } -+ -+-/* Traverse the result of ifc filter and replace it with ifcall9. */ -+- -+-static bfd_boolean -+-nds32_elf_ifc_replace (struct bfd_link_info *info) -++int -++nds32_elf_unify_tls_model (bfd *inbfd, asection *insec, bfd_byte *incontents, -++ struct bfd_link_info *lnkinfo) -+ { -+- struct elf_nds32_ifc_symbol_entry *ptr = ifc_symbol_head; -+- struct elf_nds32_ifc_irel_list *irel_ptr = NULL; -+- nds32_elf_blank_t *relax_blank_list = NULL; -+- bfd_byte *contents = NULL; -+- Elf_Internal_Rela *internal_relocs; -++ bfd_boolean result = TRUE; -+ Elf_Internal_Rela *irel; -+ Elf_Internal_Rela *irelend; -+- unsigned short insn16 = INSN_IFCALL9; -+- struct elf_nds32_link_hash_table *table; -+- int relax_status; -++ Elf_Internal_Rela *internal_relocs; -++ unsigned long r_symndx; -++ enum elf_nds32_reloc_type r_type; -+ -+- table = nds32_elf_hash_table (info); -+- relax_status = table->relax_status; -++ Elf_Internal_Sym *local_syms = NULL; -++ bfd_byte *contents = NULL; -++ -++ relax_group_list_t chain = { .id = -1, .next = NULL, .next_sibling = NULL }; -++ -++ Elf_Internal_Shdr *symtab_hdr = &elf_tdata (inbfd)->symtab_hdr; -++ struct elf_link_hash_entry **sym_hashes, **sym_hashes_end; -++ sym_hashes = elf_sym_hashes (inbfd); -++ sym_hashes_end = -++ sym_hashes + symtab_hdr->sh_size / sizeof (Elf32_External_Sym); -++ if (!elf_bad_symtab (inbfd)) -++ sym_hashes_end -= symtab_hdr->sh_info; -++ -++ /* reorder RELAX_GROUP when command line option '-r' is applied */ -++ if (bfd_link_relocatable (lnkinfo)) -++ { -++ elf32_nds32_unify_relax_group (inbfd, insec); -++ /* goto finish; */ -++ return result; -++ } -++ -++ /* Relocations MUST be kept in memory, because relaxation adjust them. */ -++ internal_relocs = _bfd_elf_link_read_relocs (inbfd, insec, NULL, NULL, -++ TRUE /* keep_memory */); -++ if (internal_relocs == NULL) -++ goto error_return; -++ -++ irelend = internal_relocs + insec->reloc_count; -++ irel = find_relocs_at_address (internal_relocs, internal_relocs, -++ irelend, R_NDS32_RELAX_ENTRY); -++ if (irel == irelend) -++ goto finish; -++ -++ /* chain/remove groups */ -++ for (irel = internal_relocs; irel < irelend; irel++) -++ { -++ r_symndx = ELF32_R_SYM (irel->r_info); -++ r_type = ELF32_R_TYPE (irel->r_info); -++ if (r_type != R_NDS32_RELAX_GROUP) -++ continue; -++ -++ /* remove it */ -++ irel->r_info = ELF32_R_INFO (r_symndx, R_NDS32_NONE); -++ /* chain it now */ -++ if (!list_insert (&chain, irel)) -++ goto error_return; -++ } -+ -+- while (ptr) -++ /* collect group relocations */ -++ /* presume relocations are sorted */ -++ relax_group_list_t *pNext = chain.next; -++ while (pNext) -+ { -+- /* Traverse the ifc gather list, and replace the -+- filter entries by ifcall9. */ -+- if ((!(relax_status & NDS32_RELAX_JUMP_IFC_DONE) && ptr->enable == 1) -+- || ((relax_status & NDS32_RELAX_JUMP_IFC_DONE) -+- && ptr->ex9_enable == 1)) -++ for (irel = internal_relocs; irel < irelend; irel++) -+ { -+- irel_ptr = ptr->irel_head; -+- if (ptr->h == NULL) -++ if (irel->r_offset == pNext->relo->r_offset) -+ { -+- /* Local symbol. */ -+- internal_relocs = _bfd_elf_link_read_relocs -+- (ptr->sec->owner, ptr->sec, NULL, NULL, TRUE /* keep_memory */); -+- irelend = internal_relocs + ptr->sec->reloc_count; -+- -+- if (!nds32_get_section_contents (ptr->sec->owner, ptr->sec, -+- &contents, TRUE)) -+- return FALSE; -++ /* ignore Non-TLS relocation types */ -++ r_type = ELF32_R_TYPE (irel->r_info); -++ if ((R_NDS32_TLS_LE_HI20 > r_type) -++ || (R_NDS32_RELAX_ENTRY == r_type)) -++ continue; -+ -+- while (irel_ptr) -+- { -+- if (irel_ptr->keep == 0 && irel_ptr->next) -+- { -+- /* The one can be replaced. We have to check whether -+- there is any alignment point in the region. */ -+- irel = irel_ptr->irel; -+- while (((irel_ptr->next->keep == 0 -+- && irel < irel_ptr->next->irel) -+- || (irel_ptr->next->keep == 1 && irel < irelend)) -+- && !(ELF32_R_TYPE (irel->r_info) == R_NDS32_LABEL -+- && (irel->r_addend & 0x1f) == 2)) -+- irel++; -+- if (irel >= irelend -+- || !(ELF32_R_TYPE (irel->r_info) == R_NDS32_LABEL -+- && (irel->r_addend & 0x1f) == 2 -+- && ((irel->r_offset - get_nds32_elf_blank_total -+- (&relax_blank_list, irel->r_offset, 1)) -+- & 0x02) == 0)) -+- { -+- /* Replace by ifcall9. */ -+- bfd_putb16 (insn16, contents + irel_ptr->irel->r_offset); -+- if (!insert_nds32_elf_blank_recalc_total -+- (&relax_blank_list, irel_ptr->irel->r_offset + 2, 2)) -+- return FALSE; -+- irel_ptr->irel->r_info = -+- ELF32_R_INFO (ELF32_R_SYM (irel_ptr->irel->r_info), -+- R_NDS32_10IFCU_PCREL_RELA); -+- } -+- } -+- irel_ptr = irel_ptr->next; -+- } -++ if (!list_insert_sibling (pNext, irel)) -++ goto error_return; -++ } -++ else if (irel->r_offset > pNext->relo->r_offset) -++ { -++ pNext = pNext->next; -++ if (!pNext) -++ break; -+ -+- /* Delete the redundant code. */ -+- if (relax_blank_list) -+- { -+- nds32_elf_relax_delete_blanks (ptr->sec->owner, ptr->sec, -+- relax_blank_list); -+- relax_blank_list = NULL; -+- } -++ bfd_vma current_offset = pNext->relo->r_offset; -++ if (irel->r_offset > current_offset) -++ irel = internal_relocs; /* restart from head */ -++ else -++ --irel; /* check current irel again */ -++ continue; -+ } -+ else -+ { -+- /* Global symbol. */ -+- while (irel_ptr) -+- { -+- if (irel_ptr->keep == 0 && irel_ptr->next) -+- { -+- /* The one can be replaced, and we have to check -+- whether there is any alignment point in the region. */ -+- internal_relocs = _bfd_elf_link_read_relocs -+- (irel_ptr->sec->owner, irel_ptr->sec, NULL, NULL, -+- TRUE /* keep_memory */); -+- irelend = internal_relocs + irel_ptr->sec->reloc_count; -+- if (!nds32_get_section_contents (irel_ptr->sec->owner, -+- irel_ptr->sec, &contents, -+- TRUE)) -+- return FALSE; -+- -+- irel = irel_ptr->irel; -+- while (((irel_ptr->sec == irel_ptr->next->sec -+- && irel_ptr->next->keep == 0 -+- && irel < irel_ptr->next->irel) -+- || ((irel_ptr->sec != irel_ptr->next->sec -+- || irel_ptr->next->keep == 1) -+- && irel < irelend)) -+- && !(ELF32_R_TYPE (irel->r_info) == R_NDS32_LABEL -+- && (irel->r_addend & 0x1f) == 2)) -+- irel++; -+- if (irel >= irelend -+- || !(ELF32_R_TYPE (irel->r_info) == R_NDS32_LABEL -+- && (irel->r_addend & 0x1f) == 2 -+- && ((irel->r_offset -+- - get_nds32_elf_blank_total (&relax_blank_list, -+- irel->r_offset, 1)) & 0x02) == 0)) -+- { -+- /* Replace by ifcall9. */ -+- bfd_putb16 (insn16, contents + irel_ptr->irel->r_offset); -+- if (!insert_nds32_elf_blank_recalc_total -+- (&relax_blank_list, irel_ptr->irel->r_offset + 2, 2)) -+- return FALSE; -+- -+- /* Delete the redundant code, and clear the relocation. */ -+- nds32_elf_relax_delete_blanks (irel_ptr->sec->owner, -+- irel_ptr->sec, -+- relax_blank_list); -+- irel_ptr->irel->r_info = -+- ELF32_R_INFO (ELF32_R_SYM (irel_ptr->irel->r_info), -+- R_NDS32_10IFCU_PCREL_RELA); -+- relax_blank_list = NULL; -+- } -+- } -+- -+- irel_ptr = irel_ptr->next; -+- } -++ //printf("irel->off = 0x%08x, pNext->relo->off = 0x%08x (0x%08x)\n", (unsigned)irel->r_offset, (unsigned)pNext->relo->r_offset, (unsigned)first_offset); -+ } -+ } -+- ptr = ptr->next; -++ if (pNext) -++ pNext = pNext->next; -+ } -+ -+- return TRUE; -+-} -+- -+-/* Relocate ifcall. */ -+- -+-static bfd_boolean -+-nds32_elf_ifc_reloc (void) -+-{ -+- struct elf_nds32_ifc_symbol_entry *ptr = ifc_symbol_head; -+- struct elf_nds32_ifc_irel_list *irel_ptr = NULL; -+- struct elf_nds32_ifc_irel_list *irel_keeper = NULL; -+- bfd_vma relocation, address; -+- unsigned short insn16; -+- bfd_byte *contents = NULL; -+- static bfd_boolean done = FALSE; -++#ifdef DUBUG_VERBOSE -++ dump_chain(&chain); -++#endif -+ -+- if (done) -+- return TRUE; -++ /* Get symbol table and section content. */ -++ if (incontents) -++ contents = incontents; -++ else if (!nds32_get_section_contents (inbfd, insec, &contents, TRUE) -++ || !nds32_get_local_syms (inbfd, insec, &local_syms)) -++ goto error_return; -+ -+- done = TRUE; -++ char *local_got_tls_type = elf32_nds32_local_got_tls_type (inbfd); -+ -+- while (ptr) -++ /* convert TLS model each group if necessary */ -++ pNext = chain.next; -++ int cur_grp_id = -1; -++ int sethi_rt = -1; -++ int add_rt = -1; -++ enum elf_nds32_tls_type tls_type, org_tls_type, eff_tls_type; -++ tls_type = org_tls_type = eff_tls_type = 0; -++ while (pNext) -+ { -+- /* Check the entry is enable ifcall. */ -+- if (ptr->enable == 1 || ptr->ex9_enable == 1) -++ relax_group_list_t *pNextSig = pNext->next_sibling; -++ while (pNextSig) -+ { -+- /* Get the reserve jump. */ -+- irel_ptr = ptr->irel_head; -+- while (irel_ptr) -++ struct elf_link_hash_entry *h = NULL; -++ irel = pNextSig->relo; -++ r_symndx = ELF32_R_SYM(irel->r_info); -++ r_type = ELF32_R_TYPE(irel->r_info); -++ -++ if (pNext->id != cur_grp_id) -+ { -+- if (irel_ptr->keep == 1) -++ cur_grp_id = pNext->id; -++ org_tls_type = get_tls_type (r_type, NULL); -++ if (r_symndx >= symtab_hdr->sh_info) -+ { -+- irel_keeper = irel_ptr; -+- break; -++ h = sym_hashes[r_symndx - symtab_hdr->sh_info]; -++ while (h->root.type == bfd_link_hash_indirect -++ || h->root.type == bfd_link_hash_warning) -++ h = (struct elf_link_hash_entry *) h->root.u.i.link; -++ tls_type = ((struct elf_nds32_link_hash_entry *) h)->tls_type; -++ } -++ else -++ { -++ /* TODO: find local symbol hash if necessary? */ -++ tls_type = local_got_tls_type ? local_got_tls_type[r_symndx] : GOT_NORMAL; -+ } -+- irel_ptr = irel_ptr->next; -++ -++ eff_tls_type = 1 << (fls (tls_type) - 1); -++ sethi_rt = N32_RT5(bfd_getb32 (contents + irel->r_offset)); -+ } -+ -+- irel_ptr = ptr->irel_head; -+- if (ptr->h == NULL) -++ if (eff_tls_type != org_tls_type) -+ { -+- /* Local symbol. */ -+- if (!nds32_get_section_contents (ptr->sec->owner, ptr->sec, -+- &contents, TRUE)) -+- return FALSE; -+- -+- while (irel_ptr) -++ switch (org_tls_type) -+ { -+- if (irel_ptr->keep == 0 -+- && ELF32_R_TYPE (irel_ptr->irel->r_info) == R_NDS32_10IFCU_PCREL_RELA) -++ /* DESC to IEGP/IE/LE. */ -++ case GOT_TLS_DESC: -++ switch (eff_tls_type) -+ { -+- relocation = irel_keeper->irel->r_offset; -+- relocation = relocation - irel_ptr->irel->r_offset; -+- while (irel_keeper && relocation > 1022) -++ case GOT_TLS_IE: -++ switch (r_type) -+ { -+- irel_keeper = irel_keeper->next; -+- if (irel_keeper && irel_keeper->keep == 1) -+- { -+- relocation = irel_keeper->irel->r_offset; -+- relocation = relocation - irel_ptr->irel->r_offset; -+- } -++ case R_NDS32_TLS_DESC_HI20: -++ irel->r_info = ELF32_R_INFO(r_symndx, -++ R_NDS32_TLS_IE_HI20); -++ break; -++ case R_NDS32_TLS_DESC_LO12: -++ irel->r_info = ELF32_R_INFO(r_symndx, -++ R_NDS32_TLS_IE_LO12); -++ break; -++ case R_NDS32_TLS_DESC_ADD: -++ { -++ uint32_t insn = bfd_getb32 ( -++ contents + irel->r_offset); -++ add_rt = N32_RT5 (insn); -++ insn = N32_TYPE2 (LWI, add_rt, sethi_rt, 0); -++ bfd_putb32 (insn, contents + irel->r_offset); -++ -++ irel->r_info = ELF32_R_INFO(r_symndx, R_NDS32_NONE); -++/* irel->r_info = ELF32_R_INFO (r_symndx, R_NDS32_TLS_IE_LW); -++*/ -++ } -++ break; -++ case R_NDS32_TLS_DESC_FUNC: -++ bfd_putb32 (INSN_NOP, contents + irel->r_offset); -++ irel->r_info = ELF32_R_INFO(r_symndx, -++ R_NDS32_RELAX_REMOVE); -++ break; -++ case R_NDS32_TLS_DESC_CALL: -++ { -++ uint32_t insn = N32_ALU1(ADD, REG_R0, add_rt, -++ REG_TP); -++ bfd_putb32 (insn, contents + irel->r_offset); -++ -++ irel->r_info = ELF32_R_INFO(r_symndx, R_NDS32_NONE); -++ } -++ break; -++ case R_NDS32_LOADSTORE: -++ case R_NDS32_PTR: -++ case R_NDS32_PTR_RESOLVED: -++ case R_NDS32_NONE: -++ case R_NDS32_LABEL: -++ break; -++ default: -++ BFD_ASSERT(0); -++ break; -+ } -+- if (relocation > 1022) -++ break; -++ case GOT_TLS_IEGP: -++ switch (r_type) -+ { -+- /* Double check. */ -+- irel_keeper = ptr->irel_head; -+- while (irel_keeper) -+- { -+- if (irel_keeper->keep == 1) -+- { -+- relocation = irel_keeper->irel->r_offset; -+- relocation = relocation - irel_ptr->irel->r_offset; -+- } -+- if (relocation <= 1022) -+- break; -+- irel_keeper = irel_keeper->next; -+- } -+- if (!irel_keeper) -+- return FALSE; -++ case R_NDS32_TLS_DESC_HI20: -++ irel->r_info = ELF32_R_INFO(r_symndx, -++ R_NDS32_TLS_IEGP_HI20); -++ break; -++ case R_NDS32_TLS_DESC_LO12: -++ irel->r_info = ELF32_R_INFO(r_symndx, -++ R_NDS32_TLS_IEGP_LO12); -++ break; -++ case R_NDS32_TLS_DESC_ADD: -++ { -++ uint32_t insn = bfd_getb32 ( -++ contents + irel->r_offset); -++ add_rt = N32_RT5 (insn); -++ insn = N32_MEM(LW, add_rt, sethi_rt, REG_GP, 0); -++ bfd_putb32 (insn, contents + irel->r_offset); -++ -++ irel->r_info = ELF32_R_INFO(r_symndx, R_NDS32_NONE); -++/* irel->r_info = ELF32_R_INFO (r_symndx, R_NDS32_TLS_IEGP_LW); -++*/ -++ } -++ break; -++ case R_NDS32_TLS_DESC_FUNC: -++ bfd_putb32 (INSN_NOP, contents + irel->r_offset); -++ irel->r_info = ELF32_R_INFO(r_symndx, -++ R_NDS32_RELAX_REMOVE); -++ break; -++ case R_NDS32_TLS_DESC_CALL: -++ { -++ uint32_t insn = N32_ALU1(ADD, REG_R0, add_rt, -++ REG_TP); -++ bfd_putb32 (insn, contents + irel->r_offset); -++ -++ irel->r_info = ELF32_R_INFO(r_symndx, R_NDS32_NONE); -++ } -++ break; -++ case R_NDS32_LOADSTORE: -++ case R_NDS32_PTR: -++ case R_NDS32_PTR_RESOLVED: -++ case R_NDS32_NONE: -++ case R_NDS32_LABEL: -++ break; -++ default: -++ BFD_ASSERT(0); -++ break; -+ } -+- irel_ptr->irel->r_info = -+- ELF32_R_INFO (ELF32_R_SYM (irel_ptr->irel->r_info), -+- R_NDS32_NONE); -+- insn16 = INSN_IFCALL9 | (relocation >> 1); -+- bfd_putb16 (insn16, contents + irel_ptr->irel->r_offset); -++ break; -++ case GOT_TLS_LE: -++ switch (r_type) -++ { -++ case R_NDS32_TLS_DESC_HI20: -++ irel->r_info = ELF32_R_INFO (r_symndx, R_NDS32_TLS_LE_HI20); -++ break; -++ case R_NDS32_TLS_DESC_LO12: -++ irel->r_info = ELF32_R_INFO (r_symndx, R_NDS32_TLS_LE_LO12); -++ break; -++ case R_NDS32_TLS_DESC_ADD: -++ { -++ uint32_t insn = bfd_getb32 (contents + irel->r_offset); -++ add_rt = N32_RT5 (insn); -++ insn = N32_ALU1 (ADD, REG_R0, sethi_rt, REG_TP); -++ bfd_putb32 (insn, contents + irel->r_offset); -++ -++ irel->r_info = ELF32_R_INFO (r_symndx, R_NDS32_TLS_LE_ADD); -++ } -++ break; -++ case R_NDS32_TLS_DESC_FUNC: -++ bfd_putb32 (INSN_NOP, contents + irel->r_offset); -++ irel->r_info = ELF32_R_INFO (r_symndx, R_NDS32_RELAX_REMOVE); -++ break; -++ case R_NDS32_TLS_DESC_CALL: -++ bfd_putb32 (INSN_NOP, contents + irel->r_offset); -++ irel->r_info = ELF32_R_INFO (r_symndx, R_NDS32_RELAX_REMOVE); -++ break; -++ case R_NDS32_LOADSTORE: -++ case R_NDS32_PTR: -++ case R_NDS32_PTR_RESOLVED: -++ case R_NDS32_NONE: -++ case R_NDS32_LABEL: -++ break; -++ default: -++ BFD_ASSERT(0); -++ break; -++ } -++ break; -++ default: -++#ifdef DEBUG_VERBOSE -++ printf ( -++ "SKIP: %s: %s @ 0x%08x tls_type = 0x%08x, eff_tls_type = 0x%08x, org_tls_type = 0x%08x\n", -++ inbfd->filename, h ? h->root.root.string : "local", -++ (unsigned) irel->r_offset, tls_type, eff_tls_type, -++ org_tls_type); -++#endif -++ break; -+ } -+- irel_ptr = irel_ptr->next; -+- } -+- } -+- else -+- { -+- /* Global symbol. */ -+- while (irel_ptr) -+- { -+- if (irel_ptr->keep == 0 -+- && ELF32_R_TYPE (irel_ptr->irel->r_info) == R_NDS32_10IFCU_PCREL_RELA) -++ break; -++ /* IEGP to IE/LE. */ -++ case GOT_TLS_IEGP: -++ switch (eff_tls_type) -+ { -+- /* Get the distance between ifcall and jump. */ -+- relocation = (irel_keeper->irel->r_offset -+- + irel_keeper->sec->output_section->vma -+- + irel_keeper->sec->output_offset); -+- address = (irel_ptr->irel->r_offset -+- + irel_ptr->sec->output_section->vma -+- + irel_ptr->sec->output_offset); -+- relocation = relocation - address; -+- -+- /* The distance is over ragne, find callee again. */ -+- while (irel_keeper && relocation > 1022) -++ case GOT_TLS_IE: -++ switch (r_type) -+ { -+- irel_keeper = irel_keeper->next; -+- if (irel_keeper && irel_keeper->keep ==1) -+- { -+- relocation = (irel_keeper->irel->r_offset -+- + irel_keeper->sec->output_section->vma -+- + irel_keeper->sec->output_offset); -+- relocation = relocation - address; -+- } -++ case R_NDS32_TLS_IEGP_HI20: -++ irel->r_info = ELF32_R_INFO(r_symndx, -++ R_NDS32_TLS_IE_HI20); -++ break; -++ case R_NDS32_TLS_IEGP_LO12: -++ irel->r_info = ELF32_R_INFO(r_symndx, -++ R_NDS32_TLS_IE_LO12); -++ break; -++ case R_NDS32_PTR_RESOLVED: -++ { -++ uint32_t insn = bfd_getb32 ( -++ contents + irel->r_offset); -++ add_rt = N32_RT5 (insn); -++ insn = N32_TYPE2 (LWI, add_rt, sethi_rt, 0); -++ bfd_putb32 (insn, contents + irel->r_offset); -++ } -++ break; -++ case R_NDS32_TLS_IEGP_LW: -++ break; -++ case R_NDS32_LOADSTORE: -++ case R_NDS32_PTR: -++ case R_NDS32_NONE: -++ case R_NDS32_LABEL: -++ break; -++ default: -++ BFD_ASSERT(0); -++ break; -+ } -+- -+- if (relocation > 1022) -++ break; -++ case GOT_TLS_LE: -++ switch (r_type) -+ { -+- /* Double check. */ -+- irel_keeper = ptr->irel_head; -+- while (irel_keeper) -+- { -+- if (irel_keeper->keep == 1) -+- { -+- -+- relocation = (irel_keeper->irel->r_offset -+- + irel_keeper->sec->output_section->vma -+- + irel_keeper->sec->output_offset); -+- relocation = relocation - address; -+- } -+- if (relocation <= 1022) -+- break; -+- irel_keeper = irel_keeper->next; -+- } -+- if (!irel_keeper) -+- return FALSE; -++ case R_NDS32_TLS_IEGP_HI20: -++ irel->r_info = ELF32_R_INFO (r_symndx, R_NDS32_TLS_LE_HI20); -++ break; -++ case R_NDS32_TLS_IEGP_LO12: -++ irel->r_info = ELF32_R_INFO (r_symndx, R_NDS32_TLS_LE_LO12); -++ break; -++ case R_NDS32_TLS_IEGP_LW: -++ /* irel->r_info = ELF32_R_INFO(r_symndx, R_NDS32_TLS_LE_ADD); */ -++ bfd_putb32 (INSN_NOP, contents + irel->r_offset); -++ irel->r_info = ELF32_R_INFO (r_symndx, R_NDS32_RELAX_REMOVE); -++ break; -++ case R_NDS32_LOADSTORE: -++ case R_NDS32_PTR: -++ case R_NDS32_NONE: -++ case R_NDS32_LABEL: -++ case R_NDS32_PTR_RESOLVED: -++ break; -++ default: -++ BFD_ASSERT(0); -++ break; -+ } -+- if (!nds32_get_section_contents -+- (irel_ptr->sec->owner, irel_ptr->sec, &contents, TRUE)) -+- return FALSE; -+- insn16 = INSN_IFCALL9 | (relocation >> 1); -+- bfd_putb16 (insn16, contents + irel_ptr->irel->r_offset); -+- irel_ptr->irel->r_info = -+- ELF32_R_INFO (ELF32_R_SYM (irel_ptr->irel->r_info), -+- R_NDS32_NONE); -++ break; -++ default: -++#ifdef DEBUG_VERBOSE -++ printf ( -++ "SKIP: %s: %s @ 0x%08x tls_type = 0x%08x, eff_tls_type = 0x%08x, org_tls_type = 0x%08x\n", -++ inbfd->filename, h ? h->root.root.string : "local", -++ (unsigned) irel->r_offset, tls_type, eff_tls_type, -++ org_tls_type); -++#endif -++ break; -++ } -++ break; -++ /* IE to LE. */ -++ case GOT_TLS_IE: -++ switch (eff_tls_type) -++ { -++ case GOT_TLS_LE: -++ switch (r_type) -++ { -++ case R_NDS32_TLS_IE_HI20: -++ irel->r_info = ELF32_R_INFO (r_symndx, R_NDS32_TLS_LE_HI20); -++ break; -++ case R_NDS32_TLS_IE_LO12S2: -++ { -++ uint32_t insn = bfd_getb32 (contents + irel->r_offset); -++ add_rt = N32_RT5 (insn); -++ insn = N32_TYPE2 (ORI, add_rt, sethi_rt, 0); -++ bfd_putb32 (insn, contents + irel->r_offset); -++ -++ irel->r_info = ELF32_R_INFO (r_symndx, R_NDS32_TLS_LE_LO12); -++ } -++ break; -++ /* -++ case R_NDS32_TLS_IE_ADD: -++ irel->r_info = ELF32_R_INFO (r_symndx, R_NDS32_TLS_LE_ADD); -++ break; -++ */ -++ case R_NDS32_LOADSTORE: -++ case R_NDS32_PTR: -++ case R_NDS32_NONE: -++ case R_NDS32_LABEL: -++ break; -++ default: -++ BFD_ASSERT(0); -++ break; -++ } -++ break; -++ default: -++#ifdef DEBUG_VERBOSE -++ printf ( -++ "SKIP: %s: %s @ 0x%08x tls_type = 0x%08x, eff_tls_type = 0x%08x, org_tls_type = 0x%08x\n", -++ inbfd->filename, h ? h->root.root.string : "local", -++ (unsigned) irel->r_offset, tls_type, eff_tls_type, -++ org_tls_type); -++#endif -++ break; -+ } -+- irel_ptr =irel_ptr->next; -++ break; -++ default: -++#ifdef DEBUG_VERBOSE -++ printf ( -++ "SKIP: %s: %s @ 0x%08x tls_type = 0x%08x, eff_tls_type = 0x%08x, org_tls_type = 0x%08x\n", -++ inbfd->filename, h ? h->root.root.string : "local", -++ (unsigned) irel->r_offset, tls_type, eff_tls_type, -++ org_tls_type); -++#endif -++ break; -+ } -+ } -++ pNextSig = pNextSig->next_sibling; -+ } -+- ptr = ptr->next; -+- } -+- -+- return TRUE; -+-} -+ -+-/* End of IFC relaxation. */ -+- -+-/* EX9 Instruction Table Relaxation. */ -++#if 1 -++ pNext = pNext->next; -++#else -++ while (pNext) -++ { -++ if (pNext->id != cur_grp_id) -++ break; -++ pNext = pNext->next; -++ } -++#endif -++ } -+ -+-/* Global hash list. */ -+-struct elf_link_hash_entry_list -+-{ -+- struct elf_link_hash_entry *h; -+- struct elf_link_hash_entry_list *next; -+-}; -++finish: -++ if (incontents) -++ contents = NULL; -+ -+-/* Save different destination but same insn. */ -+-struct elf_link_hash_entry_mul_list -+-{ -+- /* Global symbol times. */ -+- int times; -+- /* Save relocation for each global symbol but useful?? */ -+- Elf_Internal_Rela *irel; -+- /* For sethi, two sethi may have the same high-part but different low-parts. */ -+- Elf_Internal_Rela rel_backup; -+- struct elf_link_hash_entry_list *h_list; -+- struct elf_link_hash_entry_mul_list *next; -+-}; -++ if (internal_relocs != NULL -++ && elf_section_data (insec)->relocs != internal_relocs) -++ free (internal_relocs); -+ -+-/* Instruction hash table. */ -+-struct elf_nds32_code_hash_entry -+-{ -+- struct bfd_hash_entry root; -+- int times; -+- /* For insn that can use relocation or constant ex: sethi. */ -+- int const_insn; -+- asection *sec; -+- struct elf_link_hash_entry_mul_list *m_list; -+- /* Using r_addend. */ -+- Elf_Internal_Rela *irel; -+- /* Using r_info. */ -+- Elf_Internal_Rela rel_backup; -+-}; -++ if (contents != NULL -++ && elf_section_data (insec)->this_hdr.contents != contents) -++ free (contents); -+ -+-/* Instruction count list. */ -+-struct elf_nds32_insn_times_entry -+-{ -+- const char *string; -+- int times; -+- int order; -+- asection *sec; -+- struct elf_link_hash_entry_mul_list *m_list; -+- Elf_Internal_Rela *irel; -+- Elf_Internal_Rela rel_backup; -+- struct elf_nds32_insn_times_entry *next; -+-}; -++ if (local_syms != NULL && symtab_hdr->contents != (bfd_byte *) local_syms) -++ free (local_syms); -+ -+-/* J and JAL symbol list. */ -+-struct elf_nds32_symbol_entry -+-{ -+- char *string; -+- unsigned long insn; -+- struct elf_nds32_symbol_entry *next; -+-}; -++ if (chain.next) -++ { -++ pNext = chain.next; -++ relax_group_list_t *pDel; -++ while (pNext) -++ { -++ pDel = pNext; -++ pNext = pNext->next; -++ free (pDel); -++ } -++ } -+ -+-/* Relocation list. */ -+-struct elf_nds32_irel_entry -+-{ -+- Elf_Internal_Rela *irel; -+- struct elf_nds32_irel_entry *next; -+-}; -++ return result; -+ -+-/* ex9.it insn need to be fixed. */ -+-struct elf_nds32_ex9_refix -+-{ -+- Elf_Internal_Rela *irel; -+- asection *sec; -+- struct elf_link_hash_entry *h; -+- int order; -+- struct elf_nds32_ex9_refix *next; -+-}; -++error_return: -++ result = FALSE; -++ goto finish; -++} -+ -+-static struct bfd_hash_table ex9_code_table; -+-static struct elf_nds32_insn_times_entry *ex9_insn_head = NULL; -+-static struct elf_nds32_ex9_refix *ex9_refix_head = NULL; -++/* End TLS model conversion. */ -++ -+ -+-/* EX9 hash function. */ -++/* Rom-patch table hash function. */ -+ -+ static struct bfd_hash_entry * -+-nds32_elf_code_hash_newfunc (struct bfd_hash_entry *entry, -+- struct bfd_hash_table *table, -+- const char *string) -++nds32_elf_ict_hash_newfunc (struct bfd_hash_entry *entry, -++ struct bfd_hash_table *table, -++ const char *string) -+ { -+- struct elf_nds32_code_hash_entry *ret; -++ struct elf_nds32_ict_hash_entry *ret; -+ -+ /* Allocate the structure if it has not already been allocated by a -+ subclass. */ -+@@ -13602,1837 +15138,118 @@ nds32_elf_code_hash_newfunc (struct bfd_hash_entry *entry, -+ if (entry == NULL) -+ return entry; -+ -+- ret = (struct elf_nds32_code_hash_entry*) entry; -+- ret->times = 0; -+- ret->const_insn = 0; -+- ret->m_list = NULL; -+- ret->sec = NULL; -+- ret->irel = NULL; -++ ret = (struct elf_nds32_ict_hash_entry*) entry; -++ ret->order = 0; -+ return &ret->root; -+ } -+ -+-/* Insert ex9 entry -+- this insert must be stable sorted by times. */ -++static void -++nds32_elf_ict_hash_init (void) -++{ -++ if (!bfd_hash_table_init_n (&indirect_call_table, nds32_elf_ict_hash_newfunc, -++ sizeof (struct elf_nds32_ict_hash_entry), -++ 1023)) -++ _bfd_error_handler (_("ld error: cannot init rom patch hash table\n")); -++ return; -++} -+ -++/* Relocate for NDS32_ICT_SECTION. */ -+ static void -+-nds32_elf_ex9_insert_entry (struct elf_nds32_insn_times_entry *ptr) -++nds32_elf_ict_relocate (bfd *output_bfd, struct bfd_link_info *info) -+ { -+- struct elf_nds32_insn_times_entry *temp; -+- struct elf_nds32_insn_times_entry *temp2; -++ static bfd_boolean done = FALSE; -++ asection *sec; -++ bfd_byte *contents = NULL; -++ uint32_t insn; -++ unsigned int i; -++ struct elf_link_hash_entry *h; -++ struct bfd_link_hash_entry *h2; -++ bfd_vma relocation, base; -+ -+- if (ex9_insn_head == NULL) -+- { -+- ex9_insn_head = ptr; -+- ptr->next = NULL; -+- } -+- else -++ if (done) -++ return; -++ -++ done = TRUE; -++ -++ sec = nds32_elf_get_target_section (info, NDS32_ICT_SECTION); -++ h2 = bfd_link_hash_lookup (info->hash, "_INDIRECT_CALL_TABLE_BASE_", -++ FALSE, FALSE, FALSE); -++ base = ((h2->u.def.value -++ + h2->u.def.section->output_section->vma -++ + h2->u.def.section->output_offset)); -++ -++ if (!nds32_get_section_contents (sec->owner, sec, &contents, TRUE)) -++ return; -++ -++ indirect_call_table.frozen = 1; -++ for (i = 0; i < indirect_call_table.size; i++) -+ { -+- temp = ex9_insn_head; -+- temp2 = ex9_insn_head; -+- while (temp->next && -+- (temp->next->times >= ptr->times -+- || temp->times == -1)) -+- { -+- if (temp->times == -1) -+- temp2 = temp; -+- temp = temp->next; -+- } -+- if (ptr->times > temp->times && temp->times != -1) -++ struct bfd_hash_entry *p; -++ struct elf_nds32_ict_hash_entry *entry; -++ -++ for (p = indirect_call_table.table[i]; p != NULL; p = p->next) -+ { -+- ptr->next = temp; -+- if (temp2->times == -1) -+- temp2->next = ptr; -++ entry = (struct elf_nds32_ict_hash_entry *) p; -++ insn = INSN_J; -++ h = entry->h; -++ if ((h->root.type == bfd_link_hash_defined -++ || h->root.type == bfd_link_hash_defweak) -++ && h->root.u.def.section != NULL -++ && h->root.u.def.section->output_section != NULL) -++ { -++ if (ict_model == R_NDS32_RELAX_ENTRY_ICT_LARGE) -++ { -++ insn = h->root.u.def.value + -++ h->root.u.def.section->output_section->vma + -++ h->root.u.def.section->output_offset; -++ bfd_put_32 (output_bfd, insn, contents + (entry->order) * 4); -++ } -++ else -++ { -++ relocation = h->root.u.def.value + -++ h->root.u.def.section->output_section->vma + -++ h->root.u.def.section->output_offset; -++ insn |= ((relocation - base - entry->order * 4) >> 1) -++ & 0xffffff; -++ bfd_putb32 (insn, contents + (entry->order) * 4); -++ } -++ } -+ else -+- ex9_insn_head = ptr; -+- } -+- else if (temp->next == NULL) -+- { -+- temp->next = ptr; -+- ptr->next = NULL; -+- } -+- else -+- { -+- ptr->next = temp->next; -+- temp->next = ptr; -++ { -++ if (ict_model == R_NDS32_RELAX_ENTRY_ICT_LARGE) -++ { -++ insn = 0; -++ bfd_put_32 (output_bfd, insn, contents + (entry->order) * 4); -++ } -++ else -++ bfd_putb32 (insn, contents + (entry->order) * 4); -++ } -+ } -+ } -++ indirect_call_table.frozen = 0; -+ } -+ -+-/* Examine each insn times in hash table. -+- Handle multi-link hash entry. -+- -+- TODO: This function doesn't assign so much info since it is fake. */ -+- -+-static int -+-nds32_elf_examine_insn_times (struct elf_nds32_code_hash_entry *h) -++static asection* -++nds32_elf_get_target_section (struct bfd_link_info *info, char *name) -+ { -+- struct elf_nds32_insn_times_entry *ptr; -+- int times; -++ asection *sec = NULL; -++ bfd *abfd; -+ -+- if (h->m_list == NULL) -++ for (abfd = info->input_bfds; abfd != NULL; abfd = abfd->link.next) -+ { -+- /* Local symbol insn or insn without relocation. */ -+- if (h->times < 3) -+- return TRUE; -+- -+- ptr = (struct elf_nds32_insn_times_entry *) -+- bfd_malloc (sizeof (struct elf_nds32_insn_times_entry)); -+- ptr->times = h->times; -+- ptr->string = h->root.string; -+- ptr->m_list = NULL; -+- ptr->sec = h->sec; -+- ptr->irel = h->irel; -+- ptr->rel_backup = h->rel_backup; -+- nds32_elf_ex9_insert_entry (ptr); -++ sec = bfd_get_section_by_name (abfd, name); -++ if (sec != NULL) -++ break; -+ } -+- else -+- { -+- /* Global symbol insn. */ -+- /* Only sethi insn has multiple m_list. */ -+- struct elf_link_hash_entry_mul_list *m_list = h->m_list; -+ -+- times = 0; -+- while (m_list) -+- { -+- times += m_list->times; -+- m_list = m_list->next; -+- } -+- if (times >= 3) -+- { -+- m_list = h->m_list; -+- ptr = (struct elf_nds32_insn_times_entry *) -+- bfd_malloc (sizeof (struct elf_nds32_insn_times_entry)); -+- ptr->times = times; /* Use the total times. */ -+- ptr->string = h->root.string; -+- ptr->m_list = m_list; -+- ptr->sec = h->sec; -+- ptr->irel = m_list->irel; -+- ptr->rel_backup = m_list->rel_backup; -+- nds32_elf_ex9_insert_entry (ptr); -+- } -+- if (h->const_insn == 1) -+- { -+- /* sethi with constant value. */ -+- if (h->times < 3) -+- return TRUE; -+- -+- ptr = (struct elf_nds32_insn_times_entry *) -+- bfd_malloc (sizeof (struct elf_nds32_insn_times_entry)); -+- ptr->times = h->times; -+- ptr->string = h->root.string; -+- ptr->m_list = NULL; -+- ptr->sec = NULL; -+- ptr->irel = NULL; -+- ptr->rel_backup = h->rel_backup; -+- nds32_elf_ex9_insert_entry (ptr); -+- } -+- } -+- return TRUE; -+-} -+- -+-/* Count each insn times in hash table. -+- Handle multi-link hash entry. */ -+- -+-static int -+-nds32_elf_count_insn_times (struct elf_nds32_code_hash_entry *h) -+-{ -+- int reservation, times; -+- unsigned long relocation, min_relocation; -+- struct elf_nds32_insn_times_entry *ptr; -+- -+- if (h->m_list == NULL) -+- { -+- /* Local symbol insn or insn without relocation. */ -+- if (h->times < 3) -+- return TRUE; -+- ptr = (struct elf_nds32_insn_times_entry *) -+- bfd_malloc (sizeof (struct elf_nds32_insn_times_entry)); -+- ptr->times = h->times; -+- ptr->string = h->root.string; -+- ptr->m_list = NULL; -+- ptr->sec = h->sec; -+- ptr->irel = h->irel; -+- ptr->rel_backup = h->rel_backup; -+- nds32_elf_ex9_insert_entry (ptr); -+- } -+- else -+- { -+- /* Global symbol insn. */ -+- /* Only sethi insn has multiple m_list. */ -+- struct elf_link_hash_entry_mul_list *m_list = h->m_list; -+- -+- if (ELF32_R_TYPE (m_list->rel_backup.r_info) == R_NDS32_HI20_RELA -+- && m_list->next != NULL) -+- { -+- /* Sethi insn has different symbol or addend but has same hi20. */ -+- times = 0; -+- reservation = 1; -+- relocation = 0; -+- min_relocation = 0xffffffff; -+- while (m_list) -+- { -+- /* Get the minimum sethi address -+- and calculate how many entry the sethi-list have to use. */ -+- if ((m_list->h_list->h->root.type == bfd_link_hash_defined -+- || m_list->h_list->h->root.type == bfd_link_hash_defweak) -+- && (m_list->h_list->h->root.u.def.section != NULL -+- && m_list->h_list->h->root.u.def.section->output_section != NULL)) -+- { -+- relocation = (m_list->h_list->h->root.u.def.value + -+- m_list->h_list->h->root.u.def.section->output_section->vma + -+- m_list->h_list->h->root.u.def.section->output_offset); -+- relocation += m_list->irel->r_addend; -+- } -+- else -+- relocation = 0; -+- if (relocation < min_relocation) -+- min_relocation = relocation; -+- times += m_list->times; -+- m_list = m_list->next; -+- } -+- if (min_relocation < ex9_relax_size) -+- reservation = (min_relocation >> 12) + 1; -+- else -+- reservation = (min_relocation >> 12) -+- - ((min_relocation - ex9_relax_size) >> 12) + 1; -+- if (reservation < (times / 3)) -+- { -+- /* Efficient enough to use ex9. */ -+- int i; -+- -+- for (i = reservation ; i > 0; i--) -+- { -+- /* Allocate number of reservation ex9 entry. */ -+- ptr = (struct elf_nds32_insn_times_entry *) -+- bfd_malloc (sizeof (struct elf_nds32_insn_times_entry)); -+- ptr->times = h->m_list->times / reservation; -+- ptr->string = h->root.string; -+- ptr->m_list = h->m_list; -+- ptr->sec = h->sec; -+- ptr->irel = h->m_list->irel; -+- ptr->rel_backup = h->m_list->rel_backup; -+- nds32_elf_ex9_insert_entry (ptr); -+- } -+- } -+- } -+- else -+- { -+- /* Normal global symbol that means no different address symbol -+- using same ex9 entry. */ -+- if (m_list->times >= 3) -+- { -+- ptr = (struct elf_nds32_insn_times_entry *) -+- bfd_malloc (sizeof (struct elf_nds32_insn_times_entry)); -+- ptr->times = m_list->times; -+- ptr->string = h->root.string; -+- ptr->m_list = h->m_list; -+- ptr->sec = h->sec; -+- ptr->irel = h->m_list->irel; -+- ptr->rel_backup = h->m_list->rel_backup; -+- nds32_elf_ex9_insert_entry (ptr); -+- } -+- } -+- -+- if (h->const_insn == 1) -+- { -+- /* sethi with constant value. */ -+- if (h->times < 3) -+- return TRUE; -+- -+- ptr = (struct elf_nds32_insn_times_entry *) -+- bfd_malloc (sizeof (struct elf_nds32_insn_times_entry)); -+- ptr->times = h->times; -+- ptr->string = h->root.string; -+- ptr->m_list = NULL; -+- ptr->sec = NULL; -+- ptr->irel = NULL; -+- ptr->rel_backup = h->rel_backup; -+- nds32_elf_ex9_insert_entry (ptr); -+- } -+- } -+- -+- return TRUE; -+-} -+- -+-/* Hash table traverse function. */ -+- -+-static void -+-nds32_elf_code_hash_traverse (int (*func) (struct elf_nds32_code_hash_entry*)) -+-{ -+- unsigned int i; -+- -+- ex9_code_table.frozen = 1; -+- for (i = 0; i < ex9_code_table.size; i++) -+- { -+- struct bfd_hash_entry *p; -+- -+- for (p = ex9_code_table.table[i]; p != NULL; p = p->next) -+- if (!func ((struct elf_nds32_code_hash_entry *) p)) -+- goto out; -+- } -+-out: -+- ex9_code_table.frozen = 0; -+-} -+- -+- -+-/* Give order number to insn list. */ -+- -+-static void -+-nds32_elf_order_insn_times (struct bfd_link_info *info) -+-{ -+- struct elf_nds32_insn_times_entry *ex9_insn; -+- struct elf_nds32_insn_times_entry *temp = NULL; -+- struct elf_nds32_link_hash_table *table; -+- int ex9_limit; -+- int number = 0; -+- -+- if (ex9_insn_head == NULL) -+- return; -+- -+-/* The max number of entries is 512. */ -+- ex9_insn = ex9_insn_head; -+- table = nds32_elf_hash_table (info); -+- ex9_limit = table->ex9_limit; -+- -+- ex9_insn = ex9_insn_head; -+- -+- while (ex9_insn != NULL && number < ex9_limit) -+- { -+- ex9_insn->order = number; -+- number++; -+- temp = ex9_insn; -+- ex9_insn = ex9_insn->next; -+- } -+- -+- if (ex9_insn && temp) -+- temp->next = NULL; -+- -+- while (ex9_insn != NULL) -+- { -+- /* Free useless entry. */ -+- temp = ex9_insn; -+- ex9_insn = ex9_insn->next; -+- free (temp); -+- } -+-} -+- -+-/* Build .ex9.itable section. */ -+- -+-static void -+-nds32_elf_ex9_build_itable (struct bfd_link_info *link_info) -+-{ -+- asection *table_sec; -+- struct elf_nds32_insn_times_entry *ptr; -+- bfd *it_abfd; -+- int number = 0; -+- bfd_byte *contents = NULL; -+- -+- for (it_abfd = link_info->input_bfds; it_abfd != NULL; -+- it_abfd = it_abfd->link.next) -+- { -+- /* Find the section .ex9.itable, and put all entries into it. */ -+- table_sec = bfd_get_section_by_name (it_abfd, ".ex9.itable"); -+- if (table_sec != NULL) -+- { -+- if (!nds32_get_section_contents (it_abfd, table_sec, &contents, TRUE)) -+- return; -+- -+- for (ptr = ex9_insn_head; ptr !=NULL ; ptr = ptr->next) -+- number++; -+- -+- table_sec->size = number * 4; -+- -+- if (number == 0) -+- return; -+- -+- elf_elfheader (link_info->output_bfd)->e_flags |= E_NDS32_HAS_EX9_INST; -+- number = 0; -+- for (ptr = ex9_insn_head; ptr !=NULL ; ptr = ptr->next) -+- { -+- long val; -+- -+- val = strtol (ptr->string, NULL, 16); -+- bfd_putb32 ((bfd_vma) val, (char *) contents + (number * 4)); -+- number++; -+- } -+- break; -+- } -+- } -+-} -+- -+-/* Get insn with regs according to relocation type. */ -+- -+-static void -+-nds32_elf_get_insn_with_reg (Elf_Internal_Rela *irel, -+- uint32_t insn, uint32_t *insn_with_reg) -+-{ -+- reloc_howto_type *howto = NULL; -+- -+- if (irel == NULL -+- || (ELF32_R_TYPE (irel->r_info) >= (int) ARRAY_SIZE (nds32_elf_howto_table) -+- && (ELF32_R_TYPE (irel->r_info) - R_NDS32_RELAX_ENTRY) -+- >= (int) ARRAY_SIZE (nds32_elf_relax_howto_table))) -+- { -+- *insn_with_reg = insn; -+- return; -+- } -+- -+- howto = bfd_elf32_bfd_reloc_type_table_lookup (ELF32_R_TYPE (irel->r_info)); -+- *insn_with_reg = insn & (0xffffffff ^ howto->dst_mask); -+-} -+- -+-/* Mask number of address bits according to relocation. */ -+- -+-static unsigned long -+-nds32_elf_irel_mask (Elf_Internal_Rela *irel) -+-{ -+- reloc_howto_type *howto = NULL; -+- -+- if (irel == NULL -+- || (ELF32_R_TYPE (irel->r_info) >= (int) ARRAY_SIZE (nds32_elf_howto_table) -+- && (ELF32_R_TYPE (irel->r_info) - R_NDS32_RELAX_ENTRY) -+- >= (int) ARRAY_SIZE (nds32_elf_relax_howto_table))) -+- return 0; -+- -+- howto = bfd_elf32_bfd_reloc_type_table_lookup (ELF32_R_TYPE (irel->r_info)); -+- return howto->dst_mask; -+-} -+- -+-static void -+-nds32_elf_insert_irel_entry (struct elf_nds32_irel_entry **irel_list, -+- struct elf_nds32_irel_entry *irel_ptr) -+-{ -+- if (*irel_list == NULL) -+- { -+- *irel_list = irel_ptr; -+- irel_ptr->next = NULL; -+- } -+- else -+- { -+- irel_ptr->next = *irel_list; -+- *irel_list = irel_ptr; -+- } -+-} -+- -+-static void -+-nds32_elf_ex9_insert_fix (asection * sec, Elf_Internal_Rela * irel, -+- struct elf_link_hash_entry *h, int order) -+-{ -+- struct elf_nds32_ex9_refix *ptr; -+- -+- ptr = bfd_malloc (sizeof (struct elf_nds32_ex9_refix)); -+- ptr->sec = sec; -+- ptr->irel = irel; -+- ptr->h = h; -+- ptr->order = order; -+- ptr->next = NULL; -+- -+- if (ex9_refix_head == NULL) -+- ex9_refix_head = ptr; -+- else -+- { -+- struct elf_nds32_ex9_refix *temp = ex9_refix_head; -+- -+- while (temp->next != NULL) -+- temp = temp->next; -+- temp->next = ptr; -+- } -+-} -+- -+-enum -+-{ -+- DATA_EXIST = 1, -+- CLEAN_PRE = 1 << 1, -+- PUSH_PRE = 1 << 2 -+-}; -+- -+-/* Check relocation type if supporting for ex9. */ -+- -+-static int -+-nds32_elf_ex9_relocation_check (struct bfd_link_info *info, -+- Elf_Internal_Rela **irel, -+- Elf_Internal_Rela *irelend, -+- nds32_elf_blank_t *relax_blank_list, -+- asection *sec,bfd_vma *off, -+- bfd_byte *contents) -+-{ -+- /* Suppress ex9 if `.no_relax ex9' or inner loop. */ -+- bfd_boolean nested_ex9, nested_loop; -+- bfd_boolean ex9_loop_aware; -+- /* We use the highest 1 byte of result to record -+- how many bytes location counter has to move. */ -+- int result = 0; -+- Elf_Internal_Rela *irel_save = NULL; -+- struct elf_nds32_link_hash_table *table; -+- -+- table = nds32_elf_hash_table (info); -+- ex9_loop_aware = table->ex9_loop_aware; -+- -+- while ((*irel) != NULL && (*irel) < irelend && *off == (*irel)->r_offset) -+- { -+- switch (ELF32_R_TYPE ((*irel)->r_info)) -+- { -+- case R_NDS32_RELAX_REGION_BEGIN: -+- /* Ignore code block. */ -+- nested_ex9 = FALSE; -+- nested_loop = FALSE; -+- if (((*irel)->r_addend & R_NDS32_RELAX_REGION_NO_EX9_FLAG) -+- || (ex9_loop_aware -+- && ((*irel)->r_addend & R_NDS32_RELAX_REGION_INNERMOST_LOOP_FLAG))) -+- { -+- /* Check the region if loop or not. If it is true and -+- ex9-loop-aware is true, ignore the region till region end. */ -+- /* To save the status for in .no_relax ex9 region and -+- loop region to conform the block can do ex9 relaxation. */ -+- nested_ex9 = ((*irel)->r_addend & R_NDS32_RELAX_REGION_NO_EX9_FLAG); -+- nested_loop = (ex9_loop_aware -+- && ((*irel)->r_addend & R_NDS32_RELAX_REGION_INNERMOST_LOOP_FLAG)); -+- while ((*irel) && (*irel) < irelend && (nested_ex9 || nested_loop)) -+- { -+- (*irel)++; -+- if (ELF32_R_TYPE ((*irel)->r_info) == R_NDS32_RELAX_REGION_BEGIN) -+- { -+- /* There may be nested region. */ -+- if (((*irel)->r_addend & R_NDS32_RELAX_REGION_NO_EX9_FLAG) != 0) -+- nested_ex9 = TRUE; -+- else if (ex9_loop_aware -+- && ((*irel)->r_addend & R_NDS32_RELAX_REGION_INNERMOST_LOOP_FLAG)) -+- nested_loop = TRUE; -+- } -+- else if (ELF32_R_TYPE ((*irel)->r_info) == R_NDS32_RELAX_REGION_END) -+- { -+- /* The end of region. */ -+- if (((*irel)->r_addend & R_NDS32_RELAX_REGION_NO_EX9_FLAG) != 0) -+- nested_ex9 = FALSE; -+- else if (ex9_loop_aware -+- && ((*irel)->r_addend & R_NDS32_RELAX_REGION_INNERMOST_LOOP_FLAG)) -+- nested_loop = FALSE; -+- } -+- else if (ELF32_R_TYPE ((*irel)->r_info) == R_NDS32_LABEL -+- && ((*irel)->r_addend & 0x1f) == 2) -+- { -+- /* Alignment exist in the region. */ -+- result |= CLEAN_PRE; -+- if (((*irel)->r_offset - -+- get_nds32_elf_blank_total (&relax_blank_list, -+- (*irel)->r_offset, 0)) & 0x02) -+- result |= PUSH_PRE; -+- } -+- } -+- if ((*irel) >= irelend) -+- *off = sec->size; -+- else -+- *off = (*irel)->r_offset; -+- -+- /* The final instruction in the region, regard this one as data to ignore it. */ -+- result |= DATA_EXIST; -+- return result; -+- } -+- break; -+- -+- case R_NDS32_LABEL: -+- if (((*irel)->r_addend & 0x1f) == 2) -+- { -+- /* Check this point is align and decide to do ex9 or not. */ -+- result |= CLEAN_PRE; -+- if (((*irel)->r_offset - -+- get_nds32_elf_blank_total (&relax_blank_list, -+- (*irel)->r_offset, 0)) & 0x02) -+- result |= PUSH_PRE; -+- } -+- break; -+- case R_NDS32_32_RELA: -+- /* Data. */ -+- result |= (4 << 24); -+- result |= DATA_EXIST; -+- break; -+- case R_NDS32_16_RELA: -+- /* Data. */ -+- result |= (2 << 24); -+- result |= DATA_EXIST; -+- break; -+- case R_NDS32_DATA: -+- /* Data. */ -+- /* The least code alignment is 2. If the data is only one byte, -+- we have to shift one more byte. */ -+- if ((*irel)->r_addend == 1) -+- result |= ((*irel)->r_addend << 25) ; -+- else -+- result |= ((*irel)->r_addend << 24) ; -+- -+- result |= DATA_EXIST; -+- break; -+- -+- case R_NDS32_25_PCREL_RELA: -+- case R_NDS32_SDA16S3_RELA: -+- case R_NDS32_SDA15S3_RELA: -+- case R_NDS32_SDA15S3: -+- case R_NDS32_SDA17S2_RELA: -+- case R_NDS32_SDA15S2_RELA: -+- case R_NDS32_SDA12S2_SP_RELA: -+- case R_NDS32_SDA12S2_DP_RELA: -+- case R_NDS32_SDA15S2: -+- case R_NDS32_SDA18S1_RELA: -+- case R_NDS32_SDA15S1_RELA: -+- case R_NDS32_SDA15S1: -+- case R_NDS32_SDA19S0_RELA: -+- case R_NDS32_SDA15S0_RELA: -+- case R_NDS32_SDA15S0: -+- case R_NDS32_HI20_RELA: -+- case R_NDS32_LO12S0_ORI_RELA: -+- case R_NDS32_LO12S0_RELA: -+- case R_NDS32_LO12S1_RELA: -+- case R_NDS32_LO12S2_RELA: -+- /* These relocation is supported ex9 relaxation currently. */ -+- /* We have to save the relocation for using later, since we have -+- to check there is any alignment in the same address. */ -+- irel_save = *irel; -+- break; -+- default: -+- /* Not support relocations. */ -+- if (ELF32_R_TYPE ((*irel)->r_info) < ARRAY_SIZE (nds32_elf_howto_table) -+- && ELF32_R_TYPE ((*irel)->r_info) != R_NDS32_NONE -+- && ELF32_R_TYPE ((*irel)->r_info) != R_NDS32_INSN16) -+- { -+- /* Note: To optimize aggressively, it maybe can ignore R_NDS32_INSN16 here. -+- But we have to consider if there is any side-effect. */ -+- if (!(result & DATA_EXIST)) -+- { -+- /* We have to confirm there is no data relocation in the -+- same address. In general case, this won't happen. */ -+- /* We have to do ex9 conservative, for those relocation not -+- considerd we ignore instruction. */ -+- result |= DATA_EXIST; -+- if (*(contents + *off) & 0x80) -+- result |= (2 << 24); -+- else -+- result |= (4 << 24); -+- break; -+- } -+- } -+- } -+- if ((*irel) < irelend -+- && ((*irel) + 1) < irelend -+- && (*irel)->r_offset == ((*irel) + 1)->r_offset) -+- /* There are relocations pointing to the same address, we have to -+- check all of them. */ -+- (*irel)++; -+- else -+- { -+- if (irel_save) -+- *irel = irel_save; -+- return result; -+- } -+- } -+- return result; -+-} -+- -+-/* Replace with ex9 instruction. */ -+- -+-static bfd_boolean -+-nds32_elf_ex9_push_insn (uint16_t insn16, bfd_byte *contents, bfd_vma pre_off, -+- nds32_elf_blank_t **relax_blank_list, -+- struct elf_nds32_irel_entry *pre_irel_ptr, -+- struct elf_nds32_irel_entry **irel_list) -+-{ -+- if (insn16 != 0) -+- { -+- /* Implement the ex9 relaxation. */ -+- bfd_putb16 (insn16, contents + pre_off); -+- if (!insert_nds32_elf_blank_recalc_total (relax_blank_list, -+- pre_off + 2, 2)) -+- return FALSE; -+- if (pre_irel_ptr != NULL) -+- nds32_elf_insert_irel_entry (irel_list, pre_irel_ptr); -+- } -+- return TRUE; -+-} -+- -+-/* Replace input file instruction which is in ex9 itable. */ -+- -+-static bfd_boolean -+-nds32_elf_ex9_replace_instruction (struct bfd_link_info *info, bfd *abfd, asection *sec) -+-{ -+- struct elf_nds32_insn_times_entry *ex9_insn = ex9_insn_head; -+- bfd_byte *contents = NULL; -+- bfd_vma off; -+- uint16_t insn16, insn_ex9; -+- /* `pre_*' are used to track previous instruction that can use ex9.it. */ -+- bfd_vma pre_off = -1; -+- uint16_t pre_insn16 = 0; -+- struct elf_nds32_irel_entry *pre_irel_ptr = NULL; -+- Elf_Internal_Rela *internal_relocs; -+- Elf_Internal_Rela *irel; -+- Elf_Internal_Rela *irelend; -+- Elf_Internal_Shdr *symtab_hdr; -+- Elf_Internal_Sym *isym = NULL; -+- nds32_elf_blank_t *relax_blank_list = NULL; -+- uint32_t insn = 0; -+- uint32_t insn_with_reg = 0; -+- uint32_t it_insn; -+- uint32_t it_insn_with_reg; -+- unsigned long r_symndx; -+- asection *isec; -+- struct elf_nds32_irel_entry *irel_list = NULL; -+- struct elf_link_hash_entry **sym_hashes = elf_sym_hashes (abfd); -+- int data_flag, do_replace, save_irel; -+- struct elf_link_hash_entry_list *h_list; -+- -+- -+- /* Load section instructions, relocations, and symbol table. */ -+- if (!nds32_get_section_contents (abfd, sec, &contents, TRUE) -+- || !nds32_get_local_syms (abfd, sec, &isym)) -+- return FALSE; -+- internal_relocs = -+- _bfd_elf_link_read_relocs (abfd, sec, NULL, NULL, TRUE /* keep_memory */); -+- irelend = internal_relocs + sec->reloc_count; -+- symtab_hdr = &elf_tdata (abfd)->symtab_hdr; -+- -+- off = 0; -+- -+- /* Check if the object enable ex9. */ -+- irel = find_relocs_at_address (internal_relocs, internal_relocs, -+- irelend, R_NDS32_RELAX_ENTRY); -+- -+- /* Check this section trigger ex9 relaxation. */ -+- if (irel == NULL -+- || irel >= irelend -+- || ELF32_R_TYPE (irel->r_info) != R_NDS32_RELAX_ENTRY -+- || (ELF32_R_TYPE (irel->r_info) == R_NDS32_RELAX_ENTRY -+- && !(irel->r_addend & R_NDS32_RELAX_ENTRY_EX9_FLAG))) -+- return TRUE; -+- -+- irel = internal_relocs; -+- -+- /* Check alignment and fetch proper relocation. */ -+- while (off < sec->size) -+- { -+- struct elf_link_hash_entry *h = NULL; -+- struct elf_nds32_irel_entry *irel_ptr = NULL; -+- -+- /* Syn the instruction and the relocation. */ -+- while (irel != NULL && irel < irelend && irel->r_offset < off) -+- irel++; -+- -+- data_flag = nds32_elf_ex9_relocation_check (info, &irel, irelend, -+- relax_blank_list, sec, -+- &off, contents); -+- if (data_flag & PUSH_PRE) -+- if (!nds32_elf_ex9_push_insn (pre_insn16, contents, pre_off, -+- &relax_blank_list, pre_irel_ptr, -+- &irel_list)) -+- return FALSE; -+- -+- if (data_flag & CLEAN_PRE) -+- { -+- pre_off = 0; -+- pre_insn16 = 0; -+- pre_irel_ptr = NULL; -+- } -+- if (data_flag & DATA_EXIST) -+- { -+- /* We save the move offset in the highest byte. */ -+- off += (data_flag >> 24); -+- continue; -+- } -+- -+- if (*(contents + off) & 0x80) -+- { -+- /* 2-byte instruction. */ -+- off += 2; -+- continue; -+- } -+- -+- /* Load the instruction and its opcode with register for comparing. */ -+- ex9_insn = ex9_insn_head; -+- insn = bfd_getb32 (contents + off); -+- insn_with_reg = 0; -+- while (ex9_insn) -+- { -+- it_insn = strtol (ex9_insn->string, NULL, 16); -+- it_insn_with_reg = 0; -+- do_replace = 0; -+- save_irel = 0; -+- -+- if (irel != NULL && irel < irelend && irel->r_offset == off) -+- { -+- /* Insn with relocation. */ -+- nds32_elf_get_insn_with_reg (irel, insn, &insn_with_reg); -+- -+- if (ex9_insn->irel != NULL) -+- nds32_elf_get_insn_with_reg (ex9_insn->irel, it_insn, -+- &it_insn_with_reg); -+- -+- if (ex9_insn->irel != NULL -+- && (ELF32_R_TYPE (irel->r_info) == -+- ELF32_R_TYPE (ex9_insn->irel->r_info)) -+- && (insn_with_reg == it_insn_with_reg)) -+- { -+- /* Insn relocation and format is the same as table entry. */ -+- -+- if (ELF32_R_TYPE (irel->r_info) == R_NDS32_25_PCREL_RELA -+- || ELF32_R_TYPE (irel->r_info) == R_NDS32_LO12S0_ORI_RELA -+- || ELF32_R_TYPE (irel->r_info) == R_NDS32_LO12S0_RELA -+- || ELF32_R_TYPE (irel->r_info) == R_NDS32_LO12S1_RELA -+- || ELF32_R_TYPE (irel->r_info) == R_NDS32_LO12S2_RELA -+- || (ELF32_R_TYPE (irel->r_info) >= R_NDS32_SDA15S3 -+- && ELF32_R_TYPE (irel->r_info) <= R_NDS32_SDA15S0) -+- || (ELF32_R_TYPE (irel->r_info) >= R_NDS32_SDA15S3_RELA -+- && ELF32_R_TYPE (irel->r_info) <= R_NDS32_SDA15S0_RELA) -+- || (ELF32_R_TYPE (irel->r_info) >= R_NDS32_SDA12S2_DP_RELA -+- && ELF32_R_TYPE (irel->r_info) <= -+- R_NDS32_SDA12S2_SP_RELA) -+- || (ELF32_R_TYPE (irel->r_info) >= R_NDS32_SDA16S3_RELA -+- && ELF32_R_TYPE (irel->r_info) <= R_NDS32_SDA19S0_RELA)) -+- { -+- r_symndx = ELF32_R_SYM (irel->r_info); -+- if (r_symndx < symtab_hdr->sh_info) -+- { -+- /* Local symbol. */ -+- int shndx = isym[r_symndx].st_shndx; -+- -+- isec = elf_elfsections (abfd)[shndx]->bfd_section; -+- if (ex9_insn->sec == isec -+- && ex9_insn->irel->r_addend == irel->r_addend -+- && ex9_insn->irel->r_info == irel->r_info) -+- { -+- do_replace = 1; -+- save_irel = 1; -+- } -+- } -+- else -+- { -+- /* External symbol. */ -+- h = sym_hashes[r_symndx - symtab_hdr->sh_info]; -+- if (ex9_insn->m_list) -+- { -+- h_list = ex9_insn->m_list->h_list; -+- while (h_list) -+- { -+- if (h == h_list->h -+- && (ex9_insn->m_list->irel->r_addend == -+- irel->r_addend)) -+- { -+- do_replace = 1; -+- save_irel = 1; -+- break; -+- } -+- h_list = h_list->next; -+- } -+- } -+- } -+- } -+- else if (ELF32_R_TYPE (irel->r_info) == R_NDS32_HI20_RELA) -+- { -+- r_symndx = ELF32_R_SYM (irel->r_info); -+- if (r_symndx < symtab_hdr->sh_info) -+- { -+- /* Local symbols. Compare its base symbol and offset. */ -+- int shndx = isym[r_symndx].st_shndx; -+- -+- isec = elf_elfsections (abfd)[shndx]->bfd_section; -+- if (ex9_insn->sec == isec -+- && ex9_insn->irel->r_addend == irel->r_addend -+- && ex9_insn->irel->r_info == irel->r_info) -+- { -+- do_replace = 1; -+- save_irel = 1; -+- } -+- } -+- else -+- { -+- /* External symbol. */ -+- struct elf_link_hash_entry_mul_list *m_list; -+- -+- h = sym_hashes[r_symndx - symtab_hdr->sh_info]; -+- m_list = ex9_insn->m_list; -+- -+- while (m_list) -+- { -+- h_list = m_list->h_list; -+- -+- while (h_list) -+- { -+- if (h == h_list->h -+- && (m_list->irel->r_addend -+- == irel->r_addend)) -+- { -+- do_replace = 1; -+- save_irel = 1; -+- if (ex9_insn->next -+- && ex9_insn->m_list -+- && ex9_insn->m_list == ex9_insn->next->m_list) -+- { -+- /* sethi multiple entry must be fixed */ -+- nds32_elf_ex9_insert_fix (sec, irel, -+- h, ex9_insn->order); -+- } -+- break; -+- } -+- h_list = h_list->next; -+- } -+- m_list = m_list->next; -+- } -+- } -+- } -+- } -+- -+- /* Import table: Check the symbol hash table and the -+- jump target. Only R_NDS32_25_PCREL_RELA now. */ -+- else if (ex9_insn->times == -1 -+- && ELF32_R_TYPE (irel->r_info) == R_NDS32_25_PCREL_RELA) -+- { -+- nds32_elf_get_insn_with_reg (irel, it_insn, &it_insn_with_reg); -+- if (insn_with_reg == it_insn_with_reg) -+- { -+- char code[10]; -+- bfd_vma relocation; -+- -+- r_symndx = ELF32_R_SYM (irel->r_info); -+- if (r_symndx >= symtab_hdr->sh_info) -+- { -+- h = sym_hashes[r_symndx - symtab_hdr->sh_info]; -+- if ((h->root.type == bfd_link_hash_defined -+- || h->root.type == bfd_link_hash_defweak) -+- && h->root.u.def.section != NULL -+- && h->root.u.def.section->output_section != NULL -+- && h->root.u.def.section->gc_mark == 1 -+- && bfd_is_abs_section (h->root.u.def.section) -+- && h->root.u.def.value > sec->size) -+- { -+- relocation = h->root.u.def.value + -+- h->root.u.def.section->output_section->vma + -+- h->root.u.def.section->output_offset; -+- relocation += irel->r_addend; -+- insn = insn_with_reg -+- | ((relocation >> 1) & 0xffffff); -+- snprintf (code, sizeof (code), "%08x", insn); -+- if (strcmp (code, ex9_insn->string) == 0) -+- { -+- do_replace = 1; -+- save_irel = 1; -+- } -+- } -+- } -+- } -+- } -+- else if (ELF32_R_TYPE (irel->r_info) == R_NDS32_RELAX_REGION_BEGIN -+- || ELF32_R_TYPE (irel->r_info) == R_NDS32_RELAX_REGION_END -+- || ELF32_R_TYPE (irel->r_info) == R_NDS32_NONE) -+- { -+- /* These relocations do not have to relocate contens, so it can -+- be regard as instruction without relocation. */ -+- if (insn == it_insn && ex9_insn->irel == NULL) -+- do_replace = 1; -+- } -+- } -+- else -+- { -+- /* Instruction without relocation, we only -+- have to compare their byte code. */ -+- if (insn == it_insn && ex9_insn->irel == NULL) -+- do_replace = 1; -+- } -+- -+- /* Insntruction match so replacing the code here. */ -+- if (do_replace == 1) -+- { -+- /* There are two formats of ex9 instruction. */ -+- if (ex9_insn->order < 32) -+- insn_ex9 = INSN_EX9_IT_2; -+- else -+- insn_ex9 = INSN_EX9_IT_1; -+- insn16 = insn_ex9 | ex9_insn->order; -+- -+- /* Insert ex9 instruction. */ -+- nds32_elf_ex9_push_insn (pre_insn16, contents, pre_off, -+- &relax_blank_list, pre_irel_ptr, -+- &irel_list); -+- pre_off = off; -+- pre_insn16 = insn16; -+- -+- if (save_irel) -+- { -+- /* For instuction with relocation do relax. */ -+- irel_ptr = (struct elf_nds32_irel_entry *) -+- bfd_malloc (sizeof (struct elf_nds32_irel_entry)); -+- irel_ptr->irel = irel; -+- irel_ptr->next = NULL; -+- pre_irel_ptr = irel_ptr; -+- } -+- else -+- pre_irel_ptr = NULL; -+- break; -+- } -+- ex9_insn = ex9_insn->next; -+- } -+- off += 4; -+- } -+- -+- /* Insert ex9 instruction. */ -+- nds32_elf_ex9_push_insn (pre_insn16, contents, pre_off, -+- &relax_blank_list, pre_irel_ptr, -+- &irel_list); -+- -+- /* Delete the redundant code. */ -+- if (relax_blank_list) -+- { -+- nds32_elf_relax_delete_blanks (abfd, sec, relax_blank_list); -+- relax_blank_list = NULL; -+- } -+- -+- /* Clear the relocation that is replaced by ex9. */ -+- while (irel_list) -+- { -+- struct elf_nds32_irel_entry *irel_ptr; -+- -+- irel_ptr = irel_list; -+- irel_list = irel_ptr->next; -+- irel_ptr->irel->r_info = -+- ELF32_R_INFO (ELF32_R_SYM (irel_ptr->irel->r_info), R_NDS32_TRAN); -+- free (irel_ptr); -+- } -+- return TRUE; -+-} -+- -+-/* Initialize ex9 hash table. */ -+- -+-int -+-nds32_elf_ex9_init (void) -+-{ -+- if (!bfd_hash_table_init_n (&ex9_code_table, nds32_elf_code_hash_newfunc, -+- sizeof (struct elf_nds32_code_hash_entry), -+- 1023)) -+- { -+- _bfd_error_handler (_("Linker: cannot init ex9 hash table error \n")); -+- return FALSE; -+- } -+- return TRUE; -+-} -+- -+-/* Predict how many bytes will be relaxed with ex9 and ifc. */ -+- -+-static void -+-nds32_elf_ex9_total_relax (struct bfd_link_info *info) -+-{ -+- struct elf_nds32_insn_times_entry *ex9_insn; -+- struct elf_nds32_insn_times_entry *temp; -+- int target_optimize; -+- struct elf_nds32_link_hash_table *table; -+- -+- if (ex9_insn_head == NULL) -+- return; -+- -+- table = nds32_elf_hash_table (info); -+- target_optimize = table->target_optimize; -+- ex9_insn = ex9_insn_head; -+- while (ex9_insn) -+- { -+- ex9_relax_size = ex9_insn->times * 2 + ex9_relax_size; -+- temp = ex9_insn; -+- ex9_insn = ex9_insn->next; -+- free (temp); -+- } -+- ex9_insn_head = NULL; -+- -+- if ((target_optimize & NDS32_RELAX_JUMP_IFC_ON)) -+- { -+- /* Examine ifc reduce size. */ -+- struct elf_nds32_ifc_symbol_entry *ifc_ent = ifc_symbol_head; -+- struct elf_nds32_ifc_irel_list *irel_ptr = NULL; -+- int size = 0; -+- -+- while (ifc_ent) -+- { -+- if (ifc_ent->enable == 0) -+- { -+- /* Not ifc yet. */ -+- irel_ptr = ifc_ent->irel_head; -+- while (irel_ptr) -+- { -+- size += 2; -+- irel_ptr = irel_ptr->next; -+- } -+- } -+- size -= 2; -+- ifc_ent = ifc_ent->next; -+- } -+- ex9_relax_size += size; -+- } -+-} -+- -+-/* Finish ex9 table. */ -+- -+-void -+-nds32_elf_ex9_finish (struct bfd_link_info *link_info) -+-{ -+- nds32_elf_code_hash_traverse (nds32_elf_examine_insn_times); -+- nds32_elf_order_insn_times (link_info); -+- nds32_elf_ex9_total_relax (link_info); -+- /* Traverse the hash table and count its times. */ -+- nds32_elf_code_hash_traverse (nds32_elf_count_insn_times); -+- nds32_elf_order_insn_times (link_info); -+- nds32_elf_ex9_build_itable (link_info); -+-} -+- -+-/* Relocate the entries in ex9 table. */ -+- -+-static bfd_vma -+-nds32_elf_ex9_reloc_insn (struct elf_nds32_insn_times_entry *ptr, -+- struct bfd_link_info *link_info) -+-{ -+- Elf_Internal_Sym *isym = NULL; -+- bfd_vma relocation = -1; -+- struct elf_link_hash_entry *h; -+- -+- if (ptr->m_list != NULL) -+- { -+- /* Global symbol. */ -+- h = ptr->m_list->h_list->h; -+- if ((h->root.type == bfd_link_hash_defined -+- || h->root.type == bfd_link_hash_defweak) -+- && h->root.u.def.section != NULL -+- && h->root.u.def.section->output_section != NULL) -+- { -+- -+- relocation = h->root.u.def.value + -+- h->root.u.def.section->output_section->vma + -+- h->root.u.def.section->output_offset; -+- relocation += ptr->m_list->irel->r_addend; -+- } -+- else -+- relocation = 0; -+- } -+- else if (ptr->sec !=NULL) -+- { -+- /* Local symbol. */ -+- Elf_Internal_Sym sym; -+- asection *sec = NULL; -+- asection isec; -+- asection *isec_ptr = &isec; -+- Elf_Internal_Rela irel_backup = *(ptr->irel); -+- asection *sec_backup = ptr->sec; -+- bfd *abfd = ptr->sec->owner; -+- -+- if (!nds32_get_local_syms (abfd, sec, &isym)) -+- return FALSE; -+- isym = isym + ELF32_R_SYM (ptr->irel->r_info); -+- -+- sec = bfd_section_from_elf_index (abfd, isym->st_shndx); -+- if (sec != NULL) -+- *isec_ptr = *sec; -+- sym = *isym; -+- -+- /* The purpose is same as elf_link_input_bfd. */ -+- if (isec_ptr != NULL -+- && isec_ptr->sec_info_type == SEC_INFO_TYPE_MERGE -+- && ELF_ST_TYPE (isym->st_info) != STT_SECTION) -+- { -+- sym.st_value = -+- _bfd_merged_section_offset (ptr->sec->output_section->owner, &isec_ptr, -+- elf_section_data (isec_ptr)->sec_info, -+- isym->st_value); -+- } -+- relocation = _bfd_elf_rela_local_sym (link_info->output_bfd, &sym, -+- &ptr->sec, ptr->irel); -+- if (ptr->irel != NULL) -+- relocation += ptr->irel->r_addend; -+- -+- /* Restore origin value since there may be some insntructions that -+- could not be replaced with ex9.it. */ -+- *(ptr->irel) = irel_backup; -+- ptr->sec = sec_backup; -+- } -+- -+- return relocation; -+-} -+- -+-/* Import ex9 table and build list. */ -+- -+-void -+-nds32_elf_ex9_import_table (struct bfd_link_info *info) -+-{ -+- int num = 0; -+- bfd_byte *contents; -+- FILE *ex9_import_file; -+- int update_ex9_table; -+- struct elf_nds32_link_hash_table *table; -+- -+- table = nds32_elf_hash_table (info); -+- ex9_import_file = table->ex9_import_file; -+- rewind (table->ex9_import_file); -+- -+- contents = bfd_malloc (sizeof (bfd_byte) * 4); -+- -+- /* Read instructions from the input file and build the list. */ -+- while (!feof (ex9_import_file)) -+- { -+- unsigned long insn; -+- char *code; -+- struct elf_nds32_insn_times_entry *ptr; -+- size_t nread; -+- -+- nread = fread (contents, sizeof (bfd_byte) * 4, 1, ex9_import_file); -+- /* Ignore the final byte 0x0a. */ -+- if (nread < 1) -+- break; -+- insn = bfd_getb32 (contents); -+- code = bfd_malloc (sizeof (char) * 9); -+- snprintf (code, 9, "%08lx", (insn & 0xffffffff)); -+- ptr = bfd_malloc (sizeof (struct elf_nds32_insn_times_entry)); -+- ptr->string = code; -+- ptr->order = num; -+- ptr->times = -1; -+- ptr->sec = NULL; -+- ptr->m_list = NULL; -+- ptr->rel_backup.r_offset = 0; -+- ptr->rel_backup.r_info = 0; -+- ptr->rel_backup.r_addend = 0; -+- ptr->irel = NULL; -+- ptr->next = NULL; -+- nds32_elf_ex9_insert_entry (ptr); -+- num++; -+- } -+- -+- update_ex9_table = table->update_ex9_table; -+- if (update_ex9_table == 1) -+- { -+- /* It has to consider of sethi need to use multiple page -+- but it not be done yet. */ -+- nds32_elf_code_hash_traverse (nds32_elf_examine_insn_times); -+- nds32_elf_order_insn_times (info); -+- } -+-} -+- -+-/* Export ex9 table. */ -+- -+-static void -+-nds32_elf_ex9_export (struct bfd_link_info *info, -+- bfd_byte *contents, int size) -+-{ -+- FILE *ex9_export_file; -+- struct elf_nds32_link_hash_table *table; -+- -+- table = nds32_elf_hash_table (info); -+- ex9_export_file = table->ex9_export_file; -+- fwrite (contents, sizeof (bfd_byte), size, ex9_export_file); -+- fclose (ex9_export_file); -+-} -+- -+-/* Adjust relocations of J and JAL in ex9.itable. -+- Export ex9 table. */ -+- -+-static void -+-nds32_elf_ex9_reloc_jmp (struct bfd_link_info *link_info) -+-{ -+- asection *table_sec = NULL; -+- struct elf_nds32_insn_times_entry *ex9_insn = ex9_insn_head; -+- struct elf_nds32_insn_times_entry *temp_ptr, *temp_ptr2; -+- bfd *it_abfd; -+- uint32_t insn, insn_with_reg, source_insn; -+- bfd_byte *contents = NULL, *source_contents = NULL; -+- int size = 0; -+- bfd_vma gp; -+- int shift, update_ex9_table, offset = 0; -+- reloc_howto_type *howto = NULL; -+- Elf_Internal_Rela rel_backup; -+- unsigned short insn_ex9; -+- struct elf_nds32_link_hash_table *table; -+- FILE *ex9_export_file; -+- static bfd_boolean done = FALSE; -+- -+- if (done) -+- return; -+- -+- done = TRUE; -+- -+- table = nds32_elf_hash_table (link_info); -+- if (table) -+- table->relax_status |= NDS32_RELAX_EX9_DONE; -+- -+- -+- update_ex9_table = table->update_ex9_table; -+- /* Generated ex9.itable exactly. */ -+- if (update_ex9_table == 0) -+- { -+- for (it_abfd = link_info->input_bfds; it_abfd != NULL; -+- it_abfd = it_abfd->link.next) -+- { -+- table_sec = bfd_get_section_by_name (it_abfd, ".ex9.itable"); -+- if (table_sec != NULL) -+- break; -+- } -+- -+- if (table_sec != NULL) -+- { -+- bfd *output_bfd; -+- -+- output_bfd = table_sec->output_section->owner; -+- nds32_elf_final_sda_base (output_bfd, link_info, &gp, FALSE); -+- if (table_sec->size == 0) -+- return; -+- -+- if (!nds32_get_section_contents (it_abfd, table_sec, &contents, TRUE)) -+- return; -+- } -+- } -+- else -+- { -+- /* Set gp. */ -+- bfd *output_bfd; -+- -+- output_bfd = link_info->input_bfds->sections->output_section->owner; -+- nds32_elf_final_sda_base (output_bfd, link_info, &gp, FALSE); -+- contents = bfd_malloc (sizeof (bfd_byte) * 2048); -+- } -+- -+- /* Relocate instruction. */ -+- while (ex9_insn) -+- { -+- bfd_vma relocation, min_relocation = 0xffffffff; -+- -+- insn = strtol (ex9_insn->string, NULL, 16); -+- insn_with_reg = 0; -+- if (ex9_insn->m_list != NULL || ex9_insn->sec != NULL) -+- { -+- if (ex9_insn->m_list) -+- rel_backup = ex9_insn->m_list->rel_backup; -+- else -+- rel_backup = ex9_insn->rel_backup; -+- -+- nds32_elf_get_insn_with_reg (&rel_backup, insn, &insn_with_reg); -+- howto = -+- bfd_elf32_bfd_reloc_type_table_lookup (ELF32_R_TYPE -+- (rel_backup.r_info)); -+- shift = howto->rightshift; -+- if (ELF32_R_TYPE (rel_backup.r_info) == R_NDS32_25_PCREL_RELA -+- || ELF32_R_TYPE (rel_backup.r_info) == R_NDS32_LO12S0_ORI_RELA -+- || ELF32_R_TYPE (rel_backup.r_info) == R_NDS32_LO12S0_RELA -+- || ELF32_R_TYPE (rel_backup.r_info) == R_NDS32_LO12S1_RELA -+- || ELF32_R_TYPE (rel_backup.r_info) == R_NDS32_LO12S2_RELA) -+- { -+- relocation = nds32_elf_ex9_reloc_insn (ex9_insn, link_info); -+- insn = -+- insn_with_reg | ((relocation >> shift) & -+- nds32_elf_irel_mask (&rel_backup)); -+- bfd_putb32 (insn, contents + (ex9_insn->order) * 4); -+- } -+- else if ((ELF32_R_TYPE (rel_backup.r_info) >= R_NDS32_SDA15S3 -+- && ELF32_R_TYPE (rel_backup.r_info) <= R_NDS32_SDA15S0) -+- || (ELF32_R_TYPE (rel_backup.r_info) >= R_NDS32_SDA15S3_RELA -+- && ELF32_R_TYPE (rel_backup.r_info) <= R_NDS32_SDA15S0_RELA) -+- || (ELF32_R_TYPE (rel_backup.r_info) >= R_NDS32_SDA12S2_DP_RELA -+- && ELF32_R_TYPE (rel_backup.r_info) <= R_NDS32_SDA12S2_SP_RELA) -+- || (ELF32_R_TYPE (rel_backup.r_info) >= R_NDS32_SDA16S3_RELA -+- && ELF32_R_TYPE (rel_backup.r_info) <= R_NDS32_SDA19S0_RELA)) -+- { -+- relocation = nds32_elf_ex9_reloc_insn (ex9_insn, link_info); -+- insn = -+- insn_with_reg | (((relocation - gp) >> shift) & -+- nds32_elf_irel_mask (&rel_backup)); -+- bfd_putb32 (insn, contents + (ex9_insn->order) * 4); -+- } -+- else if (ELF32_R_TYPE (rel_backup.r_info) == R_NDS32_HI20_RELA) -+- { -+- /* Sethi may be multiple entry for one insn. */ -+- if (ex9_insn->next && ex9_insn->m_list -+- && ex9_insn->m_list == ex9_insn->next->m_list) -+- { -+- struct elf_link_hash_entry_mul_list *m_list; -+- struct elf_nds32_ex9_refix *fix_ptr; -+- struct elf_link_hash_entry *h; -+- -+- temp_ptr = ex9_insn; -+- temp_ptr2 = ex9_insn; -+- m_list = ex9_insn->m_list; -+- while (m_list) -+- { -+- h = m_list->h_list->h; -+- relocation = h->root.u.def.value + -+- h->root.u.def.section->output_section->vma + -+- h->root.u.def.section->output_offset; -+- relocation += m_list->irel->r_addend; -+- -+- if (relocation < min_relocation) -+- min_relocation = relocation; -+- m_list = m_list->next; -+- } -+- relocation = min_relocation; -+- -+- /* Put insntruction into ex9 table. */ -+- insn = insn_with_reg -+- | ((relocation >> shift) & nds32_elf_irel_mask (&rel_backup)); -+- bfd_putb32 (insn, contents + (ex9_insn->order) * 4); -+- relocation = relocation + 0x1000; /* hi20 */ -+- -+- while (ex9_insn->next && ex9_insn->m_list -+- && ex9_insn->m_list == ex9_insn->next->m_list) -+- { -+- /* Multiple sethi. */ -+- ex9_insn = ex9_insn->next; -+- size += 4; -+- insn = -+- insn_with_reg | ((relocation >> shift) & -+- nds32_elf_irel_mask (&rel_backup)); -+- bfd_putb32 (insn, contents + (ex9_insn->order) * 4); -+- relocation = relocation + 0x1000; /* hi20 */ -+- } -+- -+- fix_ptr = ex9_refix_head; -+- while (fix_ptr) -+- { -+- /* Fix ex9 insn. */ -+- /* temp_ptr2 points to the head of multiple sethi. */ -+- temp_ptr = temp_ptr2; -+- while (fix_ptr->order != temp_ptr->order && fix_ptr->next) -+- { -+- fix_ptr = fix_ptr->next; -+- } -+- if (fix_ptr->order != temp_ptr->order) -+- break; -+- -+- /* Set source insn. */ -+- relocation = -+- fix_ptr->h->root.u.def.value + -+- fix_ptr->h->root.u.def.section->output_section->vma + -+- fix_ptr->h->root.u.def.section->output_offset; -+- relocation += fix_ptr->irel->r_addend; -+- /* sethi imm is imm20s. */ -+- source_insn = insn_with_reg | ((relocation >> shift) & 0xfffff); -+- -+- while (temp_ptr) -+- { -+- /* Match entry and source code. */ -+- insn = bfd_getb32 (contents + (temp_ptr->order) * 4 + offset); -+- if (insn == source_insn) -+- { -+- /* Fix the ex9 insn. */ -+- if (temp_ptr->order != fix_ptr->order) -+- { -+- if (!nds32_get_section_contents -+- (fix_ptr->sec->owner, fix_ptr->sec, -+- &source_contents, TRUE)) -+- _bfd_error_handler -+- (_("Linker: error cannot fixed ex9 relocation \n")); -+- if (temp_ptr->order < 32) -+- insn_ex9 = INSN_EX9_IT_2; -+- else -+- insn_ex9 = INSN_EX9_IT_1; -+- insn_ex9 = insn_ex9 | temp_ptr->order; -+- bfd_putb16 (insn_ex9, source_contents + fix_ptr->irel->r_offset); -+- } -+- break; -+- } -+- else -+- { -+- if (!temp_ptr->next || temp_ptr->m_list != temp_ptr->next->m_list) -+- _bfd_error_handler -+- (_("Linker: error cannot fixed ex9 relocation \n")); -+- else -+- temp_ptr = temp_ptr->next; -+- } -+- } -+- fix_ptr = fix_ptr->next; -+- } -+- } -+- else -+- { -+- relocation = nds32_elf_ex9_reloc_insn (ex9_insn, link_info); -+- insn = insn_with_reg -+- | ((relocation >> shift) & nds32_elf_irel_mask (&rel_backup)); -+- bfd_putb32 (insn, contents + (ex9_insn->order) * 4); -+- } -+- } -+- } -+- else -+- { -+- /* Insn without relocation does not have to be fixed -+- if need to update export table. */ -+- if (update_ex9_table == 1) -+- bfd_putb32 (insn, contents + (ex9_insn->order) * 4); -+- } -+- ex9_insn = ex9_insn->next; -+- size += 4; -+- } -+- -+- ex9_export_file = table->ex9_export_file; -+- if (ex9_export_file != NULL) -+- nds32_elf_ex9_export (link_info, contents, table_sec->size); -+- else if (update_ex9_table == 1) -+- { -+- table->ex9_export_file = table->ex9_import_file; -+- rewind (table->ex9_export_file); -+- nds32_elf_ex9_export (link_info, contents, size); -+- } -+-} -+- -+-/* Generate ex9 hash table. */ -+- -+-static bfd_boolean -+-nds32_elf_ex9_build_hash_table (bfd *abfd, asection *sec, -+- struct bfd_link_info *link_info) -+-{ -+- Elf_Internal_Rela *internal_relocs; -+- Elf_Internal_Rela *irelend; -+- Elf_Internal_Rela *irel; -+- Elf_Internal_Rela *jrel; -+- Elf_Internal_Rela rel_backup; -+- Elf_Internal_Shdr *symtab_hdr; -+- Elf_Internal_Sym *isym = NULL; -+- asection *isec; -+- struct elf_link_hash_entry **sym_hashes; -+- bfd_byte *contents = NULL; -+- bfd_vma off = 0; -+- unsigned long r_symndx; -+- uint32_t insn, insn_with_reg; -+- struct elf_link_hash_entry *h; -+- int data_flag, shift, align; -+- bfd_vma relocation; -+- /* Suppress ex9 if `.no_relax ex9' or inner loop. */ -+- reloc_howto_type *howto = NULL; -+- -+- sym_hashes = elf_sym_hashes (abfd); -+- /* Load section instructions, relocations, and symbol table. */ -+- if (!nds32_get_section_contents (abfd, sec, &contents, TRUE)) -+- return FALSE; -+- -+- internal_relocs = _bfd_elf_link_read_relocs (abfd, sec, NULL, NULL, -+- TRUE /* keep_memory */); -+- irelend = internal_relocs + sec->reloc_count; -+- symtab_hdr = &elf_tdata (abfd)->symtab_hdr; -+- if (!nds32_get_local_syms (abfd, sec, &isym)) -+- return FALSE; -+- -+- /* Check the object if enable ex9. */ -+- irel = find_relocs_at_address (internal_relocs, internal_relocs, irelend, -+- R_NDS32_RELAX_ENTRY); -+- -+- /* Check this section trigger ex9 relaxation. */ -+- if (irel == NULL -+- || irel >= irelend -+- || ELF32_R_TYPE (irel->r_info) != R_NDS32_RELAX_ENTRY -+- || (ELF32_R_TYPE (irel->r_info) == R_NDS32_RELAX_ENTRY -+- && !(irel->r_addend & R_NDS32_RELAX_ENTRY_EX9_FLAG))) -+- return TRUE; -+- -+- irel = internal_relocs; -+- -+- /* Push each insn into hash table. */ -+- while (off < sec->size) -+- { -+- char code[10]; -+- struct elf_nds32_code_hash_entry *entry; -+- -+- while (irel != NULL && irel < irelend && irel->r_offset < off) -+- irel++; -+- -+- data_flag = nds32_elf_ex9_relocation_check (link_info, &irel, irelend, -+- NULL, sec, &off, contents); -+- if (data_flag & DATA_EXIST) -+- { -+- /* We save the move offset in the highest byte. */ -+- off += (data_flag >> 24); -+- continue; -+- } -+- -+- if (*(contents + off) & 0x80) -+- { -+- off += 2; -+- } -+- else -+- { -+- h = NULL; -+- isec = NULL; -+- jrel = NULL; -+- rel_backup.r_info = 0; -+- rel_backup.r_offset = 0; -+- rel_backup.r_addend = 0; -+- /* Load the instruction and its opcode with register for comparing. */ -+- insn = bfd_getb32 (contents + off); -+- insn_with_reg = 0; -+- if (irel != NULL && irel < irelend && irel->r_offset == off) -+- { -+- nds32_elf_get_insn_with_reg (irel, insn, &insn_with_reg); -+- howto = bfd_elf32_bfd_reloc_type_table_lookup (ELF32_R_TYPE (irel->r_info)); -+- shift = howto->rightshift; -+- align = (1 << shift) - 1; -+- if (ELF32_R_TYPE (irel->r_info) == R_NDS32_25_PCREL_RELA -+- || ELF32_R_TYPE (irel->r_info) == R_NDS32_HI20_RELA -+- || ELF32_R_TYPE (irel->r_info) == R_NDS32_LO12S0_ORI_RELA -+- || ELF32_R_TYPE (irel->r_info) == R_NDS32_LO12S0_RELA -+- || ELF32_R_TYPE (irel->r_info) == R_NDS32_LO12S1_RELA -+- || ELF32_R_TYPE (irel->r_info) == R_NDS32_LO12S2_RELA -+- ||(ELF32_R_TYPE (irel->r_info) >= R_NDS32_SDA15S3 -+- && ELF32_R_TYPE (irel->r_info) <= R_NDS32_SDA15S0) -+- || (ELF32_R_TYPE (irel->r_info) >= R_NDS32_SDA15S3_RELA -+- && ELF32_R_TYPE (irel->r_info) <= R_NDS32_SDA15S0_RELA) -+- || (ELF32_R_TYPE (irel->r_info) >= R_NDS32_SDA12S2_DP_RELA -+- && ELF32_R_TYPE (irel->r_info) <= R_NDS32_SDA12S2_SP_RELA) -+- || (ELF32_R_TYPE (irel->r_info) >= R_NDS32_SDA16S3_RELA -+- && ELF32_R_TYPE (irel->r_info) <= R_NDS32_SDA19S0_RELA)) -+- { -+- r_symndx = ELF32_R_SYM (irel->r_info); -+- jrel = irel; -+- rel_backup = *irel; -+- if (r_symndx < symtab_hdr->sh_info) -+- { -+- /* Local symbol. */ -+- int shndx = isym[r_symndx].st_shndx; -+- -+- bfd_vma st_value = (isym + r_symndx)->st_value; -+- isec = elf_elfsections (abfd)[shndx]->bfd_section; -+- relocation = (isec->output_section->vma + isec->output_offset -+- + st_value + irel->r_addend); -+- } -+- else -+- { -+- /* External symbol. */ -+- bfd_boolean warned ATTRIBUTE_UNUSED; -+- bfd_boolean ignored ATTRIBUTE_UNUSED; -+- bfd_boolean unresolved_reloc ATTRIBUTE_UNUSED; -+- asection *sym_sec; -+- -+- /* Maybe there is a better way to get h and relocation */ -+- RELOC_FOR_GLOBAL_SYMBOL (link_info, abfd, sec, irel, -+- r_symndx, symtab_hdr, sym_hashes, -+- h, sym_sec, relocation, -+- unresolved_reloc, warned, ignored); -+- relocation += irel->r_addend; -+- if ((h->root.type != bfd_link_hash_defined -+- && h->root.type != bfd_link_hash_defweak) -+- || strcmp (h->root.root.string, "_FP_BASE_") == 0) -+- { -+- off += 4; -+- continue; -+- } -+- } -+- -+- /* Check for gp relative instruction alignment. */ -+- if ((ELF32_R_TYPE (irel->r_info) >= R_NDS32_SDA15S3 -+- && ELF32_R_TYPE (irel->r_info) <= R_NDS32_SDA15S0) -+- || (ELF32_R_TYPE (irel->r_info) >= R_NDS32_SDA15S3_RELA -+- && ELF32_R_TYPE (irel->r_info) <= R_NDS32_SDA15S0_RELA) -+- || (ELF32_R_TYPE (irel->r_info) >= R_NDS32_SDA12S2_DP_RELA -+- && ELF32_R_TYPE (irel->r_info) <= R_NDS32_SDA12S2_SP_RELA) -+- || (ELF32_R_TYPE (irel->r_info) >= R_NDS32_SDA16S3_RELA -+- && ELF32_R_TYPE (irel->r_info) <= R_NDS32_SDA19S0_RELA)) -+- { -+- bfd_vma gp; -+- bfd *output_bfd = sec->output_section->owner; -+- bfd_reloc_status_type r; -+- -+- /* If the symbol is in the abs section, the out_bfd will be null. -+- This happens when the relocation has a symbol@GOTOFF. */ -+- r = nds32_elf_final_sda_base (output_bfd, link_info, &gp, FALSE); -+- if (r != bfd_reloc_ok) -+- { -+- off += 4; -+- continue; -+- } -+- -+- relocation -= gp; -+- -+- /* Make sure alignment is correct. */ -+- if (relocation & align) -+- { -+- /* Incorrect alignment. */ -+- _bfd_error_handler -+- /* xgettext:c-format */ -+- (_("%B: warning: unaligned small data access " -+- "for entry: {%Ld, %Ld, %Ld}, addr = %#Lx, align = %#x"), -+- abfd, irel->r_offset, -+- irel->r_info, irel->r_addend, relocation, align); -+- off += 4; -+- continue; -+- } -+- } -+- -+- insn = insn_with_reg -+- | ((relocation >> shift) & nds32_elf_irel_mask (irel)); -+- } -+- else if (ELF32_R_TYPE (irel->r_info) == R_NDS32_RELAX_REGION_BEGIN -+- || ELF32_R_TYPE (irel->r_info) == R_NDS32_RELAX_REGION_END -+- || ELF32_R_TYPE (irel->r_info) == R_NDS32_NONE) -+- { -+- /* These relocations do not have to relocate contens, so it can -+- be regard as instruction without relocation. */ -+- } -+- else -+- { -+- off += 4; -+- continue; -+- } -+- } -+- -+- snprintf (code, sizeof (code), "%08x", insn); -+- /* Copy "code". */ -+- entry = (struct elf_nds32_code_hash_entry*) -+- bfd_hash_lookup (&ex9_code_table, code, TRUE, TRUE); -+- if (entry == NULL) -+- { -+- _bfd_error_handler -+- (_("failed creating ex9.it %s hash table entry"), code); -+- return FALSE; -+- } -+- if (h) -+- { -+- if (h->root.type == bfd_link_hash_undefined) -+- return TRUE; -+- /* Global symbol. */ -+- /* In order to do sethi with different symbol but same value. */ -+- if (entry->m_list == NULL) -+- { -+- struct elf_link_hash_entry_mul_list *m_list_new; -+- struct elf_link_hash_entry_list *h_list_new; -+- -+- m_list_new = (struct elf_link_hash_entry_mul_list *) -+- bfd_malloc (sizeof (struct elf_link_hash_entry_mul_list)); -+- h_list_new = (struct elf_link_hash_entry_list *) -+- bfd_malloc (sizeof (struct elf_link_hash_entry_list)); -+- entry->m_list = m_list_new; -+- m_list_new->h_list = h_list_new; -+- m_list_new->rel_backup = rel_backup; -+- m_list_new->times = 1; -+- m_list_new->irel = jrel; -+- m_list_new->next = NULL; -+- h_list_new->h = h; -+- h_list_new->next = NULL; -+- } -+- else -+- { -+- struct elf_link_hash_entry_mul_list *m_list = entry->m_list; -+- struct elf_link_hash_entry_list *h_list; -+- -+- while (m_list) -+- { -+- /* Build the different symbols that point to the same address. */ -+- h_list = m_list->h_list; -+- if (h_list->h->root.u.def.value == h->root.u.def.value -+- && h_list->h->root.u.def.section->output_section->vma -+- == h->root.u.def.section->output_section->vma -+- && h_list->h->root.u.def.section->output_offset -+- == h->root.u.def.section->output_offset -+- && m_list->rel_backup.r_addend == rel_backup.r_addend) -+- { -+- m_list->times++; -+- m_list->irel = jrel; -+- while (h_list->h != h && h_list->next) -+- h_list = h_list->next; -+- if (h_list->h != h) -+- { -+- struct elf_link_hash_entry_list *h_list_new; -+- -+- h_list_new = (struct elf_link_hash_entry_list *) -+- bfd_malloc (sizeof (struct elf_link_hash_entry_list)); -+- h_list->next = h_list_new; -+- h_list_new->h = h; -+- h_list_new->next = NULL; -+- } -+- break; -+- } -+- /* The sethi case may have different address but the -+- hi20 is the same. */ -+- else if (ELF32_R_TYPE (jrel->r_info) == R_NDS32_HI20_RELA -+- && m_list->next == NULL) -+- { -+- struct elf_link_hash_entry_mul_list *m_list_new; -+- struct elf_link_hash_entry_list *h_list_new; -+- -+- m_list_new = (struct elf_link_hash_entry_mul_list *) -+- bfd_malloc (sizeof (struct elf_link_hash_entry_mul_list)); -+- h_list_new = (struct elf_link_hash_entry_list *) -+- bfd_malloc (sizeof (struct elf_link_hash_entry_list)); -+- m_list->next = m_list_new; -+- m_list_new->h_list = h_list_new; -+- m_list_new->rel_backup = rel_backup; -+- m_list_new->times = 1; -+- m_list_new->irel = jrel; -+- m_list_new->next = NULL; -+- h_list_new->h = h; -+- h_list_new->next = NULL; -+- break; -+- } -+- m_list = m_list->next; -+- } -+- if (!m_list) -+- { -+- off += 4; -+- continue; -+- } -+- } -+- } -+- else -+- { -+- /* Local symbol and insn without relocation*/ -+- entry->times++; -+- entry->rel_backup = rel_backup; -+- } -+- -+- /* Use in sethi insn with constant and global symbol in same format. */ -+- if (!jrel) -+- entry->const_insn = 1; -+- else -+- entry->irel = jrel; -+- entry->sec = isec; -+- off += 4; -+- } -+- } -+- return TRUE; -++ return sec; -+ } -+- -+-/* Set the _ITB_BASE, and point it to ex9 table. */ -+- -+-bfd_boolean -+-nds32_elf_ex9_itb_base (struct bfd_link_info *link_info) -+-{ -+- bfd *abfd; -+- asection *sec; -+- bfd *output_bfd = NULL; -+- struct bfd_link_hash_entry *bh = NULL; -+- -+- if (is_ITB_BASE_set == 1) -+- return TRUE; -+- -+- is_ITB_BASE_set = 1; -+- -+- bh = bfd_link_hash_lookup (link_info->hash, "_ITB_BASE_", FALSE, FALSE, TRUE); -+- -+- if (bh && (bh->type == bfd_link_hash_defined -+- || bh->type == bfd_link_hash_defweak)) -+- return TRUE; -+- -+- for (abfd = link_info->input_bfds; abfd != NULL; -+- abfd = abfd->link.next) -+- { -+- sec = bfd_get_section_by_name (abfd, ".ex9.itable"); -+- if (sec != NULL) -+- { -+- output_bfd = sec->output_section->owner; -+- break; -+- } -+- } -+- if (output_bfd == NULL) -+- { -+- output_bfd = link_info->output_bfd; -+- if (output_bfd->sections == NULL) -+- return TRUE; -+- else -+- sec = bfd_abs_section_ptr; -+- } -+- bh = bfd_link_hash_lookup (link_info->hash, "_ITB_BASE_", -+- FALSE, FALSE, TRUE); -+- return (_bfd_generic_link_add_one_symbol -+- (link_info, output_bfd, "_ITB_BASE_", -+- BSF_GLOBAL | BSF_WEAK, sec, 0, -+- (const char *) NULL, FALSE, get_elf_backend_data -+- (output_bfd)->collect, &bh)); -+-} /* End EX9.IT */ -+ -+ -+ #define ELF_ARCH bfd_arch_nds32 -+ #define ELF_MACHINE_CODE EM_NDS32 -+ #define ELF_MAXPAGESIZE 0x1000 -+-#define ELF_TARGET_ID NDS32_ELF_DATA -++#define ELF_TARGET_ID NDS32_ELF_DATA -+ -+ #define TARGET_BIG_SYM nds32_elf32_be_vec -+ #define TARGET_BIG_NAME "elf32-nds32be" -+@@ -15448,7 +15265,7 @@ nds32_elf_ex9_itb_base (struct bfd_link_info *link_info) -+ #define bfd_elf32_bfd_relax_section nds32_elf_relax_section -+ #define bfd_elf32_bfd_set_private_flags nds32_elf_set_private_flags -+ -+-#define bfd_elf32_mkobject nds32_elf_mkobject -++#define bfd_elf32_mkobject nds32_elf_mkobject -+ #define elf_backend_action_discarded nds32_elf_action_discarded -+ #define elf_backend_add_symbol_hook nds32_elf_add_symbol_hook -+ #define elf_backend_check_relocs nds32_elf_check_relocs -+@@ -15469,7 +15286,9 @@ nds32_elf_ex9_itb_base (struct bfd_link_info *link_info) -+ #define elf_backend_final_write_processing nds32_elf_final_write_processing -+ #define elf_backend_special_sections nds32_elf_special_sections -+ #define bfd_elf32_bfd_get_relocated_section_contents \ -+- nds32_elf_get_relocated_section_contents -++ nds32_elf_get_relocated_section_contents -++#define bfd_elf32_bfd_is_target_special_symbol nds32_elf_is_target_special_symbol -++#define elf_backend_maybe_function_sym nds32_elf_maybe_function_sym -+ -+ #define elf_backend_can_gc_sections 1 -+ #define elf_backend_can_refcount 1 -+@@ -15480,7 +15299,6 @@ nds32_elf_ex9_itb_base (struct bfd_link_info *link_info) -+ #define elf_backend_may_use_rel_p 1 -+ #define elf_backend_default_use_rela_p 1 -+ #define elf_backend_may_use_rela_p 1 -+-#define elf_backend_dtrel_excludes_plt 1 -+ -+ #include "elf32-target.h" -+ -+diff --git binutils-2.30/bfd/elf32-nds32.h binutils-2.30-nds32/bfd/elf32-nds32.h -+index 7e09e01a3f..fda4155ab3 100644 -+--- binutils-2.30/bfd/elf32-nds32.h -++++ binutils-2.30-nds32/bfd/elf32-nds32.h -+@@ -22,6 +22,8 @@ -+ #ifndef ELF32_NDS32_H -+ #define ELF32_NDS32_H -+ -++#include "bfd_stdint.h" -++ -+ #ifdef __cplusplus -+ extern "C" { -+ #endif -+@@ -46,6 +48,13 @@ extern "C" { -+ #define R_NDS32_RELAX_ENTRY_EX9_FLAG (1 << 2) -+ /* Enable IFC optimization for this section. */ -+ #define R_NDS32_RELAX_ENTRY_IFC_FLAG (1 << 3) -++/* Two bits for ICT to comply with files without directive. */ -++/* ICT small model. */ -++#define R_NDS32_RELAX_ENTRY_ICT_SMALL (0x2 << 4) -++/* ICT large model. */ -++#define R_NDS32_RELAX_ENTRY_ICT_LARGE (0x3 << 4) -++/* Mask for get ict bits. */ -++#define R_NDS32_RELAX_ENTRY_ICT_MASK (0x3 << 4) -+ -+ -+ /* Relocation flags for R_NDS32_INSN16. */ -+@@ -66,8 +75,6 @@ extern "C" { -+ /* NOT_OMIT_FP_FLAG is set if this region is not worth -+ for fp-as-gp. */ -+ #define R_NDS32_RELAX_REGION_NOT_OMIT_FP_FLAG (1 << 1) -+-/* Suppress EX9 optimization in the region. */ -+-#define R_NDS32_RELAX_REGION_NO_EX9_FLAG (1 << 2) -+ /* A Innermost loop region. Some optimizations is suppressed -+ in this region due to performance drop. */ -+ #define R_NDS32_RELAX_REGION_INNERMOST_LOOP_FLAG (1 << 4) -+@@ -91,35 +98,57 @@ enum -+ NDS32_RELAX_NONE_ROUND = 0, -+ NDS32_RELAX_NORMAL_ROUND, -+ NDS32_RELAX_JUMP_IFC_ROUND, -++ NDS32_RELAX_IFC_ROUND, -+ NDS32_RELAX_EX9_BUILD_ROUND, -+ NDS32_RELAX_EX9_REPLACE_ROUND, -+ NDS32_RELAX_EMPTY_ROUND -+ }; -+ -+-/* Optimization status mask. */ -+-#define NDS32_RELAX_JUMP_IFC_DONE (1 << 0) -+-#define NDS32_RELAX_EX9_DONE (1 << 1) -++/* Security tag. */ -++enum -++{ -++ NDS32_SECURITY_NONE = 0, -++ NDS32_SECURITY_START, -++ NDS32_SECURITY_RESTART, -++ NDS32_SECURITY_END -++}; -+ -+ /* Optimization turn on mask. */ -+-#define NDS32_RELAX_JUMP_IFC_ON (1 << 0) -++#define NDS32_RELAX_IFC_ON (1 << 0) -+ #define NDS32_RELAX_EX9_ON (1 << 1) -+ -+ extern void nds32_insertion_sort -+ (void *, size_t, size_t, int (*) (const void *, const void *)); -+ -+-extern int nds32_elf_ex9_init (void); -+-extern int nds32_convert_32_to_16 (bfd *, uint32_t, uint16_t *, int *); -+-extern int nds32_convert_16_to_32 (bfd *, uint16_t, uint32_t *); -+-extern void bfd_elf32_nds32_set_target_option (struct bfd_link_info *, -+- int, int, FILE *, int, -+- int, int, int, FILE *, -+- FILE *, int, int, -+- bfd_boolean, bfd_boolean); -++struct section_id_list_t -++{ -++ int id; -++ struct section_id_list_t *next; -++}; -++ -++extern struct section_id_list_t * -++elf32_nds32_lookup_section_id (int, struct section_id_list_t **); -++extern int elf32_nds32_check_relax_group (bfd *, asection *); -++extern int elf32_nds32_unify_relax_group (bfd *, asection *); -++extern int nds32_elf_unify_tls_model (bfd *, asection *, bfd_byte *, -++ struct bfd_link_info *); -++ -++extern void bfd_elf32_nds32_set_target_option (struct bfd_link_info *, int, int, -++ FILE *, int, int, int, int, int, -++ int, char *); -++extern void bfd_elf32_nds32_append_section (struct bfd_link_info*, bfd *); -++extern int nds32_convert_32_to_16 (bfd *, uint32_t, uint16_t *, int *); -++extern int nds32_convert_16_to_32 (bfd *, uint16_t, uint32_t *); -+ -+ #define nds32_elf_hash_table(info) \ -+ (elf_hash_table_id ((struct elf_link_hash_table *) ((info)->hash)) \ -+- == NDS32_ELF_DATA ? \ -+- ((struct elf_nds32_link_hash_table *) ((info)->hash)) : NULL) -++ == NDS32_ELF_DATA ? ((struct elf_nds32_link_hash_table *) ((info)->hash)) : NULL) -++ -++#define elf32_nds32_compute_jump_table_size(htab) \ -++ ((htab)->next_tls_desc_index * 4) -++ -++#define elf32_nds32_local_tlsdesc_gotent(bfd) \ -++ (elf_nds32_tdata (bfd)->local_tlsdesc_gotent) -+ -+ /* Hash table structure for target nds32. There are some members to -+ save target options passed from nds32elf.em to bfd. */ -+@@ -144,12 +173,34 @@ struct elf_nds32_link_hash_table -+ int target_optimize; /* Switch optimization. */ -+ int relax_status; /* Finished optimization. */ -+ int relax_round; /* Going optimization. */ -+- FILE *ex9_export_file; /* --mexport-ex9= */ -+- FILE *ex9_import_file; /* --mimport-ex9= */ -+- int update_ex9_table; /* --mupdate-ex9. */ -+- int ex9_limit; -+- bfd_boolean ex9_loop_aware; /* Ignore ex9 if inside a loop. */ -+- bfd_boolean ifc_loop_aware; /* Ignore ifc if inside a loop. */ -++ bfd_boolean hyper_relax; /* Relax for symbol not in RW sections. */ -++ int tls_desc_trampoline; /* --m[no-]tlsdesc-trampoline. */ -++ -++ /* The offset into splt of the PLT entry for the TLS descriptor -++ resolver. Special values are 0, if not necessary (or not found -++ to be necessary yet), and -1 if needed but not determined -++ yet. */ -++ bfd_vma dt_tlsdesc_plt; -++ -++ /* The offset into sgot of the GOT entry used by the PLT entry -++ above. */ -++ bfd_vma dt_tlsdesc_got; -++ -++ /* Offset in .plt section of tls_nds32_trampoline. */ -++ bfd_vma tls_trampoline; -++ -++ /* The index of the next unused R_NDS32_TLS_DESC slot in .rel.plt. */ -++ bfd_vma next_tls_desc_index; -++ -++ /* How many R_NDS32_TLS_DESC relocations were generated so far. */ -++ bfd_vma num_tls_desc; -++ -++ /* The amount of space used by the reserved portion of the sgotplt -++ section, plus whatever space is used by the jump slots. */ -++ bfd_vma sgotplt_jump_table_size; -++ -++ /* True if the target uses REL relocations. */ -++ int use_rel; -+ }; -+ -+ #ifdef __cplusplus -+diff --git binutils-2.30/bfd/libbfd.h binutils-2.30-nds32/bfd/libbfd.h -+index 2f5f16e776..ff89105086 100644 -+--- binutils-2.30/bfd/libbfd.h -++++ binutils-2.30-nds32/bfd/libbfd.h -+@@ -1872,6 +1872,7 @@ static const char *const bfd_reloc_code_real_names[] = { "@@uninitialized@@", -+ "BFD_RELOC_NDS32_SDA17S2", -+ "BFD_RELOC_NDS32_SDA18S1", -+ "BFD_RELOC_NDS32_SDA19S0", -++ "BFD_RELOC_NDS32_SECURITY_16", -+ "BFD_RELOC_NDS32_GOT20", -+ "BFD_RELOC_NDS32_9_PLTREL", -+ "BFD_RELOC_NDS32_25_PLTREL", -+@@ -1955,18 +1956,39 @@ static const char *const bfd_reloc_code_real_names[] = { "@@uninitialized@@", -+ "BFD_RELOC_NDS32_17IFC_PCREL", -+ "BFD_RELOC_NDS32_10IFCU_PCREL", -+ "BFD_RELOC_NDS32_TPOFF", -++ "BFD_RELOC_NDS32_GOTTPOFF", -+ "BFD_RELOC_NDS32_TLS_LE_HI20", -+ "BFD_RELOC_NDS32_TLS_LE_LO12", -+- "BFD_RELOC_NDS32_TLS_LE_ADD", -+- "BFD_RELOC_NDS32_TLS_LE_LS", -+- "BFD_RELOC_NDS32_GOTTPOFF", -+- "BFD_RELOC_NDS32_TLS_IE_HI20", -+- "BFD_RELOC_NDS32_TLS_IE_LO12S2", -+- "BFD_RELOC_NDS32_TLS_TPOFF", -+ "BFD_RELOC_NDS32_TLS_LE_20", -+ "BFD_RELOC_NDS32_TLS_LE_15S0", -+ "BFD_RELOC_NDS32_TLS_LE_15S1", -+ "BFD_RELOC_NDS32_TLS_LE_15S2", -++ "BFD_RELOC_NDS32_TLS_LE_ADD", -++ "BFD_RELOC_NDS32_TLS_LE_LS", -++ "BFD_RELOC_NDS32_TLS_IE_HI20", -++ "BFD_RELOC_NDS32_TLS_IE_LO12", -++ "BFD_RELOC_NDS32_TLS_IE_LO12S2", -++ "BFD_RELOC_NDS32_TLS_IEGP_HI20", -++ "BFD_RELOC_NDS32_TLS_IEGP_LO12", -++ "BFD_RELOC_NDS32_TLS_IEGP_LO12S2", -++ "BFD_RELOC_NDS32_TLS_IEGP_LW", -++ "BFD_RELOC_NDS32_TLS_DESC", -++ "BFD_RELOC_NDS32_TLS_DESC_HI20", -++ "BFD_RELOC_NDS32_TLS_DESC_LO12", -++ "BFD_RELOC_NDS32_TLS_DESC_20", -++ "BFD_RELOC_NDS32_TLS_DESC_SDA17S2", -++ "BFD_RELOC_NDS32_TLS_DESC_ADD", -++ "BFD_RELOC_NDS32_TLS_DESC_FUNC", -++ "BFD_RELOC_NDS32_TLS_DESC_CALL", -++ "BFD_RELOC_NDS32_TLS_DESC_MEM", -++ "BFD_RELOC_NDS32_REMOVE", -++ "BFD_RELOC_NDS32_GROUP", -++ "BFD_RELOC_NDS32_ICT", -++ "BFD_RELOC_NDS32_ICT_HI20", -++ "BFD_RELOC_NDS32_ICT_LO12", -++ "BFD_RELOC_NDS32_ICT_25PC", -++ "BFD_RELOC_NDS32_ICT_LO12S2", -++ "BFD_RELOC_NDS32_LSI", -+ "BFD_RELOC_V850_9_PCREL", -+ "BFD_RELOC_V850_22_PCREL", -+ "BFD_RELOC_V850_SDA_16_16_OFFSET", -+diff --git binutils-2.30/bfd/reloc.c binutils-2.30-nds32/bfd/reloc.c -+index a1353a281b..0d96e13027 100644 -+--- binutils-2.30/bfd/reloc.c -++++ binutils-2.30-nds32/bfd/reloc.c -+@@ -4182,6 +4182,10 @@ ENUMDOC -+ This is a 19-bit reloc containing the small data area 19-bit signed offset -+ and shift left by 0 for use in lbi.gp, sbi.gp... -+ ENUM -++ BFD_RELOC_NDS32_SECURITY_16 -++ENUMDOC -++ This is a 24-bit reloc for security check sum. -++ENUM -+ BFD_RELOC_NDS32_GOT20 -+ ENUMX -+ BFD_RELOC_NDS32_9_PLTREL -+@@ -4375,33 +4379,62 @@ ENUMDOC -+ ENUM -+ BFD_RELOC_NDS32_TPOFF -+ ENUMX -++ BFD_RELOC_NDS32_GOTTPOFF -++ENUMX -+ BFD_RELOC_NDS32_TLS_LE_HI20 -+ ENUMX -+ BFD_RELOC_NDS32_TLS_LE_LO12 -+ ENUMX -++ BFD_RELOC_NDS32_TLS_LE_20 -++ENUMX -++ BFD_RELOC_NDS32_TLS_LE_15S0 -++ENUMX -++ BFD_RELOC_NDS32_TLS_LE_15S1 -++ENUMX -++ BFD_RELOC_NDS32_TLS_LE_15S2 -++ENUMX -+ BFD_RELOC_NDS32_TLS_LE_ADD -+ ENUMX -+ BFD_RELOC_NDS32_TLS_LE_LS -+ ENUMX -+- BFD_RELOC_NDS32_GOTTPOFF -+-ENUMX -+ BFD_RELOC_NDS32_TLS_IE_HI20 -+ ENUMX -++ BFD_RELOC_NDS32_TLS_IE_LO12 -++ENUMX -+ BFD_RELOC_NDS32_TLS_IE_LO12S2 -+ ENUMX -+- BFD_RELOC_NDS32_TLS_TPOFF -++ BFD_RELOC_NDS32_TLS_IEGP_HI20 -+ ENUMX -+- BFD_RELOC_NDS32_TLS_LE_20 -++ BFD_RELOC_NDS32_TLS_IEGP_LO12 -+ ENUMX -+- BFD_RELOC_NDS32_TLS_LE_15S0 -++ BFD_RELOC_NDS32_TLS_IEGP_LO12S2 -+ ENUMX -+- BFD_RELOC_NDS32_TLS_LE_15S1 -++ BFD_RELOC_NDS32_TLS_IEGP_LW -+ ENUMX -+- BFD_RELOC_NDS32_TLS_LE_15S2 -++ BFD_RELOC_NDS32_TLS_DESC -++ENUMX -++ BFD_RELOC_NDS32_TLS_DESC_HI20 -++ENUMX -++ BFD_RELOC_NDS32_TLS_DESC_LO12 -++ENUMX -++ BFD_RELOC_NDS32_TLS_DESC_20 -++ENUMX -++ BFD_RELOC_NDS32_TLS_DESC_SDA17S2 -++ENUMX -++ BFD_RELOC_NDS32_TLS_DESC_ADD -++ENUMX -++ BFD_RELOC_NDS32_TLS_DESC_FUNC -++ENUMX -++ BFD_RELOC_NDS32_TLS_DESC_CALL -++ENUMX -++ BFD_RELOC_NDS32_TLS_DESC_MEM -++ENUMX -++ BFD_RELOC_NDS32_REMOVE -++ENUMX -++ BFD_RELOC_NDS32_GROUP -+ ENUMDOC -+ For TLS. -+ -+- -+ ENUM -+ BFD_RELOC_V850_9_PCREL -+ ENUMDOC -+diff --git binutils-2.30/gas/config.in binutils-2.30-nds32/gas/config.in -+index 0855179696..551434a45b 100644 -+--- binutils-2.30/gas/config.in -++++ binutils-2.30-nds32/gas/config.in -+@@ -202,6 +202,9 @@ -+ /* Define default value for nds32_audio_ext */ -+ #undef NDS32_DEFAULT_AUDIO_EXT -+ -++/* Define default value for nds32_dsp_ext */ -++#undef NDS32_DEFAULT_DSP_EXT -++ -+ /* Define default value for nds32_dx_regs */ -+ #undef NDS32_DEFAULT_DX_REGS -+ -+@@ -214,6 +217,12 @@ -+ /* Define default value for nds32_string_ext */ -+ #undef NDS32_DEFAULT_STRING_EXT -+ -++/* Define default value for nds32_zol_ext */ -++#undef NDS32_DEFAULT_ZOL_EXT -++ -++/* Defined for linux toolchain */ -++#undef NDS32_LINUX_TOOLCHAIN -++ -+ /* Define if environ is not declared in system header files. */ -+ #undef NEED_DECLARATION_ENVIRON -+ -+diff --git binutils-2.30/gas/config/tc-nds32.c binutils-2.30-nds32/gas/config/tc-nds32.c -+index b2741b8213..f8cbd80edc 100644 -+--- binutils-2.30/gas/config/tc-nds32.c -++++ binutils-2.30-nds32/gas/config/tc-nds32.c -+@@ -19,6 +19,8 @@ -+ Software Foundation, 51 Franklin Street - Fifth Floor, Boston, MA -+ 02110-1301, USA. */ -+ -++#pragma GCC diagnostic ignored "-Wstack-usage=" -++ -+ #include "as.h" -+ #include "safe-ctype.h" -+ #include "subsegs.h" -+@@ -35,6 +37,8 @@ -+ #include "opcode/nds32.h" -+ -+ #include -++#include -++#include -+ -+ /* GAS definitions. */ -+ -+@@ -66,6 +70,8 @@ struct nds32_relocs_pattern -+ struct nds32_opcode *opcode; -+ char *where; -+ struct nds32_relocs_pattern *next; -++ /* Assembled instruction bytes. */ -++ uint32_t insn; -+ }; -+ -+ /* Suffix name and relocation. */ -+@@ -73,7 +79,6 @@ struct suffix_name -+ { -+ const 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 -+@@ -87,11 +92,7 @@ static struct hash_control *nds32_hint_hash; -+ -+ /* 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 performance. */ -++/* Save option -O for perfomance. */ -+ static int optimize = 0; -+ /* Save option -Os for code size. */ -+ static int optimize_for_space = 0; -+@@ -99,1768 +100,1798 @@ static int optimize_for_space = 0; -+ 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[]; -++extern keyword_t keyword_gpr[]; -+ /* Tag there is relax relocation having to link. */ -+ static bfd_boolean relaxing = FALSE; -++/* Save security status. */ -++static bfd_boolean crcing = FALSE; -++/* Inline asm status. */ -++static bfd_boolean inline_asm = FALSE; -++/* v3 is compatiable with v3f/v3s. */ -++static bfd_boolean compatible_abi = FALSE; -++/* ICT model. */ -++enum ict_option { -++ ICT_NONE = 0, -++ ICT_SMALL, -++ ICT_LARGE -++}; -++static enum ict_option ict_flag = ICT_NONE; -++/* True if ICT existed. */ -++static bfd_boolean ict_exist = FALSE; -+ -+ static struct hash_control *nds32_relax_info_hash; -++/* Branch pattern. */ -+ 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, NDS32_PCREL, BFD_RELOC_NDS32_25_PCREL}, -+- {0, 0, 0, 0} -+- }, /* BR_RANGE_S256 */ -+- { -+- {0, 4, NDS32_PCREL, BFD_RELOC_NDS32_25_PCREL}, -+- {0, 0, 0, 0} -+- }, /* BR_RANGE_S16K */ -+- { -+- {0, 4, NDS32_PCREL, BFD_RELOC_NDS32_25_PCREL}, -+- {0, 0, 0, 0} -+- }, /* BR_RANGE_S64K */ -+- { -+- {0, 4, NDS32_PCREL, 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, NDS32_PCREL, BFD_RELOC_NDS32_17_PCREL}, -+- {0, 0, 0, 0} -+- }, /* BR_RANGE_S256 */ -+- { -+- {0, 4, NDS32_PCREL, BFD_RELOC_NDS32_17_PCREL}, -+- {0, 0, 0, 0} -+- }, /* BR_RANGE_S16K */ -+- { -+- {0, 4, NDS32_PCREL, BFD_RELOC_NDS32_17_PCREL}, -+- {0, 0, 0, 0} -+- }, /* BR_RANGE_S64K */ -+- { -+- {0, 4, NDS32_CREATE_LABEL | NDS32_PCREL, BFD_RELOC_NDS32_17_PCREL}, -+- {0, 4, NDS32_PTR | NDS32_HINT, BFD_RELOC_NDS32_LONGCALL5}, -+- {4, 4, NDS32_PCREL, BFD_RELOC_NDS32_25_PCREL}, -+- {0, 0, 0, 0} -+- }, /* BR_RANGE_S16M */ -+- { -+- {0, 4, NDS32_CREATE_LABEL | NDS32_PCREL, 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, NDS32_PCREL, BFD_RELOC_NDS32_17_PCREL}, -+- {0, 0, 0, 0} -+- }, /* BR_RANGE_S256 */ -+- { -+- {0, 4, NDS32_PCREL, BFD_RELOC_NDS32_17_PCREL}, -+- {0, 0, 0, 0} -+- }, /* BR_RANGE_S16K */ -+- { -+- {0, 4, NDS32_PCREL, BFD_RELOC_NDS32_17_PCREL}, -+- {0, 0, 0, 0} -+- }, /* BR_RANGE_S64K */ -+- { -+- {0, 4, NDS32_CREATE_LABEL | NDS32_PCREL, BFD_RELOC_NDS32_17_PCREL}, -+- {0, 4, NDS32_PTR | NDS32_HINT, BFD_RELOC_NDS32_LONGCALL5}, -+- {4, 4, NDS32_PCREL, BFD_RELOC_NDS32_25_PCREL}, -+- {0, 0, 0, 0} -+- }, /* BR_RANGE_S16M */ -+- { -+- {0, 4, NDS32_CREATE_LABEL | NDS32_PCREL, 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, NDS32_PCREL, BFD_RELOC_NDS32_9_PCREL}, -+- {0, 0, 0, 0} -+- }, /* BR_RANGE_S256 */ -+- { -+- {0, 4, NDS32_PCREL, BFD_RELOC_NDS32_25_PCREL}, -+- {0, 0, 0, 0} -+- }, /* BR_RANGE_S16K */ -+- { -+- {0, 4, NDS32_PCREL, BFD_RELOC_NDS32_25_PCREL}, -+- {0, 0, 0, 0} -+- }, /* BR_RANGE_S64K */ -+- { -+- {0, 4, NDS32_PCREL, 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, NDS32_PCREL, BFD_RELOC_NDS32_9_PCREL}, -+- {0, 0, 0, 0} -+- }, /* BR_RANGE_S256 */ -+- { -+- {0, 4, NDS32_PCREL, BFD_RELOC_NDS32_25_PCREL}, -+- {0, 0, 0, 0} -+- }, /* BR_RANGE_S16K */ -+- { -+- {0, 4, NDS32_PCREL, BFD_RELOC_NDS32_25_PCREL}, -+- {0, 0, 0, 0} -+- }, /* BR_RANGE_S64K */ -+- { -+- {0, 4, NDS32_PCREL, 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, NDS32_PCREL, BFD_RELOC_NDS32_17_PCREL}, -+- {0, 4, NDS32_INSN16 , BFD_RELOC_NDS32_INSN16}, -+- {0, 0, 0, 0} -+- }, /* BR_RANGE_S256 */ -+- { -+- {0, 4, NDS32_PCREL, BFD_RELOC_NDS32_17_PCREL}, -+- {0, 0, 0, 0} -+- }, /* BR_RANGE_S16K */ -+- { -+- {0, 4, NDS32_PCREL, BFD_RELOC_NDS32_17_PCREL}, -+- {0, 0, 0, 0} -+- }, /* BR_RANGE_S64K */ -+- { -+- {0, 4, NDS32_CREATE_LABEL | NDS32_PCREL, 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, NDS32_PCREL, 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 | NDS32_PCREL, 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, NDS32_PCREL, BFD_RELOC_NDS32_17_PCREL}, -+- {0, 0, 0, 0} -+- }, /* BR_RANGE_S256 */ -+- { -+- {0, 4, NDS32_PCREL, BFD_RELOC_NDS32_17_PCREL}, -+- {0, 0, 0, 0} -+- }, /* BR_RANGE_S16K */ -+- { -+- {0, 4, NDS32_PCREL, BFD_RELOC_NDS32_17_PCREL}, -+- {0, 0, 0, 0} -+- }, /* BR_RANGE_S64K */ -+- { -+- {0, 4, NDS32_CREATE_LABEL | NDS32_PCREL, BFD_RELOC_NDS32_15_PCREL}, -+- {0, 4, NDS32_PTR | NDS32_HINT, BFD_RELOC_NDS32_LONGJUMP5}, -+- {4, 4, NDS32_PCREL, BFD_RELOC_NDS32_25_PCREL}, -+- {0, 0, 0, 0} -+- }, /* BR_RANGE_S16M */ -+- { -+- {0, 4, NDS32_CREATE_LABEL | NDS32_PCREL, 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, NDS32_PCREL, BFD_RELOC_NDS32_17_PCREL}, -+- {0, 4, NDS32_INSN16 , BFD_RELOC_NDS32_INSN16}, -+- {0, 0, 0, 0} -+- }, /* BR_RANGE_S256 */ -+- { -+- {0, 4, NDS32_PCREL, BFD_RELOC_NDS32_17_PCREL}, -+- {0, 0, 0, 0} -+- }, /* BR_RANGE_S16K */ -+- { -+- {0, 4, NDS32_PCREL, BFD_RELOC_NDS32_17_PCREL}, -+- {0, 0, 0, 0} -+- }, /* BR_RANGE_S64K */ -+- { -+- {0, 4, NDS32_CREATE_LABEL | NDS32_PCREL, 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, NDS32_PCREL, 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 | NDS32_PCREL, 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, NDS32_PCREL, BFD_RELOC_NDS32_17_PCREL}, -+- {0, 0, 0, 0} -+- }, /* BR_RANGE_S256 */ -+- { -+- {0, 4, NDS32_PCREL, BFD_RELOC_NDS32_17_PCREL}, -+- {0, 0, 0, 0} -+- }, /* BR_RANGE_S16K */ -+- { -+- {0, 4, NDS32_PCREL, BFD_RELOC_NDS32_17_PCREL}, -+- {0, 0, 0, 0} -+- }, /* BR_RANGE_S64K */ -+- { -+- {0, 4, NDS32_CREATE_LABEL | NDS32_PCREL, BFD_RELOC_NDS32_15_PCREL}, -+- {0, 4, NDS32_PTR | NDS32_HINT, BFD_RELOC_NDS32_LONGJUMP5}, -+- {4, 4, NDS32_PCREL, BFD_RELOC_NDS32_25_PCREL}, -+- {0, 0, 0, 0} -+- }, /* BR_RANGE_S16M */ -+- { -+- {0, 4, NDS32_CREATE_LABEL | NDS32_PCREL, 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, NDS32_PCREL, BFD_RELOC_NDS32_17_PCREL}, -+- {0, 0, 0, 0} -+- }, /* BR_RANGE_S256 */ -+- { -+- {0, 4, NDS32_PCREL, BFD_RELOC_NDS32_17_PCREL}, -+- {0, 0, 0, 0} -+- }, /* BR_RANGE_S16K */ -+- { -+- {0, 4, NDS32_PCREL, BFD_RELOC_NDS32_17_PCREL}, -+- {0, 0, 0, 0} -+- }, /* BR_RANGE_S64K */ -+- { -+- {0, 4, NDS32_CREATE_LABEL | NDS32_PCREL, BFD_RELOC_NDS32_15_PCREL}, -+- {0, 4, NDS32_PTR | NDS32_HINT, BFD_RELOC_NDS32_LONGJUMP5}, -+- {4, 4, NDS32_PCREL, BFD_RELOC_NDS32_25_PCREL}, -+- {0, 0, 0, 0} -+- }, /* BR_RANGE_S16M */ -+- { -+- {0, 4, NDS32_CREATE_LABEL | NDS32_PCREL, 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, NDS32_PCREL, BFD_RELOC_NDS32_17_PCREL}, -+- {0, 0, 0, 0} -+- }, /* BR_RANGE_S256 */ -+- { -+- {0, 4, NDS32_PCREL, BFD_RELOC_NDS32_17_PCREL}, -+- {0, 0, 0, 0} -+- }, /* BR_RANGE_S16K */ -+- { -+- {0, 4, NDS32_PCREL, BFD_RELOC_NDS32_17_PCREL}, -+- {0, 0, 0, 0} -+- }, /* BR_RANGE_S64K */ -+- { -+- {0, 4, NDS32_CREATE_LABEL | NDS32_PCREL, BFD_RELOC_NDS32_15_PCREL}, -+- {0, 4, NDS32_PTR | NDS32_HINT, BFD_RELOC_NDS32_LONGJUMP5}, -+- {4, 4, NDS32_PCREL, BFD_RELOC_NDS32_25_PCREL}, -+- {0, 0, 0, 0} -+- }, /* BR_RANGE_S16M */ -+- { -+- {0, 4, NDS32_CREATE_LABEL | NDS32_PCREL, 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, NDS32_PCREL, BFD_RELOC_NDS32_15_PCREL}, -+- {0, 4, NDS32_INSN16, BFD_RELOC_NDS32_INSN16}, -+- {0, 0, 0, 0} -+- }, /* BR_RANGE_S256 */ -+- { -+- {0, 4, NDS32_PCREL, BFD_RELOC_NDS32_15_PCREL}, -+- {0, 0, 0, 0} -+- }, /* BR_RANGE_S16K */ -+- { -+- {0, 4, NDS32_CREATE_LABEL | NDS32_PCREL, 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, NDS32_PCREL, 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 | NDS32_PCREL, 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, NDS32_PCREL, 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 | NDS32_PCREL, 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, NDS32_PCREL, BFD_RELOC_NDS32_15_PCREL}, -+- {0, 4, NDS32_INSN16, BFD_RELOC_NDS32_INSN16}, -+- {0, 0, 0, 0} -+- }, /* BR_RANGE_S256 */ -+- { -+- {0, 4, NDS32_PCREL, BFD_RELOC_NDS32_15_PCREL}, -+- {0, 0, 0, 0} -+- }, /* BR_RANGE_S16K */ -+- { -+- {0, 4, NDS32_CREATE_LABEL | NDS32_PCREL, 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, NDS32_PCREL, 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 | NDS32_PCREL, 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, NDS32_PCREL, 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 | NDS32_PCREL, 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, NDS32_PCREL, BFD_RELOC_NDS32_9_PCREL}, -+- {0, 0, 0, 0} -+- }, /* BR_RANGE_S256 */ -+- { -+- {0, 4, NDS32_PCREL, BFD_RELOC_NDS32_17_PCREL}, -+- {0, 0, 0, 0} -+- }, /* BR_RANGE_S16K */ -+- { -+- {0, 4, NDS32_PCREL, BFD_RELOC_NDS32_17_PCREL}, -+- {0, 0, 0, 0} -+- }, /* BR_RANGE_S64K */ -+- { -+- {0, 4, NDS32_CREATE_LABEL | NDS32_PCREL, 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, NDS32_PCREL, 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 | NDS32_PCREL, 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 */ -++ .opcode = "jal", -++ .br_range = BR_RANGE_S16M, -++ .cond_field = { -++ {0, 0, 0, FALSE} -++ }, -++ .relax_code_seq[BR_RANGE_S256] = { -++ INSN_JAL}, /* jal label */ -++ .relax_code_size[BR_RANGE_S256] = 4, -++ .relax_branch_isize[BR_RANGE_S256] = 4, -++ .relax_fixup[BR_RANGE_S256] = { -++ {0, 4, NDS32_PCREL, BFD_RELOC_NDS32_25_PCREL}, -++ {0, 0, 0, 0} -++ }, -++ -++ .relax_code_seq[BR_RANGE_S16K] = { -++ INSN_JAL}, /* jal label */ -++ .relax_code_size[BR_RANGE_S16K] = 4, -++ .relax_branch_isize[BR_RANGE_S16K] = 4, -++ .relax_fixup[BR_RANGE_S16K] = { -++ {0, 4, NDS32_PCREL, BFD_RELOC_NDS32_25_PCREL}, -++ {0, 0, 0, 0} -++ }, -++ -++ .relax_code_seq[BR_RANGE_S64K] = { -++ INSN_JAL}, /* jal label */ -++ .relax_code_size[BR_RANGE_S64K] = 4, -++ .relax_branch_isize[BR_RANGE_S64K] = 4, -++ .relax_fixup[BR_RANGE_S64K] = { -++ {0, 4, NDS32_PCREL, BFD_RELOC_NDS32_25_PCREL}, -++ {0, 0, 0, 0} -++ }, -++ -++ .relax_code_seq[BR_RANGE_S16M] = { -++ INSN_JAL}, /* jal label */ -++ .relax_code_size[BR_RANGE_S16M] = 4, -++ .relax_branch_isize[BR_RANGE_S16M] = 4, -++ .relax_fixup[BR_RANGE_S16M] = { -++ {0, 4, NDS32_PCREL, BFD_RELOC_NDS32_25_PCREL}, -++ {0, 0, 0, 0} -++ }, -++ -++ .relax_code_seq[BR_RANGE_U4G] = { -++ INSN_SETHI_TA, /* sethi $ta, label */ -++ INSN_ORI_TA, /* ori $ta, $ta, label */ -++ INSN_JRAL_TA}, /* jral $ta */ -++ .relax_code_size[BR_RANGE_U4G] = 12, -++ .relax_branch_isize[BR_RANGE_U4G] = 4, -++ .relax_fixup[BR_RANGE_U4G] = { -++ {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} -++ }, -++ }, -+ { -+- { -+- {0, 2, NDS32_PCREL, BFD_RELOC_NDS32_9_PCREL}, -+- {0, 0, 0, 0} -+- }, /* BR_RANGE_S256 */ -+- { -+- {0, 4, NDS32_PCREL, BFD_RELOC_NDS32_17_PCREL}, -+- {0, 0, 0, 0} -+- }, /* BR_RANGE_S16K */ -+- { -+- {0, 4, NDS32_PCREL, BFD_RELOC_NDS32_17_PCREL}, -+- {0, 0, 0, 0} -+- }, /* BR_RANGE_S64K */ -+- { -+- {0, 4, NDS32_CREATE_LABEL | NDS32_PCREL, 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, NDS32_PCREL, 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 | NDS32_PCREL, 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 */ -++ .opcode = "bgezal", -++ .br_range = BR_RANGE_S64K, -++ .cond_field = { -++ {0, 20, 0x1F, FALSE}, -++ {0, 0, 0, FALSE} -++ }, -++ .relax_code_seq[BR_RANGE_S256] = { -++ INSN_BGEZAL}, /* bgezal $rt, label */ -++ .relax_code_condition[BR_RANGE_S256] = { -++ {0, 20, 0x1F, FALSE}, -++ {0, 0, 0, FALSE}, -++ }, -++ .relax_code_size[BR_RANGE_S256] = 4, -++ .relax_branch_isize[BR_RANGE_S256] = 4, -++ .relax_fixup[BR_RANGE_S256] = { -++ {0, 4, NDS32_PCREL, BFD_RELOC_NDS32_17_PCREL}, -++ {0, 0, 0, 0} -++ }, -++ -++ .relax_code_seq[BR_RANGE_S16K] = { -++ INSN_BGEZAL}, /* bgezal $rt, label */ -++ .relax_code_condition[BR_RANGE_S16K] = { -++ {0, 20, 0x1F, FALSE}, -++ {0, 0, 0, FALSE}, -++ }, -++ .relax_code_size[BR_RANGE_S16K] = 4, -++ .relax_branch_isize[BR_RANGE_S16K] = 4, -++ .relax_fixup[BR_RANGE_S16K] = { -++ {0, 4, NDS32_PCREL, BFD_RELOC_NDS32_17_PCREL}, -++ {0, 0, 0, 0} -++ }, -++ -++ .relax_code_seq[BR_RANGE_S64K] = { -++ INSN_BGEZAL}, /* bgezal $rt, label */ -++ .relax_code_condition[BR_RANGE_S64K] = { -++ {0, 20, 0x1F, FALSE}, -++ {0, 0, 0, FALSE}, -++ }, -++ .relax_code_size[BR_RANGE_S64K] = 4, -++ .relax_branch_isize[BR_RANGE_S64K] = 4, -++ .relax_fixup[BR_RANGE_S64K] = { -++ {0, 4, NDS32_PCREL, BFD_RELOC_NDS32_17_PCREL}, -++ {0, 0, 0, 0} -++ }, -++ -++ .relax_code_seq[BR_RANGE_S16M] = { -++ INSN_BLTZ, /* bltz $rt, $1 */ -++ INSN_JAL}, /* jal label */ -++ .relax_code_condition[BR_RANGE_S16M] = { -++ {0, 20, 0x1F, FALSE}, -++ {0, 0, 0, FALSE}, -++ }, -++ .relax_code_size[BR_RANGE_S16M] = 8, -++ .relax_branch_isize[BR_RANGE_S16M] = 4, -++ .relax_fixup[BR_RANGE_S16M] = { -++ {0, 4, NDS32_CREATE_LABEL | NDS32_PCREL, BFD_RELOC_NDS32_17_PCREL}, -++ {0, 4, NDS32_PTR | NDS32_HINT, BFD_RELOC_NDS32_LONGCALL5}, -++ {4, 4, NDS32_PCREL, BFD_RELOC_NDS32_25_PCREL}, -++ {0, 0, 0, 0} -++ }, -++ -++ .relax_code_seq[BR_RANGE_U4G] = { -++ INSN_BLTZ, /* bltz $rt, $1 */ -++ INSN_SETHI_TA, /* sethi $ta, label */ -++ INSN_ORI_TA, /* ori $ta, $ta, label */ -++ INSN_JRAL_TA}, /* jral $ta */ -++ .relax_code_condition[BR_RANGE_U4G] = { -++ {0, 20, 0x1F, FALSE}, -++ {0, 0, 0, FALSE}, -++ }, -++ .relax_code_size[BR_RANGE_U4G] = 16, -++ .relax_branch_isize[BR_RANGE_U4G] = 4, -++ .relax_fixup[BR_RANGE_U4G] = { -++ {0, 4, NDS32_CREATE_LABEL | NDS32_PCREL, 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} -++ }, -++ }, -+ { -+- { -+- 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 */ -++ .opcode = "bltzal", -++ .br_range = BR_RANGE_S64K, -++ .cond_field = { -++ {0, 20, 0x1F, FALSE}, -++ {0, 0, 0, FALSE} -++ }, -++ .relax_code_seq[BR_RANGE_S256] = { -++ INSN_BLTZAL}, /* bltzal $rt, label */ -++ .relax_code_condition[BR_RANGE_S256] = { -++ {0, 20, 0x1F, FALSE}, -++ {0, 0, 0, FALSE}, -++ }, -++ .relax_code_size[BR_RANGE_S256] = 4, -++ .relax_branch_isize[BR_RANGE_S256] = 4, -++ .relax_fixup[BR_RANGE_S256] = { -++ {0, 4, NDS32_PCREL, BFD_RELOC_NDS32_17_PCREL}, -++ {0, 0, 0, 0} -++ }, -++ -++ .relax_code_seq[BR_RANGE_S16K] = { -++ INSN_BLTZAL}, /* bltzal $rt, label */ -++ .relax_code_condition[BR_RANGE_S16K] = { -++ {0, 20, 0x1F, FALSE}, -++ {0, 0, 0, FALSE}, -++ }, -++ .relax_code_size[BR_RANGE_S16K] = 4, -++ .relax_branch_isize[BR_RANGE_S16K] = 4, -++ .relax_fixup[BR_RANGE_S16K] = { -++ {0, 4, NDS32_PCREL, BFD_RELOC_NDS32_17_PCREL}, -++ {0, 0, 0, 0} -++ }, -++ -++ .relax_code_seq[BR_RANGE_S64K] = { -++ INSN_BLTZAL}, /* bltzal $rt, label */ -++ .relax_code_condition[BR_RANGE_S64K] = { -++ {0, 20, 0x1F, FALSE}, -++ {0, 0, 0, FALSE}, -++ }, -++ .relax_code_size[BR_RANGE_S64K] = 4, -++ .relax_branch_isize[BR_RANGE_S64K] = 4, -++ .relax_fixup[BR_RANGE_S64K] = { -++ {0, 4, NDS32_PCREL, BFD_RELOC_NDS32_17_PCREL}, -++ {0, 0, 0, 0} -++ }, -++ -++ .relax_code_seq[BR_RANGE_S16M] = { -++ INSN_BGEZ, /* bgez $rt, $1 */ -++ INSN_JAL}, /* jal label */ -++ .relax_code_condition[BR_RANGE_S16M] = { -++ {0, 20, 0x1F, FALSE}, -++ {0, 0, 0, FALSE}, -++ }, -++ .relax_code_size[BR_RANGE_S16M] = 8, -++ .relax_branch_isize[BR_RANGE_S16M] = 4, -++ .relax_fixup[BR_RANGE_S16M] = { -++ {0, 4, NDS32_CREATE_LABEL | NDS32_PCREL, BFD_RELOC_NDS32_17_PCREL}, -++ {0, 4, NDS32_PTR | NDS32_HINT, BFD_RELOC_NDS32_LONGCALL5}, -++ {4, 4, NDS32_PCREL, BFD_RELOC_NDS32_25_PCREL}, -++ {0, 0, 0, 0} -++ }, -++ -++ .relax_code_seq[BR_RANGE_U4G] = { -++ INSN_BGEZ, /* bgez $rt, $1 */ -++ INSN_SETHI_TA, /* sethi $ta, label */ -++ INSN_ORI_TA, /* ori $ta, $ta, label */ -++ INSN_JRAL_TA}, /* jral $ta */ -++ .relax_code_condition[BR_RANGE_U4G] = { -++ {0, 20, 0x1F, FALSE}, -++ {0, 0, 0, FALSE}, -++ }, -++ .relax_code_size[BR_RANGE_U4G] = 16, -++ .relax_branch_isize[BR_RANGE_U4G] = 4, -++ .relax_fixup[BR_RANGE_U4G] = { -++ {0, 4, NDS32_CREATE_LABEL | NDS32_PCREL, 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} -++ }, -++ }, -+ { -+- { -+- {0, 2, NDS32_PCREL, BFD_RELOC_NDS32_9_PCREL}, -+- {0, 0, 0, 0} -+- }, /* BR_RANGE_S256 */ -+- { -+- {0, 4, NDS32_PCREL, BFD_RELOC_NDS32_17_PCREL}, -+- {0, 0, 0, 0} -+- }, /* BR_RANGE_S16K */ -+- { -+- {0, 4, NDS32_PCREL, BFD_RELOC_NDS32_17_PCREL}, -+- {0, 0, 0, 0} -+- }, /* BR_RANGE_S64K */ -+- { -+- {0, 4, NDS32_CREATE_LABEL | NDS32_PCREL, 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, NDS32_PCREL, 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 | NDS32_PCREL, 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 */ -++ .opcode = "j", -++ .br_range = BR_RANGE_S16M, -++ .cond_field = { -++ {0, 0, 0, FALSE} -++ }, -++ .relax_code_seq[BR_RANGE_S256] = { -++ (INSN_J8 << 16)}, /* j8 label */ -++ .relax_code_size[BR_RANGE_S256] = 2, -++ .relax_branch_isize[BR_RANGE_S256] = 2, -++ .relax_fixup[BR_RANGE_S256] = { -++ {0, 2, NDS32_PCREL, BFD_RELOC_NDS32_9_PCREL}, -++ {0, 0, 0, 0} -++ }, -++ -++ .relax_code_seq[BR_RANGE_S16K] = { -++ INSN_J}, /* j label */ -++ .relax_code_size[BR_RANGE_S16K] = 4, -++ .relax_branch_isize[BR_RANGE_S16K] = 4, -++ .relax_fixup[BR_RANGE_S16K] = { -++ {0, 4, NDS32_PCREL, BFD_RELOC_NDS32_25_PCREL}, -++ {0, 0, 0, 0} -++ }, -++ -++ .relax_code_seq[BR_RANGE_S64K] = { -++ INSN_J}, /* j label */ -++ .relax_code_size[BR_RANGE_S64K] = 4, -++ .relax_branch_isize[BR_RANGE_S64K] = 4, -++ .relax_fixup[BR_RANGE_S64K] = { -++ {0, 4, NDS32_PCREL, BFD_RELOC_NDS32_25_PCREL}, -++ {0, 0, 0, 0} -++ }, -++ -++ .relax_code_seq[BR_RANGE_S16M] = { -++ INSN_J}, /* j label */ -++ .relax_code_size[BR_RANGE_S16M] = 4, -++ .relax_branch_isize[BR_RANGE_S16M] = 4, -++ .relax_fixup[BR_RANGE_S16M] = { -++ {0, 4, NDS32_PCREL, BFD_RELOC_NDS32_25_PCREL}, -++ {0, 0, 0, 0} -++ }, -++ -++ .relax_code_seq[BR_RANGE_U4G] = { -++ INSN_SETHI_TA, /* sethi $ta, label */ -++ INSN_ORI_TA, /* ori $ta, $ta, label */ -++ INSN_JR_TA}, /* jr $ta */ -++ .relax_code_size[BR_RANGE_U4G] = 12, -++ .relax_branch_isize[BR_RANGE_U4G] = 4, -++ .relax_fixup[BR_RANGE_U4G] = { -++ {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} -++ }, -++ }, -+ { -+- { -+- 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 */ -++ .opcode = "j8", -++ .br_range = BR_RANGE_S256, -++ .cond_field = { -++ {0, 0, 0, FALSE} -++ }, -++ .relax_code_seq[BR_RANGE_S256] = { -++ (INSN_J8 << 16)}, /* j8 label */ -++ .relax_code_size[BR_RANGE_S256] = 2, -++ .relax_branch_isize[BR_RANGE_S256] = 2, -++ .relax_fixup[BR_RANGE_S256] = { -++ {0, 2, NDS32_PCREL, BFD_RELOC_NDS32_9_PCREL}, -++ {0, 0, 0, 0} -++ }, -++ -++ .relax_code_seq[BR_RANGE_S16K] = { -++ INSN_J}, /* j label */ -++ .relax_code_size[BR_RANGE_S16K] = 4, -++ .relax_branch_isize[BR_RANGE_S16K] = 4, -++ .relax_fixup[BR_RANGE_S16K] = { -++ {0, 4, NDS32_PCREL, BFD_RELOC_NDS32_25_PCREL}, -++ {0, 0, 0, 0} -++ }, -++ -++ .relax_code_seq[BR_RANGE_S64K] = { -++ INSN_J}, /* j label */ -++ .relax_code_size[BR_RANGE_S64K] = 4, -++ .relax_branch_isize[BR_RANGE_S64K] = 4, -++ .relax_fixup[BR_RANGE_S64K] = { -++ {0, 4, NDS32_PCREL, BFD_RELOC_NDS32_25_PCREL}, -++ {0, 0, 0, 0} -++ }, -++ -++ .relax_code_seq[BR_RANGE_S16M] = { -++ INSN_J}, /* j label */ -++ .relax_code_size[BR_RANGE_S16M] = 4, -++ .relax_branch_isize[BR_RANGE_S16M] = 4, -++ .relax_fixup[BR_RANGE_S16M] = { -++ {0, 4, NDS32_PCREL, BFD_RELOC_NDS32_25_PCREL}, -++ {0, 0, 0, 0} -++ }, -++ -++ .relax_code_seq[BR_RANGE_U4G] = { -++ INSN_SETHI_TA, /* sethi $ta, label */ -++ INSN_ORI_TA, /* ori $ta, $ta, label */ -++ INSN_JR_TA}, /* jr $ta */ -++ .relax_code_size[BR_RANGE_U4G] = 12, -++ .relax_branch_isize[BR_RANGE_U4G] = 4, -++ .relax_fixup[BR_RANGE_U4G] = { -++ {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} -++ }, -++ }, -+ { -+- { -+- {0, 2, NDS32_PCREL, BFD_RELOC_NDS32_9_PCREL}, -+- {0, 0, 0, 0} -+- }, /* BR_RANGE_S256 */ -+- { -+- {0, 4, NDS32_PCREL, BFD_RELOC_NDS32_17_PCREL}, -+- {0, 0, 0, 0} -+- }, /* BR_RANGE_S16K */ -+- { -+- {0, 4, NDS32_PCREL, BFD_RELOC_NDS32_17_PCREL}, -+- {0, 0, 0, 0} -+- }, /* BR_RANGE_S64K */ -+- { -+- {0, 4, NDS32_CREATE_LABEL | NDS32_PCREL, 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, NDS32_PCREL, 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 | NDS32_PCREL, 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 */ -++ .opcode = "beqz", -++ .br_range = BR_RANGE_S64K, -++ .cond_field = { -++ {0, 20, 0x1F, FALSE}, -++ {0, 0, 0, FALSE} -++ }, -++ /* We do not use beqz38 and beqzs8 here directly because we -++ don't want to check register number for specail condition. */ -++ .relax_code_seq[BR_RANGE_S256] = { -++ INSN_BEQZ}, /* beqz $rt, label */ -++ .relax_code_condition[BR_RANGE_S256] = { -++ {0, 20, 0x1F, FALSE}, -++ {0, 0, 0, FALSE}, -++ }, -++ .relax_code_size[BR_RANGE_S256] = 4, -++ .relax_branch_isize[BR_RANGE_S256] = 4, -++ .relax_fixup[BR_RANGE_S256] = { -++ {0, 4, NDS32_PCREL, BFD_RELOC_NDS32_17_PCREL}, -++ {0, 4, NDS32_INSN16 , BFD_RELOC_NDS32_INSN16}, -++ {0, 0, 0, 0} -++ }, -++ -++ .relax_code_seq[BR_RANGE_S16K] = { -++ INSN_BEQZ}, /* beqz $rt, label */ -++ .relax_code_condition[BR_RANGE_S16K] = { -++ {0, 20, 0x1F, FALSE}, -++ {0, 0, 0, FALSE}, -++ }, -++ .relax_code_size[BR_RANGE_S16K] = 4, -++ .relax_branch_isize[BR_RANGE_S16K] = 4, -++ .relax_fixup[BR_RANGE_S16K] = { -++ {0, 4, NDS32_PCREL, BFD_RELOC_NDS32_17_PCREL}, -++ {0, 0, 0, 0} -++ }, -++ -++ .relax_code_seq[BR_RANGE_S64K] = { -++ INSN_BEQZ}, /* beqz $rt, label */ -++ .relax_code_condition[BR_RANGE_S64K] = { -++ {0, 20, 0x1F, FALSE}, -++ {0, 0, 0, FALSE}, -++ }, -++ .relax_code_size[BR_RANGE_S64K] = 4, -++ .relax_branch_isize[BR_RANGE_S64K] = 4, -++ .relax_fixup[BR_RANGE_S64K] = { -++ {0, 4, NDS32_PCREL, BFD_RELOC_NDS32_17_PCREL}, -++ {0, 0, 0, 0} -++ }, -++ -++ .relax_code_seq[BR_RANGE_S16M] = { -++ INSN_BNEZ, /* bnez $rt, $1 */ -++ INSN_J}, /* j label */ -++ .relax_code_condition[BR_RANGE_S16M] = { -++ {0, 20, 0x1F, FALSE}, -++ {0, 0, 0, FALSE}, -++ }, -++ .relax_code_size[BR_RANGE_S16M] = 8, -++ .relax_branch_isize[BR_RANGE_S16M] = 4, -++ .relax_fixup[BR_RANGE_S16M] = { -++ /* bnez range is 17 pcrel, but it use 15 pcrel here since link time -++ relaxtion. If 17 pcrel can reach, it do not have to -++ use S16M. Therefore, 15 pcrel is just for linker to -++ distinguish LONGJUMP5 and LONGJUMP6. */ -++ {0, 4, NDS32_CREATE_LABEL | NDS32_PCREL, 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, NDS32_PCREL, BFD_RELOC_NDS32_25_PCREL}, -++ {4, 4, NDS32_INSN16 | NDS32_HINT, BFD_RELOC_NDS32_INSN16}, -++ {0, 0, 0, 0} -++ }, -++ -++ .relax_code_seq[BR_RANGE_U4G] = { -++ INSN_BNEZ, /* bnez $rt, $1 */ -++ INSN_SETHI_TA, /* sethi $ta, label */ -++ INSN_ORI_TA, /* ori $ta, $ta, label */ -++ INSN_JR_TA}, /* jr $ta */ -++ .relax_code_condition[BR_RANGE_U4G] = { -++ {0, 20, 0x1F, FALSE}, -++ {0, 0, 0, FALSE}, -++ }, -++ .relax_code_size[BR_RANGE_U4G] = 16, -++ .relax_branch_isize[BR_RANGE_U4G] = 4, -++ .relax_fixup[BR_RANGE_U4G] = { -++ {0, 4, NDS32_CREATE_LABEL | NDS32_PCREL, 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} -++ }, -++ }, -+ { -+- {0, 8, 0x7, FALSE}, -+- {0, 0, 0, FALSE} -+- }, /* cond_field */ -++ .opcode = "bgez", -++ .br_range = BR_RANGE_S64K, -++ .cond_field = { -++ {0, 20, 0x1F, FALSE}, -++ {0, 0, 0, FALSE} -++ }, -++ .relax_code_seq[BR_RANGE_S256] = { -++ INSN_BGEZ}, /* bgez $rt, label */ -++ .relax_code_condition[BR_RANGE_S256] = { -++ {0, 20, 0x1F, FALSE}, -++ {0, 0, 0, FALSE}, -++ }, -++ .relax_code_size[BR_RANGE_S256] = 4, -++ .relax_branch_isize[BR_RANGE_S256] = 4, -++ .relax_fixup[BR_RANGE_S256] = { -++ {0, 4, NDS32_PCREL, BFD_RELOC_NDS32_17_PCREL}, -++ {0, 0, 0, 0} -++ }, -++ -++ .relax_code_seq[BR_RANGE_S16K] = { -++ INSN_BGEZ}, /* bgez $rt, label */ -++ .relax_code_condition[BR_RANGE_S16K] = { -++ {0, 20, 0x1F, FALSE}, -++ {0, 0, 0, FALSE}, -++ }, -++ .relax_code_size[BR_RANGE_S16K] = 4, -++ .relax_branch_isize[BR_RANGE_S16K] = 4, -++ .relax_fixup[BR_RANGE_S16K] = { -++ {0, 4, NDS32_PCREL, BFD_RELOC_NDS32_17_PCREL}, -++ {0, 0, 0, 0} -++ }, -++ -++ .relax_code_seq[BR_RANGE_S64K] = { -++ INSN_BGEZ}, /* bgez $rt, label */ -++ .relax_code_condition[BR_RANGE_S64K] = { -++ {0, 20, 0x1F, FALSE}, -++ {0, 0, 0, FALSE}, -++ }, -++ .relax_code_size[BR_RANGE_S64K] = 4, -++ .relax_branch_isize[BR_RANGE_S64K] = 4, -++ .relax_fixup[BR_RANGE_S64K] = { -++ {0, 4, NDS32_PCREL, BFD_RELOC_NDS32_17_PCREL}, -++ {0, 0, 0, 0} -++ }, -++ -++ .relax_code_seq[BR_RANGE_S16M] = { -++ INSN_BLTZ, /* bltz $rt, $1 */ -++ INSN_J}, /* j label */ -++ .relax_code_condition[BR_RANGE_S16M] = { -++ {0, 20, 0x1F, FALSE}, -++ {0, 0, 0, FALSE}, -++ }, -++ .relax_code_size[BR_RANGE_S16M] = 8, -++ .relax_branch_isize[BR_RANGE_S16M] = 4, -++ .relax_fixup[BR_RANGE_S16M] = { -++ {0, 4, NDS32_CREATE_LABEL | NDS32_PCREL, BFD_RELOC_NDS32_15_PCREL}, -++ {0, 4, NDS32_PTR | NDS32_HINT, BFD_RELOC_NDS32_LONGJUMP5}, -++ {4, 4, NDS32_PCREL, BFD_RELOC_NDS32_25_PCREL}, -++ {0, 0, 0, 0} -++ }, -++ .relax_code_seq[BR_RANGE_U4G] = { -++ INSN_BLTZ, /* bltz $rt, $1 */ -++ INSN_SETHI_TA, /* sethi $ta, label */ -++ INSN_ORI_TA, /* ori $ta, $ta, label */ -++ INSN_JR_TA}, /* jr $ta */ -++ .relax_code_condition[BR_RANGE_U4G] = { -++ {0, 20, 0x1F, FALSE}, -++ {0, 0, 0, FALSE}, -++ }, -++ .relax_code_size[BR_RANGE_U4G] = 16, -++ .relax_branch_isize[BR_RANGE_U4G] = 4, -++ .relax_fixup[BR_RANGE_U4G] = { -++ {0, 4, NDS32_CREATE_LABEL | NDS32_PCREL, 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} -++ }, -++ }, -+ { -+- { -+- 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 */ -++ .opcode = "bnez", -++ .br_range = BR_RANGE_S64K, -++ .cond_field = { -++ {0, 20, 0x1F, FALSE}, -++ {0, 0, 0, FALSE} -++ }, -++ .relax_code_seq[BR_RANGE_S256] = { -++ INSN_BNEZ}, /* bnez $rt, label */ -++ .relax_code_condition[BR_RANGE_S256] = { -++ {0, 20, 0x1F, FALSE}, -++ {0, 0, 0, FALSE}, -++ }, -++ .relax_code_size[BR_RANGE_S256] = 4, -++ .relax_branch_isize[BR_RANGE_S256] = 4, -++ .relax_fixup[BR_RANGE_S256] = { -++ {0, 4, NDS32_PCREL, BFD_RELOC_NDS32_17_PCREL}, -++ {0, 4, NDS32_INSN16, BFD_RELOC_NDS32_INSN16}, -++ {0, 0, 0, 0} -++ }, -++ -++ .relax_code_seq[BR_RANGE_S16K] = { -++ INSN_BNEZ}, /* bnez $rt, label */ -++ .relax_code_condition[BR_RANGE_S16K] = { -++ {0, 20, 0x1F, FALSE}, -++ {0, 0, 0, FALSE}, -++ }, -++ .relax_code_size[BR_RANGE_S16K] = 4, -++ .relax_branch_isize[BR_RANGE_S16K] = 4, -++ .relax_fixup[BR_RANGE_S16K] = { -++ {0, 4, NDS32_PCREL, BFD_RELOC_NDS32_17_PCREL}, -++ {0, 0, 0, 0} -++ }, -++ -++ .relax_code_seq[BR_RANGE_S64K] = { -++ INSN_BNEZ}, /* bnez $rt, label */ -++ .relax_code_condition[BR_RANGE_S64K] = { -++ {0, 20, 0x1F, FALSE}, -++ {0, 0, 0, FALSE}, -++ }, -++ .relax_code_size[BR_RANGE_S64K] = 4, -++ .relax_branch_isize[BR_RANGE_S64K] = 4, -++ .relax_fixup[BR_RANGE_S64K] = { -++ {0, 4, NDS32_PCREL, BFD_RELOC_NDS32_17_PCREL}, -++ {0, 0, 0, 0} -++ }, -++ -++ .relax_code_seq[BR_RANGE_S16M] = { -++ INSN_BEQZ, /* beqz $rt, $1 */ -++ INSN_J}, /* j label */ -++ .relax_code_condition[BR_RANGE_S16M] = { -++ {0, 20, 0x1F, FALSE}, -++ {0, 0, 0, FALSE}, -++ }, -++ .relax_code_size[BR_RANGE_S16M] = 8, -++ .relax_branch_isize[BR_RANGE_S16M] = 4, -++ .relax_fixup[BR_RANGE_S16M] = { -++ {0, 4, NDS32_CREATE_LABEL | NDS32_PCREL, 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, NDS32_PCREL, BFD_RELOC_NDS32_25_PCREL}, -++ {4, 4, NDS32_INSN16 | NDS32_HINT, BFD_RELOC_NDS32_INSN16}, -++ {0, 0, 0, 0} -++ }, -++ -++ .relax_code_seq[BR_RANGE_U4G] = { -++ INSN_BEQZ, /* beqz $rt, $1 */ -++ INSN_SETHI_TA, /* sethi $ta, label */ -++ INSN_ORI_TA, /* ori $ta, $ta, label */ -++ INSN_JR_TA}, /* jr $ta */ -++ .relax_code_condition[BR_RANGE_U4G] = { -++ {0, 20, 0x1F, FALSE}, -++ {0, 0, 0, FALSE}, -++ }, -++ .relax_code_size[BR_RANGE_U4G] = 16, -++ .relax_branch_isize[BR_RANGE_U4G] = 4, -++ .relax_fixup[BR_RANGE_U4G] = { -++ {0, 4, NDS32_CREATE_LABEL | NDS32_PCREL, 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} -++ }, -++ }, -+ { -+- { -+- {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 */ -++ .opcode = "bgtz", -++ .br_range = BR_RANGE_S64K, -++ .cond_field = { -++ {0, 20, 0x1F, FALSE}, -++ {0, 0, 0, FALSE} -++ }, -++ .relax_code_seq[BR_RANGE_S256] = { -++ INSN_BGTZ}, /* bgtz $rt, label */ -++ .relax_code_condition[BR_RANGE_S256] = { -++ {0, 20, 0x1F, FALSE}, -++ {0, 0, 0, FALSE}, -++ }, -++ .relax_code_size[BR_RANGE_S256] = 4, -++ .relax_branch_isize[BR_RANGE_S256] = 4, -++ .relax_fixup[BR_RANGE_S256] = { -++ {0, 4, NDS32_PCREL, BFD_RELOC_NDS32_17_PCREL}, -++ {0, 0, 0, 0} -++ }, -++ -++ .relax_code_seq[BR_RANGE_S16K] = { -++ INSN_BGTZ}, /* bgtz $rt, label */ -++ .relax_code_condition[BR_RANGE_S16K] = { -++ {0, 20, 0x1F, FALSE}, -++ {0, 0, 0, FALSE}, -++ }, -++ .relax_code_size[BR_RANGE_S16K] = 4, -++ .relax_branch_isize[BR_RANGE_S16K] = 4, -++ .relax_fixup[BR_RANGE_S16K] = { -++ {0, 4, NDS32_PCREL, BFD_RELOC_NDS32_17_PCREL}, -++ {0, 0, 0, 0} -++ }, -++ -++ .relax_code_seq[BR_RANGE_S64K] = { -++ INSN_BGTZ}, /* bgtz $rt, label */ -++ .relax_code_condition[BR_RANGE_S64K] = { -++ {0, 20, 0x1F, FALSE}, -++ {0, 0, 0, FALSE}, -++ }, -++ .relax_code_size[BR_RANGE_S64K] = 4, -++ .relax_branch_isize[BR_RANGE_S64K] = 4, -++ .relax_fixup[BR_RANGE_S64K] = { -++ {0, 4, NDS32_PCREL, BFD_RELOC_NDS32_17_PCREL}, -++ {0, 0, 0, 0} -++ }, -++ -++ .relax_code_seq[BR_RANGE_S16M] = { -++ INSN_BLEZ, /* blez $rt, $1 */ -++ INSN_J}, /* j label */ -++ .relax_code_condition[BR_RANGE_S16M] = { -++ {0, 20, 0x1F, FALSE}, -++ {0, 0, 0, FALSE}, -++ }, -++ .relax_code_size[BR_RANGE_S16M] = 8, -++ .relax_branch_isize[BR_RANGE_S16M] = 4, -++ .relax_fixup[BR_RANGE_S16M] = { -++ {0, 4, NDS32_CREATE_LABEL | NDS32_PCREL, BFD_RELOC_NDS32_15_PCREL}, -++ {0, 4, NDS32_PTR | NDS32_HINT, BFD_RELOC_NDS32_LONGJUMP5}, -++ {4, 4, NDS32_PCREL, BFD_RELOC_NDS32_25_PCREL}, -++ {0, 0, 0, 0} -++ }, -++ -++ .relax_code_seq[BR_RANGE_U4G] = { -++ INSN_BLEZ, /* blez $rt, $1 */ -++ INSN_SETHI_TA, /* sethi $ta, label */ -++ INSN_ORI_TA, /* ori $ta, $ta, label */ -++ INSN_JR_TA}, /* jr $ta */ -++ .relax_code_condition[BR_RANGE_U4G] = { -++ {0, 20, 0x1F, FALSE}, -++ {0, 0, 0, FALSE}, -++ }, -++ .relax_code_size[BR_RANGE_U4G] = 16, -++ .relax_branch_isize[BR_RANGE_U4G] = 4, -++ .relax_fixup[BR_RANGE_U4G] = { -++ {0, 4, NDS32_CREATE_LABEL | NDS32_PCREL, 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} -++ }, -++ }, -+ { -+- { -+- {0, 2, NDS32_PCREL, BFD_RELOC_NDS32_9_PCREL}, -+- {0, 0, 0, 0} -+- }, /* BR_RANGE_S256 */ -+- { -+- {0, 4, NDS32_PCREL, BFD_RELOC_NDS32_15_PCREL}, -+- {0, 0, 0, 0} -+- }, /* BR_RANGE_S16K */ -+- { -+- {0, 4, NDS32_CREATE_LABEL | NDS32_PCREL, 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, NDS32_PCREL, 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 | NDS32_PCREL, 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, NDS32_PCREL, 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 | NDS32_PCREL, 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 */ -++ .opcode = "blez", -++ .br_range = BR_RANGE_S64K, -++ .cond_field = { -++ {0, 20, 0x1F, FALSE}, -++ {0, 0, 0, FALSE} -++ }, -++ .relax_code_seq[BR_RANGE_S256] = { -++ INSN_BLEZ}, /* blez $rt, label */ -++ .relax_code_condition[BR_RANGE_S256] = { -++ {0, 20, 0x1F, FALSE}, -++ {0, 0, 0, FALSE}, -++ }, -++ .relax_code_size[BR_RANGE_S256] = 4, -++ .relax_branch_isize[BR_RANGE_S256] = 4, -++ .relax_fixup[BR_RANGE_S256] = { -++ {0, 4, NDS32_PCREL, BFD_RELOC_NDS32_17_PCREL}, -++ {0, 0, 0, 0} -++ }, -++ -++ .relax_code_seq[BR_RANGE_S16K] = { -++ INSN_BLEZ}, /* blez $rt, label */ -++ .relax_code_condition[BR_RANGE_S16K] = { -++ {0, 20, 0x1F, FALSE}, -++ {0, 0, 0, FALSE}, -++ }, -++ .relax_code_size[BR_RANGE_S16K] = 4, -++ .relax_branch_isize[BR_RANGE_S16K] = 4, -++ .relax_fixup[BR_RANGE_S16K] = { -++ {0, 4, NDS32_PCREL, BFD_RELOC_NDS32_17_PCREL}, -++ {0, 0, 0, 0} -++ }, -++ -++ .relax_code_seq[BR_RANGE_S64K] = { -++ INSN_BLEZ}, /* blez $rt, label */ -++ .relax_code_condition[BR_RANGE_S64K] = { -++ {0, 20, 0x1F, FALSE}, -++ {0, 0, 0, FALSE}, -++ }, -++ .relax_code_size[BR_RANGE_S64K] = 4, -++ .relax_branch_isize[BR_RANGE_S64K] = 4, -++ .relax_fixup[BR_RANGE_S64K] = { -++ {0, 4, NDS32_PCREL, BFD_RELOC_NDS32_17_PCREL}, -++ {0, 0, 0, 0} -++ }, -++ -++ .relax_code_seq[BR_RANGE_S16M] = { -++ INSN_BGTZ, /* bgtz $rt, $1 */ -++ INSN_J}, /* j label */ -++ .relax_code_condition[BR_RANGE_S16M] = { -++ {0, 20, 0x1F, FALSE}, -++ {0, 0, 0, FALSE}, -++ }, -++ .relax_code_size[BR_RANGE_S16M] = 8, -++ .relax_branch_isize[BR_RANGE_S16M] = 4, -++ .relax_fixup[BR_RANGE_S16M] = { -++ {0, 4, NDS32_CREATE_LABEL | NDS32_PCREL, BFD_RELOC_NDS32_15_PCREL}, -++ {0, 4, NDS32_PTR | NDS32_HINT, BFD_RELOC_NDS32_LONGJUMP5}, -++ {4, 4, NDS32_PCREL, BFD_RELOC_NDS32_25_PCREL}, -++ {0, 0, 0, 0} -++ }, -++ -++ .relax_code_seq[BR_RANGE_U4G] = { -++ INSN_BGTZ, /* bgtz $rt, $1 */ -++ INSN_SETHI_TA, /* sethi $ta, label */ -++ INSN_ORI_TA, /* ori $ta, $ta, label */ -++ INSN_JR_TA}, /* jr $ta */ -++ .relax_code_condition[BR_RANGE_U4G] = { -++ {0, 20, 0x1F, FALSE}, -++ {0, 0, 0, FALSE}, -++ }, -++ .relax_code_size[BR_RANGE_U4G] = 16, -++ .relax_branch_isize[BR_RANGE_U4G] = 4, -++ .relax_fixup[BR_RANGE_U4G] = { -++ {0, 4, NDS32_CREATE_LABEL | NDS32_PCREL, 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} -++ }, -++ }, -+ { -+- {0, 8, 0x7, FALSE}, -+- {0, 0, 0, FALSE} -+- }, /* cond_field */ -++ .opcode = "bltz", -++ .br_range = BR_RANGE_S64K, -++ .cond_field = { -++ {0, 20, 0x1F, FALSE}, -++ {0, 0, 0, FALSE} -++ }, -++ .relax_code_seq[BR_RANGE_S256] = { -++ INSN_BLTZ}, /* bltz $rt, label */ -++ .relax_code_condition[BR_RANGE_S256] = { -++ {0, 20, 0x1F, FALSE}, -++ {0, 0, 0, FALSE}, -++ }, -++ .relax_code_size[BR_RANGE_S256] = 4, -++ .relax_branch_isize[BR_RANGE_S256] = 4, -++ .relax_fixup[BR_RANGE_S256] = { -++ {0, 4, NDS32_PCREL, BFD_RELOC_NDS32_17_PCREL}, -++ {0, 0, 0, 0} -++ }, -++ -++ .relax_code_seq[BR_RANGE_S16K] = { -++ INSN_BLTZ}, /* bltz $rt, label */ -++ .relax_code_condition[BR_RANGE_S16K] = { -++ {0, 20, 0x1F, FALSE}, -++ {0, 0, 0, FALSE}, -++ }, -++ .relax_code_size[BR_RANGE_S16K] = 4, -++ .relax_branch_isize[BR_RANGE_S16K] = 4, -++ .relax_fixup[BR_RANGE_S16K] = { -++ {0, 4, NDS32_PCREL, BFD_RELOC_NDS32_17_PCREL}, -++ {0, 0, 0, 0} -++ }, -++ -++ .relax_code_seq[BR_RANGE_S64K] = { -++ INSN_BLTZ}, /* bltz $rt, label */ -++ .relax_code_condition[BR_RANGE_S64K] = { -++ {0, 20, 0x1F, FALSE}, -++ {0, 0, 0, FALSE}, -++ }, -++ .relax_code_size[BR_RANGE_S64K] = 4, -++ .relax_branch_isize[BR_RANGE_S64K] = 4, -++ .relax_fixup[BR_RANGE_S64K] = { -++ {0, 4, NDS32_PCREL, BFD_RELOC_NDS32_17_PCREL}, -++ {0, 0, 0, 0} -++ }, -++ -++ .relax_code_seq[BR_RANGE_S16M] = { -++ INSN_BGEZ, /* bgez $rt, $1 */ -++ INSN_J}, /* j label */ -++ .relax_code_condition[BR_RANGE_S16M] = { -++ {0, 20, 0x1F, FALSE}, -++ {0, 0, 0, FALSE}, -++ }, -++ .relax_code_size[BR_RANGE_S16M] = 8, -++ .relax_branch_isize[BR_RANGE_S16M] = 4, -++ .relax_fixup[BR_RANGE_S16M] = { -++ {0, 4, NDS32_CREATE_LABEL | NDS32_PCREL, BFD_RELOC_NDS32_15_PCREL}, -++ {0, 4, NDS32_PTR | NDS32_HINT, BFD_RELOC_NDS32_LONGJUMP5}, -++ {4, 4, NDS32_PCREL, BFD_RELOC_NDS32_25_PCREL}, -++ {0, 0, 0, 0} -++ }, -++ -++ .relax_code_seq[BR_RANGE_U4G] = { -++ INSN_BGEZ, /* bgez $rt, $1 */ -++ INSN_SETHI_TA, /* sethi $ta, label */ -++ INSN_ORI_TA, /* ori $ta, $ta, label */ -++ INSN_JR_TA}, /* jr $ta */ -++ .relax_code_condition[BR_RANGE_U4G] = { -++ {0, 20, 0x1F, FALSE}, -++ {0, 0, 0, FALSE}, -++ }, -++ .relax_code_size[BR_RANGE_U4G] = 16, -++ .relax_branch_isize[BR_RANGE_U4G] = 4, -++ .relax_fixup[BR_RANGE_U4G] = { -++ {0, 4, NDS32_CREATE_LABEL | NDS32_PCREL, 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} -++ }, -++ }, -+ { -+- { -+- 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 */ -++ .opcode = "beq", -++ .br_range = BR_RANGE_S16K, -++ .cond_field = { -++ {0, 20, 0x1F, FALSE}, -++ {0, 15, 0x1F, FALSE}, -++ {0, 0, 0, FALSE} -++ }, -++ .relax_code_seq[BR_RANGE_S256] = { -++ INSN_BEQ}, /* beq $rt, $ra, label */ -++ .relax_code_condition[BR_RANGE_S256] = { -++ {0, 20, 0x1F, FALSE}, -++ {0, 15, 0x1F, FALSE}, -++ {0, 0, 0, FALSE} -++ }, -++ .relax_code_size[BR_RANGE_S256] = 4, -++ .relax_branch_isize[BR_RANGE_S256] = 4, -++ .relax_fixup[BR_RANGE_S256] = { -++ {0, 4, NDS32_PCREL, BFD_RELOC_NDS32_15_PCREL}, -++ {0, 4, NDS32_INSN16, BFD_RELOC_NDS32_INSN16}, -++ {0, 0, 0, 0} -++ }, -++ -++ .relax_code_seq[BR_RANGE_S16K] = { -++ INSN_BEQ}, /* beq $rt, $ra, label */ -++ .relax_code_condition[BR_RANGE_S16K] = { -++ {0, 20, 0x1F, FALSE}, -++ {0, 15, 0x1F, FALSE}, -++ {0, 0, 0, FALSE} -++ }, -++ .relax_code_size[BR_RANGE_S16K] = 4, -++ .relax_branch_isize[BR_RANGE_S16K] = 4, -++ .relax_fixup[BR_RANGE_S16K] = { -++ {0, 4, NDS32_PCREL, BFD_RELOC_NDS32_15_PCREL}, -++ {0, 0, 0, 0} -++ }, -++ -++ .relax_code_seq[BR_RANGE_S64K] = { -++ INSN_BNE, /* bne $rt, $ra, $1 */ -++ INSN_J}, /* j label */ -++ .relax_code_condition[BR_RANGE_S64K] = { -++ {0, 20, 0x1F, FALSE}, -++ {0, 15, 0x1F, FALSE}, -++ {0, 0, 0, FALSE} -++ }, -++ .relax_code_size[BR_RANGE_S64K] = 8, -++ .relax_branch_isize[BR_RANGE_S64K] = 4, -++ .relax_fixup[BR_RANGE_S64K] = { -++ {0, 4, NDS32_CREATE_LABEL | NDS32_PCREL, 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, NDS32_PCREL, BFD_RELOC_NDS32_25_PCREL}, -++ {4, 4, NDS32_INSN16 | NDS32_HINT, BFD_RELOC_NDS32_INSN16}, -++ {0, 0, 0, 0} -++ }, -++ -++ .relax_code_seq[BR_RANGE_S16M] = { -++ INSN_BNE, /* bne $rt, $ra, $1 */ -++ INSN_J}, /* j label */ -++ .relax_code_condition[BR_RANGE_S16M] = { -++ {0, 20, 0x1F, FALSE}, -++ {0, 15, 0x1F, FALSE}, -++ {0, 0, 0, FALSE} -++ }, -++ .relax_code_size[BR_RANGE_S16M] = 8, -++ .relax_branch_isize[BR_RANGE_S16M] = 4, -++ .relax_fixup[BR_RANGE_S16M] = { -++ {0, 4, NDS32_CREATE_LABEL | NDS32_PCREL, 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, NDS32_PCREL, BFD_RELOC_NDS32_25_PCREL}, -++ {4, 4, NDS32_INSN16 | NDS32_HINT, BFD_RELOC_NDS32_INSN16}, -++ {0, 0, 0, 0} -++ }, -++ -++ .relax_code_seq[BR_RANGE_U4G] = { -++ INSN_BNE, /* bne $rt, $ra, $1 */ -++ INSN_SETHI_TA, /* sethi $ta, label */ -++ INSN_ORI_TA, /* ori $ta, $ta, label */ -++ INSN_JR_TA}, /* jr $ta */ -++ .relax_code_condition[BR_RANGE_U4G] = { -++ {0, 20, 0x1F, FALSE}, -++ {0, 15, 0x1F, FALSE}, -++ {0, 0, 0, FALSE} -++ }, -++ .relax_code_size[BR_RANGE_U4G] = 16, -++ .relax_branch_isize[BR_RANGE_U4G] = 4, -++ .relax_fixup[BR_RANGE_U4G] = { -++ {0, 4, NDS32_CREATE_LABEL | NDS32_PCREL, 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} -++ }, -++ }, -+ { -+- { -+- {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 */ -++ .opcode = "bne", -++ .br_range = BR_RANGE_S16K, -++ .cond_field = { -++ {0, 20, 0x1F, FALSE}, -++ {0, 15, 0x1F, FALSE}, -++ {0, 0, 0, FALSE} -++ }, -++ .relax_code_seq[BR_RANGE_S256] = { -++ INSN_BNE}, /* bne $rt, $ra, label */ -++ .relax_code_condition[BR_RANGE_S256] = { -++ {0, 20, 0x1F, FALSE}, -++ {0, 15, 0x1F, FALSE}, -++ {0, 0, 0, FALSE} -++ }, -++ .relax_code_size[BR_RANGE_S256] = 4, -++ .relax_branch_isize[BR_RANGE_S256] = 4, -++ .relax_fixup[BR_RANGE_S256] = { -++ {0, 4, NDS32_PCREL, BFD_RELOC_NDS32_15_PCREL}, -++ {0, 4, NDS32_INSN16, BFD_RELOC_NDS32_INSN16}, -++ {0, 0, 0, 0} -++ }, -++ -++ .relax_code_seq[BR_RANGE_S16K] = { -++ INSN_BNE}, /* bne $rt, $ra, label */ -++ .relax_code_condition[BR_RANGE_S16K] = { -++ {0, 20, 0x1F, FALSE}, -++ {0, 15, 0x1F, FALSE}, -++ {0, 0, 0, FALSE} -++ }, -++ .relax_code_size[BR_RANGE_S16K] = 4, -++ .relax_branch_isize[BR_RANGE_S16K] = 4, -++ .relax_fixup[BR_RANGE_S16K] = { -++ {0, 4, NDS32_PCREL, BFD_RELOC_NDS32_15_PCREL}, -++ {0, 0, 0, 0} -++ }, -++ -++ .relax_code_seq[BR_RANGE_S64K] = { -++ INSN_BEQ, /* beq $rt, $ra, $1 */ -++ INSN_J}, /* j label */ -++ .relax_code_condition[BR_RANGE_S64K] = { -++ {0, 20, 0x1F, FALSE}, -++ {0, 15, 0x1F, FALSE}, -++ {0, 0, 0, FALSE} -++ }, -++ .relax_code_size[BR_RANGE_S64K] = 8, -++ .relax_branch_isize[BR_RANGE_S64K] = 4, -++ .relax_fixup[BR_RANGE_S64K] = { -++ {0, 4, NDS32_CREATE_LABEL | NDS32_PCREL, 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, NDS32_PCREL, BFD_RELOC_NDS32_25_PCREL}, -++ {4, 4, NDS32_INSN16 | NDS32_HINT, BFD_RELOC_NDS32_INSN16}, -++ {0, 0, 0, 0} -++ }, -++ -++ .relax_code_seq[BR_RANGE_S16M] = { -++ INSN_BEQ, /* beq $rt, $ra, $1 */ -++ INSN_J}, /* j label */ -++ .relax_code_condition[BR_RANGE_S16M] = { -++ {0, 20, 0x1F, FALSE}, -++ {0, 15, 0x1F, FALSE}, -++ {0, 0, 0, FALSE} -++ }, -++ .relax_code_size[BR_RANGE_S16M] = 8, -++ .relax_branch_isize[BR_RANGE_S16M] = 4, -++ .relax_fixup[BR_RANGE_S16M] = { -++ {0, 4, NDS32_CREATE_LABEL | NDS32_PCREL, 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, NDS32_PCREL, BFD_RELOC_NDS32_25_PCREL}, -++ {4, 4, NDS32_INSN16 | NDS32_HINT, BFD_RELOC_NDS32_INSN16}, -++ {0, 0, 0, 0} -++ }, -++ -++ .relax_code_seq[BR_RANGE_U4G] = { -++ INSN_BEQ, /* beq $rt, $ra, $1 */ -++ INSN_SETHI_TA, /* sethi $ta, label */ -++ INSN_ORI_TA, /* ori $ta, $ta, label */ -++ INSN_JR_TA}, /* jr $ta */ -++ .relax_code_condition[BR_RANGE_U4G] = { -++ {0, 20, 0x1F, FALSE}, -++ {0, 15, 0x1F, FALSE}, -++ {0, 0, 0, FALSE} -++ }, -++ .relax_code_size[BR_RANGE_U4G] = 16, -++ .relax_branch_isize[BR_RANGE_U4G] = 4, -++ .relax_fixup[BR_RANGE_U4G] = { -++ {0, 4, NDS32_CREATE_LABEL | NDS32_PCREL, 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} -++ }, -++ }, -+ { -+- { -+- {0, 2, NDS32_PCREL, BFD_RELOC_NDS32_9_PCREL}, -+- {0, 0, 0, 0} -+- }, /* BR_RANGE_S256 */ -+- { -+- {0, 4, NDS32_PCREL, BFD_RELOC_NDS32_15_PCREL}, -+- {0, 0, 0, 0} -+- }, /* BR_RANGE_S16K */ -+- { -+- {0, 4, NDS32_CREATE_LABEL | NDS32_PCREL, 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, NDS32_PCREL, 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 | NDS32_PCREL, 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, NDS32_PCREL, 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 | NDS32_PCREL, 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 */ -++ .opcode = "beqz38", -++ .br_range = BR_RANGE_S256, -++ .cond_field = { -++ {0, 8, 0x7, FALSE}, -++ {0, 0, 0, FALSE} -++ }, -++ .relax_code_seq[BR_RANGE_S256] = { -++ INSN_BEQZ38 << 16}, /* beqz $rt, label */ -++ .relax_code_condition[BR_RANGE_S256] = { -++ {0, 8, 0x7, FALSE}, -++ {0, 0, 0, FALSE} -++ }, -++ .relax_code_size[BR_RANGE_S256] = 2, -++ .relax_branch_isize[BR_RANGE_S256] = 2, -++ .relax_fixup[BR_RANGE_S256] = { -++ {0, 2, NDS32_PCREL, BFD_RELOC_NDS32_9_PCREL}, -++ {0, 0, 0, 0} -++ }, -++ -++ .relax_code_seq[BR_RANGE_S16K] = { -++ INSN_BEQZ}, /* beqz $rt, label */ -++ .relax_code_condition[BR_RANGE_S16K] = { -++ {0, 20, 0x1F, FALSE}, -++ {0, 0, 0, FALSE} -++ }, -++ .relax_code_size[BR_RANGE_S16K] = 4, -++ .relax_branch_isize[BR_RANGE_S16K] = 4, -++ .relax_fixup[BR_RANGE_S16K] = { -++ {0, 4, NDS32_PCREL, BFD_RELOC_NDS32_17_PCREL}, -++ {0, 0, 0, 0} -++ }, -++ -++ .relax_code_seq[BR_RANGE_S64K] = { -++ INSN_BEQZ}, /* beqz $rt, label */ -++ .relax_code_condition[BR_RANGE_S64K] = { -++ {0, 20, 0x1F, FALSE}, -++ {0, 0, 0, FALSE} -++ }, -++ .relax_code_size[BR_RANGE_S64K] = 4, -++ .relax_branch_isize[BR_RANGE_S64K] = 4, -++ .relax_fixup[BR_RANGE_S64K] = { -++ {0, 4, NDS32_PCREL, BFD_RELOC_NDS32_17_PCREL}, -++ {0, 0, 0, 0} -++ }, -++ -++ .relax_code_seq[BR_RANGE_S16M] = { -++ INSN_BNEZ, /* bnez $rt, $1 */ -++ INSN_J}, /* j label */ -++ .relax_code_condition[BR_RANGE_S16M] = { -++ {0, 20, 0x1F, FALSE}, -++ {0, 0, 0, FALSE} -++ }, -++ .relax_code_size[BR_RANGE_S16M] = 8, -++ .relax_branch_isize[BR_RANGE_S16M] = 4, -++ .relax_fixup[BR_RANGE_S16M] = { -++ {0, 4, NDS32_CREATE_LABEL | NDS32_PCREL, 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, NDS32_PCREL, BFD_RELOC_NDS32_25_PCREL}, -++ {4, 4, NDS32_INSN16 | NDS32_HINT, BFD_RELOC_NDS32_INSN16}, -++ {0, 0, 0, 0} -++ }, -++ -++ .relax_code_seq[BR_RANGE_U4G] = { -++ INSN_BNEZ, /* bnez $rt, $1 */ -++ INSN_SETHI_TA, /* sethi $ta, label */ -++ INSN_ORI_TA, /* ori $ta, $ta, label */ -++ INSN_JR_TA}, /* jr $ta */ -++ .relax_code_condition[BR_RANGE_U4G] = { -++ {0, 20, 0x1F, FALSE}, -++ {0, 0, 0, FALSE} -++ }, -++ .relax_code_size[BR_RANGE_U4G] = 16, -++ .relax_branch_isize[BR_RANGE_U4G] = 4, -++ .relax_fixup[BR_RANGE_U4G] = { -++ {0, 4, NDS32_CREATE_LABEL | NDS32_PCREL, 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} -++ }, -++ }, -+ { -+- {0, 8, 0x7FF, TRUE}, -+- {0, 20, 0x1F, FALSE}, -+- {0, 0, 0, FALSE} -+- }, /* cond_field */ -++ .opcode = "bnez38", -++ .br_range = BR_RANGE_S256, -++ .cond_field = { -++ {0, 8, 0x7, FALSE}, -++ {0, 0, 0, FALSE} -++ }, -++ .relax_code_seq[BR_RANGE_S256] = { -++ INSN_BNEZ38 << 16}, /* bnez $rt, label */ -++ .relax_code_condition[BR_RANGE_S256] = { -++ {0, 8, 0x7, FALSE}, -++ {0, 0, 0, FALSE} -++ }, -++ .relax_code_size[BR_RANGE_S256] = 2, -++ .relax_branch_isize[BR_RANGE_S256] = 2, -++ .relax_fixup[BR_RANGE_S256] = { -++ {0, 2, NDS32_PCREL, BFD_RELOC_NDS32_9_PCREL}, -++ {0, 0, 0, 0} -++ }, -++ -++ .relax_code_seq[BR_RANGE_S16K] = { -++ INSN_BNEZ}, /* bnez $rt, label */ -++ .relax_code_condition[BR_RANGE_S16K] = { -++ {0, 20, 0x1F, FALSE}, -++ {0, 0, 0, FALSE} -++ }, -++ .relax_code_size[BR_RANGE_S16K] = 4, -++ .relax_branch_isize[BR_RANGE_S16K] = 4, -++ .relax_fixup[BR_RANGE_S16K] = { -++ {0, 4, NDS32_PCREL, BFD_RELOC_NDS32_17_PCREL}, -++ {0, 0, 0, 0} -++ }, -++ -++ .relax_code_seq[BR_RANGE_S64K] = { -++ INSN_BNEZ}, /* bnez $rt, label */ -++ .relax_code_condition[BR_RANGE_S64K] = { -++ {0, 20, 0x1F, FALSE}, -++ {0, 0, 0, FALSE} -++ }, -++ .relax_code_size[BR_RANGE_S64K] = 4, -++ .relax_branch_isize[BR_RANGE_S64K] = 4, -++ .relax_fixup[BR_RANGE_S64K] = { -++ {0, 4, NDS32_PCREL, BFD_RELOC_NDS32_17_PCREL}, -++ {0, 0, 0, 0} -++ }, -++ -++ .relax_code_seq[BR_RANGE_S16M] = { -++ INSN_BEQZ, /* beqz $rt, $1 */ -++ INSN_J}, /* j label */ -++ .relax_code_condition[BR_RANGE_S16M] = { -++ {0, 20, 0x1F, FALSE}, -++ {0, 0, 0, FALSE} -++ }, -++ .relax_code_size[BR_RANGE_S16M] = 8, -++ .relax_branch_isize[BR_RANGE_S16M] = 4, -++ .relax_fixup[BR_RANGE_S16M] = { -++ {0, 4, NDS32_CREATE_LABEL | NDS32_PCREL, 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, NDS32_PCREL, BFD_RELOC_NDS32_25_PCREL}, -++ {4, 4, NDS32_INSN16 | NDS32_HINT, BFD_RELOC_NDS32_INSN16}, -++ {0, 0, 0, 0} -++ }, -++ -++ .relax_code_seq[BR_RANGE_U4G] = { -++ INSN_BEQZ, /* beqz $rt, $1 */ -++ INSN_SETHI_TA, /* sethi $ta, label */ -++ INSN_ORI_TA, /* ori $ta, $ta, label */ -++ INSN_JR_TA}, /* jr $ a */ -++ .relax_code_condition[BR_RANGE_U4G] = { -++ {0, 20, 0x1F, FALSE}, -++ {0, 0, 0, FALSE} -++ }, -++ .relax_code_size[BR_RANGE_U4G] = 16, -++ .relax_branch_isize[BR_RANGE_U4G] = 4, -++ .relax_fixup[BR_RANGE_U4G] = { -++ {0, 4, NDS32_CREATE_LABEL | NDS32_PCREL, 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} -++ }, -++ }, -+ { -+- { -+- 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 */ -++ .opcode = "beqzs8", -++ .br_range = BR_RANGE_S256, -++ .cond_field = { -++ {0, 0, 0, FALSE} -++ }, -++ .relax_code_seq[BR_RANGE_S256] = { -++ INSN_BEQZS8 << 16}, /* beqz $r15, label */ -++ .relax_code_size[BR_RANGE_S256] = 2, -++ .relax_branch_isize[BR_RANGE_S256] = 2, -++ .relax_fixup[BR_RANGE_S256] = { -++ {0, 2, NDS32_PCREL, BFD_RELOC_NDS32_9_PCREL}, -++ {0, 0, 0, 0} -++ }, -++ -++ .relax_code_seq[BR_RANGE_S16K] = { -++ INSN_BEQZ_TA}, /* beqz $r15, label */ -++ .relax_code_size[BR_RANGE_S16K] = 4, -++ .relax_branch_isize[BR_RANGE_S16K] = 4, -++ .relax_fixup[BR_RANGE_S16K] = { -++ {0, 4, NDS32_PCREL, BFD_RELOC_NDS32_17_PCREL}, -++ {0, 0, 0, 0} -++ }, -++ -++ .relax_code_seq[BR_RANGE_S64K] = { -++ INSN_BEQZ_TA}, /* beqz $r15, label */ -++ .relax_code_size[BR_RANGE_S64K] = 4, -++ .relax_branch_isize[BR_RANGE_S64K] = 4, -++ .relax_fixup[BR_RANGE_S64K] = { -++ {0, 4, NDS32_PCREL, BFD_RELOC_NDS32_17_PCREL}, -++ {0, 0, 0, 0} -++ }, -++ -++ .relax_code_seq[BR_RANGE_S16M] = { -++ INSN_BNEZ_TA, /* bnez $r15, $1 */ -++ INSN_J}, /* j label */ -++ .relax_code_size[BR_RANGE_S16M] = 8, -++ .relax_branch_isize[BR_RANGE_S16M] = 4, -++ .relax_fixup[BR_RANGE_S16M] = { -++ {0, 4, NDS32_CREATE_LABEL | NDS32_PCREL, 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, NDS32_PCREL, BFD_RELOC_NDS32_25_PCREL}, -++ {4, 4, NDS32_INSN16 | NDS32_HINT, BFD_RELOC_NDS32_INSN16}, -++ {0, 0, 0, 0} -++ }, -++ -++ .relax_code_seq[BR_RANGE_U4G] = { -++ INSN_BNEZ_TA, /* bnez $r15, $1 */ -++ INSN_SETHI_TA, /* sethi $ta, label */ -++ INSN_ORI_TA, /* ori $ta, $ta, label */ -++ INSN_JR_TA}, /* jr $ a */ -++ .relax_code_size[BR_RANGE_U4G] = 16, -++ .relax_branch_isize[BR_RANGE_U4G] = 4, -++ .relax_fixup[BR_RANGE_U4G] = { -++ {0, 4, NDS32_CREATE_LABEL | NDS32_PCREL, 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} -++ }, -++ }, -+ { -+- { -+- {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 */ -++ .opcode = "bnezs8", -++ .br_range = BR_RANGE_S256, -++ .cond_field = { -++ {0, 0, 0, FALSE} -++ }, -++ .relax_code_seq[BR_RANGE_S256] = { -++ INSN_BNEZS8 << 16}, /* bnez $r15, label */ -++ .relax_code_size[BR_RANGE_S256] = 2, -++ .relax_branch_isize[BR_RANGE_S256] = 2, -++ .relax_fixup[BR_RANGE_S256] = { -++ {0, 2, NDS32_PCREL, BFD_RELOC_NDS32_9_PCREL}, -++ {0, 0, 0, 0} -++ }, -++ -++ .relax_code_seq[BR_RANGE_S16K] = { -++ INSN_BNEZ_TA}, /* bnez $r15, label */ -++ .relax_code_size[BR_RANGE_S16K] = 4, -++ .relax_branch_isize[BR_RANGE_S16K] = 4, -++ .relax_fixup[BR_RANGE_S16K] = { -++ {0, 4, NDS32_PCREL, BFD_RELOC_NDS32_17_PCREL}, -++ {0, 0, 0, 0} -++ }, -++ -++ .relax_code_seq[BR_RANGE_S64K] = { -++ INSN_BNEZ_TA}, /* bnez $r15, label */ -++ .relax_code_size[BR_RANGE_S64K] = 4, -++ .relax_branch_isize[BR_RANGE_S64K] = 4, -++ .relax_fixup[BR_RANGE_S64K] = { -++ {0, 4, NDS32_PCREL, BFD_RELOC_NDS32_17_PCREL}, -++ {0, 0, 0, 0} -++ }, -++ -++ .relax_code_seq[BR_RANGE_S16M] = { -++ INSN_BEQZ_TA, /* beqz $r15, $1 */ -++ INSN_J}, /* j label */ -++ .relax_code_size[BR_RANGE_S16M] = 8, -++ .relax_branch_isize[BR_RANGE_S16M] = 4, -++ .relax_fixup[BR_RANGE_S16M] = { -++ {0, 4, NDS32_CREATE_LABEL | NDS32_PCREL, 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, NDS32_PCREL, BFD_RELOC_NDS32_25_PCREL}, -++ {4, 4, NDS32_INSN16 | NDS32_HINT, BFD_RELOC_NDS32_INSN16}, -++ {0, 0, 0, 0} -++ }, -++ -++ .relax_code_seq[BR_RANGE_U4G] = { -++ INSN_BEQZ_TA, /* beqz $r15, $1 */ -++ INSN_SETHI_TA, /* sethi $ta, label */ -++ INSN_ORI_TA, /* ori $ta, $ta, label */ -++ INSN_JR_TA}, /* jr $ a */ -++ .relax_code_size[BR_RANGE_U4G] = 16, -++ .relax_branch_isize[BR_RANGE_U4G] = 4, -++ .relax_fixup[BR_RANGE_U4G] = { -++ {0, 4, NDS32_CREATE_LABEL | NDS32_PCREL, 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} -++ }, -++ }, -+ { -+- { -+- {0, 4, NDS32_PCREL, 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, NDS32_PCREL, BFD_RELOC_NDS32_15_PCREL}, -+- {0, 0, 0, 0} -+- }, /* BR_RANGE_S16K */ -+- { -+- {0, 4, NDS32_CREATE_LABEL | NDS32_PCREL, BFD_RELOC_NDS32_WORD_9_PCREL}, -+- {4, 4, NDS32_PCREL, BFD_RELOC_NDS32_25_PCREL}, -+- {0, 0, 0, 0} -+- }, /* BR_RANGE_S64K */ -+- { -+- {0, 4, NDS32_CREATE_LABEL | NDS32_PCREL, BFD_RELOC_NDS32_WORD_9_PCREL}, -+- {4, 4, NDS32_PCREL, BFD_RELOC_NDS32_25_PCREL}, -+- {0, 0, 0, 0} -+- }, /* BR_RANGE_S16M */ -+- { -+- {0, 4, NDS32_CREATE_LABEL | NDS32_PCREL, 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 */ -++ .opcode = "bnes38", -++ .br_range = BR_RANGE_S256, -++ .cond_field = { -++ {0, 8, 0x7, FALSE}, -++ {0, 0, 0, FALSE} -++ }, -++ .relax_code_seq[BR_RANGE_S256] = { -++ INSN_BNES38 << 16}, /* bne $rt, $r5, label */ -++ .relax_code_condition[BR_RANGE_S256] = { -++ {0, 8, 0x7, FALSE}, -++ {0, 0, 0, FALSE} -++ }, -++ .relax_code_size[BR_RANGE_S256] = 2, -++ .relax_branch_isize[BR_RANGE_S256] = 2, -++ .relax_fixup[BR_RANGE_S256] = { -++ {0, 2, NDS32_PCREL, BFD_RELOC_NDS32_9_PCREL}, -++ {0, 0, 0, 0} -++ }, -++ -++ .relax_code_seq[BR_RANGE_S16K] = { -++ INSN_BNE_R5}, /* bne $rt, $r5, label */ -++ .relax_code_condition[BR_RANGE_S16K] = { -++ {0, 20, 0x1F, FALSE}, -++ {0, 0, 0, FALSE} -++ }, -++ .relax_code_size[BR_RANGE_S16K] = 4, -++ .relax_branch_isize[BR_RANGE_S16K] = 4, -++ .relax_fixup[BR_RANGE_S16K] = { -++ {0, 4, NDS32_PCREL, BFD_RELOC_NDS32_15_PCREL}, -++ {0, 0, 0, 0} -++ }, -++ -++ .relax_code_seq[BR_RANGE_S64K] = { -++ INSN_BEQ_R5, /* beq $rt, $r5, $1 */ -++ INSN_J}, /* j label */ -++ .relax_code_condition[BR_RANGE_S64K] = { -++ {0, 20, 0x1F, FALSE}, -++ {0, 0, 0, FALSE} -++ }, -++ .relax_code_size[BR_RANGE_S64K] = 8, -++ .relax_branch_isize[BR_RANGE_S64K] = 4, -++ .relax_fixup[BR_RANGE_S64K] = { -++ {0, 4, NDS32_CREATE_LABEL | NDS32_PCREL, 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, NDS32_PCREL, BFD_RELOC_NDS32_25_PCREL}, -++ {4, 4, NDS32_INSN16 | NDS32_HINT, BFD_RELOC_NDS32_INSN16}, -++ {0, 0, 0, 0} -++ }, -++ -++ .relax_code_seq[BR_RANGE_S16M] = { -++ INSN_BEQ_R5, /* beq $rt, $r5, $1 */ -++ INSN_J}, /* j label */ -++ .relax_code_condition[BR_RANGE_S16M] = { -++ {0, 20, 0x1F, FALSE}, -++ {0, 0, 0, FALSE} -++ }, -++ .relax_code_size[BR_RANGE_S16M] = 8, -++ .relax_branch_isize[BR_RANGE_S16M] = 4, -++ .relax_fixup[BR_RANGE_S16M] = { -++ {0, 4, NDS32_CREATE_LABEL | NDS32_PCREL, 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, NDS32_PCREL, BFD_RELOC_NDS32_25_PCREL}, -++ {4, 4, NDS32_INSN16 | NDS32_HINT, BFD_RELOC_NDS32_INSN16}, -++ {0, 0, 0, 0} -++ }, -++ -++ .relax_code_seq[BR_RANGE_U4G] = { -++ INSN_BEQ_R5, /* beq $rt, $r5, $1 */ -++ INSN_SETHI_TA, /* sethi $ta, label */ -++ INSN_ORI_TA, /* ori $ta, $ta, label */ -++ INSN_JR_TA}, /* jr $ a */ -++ .relax_code_condition[BR_RANGE_U4G] = { -++ {0, 20, 0x1F, FALSE}, -++ {0, 0, 0, FALSE} -++ }, -++ .relax_code_size[BR_RANGE_U4G] = 16, -++ .relax_branch_isize[BR_RANGE_U4G] = 4, -++ .relax_fixup[BR_RANGE_U4G] = { -++ {0, 4, NDS32_CREATE_LABEL | NDS32_PCREL, 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} -++ }, -++ }, -+ { -+- {0, 8, 0x7FF, TRUE}, -+- {0, 20, 0x1F, FALSE}, -+- {0, 0, 0, FALSE} -+- }, /* cond_field */ -++ .opcode = "beqs38", -++ .br_range = BR_RANGE_S256, -++ .cond_field = { -++ {0, 8, 0x7, FALSE}, -++ {0, 0, 0, FALSE} -++ }, -++ .relax_code_seq[BR_RANGE_S256] = { -++ INSN_BEQS38 << 16}, /* beq $rt, $r5, label */ -++ .relax_code_condition[BR_RANGE_S256] = { -++ {0, 8, 0x7, FALSE}, -++ {0, 0, 0, FALSE} -++ }, -++ .relax_code_size[BR_RANGE_S256] = 2, -++ .relax_branch_isize[BR_RANGE_S256] = 2, -++ .relax_fixup[BR_RANGE_S256] = { -++ {0, 2, NDS32_PCREL, BFD_RELOC_NDS32_9_PCREL}, -++ {0, 0, 0, 0} -++ }, -++ -++ .relax_code_seq[BR_RANGE_S16K] = { -++ INSN_BEQ_R5}, /* beq $rt, $r5, label */ -++ .relax_code_condition[BR_RANGE_S16K] = { -++ {0, 20, 0x1F, FALSE}, -++ {0, 0, 0, FALSE} -++ }, -++ .relax_code_size[BR_RANGE_S16K] = 4, -++ .relax_branch_isize[BR_RANGE_S16K] = 4, -++ .relax_fixup[BR_RANGE_S16K] = { -++ {0, 4, NDS32_PCREL, BFD_RELOC_NDS32_15_PCREL}, -++ {0, 0, 0, 0} -++ }, -++ -++ .relax_code_seq[BR_RANGE_S64K] = { -++ INSN_BNE_R5, /* bne $rt, $r5, $1 */ -++ INSN_J}, /* j label */ -++ .relax_code_condition[BR_RANGE_S64K] = { -++ {0, 20, 0x1F, FALSE}, -++ {0, 0, 0, FALSE} -++ }, -++ .relax_code_size[BR_RANGE_S64K] = 8, -++ .relax_branch_isize[BR_RANGE_S64K] = 4, -++ .relax_fixup[BR_RANGE_S64K] = { -++ {0, 4, NDS32_CREATE_LABEL | NDS32_PCREL, 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, NDS32_PCREL, BFD_RELOC_NDS32_25_PCREL}, -++ {4, 4, NDS32_INSN16 | NDS32_HINT, BFD_RELOC_NDS32_INSN16}, -++ {0, 0, 0, 0} -++ }, -++ -++ .relax_code_seq[BR_RANGE_S16M] = { -++ INSN_BNE_R5, /* bne $rt, $r5, $1 */ -++ INSN_J}, /* j label */ -++ .relax_code_condition[BR_RANGE_S16M] = { -++ {0, 20, 0x1F, FALSE}, -++ {0, 0, 0, FALSE} -++ }, -++ .relax_code_size[BR_RANGE_S16M] = 8, -++ .relax_branch_isize[BR_RANGE_S16M] = 4, -++ .relax_fixup[BR_RANGE_S16M] = { -++ {0, 4, NDS32_CREATE_LABEL | NDS32_PCREL, 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, NDS32_PCREL, BFD_RELOC_NDS32_25_PCREL}, -++ {4, 4, NDS32_INSN16 | NDS32_HINT, BFD_RELOC_NDS32_INSN16}, -++ {0, 0, 0, 0} -++ }, -++ -++ .relax_code_seq[BR_RANGE_U4G] = { -++ INSN_BNE_R5, /* bne $rt, $r5, $1 */ -++ INSN_SETHI_TA, /* sethi $ta, label */ -++ INSN_ORI_TA, /* ori $ta, $ta, label */ -++ INSN_JR_TA}, /* jr $ a */ -++ .relax_code_condition[BR_RANGE_U4G] = { -++ {0, 20, 0x1F, FALSE}, -++ {0, 0, 0, FALSE} -++ }, -++ .relax_code_size[BR_RANGE_U4G] = 16, -++ .relax_branch_isize[BR_RANGE_U4G] = 4, -++ .relax_fixup[BR_RANGE_U4G] = { -++ {0, 4, NDS32_CREATE_LABEL | NDS32_PCREL, 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} -++ }, -++ }, -+ { -+- { -+- 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 */ -++ .opcode = "beqc", -++ .br_range = BR_RANGE_S256, -++ .cond_field = { -++ {0, 8, 0x7FF, TRUE}, -++ {0, 20, 0x1F, FALSE}, -++ {0, 0, 0, FALSE} -++ }, -++ .relax_code_seq[BR_RANGE_S256] = { -++ INSN_BEQC}, /* beqc $rt, imm11s, label */ -++ .relax_code_condition[BR_RANGE_S256] = { -++ {0, 8, 0x7FF, FALSE}, -++ {0, 20, 0x1F, FALSE}, -++ {0, 0, 0, FALSE} -++ }, -++ .relax_code_size[BR_RANGE_S256] = 4, -++ .relax_branch_isize[BR_RANGE_S256] = 4, -++ .relax_fixup[BR_RANGE_S256] = { -++ {0, 4, NDS32_PCREL, BFD_RELOC_NDS32_WORD_9_PCREL}, -++ {0, 0, 0, 0} -++ }, -++ -++ .relax_code_seq[BR_RANGE_S16K] = { -++ INSN_MOVI_TA, /* movi $ta, imm11s */ -++ INSN_BEQ_TA}, /* beq $rt, $ta, label */ -++ .relax_code_condition[BR_RANGE_S16K] = { -++ {0, 0, 0xFFFFF, FALSE}, -++ {4, 20, 0x1F, FALSE}, -++ {0, 0, 0, FALSE} -++ }, -++ .relax_code_size[BR_RANGE_S16K] = 8, -++ .relax_branch_isize[BR_RANGE_S16K] = 4, -++ .relax_fixup[BR_RANGE_S16K] = { -++ {0, 4, NDS32_INSN16 | NDS32_HINT, BFD_RELOC_NDS32_INSN16}, -++ {0, 4, NDS32_PTR | NDS32_HINT, BFD_RELOC_NDS32_LONGJUMP7}, -++ {4, 4, NDS32_PCREL, BFD_RELOC_NDS32_15_PCREL}, -++ {0, 0, 0, 0} -++ }, -++ -++ .relax_code_seq[BR_RANGE_S64K] = { -++ INSN_BNEC, /* bnec $rt, imm11s, $1 */ -++ INSN_J}, /* j label */ -++ .relax_code_condition[BR_RANGE_S64K] = { -++ {0, 8, 0x7FF, FALSE}, -++ {0, 20, 0x1F, FALSE}, -++ {0, 0, 0, FALSE} -++ }, -++ .relax_code_size[BR_RANGE_S64K] = 8, -++ .relax_branch_isize[BR_RANGE_S64K] = 4, -++ .relax_fixup[BR_RANGE_S64K] = { -++ {0, 4, NDS32_CREATE_LABEL | NDS32_PCREL, BFD_RELOC_NDS32_WORD_9_PCREL}, -++ {4, 4, NDS32_PCREL, BFD_RELOC_NDS32_25_PCREL}, -++ {0, 0, 0, 0} -++ }, -++ -++ .relax_code_seq[BR_RANGE_S16M] = { -++ INSN_BNEC, /* bnec $rt, imm11s, $1 */ -++ INSN_J}, /* j label */ -++ .relax_code_condition[BR_RANGE_S16M] = { -++ {0, 8, 0x7FF, FALSE}, -++ {0, 20, 0x1F, FALSE}, -++ {0, 0, 0, FALSE} -++ }, -++ .relax_code_size[BR_RANGE_S16M] = 8, -++ .relax_branch_isize[BR_RANGE_S16M] = 4, -++ .relax_fixup[BR_RANGE_S16M] = { -++ {0, 4, NDS32_CREATE_LABEL | NDS32_PCREL, BFD_RELOC_NDS32_WORD_9_PCREL}, -++ {4, 4, NDS32_PCREL, BFD_RELOC_NDS32_25_PCREL}, -++ {0, 0, 0, 0} -++ }, -++ -++ .relax_code_seq[BR_RANGE_U4G] = { -++ INSN_BNEC, /* bnec $rt, imm11s, $1 */ -++ INSN_SETHI_TA, /* sethi $ta, label */ -++ INSN_ORI_TA, /* ori $ta, $ta, label */ -++ INSN_JR_TA}, /* jr $ a */ -++ .relax_code_condition[BR_RANGE_U4G] = { -++ {0, 8, 0x7FF, FALSE}, -++ {0, 20, 0x1F, FALSE}, -++ {0, 0, 0, FALSE} -++ }, -++ .relax_code_size[BR_RANGE_U4G] = 16, -++ .relax_branch_isize[BR_RANGE_U4G] = 4, -++ .relax_fixup[BR_RANGE_U4G] = { -++ {0, 4, NDS32_CREATE_LABEL | NDS32_PCREL, 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} -++ }, -++ }, -+ { -+- { -+- {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 */ -++ .opcode = "bnec", -++ .br_range = BR_RANGE_S256, -++ .cond_field = { -++ {0, 8, 0x7FF, TRUE}, -++ {0, 20, 0x1F, FALSE}, -++ {0, 0, 0, FALSE} -++ }, -++ .relax_code_seq[BR_RANGE_S256] = { -++ INSN_BNEC}, /* bnec $rt, imm11s, label */ -++ .relax_code_condition[BR_RANGE_S256] = { -++ {0, 8, 0x7FF, FALSE}, -++ {0, 20, 0x1F, FALSE}, -++ {0, 0, 0, FALSE} -++ }, -++ .relax_code_size[BR_RANGE_S256] = 4, -++ .relax_branch_isize[BR_RANGE_S256] = 4, -++ .relax_fixup[BR_RANGE_S256] = { -++ {0, 4, NDS32_PCREL, BFD_RELOC_NDS32_WORD_9_PCREL}, -++ {0, 0, 0, 0} -++ }, -++ -++ .relax_code_seq[BR_RANGE_S16K] = { -++ INSN_MOVI_TA, /* movi $ta, imm11s */ -++ INSN_BNE_TA}, /* bne $rt, $ta, label */ -++ .relax_code_condition[BR_RANGE_S16K] = { -++ {0, 0, 0xFFFFF, FALSE}, -++ {4, 20, 0x1F, FALSE}, -++ {0, 0, 0, FALSE} -++ }, -++ .relax_code_size[BR_RANGE_S16K] = 8, -++ .relax_branch_isize[BR_RANGE_S16K] = 4, -++ .relax_fixup[BR_RANGE_S16K] = { -++ {0, 4, NDS32_INSN16 | NDS32_HINT, BFD_RELOC_NDS32_INSN16}, -++ {0, 4, NDS32_PTR | NDS32_HINT, BFD_RELOC_NDS32_LONGJUMP7}, -++ {4, 4, NDS32_PCREL, BFD_RELOC_NDS32_15_PCREL}, -++ {0, 0, 0, 0} -++ }, -++ -++ .relax_code_seq[BR_RANGE_S64K] = { -++ INSN_BEQC, /* beqc $rt, imm11s, $1 */ -++ INSN_J}, /* j label */ -++ .relax_code_condition[BR_RANGE_S64K] = { -++ {0, 8, 0x7FF, FALSE}, -++ {0, 20, 0x1F, FALSE}, -++ {0, 0, 0, FALSE} -++ }, -++ .relax_code_size[BR_RANGE_S64K] = 8, -++ .relax_branch_isize[BR_RANGE_S64K] = 4, -++ .relax_fixup[BR_RANGE_S64K] = { -++ {0, 4, NDS32_CREATE_LABEL | NDS32_PCREL, BFD_RELOC_NDS32_WORD_9_PCREL}, -++ {4, 4, NDS32_PCREL, BFD_RELOC_NDS32_25_PCREL}, -++ {0, 0, 0, 0} -++ }, -++ -++ .relax_code_seq[BR_RANGE_S16M] = { -++ INSN_BEQC, /* beqc $rt, imm11s, $1 */ -++ INSN_J}, /* j label */ -++ .relax_code_condition[BR_RANGE_S16M] = { -++ {0, 8, 0x7FF, FALSE}, -++ {0, 20, 0x1F, FALSE}, -++ {0, 0, 0, FALSE} -++ }, -++ .relax_code_size[BR_RANGE_S16M] = 8, -++ .relax_branch_isize[BR_RANGE_S16M] = 4, -++ .relax_fixup[BR_RANGE_S16M] = { -++ {0, 4, NDS32_CREATE_LABEL | NDS32_PCREL, BFD_RELOC_NDS32_WORD_9_PCREL}, -++ {4, 4, NDS32_PCREL, BFD_RELOC_NDS32_25_PCREL}, -++ {0, 0, 0, 0} -++ }, -++ -++ .relax_code_seq[BR_RANGE_U4G] = { -++ INSN_BEQC, /* beqc $rt, imm11s, $1 */ -++ INSN_SETHI_TA, /* sethi $ta, label */ -++ INSN_ORI_TA, /* ori $ta, $ta, label */ -++ INSN_JR_TA}, /* jr $ a */ -++ .relax_code_condition[BR_RANGE_U4G] = { -++ {0, 8, 0x7FF, FALSE}, -++ {0, 20, 0x1F, FALSE}, -++ {0, 0, 0, FALSE} -++ }, -++ .relax_code_size[BR_RANGE_U4G] = 16, -++ .relax_branch_isize[BR_RANGE_U4G] = 4, -++ .relax_fixup[BR_RANGE_U4G] = { -++ {0, 4, NDS32_CREATE_LABEL | NDS32_PCREL, 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} -++ }, -++ }, -+ { -+- { -+- {0, 4, NDS32_PCREL, 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, NDS32_PCREL, BFD_RELOC_NDS32_15_PCREL}, -+- {0, 0, 0, 0} -+- }, /* BR_RANGE_S16K */ -+- { -+- {0, 4, NDS32_CREATE_LABEL | NDS32_PCREL, BFD_RELOC_NDS32_WORD_9_PCREL}, -+- {4, 4, NDS32_PCREL, BFD_RELOC_NDS32_25_PCREL}, -+- {0, 0, 0, 0} -+- }, /* BR_RANGE_S64K */ -+- { -+- {0, 4, NDS32_CREATE_LABEL | NDS32_PCREL, BFD_RELOC_NDS32_WORD_9_PCREL}, -+- {4, 4, NDS32_PCREL, BFD_RELOC_NDS32_25_PCREL}, -+- {0, 0, 0, 0} -+- }, /* BR_RANGE_S16M */ -+- { -+- {0, 4, NDS32_CREATE_LABEL | NDS32_PCREL, 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 */ -+- } -++ .opcode = NULL, -++ }, -+ }; -++ -+ -+ /* GAS definitions for command-line options. */ -+ enum options -+@@ -1901,9 +1932,9 @@ size_t md_longopts_size = sizeof (md_longopts); -+ -+ struct nds32_parse_option_table -+ { -+- const char *name; /* Option string. */ -+- const char *help; /* Help description. */ -+- int (*func) (const char *arg); /* How to parse it. */ -++ const char *name; /* Option string. */ -++ const char *help; /* Help description. */ -++ int (*func) (const char *arg); /* How to parse it. */ -+ }; -+ -+ -+@@ -1920,7 +1951,7 @@ static int nds32_fpu_dp_ext = -1; -+ static int nds32_freg = -1; -+ static int nds32_abi = -1; -+ -+-/* Record ELF flags */ -++/* Record ELF flags. */ -+ static int nds32_elf_flags = 0; -+ static int nds32_fpu_com = 0; -+ -+@@ -1929,34 +1960,49 @@ static int nds32_parse_baseline (const char *str); -+ static int nds32_parse_freg (const char *str); -+ static int nds32_parse_abi (const char *str); -+ -++static void add_mapping_symbol (enum mstate state, -++ unsigned int padding_byte, unsigned int align); -++ -+ static struct nds32_parse_option_table parse_opts [] = -+ { -++ {"ace=", N_("\t Support user defined instruction extension"), -++ nds32_parse_udi}, -++ {"cop0=", N_("\t Support coprocessor 0 extension"), -++ nds32_parse_cop0}, -++ {"cop1=", N_("\t Support coprocessor 1 extension"), -++ nds32_parse_cop1}, -++ {"cop2=", N_("\t Support coprocessor 2 extension"), -++ nds32_parse_cop2}, -++ {"cop3=", N_("\t Support coprocessor 3 extension"), -++ nds32_parse_cop3}, -+ {"arch=", N_("\t Assemble for architecture \n\ -+ could be\n\ -+- v3, v3j, v3m, v3f, v3s, "\ -++ v3, v3j, v3m, v3m+ v3f, v3s, "\ -+ "v2, v2j, v2f, v2s"), nds32_parse_arch}, -+ {"baseline=", N_("\t Assemble for baseline \n\ -+ could be v2, v3, v3m"), -+ nds32_parse_baseline}, -+ {"fpu-freg=", N_("\t Specify a FPU configuration\n\ -+ \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}, -++ 0/4: 8 SP / 4 DP registers\n\ -++ 1/5: 16 SP / 8 DP registers\n\ -++ 2/6: 32 SP / 16 DP registers\n\ -++ 3/7: 32 SP / 32 DP registers"), nds32_parse_freg}, -+ {"abi=", N_("\t Specify a abi version\n\ -+- could be v1, v2, v2fp, v2fpp"), nds32_parse_abi}, -++ could be v1, v2, v2fp, v2fp+"), 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_dx_regs = NDS32_DEFAULT_DX_REGS; -++static int nds32_perf_ext = NDS32_DEFAULT_PERF_EXT; -++static int nds32_perf_ext2 = NDS32_DEFAULT_PERF_EXT2; -++static int nds32_string_ext = NDS32_DEFAULT_STRING_EXT; -++static int nds32_audio_ext = NDS32_DEFAULT_AUDIO_EXT; -++static int nds32_dsp_ext = NDS32_DEFAULT_DSP_EXT; -++static int nds32_zol_ext = NDS32_DEFAULT_ZOL_EXT; -+ static int nds32_fpu_fma = 0; -+ static int nds32_pic = 0; -+ static int nds32_relax_fp_as_gp = 1; -+@@ -1965,7 +2011,7 @@ static int nds32_relax_all = 1; -+ struct nds32_set_option_table -+ { -+ const char *name; /* Option string. */ -+- const char *help; /* Help description. */ -++ const char *help; /* Help description. */ -+ int *var; /* Variable to be set. */ -+ int value; /* Value to set. */ -+ }; -+@@ -1987,6 +2033,8 @@ static struct nds32_set_option_table toggle_opts [] = -+ {"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}, -++ {"dsp-ext", N_("DSP extension"), &nds32_dsp_ext, 1}, -++ {"zol-ext", N_("hardware loop extension"), &nds32_zol_ext, 1}, -+ {NULL, NULL, NULL, 0} -+ }; -+ -+@@ -2000,7 +2048,7 @@ nds32_asm_parse_operand (struct nds32_asm_desc *pdesc, -+ char **pstr, int64_t *value); -+ -+ -+-struct nds32_asm_desc asm_desc; -++static struct nds32_asm_desc asm_desc; -+ -+ /* md_after_parse_args () -+ -+@@ -2086,11 +2134,9 @@ nds32_start_line_hook (void) -+ { -+ } -+ -+-/* -+- * Pseudo opcodes -+- */ -++/* Pseudo opcodes. */ -+ -+-typedef void (*nds32_pseudo_opcode_func) (int argc, char *argv[], unsigned int pv); -++typedef void (*nds32_pseudo_opcode_func) (int argc, char *argv[], int pv); -+ struct nds32_pseudo_opcode -+ { -+ const char *opcode; -+@@ -2183,13 +2229,12 @@ static void do_pseudo_li_internal (const 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[], -+- unsigned int pv ATTRIBUTE_UNUSED) -++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")) -++ if (nds32_pic) -+ { -+ md_assemblef ("sethi $ta,hi20(%s)", arg_label); -+ md_assemblef ("ori $ta,$ta,lo12(%s)", arg_label); -+@@ -2204,18 +2249,16 @@ do_pseudo_b (int argc ATTRIBUTE_UNUSED, char *argv[], -+ } -+ -+ static void -+-do_pseudo_bal (int argc ATTRIBUTE_UNUSED, char *argv[], -+- unsigned int pv ATTRIBUTE_UNUSED) -++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"))) -++ if (nds32_pic) -+ { -+ md_assemblef ("sethi $ta,hi20(%s)", arg_label); -+ md_assemblef ("ori $ta,$ta,lo12(%s)", arg_label); -+- md_assemble ((char *) "add $ta,$ta,$gp"); -++ md_assemble ((char *) "add $ta,$ta,$gp"); -+ md_assemble ((char *) "jral $ta"); -+ } -+ else -+@@ -2226,8 +2269,7 @@ do_pseudo_bal (int argc ATTRIBUTE_UNUSED, char *argv[], -+ } -+ -+ static void -+-do_pseudo_bge (int argc ATTRIBUTE_UNUSED, char *argv[], -+- unsigned int pv ATTRIBUTE_UNUSED) -++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]); -+@@ -2235,8 +2277,7 @@ do_pseudo_bge (int argc ATTRIBUTE_UNUSED, char *argv[], -+ } -+ -+ static void -+-do_pseudo_bges (int argc ATTRIBUTE_UNUSED, char *argv[], -+- unsigned int pv ATTRIBUTE_UNUSED) -++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]); -+@@ -2244,8 +2285,7 @@ do_pseudo_bges (int argc ATTRIBUTE_UNUSED, char *argv[], -+ } -+ -+ static void -+-do_pseudo_bgt (int argc ATTRIBUTE_UNUSED, char *argv[], -+- unsigned int pv ATTRIBUTE_UNUSED) -++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]); -+@@ -2253,8 +2293,7 @@ do_pseudo_bgt (int argc ATTRIBUTE_UNUSED, char *argv[], -+ } -+ -+ static void -+-do_pseudo_bgts (int argc ATTRIBUTE_UNUSED, char *argv[], -+- unsigned int pv ATTRIBUTE_UNUSED) -++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]); -+@@ -2262,8 +2301,7 @@ do_pseudo_bgts (int argc ATTRIBUTE_UNUSED, char *argv[], -+ } -+ -+ static void -+-do_pseudo_ble (int argc ATTRIBUTE_UNUSED, char *argv[], -+- unsigned int pv ATTRIBUTE_UNUSED) -++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]); -+@@ -2271,8 +2309,7 @@ do_pseudo_ble (int argc ATTRIBUTE_UNUSED, char *argv[], -+ } -+ -+ static void -+-do_pseudo_bles (int argc ATTRIBUTE_UNUSED, char *argv[], -+- unsigned int pv ATTRIBUTE_UNUSED) -++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]); -+@@ -2280,8 +2317,7 @@ do_pseudo_bles (int argc ATTRIBUTE_UNUSED, char *argv[], -+ } -+ -+ static void -+-do_pseudo_blt (int argc ATTRIBUTE_UNUSED, char *argv[], -+- unsigned int pv ATTRIBUTE_UNUSED) -++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]); -+@@ -2289,8 +2325,7 @@ do_pseudo_blt (int argc ATTRIBUTE_UNUSED, char *argv[], -+ } -+ -+ static void -+-do_pseudo_blts (int argc ATTRIBUTE_UNUSED, char *argv[], -+- unsigned int pv ATTRIBUTE_UNUSED) -++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]); -+@@ -2298,15 +2333,13 @@ do_pseudo_blts (int argc ATTRIBUTE_UNUSED, char *argv[], -+ } -+ -+ static void -+-do_pseudo_br (int argc ATTRIBUTE_UNUSED, char *argv[], -+- unsigned int pv ATTRIBUTE_UNUSED) -++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[], -+- unsigned int pv ATTRIBUTE_UNUSED) -++do_pseudo_bral (int argc, char *argv[], int pv ATTRIBUTE_UNUSED) -+ { -+ if (argc == 1) -+ md_assemblef ("jral $lp,%s", argv[0]); -+@@ -2329,19 +2362,24 @@ do_pseudo_la_internal (const char *arg_reg, char *arg_label, -+ -+ relaxing = TRUE; -+ /* rt, label */ -+- if (!nds32_pic && !strstr(arg_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, "@ICT")) -+ { -+ 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 */ -++ /* 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")) -++ else if (strstr (arg_label, "@GOTTPOFF")) -+ { -+ /* la $rt, sym@GOTTPOFF*/ -+ md_assemblef ("sethi $ta,hi20(%s)", arg_label); -+@@ -2381,8 +2419,7 @@ do_pseudo_la_internal (const char *arg_reg, char *arg_label, -+ } -+ -+ static void -+-do_pseudo_la (int argc ATTRIBUTE_UNUSED, char *argv[], -+- unsigned int pv ATTRIBUTE_UNUSED) -++do_pseudo_la (int argc ATTRIBUTE_UNUSED, char *argv[], int pv ATTRIBUTE_UNUSED) -+ { -+ do_pseudo_la_internal (argv[0], argv[1], argv[argc]); -+ } -+@@ -2404,8 +2441,7 @@ do_pseudo_li_internal (const char *rt, int imm32s) -+ } -+ -+ static void -+-do_pseudo_li (int argc ATTRIBUTE_UNUSED, char *argv[], -+- unsigned int pv ATTRIBUTE_UNUSED) -++do_pseudo_li (int argc ATTRIBUTE_UNUSED, char *argv[], int pv ATTRIBUTE_UNUSED) -+ { -+ /* Validate argv[1] for constant expression. */ -+ expressionS exp; -+@@ -2421,8 +2457,7 @@ do_pseudo_li (int argc ATTRIBUTE_UNUSED, char *argv[], -+ } -+ -+ static void -+-do_pseudo_ls_bhw (int argc ATTRIBUTE_UNUSED, char *argv[], -+- unsigned int pv) -++do_pseudo_ls_bhw (int argc ATTRIBUTE_UNUSED, char *argv[], int pv) -+ { -+ char ls = 'r'; -+ char size = 'x'; -+@@ -2451,14 +2486,14 @@ do_pseudo_ls_bhw (int argc ATTRIBUTE_UNUSED, char *argv[], -+ relaxing = TRUE; -+ if (strstr (argv[1], "@TPOFF")) -+ { -+- /* ls.w $rt, sym@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 */ -++ /* 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); -+@@ -2509,8 +2544,7 @@ do_pseudo_ls_bhw (int argc ATTRIBUTE_UNUSED, char *argv[], -+ } -+ -+ static void -+-do_pseudo_ls_bhwp (int argc ATTRIBUTE_UNUSED, char *argv[], -+- unsigned int pv) -++do_pseudo_ls_bhwp (int argc ATTRIBUTE_UNUSED, char *argv[], int pv) -+ { -+ char *arg_rt = argv[0]; -+ char *arg_label = argv[1]; -+@@ -2537,8 +2571,7 @@ do_pseudo_ls_bhwp (int argc ATTRIBUTE_UNUSED, char *argv[], -+ } -+ -+ static void -+-do_pseudo_ls_bhwpc (int argc ATTRIBUTE_UNUSED, char *argv[], -+- unsigned int pv) -++do_pseudo_ls_bhwpc (int argc ATTRIBUTE_UNUSED, char *argv[], int pv) -+ { -+ char *arg_rt = argv[0]; -+ char *arg_inc = argv[1]; -+@@ -2563,8 +2596,7 @@ do_pseudo_ls_bhwpc (int argc ATTRIBUTE_UNUSED, char *argv[], -+ } -+ -+ static void -+-do_pseudo_ls_bhwi (int argc ATTRIBUTE_UNUSED, char *argv[], -+- unsigned int pv) -++do_pseudo_ls_bhwi (int argc ATTRIBUTE_UNUSED, char *argv[], int pv) -+ { -+ char ls = 'r'; -+ char size = 'x'; -+@@ -2597,8 +2629,7 @@ do_pseudo_move_reg_internal (char *dst, char *src) -+ } -+ -+ static void -+-do_pseudo_move (int argc ATTRIBUTE_UNUSED, char *argv[], -+- unsigned int pv ATTRIBUTE_UNUSED) -++do_pseudo_move (int argc ATTRIBUTE_UNUSED, char *argv[], int pv ATTRIBUTE_UNUSED) -+ { -+ expressionS exp; -+ -+@@ -2617,23 +2648,20 @@ do_pseudo_move (int argc ATTRIBUTE_UNUSED, char *argv[], -+ } -+ -+ static void -+-do_pseudo_neg (int argc ATTRIBUTE_UNUSED, char *argv[], -+- unsigned int pv ATTRIBUTE_UNUSED) -++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[], -+- unsigned int pv ATTRIBUTE_UNUSED) -++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[], -+- unsigned int pv ATTRIBUTE_UNUSED) -++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 */ -+@@ -2683,11 +2711,11 @@ do_pseudo_pushpopm (int argc, char *argv[], -+ /* Reduce register. */ -+ if (nds32_gpr16 && re > 10 && !(rb == 31 && re == 31)) -+ { -+- if (re >= 15 && strstr(opc, "smw") != NULL) -++ 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) -++ if (re >= 15 && strstr (opc, "lmw") != NULL) -+ md_assemblef ("%s $r15,[$sp],$r15,%d", opc, en4); -+ } -+ else -+@@ -2695,10 +2723,9 @@ do_pseudo_pushpopm (int argc, char *argv[], -+ } -+ -+ static void -+-do_pseudo_pushpop (int argc, char *argv[], -+- unsigned int pv ATTRIBUTE_UNUSED) -++do_pseudo_pushpop (int argc, char *argv[], int pv ATTRIBUTE_UNUSED) -+ { -+- /* push/pop $ra5, $label=$sp */ -++ /* push/pop $ra5, $label=$sp */ -+ char *argvm[3]; -+ -+ if (argc == 2) -+@@ -2712,15 +2739,13 @@ do_pseudo_pushpop (int argc, char *argv[], -+ } -+ -+ static void -+-do_pseudo_v3push (int argc ATTRIBUTE_UNUSED, char *argv[], -+- unsigned int pv ATTRIBUTE_UNUSED) -++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[], -+- unsigned int pv ATTRIBUTE_UNUSED) -++do_pseudo_v3pop (int argc ATTRIBUTE_UNUSED, char *argv[], int pv ATTRIBUTE_UNUSED) -+ { -+ md_assemblef ("pop25 %s,%s", argv[0], argv[1]); -+ } -+@@ -2729,11 +2754,10 @@ do_pseudo_v3pop (int argc ATTRIBUTE_UNUSED, char *argv[], -+ pv != 0, parsing "pop.s" pseudo instruction operands. */ -+ -+ static void -+-do_pseudo_pushpop_stack (int argc, char *argv[], -+- unsigned int pv) -++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 */ -++ /* 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; -+@@ -2794,8 +2818,7 @@ do_pseudo_pushpop_stack (int argc, char *argv[], -+ } -+ -+ static void -+-do_pseudo_push_bhwd (int argc ATTRIBUTE_UNUSED, char *argv[], -+- unsigned int pv ATTRIBUTE_UNUSED) -++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. */ -+@@ -2818,7 +2841,7 @@ do_pseudo_push_bhwd (int argc ATTRIBUTE_UNUSED, char *argv[], -+ md_assemblef ("l.%c $ta,%s", size, argv[0]); -+ md_assemblef ("smw.adm $ta,[%s],$ta", location); -+ -+- if ((pv & 0x3) == 0x3) /* double-word */ -++ if ((pv & 0x3) == 0x3) /* double-word */ -+ { -+ md_assemblef ("l.w $ta,%s+4", argv[0]); -+ md_assemblef ("smw.adm $ta,[%s],$ta", location); -+@@ -2826,8 +2849,7 @@ do_pseudo_push_bhwd (int argc ATTRIBUTE_UNUSED, char *argv[], -+ } -+ -+ static void -+-do_pseudo_pop_bhwd (int argc ATTRIBUTE_UNUSED, char *argv[], -+- unsigned int pv ATTRIBUTE_UNUSED) -++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. */ -+@@ -2847,7 +2869,7 @@ do_pseudo_pop_bhwd (int argc ATTRIBUTE_UNUSED, char *argv[], -+ location[7] = '\0'; -+ } -+ -+- if ((pv & 0x3) == 0x3) /* double-word */ -++ 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]); -+@@ -2858,8 +2880,7 @@ do_pseudo_pop_bhwd (int argc ATTRIBUTE_UNUSED, char *argv[], -+ } -+ -+ static void -+-do_pseudo_pusha (int argc ATTRIBUTE_UNUSED, char *argv[], -+- unsigned int pv ATTRIBUTE_UNUSED) -++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. */ -+@@ -2875,8 +2896,7 @@ do_pseudo_pusha (int argc ATTRIBUTE_UNUSED, char *argv[], -+ } -+ -+ static void -+-do_pseudo_pushi (int argc ATTRIBUTE_UNUSED, char *argv[], -+- unsigned int pv ATTRIBUTE_UNUSED) -++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. */ -+@@ -2891,8 +2911,7 @@ do_pseudo_pushi (int argc ATTRIBUTE_UNUSED, char *argv[], -+ md_assemblef ("smw.adm $ta,[%s],$ta", location); -+ } -+ -+-struct nds32_pseudo_opcode nds32_pseudo_opcode_table[] = -+-{ -++static struct nds32_pseudo_opcode nds32_pseudo_opcode_table[] = { -+ {"b", 1, do_pseudo_b, 0, 0}, -+ {"bal", 1, do_pseudo_bal, 0, 0}, -+ -+@@ -2967,8 +2986,8 @@ struct nds32_pseudo_opcode nds32_pseudo_opcode_table[] = -+ {"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 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 }, -+@@ -3009,18 +3028,16 @@ static struct nds32_pseudo_opcode * -+ nds32_lookup_pseudo_opcode (const char *str) -+ { -+ int i = 0; -+- /* Assume pseudo-opcode are less than 16-char in length. */ -+- char op[16] = {0}; -++ /* *op = first word of current source line (*str) */ -++ int maxlen = strlen (str); -++ char *op = alloca (maxlen + 1); -+ -+- for (i = 0; i < (int)ARRAY_SIZE (op); i++) -++ for (i = 0; i < maxlen; 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); -+@@ -3081,6 +3098,7 @@ nds32_parse_arch (const char *str) -+ } archs[] = -+ { -+ {"v3m", ISA_V3M, 1, 0, 0, E_NDS32_FPU_REG_32SP_16DP, E_NDS_ABI_AABI}, -++ {"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}, -+@@ -3119,11 +3137,11 @@ nds32_parse_arch (const char *str) -+ static int -+ nds32_parse_baseline (const char *str) -+ { -+- if (strcmp (str, "v3") == 0) -++ if (strcasecmp (str, "v3") == 0) -+ nds32_baseline = ISA_V3; -+- else if (strcmp (str, "v3m") == 0) -++ else if (strcasecmp (str, "v3m") == 0) -+ nds32_baseline = ISA_V3M; -+- else if (strcmp (str, "v2") == 0) -++ else if (strcasecmp (str, "v2") == 0) -+ nds32_baseline = ISA_V2; -+ else -+ { -+@@ -3140,13 +3158,13 @@ nds32_parse_baseline (const char *str) -+ static int -+ nds32_parse_freg (const char *str) -+ { -+- if (strcmp (str, "2") == 0) -++ if (strcmp (str, "2") == 0 || strcmp (str, "6") == 0) -+ nds32_freg = E_NDS32_FPU_REG_32SP_16DP; -+- else if (strcmp (str, "3") == 0) -++ else if (strcmp (str, "3") == 0 || strcmp (str, "7") == 0) -+ nds32_freg = E_NDS32_FPU_REG_32SP_32DP; -+- else if (strcmp (str, "1") == 0) -++ else if (strcmp (str, "1") == 0 || strcmp (str, "5") == 0) -+ nds32_freg = E_NDS32_FPU_REG_16SP_8DP; -+- else if (strcmp (str, "0") == 0) -++ else if (strcmp (str, "0") == 0 || strcmp (str, "4") == 0) -+ nds32_freg = E_NDS32_FPU_REG_8SP_4DP; -+ else -+ { -+@@ -3170,13 +3188,19 @@ nds32_parse_abi (const char *str) -+ nds32_abi = E_NDS_ABI_V2FP; -+ else if (strcmp (str, "v1") == 0) -+ nds32_abi = E_NDS_ABI_V1; -+- else if (strcmp (str,"v2fpp") == 0) -++ else if (strcmp (str,"v2fpp") == 0 || strcmp (str,"v2fp+") == 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; -++ /* bug-10880, decided to accept any other versions but drop them. */ -++ if (TRUE) -++ return 1; -++ else -++ { -++ /* Logic here rejects the input abi version. */ -++ as_bad (_("unknown ABI version`%s'\n"), str); -++ return 0; -++ } -+ } -+ -+ return 1; -+@@ -3198,6 +3222,10 @@ nds32_all_ext (void) -+ nds32_fpu_fma = 1; -+ nds32_fpu_sp_ext = 1; -+ nds32_fpu_dp_ext = 1; -++ nds32_dsp_ext = 1; -++ nds32_zol_ext = 1; -++ /* Turn off reduced register. */ -++ nds32_gpr16 = 0; -+ -+ return 1; -+ } -+@@ -3295,7 +3323,7 @@ nds32_parse_option (int c, const char *arg) -+ return 1; -+ } -+ -+-/* tc_check_label */ -++/* tc_check_label */ -+ -+ void -+ nds32_check_label (symbolS *label ATTRIBUTE_UNUSED) -+@@ -3342,8 +3370,7 @@ typedef struct nds32_seg_entryT -+ flagword flags; -+ } nds32_seg_entry; -+ -+-nds32_seg_entry nds32_seg_table[] = -+-{ -++static 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 -+@@ -3409,24 +3436,40 @@ nds32_seg (int i) -+ } -+ -+ /* Set if label adjustment is needed. I should not adjust .xbyte in dwarf. */ -+-static symbolS *nds32_last_label; /* Last label for alignment. */ -++static symbolS *nds32_last_label; /* Last label for aligment. */ -++ -++static void -++add_mapping_symbol_for_align (int shift, valueT addr, int is_data_align) -++{ -++ if ((shift > 1) && (addr & 1)) -++ { -++ int n = (1 << shift) - 1; -++ if (!is_data_align) -++ add_mapping_symbol (MAP_CODE, 1, 0); -++ else if ((int) (addr & n) != n) -++ add_mapping_symbol (MAP_CODE, 1, 0); -++ } -++ else if ((shift > 1) && ((int) (addr & 1) == 0)) -++ add_mapping_symbol (MAP_CODE, 0, 0); -+ -+-/* This code is referred from D30V for adjust label to be with pending -+- alignment. For example, -++} -++ -++/* 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 attach to incoming data. */ -++ Without this, the above label will not attatch to incoming data. */ -+ -+ static void -+ nds32_adjust_label (int n) -+ { -+- /* FIXME: I think adjust label and alignment is -+- the programmer's obligation. Sadly, VLSI team doesn't -++ /* 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 implementation is simple and good enough. */ -++ I think d30v's implmentation is simple and good enough. */ -+ -+ symbolS *label = nds32_last_label; -+ nds32_last_label = NULL; -+@@ -3441,10 +3484,14 @@ nds32_adjust_label (int n) -+ /* 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); -++ { -++ add_mapping_symbol_for_align (n, frag_now_fix (), 1); -++ frag_align_code (n, 0); -++ } -+ else -+ frag_align (n, 0, 0); -+ -+@@ -3474,7 +3521,7 @@ nds32_adjust_label (int n) -+ if (symbol_get_frag (sym) == old_frag -+ && S_GET_VALUE (sym) == old_value) -+ { -+- /* Warning HERE! */ -++ /* Warning HERE! */ -+ label_seen = TRUE; -+ symbol_set_frag (sym, frag_now); -+ S_SET_VALUE (sym, new_value); -+@@ -3493,7 +3540,7 @@ nds32_cons_align (int size ATTRIBUTE_UNUSED) -+ -+ 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 incoming data/instructions will not -++ 2. Clear auto-adjust state, so incommng data/instructions will not -+ adjust the label. -+ -+ For example, -+@@ -3510,15 +3557,67 @@ nds32_cons_align (int size ATTRIBUTE_UNUSED) -+ } -+ -+ static void -++make_mapping_symbol (enum mstate state, valueT value, fragS * frag, unsigned int align) -++{ -++ symbolS *symbol_p = NULL; -++ const char *symbol_name = NULL; -++ switch (state) -++ { -++ case MAP_DATA: -++ if (align == 0) { -++ symbol_name = "$d0"; -++ } -++ else if (align == 1) { -++ symbol_name = "$d1"; -++ } -++ else if (align == 2) -++ symbol_name = "$d2"; -++ else if (align == 3) -++ symbol_name = "$d3"; -++ else if (align == 4) -++ symbol_name = "$d4"; -++ break; -++ case MAP_CODE: -++ symbol_name = "$c"; -++ break; -++ default: -++ abort (); -++ } -++ -++ symbol_p = symbol_new (symbol_name, now_seg, value, frag); -++ /* local scope attribute */ -++ symbol_get_bfdsym (symbol_p)->flags |= BSF_NO_FLAGS | BSF_LOCAL; -++} -++ -++static void -++add_mapping_symbol (enum mstate state, unsigned int padding_byte, unsigned int align) -++{ -++ enum mstate current_mapping_state = -++ seg_info (now_seg)->tc_segment_info_data.mapstate; -++ -++ if (state == MAP_CODE && current_mapping_state == state) -++ return; -++ -++ if (!SEG_NORMAL (now_seg) || !subseg_text_p (now_seg)) -++ return; -++ -++ /* start adding mapping symbol */ -++ seg_info (now_seg)->tc_segment_info_data.mapstate = state; -++ make_mapping_symbol (state, (valueT) frag_now_fix () + padding_byte, -++ frag_now, align); -++} -++ -++static void -+ nds32_aligned_cons (int idx) -+ { -+ nds32_adjust_label (idx); -++ add_mapping_symbol (MAP_DATA, 0, 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. */ -++ /* Use BFD_RELOC_NDS32_DATA to avoid linker optimization replacing data. */ -+ expressionS exp; -+ -+ exp.X_add_number = 0; -+@@ -3578,7 +3677,7 @@ nds32_relax_relocs (int relax) -+ char *name; -+ int i; -+ const char *subtype_relax[] = -+- {"", "", "ex9", "ifc"}; -++ {"", "",}; -+ -+ name = input_line_pointer; -+ while (*input_line_pointer && !ISSPACE (*input_line_pointer)) -+@@ -3595,14 +3694,6 @@ nds32_relax_relocs (int relax) -+ 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; -+@@ -3652,51 +3743,36 @@ nds32_omit_fp_begin (int mode) -+ } -+ } -+ -+-/* 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) -++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_NO_EX9_FLAG; -++ 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_NO_EX9_FLAG; -++ 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); -+ } -+ } -+ -++/* Record if in the inline assembly code segment. */ -+ static void -+-nds32_loop_begin (int mode) -++nds32_inline_asm (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); -+- } -++ if (mode) -++ inline_asm = TRUE; -+ 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); -+- } -++ inline_asm = FALSE; -+ } -+ -+ struct nds32_relocs_group -+@@ -3706,16 +3782,49 @@ struct nds32_relocs_group -+ }; -+ -+ static struct nds32_relocs_group *nds32_relax_hint_current = NULL; -++/* Used to reorder the id for ".relax_hint id". */ -++static int relax_hint_bias = 0; -++/* Record current relax hint id. */ -++static int relax_hint_id_current = -1; -++int reset_bias = 0; -++/* If ".relax_hint begin" is triggered? */ -++int relax_hint_begin = 0; -++ -++/* Record the reordered relax hint id. */ -++ -++struct relax_hint_id -++{ -++ int old_id; -++ int new_id; -++ struct relax_hint_id *next; -++}; -++ -++/* FIXME: Need to find somewhere to free the list. */ -++struct relax_hint_id *record_id_head = NULL; -++ -++/* Is the buffer large enough? */ -++#define MAX_BUFFER 12 -++ -++static char *nds_itoa (int n); -++ -++static char * -++nds_itoa (int n) -++{ -++ char *buf = xmalloc (MAX_BUFFER * sizeof (char)); -++ snprintf (buf, MAX_BUFFER, "%d", n); -++ return buf; -++} -+ -+ /* Insert a relax hint. */ -+ -+ static void -+ nds32_relax_hint (int mode ATTRIBUTE_UNUSED) -+ { -+- char *name; -++ char *name = NULL; -+ char saved_char; -+ struct nds32_relocs_pattern *relocs = NULL; -+ struct nds32_relocs_group *group, *new; -++ struct relax_hint_id *record_id; -+ -+ name = input_line_pointer; -+ while (*input_line_pointer && !ISSPACE (*input_line_pointer)) -+@@ -3724,20 +3833,66 @@ nds32_relax_hint (int mode ATTRIBUTE_UNUSED) -+ *input_line_pointer = 0; -+ name = strdup (name); -+ -++ if (name && strcmp (name, "begin") == 0) -++ { -++ if (relax_hint_id_current == -1) -++ reset_bias = 1; -++ relax_hint_bias++; -++ relax_hint_id_current++; -++ relax_hint_begin = 1; -++ } -++ -++ /* Original case ".relax_hint id". It's id may need to be reordered. */ -++ if (!relax_hint_begin) -++ { -++ int tmp = strtol (name, NULL, 10); -++ record_id = record_id_head; -++ while (record_id) -++ { -++ if (record_id->old_id == tmp) -++ { -++ name = nds_itoa (record_id->new_id); -++ goto reordered_id; -++ } -++ record_id = record_id->next; -++ } -++ if (reset_bias) -++ { -++ relax_hint_bias = relax_hint_id_current - atoi (name) + 1; -++ reset_bias = 0; -++ } -++ relax_hint_id_current = tmp + relax_hint_bias; -++ -++ /* Insert the element to the head of the link list. */ -++ struct relax_hint_id *tmp_id = malloc (sizeof (struct relax_hint_id)); -++ tmp_id->old_id = tmp; -++ tmp_id->new_id = relax_hint_id_current; -++ tmp_id->next = record_id_head; -++ record_id_head = tmp_id; -++ } -++ -++ if (name && strcmp (name, "end") == 0) -++ relax_hint_begin = 0; -++ name = nds_itoa (relax_hint_id_current); -++ -++reordered_id: -++ -+ /* 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 = XNEW (struct nds32_relocs_pattern); -++ relocs = malloc (sizeof (struct nds32_relocs_pattern)); -++ memset (relocs, 0, sizeof (struct nds32_relocs_pattern)); -+ hash_insert (nds32_hint_hash, name, relocs); -+ } -+ else -+ { -+ while (relocs->next) -+ relocs=relocs->next; -+- relocs->next = XNEW (struct nds32_relocs_pattern); -++ relocs->next = malloc (sizeof (struct nds32_relocs_pattern)); -+ relocs = relocs->next; -++ memset (relocs, 0, sizeof (struct nds32_relocs_pattern)); -+ } -+ -+ relocs->next = NULL; -+@@ -3749,7 +3904,8 @@ nds32_relax_hint (int mode ATTRIBUTE_UNUSED) -+ /* 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 = XNEW (struct nds32_relocs_group); -++ new = malloc (sizeof (struct nds32_relocs_group)); -++ memset (new, 0, sizeof (struct nds32_relocs_group)); -+ new->pattern = relocs; -+ new->next = NULL; -+ group = nds32_relax_hint_current; -+@@ -3764,6 +3920,27 @@ nds32_relax_hint (int mode ATTRIBUTE_UNUSED) -+ relaxing = TRUE; -+ } -+ -++/* This is directive generated for compiler to estimate branch target -++ alignment. But assembler does not use the info currently. */ -++ -++static void -++nds32_maybe_align (int mode ATTRIBUTE_UNUSED) -++{ -++ /* Ignore the reset of line. */ -++ ignore_rest_of_line (); -++} -++ -++/* The end of security. It must check if there is any branch -++ between begin and end. */ -++static void -++nds32_security_end (int mode ATTRIBUTE_UNUSED) -++{ -++ if (crcing == FALSE) -++ as_bad (_("Found unexpected branches inside the " -++ "signature protected region.")); -++ -++} -++ -+ /* Decide the size of vector entries, only accepts 4 or 16 now. */ -+ -+ static void -+@@ -3819,7 +3996,7 @@ nds32_flag (int ignore ATTRIBUTE_UNUSED) -+ switch (i) -+ { -+ case 0: -+- /* flag: verbatim */ -++ /* flag: verbatim */ -+ verbatim = 1; -+ break; -+ default: -+@@ -3835,6 +4012,54 @@ nds32_flag (int ignore ATTRIBUTE_UNUSED) -+ } -+ -+ static void -++ict_model (int ignore ATTRIBUTE_UNUSED) -++{ -++ char *name; -++ char saved_char; -++ int i; -++ const char *possible_flags[] = { "small", "large" }; -++ -++ /* 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 */ -++ ict_flag = ICT_SMALL; -++ break; -++ case 1: -++ ict_flag = ICT_LARGE; -++ break; -++ default: -++ break; -++ } -++ /* Already found the flag, no need to continue next loop. */ -++ break; -++ } -++ } -++ -++ *input_line_pointer = saved_char; -++ ignore_rest_of_line (); -++} -++ -++/* Create .note.v2abi_compatible section if the object is compatible with v3f/v3s. -++ Do it at the md_end(). */ -++static void -++nds32_compatible_abi (int mode ATTRIBUTE_UNUSED) -++{ -++ compatible_abi = TRUE; -++} -++ -++static void -+ nds32_n12hc (int ignore ATTRIBUTE_UNUSED) -+ { -+ /* N1213HC core is used. */ -+@@ -3842,8 +4067,7 @@ nds32_n12hc (int ignore ATTRIBUTE_UNUSED) -+ -+ -+ /* The target specific pseudo-ops which we support. */ -+-const pseudo_typeS md_pseudo_table[] = -+-{ -++const pseudo_typeS md_pseudo_table[] = { -+ /* Forced alignment if declared these ways. */ -+ {"ascii", stringer, 8 + 0}, -+ {"asciz", stringer, 8 + 1}, -+@@ -3894,13 +4118,17 @@ const pseudo_typeS md_pseudo_table[] = -+ {"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}, -++ {"maybe_align", nds32_maybe_align, 0}, -++ {"signature_end", nds32_security_end, 0}, -++ {"inline_asm_begin", nds32_inline_asm, 1}, -++ {"inline_asm_end", nds32_inline_asm, 0}, -++ {"ict_model", ict_model, 0}, -++ {"v2abi_compatible", nds32_compatible_abi, 0}, -+ {NULL, NULL, 0} -+ }; -+ -+@@ -3917,9 +4145,10 @@ nds32_pre_do_align (int n, char *fill, int len, int max) -+ { -+ dwarf2_emit_insn (0); -+ fragP = frag_now; -++ add_mapping_symbol_for_align (n, frag_now_fix (), 0); -+ frag_align_code (n, max); -+ -+- /* Tag this alignment when there is a label before it. */ -++ /* Tag this alignment when there is a lable before it. */ -+ if (label_exist) -+ { -+ fragP->tc_frag_data.flag = NDS32_FRAG_LABEL; -+@@ -4003,24 +4232,26 @@ void -+ md_begin (void) -+ { -+ struct nds32_keyword *k; -+- unsigned int i; -++ relax_info_t *relax_info; -++ int flags = 0; -+ -+ 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); -++ if (nds32_gpr16) -++ flags |= NASM_OPEN_REDUCED_REG; -++ nds32_asm_init (&asm_desc, flags); -+ -+- /* Initial general purpose registers hash table. */ -++ /* 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 (i = 0; i < ARRAY_SIZE (relax_table); i++) -+- hash_insert (nds32_relax_info_hash, relax_table[i].opcode, -+- &relax_table[i]); -++ 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 (); -+@@ -4138,13 +4369,14 @@ get_range_type (const struct nds32_field *field) -+ /* Save pseudo instruction relocation list. */ -+ -+ static struct nds32_relocs_pattern* -+-nds32_elf_save_pseudo_pattern (fixS* fixP, struct nds32_opcode *opcode, -++nds32_elf_save_pseudo_pattern (fixS* fixP, struct nds32_asm_insn *insn, -+ char *out, symbolS *sym, -+ struct nds32_relocs_pattern *reloc_ptr, -+ fragS *fragP) -+ { -++ struct nds32_opcode *opcode = insn->opcode; -+ if (!reloc_ptr) -+- reloc_ptr = XNEW (struct nds32_relocs_pattern); -++ reloc_ptr = malloc (sizeof (struct nds32_relocs_pattern)); -+ reloc_ptr->seg = now_seg; -+ reloc_ptr->sym = sym; -+ reloc_ptr->frag = fragP; -+@@ -4152,6 +4384,7 @@ nds32_elf_save_pseudo_pattern (fixS* fixP, struct nds32_opcode *opcode, -+ reloc_ptr->fixP = fixP; -+ reloc_ptr->opcode = opcode; -+ reloc_ptr->where = out; -++ reloc_ptr->insn = insn->insn; -+ reloc_ptr->next = NULL; -+ return reloc_ptr; -+ } -+@@ -4193,10 +4426,21 @@ nds32_elf_record_fixup_exp (fragS *fragP, const char *str, -+ reloc = BFD_RELOC_NDS32_TLS_LE_HI20; -+ break; -+ case BFD_RELOC_NDS32_GOTTPOFF: /* @GOTTPOFF */ -+- reloc = BFD_RELOC_NDS32_TLS_IE_HI20; -++ reloc = nds32_pic ? BFD_RELOC_NDS32_TLS_IEGP_HI20 : BFD_RELOC_NDS32_TLS_IE_HI20; -++ break; -++ case BFD_RELOC_NDS32_TLS_DESC: /* @TLSDESC */ -++ reloc = BFD_RELOC_NDS32_TLS_DESC_HI20; -++ break; -++ case BFD_RELOC_NDS32_ICT: -++ reloc = BFD_RELOC_NDS32_ICT_HI20; -+ break; -+ default: /* No suffix. */ -+- reloc = BFD_RELOC_NDS32_HI20; -++ if (nds32_pic) -++ /* When the file is pic, the address must be offset to gp. -++ It may define another relocation or use GOTOFF. */ -++ reloc = BFD_RELOC_NDS32_PLT_GOTREL_HI20; -++ else -++ reloc = BFD_RELOC_NDS32_HI20; -+ break; -+ } -+ fixP = fix_new_exp (fragP, out - fragP->fr_literal, insn->opcode->isize, -+@@ -4228,8 +4472,22 @@ nds32_elf_record_fixup_exp (fragS *fragP, const char *str, -+ case BFD_RELOC_NDS32_TPOFF: /* @TPOFF */ -+ reloc = BFD_RELOC_NDS32_TLS_LE_LO12; -+ break; -++ case BFD_RELOC_NDS32_GOTTPOFF: /* @GOTTPOFF */ -++ reloc = nds32_pic ? BFD_RELOC_NDS32_TLS_IEGP_LO12 : BFD_RELOC_NDS32_TLS_IE_LO12; -++ break; -++ case BFD_RELOC_NDS32_TLS_DESC: /* @TLSDESC */ -++ reloc = BFD_RELOC_NDS32_TLS_DESC_LO12; -++ break; -++ case BFD_RELOC_NDS32_ICT: -++ reloc = BFD_RELOC_NDS32_ICT_LO12; -++ break; -+ default: /* No suffix. */ -+- reloc = BFD_RELOC_NDS32_LO12S0; -++ if (nds32_pic) -++ /* When the file is pic, the address must be offset to gp. -++ It may define another relocation or use GOTOFF. */ -++ reloc = BFD_RELOC_NDS32_PLT_GOTREL_LO12; -++ else -++ reloc = BFD_RELOC_NDS32_LO12S0; -+ break; -+ } -+ } -+@@ -4237,11 +4495,14 @@ nds32_elf_record_fixup_exp (fragS *fragP, const char *str, -+ reloc = BFD_RELOC_NDS32_LO12S1; /* [ls]hi */ -+ else if (fld->bitsize == 15 && fld->shift == 2) -+ { -+- /* [ls]wi */ -++ /* [ls]wi */ -+ switch (pexp->X_md) -+ { -+ case BFD_RELOC_NDS32_GOTTPOFF: /* @GOTTPOFF */ -+- reloc = BFD_RELOC_NDS32_TLS_IE_LO12S2; -++ reloc = nds32_pic ? BFD_RELOC_NDS32_TLS_IEGP_LO12S2 : BFD_RELOC_NDS32_TLS_IE_LO12S2; -++ break; -++ case BFD_RELOC_NDS32_ICT: -++ reloc = BFD_RELOC_NDS32_ICT_LO12S2; -+ break; -+ default: /* No suffix. */ -+ reloc = BFD_RELOC_NDS32_LO12S2; -+@@ -4251,7 +4512,7 @@ nds32_elf_record_fixup_exp (fragS *fragP, const char *str, -+ 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 */ -++ reloc = BFD_RELOC_NDS32_LO12S2_SP; /* f[ls][sd]i */ -+ -+ fixP = fix_new_exp (fragP, out - fragP->fr_literal, insn->opcode->isize, -+ insn->info, 0 /* pcrel */, reloc); -+@@ -4261,7 +4522,12 @@ nds32_elf_record_fixup_exp (fragS *fragP, const char *str, -+ { -+ /* Relocation for 32-bit branch instructions. */ -+ if (fld->bitsize == 24 && fld->shift == 1) -+- reloc = BFD_RELOC_NDS32_25_PCREL; -++ { -++ if (pexp->X_md == BFD_RELOC_NDS32_ICT) -++ reloc = BFD_RELOC_NDS32_ICT_25PC; -++ else -++ 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) -+@@ -4272,7 +4538,7 @@ nds32_elf_record_fixup_exp (fragS *fragP, const char *str, -+ abort (); -+ -+ fixP = fix_new_exp (fragP, out - fragP->fr_literal, insn->opcode->isize, -+- insn->info, 1 /* pcrel */, reloc); -++ insn->info, 1 /* pcrel */, reloc); -+ } -+ else if (fld && fld->bitpos == 0 && insn->opcode->isize == 4 -+ && (insn->attr & NASM_ATTR_GPREL)) -+@@ -4288,7 +4554,7 @@ nds32_elf_record_fixup_exp (fragS *fragP, const char *str, -+ abort (); -+ -+ fixP = fix_new_exp (fragP, out - fragP->fr_literal, insn->opcode->isize, -+- insn->info, 0 /* pcrel */, reloc); -++ insn->info, 0 /* pcrel */, reloc); -+ /* Insert INSN16 for converting fp_as_gp. */ -+ exp.X_op = O_symbol; -+ exp.X_add_symbol = abs_section_sym; -+@@ -4310,20 +4576,6 @@ nds32_elf_record_fixup_exp (fragS *fragP, const char *str, -+ 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); -+ -+@@ -4335,8 +4587,9 @@ nds32_elf_record_fixup_exp (fragS *fragP, const char *str, -+ -+ 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_asm_insn *insn, fragS *fragP, -++ const struct nds32_field *fld, -++ bfd_boolean pseudo_hint) -+ { -+ struct nds32_relocs_pattern *reloc_ptr; -+ struct nds32_relocs_group *group; -+@@ -4346,10 +4599,32 @@ nds32_elf_build_relax_relation (fixS *fixP, expressionS *pexp, char* out, -+ if (fld) -+ sym = pexp->X_add_symbol; -+ -+- if (pseudo_opcode) -++ if (pseudo_hint) -++ { -++ /* We cannot know how many instructions will be expanded for -++ the pseudo instruction here. The first expanded instruction fills -++ the memory created by relax_hint. The follower will created and link -++ here. */ -++ group = nds32_relax_hint_current; -++ while (group) -++ { -++ if (group->pattern->opcode == NULL) -++ nds32_elf_save_pseudo_pattern (fixP, insn, out, sym, -++ group->pattern, fragP); -++ else -++ { -++ group->pattern->next = -++ nds32_elf_save_pseudo_pattern (fixP, insn, out, sym, -++ NULL, fragP); -++ group->pattern = group->pattern->next; -++ } -++ group = group->next; -++ } -++ } -++ else if (pseudo_opcode) -+ { -+ /* Save instruction relation for pseudo instruction expanding pattern. */ -+- reloc_ptr = nds32_elf_save_pseudo_pattern (fixP, opcode, out, sym, -++ reloc_ptr = nds32_elf_save_pseudo_pattern (fixP, insn, out, sym, -+ NULL, fragP); -+ if (!relocs_list) -+ relocs_list = reloc_ptr; -+@@ -4367,7 +4642,7 @@ nds32_elf_build_relax_relation (fixS *fixP, expressionS *pexp, char* out, -+ group = nds32_relax_hint_current; -+ while (group) -+ { -+- nds32_elf_save_pseudo_pattern (fixP, opcode, out, sym, -++ nds32_elf_save_pseudo_pattern (fixP, insn, out, sym, -+ group->pattern, fragP); -+ group = group->next; -+ free (nds32_relax_hint_current); -+@@ -4383,40 +4658,214 @@ nds32_elf_build_relax_relation (fixS *fixP, expressionS *pexp, char* out, -+ #define N32_MEM_EXT(insn) ((N32_OP6_MEM << 25) | insn) -+ -+ /* Relax pattern for link time relaxation. */ -++/* relaxation types only! relocation types are not necessary */ -++/* refer to nds32_elf_record_fixup_exp() */ -+ -+ 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 */ -++ /* For bug-12566, LA and Floating LSI. */ -++ .main_type = NDS32_RELAX_HINT_LA_FLSI, -++ .relax_code_size = 12, -++ .relax_code_seq = -++ { -++ OP6 (SETHI), -++ OP6 (ORI), -++ OP6 (LBI), -++ }, -++ .relax_fixup = -++ { -++ {0, 4, NDS32_HINT | NDS32_ADDEND, BFD_RELOC_NDS32_LOADSTORE}, -++ {4, 4, NDS32_HINT | NDS32_PTR, BFD_RELOC_NDS32_PTR}, -++ {4, 4, NDS32_HINT | NDS32_INSN16, BFD_RELOC_NDS32_INSN16}, -++ {8, 4, NDS32_HINT | NDS32_SYM, BFD_RELOC_NDS32_LSI}, -++ {8, 4, NDS32_HINT | NDS32_ABS, BFD_RELOC_NDS32_PTR_RESOLVED}, -++ {8, 4, NDS32_HINT | NDS32_INSN16, BFD_RELOC_NDS32_INSN16}, -++ {0, 0, 0, 0} -++ } -+ }, -+ { -+- /* 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 */ -++ /* Load Address / Load-Store (LALS). */ -++ .main_type = NDS32_RELAX_HINT_LALS, -++ .relax_code_size = 12, -++ .relax_code_seq = -++ { -++ OP6 (SETHI), -++ OP6 (ORI), -++ OP6 (LBI), -++ }, -++ .relax_fixup = -++ { -++ {0, 4, NDS32_HINT | NDS32_ADDEND, BFD_RELOC_NDS32_LOADSTORE}, -++ {4, 4, NDS32_HINT | NDS32_INSN16, BFD_RELOC_NDS32_INSN16}, -++ {8, 4, NDS32_HINT | NDS32_INSN16, BFD_RELOC_NDS32_INSN16}, -++ {0, 0, 0, 0} -++ } -+ }, -+ { -+- 0, -+- 0, -+- {0}, -+- {{0, 0 , 0, 0}} -++ /* B(AL) symbol@PLT */ -++ .main_type = NDS32_RELAX_HINT_LA_PLT, -++ .relax_code_size = 16, -++ .relax_code_seq = -++ { -++ OP6 (SETHI), -++ OP6 (ORI), -++ OP6 (ALU1), -++ OP6 (JREG), -++ }, -++ .relax_fixup = -++ { -++ {0, 4, NDS32_HINT | NDS32_ADDEND, BFD_RELOC_NDS32_LOADSTORE}, -++ {4, 4, NDS32_HINT | NDS32_PTR, BFD_RELOC_NDS32_PTR}, -++ {8, 4, NDS32_HINT | NDS32_PTR, BFD_RELOC_NDS32_PTR}, -++ {12, 4, NDS32_HINT | NDS32_ABS, BFD_RELOC_NDS32_PLT_GOT_SUFF}, -++ {12, 4, NDS32_HINT | NDS32_ABS, BFD_RELOC_NDS32_PTR_RESOLVED}, -++ {12, 4, NDS32_HINT | NDS32_INSN16, BFD_RELOC_NDS32_INSN16}, -++ {0, 0, 0, 0} -++ } -++ }, -++ { -++ /* LA (@GOT). */ -++ .main_type = NDS32_RELAX_HINT_LA_GOT, -++ .relax_code_size = 12, -++ .relax_code_seq = -++ { -++ OP6 (SETHI), -++ OP6 (ORI), -++ OP6 (MEM), -++ }, -++ .relax_fixup = -++ { -++ {0, 4, NDS32_HINT | NDS32_ADDEND, BFD_RELOC_NDS32_LOADSTORE}, -++ {4, 4, NDS32_HINT | NDS32_PTR, BFD_RELOC_NDS32_PTR}, -++ {8, 4, NDS32_HINT | NDS32_ABS, BFD_RELOC_NDS32_PTR_RESOLVED}, -++ {8, 4, NDS32_HINT | NDS32_ABS, BFD_RELOC_NDS32_GOT_SUFF}, -++ {0, 0, 0, 0} -++ } -++ }, -++ { -++ /* LA (@GOTOFF). */ -++ .main_type = NDS32_RELAX_HINT_LA_GOTOFF, -++ .relax_code_size = 16, -++ .relax_code_seq = -++ { -++ OP6 (SETHI), -++ OP6 (ORI), -++ OP6 (ALU1), -++ OP6 (MEM), -++ }, -++ .relax_fixup = -++ { -++ {0, 4, NDS32_HINT | NDS32_ADDEND, BFD_RELOC_NDS32_LOADSTORE}, -++ {4, 4, NDS32_HINT | NDS32_PTR, BFD_RELOC_NDS32_PTR}, -++ {8, 4, NDS32_HINT | NDS32_ABS, BFD_RELOC_NDS32_PTR_RESOLVED}, -++ {8, 4, NDS32_HINT | NDS32_ABS, BFD_RELOC_NDS32_GOTOFF_SUFF}, -++ {12, 4, NDS32_HINT | NDS32_ABS, BFD_RELOC_NDS32_PTR_RESOLVED}, -++ {12, 4, NDS32_HINT | NDS32_ABS, BFD_RELOC_NDS32_GOTOFF_SUFF}, -++ {0, 0, 0, 0} -++ } -++ }, -++ { -++ /* TLS LE LS|LA */ -++ .main_type = NDS32_RELAX_HINT_TLS_LE_LS, -++ .relax_code_size = 16, -++ .relax_code_seq = -++ { -++ OP6(SETHI), -++ OP6(ORI), -++ OP6(MEM), -++ OP6(ALU1), -++ }, -++ .relax_fixup = -++ { -++ {0, 4, NDS32_HINT | NDS32_ADDEND, BFD_RELOC_NDS32_LOADSTORE}, -++ {4, 4, NDS32_HINT | NDS32_PTR_MULTIPLE, BFD_RELOC_NDS32_PTR}, -++ {8, 4, NDS32_HINT | NDS32_ABS, BFD_RELOC_NDS32_PTR_RESOLVED}, -++ {8, 4, NDS32_HINT | NDS32_SYM, BFD_RELOC_NDS32_TLS_LE_LS}, -++ {12, 4, NDS32_HINT | NDS32_ABS, BFD_RELOC_NDS32_PTR_RESOLVED}, -++ {12, 4, NDS32_HINT | NDS32_SYM, BFD_RELOC_NDS32_TLS_LE_ADD}, -++ {0, 0, 0, 0} -++ } -++ }, -++ { -++ /* TLS IE LA */ -++ .main_type = NDS32_RELAX_HINT_TLS_IE_LA, -++ .relax_code_size = 8, -++ .relax_code_seq = -++ { -++ OP6(SETHI), -++ OP6(LBI), -++ }, -++ .relax_fixup = -++ { -++ {0, 4, NDS32_HINT | NDS32_ADDEND, BFD_RELOC_NDS32_LOADSTORE}, -++ {4, 4, NDS32_HINT | NDS32_INSN16, BFD_RELOC_NDS32_INSN16}, -++ {0, 0, 0, 0} -++ } -++ }, -++ { -++ /* TLS IEGP LA */ -++ .main_type = NDS32_RELAX_HINT_TLS_IEGP_LA, -++ .relax_code_size = 12, -++ .relax_code_seq = -++ { -++ OP6 (SETHI), -++ OP6 (ORI), -++ OP6 (MEM), -++ }, -++ .relax_fixup = -++ { -++ {0, 4, NDS32_HINT | NDS32_ADDEND, BFD_RELOC_NDS32_LOADSTORE}, -++ {4, 4, NDS32_HINT | NDS32_PTR_PATTERN, BFD_RELOC_NDS32_PTR}, -++ {8, 4, NDS32_HINT | NDS32_ABS, BFD_RELOC_NDS32_PTR_RESOLVED}, -++ {8, 4, NDS32_HINT | NDS32_SYM, BFD_RELOC_NDS32_TLS_IEGP_LW}, -++ {0, 0, 0, 0} -++ } -++ }, -++ { -++ /* TLS DESC LS: */ -++ .main_type = NDS32_RELAX_HINT_TLS_DESC_LS, -++ .relax_code_size = 24, -++ .relax_code_seq = -++ { -++ OP6 (SETHI), -++ OP6 (ORI), -++ OP6 (ALU1), -++ OP6 (LBI), /* load argument */ -++ OP6 (JREG), -++ OP6 (MEM), /* load/store variable or load argument */ -++ }, -++ .relax_fixup = -++ { -++ {0, 4, NDS32_HINT | NDS32_ADDEND, BFD_RELOC_NDS32_LOADSTORE}, -++ {4, 4, NDS32_HINT | NDS32_PTR_PATTERN, BFD_RELOC_NDS32_PTR}, -++ {8, 4, NDS32_HINT | NDS32_ABS, BFD_RELOC_NDS32_PTR_RESOLVED}, -++ {8, 4, NDS32_HINT | NDS32_SYM, BFD_RELOC_NDS32_TLS_DESC_ADD}, -++ {12, 4, NDS32_HINT | NDS32_SYM, BFD_RELOC_NDS32_TLS_DESC_FUNC}, -++ {16, 4, NDS32_HINT | NDS32_SYM, BFD_RELOC_NDS32_TLS_DESC_CALL}, -++ {20, 4, NDS32_HINT | NDS32_SYM_DESC_MEM, BFD_RELOC_NDS32_TLS_DESC_MEM}, -++ {0, 0, 0, 0} -++ } -++ }, -++ { -++ /* Load Address of ICT. */ -++ .main_type = NDS32_RELAX_HINT_ICT_LA, -++ .relax_code_size = 8, -++ .relax_code_seq = -++ { -++ OP6 (SETHI), -++ OP6 (ORI), -++ }, -++ .relax_fixup = -++ { -++ /* TODO: insert relocations to do relax. */ -++ {0, 0, 0, 0} -++ } -++ }, -++ { -++ .main_type = 0, -++ .relax_code_seq = {0}, -++ .relax_fixup = {{0, 0 , 0, 0}} -+ } -+ }; -+ -+@@ -4481,118 +4930,189 @@ nds32_elf_sethi_range (struct nds32_relocs_pattern *pattern) -+ (((size) & 0xff) | ((convertible) ? 1 << 31 : 0) \ -+ | ((optimize) ? 1<< 30 : 0) | (insn16_on ? 1 << 29 : 0)) -+ -++#define MAC_COMBO (E_NDS32_HAS_FPU_MAC_INST|E_NDS32_HAS_MAC_DX_INST) -+ 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)) -++ static int skip_flags = NASM_ATTR_EX9_EXT | NASM_ATTR_FPU_FMA -++ | NASM_ATTR_BRANCH | NASM_ATTR_SATURATION_EXT | NASM_ATTR_GPREL -++ | NASM_ATTR_DXREG | NASM_ATTR_ISA_V1 | NASM_ATTR_ISA_V2 | NASM_ATTR_ISA_V3 -++ | NASM_ATTR_ISA_V3M | NASM_ATTR_PCREL; -++ -++ int new_flags = insn->opcode->attr & ~skip_flags; -++ while (new_flags) -+ { -+- if (nds32_fpu_dp_ext && nds32_mac) -++ int next = 1 << (ffs (new_flags) - 1); -++ new_flags &= ~next; -++ switch (next) -+ { -+- nds32_elf_flags |= E_NDS32_HAS_FPU_MAC_INST; -+- nds32_elf_flags |= E_NDS32_HAS_FPU_DP_INST; -++ case NASM_ATTR_PERF_EXT: -++ { -++ if (nds32_perf_ext) -++ { -++ nds32_elf_flags |= E_NDS32_HAS_EXT_INST; -++ skip_flags |= NASM_ATTR_PERF_EXT; -++ } -++ else -++ as_bad (_("instruction %s requires enabling performance " -++ "extension"), insn->opcode->opcode); -++ } -++ break; -++ case NASM_ATTR_PERF2_EXT: -++ { -++ if (nds32_perf_ext2) -++ { -++ nds32_elf_flags |= E_NDS32_HAS_EXT2_INST; -++ skip_flags |= NASM_ATTR_PERF2_EXT; -++ } -++ else -++ as_bad (_("instruction %s requires enabling performance " -++ "extension II"), insn->opcode->opcode); -++ } -++ break; -++ case NASM_ATTR_AUDIO_ISAEXT: -++ { -++ if (nds32_audio_ext) -++ { -++ nds32_elf_flags |= E_NDS32_HAS_AUDIO_INST; -++ skip_flags |= NASM_ATTR_AUDIO_ISAEXT; -++ } -++ else -++ as_bad (_("instruction %s requires enabling AUDIO extension"), -++ insn->opcode->opcode); -++ } -++ break; -++ case NASM_ATTR_STR_EXT: -++ { -++ if (nds32_string_ext) -++ { -++ nds32_elf_flags |= E_NDS32_HAS_STRING_INST; -++ skip_flags |= NASM_ATTR_STR_EXT; -++ } -++ else -++ as_bad (_("instruction %s requires enabling STRING extension"), -++ insn->opcode->opcode); -++ } -++ break; -++ case NASM_ATTR_DIV: -++ { -++ if (insn->opcode->attr & NASM_ATTR_DXREG) -++ { -++ if (nds32_div && nds32_dx_regs) -++ { -++ nds32_elf_flags |= E_NDS32_HAS_DIV_DX_INST; -++ skip_flags |= NASM_ATTR_DIV; -++ } -++ else -++ as_bad (_("instruction %s requires enabling DIV & DX_REGS " -++ "extension"), insn->opcode->opcode); -++ } -++ } -++ break; -++ case 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; -++ skip_flags |= NASM_ATTR_FPU; -++ } -++ else -++ as_bad (_("instruction %s requires enabling FPU extension"), -++ insn->opcode->opcode); -++ } -++ break; -++ case NASM_ATTR_FPU_SP_EXT: -++ { -++ if (nds32_fpu_sp_ext) -++ { -++ nds32_elf_flags |= E_NDS32_HAS_FPU_INST; -++ skip_flags |= NASM_ATTR_FPU_SP_EXT; -++ } -++ else -++ as_bad (_("instruction %s requires enabling FPU_SP extension"), -++ insn->opcode->opcode); -++ } -++ break; -++ case NASM_ATTR_FPU_DP_EXT: -++ { -++ if (nds32_fpu_dp_ext) -++ { -++ nds32_elf_flags |= E_NDS32_HAS_FPU_DP_INST; -++ skip_flags |= NASM_ATTR_FPU_DP_EXT; -++ } -++ else -++ as_bad (_("instruction %s requires enabling FPU_DP extension"), -++ insn->opcode->opcode); -++ } -++ break; -++ case NASM_ATTR_MAC: -++ { -++ if (insn->opcode->attr & NASM_ATTR_FPU_SP_EXT) -++ { -++ if (nds32_fpu_sp_ext && nds32_mac) -++ nds32_elf_flags |= E_NDS32_HAS_FPU_MAC_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_mac) -++ nds32_elf_flags |= E_NDS32_HAS_FPU_MAC_INST; -++ else -++ as_bad (_("instruction %s requires enabling FPU_MAC " -++ "extension"), insn->opcode->opcode); -++ } -++ else if (insn->opcode->attr & NASM_ATTR_DXREG) -++ { -++ if (nds32_dx_regs && nds32_mac) -++ nds32_elf_flags |= E_NDS32_HAS_MAC_DX_INST; -++ else -++ as_bad (_("instruction %s requires enabling DX_REGS " -++ "extension"), insn->opcode->opcode); -++ } -++ -++ if (MAC_COMBO == (MAC_COMBO & nds32_elf_flags)) -++ skip_flags |= NASM_ATTR_MAC; -++ } -++ break; -++ case NASM_ATTR_IFC_EXT: -++ { -++ nds32_elf_flags |= E_NDS32_HAS_IFC_INST; -++ skip_flags |= NASM_ATTR_IFC_EXT; -++ } -++ break; -++ case NASM_ATTR_DSP_ISAEXT: -++ { -++ if (nds32_dsp_ext) -++ { -++ nds32_elf_flags |= E_NDS32_HAS_DSP_INST; -++ skip_flags |= NASM_ATTR_DSP_ISAEXT; -++ } -++ else -++ as_bad (_("instruction %s requires enabling dsp extension"), -++ insn->opcode->opcode); -++ } -++ break; -++ case NASM_ATTR_ZOL: -++ { -++ if (nds32_zol_ext) -++ { -++ nds32_elf_flags |= E_NDS32_HAS_ZOL; -++ skip_flags |= NASM_ATTR_ZOL; -++ } -++ else -++ as_bad (_("instruction %s requires enabling zol extension"), -++ insn->opcode->opcode); -++ } -++ break; -++ default: -++ as_bad (_("internal error: unknown instruction attribute: 0x%08x"), -++ next); -+ } -+- 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. */ -+@@ -4607,100 +5127,212 @@ enum nds32_insn_type -+ N32_RELAX_ORI = (1 << 5), -+ N32_RELAX_MEM = (1 << 6), -+ N32_RELAX_MOVI = (1 << 7), -++ N32_RELAX_ALU1 = (1 << 8), -++ N32_RELAX_16BIT = (1 << 9), -+ }; -+ -+ struct nds32_hint_map -+ { -++ /* the preamble relocation */ -+ bfd_reloc_code_real_type hi_type; -++ /* mnemonic */ -+ const char *opc; -++ /* relax pattern ID */ -+ enum nds32_relax_hint_type hint_type; -++ /* range */ -+ enum nds32_br_range range; -++ /* pattern character flags */ -+ enum nds32_insn_type insn_list; -++ /* optional pattern character flags */ -++ enum nds32_insn_type option_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 variations 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} -++ { -++ /* LONGCALL4. */ -++ BFD_RELOC_NDS32_HI20, -++ "jal", -++ NDS32_RELAX_HINT_NONE, -++ BR_RANGE_U4G, -++ N32_RELAX_SETHI | N32_RELAX_ORI | N32_RELAX_CALL, -++ 0, -++ }, -++ { -++ /* LONGCALL5. */ -++ _dummy_first_bfd_reloc_code_real, -++ "bgezal", -++ NDS32_RELAX_HINT_NONE, -++ BR_RANGE_S16M, -++ N32_RELAX_BR | N32_RELAX_CALL, -++ 0, -++ }, -++ { -++ /* 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, -++ 0, -++ }, -++ { -++ /* LONGJUMP4. */ -++ BFD_RELOC_NDS32_HI20, -++ "j", -++ NDS32_RELAX_HINT_NONE, -++ BR_RANGE_U4G, -++ N32_RELAX_SETHI | N32_RELAX_ORI | N32_RELAX_JUMP, -++ 0, -++ }, -++ { -++ /* LONGJUMP5. */ -++ /* There is two kinds of variation 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, -++ 0, -++ }, -++ { -++ /* 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, -++ 0, -++ }, -++ { -++ /* LONGJUMP7. */ -++ _dummy_first_bfd_reloc_code_real, -++ "beqc", -++ NDS32_RELAX_HINT_NONE, -++ BR_RANGE_S16K, -++ N32_RELAX_MOVI | N32_RELAX_BR, -++ 0, -++ }, -++ { -++ /* LONGCALL (BAL|JR|LA symbol@PLT). */ -++ BFD_RELOC_NDS32_PLT_GOTREL_HI20, -++ NULL, -++ NDS32_RELAX_HINT_LA_PLT, -++ BR_RANGE_U4G, -++ N32_RELAX_SETHI | N32_RELAX_ORI, -++ N32_RELAX_ALU1 | N32_RELAX_CALL | N32_RELAX_JUMP, -++ }, -++ /* relative issue: #12566 */ -++ { -++ /* LA and Floating LSI. */ -++ BFD_RELOC_NDS32_HI20, -++ NULL, -++ NDS32_RELAX_HINT_LA_FLSI, -++ BR_RANGE_U4G, -++ N32_RELAX_SETHI | N32_RELAX_ORI | N32_RELAX_LSI, -++ 0, -++ }, -++ /* relative issue: #11685 #11602 */ -++ { -++ /* load address / load-store (LALS). */ -++ BFD_RELOC_NDS32_HI20, -++ NULL, -++ NDS32_RELAX_HINT_LALS, -++ BR_RANGE_U4G, -++ N32_RELAX_SETHI, -++ N32_RELAX_ORI | N32_RELAX_LSI, -++ }, -++ { -++ /* setup $GP (_GLOBAL_OFFSET_TABLE_) */ -++ BFD_RELOC_NDS32_GOTPC_HI20, -++ NULL, -++ NDS32_RELAX_HINT_LALS, -++ BR_RANGE_U4G, -++ N32_RELAX_SETHI | N32_RELAX_ORI, -++ 0, -++ }, -++ { -++ /* GOT LA/LS (symbol@GOT) */ -++ BFD_RELOC_NDS32_GOT_HI20, -++ NULL, -++ NDS32_RELAX_HINT_LA_GOT, -++ BR_RANGE_U4G, -++ N32_RELAX_SETHI | N32_RELAX_ORI, -++ N32_RELAX_MEM, -++ }, -++ { -++ /* GOTOFF LA/LS (symbol@GOTOFF) */ -++ BFD_RELOC_NDS32_GOTOFF_HI20, -++ NULL, -++ NDS32_RELAX_HINT_LA_GOTOFF, -++ BR_RANGE_U4G, -++ N32_RELAX_SETHI | N32_RELAX_ORI, -++ N32_RELAX_ALU1 | N32_RELAX_MEM, /* | N32_RELAX_LSI, */ -++ }, -++ { -++ /* TLS LE LA|LS (@TPOFF) */ -++ BFD_RELOC_NDS32_TLS_LE_HI20, -++ NULL, -++ NDS32_RELAX_HINT_TLS_LE_LS, -++ BR_RANGE_U4G, -++ N32_RELAX_SETHI | N32_RELAX_ORI, -++ N32_RELAX_ALU1 | N32_RELAX_MEM, -++ }, -++ { -++ /* TLS IE LA */ -++ BFD_RELOC_NDS32_TLS_IE_HI20, -++ NULL, -++ NDS32_RELAX_HINT_TLS_IE_LA, -++ BR_RANGE_U4G, -++ N32_RELAX_SETHI | N32_RELAX_LSI, -++ 0, -++ }, -++ { -++ /* TLS IE LS */ -++ BFD_RELOC_NDS32_TLS_IE_HI20, -++ NULL, -++ NDS32_RELAX_HINT_TLS_IE_LS, -++ BR_RANGE_U4G, -++ N32_RELAX_SETHI | N32_RELAX_LSI | N32_RELAX_MEM, -++ 0, -++ }, -++ { -++ /* TLS IEGP LA */ -++ BFD_RELOC_NDS32_TLS_IEGP_HI20, -++ NULL, -++ NDS32_RELAX_HINT_TLS_IEGP_LA, -++ BR_RANGE_U4G, -++ N32_RELAX_SETHI | N32_RELAX_ORI | N32_RELAX_MEM, -++ 0, -++ }, -++ { -++ /* TLS DESC LS */ -++ BFD_RELOC_NDS32_TLS_DESC_HI20, -++ NULL, -++ NDS32_RELAX_HINT_TLS_DESC_LS, -++ BR_RANGE_U4G, -++ N32_RELAX_SETHI | N32_RELAX_ORI | N32_RELAX_ALU1 | N32_RELAX_CALL, -++ N32_RELAX_LSI | N32_RELAX_MEM, -++ }, -++ { -++ /* Jump-patch load address (LA). */ -++ BFD_RELOC_NDS32_ICT_HI20, -++ NULL, -++ NDS32_RELAX_HINT_ICT_LA, -++ BR_RANGE_U4G, -++ N32_RELAX_SETHI | N32_RELAX_ORI, -++ 0, -++ }, -++ /* last one */ -++ {0, NULL, 0, 0 ,0, 0} -+ }; -+ -+ /* Find the relaxation pattern according to instructions. */ -++/* TODO: refine this function with hash or so */ -+ -+ static bfd_boolean -+ nds32_find_reloc_table (struct nds32_relocs_pattern *relocs_pattern, -+@@ -4739,6 +5371,9 @@ nds32_find_reloc_table (struct nds32_relocs_pattern *relocs_pattern, -+ case N32_OP6_MEM: -+ relax_type |= N32_RELAX_MEM; -+ break; -++ case N32_OP6_ALU1: -++ relax_type |= N32_RELAX_ALU1; -++ break; -+ case N32_OP6_ORI: -+ relax_type |= N32_RELAX_ORI; -+ break; -+@@ -4760,6 +5395,8 @@ nds32_find_reloc_table (struct nds32_relocs_pattern *relocs_pattern, -+ case N32_OP6_SWI: -+ case N32_OP6_LWC: -+ case N32_OP6_SWC: -++ case N32_OP6_LDC: -++ case N32_OP6_SDC: -+ relax_type |= N32_RELAX_LSI; -+ break; -+ case N32_OP6_JREG: -+@@ -4784,16 +5421,20 @@ nds32_find_reloc_table (struct nds32_relocs_pattern *relocs_pattern, -+ { -+ /* 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++) -++ int is_matched = 0; -++ for (i = 0; i < ARRAY_SIZE (check_insn); i++) -+ { -+ if (strcmp (pattern->opcode->opcode, check_insn[i]) == 0) -+ { -+ relax_type |= N32_RELAX_BR; -++ is_matched += 1; -+ break; -+ } -+ } -+- if (strcmp (pattern->opcode->opcode, "movi55") == 0) -+- relax_type |= N32_RELAX_MOVI; -++ if (!is_matched) -++ { -++ relax_type |= N32_RELAX_16BIT; -++ } -+ } -+ pattern = pattern->next; -+ } -+@@ -4801,23 +5442,35 @@ nds32_find_reloc_table (struct nds32_relocs_pattern *relocs_pattern, -+ /* 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))) -++ struct nds32_hint_map *hint = map_ptr++; -++ enum nds32_insn_type must = hint->insn_list; -++ enum nds32_insn_type optional = hint->option_list; -++ enum nds32_insn_type extra; -++ -++ if (must != (must & relax_type)) -++ continue; -++ -++ extra = relax_type ^ must; -++ if (extra != (extra & optional)) -++ continue; -++ -++ if (!hi_pattern -++ || (hi_pattern->fixP -++ && hi_pattern->fixP->fx_r_type == hint->hi_type)) -+ { -+- opc = map_ptr->opc; -+- hint_type = map_ptr->hint_type; -+- range = map_ptr->range; -++ opc = hint->opc; -++ hint_type = hint->hint_type; -++ range = hint->range; -++ map_ptr = hint; -+ break; -+ } -+- map_ptr++; -+ } -+ -+ if (map_ptr->insn_list == 0) -+ { -+- as_warn (_("Can not find match relax hint. Line: %d"), -+- relocs_pattern->frag->fr_line); -++ if (!nds32_pic) -++ as_warn (_("Can not find match relax hint. line : %d"), -++ relocs_pattern->fixP->fx_line); -+ return FALSE; -+ } -+ -+@@ -4876,12 +5529,14 @@ nds32_find_reloc_table (struct nds32_relocs_pattern *relocs_pattern, -+ /* Because there are a lot of variant of load-store, check -+ all these type here. */ -+ -+-#define CLEAN_REG(insn) ((insn) & 0xff0003ff) -++#define CLEAN_REG(insn) ((insn) & 0xfe0003ff) -++#define GET_OPCODE(insn) ((insn) & 0xfe000000) -++ -+ static bfd_boolean -+ nds32_match_hint_insn (struct nds32_opcode *opcode, uint32_t seq) -+ { -+ const char *check_insn[] = -+- { "bnes38", "beqs38", "bnez38", "bnezs8", "beqz38", "beqzs8" }; -++ { "bnes38", "beqs38", "bnez38", "bnezs8", "beqz38", "beqzs8", "jral5" }; -+ uint32_t insn = opcode->value; -+ unsigned int i; -+ -+@@ -4897,22 +5552,23 @@ nds32_match_hint_insn (struct nds32_opcode *opcode, uint32_t seq) -+ 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; -++ || insn == OP6 (LWC) || insn == OP6 (SWC) -++ || insn == OP6 (LDC) || insn == OP6 (SDC)) -++ return TRUE; -+ break; -+ case OP6 (BR2): -+ /* This is for LONGCALL5 and LONGCALL6. */ -+ if (insn == OP6 (BR2)) -+- return TRUE; -++ 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; -++ return TRUE; -+ else if (opcode->isize == 2) -+ { -+- for (i = 0; i < sizeof (check_insn) / sizeof (check_insn[0]); i++) -++ for (i = 0; i < ARRAY_SIZE (check_insn); i++) -+ if (strcmp (opcode->opcode, check_insn[i]) == 0) -+ return TRUE; -+ } -+@@ -4920,8 +5576,28 @@ nds32_match_hint_insn (struct nds32_opcode *opcode, uint32_t seq) -+ case OP6 (MOVI): -+ /* This is for LONGJUMP7. */ -+ if (opcode->isize == 2 && strcmp (opcode->opcode, "movi55") == 0) -+- return TRUE; -++ return TRUE; -++ break; -++ case OP6 (MEM): -++ if (OP6 (MEM) == GET_OPCODE (insn)) -++ return TRUE; -+ break; -++ case OP6 (JREG): -++ /* bit 24: N32_JI_JAL */ /* feed me! */ -++ if ((insn & ~(N32_BIT (24))) == JREG (JRAL)) -++ return TRUE; -++ break; -++ default: -++ if (opcode->isize == 2) -++ { -++ for (i = 0; i < ARRAY_SIZE (check_insn); i++) -++ if (strcmp (opcode->opcode, check_insn[i]) == 0) -++ return TRUE; -++ -++ if ((strcmp (opcode->opcode, "add5.pc") == 0) || -++ (strcmp (opcode->opcode, "add45") == 0)) -++ return TRUE; -++ } -+ } -+ return FALSE; -+ } -+@@ -4929,7 +5605,7 @@ nds32_match_hint_insn (struct nds32_opcode *opcode, uint32_t seq) -+ /* Append relax relocation for link time relaxing. */ -+ -+ static void -+-nds32_elf_append_relax_relocs (const char *key ATTRIBUTE_UNUSED, void *value) -++nds32_elf_append_relax_relocs (const char *key, void *value) -+ { -+ struct nds32_relocs_pattern *relocs_pattern = -+ (struct nds32_relocs_pattern *) value; -+@@ -4942,7 +5618,7 @@ nds32_elf_append_relax_relocs (const char *key ATTRIBUTE_UNUSED, void *value) -+ struct nds32_relax_hint_table hint_info; -+ nds32_relax_fixup_info_t *hint_fixup, *fixup_now; -+ size_t fixup_size; -+- offsetT branch_offset; -++ offsetT branch_offset, hi_branch_offset = 0; -+ fixS *fixP; -+ int range, offset; -+ unsigned int ptr_offset, hint_count, relax_code_size, count = 0; -+@@ -4963,6 +5639,7 @@ nds32_elf_append_relax_relocs (const char *key ATTRIBUTE_UNUSED, void *value) -+ if (pattern_now->opcode->value == OP6 (SETHI)) -+ { -+ hi_sym = pattern_now->sym; -++ hi_branch_offset = pattern_now->fixP->fx_offset; -+ break; -+ } -+ pattern_now = pattern_now->next; -+@@ -4979,15 +5656,36 @@ nds32_elf_append_relax_relocs (const char *key ATTRIBUTE_UNUSED, void *value) -+ relax_code_size = hint_info.relax_code_size; -+ pattern_now = relocs_pattern; -+ -++#ifdef NDS32_LINUX_TOOLCHAIN -++ /* prepare group relocation ID (number). */ -++ long group_id = 0; -++ if (key) -++ { -++ /* convert .relax_hint key to number */ -++ errno = 0; -++ group_id = strtol (key, NULL, 10); -++ if ((errno == ERANGE && (group_id == LONG_MAX || group_id == LONG_MIN)) -++ || (errno != 0 && group_id == 0)) -++ { -++ as_bad (_("Internal error: .relax_hint KEY is not a number!")); -++ goto restore; -++ } -++ } -++#endif -++ -+ /* Insert relaxation. */ -+ exp.X_op = O_symbol; -+ -++ /* for each instruction in the hint group */ -+ while (pattern_now) -+ { -+- /* Choose the match fixup by instruction. */ -++ if (count >= relax_code_size / 4) -++ count = 0; -++ /* Choose the match fix-up by instruction. */ -+ code_insn = CLEAN_REG (*(code_seq + count)); -+ if (!nds32_match_hint_insn (pattern_now->opcode, code_insn)) -+ { -++ /* try search from head again */ -+ count = 0; -+ code_insn = CLEAN_REG (*(code_seq + count)); -+ -+@@ -4996,8 +5694,11 @@ nds32_elf_append_relax_relocs (const char *key ATTRIBUTE_UNUSED, void *value) -+ count++; -+ if (count >= relax_code_size / 4) -+ { -+- as_bad (_("Internal error: Relax hint error. %s: %x"), -+- now_seg->name, pattern_now->opcode->value); -++ as_bad (_("Internal error: Relax hint (%s) error. %s: %s (%x)"), -++ key, -++ now_seg->name, -++ pattern_now->opcode->opcode, -++ pattern_now->opcode->value); -+ goto restore; -+ } -+ code_insn = CLEAN_REG (*(code_seq + count)); -+@@ -5024,7 +5725,7 @@ nds32_elf_append_relax_relocs (const char *key ATTRIBUTE_UNUSED, void *value) -+ } -+ fixup_size = fixup_now->size; -+ -+- /* Insert all fixup. */ -++ /* Insert all fix-up. */ -+ while (fixup_size != 0 && fixup_now->offset == offset) -+ { -+ /* Set the real instruction size in element. */ -+@@ -5093,7 +5794,108 @@ nds32_elf_append_relax_relocs (const char *key ATTRIBUTE_UNUSED, void *value) -+ { -+ /* For EMPTY relocation save the true symbol. */ -+ exp.X_add_symbol = hi_sym; -+- exp.X_add_number = branch_offset; -++ exp.X_add_number = hi_branch_offset; -++ } -++ else if (NDS32_SYM_DESC_MEM & fixup_now->ramp) -++ { -++ /* do the same as NDS32_SYM */ -++ exp.X_add_symbol = hi_sym; -++ exp.X_add_number = hi_branch_offset; -++ -++ /* extra to NDS32_SYM */ -++ /* detect if DESC_FUNC relax type do apply */ -++ if ((REG_GP == N32_RA5 (pattern_now->insn)) -++ || (REG_GP == N32_RB5 (pattern_now->insn))) -++ { -++ fixP = fix_new_exp (fragP, where - fragP->fr_literal, -++ fixup_size, &exp, pcrel, -++ BFD_RELOC_NDS32_TLS_DESC_FUNC); -++ fixP->fx_addnumber = fixP->fx_offset; -++ -++ fixup_size = 0; -++ } -++ /* else do as usual */ -++ } -++ else if (fixup_now->ramp & NDS32_PTR_PATTERN) -++ { -++ /* find out PTR_RESOLVED code pattern */ -++ nds32_relax_fixup_info_t *next_fixup = fixup_now + 1; -++ uint32_t resolved_pattern = 0; -++ while (next_fixup->offset) -++ { -++ if (next_fixup->r_type == BFD_RELOC_NDS32_PTR_RESOLVED) -++ { -++ uint32_t new_pattern = code_seq[next_fixup->offset >> 2]; -++ if (!resolved_pattern) -++ resolved_pattern = new_pattern; -++ else if (new_pattern != resolved_pattern) -++ { -++ as_warn (_("Multiple BFD_RELOC_NDS32_PTR_RESOLVED patterns are not supported yet!")); -++ break; -++ } -++ } -++ ++next_fixup; -++ } -++ -++ /* find matched code and insert fix-ups */ -++ struct nds32_relocs_pattern *next_pattern = pattern_now->next; -++ /* This relocation has to point to another instruction. Make -++ sure each resolved relocation has to be pointed. */ -++ /* All instruction in relax_table should be 32-bit. */ -++ while (next_pattern) -++ { -++ uint32_t cur_pattern = GET_OPCODE (next_pattern->opcode->value); -++ if (cur_pattern == resolved_pattern) -++ { -++ ptr_offset = next_pattern->where -++ - next_pattern->frag->fr_literal; -++ exp.X_add_symbol = symbol_temp_new (now_seg, ptr_offset, -++ next_pattern->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; -++ } -++ next_pattern = next_pattern->next; -++ } -++ -++ fixup_size = 0; -++ } -++ else if (fixup_now->ramp & NDS32_PTR_MULTIPLE) -++ { -++ /* find each PTR_RESOLVED pattern after PTR */ -++ nds32_relax_fixup_info_t *next_fixup = fixup_now + 1; -++ while (next_fixup->offset) -++ { -++ if (next_fixup->r_type == BFD_RELOC_NDS32_PTR_RESOLVED) -++ { -++ uint32_t pattern = code_seq[next_fixup->offset >> 2]; -++ /* find matched code to insert fix-ups */ -++ struct nds32_relocs_pattern *next_insn = pattern_now->next; -++ while (next_insn) -++ { -++ uint32_t insn_pattern = GET_OPCODE( -++ next_insn->opcode->value); -++ if (insn_pattern == pattern) -++ { -++ ptr_offset = next_insn->where -++ - next_insn->frag->fr_literal; -++ exp.X_add_symbol = symbol_temp_new ( -++ now_seg, ptr_offset, next_insn->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; -++ } -++ next_insn = next_insn->next; -++ } -++ } -++ ++next_fixup; -++ } -++ fixup_size = 0; -+ } -+ else -+ { -+@@ -5110,6 +5912,19 @@ nds32_elf_append_relax_relocs (const char *key ATTRIBUTE_UNUSED, void *value) -+ fixup_now++; -+ fixup_size = fixup_now->size; -+ } -++ -++#ifdef NDS32_LINUX_TOOLCHAIN -++ /* Insert group relocation for each relax hint. */ -++ if (key) -++ { -++ exp.X_add_symbol = hi_sym; /* for eyes only */ -++ exp.X_add_number = group_id; -++ fixP = fix_new_exp (fragP, where - fragP->fr_literal, fixup_size, -++ &exp, pcrel, BFD_RELOC_NDS32_GROUP); -++ fixP->fx_addnumber = fixP->fx_offset; -++ } -++#endif -++ -+ if (count < relax_code_size / 4) -+ count++; -+ pattern_now = pattern_now->next; -+@@ -5120,6 +5935,19 @@ restore: -+ frchain_now = frchain_bak; -+ } -+ -++static void -++nds32_str_tolower (const char *src, char *dest) -++{ -++ unsigned int i, len; -++ -++ len = strlen (src); -++ -++ for (i = 0; i < len; i++) -++ *(dest + i) = TOLOWER (*(src + i)); -++ -++ *(dest + i) = '\0'; -++} -++ -+ /* Check instruction if it can be used for the baseline. */ -+ -+ static bfd_boolean -+@@ -5127,6 +5955,28 @@ nds32_check_insn_available (struct nds32_asm_insn insn, const char *str) -+ { -+ int attr = insn.attr & ATTR_ALL; -+ static int baseline_isa = 0; -++ char *s; -++ -++ s = alloca (strlen (str) + 1); -++ nds32_str_tolower (str, s); -++ if (verbatim && inline_asm -++ && (((insn.opcode->value == ALU2 (MTUSR) -++ || insn.opcode->value == ALU2 (MFUSR)) -++ && (strstr (s, "lc") -++ || strstr (s, "le") -++ || strstr (s, "lb"))) -++ || (insn.attr & NASM_ATTR_ZOL))) -++ { -++ as_bad (_("Not support instruction %s in verbatim."), str); -++ return FALSE; -++ } -++ -++ if (!enable_16bit && insn.opcode->isize == 2) -++ { -++ as_bad (_("16-bit instruction is disabled: %s."), str); -++ return FALSE; -++ } -++ -+ /* No isa setting or all isa can use. */ -+ if (attr == 0 || attr == ATTR_ALL) -+ return TRUE; -+@@ -5150,28 +6000,70 @@ nds32_check_insn_available (struct nds32_asm_insn insn, const char *str) -+ -+ if ((baseline_isa & attr) == 0) -+ { -+- as_bad (_("Instruction %s not supported in the baseline."), str); -++ as_bad (_("Not support instruction %s in the baseline."), str); -+ return FALSE; -+ } -+ return TRUE; -+ } -+ -++/* Clear security and insert relocation. */ -++static void -++nds32_set_crc (fragS *fragP, struct nds32_asm_insn *insn, char *out) -++{ -++ expressionS exp; -++ -++ /* The security region begin. */ -++ if (strcmp (insn->opcode->opcode, "isps") == 0) -++ { -++ exp.X_op = O_symbol; -++ exp.X_add_symbol = abs_section_sym; -++ /* Meet the new crc in previos crc region. */ -++ if (crcing == TRUE) -++ { -++ exp.X_add_number = NDS32_SECURITY_RESTART; -++ fix_new_exp (fragP, out - fragP->fr_literal, 0, &exp, -++ 0, BFD_RELOC_NDS32_SECURITY_16); -++ } -++ crcing = TRUE; -++ /* For security used only. */ -++ exp.X_add_number = NDS32_SECURITY_START; -++ fix_new_exp (fragP, out - fragP->fr_literal, insn->opcode->isize, -++ &exp, 0 /* pcrel */, BFD_RELOC_NDS32_SECURITY_16); -++ } -++ /* Turn off security region when meeting branch. */ -++ else if (crcing && ((insn->attr & NASM_ATTR_BRANCH) -++ || insn->opcode->value == MISC (SYSCALL) -++ || insn->opcode->value == MISC (TRAP) -++ || insn->opcode->value == MISC (TEQZ) -++ || insn->opcode->value == MISC (TNEZ) -++ || insn->opcode->value == MISC (IRET) -++ || insn->attr & NASM_ATTR_IFC_EXT)) -++ { -++ crcing = FALSE; -++ exp.X_op = O_symbol; -++ exp.X_add_symbol = abs_section_sym; -++ exp.X_add_number = NDS32_SECURITY_END; -++ fix_new_exp (fragP, out - fragP->fr_literal, 0, &exp, -++ 0, BFD_RELOC_NDS32_SECURITY_16); -++ } -++} -++ -+ /* Stub of machine dependent. */ -+ -+ void -+ md_assemble (char *str) -+ { -+ struct nds32_asm_insn insn; -+- expressionS expr; -+ 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; -++ struct nds32_relocs_group *group_temp; -+ fragS *fragP; -+ int label = label_exist; -++ static bfd_boolean pseudo_hint = FALSE; -+ -+ popcode = nds32_lookup_pseudo_opcode (str); -+ /* Note that we need to check 'verbatim' and -+@@ -5180,11 +6072,23 @@ md_assemble (char *str) -+ need to perform pseudo instruction expansion/transformation. */ -+ if (popcode && !(verbatim && popcode->physical_op)) -+ { -++ /* Pseudo instruction is with relax_hint. */ -++ if (relaxing) -++ pseudo_hint = TRUE; -+ pseudo_opcode = TRUE; -+ nds32_pseudo_opcode_wrapper (str, popcode); -+ pseudo_opcode = FALSE; -++ pseudo_hint = FALSE; -+ nds32_elf_append_relax_relocs (NULL, relocs_list); -+ -++ /* Free relax_hint group list. */ -++ while (nds32_relax_hint_current) -++ { -++ group_temp = nds32_relax_hint_current->next; -++ free (nds32_relax_hint_current); -++ nds32_relax_hint_current = group_temp; -++ } -++ -+ /* Free pseudo list. */ -+ relocs_temp = relocs_list; -+ while (relocs_temp) -+@@ -5193,12 +6097,11 @@ md_assemble (char *str) -+ free (relocs_temp); -+ relocs_temp = relocs_list; -+ } -+- -+ return; -+ } -+ -+ label_exist = 0; -+- insn.info = & expr; -++ insn.info = (expressionS *) alloca (sizeof (expressionS)); -+ asm_desc.result = NASM_OK; -+ nds32_assemble (&asm_desc, &insn, str); -+ -+@@ -5235,11 +6138,13 @@ md_assemble (char *str) -+ -+ /* Make sure the beginning of text being 2-byte align. */ -+ nds32_adjust_label (1); -++ add_mapping_symbol (MAP_CODE, 0, 0); -+ 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)) -+@@ -5247,7 +6152,7 @@ md_assemble (char *str) -+ { -+ /* User assembly code branch relax for it. */ -+ /* If fld is not NULL, it is a symbol. */ -+- /* Branch must relax to proper pattern in user assembly code exclude -++ /* 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 -+@@ -5257,8 +6162,8 @@ md_assemble (char *str) -+ /* Get branch range type. */ -+ dwarf2_emit_insn (0); -+ enum nds32_br_range range_type; -++ expressionS *pexp = insn.info; -+ -+- pexp = insn.info; -+ range_type = get_range_type (fld); -+ -+ out = frag_var (rs_machine_dependent, NDS32_MAXCHAR, -+@@ -5274,6 +6179,12 @@ md_assemble (char *str) -+ else if (insn.opcode->isize == 2) -+ bfd_putb16 (insn.insn, out); -+ fragP->tc_frag_data.flag |= NDS32_FRAG_BRANCH; -++ -++ if (fld->bitsize == 24 && fld->shift == 1 -++ && pexp->X_md == BFD_RELOC_NDS32_ICT) -++ fragP->tc_frag_data.flag |= NDS32_FRAG_ICT_BRANCH; -++ -++ nds32_set_crc (fragP, &insn, out); -+ return; -+ /* md_convert_frag will insert relocations. */ -+ } -+@@ -5284,7 +6195,7 @@ md_assemble (char *str) -+ && nds32_convert_16_to_32 (stdoutput, insn.insn, NULL)))) -+ { -+ /* Record this one is relaxable. */ -+- pexp = insn.info; -++ expressionS *pexp = insn.info; -+ dwarf2_emit_insn (0); -+ if (fld) -+ { -+@@ -5304,7 +6215,7 @@ md_assemble (char *str) -+ fragP->tc_frag_data.insn = insn.insn; -+ fragP->fr_fix += 2; -+ -+- /* In original, we don't relax the instruction with label on it, -++ /* 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) -+@@ -5314,6 +6225,7 @@ md_assemble (char *str) -+ bfd_putb16 (insn_16, out); -+ else if (insn.opcode->isize == 2) -+ bfd_putb16 (insn.insn, out); -++ nds32_set_crc (fragP, &insn, out); -+ return; -+ } -+ else if ((verbatim || !relaxing) && optimize && label) -+@@ -5322,7 +6234,7 @@ md_assemble (char *str) -+ expressionS exp; -+ out = frag_var (rs_machine_dependent, insn.opcode->isize, -+ 0, 0, NULL, 0, NULL); -+- /* If this instruction is branch target, it is not relaxable. */ -++ /* 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; -+@@ -5343,18 +6255,20 @@ md_assemble (char *str) -+ -+ if (insn.opcode->isize == 4) -+ bfd_putb32 (insn.insn, out); -+- if (insn.opcode->isize == 2) -++ else 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; -++ expressionS *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); -++ nds32_elf_build_relax_relation (fixP, pexp, out, &insn, fragP, fld, -++ pseudo_hint); -++ nds32_set_crc (fragP, &insn, out); -+ } -+ -+ /* md_macro_start */ -+@@ -5402,7 +6316,7 @@ md_section_align (segT segment, valueT size) -+ { -+ int align = bfd_get_section_alignment (stdoutput, segment); -+ -+- return ((size + (1 << align) - 1) & -(1 << align)); -++ return ((size + (1 << align) - 1) & ((valueT) -1 << align)); -+ } -+ -+ /* GAS will call this function when a symbol table lookup fails, before it -+@@ -5441,6 +6355,7 @@ nds32_calc_branch_offset (segT segment, fragS *fragP, -+ { -+ /* 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) -+@@ -5464,31 +6379,31 @@ nds32_convert_to_range_type (long offset) -+ { -+ enum nds32_br_range range_type; -+ -+- if (-(0x100) <= offset && offset < 0x100) /* 256 bytes */ -++ if (-(0x100) <= offset && offset < 0x100) /* 256 bytes */ -+ range_type = BR_RANGE_S256; -+- else if (-(0x4000) <= offset && offset < 0x4000) /* 16K bytes */ -++ else if (-(0x4000) <= offset && offset < 0x4000) /* 16K bytes */ -+ range_type = BR_RANGE_S16K; -+- else if (-(0x10000) <= offset && offset < 0x10000) /* 64K bytes */ -++ else if (-(0x10000) <= offset && offset < 0x10000) /* 64K bytes */ -+ range_type = BR_RANGE_S64K; -+- else if (-(0x1000000) <= offset && offset < 0x1000000) /* 16M bytes */ -++ else if (-(0x1000000) <= offset && offset < 0x1000000) /* 16M bytes */ -+ range_type = BR_RANGE_S16M; -+- else /* 4G bytes */ -++ else /* 4G bytes */ -+ range_type = BR_RANGE_U4G; -+ -+ return range_type; -+ } -+ -+-/* Set instruction register mask. */ -++/* 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 *cond_fields; -++ 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) -+ { -+@@ -5525,24 +6440,45 @@ nds32_relax_branch_instructions (segT segment, fragS *fragP, -+ int insn_size; -+ int code_seq_offset; -+ -+- /* Replace with gas_assert (fragP->fr_symbol != NULL); */ -++ /* Replace with gas_assert (fragP->fr_symbol != NULL); */ -+ if (fragP->fr_symbol == NULL) -+ return adjust; -+ -+- /* If frag_var is not enough room, the previous frag is fr_full and with -++ /* 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; -+ -++ /* Use U4G mode for b and bal in verbatim mode because lto may combine -++ functions into a file. And order the file in the last when linking. -++ Once there is multiple definition, the same function will be kicked. -++ This may cause relocation truncated error. */ -++ if (verbatim && !nds32_pic -++ && (strcmp (opcode->opcode, "j") == 0 -++ || strcmp (opcode->opcode, "jal") == 0)) -++ { -++ fragP->fr_subtype = BR_RANGE_U4G; -++ if (init) -++ return 8; -++ else -++ return 0; -++ } -++ -+ 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; -++ { -++ branch_range_type = relax_info->br_range; -++ i = BR_RANGE_S256; -++ } -+ else -+- branch_range_type = fragP->fr_subtype; -++ { -++ branch_range_type = fragP->fr_subtype; -++ i = branch_range_type; -++ } -+ -+ offset = nds32_calc_branch_offset (segment, fragP, stretch, -+ relax_info, branch_range_type); -+@@ -5551,15 +6487,21 @@ nds32_relax_branch_instructions (segT segment, fragS *fragP, -+ -+ /* If actual range is equal to instruction jump range, do nothing. */ -+ if (real_range_type == branch_range_type) -+- return adjust; -++ { -++ fragP->fr_subtype = real_range_type; -++ return adjust; -++ } -+ -+ /* Find out proper relaxation code sequence. */ -+- for (i = BR_RANGE_S256; i < BR_RANGE_NUM; i++) -++ for (; i < BR_RANGE_NUM; i++) -+ { -+ if (real_range_type <= (unsigned int) i) -+ { -+ if (init) -+ diff = relax_info->relax_code_size[i] - opcode->isize; -++ else if (real_range_type < (unsigned int) i) -++ diff = relax_info->relax_code_size[real_range_type] -++ - relax_info->relax_code_size[branch_range_type]; -+ else -+ diff = relax_info->relax_code_size[i] -+ - relax_info->relax_code_size[branch_range_type]; -+@@ -5592,7 +6534,7 @@ nds32_relax_branch_instructions (segT segment, fragS *fragP, -+ } -+ -+ /* Update fr_subtype to new NDS32_BR_RANGE. */ -+- fragP->fr_subtype = i; -++ fragP->fr_subtype = real_range_type; -+ break; -+ } -+ } -+@@ -5631,19 +6573,19 @@ nds32_get_align (addressT address, int align) -+ { -+ addressT mask, new_address; -+ -+- mask = ~((~0U) << align); -++ mask = ~((addressT) (~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) -++invalid_prev_frag (fragS * fragP, fragS **prev_frag, bfd_boolean relax) -+ { -+ addressT address; -+ fragS *frag_start = *prev_frag; -+ -+- if (!frag_start) -++ if (!frag_start || !relax) -+ return; -+ -+ if (frag_start->last_fr_address >= fragP->last_fr_address) -+@@ -5659,13 +6601,13 @@ invalid_prev_frag (fragS * fragP, fragS **prev_frag) -+ || frag_t->fr_type == rs_align_code -+ || frag_t->fr_type == rs_align_test) -+ { -+- /* Relax instruction can not walk across label. */ -++ /* Relax instruction can not walk across lable. */ -+ if (frag_t->tc_frag_data.flag & NDS32_FRAG_LABEL) -+ { -+ prev_frag = NULL; -+ return; -+ } -+- /* Relax previous relaxable to align rs_align frag. */ -++ /* 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) -+@@ -5711,7 +6653,7 @@ nds32_relax_frag (segT segment, fragS *fragP, long stretch ATTRIBUTE_UNUSED) -+ static fragS *prev_frag = NULL; -+ int adjust = 0; -+ -+- invalid_prev_frag (fragP, &prev_frag); -++ invalid_prev_frag (fragP, &prev_frag, TRUE); -+ -+ if (fragP->tc_frag_data.flag & NDS32_FRAG_BRANCH) -+ adjust = nds32_relax_branch_instructions (segment, fragP, stretch, 0); -+@@ -5720,8 +6662,8 @@ nds32_relax_frag (segT segment, fragS *fragP, long stretch ATTRIBUTE_UNUSED) -+ 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 -+- an endless loop when relaxing. Once the instruction is relaxed, -+- it can not be undone. */ -++ unendless loop when relaxing. Once the instruction is relaxed, -++ it can not be undo. */ -+ prev_frag = fragP; -+ -+ return adjust; -+@@ -5744,11 +6686,11 @@ md_estimate_size_before_relax (fragS *fragP, segT segment) -+ 1. relax for branch -+ 2. relax for 32-bits to 16-bits */ -+ -+- /* Save previous relaxable frag. */ -++ /* Save previos relaxable frag. */ -+ static fragS *prev_frag = NULL; -+ int adjust = 0; -+ -+- invalid_prev_frag (fragP, &prev_frag); -++ invalid_prev_frag (fragP, &prev_frag, FALSE); -+ -+ if (fragP->tc_frag_data.flag & NDS32_FRAG_BRANCH) -+ adjust = nds32_relax_branch_instructions (segment, fragP, 0, 1); -+@@ -5798,12 +6740,14 @@ md_convert_frag (bfd *abfd ATTRIBUTE_UNUSED, segT sec, fragS *fragP) -+ 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; -++ bfd_boolean is_ict_sym; -++ enum bfd_reloc_code_real final_r_type; -+ -+- /* Replace with gas_assert (branch_symbol != NULL); */ -++ /* 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 previous frag is fr_full and with -++ /* 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; -+@@ -5872,6 +6816,8 @@ md_convert_frag (bfd *abfd ATTRIBUTE_UNUSED, segT sec, fragS *fragP) -+ /* Branch instruction adjust and append relocations. */ -+ relax_info = hash_find (nds32_relax_info_hash, opcode->opcode); -+ -++ is_ict_sym = fragP->tc_frag_data.flag & NDS32_FRAG_ICT_BRANCH; -++ -+ if (relax_info == NULL) -+ return; -+ -+@@ -5902,8 +6848,8 @@ md_convert_frag (bfd *abfd ATTRIBUTE_UNUSED, segT sec, fragS *fragP) -+ /* Fill in frag. */ -+ i = 0; -+ k = 0; -+- offset = 0; /* code_seq offset */ -+- buf_offset = 0; /* fr_buffer offset */ -++ offset = 0; /* code_seq offset */ -++ buf_offset = 0; /* fr_buffer offset */ -+ while (offset < code_size) -+ { -+ insn = code_seq[i]; -+@@ -5921,7 +6867,7 @@ md_convert_frag (bfd *abfd ATTRIBUTE_UNUSED, segT sec, fragS *fragP) -+ origin_insn, branch_range_type); -+ -+ /* Try to convert to 16-bits instruction. Currently, only the first -+- instruction in pattern can be converted. EX: bnez sethi ori jr, -++ 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 -+@@ -5978,9 +6924,20 @@ md_convert_frag (bfd *abfd ATTRIBUTE_UNUSED, segT sec, fragS *fragP) -+ -+ if (fixup_info[i].r_type != 0) -+ { -++ final_r_type = fixup_info[i].r_type; -++ -++ /* Convert reloc type to ICT style if this frag is -++ handle for ICT symbol. */ -++ if (is_ict_sym && final_r_type == BFD_RELOC_NDS32_HI20) -++ final_r_type = BFD_RELOC_NDS32_ICT_HI20; -++ else if (is_ict_sym && final_r_type == BFD_RELOC_NDS32_LO12S0_ORI) -++ final_r_type = BFD_RELOC_NDS32_ICT_LO12; -++ else if (is_ict_sym && fixup_info[i].ramp & NDS32_HINT) -++ continue; -++ -+ fixP = fix_new_exp (fragP, fr_where + fixup_info[i].offset, -+ fixup_size, &exp, pcrel, -+- fixup_info[i].r_type); -++ final_r_type); -+ fixP->fx_addnumber = fixP->fx_offset; -+ } -+ } -+@@ -6003,7 +6960,7 @@ nds32_relaxable_section (asection *sec) -+ && strcmp (sec->name, ".eh_frame") != 0); -+ } -+ -+-/* TC_FORCE_RELOCATION */ -++/* TC_FORCE_RELOCATION */ -+ int -+ nds32_force_relocation (fixS * fix) -+ { -+@@ -6041,8 +6998,8 @@ nds32_force_relocation (fixS * fix) -+ && 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."); -++ as_bad ("Double word for difference between two symbols is not " -++ "supported across relaxation."); -+ default: -+ ; -+ } -+@@ -6202,14 +7159,16 @@ nds32_insert_relax_entry (bfd *abfd ATTRIBUTE_UNUSED, asection *sec, -+ fixS *fixp; -+ -+ seginfo = seg_info (sec); -++ if (symbol_find ("_INDIRECT_CALL_TABLE_BASE_")) -++ ict_exist = TRUE; -+ 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) -++ -++ if (!fixp && !verbatim && (!ict_exist || ict_flag == ICT_NONE)) -+ return; -+ -+ subseg_change (sec, 0); -+@@ -6217,21 +7176,21 @@ nds32_insert_relax_entry (bfd *abfd ATTRIBUTE_UNUSED, asection *sec, -+ /* 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_symbol = abs_section_sym; -+ 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 link-time, -++ 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 (ict_exist && ict_flag == ICT_SMALL) -++ exp.X_add_number |= R_NDS32_RELAX_ENTRY_ICT_SMALL; -++ else if (ict_exist && ict_flag == ICT_LARGE) -++ exp.X_add_number |= R_NDS32_RELAX_ENTRY_ICT_LARGE; -+ } -+ if (optimize) -+ exp.X_add_number |= R_NDS32_RELAX_ENTRY_OPTIMIZE_FLAG; -+@@ -6282,9 +7241,28 @@ nds32_elf_insert_final_frag (void) -+ } -+ } -+ -++static void -++nds32_create_section_compatible_abi (void) -++{ -++ segT comp_section = subseg_new (".note.v2abi_compatible", 0); -++ bfd_set_section_flags (stdoutput, comp_section, -++ SEC_READONLY | SEC_DATA | SEC_EXCLUDE); -++ -++ /* Set content to .v2abi_compatible section. */ -++ now_seg = comp_section; -++ frag_grow (NDS32_MAXCHAR); -++ char *out = frag_more (4); -++ if (compatible_abi) -++ bfd_putb32 ((bfd_vma) 1, out); -++ else -++ bfd_putb32 ((bfd_vma) 0, out); -++} -++ -+ void -+ md_end (void) -+ { -++ if (compatible_abi) -++ nds32_create_section_compatible_abi (); -+ nds32_elf_insert_final_frag (); -+ nds32_elf_analysis_relax_hint (); -+ bfd_map_over_sections (stdoutput, nds32_insert_leb128_fixes, NULL); -+@@ -6390,6 +7368,8 @@ nds32_fix_adjustable (fixS *fixP) -+ case BFD_RELOC_NDS32_LONGJUMP5: -+ case BFD_RELOC_NDS32_LONGJUMP6: -+ case BFD_RELOC_NDS32_LONGJUMP7: -++ case BFD_RELOC_NDS32_10IFCU_PCREL: -++ case BFD_RELOC_NDS32_17IFC_PCREL: -+ return 1; -+ default: -+ return 0; -+@@ -6407,7 +7387,7 @@ elf_nds32_final_processing (void) -+ && !(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 -++ 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) -+ { -+@@ -6430,9 +7410,6 @@ elf_nds32_final_processing (void) -+ 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; -+ -+@@ -6440,7 +7417,7 @@ elf_nds32_final_processing (void) -+ elf_elfheader (stdoutput)->e_flags |= nds32_elf_flags; -+ } -+ -+-/* Implement md_apply_fix. Apply the fix-up or transform the fix-up for -++/* Implement md_apply_fix. Apply the fix-up or tranform the fix-up for -+ later relocation generation. */ -+ -+ void -+@@ -6463,14 +7440,10 @@ nds32_apply_fix (fixS *fixP, valueT *valP, segT seg ATTRIBUTE_UNUSED) -+ fixP->fx_addnumber = value; -+ fixP->tc_fix_data = NULL; -+ -+- /* Transform specific relocations here for later relocation generation. -+- Tag data here for ex9 relaxation and tag tls data for linker. */ -++ /* Tranform specific relocations here for later relocation generation. -++ Tag tls data here 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: -+@@ -6479,6 +7452,12 @@ nds32_apply_fix (fixS *fixP, valueT *valP, segT seg ATTRIBUTE_UNUSED) -+ case BFD_RELOC_NDS32_GOTTPOFF: -+ case BFD_RELOC_NDS32_TLS_IE_HI20: -+ case BFD_RELOC_NDS32_TLS_IE_LO12S2: -++ case BFD_RELOC_NDS32_TLS_DESC_HI20: -++ case BFD_RELOC_NDS32_TLS_DESC_LO12: -++ case BFD_RELOC_NDS32_TLS_IE_LO12: -++ case BFD_RELOC_NDS32_TLS_IEGP_HI20: -++ case BFD_RELOC_NDS32_TLS_IEGP_LO12: -++ case BFD_RELOC_NDS32_TLS_IEGP_LO12S2: -+ S_SET_THREAD_LOCAL (fixP->fx_addsy); -+ break; -+ default: -+@@ -6519,7 +7498,7 @@ nds32_apply_fix (fixS *fixP, valueT *valP, segT seg ATTRIBUTE_UNUSED) -+ ---- 8< ---- 8< ---- 8< ---- 8< ---- -+ -+ We use a single relocation entry for this expression. -+- * The initial distance value is stored directly in that location -++ * 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. -+@@ -6605,7 +7584,6 @@ nds32_apply_fix (fixS *fixP, valueT *valP, segT seg ATTRIBUTE_UNUSED) -+ break; -+ case BFD_RELOC_64: -+ md_number_to_chars (where, value, 8); -+- break; -+ default: -+ as_bad_where (fixP->fx_file, fixP->fx_line, -+ _("Internal error: Unknown fixup type %d (`%s')"), -+@@ -6624,9 +7602,9 @@ tc_gen_reloc (asection *section ATTRIBUTE_UNUSED, fixS *fixP) -+ arelent *reloc; -+ bfd_reloc_code_real_type code; -+ -+- reloc = XNEW (arelent); -++ reloc = (arelent *) xmalloc (sizeof (arelent)); -+ -+- reloc->sym_ptr_ptr = XNEW (asymbol *); -++ 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; -+ -+@@ -6661,13 +7639,15 @@ tc_gen_reloc (asection *section ATTRIBUTE_UNUSED, fixS *fixP) -+ return reloc; -+ } -+ -+-struct suffix_name suffix_table[] = -++static 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} -++ {"GOTOFF", BFD_RELOC_NDS32_GOTOFF}, -++ {"GOT", BFD_RELOC_NDS32_GOT20}, -++ {"TPOFF", BFD_RELOC_NDS32_TPOFF}, -++ {"PLT", BFD_RELOC_NDS32_25_PLTREL}, -++ {"GOTTPOFF", BFD_RELOC_NDS32_GOTTPOFF}, -++ {"TLSDESC", BFD_RELOC_NDS32_TLS_DESC}, -++ {"ICT", BFD_RELOC_NDS32_ICT} -+ }; -+ -+ /* Implement md_parse_name. */ -+@@ -6686,9 +7666,9 @@ nds32_parse_name (char const *name, expressionS *exprP, -+ exprP->X_op = O_symbol; -+ exprP->X_add_number = 0; -+ -+- /* Check the special name if a symbol. */ -++ /* Check the specail name if a symbol. */ -+ segment = S_GET_SEGMENT (exprP->X_add_symbol); -+- if (segment != undefined_section) -++ if ((segment != undefined_section) && (*nextcharP != '@')) -+ return 0; -+ -+ if (strcmp (name, GOT_NAME) == 0 && *nextcharP != '@') -+@@ -6702,13 +7682,11 @@ nds32_parse_name (char const *name, expressionS *exprP, -+ char *next; -+ for (i = 0; i < ARRAY_SIZE (suffix_table); i++) -+ { -+- next = input_line_pointer + 1 + strlen(suffix_table[i].suffix); -++ 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; -+@@ -6718,6 +7696,10 @@ nds32_parse_name (char const *name, expressionS *exprP, -+ } -+ } -+ } -++ -++ if (exprP->X_md == BFD_RELOC_NDS32_ICT) -++ ict_exist = TRUE; -++ -+ return 1; -+ } -+ -+diff --git binutils-2.30/gas/config/tc-nds32.h binutils-2.30-nds32/gas/config/tc-nds32.h -+index 178ca4ec33..bcea94afe0 100644 -+--- binutils-2.30/gas/config/tc-nds32.h -++++ binutils-2.30-nds32/gas/config/tc-nds32.h -+@@ -24,13 +24,28 @@ -+ -+ #include "bfd_stdint.h" -+ -++/* Enum mapping symbol. */ -++enum mstate -++{ -++ MAP_UNDEFINED = 0, /* Must be zero, for seginfo in new sections. */ -++ MAP_DATA, -++ MAP_CODE, -++}; -++#define TC_SEGMENT_INFO_TYPE struct nds32_segment_info_type -++ -++/* For mapping symbol. */ -++struct nds32_segment_info_type -++{ -++ enum mstate mapstate; -++}; -++ -+ #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] */ -++/* 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 -+@@ -42,29 +57,28 @@ -+ #define TARGET_BYTES_BIG_ENDIAN 1 -+ #endif -+ -+-/* as.c. */ -+-/* Extend GAS command line option handling capability. */ -++/* as.c */ -++/* Extend GAS command line option handling capability */ -+ extern int nds32_parse_option (int, const 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); -+- -++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 */ -++/* 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. */ -++/* dwarf2dbg.c */ -+ #define DWARF2_USE_FIXED_ADVANCE_PC 1 -+ -+-/* write.c. */ -++/* 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); -+@@ -73,14 +87,13 @@ 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); -++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) -+@@ -103,7 +116,7 @@ extern void tc_nds32_frame_initial_instructions (void); -+ #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_FIX_TYPE struct fix* -+ #define TC_INIT_FIX_DATA(fixP) \ -+ do \ -+ { \ -+@@ -111,8 +124,8 @@ extern void tc_nds32_frame_initial_instructions (void); -+ } \ -+ while (0) -+ -+-/* read.c. */ -+-/* Extend GAS macro handling capability. */ -++/* 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 *); -+@@ -128,7 +141,6 @@ 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) -+@@ -143,7 +155,7 @@ extern void nds32_do_align (int); -+ #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)) \ -++ || 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 () -+@@ -151,7 +163,7 @@ extern void nds32_do_align (int); -+ #define md_cleanup() nds32_cleanup () -+ #define LOCAL_LABELS_FB 1 /* Permit temporary numeric labels. */ -+ -+-/* frags.c. */ -++/* frags.c */ -+ -+ enum FRAG_ATTR -+ { -+@@ -161,7 +173,8 @@ enum FRAG_ATTR -+ NDS32_FRAG_LABEL = 0x8, -+ NDS32_FRAG_FINAL = 0x10, -+ NDS32_FRAG_RELAXABLE_BRANCH = 0x20, -+- NDS32_FRAG_ALIGN = 0x40 -++ NDS32_FRAG_ALIGN = 0x40, -++ NDS32_FRAG_ICT_BRANCH = 0x80 -+ }; -+ -+ struct nds32_frag_type -+@@ -231,7 +244,11 @@ enum nds32_ramp -+ NDS32_FIX = (1 << 7), -+ NDS32_ADDEND = (1 << 8), -+ NDS32_SYM = (1 << 9), -+- NDS32_PCREL = (1 << 10) -++ NDS32_PCREL = (1 << 10), -++ NDS32_PTR_PATTERN = (1 << 11), -++ NDS32_PTR_MULTIPLE = (1 << 12), -++ NDS32_GROUP = (1 << 13), -++ NDS32_SYM_DESC_MEM = (1 << 14) -+ }; -+ -+ typedef struct nds32_relax_fixup_info -+@@ -255,7 +272,7 @@ typedef struct nds32_cond_field -+ #define NDS32_MAXCHAR 20 -+ /* In current, the max extended 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_NUM 6 -+ #define MAX_RELAX_FIX 12 -+ -+ typedef struct nds32_relax_info -+@@ -275,8 +292,18 @@ typedef struct nds32_relax_info -+ enum nds32_relax_hint_type -+ { -+ NDS32_RELAX_HINT_NONE = 0, -+- NDS32_RELAX_HINT_LA, -+- NDS32_RELAX_HINT_LS -++ NDS32_RELAX_HINT_LA_FLSI, -++ NDS32_RELAX_HINT_LALS, -++ NDS32_RELAX_HINT_LA_PLT, -++ NDS32_RELAX_HINT_LA_GOT, -++ NDS32_RELAX_HINT_LA_GOTOFF, -++ NDS32_RELAX_HINT_TLS_START = 0x100, -++ NDS32_RELAX_HINT_TLS_LE_LS, -++ NDS32_RELAX_HINT_TLS_IE_LS, -++ NDS32_RELAX_HINT_TLS_IE_LA, -++ NDS32_RELAX_HINT_TLS_IEGP_LA, -++ NDS32_RELAX_HINT_TLS_DESC_LS, -++ NDS32_RELAX_HINT_ICT_LA, -+ }; -+ -+ struct nds32_relax_hint_table -+@@ -287,4 +314,4 @@ struct nds32_relax_hint_table -+ nds32_relax_fixup_info_t relax_fixup[MAX_RELAX_FIX]; -+ }; -+ -+-#endif /* TC_NDS32 */ -++#endif /* TC_NDS32 */ -+diff --git binutils-2.30/gas/configure binutils-2.30-nds32/gas/configure -+index 0d5422572f..41a83a2998 100755 -+--- binutils-2.30/gas/configure -++++ binutils-2.30-nds32/gas/configure -+@@ -12491,6 +12491,11 @@ _ACEOF -+ ;; -+ -+ nds32) -++ # setup NDS32_LINUX_TOOLCHAIN definition -++ if test "linux" = $em; then -++$as_echo "#define NDS32_LINUX_TOOLCHAIN 1" >>confdefs.h -++ fi -++ -+ # Decide BASELINE, REDUCED_REGS, FPU_DP_EXT, FPU_SP_EXT features -+ # based on arch_name. -+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for default configuration of --with-arch" >&5 -+@@ -12582,6 +12587,34 @@ $as_echo "#define NDS32_DEFAULT_AUDIO_EXT 1" >>confdefs.h -+ fi -+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $enable_audio_ext" >&5 -+ $as_echo "$enable_audio_ext" >&6; } -++ -++{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for default configuration of --enable-dsp-ext" >&5 -++$as_echo_n "checking for default configuration of --enable-dsp-ext... " >&6; } -++ if test "x${enable_dsp_ext}" == xno; then -++ -++$as_echo "#define NDS32_DEFAULT_DSP_EXT 0" >>confdefs.h -++ -++ else -++ -++$as_echo "#define NDS32_DEFAULT_DSP_EXT 1" >>confdefs.h -++ -++ fi -++ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $enable_dsp_ext" >&5 -++$as_echo "$enable_dsp_ext" >&6; } -++ -++ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for default configuration of --enable-zol-ext" >&5 -++$as_echo_n "checking for default configuration of --enable-zol-ext... " >&6; } -++ if test "x${enable_zol_ext}" == xno; then -++ -++$as_echo "#define NDS32_DEFAULT_ZOL_EXT 0" >>confdefs.h -++ -++ else -++ -++$as_echo "#define NDS32_DEFAULT_ZOL_EXT 1" >>confdefs.h -++ -++ fi -++ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $enable_zol_ext" >&5 -++$as_echo "$enable_zol_ext" >&6; } -+ ;; -+ -+ aarch64 | i386 | riscv | s390 | sparc) -+diff --git binutils-2.30/include/dis-asm.h binutils-2.30-nds32/include/dis-asm.h -+index eebdaf874f..5cbe83aad7 100644 -+--- binutils-2.30/include/dis-asm.h -++++ binutils-2.30-nds32/include/dis-asm.h -+@@ -261,11 +261,13 @@ extern void print_arm_disassembler_options (FILE *); -+ extern void print_arc_disassembler_options (FILE *); -+ extern void print_s390_disassembler_options (FILE *); -+ extern void print_wasm32_disassembler_options (FILE *); -++extern void print_nds32_disassembler_options (FILE *); -+ extern bfd_boolean aarch64_symbol_is_valid (asymbol *, struct disassemble_info *); -+ extern bfd_boolean arm_symbol_is_valid (asymbol *, struct disassemble_info *); -+ extern void disassemble_init_powerpc (struct disassemble_info *); -+ extern void disassemble_init_s390 (struct disassemble_info *); -+ extern void disassemble_init_wasm32 (struct disassemble_info *); -++extern void disassemble_init_nds32 (struct disassemble_info *); -+ extern const disasm_options_t *disassembler_options_powerpc (void); -+ extern const disasm_options_t *disassembler_options_arm (void); -+ extern const disasm_options_t *disassembler_options_s390 (void); -+diff --git binutils-2.30/include/elf/nds32.h binutils-2.30-nds32/include/elf/nds32.h -+index 1b3a3219d0..7250f2bb0c 100644 -+--- binutils-2.30/include/elf/nds32.h -++++ binutils-2.30-nds32/include/elf/nds32.h -+@@ -107,9 +107,9 @@ START_RELOC_NUMBERS (elf_nds32_reloc_type) -+ RELOC_NUMBER (R_NDS32_SDA17S2_RELA, 74) -+ RELOC_NUMBER (R_NDS32_SDA18S1_RELA, 75) -+ RELOC_NUMBER (R_NDS32_SDA19S0_RELA, 76) -+- RELOC_NUMBER (R_NDS32_DWARF2_OP1_RELA, 77) -+- RELOC_NUMBER (R_NDS32_DWARF2_OP2_RELA, 78) -+- RELOC_NUMBER (R_NDS32_DWARF2_LEB_RELA, 79) -++ RELOC_NUMBER (R_NDS32_DWARF2_OP1_RELA, 77) /* This is obsoleted. */ -++ RELOC_NUMBER (R_NDS32_DWARF2_OP2_RELA, 78) /* This is obsoleted. */ -++ RELOC_NUMBER (R_NDS32_DWARF2_LEB_RELA, 79) /* This is obsoleted. */ -+ RELOC_NUMBER (R_NDS32_UPDATE_TA_RELA, 80) /* This is obsoleted. */ -+ RELOC_NUMBER (R_NDS32_9_PLTREL, 81) -+ RELOC_NUMBER (R_NDS32_PLT_GOTREL_LO20, 82) -+@@ -128,15 +128,6 @@ START_RELOC_NUMBERS (elf_nds32_reloc_type) -+ RELOC_NUMBER (R_NDS32_25_ABS_RELA, 95) -+ RELOC_NUMBER (R_NDS32_17IFC_PCREL_RELA, 96) -+ RELOC_NUMBER (R_NDS32_10IFCU_PCREL_RELA, 97) -+- RELOC_NUMBER (R_NDS32_TLS_LE_HI20, 98) -+- RELOC_NUMBER (R_NDS32_TLS_LE_LO12, 99) -+- RELOC_NUMBER (R_NDS32_TLS_IE_HI20, 100) -+- RELOC_NUMBER (R_NDS32_TLS_IE_LO12S2, 101) -+- RELOC_NUMBER (R_NDS32_TLS_TPOFF, 102) -+- RELOC_NUMBER (R_NDS32_TLS_LE_20, 103) -+- RELOC_NUMBER (R_NDS32_TLS_LE_15S0, 104) -+- RELOC_NUMBER (R_NDS32_TLS_LE_15S1, 105) -+- RELOC_NUMBER (R_NDS32_TLS_LE_15S2, 106) -+ RELOC_NUMBER (R_NDS32_LONGCALL4, 107) -+ RELOC_NUMBER (R_NDS32_LONGCALL5, 108) -+ RELOC_NUMBER (R_NDS32_LONGCALL6, 109) -+@@ -144,7 +135,37 @@ START_RELOC_NUMBERS (elf_nds32_reloc_type) -+ RELOC_NUMBER (R_NDS32_LONGJUMP5, 111) -+ RELOC_NUMBER (R_NDS32_LONGJUMP6, 112) -+ RELOC_NUMBER (R_NDS32_LONGJUMP7, 113) -++ RELOC_NUMBER (R_NDS32_SECURITY_16, 114) -++ /* TLS support { */ -++ RELOC_NUMBER (R_NDS32_TLS_TPOFF, 102) -++ RELOC_NUMBER (R_NDS32_TLS_LE_HI20, 98) -++ RELOC_NUMBER (R_NDS32_TLS_LE_LO12, 99) -++ RELOC_NUMBER (R_NDS32_TLS_LE_20, 103) -++ RELOC_NUMBER (R_NDS32_TLS_LE_15S0, 104) -++ RELOC_NUMBER (R_NDS32_TLS_LE_15S1, 105) -++ RELOC_NUMBER (R_NDS32_TLS_LE_15S2, 106) -++ RELOC_NUMBER (R_NDS32_TLS_IE_HI20, 100) -++ RELOC_NUMBER (R_NDS32_TLS_IE_LO12, 115) -++ RELOC_NUMBER (R_NDS32_TLS_IE_LO12S2, 101) -++ RELOC_NUMBER (R_NDS32_TLS_IEGP_HI20, 116) -++ RELOC_NUMBER (R_NDS32_TLS_IEGP_LO12, 117) -++ RELOC_NUMBER (R_NDS32_TLS_IEGP_LO12S2, 118) -++ RELOC_NUMBER (R_NDS32_TLS_DESC, 119) -++ RELOC_NUMBER (R_NDS32_TLS_DESC_HI20, 120) -++ RELOC_NUMBER (R_NDS32_TLS_DESC_LO12, 121) -++ RELOC_NUMBER (R_NDS32_TLS_DESC_20, 122) -++ RELOC_NUMBER (R_NDS32_TLS_DESC_SDA17S2, 123) -++ /* TLS support } */ -++ /* new relocation type add here. */ -++ RELOC_NUMBER (R_NDS32_RELOC_NEXT, 124) -++ -++ /* Jump-patch table relocations. */ -++ RELOC_NUMBER (R_NDS32_ICT_HI20, 125) -++ RELOC_NUMBER (R_NDS32_ICT_LO12, 126) -++ RELOC_NUMBER (R_NDS32_ICT_25PC, 127) -++ RELOC_NUMBER (R_NDS32_ICT_LO12S2, 128) -+ -++ /* relax only following */ -+ RELOC_NUMBER (R_NDS32_RELAX_ENTRY, 192) -+ RELOC_NUMBER (R_NDS32_GOT_SUFF, 193) -+ RELOC_NUMBER (R_NDS32_GOTOFF_SUFF, 194) -+@@ -164,9 +185,21 @@ START_RELOC_NUMBERS (elf_nds32_reloc_type) -+ RELOC_NUMBER (R_NDS32_DIFF_ULEB128, 208) -+ RELOC_NUMBER (R_NDS32_DATA, 209) -+ RELOC_NUMBER (R_NDS32_TRAN, 210) -++ RELOC_NUMBER (R_NDS32_EMPTY, 213) -++ /* TLS support { */ -+ RELOC_NUMBER (R_NDS32_TLS_LE_ADD, 211) -+ RELOC_NUMBER (R_NDS32_TLS_LE_LS, 212) -+- RELOC_NUMBER (R_NDS32_EMPTY, 213) -++ RELOC_NUMBER (R_NDS32_TLS_IEGP_LW, 220) -++ RELOC_NUMBER (R_NDS32_TLS_DESC_ADD, 214) -++ RELOC_NUMBER (R_NDS32_TLS_DESC_FUNC, 215) -++ RELOC_NUMBER (R_NDS32_TLS_DESC_CALL, 216) -++ RELOC_NUMBER (R_NDS32_TLS_DESC_MEM, 217) -++ RELOC_NUMBER (R_NDS32_RELAX_REMOVE, 218) -++ RELOC_NUMBER (R_NDS32_RELAX_GROUP, 219) -++ /* TLS support } */ -++ /* new relaxation type add here. */ -++ RELOC_NUMBER (R_NDS32_LSI, 221) -++ RELOC_NUMBER (R_NDS32_RELAX_NEXT, 222) -+ -+ END_RELOC_NUMBERS (R_NDS32_max) -+ -+@@ -259,10 +292,10 @@ END_RELOC_NUMBERS (R_NDS32_max) -+ #define E_NDS32_FPU_REG_32SP_32DP 0x3 -+ /* FPU MAC instruction used. */ -+ #define E_NDS32_HAS_FPU_MAC_INST 0x01000000 -+-/* <<>>. */ -+-#define E_NDS32_NULL 0x02000000 -+-/* PIC enabled. */ -+-#define E_NDS32_HAS_PIC 0x04000000 -++/* DSP extension. */ -++#define E_NDS32_HAS_DSP_INST 0x02000000 -++/* Hardware zero-overhead loop enabled. */ -++#define E_NDS32_HAS_ZOL (1 << 26) -+ /* Use custom section. */ -+ #define E_NDS32_HAS_CUSTOM_SEC 0x08000000 -+ -+diff --git binutils-2.30/include/opcode/nds32.h binutils-2.30-nds32/include/opcode/nds32.h -+index 4d113be8b8..04a02b5222 100644 -+--- binutils-2.30/include/opcode/nds32.h -++++ binutils-2.30-nds32/include/opcode/nds32.h -+@@ -21,31 +21,32 @@ -+ #define OPCODE_NDS32_H -+ -+ /* Registers. */ -+-#define REG_R5 5 -+-#define REG_R8 8 -+-#define REG_R10 10 -+-#define REG_R12 12 -+-#define REG_R15 15 -+-#define REG_R16 16 -+-#define REG_R20 20 -+-#define REG_TA 15 -+-#define REG_TP 27 -+-#define REG_FP 28 -+-#define REG_GP 29 -+-#define REG_LP 30 -+-#define REG_SP 31 -++#define REG_R0 (0) -++#define REG_R5 (5) -++#define REG_R8 (8) -++#define REG_R10 (10) -++#define REG_R12 (12) -++#define REG_R15 (15) -++#define REG_R16 (16) -++#define REG_R20 (20) -++#define REG_TA (15) -++#define REG_TP (25) -++#define REG_FP (28) -++#define REG_GP (29) -++#define REG_LP (30) -++#define REG_SP (31) -+ -+ /* Macros for extracting fields or making an instruction. */ -+ static const int nds32_r45map[] ATTRIBUTE_UNUSED = -+ { -+- 0, 1, 2, 3, 4, 5, 6, 7, -++ 0, 1, 2, 3, 4, 5, 6, 7, -+ 8, 9, 10, 11, 16, 17, 18, 19 -+ }; -+ -+ static const int nds32_r54map[] ATTRIBUTE_UNUSED = -+ { -+- 0, 1, 2, 3, 4, 5, 6, 7, -+- 8, 9, 10, 11, -1, -1, -1, -1, -++ 0, 1, 2, 3, 4, 5, 6, 7, -++ 8, 9, 10, 11, -1, -1, -1, -1, -+ 12, 13, 14, 15, -1, -1, -1, -1, -+ -1, -1, -1, -1, -1, -1, -1, -1 -+ }; -+@@ -146,6 +147,7 @@ static const int nds32_r54map[] ATTRIBUTE_UNUSED = -+ #define N32_RD5(insn) (((insn) >> 5) & 0x1f) -+ #define N32_SH5(insn) (((insn) >> 5) & 0x1f) -+ #define N32_SUB5(insn) (((insn) >> 0) & 0x1f) -++#define N32_SUB6(insn) (((insn) >> 0) & 0x3f) -+ #define N32_SWID(insn) (((insn) >> 5) & 0x3ff) -+ #define N32_IMMU(insn, bs) ((insn) & __MASK (bs)) -+ #define N32_IMMS(insn, bs) ((signed) __SEXT (((insn) & __MASK (bs)), bs)) -+@@ -275,7 +277,7 @@ enum n32_opcodes -+ N32_BR1_BNE = 1, -+ -+ /* bit[16:19] */ -+- N32_BR2_IFCALL = 0, -++ N32_BR2_SOP0 = 0, -+ N32_BR2_BEQZ = 2, -+ N32_BR2_BNEZ = 3, -+ N32_BR2_BGEZ = 4, -+@@ -365,7 +367,8 @@ enum n32_opcodes -+ N32_ALU2_FFZMISM, -+ N32_ALU2_KADD = 0x18, -+ N32_ALU2_KSUB, -+- N32_ALU2_KSLRA, -++ N32_ALU2_KSLRAW, -++ N32_ALU2_KSLRAWu, -+ N32_ALU2_MFUSR = 0x20, -+ N32_ALU2_MTUSR, -+ N32_ALU2_0x22, -+@@ -381,20 +384,173 @@ enum n32_opcodes -+ N32_ALU2_MSUB64, -+ N32_ALU2_DIVS, -+ N32_ALU2_DIV, -+- N32_ALU2_0x30 = 0x30, -++ N32_ALU2_ADD64 = 0x30, -+ N32_ALU2_MULT32, -+- N32_ALU2_0x32, -++ N32_ALU2_SMAL, -+ N32_ALU2_MADD32, -+- N32_ALU2_0x34, -++ N32_ALU2_SUB64, -+ N32_ALU2_MSUB32, -+- -+- /* bit[0:5], where bit[6:9] != 0 */ -++ N32_ALU2_0x36, -++ N32_ALU2_0x37, -++ N32_ALU2_RADD64 = 0x38, -++ N32_ALU2_URADD64, -++ N32_ALU2_KADD64, -++ N32_ALU2_UKADD64, -++ N32_ALU2_RSUB64, -++ N32_ALU2_URSUB64, -++ N32_ALU2_KSUB64, -++ N32_ALU2_UKSUB64, -++ -++ /* bit[0:5], where bit[6:9] = 0001 */ -++ N32_ALU2_SMAR64 = 0x0, -++ N32_ALU2_UMAR64, -++ N32_ALU2_SMSR64, -++ N32_ALU2_UMSR64, -++ N32_ALU2_KMAR64, -++ N32_ALU2_UKMAR64, -++ N32_ALU2_KMSR64, -++ N32_ALU2_UKMSR64, -++ N32_ALU2_SMALDA = 0x8, -++ N32_ALU2_SMSLDA, -++ N32_ALU2_SMALDS, -++ N32_ALU2_SMALBB, -+ N32_ALU2_FFBI = 0xe, -+ N32_ALU2_FLMISM = 0xf, -++ N32_ALU2_SMALXDA = 0x10, -++ N32_ALU2_SMSLXDA, -++ N32_ALU2_SMALXDS, -++ N32_ALU2_SMALBT, -++ N32_ALU2_SMALDRS = 0x1a, -++ N32_ALU2_SMALTT, -++ N32_ALU2_RDOV = 0x20, -++ N32_ALU2_CLROV, -+ N32_ALU2_MULSR64 = 0x28, -+ N32_ALU2_MULR64 = 0x29, -+- N32_ALU2_MADDR32 = 0x33, -+- N32_ALU2_MSUBR32 = 0x35, -++ N32_ALU2_SMDS = 0x30, -++ N32_ALU2_SMXDS, -++ N32_ALU2_SMDRS, -++ N32_ALU2_MADDR32, -++ N32_ALU2_KMADRS, -++ N32_ALU2_MSUBR32, -++ N32_ALU2_KMADS, -++ N32_ALU2_KMAXDS, -++ -++ /* bit[0:5], where bit[6:9] = 0010 */ -++ N32_ALU2_KADD16 = 0x0, -++ N32_ALU2_KSUB16, -++ N32_ALU2_KCRAS16, -++ N32_ALU2_KCRSA16, -++ N32_ALU2_KADD8, -++ N32_ALU2_KSUB8, -++ N32_ALU2_WEXT, -++ N32_ALU2_WEXTI, -++ N32_ALU2_UKADD16 = 0x8, -++ N32_ALU2_UKSUB16, -++ N32_ALU2_UKCRAS16, -++ N32_ALU2_UKCRSA16, -++ N32_ALU2_UKADD8, -++ N32_ALU2_UKSUB8, -++ N32_ALU2_ONEOP = 0xf, -++ N32_ALU2_SMBB = 0x10, -++ N32_ALU2_SMBT, -++ N32_ALU2_SMTT, -++ N32_ALU2_KMABB = 0x15, -++ N32_ALU2_KMABT, -++ N32_ALU2_KMATT, -++ N32_ALU2_KMDA = 0x18, -++ N32_ALU2_KMXDA, -++ N32_ALU2_KMADA, -++ N32_ALU2_KMAXDA, -++ N32_ALU2_KMSDA, -++ N32_ALU2_KMSXDA, -++ N32_ALU2_RADD16 = 0x20, -++ N32_ALU2_RSUB16, -++ N32_ALU2_RCRAS16, -++ N32_ALU2_RCRSA16, -++ N32_ALU2_RADD8, -++ N32_ALU2_RSUB8, -++ N32_ALU2_RADDW, -++ N32_ALU2_RSUBW, -++ N32_ALU2_URADD16 = 0x28, -++ N32_ALU2_URSUB16, -++ N32_ALU2_URCRAS16, -++ N32_ALU2_URCRSA16, -++ N32_ALU2_URADD8, -++ N32_ALU2_URSUB8, -++ N32_ALU2_URADDW, -++ N32_ALU2_URSUBW, -++ N32_ALU2_ADD16 = 0x30, -++ N32_ALU2_SUB16, -++ N32_ALU2_CRAS16, -++ N32_ALU2_CRSA16, -++ N32_ALU2_ADD8, -++ N32_ALU2_SUB8, -++ N32_ALU2_BITREV, -++ N32_ALU2_BITREVI, -++ N32_ALU2_SMMUL = 0x38, -++ N32_ALU2_SMMULu, -++ N32_ALU2_KMMAC, -++ N32_ALU2_KMMACu, -++ N32_ALU2_KMMSB, -++ N32_ALU2_KMMSBu, -++ N32_ALU2_KWMMUL, -++ N32_ALU2_KWMMULu, -++ -++ /* bit[0:5], where bit[6:9] = 0011 */ -++ N32_ALU2_SMMWB = 0x0, -++ N32_ALU2_SMMWBu, -++ N32_ALU2_SMMWT, -++ N32_ALU2_SMMWTu, -++ N32_ALU2_KMMAWB, -++ N32_ALU2_KMMAWBu, -++ N32_ALU2_KMMAWT, -++ N32_ALU2_KMMAWTu, -++ N32_ALU2_PKTT16 = 0x8, -++ N32_ALU2_PKTB16, -++ N32_ALU2_PKBT16, -++ N32_ALU2_PKBB16, -++ N32_ALU2_0x10 = 0x10, -++ N32_ALU2_SCLIP16, -++ N32_ALU2_0x12, -++ N32_ALU2_SMAX16, -++ N32_ALU2_SMAX8 = 0x17, -++ N32_ALU2_0x18 = 0x18, -++ N32_ALU2_UCLIP16, -++ N32_ALU2_0x1a, -++ N32_ALU2_UMAX16, -++ N32_ALU2_UMAX8 = 0x1f, -++ N32_ALU2_SRA16 = 0x20, -++ N32_ALU2_SRA16u, -++ N32_ALU2_SRL16, -++ N32_ALU2_SRL16u, -++ N32_ALU2_SLL16, -++ N32_ALU2_KSLRA16, -++ N32_ALU2_KSLRA16u, -++ N32_ALU2_SRAu, -++ N32_ALU2_SRAI16 = 0x28, -++ N32_ALU2_SRAI16u, -++ N32_ALU2_SRLI16, -++ N32_ALU2_SRLI16u, -++ N32_ALU2_SLLI16, -++ N32_ALU2_KSLLI16, -++ N32_ALU2_KSLLI, -++ N32_ALU2_SRAIu, -++ N32_ALU2_CMPEQ16 = 0x30, -++ N32_ALU2_SCMPLT16, -++ N32_ALU2_SCMPLE16, -++ N32_ALU2_SMIN16, -++ N32_ALU2_CMPEQ8, -++ N32_ALU2_SCMPLT8, -++ N32_ALU2_SCMPLE8, -++ N32_ALU2_SMIN8, -++ N32_ALU2_0x38, -++ N32_ALU2_UCMPLT16 = 0x39, -++ N32_ALU2_UCMPLE16, -++ N32_ALU2_UMIN16, -++ N32_ALU2_0x3c, -++ N32_ALU2_UCMPLT8, -++ N32_ALU2_UCMPLE8, -++ N32_ALU2_UMIN8, -+ -+ /* bit[0:5] */ -+ N32_MEM_LB = 0, -+@@ -459,7 +615,8 @@ enum n32_opcodes -+ N32_MISC_MSYNC, -+ N32_MISC_ISYNC, -+ N32_MISC_TLBOP, -+- N32_MISC_0xf, -++ N32_MISC_SPECL, -++ N32_MISC_BPICK = 0x10, -+ -+ /* bit[0:4] */ -+ N32_SIMD_PBSAD = 0, -+@@ -582,7 +739,7 @@ enum n32_opcodes -+ N32_FPU_MTCP_XR = 0xc, -+ -+ /* MTCP/XR b[14:10] */ -+- N32_FPU_MTCP_XR_FMTCSR = 0x1 -++ N32_FPU_MTCP_XR_FMTCSR = 0x1, -+ }; -+ -+ enum n16_opcodes -+@@ -675,7 +832,7 @@ enum n16_opcodes -+ N16_BFMI333_XLSB33 = 4, -+ N16_BFMI333_X11B33 = 5, -+ N16_BFMI333_BMSKI33 = 6, -+- N16_BFMI333_FEXTI33 = 7 -++ N16_BFMI333_FEXTI33 = 7, -+ }; -+ -+ /* These macros a deprecated. DO NOT use them anymore. -+@@ -704,6 +861,7 @@ enum n16_opcodes -+ #define INSN_ANDI 0x54000000 -+ #define INSN_LDI 0x06000000 -+ #define INSN_SDI 0x16000000 -++#define INSN_LW 0x38000002 -+ #define INSN_LWI 0x04000000 -+ #define INSN_LWSI 0x24000000 -+ #define INSN_LWIP 0x0c000000 -+diff --git binutils-2.30/ld/config.in binutils-2.30-nds32/ld/config.in -+index a846743da6..9cc2f6303a 100644 -+--- binutils-2.30/ld/config.in -++++ binutils-2.30-nds32/ld/config.in -+@@ -63,9 +63,18 @@ -+ */ -+ #undef HAVE_DIRENT_H -+ -++/* Define to 1 if you have the `dlclose' function. */ -++#undef HAVE_DLCLOSE -++ -+ /* Define to 1 if you have the header file. */ -+ #undef HAVE_DLFCN_H -+ -++/* Define to 1 if you have the `dlopen' function. */ -++#undef HAVE_DLOPEN -++ -++/* Define to 1 if you have the `dlsym' function. */ -++#undef HAVE_DLSYM -++ -+ /* Define to 1 if you have the header file. */ -+ #undef HAVE_ELF_HINTS_H -+ -+@@ -168,6 +177,9 @@ -+ */ -+ #undef LT_OBJDIR -+ -++/* Define if linux toolchain is to be built. */ -++#undef NDS32_LINUX_TOOLCHAIN -++ -+ /* Name of package */ -+ #undef PACKAGE -+ -+diff --git binutils-2.30/ld/configure binutils-2.30-nds32/ld/configure -+index 48606ae36b..732630063d 100755 -+--- binutils-2.30/ld/configure -++++ binutils-2.30-nds32/ld/configure -+@@ -17165,6 +17165,53 @@ do -+ -+ . ${srcdir}/configure.tgt -+ -++ case ${target_cpu} in -++ nds32*) -++ case ${targ} in -++ *-*-linux*) -++ -++$as_echo "#define NDS32_LINUX_TOOLCHAIN 1" >>confdefs.h -++ -++ ;; -++ esac -++ -++ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for default configuration of --enable-ifc-ext" >&5 -++$as_echo_n "checking for default configuration of --enable-ifc-ext... " >&6; } -++ if test "x${enable_ifc_ext}" == xyes; then -++ -++$as_echo "#define NDS32_IFC_EXT 1" >>confdefs.h -++ -++ fi -++ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $enable_ifc_ext" >&5 -++$as_echo "$enable_ifc_ext" >&6; } -++ -++ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for default configuration of --enable-ex9-ext" >&5 -++$as_echo_n "checking for default configuration of --enable-ex9-ext... " >&6; } -++ if test "x${enable_ex9_ext}" == xyes; then -++ -++$as_echo "#define NDS32_EX9_EXT 1" >>confdefs.h -++ -++ fi -++ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $enable_ex9_ext" >&5 -++$as_echo "$enable_ex9_ext" >&6; } -++ -++ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for default configuration of --enable-16m-addr" >&5 -++$as_echo_n "checking for default configuration of --enable-16m-addr... " >&6; } -++ if test "x${enable_16m_addr}" == xyes; then -++ case ${targ} in -++ nds32*le-*-elf*) -++ targ_emul=nds32elf16m -++ ;; -++ nds32*be-*-elf*) -++ targ_emul=nds32belf16m -++ ;; -++ esac -++ fi -++ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $enable_16m-addr" >&5 -++$as_echo "$enable_16m-addr" >&6; } -++ ;; -++ esac -++ -+ if test "$targ" = "$target"; then -+ EMUL=$targ_emul -+ fi -+diff --git binutils-2.30/ld/configure.tgt binutils-2.30-nds32/ld/configure.tgt -+index 6183a85b3d..b3d285faaa 100644 -+--- binutils-2.30/ld/configure.tgt -++++ binutils-2.30-nds32/ld/configure.tgt -+@@ -583,8 +583,8 @@ nds32*le-*-elf*) targ_emul=nds32elf -+ nds32*be-*-elf*) targ_emul=nds32belf -+ targ_extra_emuls="nds32elf nds32elf16m nds32belf16m" -+ ;; -+-nds32*le-*-linux-gnu*) targ_emul=nds32elf_linux ;; -+-nds32*be-*-linux-gnu*) targ_emul=nds32belf_linux ;; -++nds32*le-*-linux*) targ_emul=nds32elf_linux ;; -++nds32*be-*-linux*) targ_emul=nds32belf_linux ;; -+ nios2*-*-linux*) targ_emul=nios2linux ;; -+ nios2*-*-*) targ_emul=nios2elf ;; -+ ns32k-pc532-mach* | ns32k-pc532-ux*) targ_emul=pc532macha ;; -+diff --git binutils-2.30/ld/emulparams/nds32elf.sh binutils-2.30-nds32/ld/emulparams/nds32elf.sh -+index f0a7c31329..e2fde5d0a2 100644 -+--- binutils-2.30/ld/emulparams/nds32elf.sh -++++ binutils-2.30-nds32/ld/emulparams/nds32elf.sh -+@@ -14,5 +14,9 @@ MAXPAGESIZE=0x20 -+ EMBEDDED=yes -+ COMMONPAGESIZE=0x20 -+ -+-# Use external linker script files. -+-COMPILE_IN=no -++# Instruct genscripts.sh not to compile scripts in by COMPILE_IN -++# in order to use external linker scripts files. -++EMULATION_LIBPATH= -++ -++GENERATE_SHLIB_SCRIPT=yes -++GENERATE_PIE_SCRIPT=yes -+diff --git binutils-2.30/ld/emulparams/nds32elf16m.sh binutils-2.30-nds32/ld/emulparams/nds32elf16m.sh -+index deb8699004..7d3b063abd 100644 -+--- binutils-2.30/ld/emulparams/nds32elf16m.sh -++++ binutils-2.30-nds32/ld/emulparams/nds32elf16m.sh -+@@ -14,5 +14,6 @@ MAXPAGESIZE=0x20 -+ EMBEDDED=yes -+ COMMONPAGESIZE=0x20 -+ -+-# Use external linker script files. -+-COMPILE_IN=no -++# Instruct genscripts.sh not to compile scripts in by COMPILE_IN -++# in order to use external linker scripts files. -++EMULATION_LIBPATH= -+diff --git binutils-2.30/ld/emulparams/nds32elf_linux.sh binutils-2.30-nds32/ld/emulparams/nds32elf_linux.sh -+index 1145c0eeea..6d89f7924f 100644 -+--- binutils-2.30/ld/emulparams/nds32elf_linux.sh -++++ binutils-2.30-nds32/ld/emulparams/nds32elf_linux.sh -+@@ -31,5 +31,6 @@ fi -+ GENERATE_SHLIB_SCRIPT=yes -+ GENERATE_PIE_SCRIPT=yes -+ -+-# Use external linker script files. -+-COMPILE_IN=no -++# Instruct genscripts.sh not to compile scripts in by COMPILE_IN -++# in order to use external linker scripts files. -++EMULATION_LIBPATH= -+diff --git binutils-2.30/ld/emultempl/elf32.em binutils-2.30-nds32/ld/emultempl/elf32.em -+index c0925fc9b9..e5f109d3ce 100644 -+--- binutils-2.30/ld/emultempl/elf32.em -++++ binutils-2.30-nds32/ld/emultempl/elf32.em -+@@ -114,7 +114,7 @@ fi -+ if test x"$LDEMUL_AFTER_PARSE" != xgld"$EMULATION_NAME"_after_parse; then -+ fragment < */ -++static int hyper_relax = 1; /* --mhyper-relax */ -+ /* Disable if linking a dynamically linked executable. */ -+ static int load_store_relax = 1; -+ static int target_optimize = 0; /* Switch optimization. */ -+ static int relax_status = 0; /* Finished optimization. */ -+ static int relax_round = 0; /* Going optimization. */ -+-static FILE *ex9_export_file = NULL; /* --mexport-ex9= */ -+-static FILE *ex9_import_file = NULL; /* --mimport-ex9= */ -+-static int update_ex9_table = 0; /* --mupdate-ex9. */ -+-static int ex9_limit = 511; -+-static bfd_boolean ex9_loop_aware = FALSE; /* Ignore ex9 if inside a loop. */ -+-static bfd_boolean ifc_loop_aware = FALSE; /* Ignore ifc if inside a loop. */ -++static int tls_desc_trampoline = 0; /* --m[no]tlsdesc-trampoline. */ -++static char *set_output_abi = NULL; /* --mabi. */ -+ -+ /* Save the target options into output bfd to avoid using to many global -+ variables. Do this after the output has been created, but before -+@@ -61,39 +59,41 @@ nds32_elf_create_output_section_statements (void) -+ sym_ld_script, -+ load_store_relax, -+ target_optimize, relax_status, relax_round, -+- ex9_export_file, ex9_import_file, -+- update_ex9_table, ex9_limit, -+- ex9_loop_aware, ifc_loop_aware); -++ hyper_relax, -++ tls_desc_trampoline, -++ set_output_abi); -+ } -+ -+ static void -+ nds32_elf_after_parse (void) -+ { -++#ifdef NDS32_LINUX_TOOLCHAIN -++ if (RELAXATION_ENABLED) -++ { -++ einfo ("%P: warning: The relaxation isn't supported yet.\n"); -++ DISABLE_RELAXATION; -++ } -++#endif -++ -+ if (bfd_link_relocatable (&link_info)) -+ DISABLE_RELAXATION; -+ -+ if (!RELAXATION_ENABLED) -+ { -+- target_optimize = target_optimize & (!NDS32_RELAX_JUMP_IFC_ON); -+- target_optimize = target_optimize & (!NDS32_RELAX_EX9_ON); -++ target_optimize &= ~(NDS32_RELAX_IFC_ON | NDS32_RELAX_EX9_ON); -+ relax_fp_as_gp = 0; -+ } -+ -+- if (ex9_import_file != NULL) -+- { -+- ex9_export_file = NULL; -+- target_optimize = target_optimize & (!NDS32_RELAX_EX9_ON); -+- } -+- else -+- update_ex9_table = 0; -+- -+ if (bfd_link_pic (&link_info)) -+ { -+- target_optimize = target_optimize & (!NDS32_RELAX_JUMP_IFC_ON); -+- target_optimize = target_optimize & (!NDS32_RELAX_EX9_ON); -++ target_optimize &= ~(NDS32_RELAX_IFC_ON | NDS32_RELAX_EX9_ON); -+ } -+ -+- gld${EMULATION_NAME}_after_parse (); -++ after_parse_default (); -++ -++ /* Backward compatible for linker script output_format. */ -++ if (output_target && strcmp (output_target, "elf32-nds32") == 0) -++ output_target = default_target; -+ } -+ -+ static void -+@@ -107,10 +107,15 @@ nds32_elf_after_open (void) -+ We may try to merge object files with different architecture together. */ -+ for (abfd = link_info.input_bfds; abfd != NULL; abfd = abfd->link.next) -+ { -+- if (arch_ver == (unsigned int)-1 && E_N1_ARCH != (elf_elfheader (abfd)->e_flags & EF_NDS_ARCH)) -++ if (arch_ver == (unsigned int)-1 -++ && E_N1_ARCH != (elf_elfheader (abfd)->e_flags & EF_NDS_ARCH)) -+ arch_ver = elf_elfheader (abfd)->e_flags & EF_NDS_ARCH ; -+ -+- if (abi_ver == (unsigned int)-1) -++ if (set_output_abi != NULL) -++ { -++ /* do not check ABI. */ -++ } -++ else if (abi_ver == (unsigned int)-1) -+ { -+ /* Initialize ABI version, if not ABI0. -+ (OS uses empty file to create empty ELF with ABI0). */ -+@@ -120,67 +125,34 @@ nds32_elf_after_open (void) -+ else if ((elf_elfheader (abfd)->e_flags & EF_NDS_ABI) != 0 -+ && abi_ver != (elf_elfheader (abfd)->e_flags & EF_NDS_ABI)) -+ { -++ asection *section = NULL; -++ bfd_byte *contents = NULL; -++ section = bfd_get_section_by_name (abfd, ".note.v2abi_compatible"); -++ if (section) -++ bfd_get_full_section_contents (abfd, section, &contents); -++ -+ /* Incompatible objects. */ -+- einfo (_("%F%B: ABI version of object files mismatched\n"), abfd); -++ if ((contents == NULL) -++ || bfd_getb32 (contents) != 1 -++ || abi_ver != E_NDS_ABI_V2FP_PLUS) -++ einfo (_("%F%B: ABI version of object files mismatched\n"), abfd); -+ } -+ -+-#if defined NDS32_EX9_EXT -+- /* Append .ex9.itable section in the last input object file. */ -+- if (abfd->link_next == NULL && (target_optimize & NDS32_RELAX_EX9_ON)) -+- { -+- asection *itable; -+- struct bfd_link_hash_entry *h; -+- itable = bfd_make_section_with_flags (abfd, ".ex9.itable", -+- SEC_CODE | SEC_ALLOC | SEC_LOAD -+- | SEC_HAS_CONTENTS | SEC_READONLY -+- | SEC_IN_MEMORY | SEC_KEEP); -+- if (itable) -+- { -+- itable->gc_mark = 1; -+- itable->alignment_power = 2; -+- itable->size = 0x1000; -+- itable->contents = bfd_zalloc (abfd, itable->size); -+- -+- /* Add a symbol in the head of ex9.itable to objdump clearly. */ -+- h = bfd_link_hash_lookup (link_info.hash, "_EX9_BASE_", -+- FALSE, FALSE, FALSE); -+- _bfd_generic_link_add_one_symbol -+- (&link_info, link_info.output_bfd, "_EX9_BASE_", -+- BSF_GLOBAL | BSF_WEAK, itable, 0, (const char *) NULL, FALSE, -+- get_elf_backend_data (link_info.output_bfd)->collect, &h); -+- } -+- } -+-#endif -++ /* Append target needed section in the last input object file. */ -++ if (abfd->link.next == NULL) -++ bfd_elf32_nds32_append_section (&link_info, abfd); -+ } -+ -+ /* Check object files if the target is dynamic linked executable -+ or shared object. */ -+ if (elf_hash_table (&link_info)->dynamic_sections_created -+- || bfd_link_pic (&link_info)) -++ || bfd_link_pic (&link_info) || bfd_link_pie (&link_info)) -+ { -+- for (abfd = link_info.input_bfds; abfd != NULL; abfd = abfd->link.next) -+- { -+- if (!(elf_elfheader (abfd)->e_flags & E_NDS32_HAS_PIC)) -+- { -+- /* Non-PIC object file is used. */ -+- if (bfd_link_pic (&link_info)) -+- { -+- /* For PIE or shared object, all input must be PIC. */ -+- einfo (_("%B: must use -fpic to compile this file " -+- "for shared object or PIE\n"), abfd); -+- } -+- else -+- { -+- /* Dynamic linked executable with SDA and non-PIC. -+- Turn off load/store relaxtion. */ -+- /* TODO: This may support in the future. */ -+- load_store_relax = 0 ; -+- relax_fp_as_gp = 0; -+- } -+- } -+- } -+- /* Turn off relax when building shared object or PIE -+- until we can support their relaxation. */ -++ /* Dynamic linked executable with SDA and non-PIC. -++ Turn off load/store relaxtion. */ -++ /* TODO: This may support in the future. */ -++ load_store_relax = 0 ; -++ relax_fp_as_gp = 0; -+ } -+ -+ /* Call the standard elf routine. */ -+@@ -190,19 +162,26 @@ nds32_elf_after_open (void) -+ static void -+ nds32_elf_after_allocation (void) -+ { -+- if (target_optimize & NDS32_RELAX_EX9_ON -+- || (ex9_import_file != NULL && update_ex9_table == 1)) -+- { -+- /* Initialize ex9 hash table. */ -+- if (!nds32_elf_ex9_init ()) -+- return; -+- } -++ struct bfd_link_hash_entry *h; -+ -+ /* Call default after allocation callback. -+ 1. This is where relaxation is done. -+ 2. It calls gld${EMULATION_NAME}_map_segments to build ELF segment table. -+ 3. Any relaxation requires relax being done must be called after it. */ -+ gld${EMULATION_NAME}_after_allocation (); -++ -++ /* Add a symbol for linker script check the max size. */ -++ if (link_info.output_bfd->sections) -++ { -++ h = bfd_link_hash_lookup (link_info.hash, "_RELAX_END_", -++ FALSE, FALSE, FALSE); -++ if (!h) -++ _bfd_generic_link_add_one_symbol -++ (&link_info, link_info.output_bfd, "_RELAX_END_", -++ BSF_GLOBAL | BSF_WEAK, link_info.output_bfd->sections, -++ 0, (const char *) NULL, FALSE, -++ get_elf_backend_data (link_info.output_bfd)->collect, &h); -++ } -+ } -+ -+ EOF -+@@ -217,31 +196,19 @@ PARSE_AND_LIST_PROLOGUE=' -+ #define OPTION_REDUCE_FP_UPDATE (OPTION_BASELINE + 4) -+ #define OPTION_NO_REDUCE_FP_UPDATE (OPTION_BASELINE + 5) -+ #define OPTION_EXPORT_SYMBOLS (OPTION_BASELINE + 6) -+- -+-/* These are only available to ex9. */ -+-#if defined NDS32_EX9_EXT -+-#define OPTION_EX9_BASELINE 320 -+-#define OPTION_EX9_TABLE (OPTION_EX9_BASELINE + 1) -+-#define OPTION_NO_EX9_TABLE (OPTION_EX9_BASELINE + 2) -+-#define OPTION_EXPORT_EX9 (OPTION_EX9_BASELINE + 3) -+-#define OPTION_IMPORT_EX9 (OPTION_EX9_BASELINE + 4) -+-#define OPTION_UPDATE_EX9 (OPTION_EX9_BASELINE + 5) -+-#define OPTION_EX9_LIMIT (OPTION_EX9_BASELINE + 6) -+-#define OPTION_EX9_LOOP (OPTION_EX9_BASELINE + 7) -+-#endif -+- -+-/* These are only available to link-time ifc. */ -+-#if defined NDS32_IFC_EXT -+-#define OPTION_IFC_BASELINE 340 -+-#define OPTION_JUMP_IFC (OPTION_IFC_BASELINE + 1) -+-#define OPTION_NO_JUMP_IFC (OPTION_IFC_BASELINE + 2) -+-#define OPTION_IFC_LOOP (OPTION_IFC_BASELINE + 3) -+-#endif -++#define OPTION_HYPER_RELAX (OPTION_BASELINE + 7) -++#define OPTION_TLSDESC_TRAMPOLINE (OPTION_BASELINE + 8) -++#define OPTION_NO_TLSDESC_TRAMPOLINE (OPTION_BASELINE + 9) -++#define OPTION_SET_ABI (OPTION_BASELINE + 10) -+ ' -+ PARSE_AND_LIST_LONGOPTS=' -+ { "mfp-as-gp", no_argument, NULL, OPTION_FP_AS_GP}, -+ { "mno-fp-as-gp", no_argument, NULL, OPTION_NO_FP_AS_GP}, -+ { "mexport-symbols", required_argument, NULL, OPTION_EXPORT_SYMBOLS}, -++ { "mhyper-relax", required_argument, NULL, OPTION_HYPER_RELAX}, -++ { "mtlsdesc-trampoline", no_argument, NULL, OPTION_TLSDESC_TRAMPOLINE}, -++ { "mno-tlsdesc-trampoline", no_argument, NULL, OPTION_NO_TLSDESC_TRAMPOLINE}, -++ { "mabi", required_argument, NULL, OPTION_SET_ABI}, -+ /* These are deprecated options. Remove them in the future. */ -+ { "mrelax-reduce-fp-update", no_argument, NULL, OPTION_REDUCE_FP_UPDATE}, -+ { "mrelax-no-reduce-fp-update", no_argument, NULL, OPTION_NO_REDUCE_FP_UPDATE}, -+@@ -250,46 +217,14 @@ PARSE_AND_LIST_LONGOPTS=' -+ { "mrelax-omit-fp", no_argument, NULL, OPTION_FP_AS_GP}, -+ { "mrelax-no-omit-fp", no_argument, NULL, OPTION_NO_FP_AS_GP}, -+ { "mgen-symbol-ld-script", required_argument, NULL, OPTION_EXPORT_SYMBOLS}, -+- /* These are specific optioins for ex9-ext support. */ -+-#if defined NDS32_EX9_EXT -+- { "mex9", no_argument, NULL, OPTION_EX9_TABLE}, -+- { "mno-ex9", no_argument, NULL, OPTION_NO_EX9_TABLE}, -+- { "mexport-ex9", required_argument, NULL, OPTION_EXPORT_EX9}, -+- { "mimport-ex9", required_argument, NULL, OPTION_IMPORT_EX9}, -+- { "mupdate-ex9", no_argument, NULL, OPTION_UPDATE_EX9}, -+- { "mex9-limit", required_argument, NULL, OPTION_EX9_LIMIT}, -+- { "mex9-loop-aware", no_argument, NULL, OPTION_EX9_LOOP}, -+-#endif -+- /* These are specific optioins for ifc-ext support. */ -+-#if defined NDS32_IFC_EXT -+- { "mifc", no_argument, NULL, OPTION_JUMP_IFC}, -+- { "mno-ifc", no_argument, NULL, OPTION_NO_JUMP_IFC}, -+- { "mifc-loop-aware", no_argument, NULL, OPTION_IFC_LOOP}, -+-#endif -+ ' -+ PARSE_AND_LIST_OPTIONS=' -+ fprintf (file, _("\ -+ --m[no-]fp-as-gp Disable/enable fp-as-gp relaxation\n\ -+ --mexport-symbols=FILE Exporting symbols in linker script\n\ -++ --mhyper-relax=level Adjust relax level (low|medium|high). default: medium\n\ -++ --m[no-]tlsdesc-trampoline Disable/enable TLS DESC trampoline\n\ -+ ")); -+- -+-#if defined NDS32_EX9_EXT -+- fprintf (file, _("\ -+- --m[no-]ex9 Disable/enable link-time EX9 relaxation\n\ -+- --mexport-ex9=FILE Export EX9 table after linking\n\ -+- --mimport-ex9=FILE Import Ex9 table for EX9 relaxation\n\ -+- --mupdate-ex9 Update existing EX9 table\n\ -+- --mex9-limit=NUM Maximum number of entries in ex9 table\n\ -+- --mex9-loop-aware Avoid generate EX9 instruction inside loop\n\ -+-")); -+-#endif -+- -+-#if defined NDS32_IFC_EXT -+- fprintf (file, _("\ -+- --m[no-]ifc Disable/enable link-time IFC optimization\n\ -+- --mifc-loop-aware Avoid generate IFC instruction inside loop\n\ -+-")); -+-#endif -+ ' -+ PARSE_AND_LIST_ARGS_CASES=' -+ case OPTION_BASELINE: -+@@ -319,65 +254,33 @@ PARSE_AND_LIST_ARGS_CASES=' -+ einfo (_("%P%F: cannot open map file %s: %E.\n"), optarg); -+ } -+ break; -+-#if defined NDS32_EX9_EXT -+- case OPTION_EX9_TABLE: -+- target_optimize = target_optimize | NDS32_RELAX_EX9_ON; -+- break; -+- case OPTION_NO_EX9_TABLE: -+- target_optimize = target_optimize & (!NDS32_RELAX_EX9_ON); -+- break; -+- case OPTION_EXPORT_EX9: -++ case OPTION_HYPER_RELAX: -+ if (!optarg) -+- einfo (_("Missing file for --mexport-ex9=.\n")); -++ einfo (_("Valid arguments to --mhyper-relax=(low|medium|high).\n")); -+ -+- if(strcmp (optarg, "-") == 0) -+- ex9_export_file = stdout; -++ if (strcmp (optarg, "low") == 0) -++ hyper_relax = 0; -++ else if (strcmp (optarg, "medium") == 0) -++ hyper_relax = 1; -++ else if (strcmp (optarg, "high") == 0) -++ hyper_relax = 2; -+ else -+- { -+- ex9_export_file = fopen (optarg, "wb"); -+- if(ex9_export_file == NULL) -+- einfo (_("ERROR %P%F: cannot open ex9 export file %s.\n"), optarg); -+- } -+- break; -+- case OPTION_IMPORT_EX9: -+- if (!optarg) -+- einfo (_("Missing file for --mimport-ex9=.\n")); -++ einfo (_("Valid arguments to --mhyper-relax=(low|medium|high).\n")); -+ -+- ex9_import_file = fopen (optarg, "rb+"); -+- if(ex9_import_file == NULL) -+- einfo (_("ERROR %P%F: cannot open ex9 import file %s.\n"), optarg); -++ break; -++ case OPTION_TLSDESC_TRAMPOLINE: -++ tls_desc_trampoline = 1; -+ break; -+- case OPTION_UPDATE_EX9: -+- update_ex9_table = 1; -+- break; -+- case OPTION_EX9_LIMIT: -+- if (optarg) -+- { -+- ex9_limit = atoi (optarg); -+- if (ex9_limit > 511 || ex9_limit < 1) -+- { -+- einfo (_("ERROR: the range of ex9_limit must between 1 and 511\n")); -+- exit (1); -+- } -+- } -++ case OPTION_NO_TLSDESC_TRAMPOLINE: -++ tls_desc_trampoline = 0; -+ break; -+- case OPTION_EX9_LOOP: -+- target_optimize = target_optimize | NDS32_RELAX_EX9_ON; -+- ex9_loop_aware = 1; -+- break; -+-#endif -+-#if defined NDS32_IFC_EXT -+- case OPTION_JUMP_IFC: -+- target_optimize = target_optimize | NDS32_RELAX_JUMP_IFC_ON; -+- break; -+- case OPTION_NO_JUMP_IFC: -+- target_optimize = target_optimize & (!NDS32_RELAX_JUMP_IFC_ON); -+- break; -+- case OPTION_IFC_LOOP: -+- target_optimize = target_optimize | NDS32_RELAX_JUMP_IFC_ON; -+- ifc_loop_aware = 1; -++ case OPTION_SET_ABI: -++ if (strcmp (optarg, "AABI") != 0 -++ && strcmp (optarg, "V2FP+") != 0) -++ einfo (_("Valid arguments to --mabi=(AABI|V2FP+).\n")); -++ else -++ set_output_abi = optarg; -+ break; -+-#endif -+ ' -+ LDEMUL_AFTER_OPEN=nds32_elf_after_open -+ LDEMUL_AFTER_PARSE=nds32_elf_after_parse -+diff --git binutils-2.30/ld/scripttempl/nds32elf.sc binutils-2.30-nds32/ld/scripttempl/nds32elf.sc -+index dd9a0c11f7..6c09275e4d 100644 -+--- binutils-2.30/ld/scripttempl/nds32elf.sc -++++ binutils-2.30-nds32/ld/scripttempl/nds32elf.sc -+@@ -185,7 +185,7 @@ test "${LARGE_SECTIONS}" = "yes" && LARGE_SECTIONS=" -+ *(.ldata${RELOCATING+ .ldata.* .gnu.linkonce.l.*}) -+ ${RELOCATING+. = ALIGN(. != 0 ? ${ALIGNMENT} : 1);} -+ }" -+-if test "${ENABLE_INITFINI_ARRAY}" = "yes"; then -++if test "${ENABLE_INITFINI_ARRAY}" = "no"; then -+ SORT_INIT_ARRAY="KEEP (*(SORT_BY_INIT_PRIORITY(.init_array.*) SORT_BY_INIT_PRIORITY(.ctors.*)))" -+ SORT_FINI_ARRAY="KEEP (*(SORT_BY_INIT_PRIORITY(.fini_array.*) SORT_BY_INIT_PRIORITY(.dtors.*)))" -+ CTORS_IN_INIT_ARRAY="EXCLUDE_FILE (*crtbegin.o *crtbegin?.o *crtend.o *crtend?.o $OTHER_EXCLUDE_FILES) .ctors" -+@@ -335,6 +335,9 @@ eval $COMBRELOCCAT <> ldscripts/dyntmp.$$ < -+ #include -+ #include -++#include -+ -+ #include "safe-ctype.h" -+ #include "libiberty.h" -+@@ -43,8 +44,8 @@ -+ #define MAX_KEYWORD_LEN 32 -+ /* This LEX is a plain char or operand. */ -+ #define IS_LEX_CHAR(c) (((c) >> 7) == 0) -+-#define LEX_SET_FIELD(c) ((c) | SYN_FIELD) -+-#define LEX_GET_FIELD(c) operand_fields[((c) & 0xff)] -++#define LEX_SET_FIELD(k,c) ((c) | (((k) + 1) << 8)) -++#define LEX_GET_FIELD(k,c) (nds32_field_table[k])[((c) & 0xff)] -+ /* Get the char in this lexical element. */ -+ #define LEX_CHAR(c) ((c) & 0xff) -+ -+@@ -60,7 +61,8 @@ static int parse_fe5 (struct nds32_asm_desc *, struct nds32_asm_insn *, -+ char **, int64_t *); -+ static int parse_pi5 (struct nds32_asm_desc *, struct nds32_asm_insn *, -+ char **, int64_t *); -+-static int parse_aext_reg (char **, int *, int); -++static int parse_aext_reg (struct nds32_asm_desc *, char **, -++ int *, int); -+ static int parse_a30b20 (struct nds32_asm_desc *, struct nds32_asm_insn *, -+ char **, int64_t *); -+ static int parse_rt21 (struct nds32_asm_desc *, struct nds32_asm_insn *, -+@@ -159,6 +161,7 @@ const field_t operand_fields[] = -+ {"i14s1", 0, 14, 1, HW_INT, NULL}, -+ {"i15s1", 0, 15, 1, HW_INT, NULL}, -+ {"i16s1", 0, 16, 1, HW_INT, NULL}, -++ {"i16u5", 5, 16, 0, HW_UINT, NULL}, -+ {"i18s1", 0, 18, 1, HW_INT, NULL}, -+ {"i24s1", 0, 24, 1, HW_INT, NULL}, -+ {"i8s2", 0, 8, 2, HW_INT, NULL}, -+@@ -170,7 +173,6 @@ const field_t operand_fields[] = -+ {"i5u", 0, 5, 0, HW_UINT, NULL}, -+ {"ib5u", 10, 5, 0, HW_UINT, NULL}, /* imm5 field in ALU. */ -+ {"ib5s", 10, 5, 0, HW_INT, NULL}, /* imm5 field in ALU. */ -+- {"i9u", 0, 9, 0, HW_UINT, NULL}, /* for ex9.it. */ -+ {"ia3u", 3, 3, 0, HW_UINT, NULL}, /* for bmski33, fexti33. */ -+ {"i8u", 0, 8, 0, HW_UINT, NULL}, -+ {"ib8u", 7, 8, 0, HW_UINT, NULL}, /* for ffbi. */ -+@@ -183,6 +185,8 @@ const field_t operand_fields[] = -+ {"i7u2", 0, 7, 2, HW_UINT, NULL}, -+ {"i5u3", 0, 5, 3, HW_UINT, NULL}, /* for pop25/pop25. */ -+ {"i15s3", 0, 15, 3, HW_INT, NULL}, /* for dprefi.d. */ -++ {"ib4u", 10, 4, 0, HW_UINT, NULL}, /* imm5 field in ALU. */ -++ {"ib2u", 10, 2, 0, HW_UINT, NULL}, /* imm5 field in ALU. */ -+ -+ {"a_rt", 15, 5, 0, HW_GPR, NULL}, /* for audio-extension. */ -+ {"a_ru", 10, 5, 0, HW_GPR, NULL}, /* for audio-extension. */ -+@@ -199,7 +203,9 @@ const field_t operand_fields[] = -+ {"aridx", 0, 5, 0, HW_AEXT_ARIDX, NULL}, /* for audio-extension. */ -+ {"aridx2", 0, 5, 0, HW_AEXT_ARIDX2, NULL}, /* for audio-extension. */ -+ {"aridxi", 16, 4, 0, HW_AEXT_ARIDXI, NULL}, /* for audio-extension. */ -+- {"imm16", 0, 16, 0, HW_UINT, NULL}, /* for audio-extension. */ -++ {"aridxi_mx", 16, 4, 0, HW_AEXT_ARIDXI_MX, NULL}, /* for audio-extension. */ -++ {"imm16s", 0, 16, 0, HW_INT, NULL}, /* for audio-extension. */ -++ {"imm16u", 0, 16, 0, HW_UINT, NULL}, /* for audio-extension. */ -+ {"im5_i", 0, 5, 0, HW_AEXT_IM_I, parse_im5_ip}, /* for audio-extension. */ -+ {"im5_m", 0, 5, 0, HW_AEXT_IM_M, parse_im5_mr}, /* for audio-extension. */ -+ {"im6_ip", 0, 2, 0, HW_AEXT_IM_I, parse_im6_ip}, /* for audio-extension. */ -+@@ -209,6 +215,7 @@ const field_t operand_fields[] = -+ {"cp45", 4, 2, 0, HW_CP, NULL}, /* for cop-extension. */ -+ {"i12u", 8, 12, 0, HW_UINT, NULL}, /* for cop-extension. */ -+ {"cpi19", 6, 19, 0, HW_UINT, NULL}, /* for cop-extension. */ -++ -+ {NULL, 0, 0, 0, 0, NULL} -+ }; -+ -+@@ -294,7 +301,6 @@ struct nds32_opcode nds32_opcodes[] = -+ {"jrnez", "%rb", JREG (JRNEZ), 4, ATTR (BRANCH) | ATTR_V3, 0, NULL, 0, NULL}, -+ {"jralnez", "%rt,%rb", JREG (JRALNEZ), 4, ATTR (BRANCH) | ATTR_V3, 0, NULL, 0, NULL}, -+ {"ret", "%rb", JREG (JR) | JREG_RET, 4, ATTR (BRANCH) | ATTR_ALL, 0, NULL, 0, NULL}, -+- {"ifret", "", JREG (JR) | JREG_IFC | JREG_RET, 4, ATTR (BRANCH) | ATTR (IFC_EXT), 0, NULL, 0, NULL}, -+ {"jral", "%rb", JREG (JRAL) | RT (30), 4, ATTR (BRANCH) | ATTR_ALL, 0, NULL, 0, NULL}, -+ {"jralnez", "%rb", JREG (JRALNEZ) | RT (30), 4, ATTR (BRANCH) | ATTR_V3, 0, NULL, 0, NULL}, -+ {"ret", "", JREG (JR) | JREG_RET | RB (30), 4, ATTR (BRANCH) | ATTR_ALL, 0, NULL, 0, NULL}, -+@@ -306,8 +312,6 @@ struct nds32_opcode nds32_opcodes[] = -+ {"beq", "%rt,%ra,%i14s1", OP6 (BR1), 4, ATTR_PCREL | ATTR_ALL, 0, NULL, 0, NULL}, -+ {"bne", "%rt,%ra,%i14s1", OP6 (BR1) | N32_BIT (14), 4, ATTR_PCREL | ATTR_ALL, 0, NULL, 0, NULL}, -+ /* seg-BR2. */ -+-#define BR2(sub) (OP6 (BR2) | (N32_BR2_ ## sub << 16)) -+- {"ifcall", "%i16s1", BR2 (IFCALL), 4, ATTR (IFC_EXT), 0, NULL, 0, NULL}, -+ {"beqz", "%rt,%i16s1", BR2 (BEQZ), 4, ATTR_PCREL | ATTR_ALL, 0, NULL, 0, NULL}, -+ {"bnez", "%rt,%i16s1", BR2 (BNEZ), 4, ATTR_PCREL | ATTR_ALL, 0, NULL, 0, NULL}, -+ {"bgez", "%rt,%i16s1", BR2 (BGEZ), 4, ATTR_PCREL | ATTR_ALL, 0, NULL, 0, NULL}, -+@@ -377,10 +381,10 @@ struct nds32_opcode nds32_opcodes[] = -+ {"bse", "=rt,%ra,=rb", ALU2 (BSE), 4, ATTR (PERF2_EXT), 0, NULL, 0, NULL}, -+ {"bsp", "=rt,%ra,=rb", ALU2 (BSP), 4, ATTR (PERF2_EXT), 0, NULL, 0, NULL}, -+ {"ffzmism", "=rt,%ra,%rb", ALU2 (FFZMISM), 4, ATTR (STR_EXT), 0, NULL, 0, NULL}, -+- {"mfusr", "=rt,%usr", ALU2 (MFUSR), 4, ATTR_V3MEX_V1, 0, NULL, 0, NULL}, -+- {"mtusr", "%rt,%usr", ALU2 (MTUSR), 4, ATTR_V3MEX_V1, 0, NULL, 0, NULL}, -+- {"mfusr", "=rt,%ridx", ALU2 (MFUSR), 4, ATTR_V3MEX_V1, 0, NULL, 0, NULL}, -+- {"mtusr", "%rt,%ridx", ALU2 (MTUSR), 4, ATTR_V3MEX_V1, 0, NULL, 0, NULL}, -++ {"mfusr", "=rt,%usr", ALU2 (MFUSR), 4, ATTR_ALL, 0, NULL, 0, NULL}, -++ {"mtusr", "%rt,%usr", ALU2 (MTUSR), 4, ATTR_ALL, 0, NULL, 0, NULL}, -++ {"mfusr", "=rt,%ridx", ALU2 (MFUSR), 4, ATTR_ALL, 0, NULL, 0, NULL}, -++ {"mtusr", "%rt,%ridx", ALU2 (MTUSR), 4, ATTR_ALL, 0, NULL, 0, NULL}, -+ {"mul", "=rt,%ra,%rb", ALU2 (MUL), 4, ATTR_ALL, 0, NULL, 0, NULL}, -+ {"madds64", "=dt,%ra,%rb", ALU2 (MADDS64), 4, ATTR (MAC) | ATTR_ALL, 0, NULL, 0, NULL}, -+ {"madd64", "=dt,%ra,%rb", ALU2 (MADD64), 4, ATTR (MAC) | ATTR_ALL, 0, NULL, 0, NULL}, -+@@ -392,22 +396,22 @@ struct nds32_opcode nds32_opcodes[] = -+ -+ /* seg-ALU2_FFBI. */ -+ {"ffb", "=rt,%ra,%rb", ALU2 (FFB), 4, ATTR (STR_EXT), 0, NULL, 0, NULL}, -+- {"ffbi", "=rt,%ra,%ib8u", ALU2 (FFBI) | N32_BIT (6), 4, ATTR (STR_EXT), 0, NULL, 0, NULL}, -++ {"ffbi", "=rt,%ra,%ib8u", ALU2_1 (FFBI), 4, ATTR (STR_EXT), 0, NULL, 0, NULL}, -+ /* seg-ALU2_FLMISM. */ -+ {"ffmism", "=rt,%ra,%rb", ALU2 (FFMISM), 4, ATTR (STR_EXT), 0, NULL, 0, NULL}, -+- {"flmism", "=rt,%ra,%rb", ALU2 (FLMISM) | N32_BIT (6), 4, ATTR (STR_EXT), 0, NULL, 0, NULL}, -++ {"flmism", "=rt,%ra,%rb", ALU2_1 (FLMISM), 4, ATTR (STR_EXT), 0, NULL, 0, NULL}, -+ /* seg-ALU2_MULSR64. */ -+ {"mults64", "=dt,%ra,%rb", ALU2 (MULTS64), 4, ATTR_ALL, 0, NULL, 0, NULL}, -+- {"mulsr64", "=rt,%ra,%rb", ALU2 (MULSR64)| N32_BIT (6), 4, ATTR_V3MEX_V2, 0, NULL, 0, NULL}, -++ {"mulsr64", "=rt,%ra,%rb", ALU2_1 (MULSR64), 4, ATTR_V3MEX_V2, 0, NULL, 0, NULL}, -+ /* seg-ALU2_MULR64. */ -+ {"mult64", "=dt,%ra,%rb", ALU2 (MULT64), 4, ATTR_ALL, 0, NULL, 0, NULL}, -+- {"mulr64", "=rt,%ra,%rb", ALU2 (MULR64) | N32_BIT (6), 4, ATTR_V3MEX_V2, 0, NULL, 0, NULL}, -++ {"mulr64", "=rt,%ra,%rb", ALU2_1 (MULR64), 4, ATTR_V3MEX_V2, 0, NULL, 0, NULL}, -+ /* seg-ALU2_MADDR32. */ -+ {"madd32", "=dt,%ra,%rb", ALU2 (MADD32), 4, ATTR (MAC) | ATTR (DXREG) | ATTR_ALL, 0, NULL, 0, NULL}, -+- {"maddr32", "=rt,%ra,%rb", ALU2 (MADDR32) | N32_BIT (6), 4, ATTR (MAC) | ATTR_V2UP, 0, NULL, 0, NULL}, -++ {"maddr32", "=rt,%ra,%rb", ALU2_1 (MADDR32), 4, ATTR (MAC) | ATTR_V2UP, 0, NULL, 0, NULL}, -+ /* seg-ALU2_MSUBR32. */ -+ {"msub32", "=dt,%ra,%rb", ALU2 (MSUB32), 4, ATTR (MAC) | ATTR (DXREG) | ATTR_ALL, 0, NULL, 0, NULL}, -+- {"msubr32", "=rt,%ra,%rb", ALU2 (MSUBR32) | N32_BIT (6), 4, ATTR (MAC) | ATTR_V2UP, 0, NULL, 0, NULL}, -++ {"msubr32", "=rt,%ra,%rb", ALU2_1 (MSUBR32), 4, ATTR (MAC) | ATTR_V2UP, 0, NULL, 0, NULL}, -+ -+ /* seg-MISC. */ -+ {"standby", "%stdby_st", MISC (STANDBY), 4, ATTR_ALL, 0, NULL, 0, NULL}, -+@@ -439,8 +443,12 @@ struct nds32_opcode nds32_opcodes[] = -+ {"tlbop", "%ra,%tlbop_st", MISC (TLBOP), 4, ATTR_ALL, 0, NULL, 0, NULL}, -+ {"tlbop", "%ra,%tlbop_stx", MISC (TLBOP), 4, ATTR_ALL, 0, NULL, 0, NULL}, -+ {"tlbop", "%rt,%ra,pb", MISC (TLBOP) | (5 << 5), 4, ATTR_ALL, 0, NULL, 0, NULL}, -++ {"tlbop", "%rt,%ra,probe", MISC (TLBOP) | (5 << 5), 4, ATTR_ALL, 0, NULL, 0, NULL}, -+ {"tlbop", "flua", MISC (TLBOP) | (7 << 5), 4, ATTR_ALL, 0, NULL, 0, NULL}, -+ {"tlbop", "flushall", MISC (TLBOP) | (7 << 5), 4, ATTR_ALL, 0, NULL, 0, NULL}, -++ /* seg-MISC_SPECL. */ -++ {"isps", "%i16u5", MISC (SPECL), 4, ATTR_ALL, 0, NULL, 0, NULL}, -++ {"isps", "", MISC (SPECL), 4, ATTR_ALL, 0, NULL, 0, NULL}, -+ -+ /* seg-MEM. */ -+ {"lb", "=rt,[%ra+(%rb<<%sv)]", MEM (LB), 4, ATTR_ALL, 0, NULL, 0, NULL}, -+@@ -542,7 +550,6 @@ struct nds32_opcode nds32_opcodes[] = -+ {"fnmsubs", "=fst,%fsa,%fsb", FS1 (FNMSUBS), 4, ATTR (FPU) | ATTR (FPU_SP_EXT), 0, NULL, 0, NULL}, -+ {"fmuls", "=fst,%fsa,%fsb", FS1 (FMULS), 4, ATTR (FPU) | ATTR (FPU_SP_EXT), 0, NULL, 0, NULL}, -+ {"fdivs", "=fst,%fsa,%fsb", FS1 (FDIVS), 4, ATTR (FPU) | ATTR (FPU_SP_EXT), 0, NULL, 0, NULL}, -+- -+ /* seg-FPU_FS1_F2OP. */ -+ {"fs2d", "=fdt,%fsa", FS1_F2OP (FS2D), 4, ATTR (FPU) | ATTR (FPU_SP_EXT) | ATTR (FPU_DP_EXT), 0, NULL, 0, NULL}, -+ {"fsqrts", "=fst,%fsa", FS1_F2OP (FSQRTS), 4, ATTR (FPU) | ATTR (FPU_SP_EXT), 0, NULL, 0, NULL}, -+@@ -601,7 +608,6 @@ struct nds32_opcode nds32_opcodes[] = -+ {"fmfcfg", "=rt", MFCP_XR(FMFCFG), 4, ATTR (FPU), 0, NULL, 0, NULL}, -+ {"fmfcsr", "=rt", MFCP_XR(FMFCSR), 4, ATTR (FPU), 0, NULL, 0, NULL}, -+ /* seg-FPU_MTCP. */ -+- -+ {"fmtsr", "%rt,=fsa", MTCP (FMTSR), 4, ATTR (FPU), 0, NULL, 0, NULL}, -+ {"fmtdr", "%rt,=fda", MTCP (FMTDR), 4, ATTR (FPU), 0, NULL, 0, NULL}, -+ /* seg-FPU_MTCP_XR. */ -+@@ -707,14 +713,14 @@ struct nds32_opcode nds32_opcodes[] = -+ {"swi37", "%rt38,[$fp{+%i7u2}]", 0xb880, 2, ATTR_ALL, USE_REG (28), NULL, 0, NULL}, -+ /* SEG10_1 if Rt3=5. */ -+ {"j8", "%i8s1", 0xd500, 2, ATTR_PCREL | ATTR_ALL, 0, NULL, 0, NULL}, -++ /* SEG11_1 if Rt3=5. */ -+ /* SEG11_2 bit7~bit5. */ -+- {"jr5", "%ra5", 0xdd00, 2, ATTR_ALL, 0, NULL, 0, NULL}, -+- {"jral5", "%ra5", 0xdd20, 2, ATTR_ALL, 0, NULL, 0, NULL}, -+- {"ex9.it", "%i5u", 0xdd40, 2, ATTR (EX9_EXT), 0, NULL, 0, NULL}, -+- {"ret5", "%ra5", 0xdd80, 2, ATTR_ALL, 0, NULL, 0, NULL}, -++ {"jr5", "%ra5", 0xdd00, 2, ATTR_ALL | ATTR (BRANCH), 0, NULL, 0, NULL}, -++ {"jral5", "%ra5", 0xdd20, 2, ATTR_ALL | ATTR (BRANCH), 0, NULL, 0, NULL}, -++ {"ret5", "%ra5", 0xdd80, 2, ATTR_ALL | ATTR (BRANCH), 0, NULL, 0, NULL}, -+ {"add5.pc", "%ra5", 0xdda0, 2, ATTR_V3, 0, NULL, 0, NULL}, -+ /* SEG11_3 if Ra5=30. */ -+- {"ret5", "", 0xdd80 | RA5 (30), 2, ATTR_ALL, 0, NULL, 0, NULL}, -++ {"ret5", "", 0xdd80 | RA5 (30), 2, ATTR_ALL | ATTR (BRANCH), 0, NULL, 0, NULL}, -+ /* SEG12 bit10~bit9. */ -+ {"slts45", "%rt4,%ra5", 0xe000, 2, ATTR_ALL, DEF_REG (15), NULL, 0, NULL}, -+ {"slt45", "%rt4,%ra5", 0xe200, 2, ATTR_ALL, DEF_REG (15), NULL, 0, NULL}, -+@@ -727,13 +733,10 @@ struct nds32_opcode nds32_opcodes[] = -+ /* SEG13_1 bit8. */ -+ {"beqzs8", "%i8s1", 0xe800, 2, ATTR_PCREL | ATTR_ALL, USE_REG (15), NULL, 0, NULL}, -+ {"bnezs8", "%i8s1", 0xe900, 2, ATTR_PCREL | ATTR_ALL, USE_REG (15), NULL, 0, NULL}, -+- /* SEG13_2 bit8~bit5. */ -+- {"ex9.it", "%i9u", 0xea00, 2, ATTR (EX9_EXT), 0, NULL, 0, NULL}, -+ /* SEG14 bit7. */ -+ {"lwi37.sp", "=rt38,[+%i7u2]", 0xf000, 2, ATTR_V2UP, USE_REG (31), NULL, 0, NULL}, -+ {"swi37.sp", "%rt38,[+%i7u2]", 0xf080, 2, ATTR_V2UP, USE_REG (31), NULL, 0, NULL}, -+ /* SEG15 bit10~bit9. */ -+- {"ifcall9", "%i9u1", 0xf800, 2, ATTR (IFC_EXT), 0, NULL, 0, NULL}, -+ {"movpi45", "=rt4,%pi5", 0xfa00, 2, ATTR_V3MUP, 0, NULL, 0, NULL}, -+ /* SEG15_1 bit8. */ -+ {"movd44", "=rt5e,%ra5e", 0xfd00, 2, ATTR_V3MUP, 0, NULL, 0, NULL}, -+@@ -749,7 +752,7 @@ struct nds32_opcode nds32_opcodes[] = -+ {"fexti33", "=rt3,%ia3u", 0x9607, 2, ATTR_V3MUP, 0, NULL, 0, NULL}, -+ /* SEG-PUSHPOP25 bit8~bit7. */ -+ {"push25", "%re2,%i5u3", 0xfc00, 2, ATTR_V3MUP, USE_REG (31) | DEF_REG (31), NULL, 0, NULL}, -+- {"pop25", "%re2,%i5u3", 0xfc80, 2, ATTR_V3MUP, USE_REG (31) | DEF_REG (31), NULL, 0, NULL}, -++ {"pop25", "%re2,%i5u3", 0xfc80, 2, ATTR_V3MUP | ATTR (BRANCH), USE_REG (31) | DEF_REG (31), NULL, 0, NULL}, -+ /* SEG-MISC33 bit2~bit0. */ -+ {"neg33", "=rt3,%ra3", 0xfe02, 2, ATTR_V3MUP, 0, NULL, 0, NULL}, -+ {"not33", "=rt3,%ra3", 0xfe03, 2, ATTR_V3MUP, 0, NULL, 0, NULL}, -+@@ -759,29 +762,31 @@ struct nds32_opcode nds32_opcodes[] = -+ {"or33", "=rt3,%ra3", 0xfe07, 2, ATTR_V3MUP, 0, NULL, 0, NULL}, -+ /* SEG-Alias instructions. */ -+ {"nop16", "", 0x9200, 2, ATTR_ALL, 0, NULL, 0, NULL}, -+- {"ifret16", "", 0x83ff, 2, ATTR (IFC_EXT), 0, NULL, 0, NULL}, -+ -+ /* Saturation ext ISA. */ -+ {"kaddw", "=rt,%ra,%rb", ALU2 (KADD), 4, ATTR (SATURATION_EXT), 0, NULL, 0, NULL}, -+ {"ksubw", "=rt,%ra,%rb", ALU2 (KSUB), 4, ATTR (SATURATION_EXT), 0, NULL, 0, NULL}, -+- {"kaddh", "=rt,%ra,%rb", ALU2 (KADD) | N32_BIT (6), 4, ATTR (SATURATION_EXT), 0, NULL, 0, NULL}, -+- {"ksubh", "=rt,%ra,%rb", ALU2 (KSUB) | N32_BIT (6), 4, ATTR (SATURATION_EXT), 0, NULL, 0, NULL}, -++ {"kaddh", "=rt,%ra,%rb", ALU2_1 (KADD), 4, ATTR (SATURATION_EXT), 0, NULL, 0, NULL}, -++ {"ksubh", "=rt,%ra,%rb", ALU2_1 (KSUB), 4, ATTR (SATURATION_EXT), 0, NULL, 0, NULL}, -+ {"kdmbb", "=rt,%ra,%rb", ALU2 (KMxy), 4, ATTR (SATURATION_EXT), 0, NULL, 0, NULL}, -+ {"kdmbt", "=rt,%ra,%rb", ALU2 (KMxy) | N32_BIT (6), 4, ATTR (SATURATION_EXT), 0, NULL, 0, NULL}, -+ {"kdmtb", "=rt,%ra,%rb", ALU2 (KMxy) | N32_BIT (7), 4, ATTR (SATURATION_EXT), 0, NULL, 0, NULL}, -+ {"kdmtt", "=rt,%ra,%rb", ALU2 (KMxy) | N32_BIT (6) | N32_BIT (7), 4, ATTR (SATURATION_EXT), 0, NULL, 0, NULL}, -+ {"khmbb", "=rt,%ra,%rb", ALU2 (KMxy) | N32_BIT (8), 4, ATTR (SATURATION_EXT), 0, NULL, 0, NULL}, -+- {"khmbt", "=rt,%ra,%rb", ALU2 (KMxy) | N32_BIT (8) | N32_BIT (6), 4, ATTR (SATURATION_EXT), 0, NULL, 0, NULL}, -+- {"khmtb", "=rt,%ra,%rb", ALU2 (KMxy) | N32_BIT (8) | N32_BIT (7), 4, ATTR (SATURATION_EXT), 0, NULL, 0, NULL}, -+- {"khmtt", "=rt,%ra,%rb", ALU2 (KMxy) | N32_BIT (8) | N32_BIT (6) | N32_BIT (7), 4, ATTR (SATURATION_EXT), 0, NULL, 0, NULL}, -+- {"kslraw", "=rt,%ra,%rb", ALU2 (KSLRA), 4, ATTR (SATURATION_EXT), 0, NULL, 0, NULL}, -+- {"rdov", "=rt", ALU2 (MFUSR) | N32_BIT (6) | ( 0x1e << 15), 4, ATTR (SATURATION_EXT), 0, NULL, 0, NULL}, -+- {"clrov", "", ALU2 (MTUSR) | N32_BIT (6) | ( 0x1e << 15), 4, ATTR (SATURATION_EXT), 0, NULL, 0, NULL}, -++ {"khmbt", "=rt,%ra,%rb", ALU2 (KMxy) | N32_BIT (6) | N32_BIT (8), 4, ATTR (SATURATION_EXT), 0, NULL, 0, NULL}, -++ {"khmtb", "=rt,%ra,%rb", ALU2 (KMxy) | N32_BIT (7) | N32_BIT (8), 4, ATTR (SATURATION_EXT), 0, NULL, 0, NULL}, -++ {"khmtt", "=rt,%ra,%rb", ALU2 (KMxy) | N32_BIT (6) | N32_BIT (7) | N32_BIT (8), 4, ATTR (SATURATION_EXT), 0, NULL, 0, NULL}, -++ {"kslraw", "=rt,%ra,%rb", ALU2 (KSLRAW), 4, ATTR (SATURATION_EXT), 0, NULL, 0, NULL}, -++ {"ksll", "=rt,%ra,%rb", ALU2 (KSLRAW), 4, ATTR (SATURATION_EXT), 0, NULL, 0, NULL}, -++ {"kslraw.u", "=rt,%ra,%rb", ALU2 (KSLRAWu), 4, ATTR (SATURATION_EXT), 0, NULL, 0, NULL}, -++ {"rdov", "=rt", ALU2_1 (RDOV) | ( 0x1e << 15), 4, ATTR (SATURATION_EXT), 0, NULL, 0, NULL}, -++ {"clrov", "", ALU2_1 (CLROV) | ( 0x1e << 15), 4, ATTR (SATURATION_EXT), 0, NULL, 0, NULL}, -+ -+ /* Audio ext. instructions. */ -+ -+- {"amtari", "%aridxi,%imm16", AUDIO (AMTARI), 4, ATTR (AUDIO_ISAEXT), 0, NULL, 0, NULL}, -+- /* N32_AEXT_AMADD */ -++ {"amtari", "%aridxi,%imm16u", AUDIO (AMTARI), 4, ATTR (AUDIO_ISAEXT), 0, NULL, 0, NULL}, -++ {"amtari", "%aridxi_mx,%imm16s", AUDIO (AMTARI), 4, ATTR (AUDIO_ISAEXT), 0, NULL, 0, NULL}, -++ /* N32_AEXT_AMADD. */ -+ {"alr2", "=a_rt,=a_ru,[%im6_ip],[%im6_iq],%im6_mr,%im6_ms", AUDIO (AMADD) | (0x1 << 6), 4, ATTR (AUDIO_ISAEXT), 0, NULL, 0, NULL}, -+ {"amaddl.s", "=a_dx,%ra,%rb,[%im5_i],%im5_m", AUDIO (AMADD) | (0x04 << 5), 4, ATTR (AUDIO_ISAEXT), 0, NULL, 0, NULL}, -+ {"amaddl.l", "=a_dx,%a_a30,%a_b20,%a_rt21,[%im5_i],%im5_m", AUDIO (AMADD) | (0x06 << 5), 4, ATTR (AUDIO_ISAEXT), 0, NULL, 0, NULL}, -+@@ -791,7 +796,7 @@ struct nds32_opcode nds32_opcodes[] = -+ {"alr", "=a_rt,[%im5_i],%im5_m", AUDIO (AMADD) | (0x01 << 5), 4, ATTR (AUDIO_ISAEXT), 0, NULL, 0, NULL}, -+ {"amadd", "=a_dx,%ra,%rb", AUDIO (AMADD), 4, ATTR (AUDIO_ISAEXT), 0, NULL, 0, NULL}, -+ {"amabbs", "=a_dx,%ra,%rb", AUDIO (AMADD) | 0x01, 4, ATTR (AUDIO_ISAEXT), 0, NULL, 0, NULL}, -+- /* N32_AEXT_AMSUB */ -++ /* N32_AEXT_AMSUB. */ -+ {"amsubl.s", "=a_dx,%ra,%rb,[%im5_i],%im5_m", AUDIO (AMSUB) | (0x04 << 5), 4, ATTR (AUDIO_ISAEXT), 0, NULL, 0, NULL}, -+ {"amsubl.l", "=a_dx,%a_a30,%a_b20,%a_rt21,[%im5_i],%im5_m", AUDIO (AMSUB) | (0x06 << 5), 4, ATTR (AUDIO_ISAEXT), 0, NULL, 0, NULL}, -+ {"amsubl2.s", "=a_dx,%ra,%rb,[%im6_ip],[%im6_iq],%im6_mr,%im6_ms", AUDIO (AMSUB) | (0x08 << 5), 4, ATTR (AUDIO_ISAEXT), 0, NULL, 0, NULL}, -+@@ -800,7 +805,7 @@ struct nds32_opcode nds32_opcodes[] = -+ {"asr", "%ra,[%im5_i],%im5_m", AUDIO (AMSUB) | (0x01 << 5), 4, ATTR (AUDIO_ISAEXT), 0, NULL, 0, NULL}, -+ {"amsub", "=a_dx,%ra,%rb", AUDIO (AMSUB), 4, ATTR (AUDIO_ISAEXT), 0, NULL, 0, NULL}, -+ {"amabts", "=a_dx,%ra,%rb", AUDIO (AMSUB) |0x01, 4, ATTR (AUDIO_ISAEXT), 0, NULL, 0, NULL}, -+- /* N32_AEXT_AMULT */ -++ /* N32_AEXT_AMULT. */ -+ {"amultl.s", "=a_dx,%ra,%rb,[%im5_i],%im5_m", AUDIO (AMULT) | (0x04 << 5), 4, ATTR (AUDIO_ISAEXT), 0, NULL, 0, NULL}, -+ {"amultl.l", "=a_dx,%a_a30,%a_b20,%a_rt21,[%im5_i],%im5_m", AUDIO (AMULT) | (0x06 << 5), 4, ATTR (AUDIO_ISAEXT), 0, NULL, 0, NULL}, -+ {"amultl2.s", "=a_dx,%ra,%rb,[%im6_ip],[%im6_iq],%im6_mr,%im6_ms", AUDIO (AMULT) | (0x08 << 5), 4, ATTR (AUDIO_ISAEXT), 0, NULL, 0, NULL}, -+@@ -811,14 +816,14 @@ struct nds32_opcode nds32_opcodes[] = -+ {"amatbs", "=a_dx,%ra,%rb", AUDIO (AMULT) |0x01, 4, ATTR (AUDIO_ISAEXT), 0, NULL, 0, NULL}, -+ {"asats48", "=a_dx", AUDIO (AMULT) | (0x02 << 5), 4, ATTR (AUDIO_ISAEXT), 0, NULL, 0, NULL}, -+ {"awext", "%ra,%a_dx,%i5u", AUDIO (AMULT) | (0x03 << 5), 4, ATTR (AUDIO_ISAEXT), 0, NULL, 0, NULL}, -+- /* N32_AEXT_AMFAR */ -++ /* N32_AEXT_AMFAR. */ -+ {"amatts", "=a_dx,%ra,%rb", AUDIO (AMFAR) | 0x01, 4, ATTR (AUDIO_ISAEXT), 0, NULL, 0, NULL}, -+ {"asa", "=dxh,[%im5_i],%im5_m", AUDIO (AMFAR) | (0x01 << 5), 4, ATTR (AUDIO_ISAEXT), 0, NULL, 0, NULL}, -+ {"amtar", "%ra,%aridx", AUDIO (AMFAR) | (0x02 << 5), 4, ATTR (AUDIO_ISAEXT), 0, NULL, 0, NULL}, -+ {"amtar2", "%ra,%aridx2", AUDIO (AMFAR) | (0x12 << 5), 4, ATTR (AUDIO_ISAEXT), 0, NULL, 0, NULL}, -+ {"amfar", "=ra,%aridx", AUDIO (AMFAR) | (0x03 << 5), 4, ATTR (AUDIO_ISAEXT), 0, NULL, 0, NULL}, -+ {"amfar2", "=ra,%aridx2", AUDIO (AMFAR) | (0x13 << 5), 4, ATTR (AUDIO_ISAEXT), 0, NULL, 0, NULL}, -+- /* N32_AEXT_AMADDS */ -++ /* N32_AEXT_AMADDS. */ -+ {"amaddsl.s", "=a_dx,%ra,%rb,[%im5_i],%im5_m", AUDIO (AMADDS) | (0x04 << 5), 4, ATTR (AUDIO_ISAEXT), 0, NULL, 0, NULL}, -+ {"amaddsl.l", "=a_dx,%a_a30,%a_b20,%a_rt21,[%im5_i],%im5_m", AUDIO (AMADDS) | (0x06 << 5), 4, ATTR (AUDIO_ISAEXT), 0, NULL, 0, NULL}, -+ {"amaddsl2.s", "=a_dx,%ra,%rb,[%im6_ip],[%im6_iq],%im6_mr,%im6_ms", AUDIO (AMADDS) | (0x08 << 5), 4, ATTR (AUDIO_ISAEXT), 0, NULL, 0, NULL}, -+@@ -828,7 +833,7 @@ struct nds32_opcode nds32_opcodes[] = -+ {"amadds", "=a_dx,%ra,%rb", AUDIO (AMADDS), 4, ATTR (AUDIO_ISAEXT), 0, NULL, 0, NULL}, -+ {"ambbs", "=a_dx,%ra,%rb", AUDIO (AMADDS) |0x01, 4, ATTR (AUDIO_ISAEXT), 0, NULL, 0, NULL}, -+ {"amawbs", "=a_dx,%ra,%rb", AUDIO (AMADDS) |0x02, 4, ATTR (AUDIO_ISAEXT), 0, NULL, 0, NULL}, -+- /* N32_AEXT_AMSUBS */ -++ /* N32_AEXT_AMSUBS. */ -+ {"amsubsl.s", "=a_dx,%ra,%rb,[%im5_i],%im5_m", AUDIO (AMSUBS) | (0x04 << 5), 4, ATTR (AUDIO_ISAEXT), 0, NULL, 0, NULL}, -+ {"amsubsl.l", "=a_dx,%a_a30,%a_b20,%a_rt21,[%im5_i],%im5_m", AUDIO (AMSUBS) | (0x06 << 5), 4, ATTR (AUDIO_ISAEXT), 0, NULL, 0, NULL}, -+ {"amsubsl2.s", "=a_dx,%ra,%rb,[%im6_ip],[%im6_iq],%im6_mr,%im6_ms", AUDIO (AMSUBS) | (0x08 << 5), 4, ATTR (AUDIO_ISAEXT), 0, NULL, 0, NULL}, -+@@ -837,7 +842,7 @@ struct nds32_opcode nds32_opcodes[] = -+ {"amsubs", "=a_dx,%ra,%rb", AUDIO (AMSUBS), 4, ATTR (AUDIO_ISAEXT), 0, NULL, 0, NULL}, -+ {"ambts", "=a_dx,%ra,%rb", AUDIO (AMSUBS) |0x01, 4, ATTR (AUDIO_ISAEXT), 0, NULL, 0, NULL}, -+ {"amawts", "=a_dx,%ra,%rb", AUDIO (AMSUBS) |0x02, 4, ATTR (AUDIO_ISAEXT), 0, NULL, 0, NULL}, -+- /* N32_AEXT_AMULTS */ -++ /* N32_AEXT_AMULTS. */ -+ {"amultsl.s", "=a_dx,%ra,%rb,[%im5_i],%im5_m", AUDIO (AMULTS) | (0x04 << 5), 4, ATTR (AUDIO_ISAEXT), 0, NULL, 0, NULL}, -+ {"amultsl.l", "=a_dx,%a_a30,%a_b20,%a_rt21,[%im5_i],%im5_m", AUDIO (AMULTS) | (0x06 << 5), 4, ATTR (AUDIO_ISAEXT), 0, NULL, 0, NULL}, -+ {"amultsl2.s", "=a_dx,%ra,%rb,[%im6_ip],[%im6_iq],%im6_mr,%im6_ms", AUDIO (AMULTS) | (0x08 << 5), 4, ATTR (AUDIO_ISAEXT), 0, NULL, 0, NULL}, -+@@ -846,7 +851,7 @@ struct nds32_opcode nds32_opcodes[] = -+ {"amults", "=a_dx,%ra,%rb", AUDIO (AMULTS), 4, ATTR (AUDIO_ISAEXT), 0, NULL, 0, NULL}, -+ {"amtbs", "=a_dx,%ra,%rb", AUDIO (AMULTS) |0x01, 4, ATTR (AUDIO_ISAEXT), 0, NULL, 0, NULL}, -+ {"amwbs", "=a_dx,%ra,%rb", AUDIO (AMULTS) |0x02, 4, ATTR (AUDIO_ISAEXT), 0, NULL, 0, NULL}, -+- /* N32_AEXT_AMNEGS */ -++ /* N32_AEXT_AMNEGS. */ -+ {"amnegsl.s", "=a_dx,%ra,%rb,[%im5_i],%im5_m", AUDIO (AMNEGS) | (0x04 << 5), 4, ATTR (AUDIO_ISAEXT), 0, NULL, 0, NULL}, -+ {"amnegsl.l", "=a_dx,%a_a30,%a_b20,%a_rt21,[%im5_i],%im5_m", AUDIO (AMNEGS) | (0x06 << 5), 4, ATTR (AUDIO_ISAEXT), 0, NULL, 0, NULL}, -+ {"amnegsl2.s", "=a_dx,%ra,%rb,[%im6_ip],[%im6_iq],%im6_mr,%im6_ms", AUDIO (AMNEGS) | (0x08 << 5), 4, ATTR (AUDIO_ISAEXT), 0, NULL, 0, NULL}, -+@@ -855,82 +860,258 @@ struct nds32_opcode nds32_opcodes[] = -+ {"amnegs", "=a_dx,%ra,%rb", AUDIO (AMNEGS), 4, ATTR (AUDIO_ISAEXT), 0, NULL, 0, NULL}, -+ {"amtts", "=a_dx,%ra,%rb", AUDIO (AMNEGS) |0x01, 4, ATTR (AUDIO_ISAEXT), 0, NULL, 0, NULL}, -+ {"amwts", "=a_dx,%ra,%rb", AUDIO (AMNEGS) |0x02, 4, ATTR (AUDIO_ISAEXT), 0, NULL, 0, NULL}, -+- /* N32_AEXT_AADDL */ -++ /* N32_AEXT_AADDL. */ -+ {"aaddl", "=a_rte69,%ra,%rb,%a_rte69_1,[%im5_i],%im5_m", AUDIO (AADDL), 4, ATTR (AUDIO_ISAEXT), 0, NULL, 0, NULL}, -+ {"asubl", "=a_rte69,%ra,%rb,%a_rte69_1,[%im5_i],%im5_m", AUDIO (AADDL) | (0x01 << 5), 4, ATTR (AUDIO_ISAEXT), 0, NULL, 0, NULL}, -+- /* N32_AEXT_AMAWBS */ -++ /* N32_AEXT_AMAWBS. */ -+ {"amawbsl.s", "=a_dx,%ra,%rb,[%im5_i],%im5_m", AUDIO (AMAWBS) | (0x04 << 5), 4, ATTR (AUDIO_ISAEXT), 0, NULL, 0, NULL}, -+ {"amawbsl.l", "=a_dx,%a_a30,%a_b20,%a_rt21,[%im5_i],%im5_m", AUDIO (AMAWBS) | (0x06 << 5), 4, ATTR (AUDIO_ISAEXT), 0, NULL, 0, NULL}, -+ {"amawbsl2.s", "=a_dx,%ra,%rb,[%im6_ip],[%im6_iq],%im6_mr,%im6_ms", AUDIO (AMAWBS) | (0x08 << 5), 4, ATTR (AUDIO_ISAEXT), 0, NULL, 0, NULL}, -+ {"amawbsl2.l", "=a_dx,%a_a30,%a_b20,%a_rte,%a_rte1,[%im6_ip],[%im6_iq],%im6_mr,%im6_ms", AUDIO (AMAWBS) | (0x0A << 5), 4, ATTR (AUDIO_ISAEXT), 0, NULL, 0, NULL}, -+ {"amawbssa", "=a_dx,%ra,%rb,%dhy,[%im5_i],%im5_m", AUDIO (AMAWBS) | (0x0C << 5), 4, ATTR (AUDIO_ISAEXT), 0, NULL, 0, NULL}, -+- /* N32_AEXT_AMAWTS */ -++ /* N32_AEXT_AMAWTS. */ -+ {"amawtsl.s", "=a_dx,%ra,%rb,[%im5_i],%im5_m", AUDIO (AMAWTS) | (0x04 << 5), 4, ATTR (AUDIO_ISAEXT), 0, NULL, 0, NULL}, -+ {"amawtsl.l", "=a_dx,%a_a30,%a_b20,%a_rt21,[%im5_i],%im5_m", AUDIO (AMAWTS) | (0x06 << 5), 4, ATTR (AUDIO_ISAEXT), 0, NULL, 0, NULL}, -+ {"amawtsl2.s", "=a_dx,%ra,%rb,[%im6_ip],[%im6_iq],%im6_mr,%im6_ms", AUDIO (AMAWTS) | (0x08 << 5), 4, ATTR (AUDIO_ISAEXT), 0, NULL, 0, NULL}, -+ {"amawtsl2.l", "=a_dx,%a_a30,%a_b20,%a_rte,%a_rte1,[%im6_ip],[%im6_iq],%im6_mr,%im6_ms", AUDIO (AMAWTS) | (0x0A << 5), 4, ATTR (AUDIO_ISAEXT), 0, NULL, 0, NULL}, -+ {"amawtssa", "=a_dx,%ra,%rb,%dhy,[%im5_i],%im5_m", AUDIO (AMAWTS) | (0x0C << 5), 4, ATTR (AUDIO_ISAEXT), 0, NULL, 0, NULL}, -+- /* N32_AEXT_AMWBS */ -++ /* N32_AEXT_AMWBS. */ -+ {"amwbsl.s", "=a_dx,%ra,%rb,[%im5_i],%im5_m", AUDIO (AMWBS) | (0x04 << 5), 4, ATTR (AUDIO_ISAEXT), 0, NULL, 0, NULL}, -+ {"amwbsl.l", "=a_dx,%a_a30,%a_b20,%a_rt21,[%im5_i],%im5_m", AUDIO (AMWBS) | (0x06 << 5), 4, ATTR (AUDIO_ISAEXT), 0, NULL, 0, NULL}, -+ {"amwbsl2.s", "=a_dx,%ra,%rb,[%im6_ip],[%im6_iq],%im6_mr,%im6_ms", AUDIO (AMWBS) | (0x08 << 5), 4, ATTR (AUDIO_ISAEXT), 0, NULL, 0, NULL}, -+ {"amwbsl2.l", "=a_dx,%a_a30,%a_b20,%a_rte,%a_rte1,[%im6_ip],[%im6_iq],%im6_mr,%im6_ms", AUDIO (AMWBS) | (0x0A << 5), 4, ATTR (AUDIO_ISAEXT), 0, NULL, 0, NULL}, -+ {"amwbssa", "=a_dx,%ra,%rb,%dhy,[%im5_i],%im5_m", AUDIO (AMWBS) | (0x0C << 5), 4, ATTR (AUDIO_ISAEXT), 0, NULL, 0, NULL}, -+ {"amwbssa", "=a_dx,%ra,%rb,%dhy,[%im5_i],%im5_m", AUDIO (AMWBS) | (0x0C << 5), 4, ATTR (AUDIO_ISAEXT), 0, NULL, 0, NULL}, -+- /* N32_AEXT_AMWTS */ -++ /* N32_AEXT_AMWTS. */ -+ {"amwtsl.s", "=a_dx,%ra,%rb,[%im5_i],%im5_m", AUDIO (AMWTS) | (0x04 << 5), 4, ATTR (AUDIO_ISAEXT), 0, NULL, 0, NULL}, -+ {"amwtsl.l", "=a_dx,%a_a30,%a_b20,%a_rt21,[%im5_i],%im5_m", AUDIO (AMWTS) | (0x06 << 5), 4, ATTR (AUDIO_ISAEXT), 0, NULL, 0, NULL}, -+ {"amwtsl2.s", "=a_dx,%ra,%rb,[%im6_ip],[%im6_iq],%im6_mr,%im6_ms", AUDIO (AMWTS) | (0x08 << 5), 4, ATTR (AUDIO_ISAEXT), 0, NULL, 0, NULL}, -+ {"amwtsl2.l", "=a_dx,%a_a30,%a_b20,%a_rte,%a_rte1,[%im6_ip],[%im6_iq],%im6_mr,%im6_ms", AUDIO (AMWTS) | (0x0A << 5), 4, ATTR (AUDIO_ISAEXT), 0, NULL, 0, NULL}, -+ {"amwtssa", "=a_dx,%ra,%rb,%dhy,[%im5_i],%im5_m", AUDIO (AMWTS) | (0x0C << 5), 4, ATTR (AUDIO_ISAEXT), 0, NULL, 0, NULL}, -+- /* N32_AEXT_AMABBS */ -++ /* N32_AEXT_AMABBS. */ -+ {"amabbsl.s", "=a_dx,%ra,%rb,[%im5_i],%im5_m", AUDIO (AMABBS) | (0x04 << 5), 4, ATTR (AUDIO_ISAEXT), 0, NULL, 0, NULL}, -+ {"amabbsl.l", "=a_dx,%a_a30,%a_b20,%a_rt21,[%im5_i],%im5_m", AUDIO (AMABBS) | (0x06 << 5), 4, ATTR (AUDIO_ISAEXT), 0, NULL, 0, NULL}, -+ {"amabbsl2.s", "=a_dx,%ra,%rb,[%im6_ip],[%im6_iq],%im6_mr,%im6_ms", AUDIO (AMABBS) | (0x08 << 5), 4, ATTR (AUDIO_ISAEXT), 0, NULL, 0, NULL}, -+ {"amabbsl2.l", "=a_dx,%a_a30,%a_b20,%a_rte,%a_rte1,[%im6_ip],[%im6_iq],%im6_mr,%im6_ms", AUDIO (AMABBS) | (0x0A << 5), 4, ATTR (AUDIO_ISAEXT), 0, NULL, 0, NULL}, -+ {"amabbssa", "=a_dx,%ra,%rb,%dhy,[%im5_i],%im5_m", AUDIO (AMABBS) | (0x0C << 5), 4, ATTR (AUDIO_ISAEXT), 0, NULL, 0, NULL}, -+- /* N32_AEXT_AMABTS */ -++ /* N32_AEXT_AMABTS. */ -+ {"amabtsl.s", "=a_dx,%ra,%rb,[%im5_i],%im5_m", AUDIO (AMABTS) | (0x04 << 5), 4, ATTR (AUDIO_ISAEXT), 0, NULL, 0, NULL}, -+ {"amabtsl.l", "=a_dx,%a_a30,%a_b20,%a_rt21,[%im5_i],%im5_m", AUDIO (AMABTS) | (0x06 << 5), 4, ATTR (AUDIO_ISAEXT), 0, NULL, 0, NULL}, -+ {"amabtsl2.s", "=a_dx,%ra,%rb,[%im6_ip],[%im6_iq],%im6_mr,%im6_ms", AUDIO (AMABTS) | (0x08 << 5), 4, ATTR (AUDIO_ISAEXT), 0, NULL, 0, NULL}, -+ {"amabtsl2.l", "=a_dx,%a_a30,%a_b20,%a_rte,%a_rte1,[%im6_ip],[%im6_iq],%im6_mr,%im6_ms", AUDIO (AMABTS) | (0x0A << 5), 4, ATTR (AUDIO_ISAEXT), 0, NULL, 0, NULL}, -+ {"amabtssa", "=a_dx,%ra,%rb,%dhy,[%im5_i],%im5_m", AUDIO (AMABTS) | (0x0C << 5), 4, ATTR (AUDIO_ISAEXT), 0, NULL, 0, NULL}, -+- /* N32_AEXT_AMATBS */ -++ /* N32_AEXT_AMATBS. */ -+ {"amatbsl.s", "=a_dx,%ra,%rb,[%im5_i],%im5_m", AUDIO (AMATBS) | (0x04 << 5), 4, ATTR (AUDIO_ISAEXT), 0, NULL, 0, NULL}, -+ {"amatbsl.l", "=a_dx,%a_a30,%a_b20,%a_rt21,[%im5_i],%im5_m", AUDIO (AMATBS) | (0x06 << 5), 4, ATTR (AUDIO_ISAEXT), 0, NULL, 0, NULL}, -+ {"amatbsl2.s", "=a_dx,%ra,%rb,[%im6_ip],[%im6_iq],%im6_mr,%im6_ms", AUDIO (AMATBS) | (0x08 << 5), 4, ATTR (AUDIO_ISAEXT), 0, NULL, 0, NULL}, -+ {"amatbsl2.l", "=a_dx,%a_a30,%a_b20,%a_rte,%a_rte1,[%im6_ip],[%im6_iq],%im6_mr,%im6_ms", AUDIO (AMATBS) | (0x0A << 5), 4, ATTR (AUDIO_ISAEXT), 0, NULL, 0, NULL}, -+ {"amatbssa", "=a_dx,%ra,%rb,%dhy,[%im5_i],%im5_m", AUDIO (AMATBS) | (0x0C << 5), 4, ATTR (AUDIO_ISAEXT), 0, NULL, 0, NULL}, -+- /* N32_AEXT_AMATTS */ -++ /* N32_AEXT_AMATTS. */ -+ {"amattsl.s", "=a_dx,%ra,%rb,[%im5_i],%im5_m", AUDIO (AMATTS) | (0x04 << 5), 4, ATTR (AUDIO_ISAEXT), 0, NULL, 0, NULL}, -+ {"amattsl.l", "=a_dx,%a_a30,%a_b20,%a_rt21,[%im5_i],%im5_m", AUDIO (AMATTS) | (0x06 << 5), 4, ATTR (AUDIO_ISAEXT), 0, NULL, 0, NULL}, -+ {"amattsl2.s", "=a_dx,%ra,%rb,[%im6_ip],[%im6_iq],%im6_mr,%im6_ms", AUDIO (AMATTS) | (0x08 << 5), 4, ATTR (AUDIO_ISAEXT), 0, NULL, 0, NULL}, -+ {"amattsl2.l", "=a_dx,%a_a30,%a_b20,%a_rte,%a_rte1,[%im6_ip],[%im6_iq],%im6_mr,%im6_ms", AUDIO (AMATTS) | (0x0A << 5), 4, ATTR (AUDIO_ISAEXT), 0, NULL, 0, NULL}, -+ {"amattssa", "=a_dx,%ra,%rb,%dhy,[%im5_i],%im5_m", AUDIO (AMATTS) | (0x0C << 5), 4, ATTR (AUDIO_ISAEXT), 0, NULL, 0, NULL}, -+- /* N32_AEXT_AMBBS */ -++ /* N32_AEXT_AMBBS. */ -+ {"ambbsl.s", "=a_dx,%ra,%rb,[%im5_i],%im5_m", AUDIO (AMBBS) | (0x04 << 5), 4, ATTR (AUDIO_ISAEXT), 0, NULL, 0, NULL}, -+ {"ambbsl.l", "=a_dx,%a_a30,%a_b20,%a_rt21,[%im5_i],%im5_m", AUDIO (AMBBS) | (0x06 << 5), 4, ATTR (AUDIO_ISAEXT), 0, NULL, 0, NULL}, -+ {"ambbsl2.s", "=a_dx,%ra,%rb,[%im6_ip],[%im6_iq],%im6_mr,%im6_ms", AUDIO (AMBBS) | (0x08 << 5), 4, ATTR (AUDIO_ISAEXT), 0, NULL, 0, NULL}, -+ {"ambbsl2.l", "=a_dx,%a_a30,%a_b20,%a_rte,%a_rte1,[%im6_ip],[%im6_iq],%im6_mr,%im6_ms", AUDIO (AMBBS) | (0x0A << 5), 4, ATTR (AUDIO_ISAEXT), 0, NULL, 0, NULL}, -+ {"ambbssa", "=a_dx,%ra,%rb,%dhy,[%im5_i],%im5_m", AUDIO (AMBBS) | (0x0C << 5), 4, ATTR (AUDIO_ISAEXT), 0, NULL, 0, NULL}, -+- /* N32_AEXT_AMBTS */ -++ /* N32_AEXT_AMBTS. */ -+ {"ambtsl.s", "=a_dx,%ra,%rb,[%im5_i],%im5_m", AUDIO (AMBTS) | (0x04 << 5), 4, ATTR (AUDIO_ISAEXT), 0, NULL, 0, NULL}, -+ {"ambtsl.l", "=a_dx,%a_a30,%a_b20,%a_rt21,[%im5_i],%im5_m", AUDIO (AMBTS) | (0x06 << 5), 4, ATTR (AUDIO_ISAEXT), 0, NULL, 0, NULL}, -+ {"ambtsl2.s", "=a_dx,%ra,%rb,[%im6_ip],[%im6_iq],%im6_mr,%im6_ms", AUDIO (AMBTS) | (0x08 << 5), 4, ATTR (AUDIO_ISAEXT), 0, NULL, 0, NULL}, -+ {"ambtsl2.l", "=a_dx,%a_a30,%a_b20,%a_rte,%a_rte1,[%im6_ip],[%im6_iq],%im6_mr,%im6_ms", AUDIO (AMBTS) | (0x0A << 5), 4, ATTR (AUDIO_ISAEXT), 0, NULL, 0, NULL}, -+ {"ambtssa", "=a_dx,%ra,%rb,%dhy,[%im5_i],%im5_m", AUDIO (AMBTS) | (0x0C << 5), 4, ATTR (AUDIO_ISAEXT), 0, NULL, 0, NULL}, -+- /* N32_AEXT_AMTBS */ -++ /* N32_AEXT_AMTBS. */ -+ {"amtbsl.s", "=a_dx,%ra,%rb,[%im5_i],%im5_m", AUDIO (AMTBS) | (0x04 << 5), 4, ATTR (AUDIO_ISAEXT), 0, NULL, 0, NULL}, -+ {"amtbsl.l", "=a_dx,%a_a30,%a_b20,%a_rt21,[%im5_i],%im5_m", AUDIO (AMTBS) | (0x06 << 5), 4, ATTR (AUDIO_ISAEXT), 0, NULL, 0, NULL}, -+ {"amtbsl2.s", "=a_dx,%ra,%rb,[%im6_ip],[%im6_iq],%im6_mr,%im6_ms", AUDIO (AMTBS) | (0x08 << 5), 4, ATTR (AUDIO_ISAEXT), 0, NULL, 0, NULL}, -+ {"amtbsl2.l", "=a_dx,%a_a30,%a_b20,%a_rte,%a_rte1,[%im6_ip],[%im6_iq],%im6_mr,%im6_ms", AUDIO (AMTBS) | (0x0A << 5), 4, ATTR (AUDIO_ISAEXT), 0, NULL, 0, NULL}, -+ {"amtbssa", "=a_dx,%ra,%rb,%dhy,[%im5_i],%im5_m", AUDIO (AMTBS) | (0x0C << 5), 4, ATTR (AUDIO_ISAEXT), 0, NULL, 0, NULL}, -+- /* N32_AEXT_AMTTS */ -++ /* N32_AEXT_AMTTS. */ -+ {"amttsl.s", "=a_dx,%ra,%rb,[%im5_i],%im5_m", AUDIO (AMTTS) | (0x04 << 5), 4, ATTR (AUDIO_ISAEXT), 0, NULL, 0, NULL}, -+ {"amttsl.l", "=a_dx,%a_a30,%a_b20,%a_rt21,[%im5_i],%im5_m", AUDIO (AMTTS) | (0x06 << 5), 4, ATTR (AUDIO_ISAEXT), 0, NULL, 0, NULL}, -+ {"amttsl2.s", "=a_dx,%ra,%rb,[%im6_ip],[%im6_iq],%im6_mr,%im6_ms", AUDIO (AMTTS) | (0x08 << 5), 4, ATTR (AUDIO_ISAEXT), 0, NULL, 0, NULL}, -+ {"amttsl2.l", "=a_dx,%a_a30,%a_b20,%a_rte,%a_rte1,[%im6_ip],[%im6_iq],%im6_mr,%im6_ms", AUDIO (AMTTS) | (0x0A << 5), 4, ATTR (AUDIO_ISAEXT), 0, NULL, 0, NULL}, -+ {"amttssa", "=a_dx,%ra,%rb,%dhy,[%im5_i],%im5_m", AUDIO (AMTTS) | (0x0C << 5), 4, ATTR (AUDIO_ISAEXT), 0, NULL, 0, NULL}, -++ -++ /* DSP ISA. */ -++ /* ALU2 Bit 9-6 = 0000. */ -++ {"add64", "=rt,%ra,%rb", ALU2 (ADD64), 4, ATTR (DSP_ISAEXT), 0, NULL, 0, NULL}, -++ {"sub64", "=rt,%ra,%rb", ALU2 (SUB64), 4, ATTR (DSP_ISAEXT), 0, NULL, 0, NULL}, -++ {"smal", "=rt,%ra,%rb", ALU2 (SMAL), 4, ATTR (DSP_ISAEXT), 0, NULL, 0, NULL}, -++ {"radd64", "=rt,%ra,%rb", ALU2 (RADD64), 4, ATTR (DSP_ISAEXT), 0, NULL, 0, NULL}, -++ {"rsub64", "=rt,%ra,%rb", ALU2 (RSUB64), 4, ATTR (DSP_ISAEXT), 0, NULL, 0, NULL}, -++ {"uradd64", "=rt,%ra,%rb", ALU2 (URADD64), 4, ATTR (DSP_ISAEXT), 0, NULL, 0, NULL}, -++ {"ursub64", "=rt,%ra,%rb", ALU2 (URSUB64), 4, ATTR (DSP_ISAEXT), 0, NULL, 0, NULL}, -++ {"kadd64", "=rt,%ra,%rb", ALU2 (KADD64), 4, ATTR (DSP_ISAEXT), 0, NULL, 0, NULL}, -++ {"ksub64", "=rt,%ra,%rb", ALU2 (KSUB64), 4, ATTR (DSP_ISAEXT), 0, NULL, 0, NULL}, -++ {"ukadd64", "=rt,%ra,%rb", ALU2 (UKADD64), 4, ATTR (DSP_ISAEXT), 0, NULL, 0, NULL}, -++ {"uksub64", "=rt,%ra,%rb", ALU2 (UKSUB64), 4, ATTR (DSP_ISAEXT), 0, NULL, 0, NULL}, -++ /* ALU2 Bit 9-6 = 0001. */ -++ {"smar64", "=rt,%ra,%rb", ALU2_1 (SMAR64), 4, ATTR (DSP_ISAEXT), 0, NULL, 0, NULL}, -++ {"umar64", "=rt,%ra,%rb", ALU2_1 (UMAR64), 4, ATTR (DSP_ISAEXT), 0, NULL, 0, NULL}, -++ {"smsr64", "=rt,%ra,%rb", ALU2_1 (SMSR64), 4, ATTR (DSP_ISAEXT), 0, NULL, 0, NULL}, -++ {"umsr64", "=rt,%ra,%rb", ALU2_1 (UMSR64), 4, ATTR (DSP_ISAEXT), 0, NULL, 0, NULL}, -++ {"kmar64", "=rt,%ra,%rb", ALU2_1 (KMAR64), 4, ATTR (DSP_ISAEXT), 0, NULL, 0, NULL}, -++ {"ukmar64", "=rt,%ra,%rb", ALU2_1 (UKMAR64), 4, ATTR (DSP_ISAEXT), 0, NULL, 0, NULL}, -++ {"kmsr64", "=rt,%ra,%rb", ALU2_1 (KMSR64), 4, ATTR (DSP_ISAEXT), 0, NULL, 0, NULL}, -++ {"ukmsr64", "=rt,%ra,%rb", ALU2_1 (UKMSR64), 4, ATTR (DSP_ISAEXT), 0, NULL, 0, NULL}, -++ {"smalda", "=rt,%ra,%rb", ALU2_1 (SMALDA), 4, ATTR (DSP_ISAEXT), 0, NULL, 0, NULL}, -++ {"smslda", "=rt,%ra,%rb", ALU2_1 (SMSLDA), 4, ATTR (DSP_ISAEXT), 0, NULL, 0, NULL}, -++ {"smalds", "=rt,%ra,%rb", ALU2_1 (SMALDS), 4, ATTR (DSP_ISAEXT), 0, NULL, 0, NULL}, -++ {"smalbb", "=rt,%ra,%rb", ALU2_1 (SMALBB), 4, ATTR (DSP_ISAEXT), 0, NULL, 0, NULL}, -++ {"smalxda", "=rt,%ra,%rb", ALU2_1 (SMALXDA), 4, ATTR (DSP_ISAEXT), 0, NULL, 0, NULL}, -++ {"smslxda", "=rt,%ra,%rb", ALU2_1 (SMSLXDA), 4, ATTR (DSP_ISAEXT), 0, NULL, 0, NULL}, -++ {"smalxds", "=rt,%ra,%rb", ALU2_1 (SMALXDS), 4, ATTR (DSP_ISAEXT), 0, NULL, 0, NULL}, -++ {"smalbt", "=rt,%ra,%rb", ALU2_1 (SMALBT), 4, ATTR (DSP_ISAEXT), 0, NULL, 0, NULL}, -++ {"smalbt", "=rt,%ra,%rb", ALU2_1 (SMALBT), 4, ATTR (DSP_ISAEXT), 0, NULL, 0, NULL}, -++ {"smaldrs", "=rt,%ra,%rb", ALU2_1 (SMALDRS), 4, ATTR (DSP_ISAEXT), 0, NULL, 0, NULL}, -++ {"smaltt", "=rt,%ra,%rb", ALU2_1 (SMALTT), 4, ATTR (DSP_ISAEXT), 0, NULL, 0, NULL}, -++ {"smds", "=rt,%ra,%rb", ALU2_1 (SMDS), 4, ATTR (DSP_ISAEXT), 0, NULL, 0, NULL}, -++ {"smxds", "=rt,%ra,%rb", ALU2_1 (SMXDS), 4, ATTR (DSP_ISAEXT), 0, NULL, 0, NULL}, -++ {"smdrs", "=rt,%ra,%rb", ALU2_1 (SMDRS), 4, ATTR (DSP_ISAEXT), 0, NULL, 0, NULL}, -++ {"kmadrs", "=rt,%ra,%rb", ALU2_1 (KMADRS), 4, ATTR (DSP_ISAEXT), 0, NULL, 0, NULL}, -++ {"kmads", "=rt,%ra,%rb", ALU2_1 (KMADS), 4, ATTR (DSP_ISAEXT), 0, NULL, 0, NULL}, -++ {"kmaxds", "=rt,%ra,%rb", ALU2_1 (KMAXDS), 4, ATTR (DSP_ISAEXT), 0, NULL, 0, NULL}, -++ /* DSP MISC. */ -++ {"bpick", "=rt,%ra,%rb,%rd", MISC (BPICK), 4, ATTR (DSP_ISAEXT), 0, NULL, 0, NULL}, -++ /* ALU_2 KMxy. */ -++ {"khm16", "=rt,%ra,%rb", ALU2 (KMxy) | N32_BIT (9) | N32_BIT (8), 4, ATTR (DSP_ISAEXT), 0, NULL, 0, NULL}, -++ {"khmx16", "=rt,%ra,%rb", ALU2 (KMxy) | N32_BIT (9) | N32_BIT (8) | N32_BIT (6), 4, ATTR (DSP_ISAEXT), 0, NULL, 0, NULL}, -++ {"smul16", "=rt,%ra,%rb", ALU2 (KMxy) | N32_BIT (9), 4, ATTR (DSP_ISAEXT), 0, NULL, 0, NULL}, -++ {"smulx16", "=rt,%ra,%rb", ALU2 (KMxy) | N32_BIT (9) | N32_BIT (6), 4, ATTR (DSP_ISAEXT), 0, NULL, 0, NULL}, -++ {"umul16", "=rt,%ra,%rb", ALU2 (KMxy) | N32_BIT (9) | N32_BIT (7), 4, ATTR (DSP_ISAEXT), 0, NULL, 0, NULL}, -++ {"umulx16", "=rt,%ra,%rb", ALU2 (KMxy) | N32_BIT (9) | N32_BIT (7) | N32_BIT (6), 4, ATTR (DSP_ISAEXT), 0, NULL, 0, NULL}, -++ /* ALU2 Bit 9-6 = 0010. */ -++ {"kadd16", "=rt,%ra,%rb", ALU2_2 (KADD16), 4, ATTR (DSP_ISAEXT), 0, NULL, 0, NULL}, -++ {"ksub16", "=rt,%ra,%rb", ALU2_2 (KSUB16), 4, ATTR (DSP_ISAEXT), 0, NULL, 0, NULL}, -++ {"kcras16", "=rt,%ra,%rb", ALU2_2 (KCRAS16), 4, ATTR (DSP_ISAEXT), 0, NULL, 0, NULL}, -++ {"kcrsa16", "=rt,%ra,%rb", ALU2_2 (KCRSA16), 4, ATTR (DSP_ISAEXT), 0, NULL, 0, NULL}, -++ {"kadd8", "=rt,%ra,%rb", ALU2_2 (KADD8), 4, ATTR (DSP_ISAEXT), 0, NULL, 0, NULL}, -++ {"ksub8", "=rt,%ra,%rb", ALU2_2 (KSUB8), 4, ATTR (DSP_ISAEXT), 0, NULL, 0, NULL}, -++ {"wext", "=rt,%ra,%rb", ALU2_2 (WEXT), 4, ATTR (DSP_ISAEXT), 0, NULL, 0, NULL}, -++ {"wexti", "=rt,%ra,%ib5u", ALU2_2 (WEXTI), 4, ATTR (DSP_ISAEXT), 0, NULL, 0, NULL}, -++ {"ukadd16", "=rt,%ra,%rb", ALU2_2 (UKADD16), 4, ATTR (DSP_ISAEXT), 0, NULL, 0, NULL}, -++ {"uksub16", "=rt,%ra,%rb", ALU2_2 (UKSUB16), 4, ATTR (DSP_ISAEXT), 0, NULL, 0, NULL}, -++ {"ukcras16", "=rt,%ra,%rb", ALU2_2 (UKCRAS16), 4, ATTR (DSP_ISAEXT), 0, NULL, 0, NULL}, -++ {"ukcrsa16", "=rt,%ra,%rb", ALU2_2 (UKCRSA16), 4, ATTR (DSP_ISAEXT), 0, NULL, 0, NULL}, -++ {"ukadd8", "=rt,%ra,%rb", ALU2_2 (UKADD8), 4, ATTR (DSP_ISAEXT), 0, NULL, 0, NULL}, -++ {"uksub8", "=rt,%ra,%rb", ALU2_2 (UKSUB8), 4, ATTR (DSP_ISAEXT), 0, NULL, 0, NULL}, -++ /* ONEOP. */ -++#define DSP_ONEOP(n) ((n) << 10) -++ {"sunpkd810", "=rt,%ra", ALU2_2 (ONEOP) | DSP_ONEOP (0x0), 4, ATTR (DSP_ISAEXT), 0, NULL, 0, NULL}, -++ {"sunpkd820", "=rt,%ra", ALU2_2 (ONEOP) | DSP_ONEOP (0x1), 4, ATTR (DSP_ISAEXT), 0, NULL, 0, NULL}, -++ {"sunpkd830", "=rt,%ra", ALU2_2 (ONEOP) | DSP_ONEOP (0x2), 4, ATTR (DSP_ISAEXT), 0, NULL, 0, NULL}, -++ {"sunpkd831", "=rt,%ra", ALU2_2 (ONEOP) | DSP_ONEOP (0x3), 4, ATTR (DSP_ISAEXT), 0, NULL, 0, NULL}, -++ {"zunpkd810", "=rt,%ra", ALU2_2 (ONEOP) | DSP_ONEOP (0x4), 4, ATTR (DSP_ISAEXT), 0, NULL, 0, NULL}, -++ {"zunpkd820", "=rt,%ra", ALU2_2 (ONEOP) | DSP_ONEOP (0x5), 4, ATTR (DSP_ISAEXT), 0, NULL, 0, NULL}, -++ {"zunpkd830", "=rt,%ra", ALU2_2 (ONEOP) | DSP_ONEOP (0x6), 4, ATTR (DSP_ISAEXT), 0, NULL, 0, NULL}, -++ {"zunpkd831", "=rt,%ra", ALU2_2 (ONEOP) | DSP_ONEOP (0x7), 4, ATTR (DSP_ISAEXT), 0, NULL, 0, NULL}, -++ {"kabs", "=rt,%ra", ALU2 (ABS), 4, ATTR (PERF_EXT), 0, NULL, 0, NULL}, -++ {"kabs16", "=rt,%ra", ALU2_2 (ONEOP) | DSP_ONEOP (0x8), 4, ATTR (DSP_ISAEXT), 0, NULL, 0, NULL}, -++ {"kabs8", "=rt,%ra", ALU2_2 (ONEOP) | DSP_ONEOP (0xc), 4, ATTR (DSP_ISAEXT), 0, NULL, 0, NULL}, -++ {"insb", "=rt,%ra,%ib2u", ALU2_2 (ONEOP) | DSP_ONEOP (0x10), 4, ATTR (DSP_ISAEXT), 0, NULL, 0, NULL}, -++ {"smbb", "=rt,%ra,%rb", ALU2_2 (SMBB), 4, ATTR (DSP_ISAEXT), 0, NULL, 0, NULL}, -++ {"smbt", "=rt,%ra,%rb", ALU2_2 (SMBT), 4, ATTR (DSP_ISAEXT), 0, NULL, 0, NULL}, -++ {"smtt", "=rt,%ra,%rb", ALU2_2 (SMTT), 4, ATTR (DSP_ISAEXT), 0, NULL, 0, NULL}, -++ {"kmabb", "=rt,%ra,%rb", ALU2_2 (KMABB), 4, ATTR (DSP_ISAEXT), 0, NULL, 0, NULL}, -++ {"kmabt", "=rt,%ra,%rb", ALU2_2 (KMABT), 4, ATTR (DSP_ISAEXT), 0, NULL, 0, NULL}, -++ {"kmatt", "=rt,%ra,%rb", ALU2_2 (KMATT), 4, ATTR (DSP_ISAEXT), 0, NULL, 0, NULL}, -++ {"kmda", "=rt,%ra,%rb", ALU2_2 (KMDA), 4, ATTR (DSP_ISAEXT), 0, NULL, 0, NULL}, -++ {"kmxda", "=rt,%ra,%rb", ALU2_2 (KMXDA), 4, ATTR (DSP_ISAEXT), 0, NULL, 0, NULL}, -++ {"kmada", "=rt,%ra,%rb", ALU2_2 (KMADA), 4, ATTR (DSP_ISAEXT), 0, NULL, 0, NULL}, -++ {"kmaxda", "=rt,%ra,%rb", ALU2_2 (KMAXDA), 4, ATTR (DSP_ISAEXT), 0, NULL, 0, NULL}, -++ {"kmsda", "=rt,%ra,%rb", ALU2_2 (KMSDA), 4, ATTR (DSP_ISAEXT), 0, NULL, 0, NULL}, -++ {"kmsxda", "=rt,%ra,%rb", ALU2_2 (KMSXDA), 4, ATTR (DSP_ISAEXT), 0, NULL, 0, NULL}, -++ {"radd16", "=rt,%ra,%rb", ALU2_2 (RADD16), 4, ATTR (DSP_ISAEXT), 0, NULL, 0, NULL}, -++ {"rsub16", "=rt,%ra,%rb", ALU2_2 (RSUB16), 4, ATTR (DSP_ISAEXT), 0, NULL, 0, NULL}, -++ {"rcras16", "=rt,%ra,%rb", ALU2_2 (RCRAS16), 4, ATTR (DSP_ISAEXT), 0, NULL, 0, NULL}, -++ {"rcrsa16", "=rt,%ra,%rb", ALU2_2 (RCRSA16), 4, ATTR (DSP_ISAEXT), 0, NULL, 0, NULL}, -++ {"radd8", "=rt,%ra,%rb", ALU2_2 (RADD8), 4, ATTR (DSP_ISAEXT), 0, NULL, 0, NULL}, -++ {"rsub8", "=rt,%ra,%rb", ALU2_2 (RSUB8), 4, ATTR (DSP_ISAEXT), 0, NULL, 0, NULL}, -++ {"raddw", "=rt,%ra,%rb", ALU2_2 (RADDW), 4, ATTR (DSP_ISAEXT), 0, NULL, 0, NULL}, -++ {"rsubw", "=rt,%ra,%rb", ALU2_2 (RSUBW), 4, ATTR (DSP_ISAEXT), 0, NULL, 0, NULL}, -++ {"uradd16", "=rt,%ra,%rb", ALU2_2 (URADD16), 4, ATTR (DSP_ISAEXT), 0, NULL, 0, NULL}, -++ {"ursub16", "=rt,%ra,%rb", ALU2_2 (URSUB16), 4, ATTR (DSP_ISAEXT), 0, NULL, 0, NULL}, -++ {"urcras16", "=rt,%ra,%rb", ALU2_2 (URCRAS16), 4, ATTR (DSP_ISAEXT), 0, NULL, 0, NULL}, -++ {"urcrsa16", "=rt,%ra,%rb", ALU2_2 (URCRSA16), 4, ATTR (DSP_ISAEXT), 0, NULL, 0, NULL}, -++ {"uradd8", "=rt,%ra,%rb", ALU2_2 (URADD8), 4, ATTR (DSP_ISAEXT), 0, NULL, 0, NULL}, -++ {"ursub8", "=rt,%ra,%rb", ALU2_2 (URSUB8), 4, ATTR (DSP_ISAEXT), 0, NULL, 0, NULL}, -++ {"uraddw", "=rt,%ra,%rb", ALU2_2 (URADDW), 4, ATTR (DSP_ISAEXT), 0, NULL, 0, NULL}, -++ {"ursubw", "=rt,%ra,%rb", ALU2_2 (URSUBW), 4, ATTR (DSP_ISAEXT), 0, NULL, 0, NULL}, -++ {"add16", "=rt,%ra,%rb", ALU2_2 (ADD16), 4, ATTR (DSP_ISAEXT), 0, NULL, 0, NULL}, -++ {"sub16", "=rt,%ra,%rb", ALU2_2 (SUB16), 4, ATTR (DSP_ISAEXT), 0, NULL, 0, NULL}, -++ {"cras16", "=rt,%ra,%rb", ALU2_2 (CRAS16), 4, ATTR (DSP_ISAEXT), 0, NULL, 0, NULL}, -++ {"crsa16", "=rt,%ra,%rb", ALU2_2 (CRSA16), 4, ATTR (DSP_ISAEXT), 0, NULL, 0, NULL}, -++ {"add8", "=rt,%ra,%rb", ALU2_2 (ADD8), 4, ATTR (DSP_ISAEXT), 0, NULL, 0, NULL}, -++ {"sub8", "=rt,%ra,%rb", ALU2_2 (SUB8), 4, ATTR (DSP_ISAEXT), 0, NULL, 0, NULL}, -++ {"bitrev", "=rt,%ra,%rb", ALU2_2 (BITREV), 4, ATTR (DSP_ISAEXT), 0, NULL, 0, NULL}, -++ {"bitrevi", "=rt,%ra,%ib5u", ALU2_2 (BITREVI), 4, ATTR (DSP_ISAEXT), 0, NULL, 0, NULL}, -++ {"smmul", "=rt,%ra,%rb", ALU2_2 (SMMUL), 4, ATTR (DSP_ISAEXT), 0, NULL, 0, NULL}, -++ {"smmul.u", "=rt,%ra,%rb", ALU2_2 (SMMULu), 4, ATTR (DSP_ISAEXT), 0, NULL, 0, NULL}, -++ {"kmmac", "=rt,%ra,%rb", ALU2_2 (KMMAC), 4, ATTR (DSP_ISAEXT), 0, NULL, 0, NULL}, -++ {"kmmac.u", "=rt,%ra,%rb", ALU2_2 (KMMACu), 4, ATTR (DSP_ISAEXT), 0, NULL, 0, NULL}, -++ {"kmmsb", "=rt,%ra,%rb", ALU2_2 (KMMSB), 4, ATTR (DSP_ISAEXT), 0, NULL, 0, NULL}, -++ {"kmmsb.u", "=rt,%ra,%rb", ALU2_2 (KMMSBu), 4, ATTR (DSP_ISAEXT), 0, NULL, 0, NULL}, -++ {"kwmmul", "=rt,%ra,%rb", ALU2_2 (KWMMUL), 4, ATTR (DSP_ISAEXT), 0, NULL, 0, NULL}, -++ {"kwmmul.u", "=rt,%ra,%rb", ALU2_2 (KWMMULu), 4, ATTR (DSP_ISAEXT), 0, NULL, 0, NULL}, -++ /* ALU2 Bit 9-6 = 0010. */ -++ {"smmwb", "=rt,%ra,%rb", ALU2_3 (SMMWB), 4, ATTR (DSP_ISAEXT), 0, NULL, 0, NULL}, -++ {"smmwb.u", "=rt,%ra,%rb", ALU2_3 (SMMWBu), 4, ATTR (DSP_ISAEXT), 0, NULL, 0, NULL}, -++ {"smmwt", "=rt,%ra,%rb", ALU2_3 (SMMWT), 4, ATTR (DSP_ISAEXT), 0, NULL, 0, NULL}, -++ {"smmwt.u", "=rt,%ra,%rb", ALU2_3 (SMMWTu), 4, ATTR (DSP_ISAEXT), 0, NULL, 0, NULL}, -++ {"kmmawb", "=rt,%ra,%rb", ALU2_3 (KMMAWB), 4, ATTR (DSP_ISAEXT), 0, NULL, 0, NULL}, -++ {"kmmawb.u", "=rt,%ra,%rb", ALU2_3 (KMMAWBu), 4, ATTR (DSP_ISAEXT), 0, NULL, 0, NULL}, -++ {"kmmawt", "=rt,%ra,%rb", ALU2_3 (KMMAWT), 4, ATTR (DSP_ISAEXT), 0, NULL, 0, NULL}, -++ {"kmmawt.u", "=rt,%ra,%rb", ALU2_3 (KMMAWTu), 4, ATTR (DSP_ISAEXT), 0, NULL, 0, NULL}, -++ {"pktt16", "=rt,%ra,%rb", ALU2_3 (PKTT16), 4, ATTR (DSP_ISAEXT), 0, NULL, 0, NULL}, -++ {"pktb16", "=rt,%ra,%rb", ALU2_3 (PKTB16), 4, ATTR (DSP_ISAEXT), 0, NULL, 0, NULL}, -++ {"pkbt16", "=rt,%ra,%rb", ALU2_3 (PKBT16), 4, ATTR (DSP_ISAEXT), 0, NULL, 0, NULL}, -++ {"pkbb16", "=rt,%ra,%rb", ALU2_3 (PKBB16), 4, ATTR (DSP_ISAEXT), 0, NULL, 0, NULL}, -++ {"sclip32", "=rt,%ra,%ib5u", ALU2 (CLIPS), 4, ATTR (PERF_EXT), 0, NULL, 0, NULL}, -++ {"sclip16", "=rt,%ra,%ib4u", ALU2_3 (SCLIP16), 4, ATTR (DSP_ISAEXT), 0, NULL, 0, NULL}, -++ {"smax16", "=rt,%ra,%rb", ALU2_3 (SMAX16), 4, ATTR (DSP_ISAEXT), 0, NULL, 0, NULL}, -++ {"smax8", "=rt,%ra,%rb", ALU2_3 (SMAX8), 4, ATTR (DSP_ISAEXT), 0, NULL, 0, NULL}, -++ {"uclip32", "=rt,%ra,%ib5u", ALU2 (CLIP), 4, ATTR (PERF_EXT), 0, NULL, 0, NULL}, -++ {"uclip16", "=rt,%ra,%ib4u", ALU2_3 (UCLIP16), 4, ATTR (DSP_ISAEXT), 0, NULL, 0, NULL}, -++ {"umax16", "=rt,%ra,%rb", ALU2_3 (UMAX16), 4, ATTR (DSP_ISAEXT), 0, NULL, 0, NULL}, -++ {"umax8", "=rt,%ra,%rb", ALU2_3 (UMAX8), 4, ATTR (DSP_ISAEXT), 0, NULL, 0, NULL}, -++ {"sra16", "=rt,%ra,%rb", ALU2_3 (SRA16), 4, ATTR (DSP_ISAEXT), 0, NULL, 0, NULL}, -++ {"sra16.u", "=rt,%ra,%rb", ALU2_3 (SRA16u), 4, ATTR (DSP_ISAEXT), 0, NULL, 0, NULL}, -++ {"srl16", "=rt,%ra,%rb", ALU2_3 (SRL16), 4, ATTR (DSP_ISAEXT), 0, NULL, 0, NULL}, -++ {"srl16.u", "=rt,%ra,%rb", ALU2_3 (SRL16u), 4, ATTR (DSP_ISAEXT), 0, NULL, 0, NULL}, -++ {"sll16", "=rt,%ra,%rb", ALU2_3 (SLL16), 4, ATTR (DSP_ISAEXT), 0, NULL, 0, NULL}, -++ {"kslra16", "=rt,%ra,%rb", ALU2_3 (KSLRA16), 4, ATTR (DSP_ISAEXT), 0, NULL, 0, NULL}, -++ {"ksll16", "=rt,%ra,%rb", ALU2_3 (KSLRA16), 4, ATTR (DSP_ISAEXT), 0, NULL, 0, NULL}, -++ {"kslra16.u", "=rt,%ra,%rb", ALU2_3 (KSLRA16u), 4, ATTR (DSP_ISAEXT), 0, NULL, 0, NULL}, -++ {"sra.u", "=rt,%ra,%rb", ALU2_3 (SRAu), 4, ATTR (DSP_ISAEXT), 0, NULL, 0, NULL}, -++ {"srai16", "=rt,%ra,%ib4u", ALU2_3 (SRAI16), 4, ATTR (DSP_ISAEXT), 0, NULL, 0, NULL}, -++ {"srai16.u", "=rt,%ra,%ib4u", ALU2_3 (SRAI16u), 4, ATTR (DSP_ISAEXT), 0, NULL, 0, NULL}, -++ {"srli16", "=rt,%ra,%ib4u", ALU2_3 (SRLI16), 4, ATTR (DSP_ISAEXT), 0, NULL, 0, NULL}, -++ {"srli16.u", "=rt,%ra,%ib4u", ALU2_3 (SRLI16u), 4, ATTR (DSP_ISAEXT), 0, NULL, 0, NULL}, -++ {"slli16", "=rt,%ra,%ib4u", ALU2_3 (SLLI16), 4, ATTR (DSP_ISAEXT), 0, NULL, 0, NULL}, -++ {"kslli16", "=rt,%ra,%ib4u", ALU2_3 (KSLLI16), 4, ATTR (DSP_ISAEXT), 0, NULL, 0, NULL}, -++ {"kslli", "=rt,%ra,%ib5u", ALU2_3 (KSLLI), 4, ATTR (DSP_ISAEXT), 0, NULL, 0, NULL}, -++ {"srai.u", "=rt,%ra,%ib5u", ALU2_3 (SRAIu), 4, ATTR (DSP_ISAEXT), 0, NULL, 0, NULL}, -++ {"cmpeq16", "=rt,%ra,%rb", ALU2_3 (CMPEQ16), 4, ATTR (DSP_ISAEXT), 0, NULL, 0, NULL}, -++ {"scmplt16", "=rt,%ra,%rb", ALU2_3 (SCMPLT16), 4, ATTR (DSP_ISAEXT), 0, NULL, 0, NULL}, -++ {"scmple16", "=rt,%ra,%rb", ALU2_3 (SCMPLE16), 4, ATTR (DSP_ISAEXT), 0, NULL, 0, NULL}, -++ {"smin16", "=rt,%ra,%rb", ALU2_3 (SMIN16), 4, ATTR (DSP_ISAEXT), 0, NULL, 0, NULL}, -++ {"cmpeq8", "=rt,%ra,%rb", ALU2_3 (CMPEQ8), 4, ATTR (DSP_ISAEXT), 0, NULL, 0, NULL}, -++ {"scmplt8", "=rt,%ra,%rb", ALU2_3 (SCMPLT8), 4, ATTR (DSP_ISAEXT), 0, NULL, 0, NULL}, -++ {"scmple8", "=rt,%ra,%rb", ALU2_3 (SCMPLE8), 4, ATTR (DSP_ISAEXT), 0, NULL, 0, NULL}, -++ {"smin8", "=rt,%ra,%rb", ALU2_3 (SMIN8), 4, ATTR (DSP_ISAEXT), 0, NULL, 0, NULL}, -++ {"ucmplt16", "=rt,%ra,%rb", ALU2_3 (UCMPLT16), 4, ATTR (DSP_ISAEXT), 0, NULL, 0, NULL}, -++ {"ucmple16", "=rt,%ra,%rb", ALU2_3 (UCMPLE16), 4, ATTR (DSP_ISAEXT), 0, NULL, 0, NULL}, -++ {"umin16", "=rt,%ra,%rb", ALU2_3 (UMIN16), 4, ATTR (DSP_ISAEXT), 0, NULL, 0, NULL}, -++ {"ucmplt8", "=rt,%ra,%rb", ALU2_3 (UCMPLT8), 4, ATTR (DSP_ISAEXT), 0, NULL, 0, NULL}, -++ {"ucmple8", "=rt,%ra,%rb", ALU2_3 (UCMPLE8), 4, ATTR (DSP_ISAEXT), 0, NULL, 0, NULL}, -++ {"umin8", "=rt,%ra,%rb", ALU2_3 (UMIN8), 4, ATTR (DSP_ISAEXT), 0, NULL, 0, NULL}, -++ {"mtlbi", "%i16s1", BR2 (SOP0) | N32_BIT (20), 4, ATTR (ZOL) | ATTR (DSP_ISAEXT) | ATTR (PCREL), 0, NULL, 0, NULL}, -++ {"mtlei", "%i16s1", BR2 (SOP0) | N32_BIT (21), 4, ATTR (ZOL) | ATTR (DSP_ISAEXT) | ATTR (PCREL), 0, NULL, 0, NULL}, -+ {NULL, NULL, 0, 0, 0, 0, NULL, 0, NULL}, -+ }; -+ -+@@ -986,6 +1167,9 @@ const keyword_t keyword_usr[] = -+ {"d0.hi", USRIDX (0, 1), 0}, -+ {"d1.lo", USRIDX (0, 2), 0}, -+ {"d1.hi", USRIDX (0, 3), 0}, -++ {"lb", USRIDX (0, 25), 0}, -++ {"le", USRIDX (0, 26), 0}, -++ {"lc", USRIDX (0, 27), 0}, -+ {"itb", USRIDX (0, 28), 0}, -+ {"ifc_lp", USRIDX (0, 29), 0}, -+ {"pc", USRIDX (0, 31), 0}, -+@@ -1040,6 +1224,7 @@ const keyword_t keyword_sr[] = -+ {"ipc", SRIDX (1, 5, 1), 0}, {"ir9", SRIDX (1, 5, 1), 0}, -+ {"p_ipc", SRIDX (1, 5, 2), 0}, {"ir10", SRIDX (1, 5, 2), 0}, -+ {"oipc", SRIDX (1, 5, 3), 0}, {"ir11", SRIDX (1, 5, 3), 0}, -++ {"dipc", SRIDX (1, 5, 3), 0}, -+ {"p_p0", SRIDX (1, 6, 2), 0}, {"ir12", SRIDX (1, 6, 2), 0}, -+ {"p_p1", SRIDX (1, 7, 2), 0}, {"ir13", SRIDX (1, 7, 2), 0}, -+ {"int_mask", SRIDX (1, 8, 0), 0}, {"ir14", SRIDX (1, 8, 0), 0}, -+@@ -1059,6 +1244,11 @@ const keyword_t keyword_sr[] = -+ {"int_pri2", SRIDX (1, 11, 1), 0}, {"ir28", SRIDX (1, 11, 1), 0}, -+ {"int_trigger", SRIDX (1, 9, 4), 0}, {"ir29", SRIDX (1, 9, 4), 0}, -+ {"int_gpr_push_dis", SRIDX(1, 1, 3), 0}, {"ir30", SRIDX (1, 1, 3), 0}, -++ {"int_mask3", SRIDX(1, 8, 2), 0}, {"ir31", SRIDX (1, 8, 2), 0}, -++ {"int_pend3", SRIDX(1, 9, 2), 0}, {"ir32", SRIDX (1, 9, 2), 0}, -++ {"int_pri3", SRIDX(1, 11, 2), 0}, {"ir33", SRIDX (1, 11, 2), 0}, -++ {"int_pri4", SRIDX(1, 11, 3), 0}, {"ir34", SRIDX (1, 11, 3), 0}, -++ {"int_trigger2", SRIDX(1, 9, 5), 0}, {"ir35", SRIDX (1, 9, 5), 0}, -+ -+ {"mmu_ctl", SRIDX (2, 0, 0), 0}, {"mr0", SRIDX (2, 0, 0), 0}, -+ {"l1_pptb", SRIDX (2, 1, 0), 0}, {"mr1", SRIDX (2, 1, 0), 0}, -+@@ -1077,9 +1267,12 @@ const keyword_t keyword_sr[] = -+ {"pfmc1", SRIDX (4, 0, 1), 0}, {"pfr1", SRIDX (4, 0, 1), 0}, -+ {"pfmc2", SRIDX (4, 0, 2), 0}, {"pfr2", SRIDX (4, 0, 2), 0}, -+ {"pfm_ctl", SRIDX (4, 1, 0), 0}, {"pfr3", SRIDX (4, 1, 0), 0}, -++ {"pft_ctl", SRIDX (4, 2, 0), 0}, {"pfr4", SRIDX (4, 2, 0), 0}, -+ {"hsp_ctl", SRIDX (4, 6, 0), 0}, {"hspr0", SRIDX (4, 6, 0), 0}, -+ {"sp_bound", SRIDX (4, 6, 1), 0}, {"hspr1", SRIDX (4, 6, 1), 0}, -+ {"sp_bound_priv", SRIDX (4, 6, 2), 0},{"hspr2", SRIDX (4, 6, 2), 0}, -++ {"sp_base", SRIDX (4, 6, 3), 0}, {"hspr3", SRIDX (4, 6, 3), 0}, -++ {"sp_base_priv", SRIDX (4, 6, 4), 0}, {"hspr4", SRIDX (4, 6, 4), 0}, -+ -+ {"dma_cfg", SRIDX (5, 0, 0), 0}, {"dmar0", SRIDX (5, 0, 0), 0}, -+ {"dma_gcsw", SRIDX (5, 1, 0), 0}, {"dmar1", SRIDX (5, 1, 0), 0}, -+@@ -1102,51 +1295,51 @@ const keyword_t keyword_sr[] = -+ -+ {"secur0", SRIDX (6, 0, 0), 0}, {"sfcr", SRIDX (6, 0, 0), 0}, -+ {"secur1", SRIDX (6, 1, 0), 0}, {"sign", SRIDX (6, 1, 0), 0}, -+- {"secur2", SRIDX (6, 1, 1), 0}, {"isign", SRIDX (6, 1, 1), 0}, -+- {"secur3", SRIDX (6, 1, 2), 0}, {"p_isign", SRIDX (6, 1, 2), 0}, -++ {"secur2", SRIDX (6, 1, 1), 0}, {"isign", SRIDX (6, 1, 1), 0}, -++ {"secur3", SRIDX (6, 1, 2), 0}, {"p_isign", SRIDX (6, 1, 2), 0}, -+ -+ {"prusr_acc_ctl", SRIDX (4, 4, 0), 0}, -+ {"fucpr", SRIDX (4, 5, 0), 0}, {"fucop_ctl", SRIDX (4, 5, 0), 0}, -+ -+ {"bpc0", SRIDX (3, 0, 0), 0}, {"dr0", SRIDX (3, 0, 0), 0}, -+- {"bpc1", SRIDX (3, 0, 1), 0}, {"dr1", SRIDX (3, 0, 1), 0}, -+- {"bpc2", SRIDX (3, 0, 2), 0}, {"dr2", SRIDX (3, 0, 2), 0}, -+- {"bpc3", SRIDX (3, 0, 3), 0}, {"dr3", SRIDX (3, 0, 3), 0}, -+- {"bpc4", SRIDX (3, 0, 4), 0}, {"dr4", SRIDX (3, 0, 4), 0}, -+- {"bpc5", SRIDX (3, 0, 5), 0}, {"dr5", SRIDX (3, 0, 5), 0}, -+- {"bpc6", SRIDX (3, 0, 6), 0}, {"dr6", SRIDX (3, 0, 6), 0}, -+- {"bpc7", SRIDX (3, 0, 7), 0}, {"dr7", SRIDX (3, 0, 7), 0}, -+- {"bpa0", SRIDX (3, 1, 0), 0}, {"dr8", SRIDX (3, 1, 0), 0}, -+- {"bpa1", SRIDX (3, 1, 1), 0}, {"dr9", SRIDX (3, 1, 1), 0}, -+- {"bpa2", SRIDX (3, 1, 2), 0}, {"dr10", SRIDX (3, 1, 2), 0}, -+- {"bpa3", SRIDX (3, 1, 3), 0}, {"dr11", SRIDX (3, 1, 3), 0}, -+- {"bpa4", SRIDX (3, 1, 4), 0}, {"dr12", SRIDX (3, 1, 4), 0}, -+- {"bpa5", SRIDX (3, 1, 5), 0}, {"dr13", SRIDX (3, 1, 5), 0}, -+- {"bpa6", SRIDX (3, 1, 6), 0}, {"dr14", SRIDX (3, 1, 6), 0}, -+- {"bpa7", SRIDX (3, 1, 7), 0}, {"dr15", SRIDX (3, 1, 7), 0}, -+- {"bpam0", SRIDX (3, 2, 0), 0}, {"dr16", SRIDX (3, 2, 0), 0}, -+- {"bpam1", SRIDX (3, 2, 1), 0}, {"dr17", SRIDX (3, 2, 1), 0}, -+- {"bpam2", SRIDX (3, 2, 2), 0}, {"dr18", SRIDX (3, 2, 2), 0}, -+- {"bpam3", SRIDX (3, 2, 3), 0}, {"dr19", SRIDX (3, 2, 3), 0}, -+- {"bpam4", SRIDX (3, 2, 4), 0}, {"dr20", SRIDX (3, 2, 4), 0}, -+- {"bpam5", SRIDX (3, 2, 5), 0}, {"dr21", SRIDX (3, 2, 5), 0}, -+- {"bpam6", SRIDX (3, 2, 6), 0}, {"dr22", SRIDX (3, 2, 6), 0}, -+- {"bpam7", SRIDX (3, 2, 7), 0}, {"dr23", SRIDX (3, 2, 7), 0}, -+- {"bpv0", SRIDX (3, 3, 0), 0}, {"dr24", SRIDX (3, 3, 0), 0}, -+- {"bpv1", SRIDX (3, 3, 1), 0}, {"dr25", SRIDX (3, 3, 1), 0}, -+- {"bpv2", SRIDX (3, 3, 2), 0}, {"dr26", SRIDX (3, 3, 2), 0}, -+- {"bpv3", SRIDX (3, 3, 3), 0}, {"dr27", SRIDX (3, 3, 3), 0}, -+- {"bpv4", SRIDX (3, 3, 4), 0}, {"dr28", SRIDX (3, 3, 4), 0}, -+- {"bpv5", SRIDX (3, 3, 5), 0}, {"dr29", SRIDX (3, 3, 5), 0}, -+- {"bpv6", SRIDX (3, 3, 6), 0}, {"dr30", SRIDX (3, 3, 6), 0}, -+- {"bpv7", SRIDX (3, 3, 7), 0}, {"dr31", SRIDX (3, 3, 7), 0}, -+- {"bpcid0", SRIDX (3, 4, 0), 0}, {"dr32", SRIDX (3, 4, 0), 0}, -+- {"bpcid1", SRIDX (3, 4, 1), 0}, {"dr33", SRIDX (3, 4, 1), 0}, -+- {"bpcid2", SRIDX (3, 4, 2), 0}, {"dr34", SRIDX (3, 4, 2), 0}, -+- {"bpcid3", SRIDX (3, 4, 3), 0}, {"dr35", SRIDX (3, 4, 3), 0}, -+- {"bpcid4", SRIDX (3, 4, 4), 0}, {"dr36", SRIDX (3, 4, 4), 0}, -+- {"bpcid5", SRIDX (3, 4, 5), 0}, {"dr37", SRIDX (3, 4, 5), 0}, -+- {"bpcid6", SRIDX (3, 4, 6), 0}, {"dr38", SRIDX (3, 4, 6), 0}, -++ {"bpc1", SRIDX (3, 0, 1), 0}, {"dr5", SRIDX (3, 0, 1), 0}, -++ {"bpc2", SRIDX (3, 0, 2), 0}, {"dr10", SRIDX (3, 0, 2), 0}, -++ {"bpc3", SRIDX (3, 0, 3), 0}, {"dr15", SRIDX (3, 0, 3), 0}, -++ {"bpc4", SRIDX (3, 0, 4), 0}, {"dr20", SRIDX (3, 0, 4), 0}, -++ {"bpc5", SRIDX (3, 0, 5), 0}, {"dr25", SRIDX (3, 0, 5), 0}, -++ {"bpc6", SRIDX (3, 0, 6), 0}, {"dr30", SRIDX (3, 0, 6), 0}, -++ {"bpc7", SRIDX (3, 0, 7), 0}, {"dr35", SRIDX (3, 0, 7), 0}, -++ {"bpa0", SRIDX (3, 1, 0), 0}, {"dr1", SRIDX (3, 1, 0), 0}, -++ {"bpa1", SRIDX (3, 1, 1), 0}, {"dr6", SRIDX (3, 1, 1), 0}, -++ {"bpa2", SRIDX (3, 1, 2), 0}, {"dr11", SRIDX (3, 1, 2), 0}, -++ {"bpa3", SRIDX (3, 1, 3), 0}, {"dr16", SRIDX (3, 1, 3), 0}, -++ {"bpa4", SRIDX (3, 1, 4), 0}, {"dr21", SRIDX (3, 1, 4), 0}, -++ {"bpa5", SRIDX (3, 1, 5), 0}, {"dr26", SRIDX (3, 1, 5), 0}, -++ {"bpa6", SRIDX (3, 1, 6), 0}, {"dr31", SRIDX (3, 1, 6), 0}, -++ {"bpa7", SRIDX (3, 1, 7), 0}, {"dr36", SRIDX (3, 1, 7), 0}, -++ {"bpam0", SRIDX (3, 2, 0), 0}, {"dr2", SRIDX (3, 2, 0), 0}, -++ {"bpam1", SRIDX (3, 2, 1), 0}, {"dr7", SRIDX (3, 2, 1), 0}, -++ {"bpam2", SRIDX (3, 2, 2), 0}, {"dr12", SRIDX (3, 2, 2), 0}, -++ {"bpam3", SRIDX (3, 2, 3), 0}, {"dr17", SRIDX (3, 2, 3), 0}, -++ {"bpam4", SRIDX (3, 2, 4), 0}, {"dr22", SRIDX (3, 2, 4), 0}, -++ {"bpam5", SRIDX (3, 2, 5), 0}, {"dr27", SRIDX (3, 2, 5), 0}, -++ {"bpam6", SRIDX (3, 2, 6), 0}, {"dr32", SRIDX (3, 2, 6), 0}, -++ {"bpam7", SRIDX (3, 2, 7), 0}, {"dr37", SRIDX (3, 2, 7), 0}, -++ {"bpv0", SRIDX (3, 3, 0), 0}, {"dr3", SRIDX (3, 3, 0), 0}, -++ {"bpv1", SRIDX (3, 3, 1), 0}, {"dr8", SRIDX (3, 3, 1), 0}, -++ {"bpv2", SRIDX (3, 3, 2), 0}, {"dr13", SRIDX (3, 3, 2), 0}, -++ {"bpv3", SRIDX (3, 3, 3), 0}, {"dr18", SRIDX (3, 3, 3), 0}, -++ {"bpv4", SRIDX (3, 3, 4), 0}, {"dr23", SRIDX (3, 3, 4), 0}, -++ {"bpv5", SRIDX (3, 3, 5), 0}, {"dr28", SRIDX (3, 3, 5), 0}, -++ {"bpv6", SRIDX (3, 3, 6), 0}, {"dr33", SRIDX (3, 3, 6), 0}, -++ {"bpv7", SRIDX (3, 3, 7), 0}, {"dr38", SRIDX (3, 3, 7), 0}, -++ {"bpcid0", SRIDX (3, 4, 0), 0}, {"dr4", SRIDX (3, 4, 0), 0}, -++ {"bpcid1", SRIDX (3, 4, 1), 0}, {"dr9", SRIDX (3, 4, 1), 0}, -++ {"bpcid2", SRIDX (3, 4, 2), 0}, {"dr14", SRIDX (3, 4, 2), 0}, -++ {"bpcid3", SRIDX (3, 4, 3), 0}, {"dr19", SRIDX (3, 4, 3), 0}, -++ {"bpcid4", SRIDX (3, 4, 4), 0}, {"dr24", SRIDX (3, 4, 4), 0}, -++ {"bpcid5", SRIDX (3, 4, 5), 0}, {"dr29", SRIDX (3, 4, 5), 0}, -++ {"bpcid6", SRIDX (3, 4, 6), 0}, {"dr34", SRIDX (3, 4, 6), 0}, -+ {"bpcid7", SRIDX (3, 4, 7), 0}, {"dr39", SRIDX (3, 4, 7), 0}, -+ {"edm_cfg", SRIDX (3, 5, 0), 0}, {"dr40", SRIDX (3, 5, 0), 0}, -+ {"edmsw", SRIDX (3, 6, 0), 0}, {"dr41", SRIDX (3, 6, 0), 0}, -+@@ -1360,6 +1553,14 @@ const keyword_t keyword_aridxi[] = -+ {NULL, 0, 0} -+ }; -+ -++const keyword_t keyword_aridxi_mx[] = -++{ -++ {"m1", 9, 0}, {"m2", 10, 0}, {"m3",11, 0}, -++ {"m5",13, 0}, {"m6",14, 0}, {"m7",15, 0}, -++ {NULL, 0, 0} -++}; -++ -++ -+ const keyword_t *keywords[_HW_LAST] = -+ { -+ keyword_gpr, keyword_usr, keyword_dxr, keyword_sr, keyword_fsr, -+@@ -1370,15 +1571,21 @@ const keyword_t *keywords[_HW_LAST] = -+ keyword_cctl_lv, keyword_tlbop_st, keyword_standby_st, -+ keyword_msync_st, -+ keyword_im5_i, keyword_im5_m, -+- keyword_accumulator, keyword_aridx, keyword_aridx2, keyword_aridxi -++ keyword_accumulator, keyword_aridx, keyword_aridx2, -++ keyword_aridxi, keyword_aridxi_mx -+ }; -++ -++const keyword_t **nds32_keyword_table[NDS32_CORE_COUNT]; -++static unsigned int nds32_keyword_count_table[NDS32_CORE_COUNT]; -++const field_t *nds32_field_table[NDS32_CORE_COUNT]; -++opcode_t *nds32_opcode_table[NDS32_CORE_COUNT]; -+ -+ /* Hash table for syntax lex. */ -+ static htab_t field_htab; -+ /* Hash table for opcodes. */ -+ static htab_t opcode_htab; -+ /* Hash table for hardware resources. */ -+-static htab_t hw_ktabs[_HW_LAST]; -++static htab_t *hw_ktabs; -+ -+ static hashval_t -+ htab_hash_hash (const void *p) -+@@ -1396,44 +1603,198 @@ htab_hash_eq (const void *p, const void *q) -+ -+ return strcmp (name, h->name) == 0; -+ } -++ -+ -+-/* Build a hash table for array BASE. Each element is in size of SIZE, -+- and it's first element is a pointer to the key of string. -+- It stops inserting elements until reach an NULL key. */ -++/* These functions parse "share library file name" specified for ACE. */ -+ -+-static htab_t -+-build_hash_table (const void *base, size_t size) -++static int -++nds32_parse_ace (const char *str, unsigned id) -+ { -+- htab_t htab; -+- hashval_t hash; -+- const char *p; -++ void *obj, *dlc = dlopen (str, RTLD_NOW | RTLD_LOCAL); -++ char *err; -+ -+- htab = htab_create_alloc (128, htab_hash_hash, htab_hash_eq, -+- NULL, xcalloc, free); -++ if (dlc == NULL) -++ err = (char*) dlerror (); -++ else -++ { -++ obj = dlsym (dlc, "keyword_count"); -++ err = (char*) dlerror (); -++ if (err == NULL) -++ { -++ nds32_keyword_count_table[id] = *(unsigned int*) obj; -++ if (nds32_keyword_count_table[id] != 0) -++ { -++ nds32_keyword_table[id] = -++ (const keyword_t**) dlsym (dlc, "keywords"); -++ err = (char*) dlerror (); -++ } -++ if (err == NULL) -++ { -++ nds32_field_table[id] = -++ (const field_t*) dlsym (dlc, "nds32_ace_field"); -++ err = (char*) dlerror (); -++ } -++ if (err == NULL) -++ { -++ nds32_opcode_table[id] = -++ (opcode_t*) dlsym (dlc, "nds32_ace_opcode"); -++ err = (char*) dlerror (); -++ } -++ -++ if (err == NULL) -++ { -++ if (id != NDS32_ACE) -++ { -++ opcode_t *opc = nds32_opcode_table[id]; -++ unsigned cpid = id - NDS32_COP0; -++ unsigned matched = 0; -++ -++ /* Check whether the coprocessor ID encoded matches. */ -++ /* If not, coprocessor ID is fixed for flexibitlity. */ -++ if (N32_OP6 (opc->value) == N32_OP6_COP) -++ { -++ if (__GF (opc->value, 4, 2) == cpid) -++ matched = 1; -++ } -++ else -++ { -++ if (__GF (opc->value, 13, 2) == cpid) -++ matched = 1; -++ } -++ if (!matched) -++ { -++ for (; opc->opcode != NULL; opc++) -++ { -++ if (N32_OP6 (opc->value) == N32_OP6_COP) -++ opc->value = (opc->value >> 6) | __MF(cpid, 4, 2) -++ | (opc->value & 0xf); -++ else -++ opc->value = (opc->value >> 15) | __MF(cpid, 13, 2) -++ | (opc->value & 0x1fff); -++ } -++ } -++ } -++ -++ return 1; -++ } -++ } -++ } -++ -++ printf("%s\n", err); -++ return 0; -++} -++ -++int -++nds32_parse_udi (const char *str) -++{ -++ return nds32_parse_ace (str, NDS32_ACE); -++} -+ -+- p = base; -+- while (1) -++int -++nds32_parse_cop0 (const char *str) -++{ -++ return nds32_parse_ace (str, NDS32_COP0); -++} -++ -++int -++nds32_parse_cop1 (const char *str) -++{ -++ return nds32_parse_ace (str, NDS32_COP1); -++} -++ -++int -++nds32_parse_cop2 (const char *str) -++{ -++ return nds32_parse_ace (str, NDS32_COP2); -++} -++ -++int -++nds32_parse_cop3 (const char *str) -++{ -++ return nds32_parse_ace (str, NDS32_COP3); -++} -++ -++static void -++build_operand_hash_table (void) -++{ -++ unsigned k; -++ -++ field_htab = htab_create_alloc (128, htab_hash_hash, htab_hash_eq, -++ NULL, xcalloc, free); -++ -++ for (k = 0; k < NDS32_CORE_COUNT; k++) -+ { -+- struct nds32_hash_entry **slot; -+- struct nds32_hash_entry *h; -++ const field_t *fld; -+ -+- h = (struct nds32_hash_entry *) p; -++ fld = nds32_field_table[k]; -++ if (fld == NULL) -++ continue; -+ -+- if (h->name == NULL) -+- break; -++ /* Add op-codes. */ -++ while (fld->name != NULL) -++ { -++ hashval_t hash; -++ const field_t **slot; -+ -+- hash = htab_hash_string (h->name); -+- slot = (struct nds32_hash_entry **) -+- htab_find_slot_with_hash (htab, h->name, hash, INSERT); -++ hash = htab_hash_string (fld->name); -++ slot = (const field_t **) -++ htab_find_slot_with_hash (field_htab, fld->name, hash, INSERT); -+ -+- assert (slot != NULL && *slot == NULL); -++ assert (slot != NULL && *slot == NULL); -++ *slot = fld++; -++ } -++ } -++} -+ -+- *slot = h; -++static void -++build_keyword_hash_table (void) -++{ -++ unsigned int i, j, k, n; -+ -+- p = p + size; -++ /* Count total keyword tables. */ -++ for (n = 0, i = 0; i < NDS32_CORE_COUNT; i++) -++ { -++ n += nds32_keyword_count_table[i]; -+ } -+ -+- return htab; -++ /* Allocate space. */ -++ hw_ktabs = (htab_t *) malloc (n * sizeof (struct htab)); -++ for (i = 0; i < n; i++) -++ { -++ hw_ktabs[i] = htab_create_alloc (128, htab_hash_hash, htab_hash_eq, -++ NULL, xcalloc, free); -++ } -++ -++ for (n = 0, k = 0; k < NDS32_CORE_COUNT; k++, n += j) -++ { -++ const keyword_t **kwd; -++ -++ if ((j = nds32_keyword_count_table[k]) == 0) -++ continue; -++ -++ /* Add keywords. */ -++ kwd = nds32_keyword_table[k]; -++ for (i = 0; i < j; i++) -++ { -++ htab_t htab; -++ const keyword_t *kw; -++ -++ kw = kwd[i]; -++ htab = hw_ktabs[n + i]; -++ while (kw->name != NULL) -++ { -++ hashval_t hash; -++ const keyword_t **slot; -++ -++ hash = htab_hash_string (kw->name); -++ slot = (const keyword_t **) -++ htab_find_slot_with_hash (htab, kw->name, hash, INSERT); -++ -++ assert (slot != NULL && *slot == NULL); -++ *slot = kw++; -++ } -++ } -++ } -+ } -+ -+ /* Build the syntax for a given opcode OPC. It parses the string -+@@ -1458,36 +1819,31 @@ build_opcode_syntax (struct nds32_opcode *opc) -+ return; -+ -+ opc->syntax = xmalloc (MAX_LEX_NUM * sizeof (lex_t)); -++ memset (opc->syntax, 0, MAX_LEX_NUM * sizeof (lex_t)); -+ -+ str = opc->instruction; -+ plex = opc->syntax; -+ while (*str) -+ { -+- int fidx; -++ int i, k, fidx; -+ -+ switch (*str) -+ { -+- case '%': -+- *plex = SYN_INPUT; -+- break; -+- case '=': -+- *plex = SYN_OUTPUT; -+- break; -+- case '&': -+- *plex = SYN_INPUT | SYN_OUTPUT; -+- break; -++ case '%': *plex = SYN_INPUT; break; -++ case '=': *plex = SYN_OUTPUT; break; -++ case '&': *plex = SYN_INPUT | SYN_OUTPUT; break; -+ case '{': -+- *plex++ = SYN_LOPT; -+- opt++; -+- str++; -+- continue; -++ *plex++ = SYN_LOPT; -++ opt++; -++ str++; -++ continue; -+ case '}': -+- *plex++ = SYN_ROPT; -+- str++; -+- continue; -++ *plex++ = SYN_ROPT; -++ str++; -++ continue; -+ default: -+- *plex++ = *str++; -+- continue; -++ *plex++ = *str++; -++ continue; -+ } -+ str++; -+ -+@@ -1501,14 +1857,25 @@ build_opcode_syntax (struct nds32_opcode *opc) -+ -+ hash = htab_hash_string (odstr); -+ fd = (field_t *) htab_find_with_hash (field_htab, odstr, hash); -+- fidx = fd - operand_fields; -+- -+ if (fd == NULL) -+ { -+ fprintf (stderr, "Internal error: Unknown operand, %s\n", str); -+ } -+- assert (fd && fidx >= 0 && fidx < (int) ARRAY_SIZE (operand_fields)); -+- *plex |= LEX_SET_FIELD (fidx); -++ -++ /* We are not sure how these tables are organized. */ -++ /* Thus, the minimal index should be the right one. */ -++ for (fidx = 256, k = 0, i = 0; i < NDS32_CORE_COUNT; i++) -++ { -++ int tmp; -++ -++ tmp = fd - nds32_field_table[i]; -++ if (tmp >= 0 && tmp < fidx) -++ { -++ fidx = tmp; -++ k = i; -++ } -++ } -++ *plex |= LEX_SET_FIELD (k, fidx); -+ -+ str += len; -+ plex++; -+@@ -1519,44 +1886,37 @@ build_opcode_syntax (struct nds32_opcode *opc) -+ return; -+ } -+ -+-/* Initialize the assembler. It must be called before assembling. */ -+- -+-void -+-nds32_asm_init (nds32_asm_desc_t *pdesc, int flags) -++static void -++build_opcode_hash_table (void) -+ { -+- int i; -+- hashval_t hash; -++ unsigned k; -+ -+- pdesc->flags = flags; -+- pdesc->mach = flags & NASM_OPEN_ARCH_MASK; -+- -+- /* Build keyword tables. */ -+- field_htab = build_hash_table (operand_fields, -+- sizeof (operand_fields[0])); -+- -+- for (i = 0; i < _HW_LAST; i++) -+- hw_ktabs[i] = build_hash_table (keywords[i], sizeof (keyword_t)); -+- -+- /* Build opcode table. */ -+- opcode_htab = htab_create_alloc (128, htab_hash_hash, htab_hash_eq, -++ opcode_htab = htab_create_alloc (512, htab_hash_hash, htab_hash_eq, -+ NULL, xcalloc, free); -+ -+- for (i = 0; i < (int) ARRAY_SIZE (nds32_opcodes); i++) -++ for (k = 0; k < NDS32_CORE_COUNT; k++) -+ { -+- struct nds32_opcode **slot; -+- struct nds32_opcode *opc; -++ opcode_t *opc; -++ -++ opc = nds32_opcode_table[k]; -++ if (opc == NULL) -++ continue; -+ -+- opc = &nds32_opcodes[i]; -+- if ((opc->opcode != NULL) && (opc->instruction != NULL)) -++ /* Add op-codes. */ -++ while ((opc->opcode != NULL) && (opc->instruction != NULL)) -+ { -++ hashval_t hash; -++ opcode_t **slot; -++ -+ hash = htab_hash_string (opc->opcode); -+- slot = (struct nds32_opcode **) -+- htab_find_slot_with_hash (opcode_htab, opc->opcode, hash, INSERT); -++ slot = (opcode_t **) -++ htab_find_slot_with_hash (opcode_htab, opc->opcode, hash, -++ INSERT); -+ -+ #define NDS32_PREINIT_SYNTAX -+ #if defined (NDS32_PREINIT_SYNTAX) -+- /* Initial SYNTAX when build opcode table, so bug in syntax can be -+- found when initialized rather than used. */ -++ /* Initial SYNTAX when build opcode table, so bug in syntax -++ can be found when initialized rather than used. */ -+ build_opcode_syntax (opc); -+ #endif -+ -+@@ -1567,16 +1927,44 @@ nds32_asm_init (nds32_asm_desc_t *pdesc, int flags) -+ } -+ else -+ { -++ opcode_t *ptr; -++ -+ /* Already exists. Append to the list. */ -+- opc = *slot; -+- while (opc->next) -+- opc = opc->next; -+- opc->next = &nds32_opcodes[i]; -++ ptr = *slot; -++ while (ptr->next) -++ ptr = ptr->next; -++ ptr->next = opc; -++ opc->next = NULL; -+ } -++ opc++; -+ } -+ } -+ } -+ -++/* Initialize the assembler. It must be called before assembling. */ -++ -++void -++nds32_asm_init (nds32_asm_desc_t *pdesc, int flags) -++{ -++ pdesc->flags = flags; -++ pdesc->mach = flags & NASM_OPEN_ARCH_MASK; -++ -++ /* Setup main core. */ -++ nds32_keyword_table[NDS32_MAIN_CORE] = &keywords[0]; -++ nds32_keyword_count_table[NDS32_MAIN_CORE] = _HW_LAST; -++ nds32_opcode_table[NDS32_MAIN_CORE] = &nds32_opcodes[0]; -++ nds32_field_table[NDS32_MAIN_CORE] = &operand_fields[0]; -++ -++ /* Build operand hash table. */ -++ build_operand_hash_table (); -++ -++ /* Build keyword hash tables. */ -++ build_keyword_hash_table (); -++ -++ /* Build op-code hash table. */ -++ build_opcode_hash_table (); -++} -++ -+ /* Parse the input and store operand keyword string in ODSTR. -+ This function is only used for parsing keywords, -+ HW_INT/HW_UINT are parsed parse_operand callback handler. */ -+@@ -1617,6 +2005,11 @@ parse_re (struct nds32_asm_desc *pdesc ATTRIBUTE_UNUSED, -+ if (__GF (pinsn->insn, 20, 5) > (unsigned int) k->value) -+ return NASM_ERR_OPERAND; -+ -++ /* Register not allowed in reduced register. */ -++ if ((pdesc->flags & NASM_OPEN_REDUCED_REG) -++ && (k->attr & ATTR (RDREG)) == 0) -++ return NASM_ERR_REG_REDUCED; -++ -+ *value = k->value; -+ *pstr = end; -+ return NASM_R_CONST; -+@@ -1644,6 +2037,11 @@ parse_re2 (struct nds32_asm_desc *pdesc ATTRIBUTE_UNUSED, -+ if (k == NULL) -+ return NASM_ERR_OPERAND; -+ -++ /* Register not allowed in reduced register. */ -++ if ((pdesc->flags & NASM_OPEN_REDUCED_REG) -++ && (k->attr & ATTR (RDREG)) == 0) -++ return NASM_ERR_REG_REDUCED; -++ -+ if (k->value == 6) -+ *value = 0; -+ else if (k->value == 8) -+@@ -1699,7 +2097,8 @@ static int aext_im5_ip = 0; -+ static int aext_im6_ip = 0; -+ /* Parse the operand of audio ext. */ -+ static int -+-parse_aext_reg (char **pstr, int *value, int hw_res) -++parse_aext_reg (struct nds32_asm_desc *pdesc, char **pstr, -++ int *value, int hw_res) -+ { -+ char *end = *pstr; -+ char odstr[MAX_KEYWORD_LEN]; -+@@ -1716,20 +2115,27 @@ parse_aext_reg (char **pstr, int *value, int hw_res) -+ if (k == NULL) -+ return NASM_ERR_OPERAND; -+ -++ if (hw_res == HW_GPR -++ && (pdesc->flags & NASM_OPEN_REDUCED_REG) -++ && (k->attr & ATTR (RDREG)) == 0) -++ return NASM_ERR_REG_REDUCED; -++ -+ *value = k->value; -+ *pstr = end; -+ return NASM_R_CONST; -+ } -+ -+ static int -+-parse_a30b20 (struct nds32_asm_desc *pdesc ATTRIBUTE_UNUSED, -++parse_a30b20 (struct nds32_asm_desc *pdesc, -+ struct nds32_asm_insn *pinsn ATTRIBUTE_UNUSED, -+ char **pstr, int64_t *value) -+ { -+ int rt_value, ret; -+ -+- ret = parse_aext_reg (pstr, &rt_value, HW_GPR); -++ ret = parse_aext_reg (pdesc, pstr, &rt_value, HW_GPR); -+ -++ if (ret == NASM_ERR_REG_REDUCED) -++ return NASM_ERR_REG_REDUCED; -+ if ((ret == NASM_ERR_OPERAND) || (rt_value > 15)) -+ return NASM_ERR_OPERAND; -+ -+@@ -1739,14 +2145,16 @@ parse_a30b20 (struct nds32_asm_desc *pdesc ATTRIBUTE_UNUSED, -+ } -+ -+ static int -+-parse_rt21 (struct nds32_asm_desc *pdesc ATTRIBUTE_UNUSED, -++parse_rt21 (struct nds32_asm_desc *pdesc, -+ struct nds32_asm_insn *pinsn ATTRIBUTE_UNUSED, -+ char **pstr, int64_t *value) -+ { -+ int rt_value, ret, tmp_value, tmp1, tmp2; -+ -+- ret = parse_aext_reg (pstr, &rt_value, HW_GPR); -++ ret = parse_aext_reg (pdesc, pstr, &rt_value, HW_GPR); -+ -++ if (ret == NASM_ERR_REG_REDUCED) -++ return NASM_ERR_REG_REDUCED; -+ if ((ret == NASM_ERR_OPERAND) || (rt_value > 15)) -+ return NASM_ERR_OPERAND; -+ tmp1 = (aext_a30b20 & 0x08); -+@@ -1762,14 +2170,16 @@ parse_rt21 (struct nds32_asm_desc *pdesc ATTRIBUTE_UNUSED, -+ } -+ -+ static int -+-parse_rte_start (struct nds32_asm_desc *pdesc ATTRIBUTE_UNUSED, -++parse_rte_start (struct nds32_asm_desc *pdesc, -+ struct nds32_asm_insn *pinsn ATTRIBUTE_UNUSED, -+ char **pstr, int64_t *value) -+ { -+ int rt_value, ret, tmp1, tmp2; -+ -+- ret = parse_aext_reg (pstr, &rt_value, HW_GPR); -++ ret = parse_aext_reg (pdesc, pstr, &rt_value, HW_GPR); -+ -++ if (ret == NASM_ERR_REG_REDUCED) -++ return NASM_ERR_REG_REDUCED; -+ if ((ret == NASM_ERR_OPERAND) || (rt_value > 15) -+ || (rt_value & 0x01)) -+ return NASM_ERR_OPERAND; -+@@ -1786,13 +2196,16 @@ parse_rte_start (struct nds32_asm_desc *pdesc ATTRIBUTE_UNUSED, -+ } -+ -+ static int -+-parse_rte_end (struct nds32_asm_desc *pdesc ATTRIBUTE_UNUSED, -++parse_rte_end (struct nds32_asm_desc *pdesc, -+ struct nds32_asm_insn *pinsn ATTRIBUTE_UNUSED, -+ char **pstr, int64_t *value) -+ { -+ int rt_value, ret, tmp1, tmp2; -+ -+- ret = parse_aext_reg (pstr, &rt_value, HW_GPR); -++ ret = parse_aext_reg (pdesc, pstr, &rt_value, HW_GPR); -++ -++ if (ret == NASM_ERR_REG_REDUCED) -++ return NASM_ERR_REG_REDUCED; -+ if ((ret == NASM_ERR_OPERAND) || (rt_value > 15) -+ || ((rt_value & 0x01) == 0) -+ || (rt_value != (aext_rte + 1))) -+@@ -1801,6 +2214,7 @@ parse_rte_end (struct nds32_asm_desc *pdesc ATTRIBUTE_UNUSED, -+ tmp2 = (rt_value & 0x08); -+ if (tmp1 != tmp2) -+ return NASM_ERR_OPERAND; -++ -+ /* Rt=CONCAT(c, t21, 0), t21:bit11-10. */ -+ rt_value = (rt_value & 0x06) << 4; -+ *value = rt_value; -+@@ -1808,16 +2222,20 @@ parse_rte_end (struct nds32_asm_desc *pdesc ATTRIBUTE_UNUSED, -+ } -+ -+ static int -+-parse_rte69_start (struct nds32_asm_desc *pdesc ATTRIBUTE_UNUSED, -++parse_rte69_start (struct nds32_asm_desc *pdesc, -+ struct nds32_asm_insn *pinsn ATTRIBUTE_UNUSED, -+ char **pstr, int64_t *value) -+ { -+ int rt_value, ret; -+ -+- ret = parse_aext_reg (pstr, &rt_value, HW_GPR); -++ ret = parse_aext_reg (pdesc, pstr, &rt_value, HW_GPR); -++ -++ if (ret == NASM_ERR_REG_REDUCED) -++ return NASM_ERR_REG_REDUCED; -+ if ((ret == NASM_ERR_OPERAND) -+ || (rt_value & 0x01)) -+ return NASM_ERR_OPERAND; -++ -+ aext_rte = rt_value; -+ rt_value = (rt_value >> 1); -+ *value = rt_value; -+@@ -1825,17 +2243,21 @@ parse_rte69_start (struct nds32_asm_desc *pdesc ATTRIBUTE_UNUSED, -+ } -+ -+ static int -+-parse_rte69_end (struct nds32_asm_desc *pdesc ATTRIBUTE_UNUSED, -++parse_rte69_end (struct nds32_asm_desc *pdesc, -+ struct nds32_asm_insn *pinsn ATTRIBUTE_UNUSED, -+ char **pstr, int64_t *value) -+ { -+ int rt_value, ret; -+ -+- ret = parse_aext_reg (pstr, &rt_value, HW_GPR); -++ ret = parse_aext_reg (pdesc, pstr, &rt_value, HW_GPR); -++ -++ if (ret == NASM_ERR_REG_REDUCED) -++ return NASM_ERR_REG_REDUCED; -+ if ((ret == NASM_ERR_OPERAND) -+ || ((rt_value & 0x01) == 0) -+ || (rt_value != (aext_rte + 1))) -+ return NASM_ERR_OPERAND; -++ -+ aext_rte = rt_value; -+ rt_value = (rt_value >> 1); -+ *value = rt_value; -+@@ -1843,13 +2265,13 @@ parse_rte69_end (struct nds32_asm_desc *pdesc ATTRIBUTE_UNUSED, -+ } -+ -+ static int -+-parse_im5_ip (struct nds32_asm_desc *pdesc ATTRIBUTE_UNUSED, -++parse_im5_ip (struct nds32_asm_desc *pdesc, -+ struct nds32_asm_insn *pinsn ATTRIBUTE_UNUSED, -+ char **pstr, int64_t *value) -+ { -+ int rt_value, ret, new_value; -+ -+- ret = parse_aext_reg (pstr, &rt_value, HW_AEXT_IM_I); -++ ret = parse_aext_reg (pdesc, pstr, &rt_value, HW_AEXT_IM_I); -+ if (ret == NASM_ERR_OPERAND) -+ return NASM_ERR_OPERAND; -+ /* p = bit[4].bit[1:0], r = bit[4].bit[3:2]. */ -+@@ -1861,13 +2283,13 @@ parse_im5_ip (struct nds32_asm_desc *pdesc ATTRIBUTE_UNUSED, -+ } -+ -+ static int -+-parse_im5_mr (struct nds32_asm_desc *pdesc ATTRIBUTE_UNUSED, -++parse_im5_mr (struct nds32_asm_desc *pdesc, -+ struct nds32_asm_insn *pinsn ATTRIBUTE_UNUSED, -+ char **pstr, int64_t *value) -+ { -+ int rt_value, ret, new_value, tmp1, tmp2; -+ -+- ret = parse_aext_reg (pstr, &rt_value, HW_AEXT_IM_M); -++ ret = parse_aext_reg (pdesc, pstr, &rt_value, HW_AEXT_IM_M); -+ if (ret == NASM_ERR_OPERAND) -+ return NASM_ERR_OPERAND; -+ /* p = bit[4].bit[1:0], r = bit[4].bit[3:2]. */ -+@@ -1881,13 +2303,13 @@ parse_im5_mr (struct nds32_asm_desc *pdesc ATTRIBUTE_UNUSED, -+ } -+ -+ static int -+-parse_im6_ip (struct nds32_asm_desc *pdesc ATTRIBUTE_UNUSED, -++parse_im6_ip (struct nds32_asm_desc *pdesc, -+ struct nds32_asm_insn *pinsn ATTRIBUTE_UNUSED, -+ char **pstr, int64_t *value) -+ { -+ int rt_value, ret; -+ -+- ret = parse_aext_reg (pstr, &rt_value, HW_AEXT_IM_I); -++ ret = parse_aext_reg (pdesc, pstr, &rt_value, HW_AEXT_IM_I); -+ if ((ret == NASM_ERR_OPERAND) || (rt_value > 3)) -+ return NASM_ERR_OPERAND; -+ /* p = 0.bit[1:0]. */ -+@@ -1897,13 +2319,13 @@ parse_im6_ip (struct nds32_asm_desc *pdesc ATTRIBUTE_UNUSED, -+ } -+ -+ static int -+-parse_im6_iq (struct nds32_asm_desc *pdesc ATTRIBUTE_UNUSED, -++parse_im6_iq (struct nds32_asm_desc *pdesc, -+ struct nds32_asm_insn *pinsn ATTRIBUTE_UNUSED, -+ char **pstr, int64_t *value) -+ { -+ int rt_value, ret; -+ -+- ret = parse_aext_reg (pstr, &rt_value, HW_AEXT_IM_I); -++ ret = parse_aext_reg (pdesc, pstr, &rt_value, HW_AEXT_IM_I); -+ if ((ret == NASM_ERR_OPERAND) || (rt_value < 4)) -+ return NASM_ERR_OPERAND; -+ /* q = 1.bit[1:0]. */ -+@@ -1914,13 +2336,13 @@ parse_im6_iq (struct nds32_asm_desc *pdesc ATTRIBUTE_UNUSED, -+ } -+ -+ static int -+-parse_im6_mr (struct nds32_asm_desc *pdesc ATTRIBUTE_UNUSED, -++parse_im6_mr (struct nds32_asm_desc *pdesc, -+ struct nds32_asm_insn *pinsn ATTRIBUTE_UNUSED, -+ char **pstr, int64_t *value) -+ { -+ int rt_value, ret; -+ -+- ret = parse_aext_reg (pstr, &rt_value, HW_AEXT_IM_M); -++ ret = parse_aext_reg (pdesc, pstr, &rt_value, HW_AEXT_IM_M); -+ if ((ret == NASM_ERR_OPERAND) || (rt_value > 3)) -+ return NASM_ERR_OPERAND; -+ /* r = 0.bit[3:2]. */ -+@@ -1929,13 +2351,13 @@ parse_im6_mr (struct nds32_asm_desc *pdesc ATTRIBUTE_UNUSED, -+ } -+ -+ static int -+-parse_im6_ms (struct nds32_asm_desc *pdesc ATTRIBUTE_UNUSED, -++parse_im6_ms (struct nds32_asm_desc *pdesc, -+ struct nds32_asm_insn *pinsn ATTRIBUTE_UNUSED, -+ char **pstr, int64_t *value) -+ { -+ int rt_value, ret; -+ -+- ret = parse_aext_reg (pstr, &rt_value, HW_AEXT_IM_M); -++ ret = parse_aext_reg (pdesc, pstr, &rt_value, HW_AEXT_IM_M); -+ if ((ret == NASM_ERR_OPERAND) || (rt_value < 4)) -+ return NASM_ERR_OPERAND; -+ /* s = 1.bit[5:4]. */ -+@@ -1952,9 +2374,9 @@ parse_operand (nds32_asm_desc_t *pdesc, nds32_asm_insn_t *pinsn, -+ char odstr[MAX_KEYWORD_LEN]; -+ char *end; -+ hashval_t hash; -+- const field_t *fld = &LEX_GET_FIELD (syn); -++ const field_t *fld = &LEX_GET_FIELD (((syn >> 8) & 0xff) - 1, syn); -+ keyword_t *k; -+- int64_t value; -++ int64_t value = 0; /* 0x100000000; Big enough to overflow. */ -+ int r; -+ uint64_t modifier = 0; -+ -+@@ -1963,23 +2385,31 @@ parse_operand (nds32_asm_desc_t *pdesc, nds32_asm_insn_t *pinsn, -+ if (fld->parse) -+ { -+ r = fld->parse (pdesc, pinsn, &end, &value); -+- if (r == NASM_ERR_OPERAND) -++ if (r == NASM_ERR_OPERAND || r == NASM_ERR_REG_REDUCED) -+ { -+- pdesc->result = NASM_ERR_OPERAND; -++ pdesc->result = r; -+ return 0; -+ } -+ goto done; -+ } -+ -+- if (fld->hw_res < _HW_LAST) -++ /* Check valid keyword group. */ -++ if (fld->hw_res < HW_INT) -+ { -++ int n = 0, i; -++ -++ /* Calculate index of keyword hash table. */ -++ for (i = 0; i < (fld->hw_res >> 8); i++) -++ n += nds32_keyword_count_table[i]; -++ -+ /* Parse the operand in assembly code. */ -+ if (*end == '$') -+ end++; -+ end = parse_to_delimiter (end, odstr); -+ -+ hash = htab_hash_string (odstr); -+- k = htab_find_with_hash (hw_ktabs[fld->hw_res], odstr, hash); -++ k = htab_find_with_hash (hw_ktabs[n + (fld->hw_res & 0xff)], odstr, -++ hash); -+ -+ if (k == NULL) -+ { -+@@ -2086,7 +2516,7 @@ done: -+ { -+ /* Sign-ext the value. */ -+ if (((value >> 32) == 0) && (value & 0x80000000)) -+- value |= (int64_t) -1U << 31; -++ value |= (int64_t)((uint64_t) -1 << 31); -+ -+ -+ /* Shift the value to positive domain. */ -+diff --git binutils-2.30/opcodes/nds32-asm.h binutils-2.30-nds32/opcodes/nds32-asm.h -+index c67e590c64..ea165833c3 100644 -+--- binutils-2.30/opcodes/nds32-asm.h -++++ binutils-2.30-nds32/opcodes/nds32-asm.h -+@@ -77,6 +77,8 @@ enum -+ NASM_ATTR_SATURATION_EXT = 0x0400000, -+ NASM_ATTR_PCREL = 0x0800000, -+ NASM_ATTR_GPREL = 0x1000000, -++ NASM_ATTR_DSP_ISAEXT = 0x2000000, -++ NASM_ATTR_ZOL = (1 << 26), -+ -+ /* Attributes for relocations. */ -+ NASM_ATTR_HI20 = 0x10000000, -+@@ -84,22 +86,30 @@ enum -+ NASM_ATTR_LO20 = 0x40000000, -+ -+ /* Attributes for registers. */ -+- NASM_ATTR_RDREG = 0x000100 -++ NASM_ATTR_RDREG = 0x000100, -++ -+ }; -+ -++#define NDS32_CORE_COUNT 6 -++#define NDS32_MAIN_CORE 0 -++#define NDS32_ACE 1 -++#define NDS32_COP0 2 -++#define NDS32_COP1 3 -++#define NDS32_COP2 4 -++#define NDS32_COP3 5 -++ -+ enum -+ { -+- /* This is a field (operand) of just a separator char. */ -+- SYN_FIELD = 0x100, -+- -+ /* This operand is used for input or output. (define or use) */ -+- SYN_INPUT = 0x1000, -+- SYN_OUTPUT = 0x2000, -+- SYN_LOPT = 0x4000, -+- SYN_ROPT = 0x8000, -+- -+- /* Hardware resources. */ -+- HW_GPR = 0, -++ SYN_INPUT = 0x10000, -++ SYN_OUTPUT = 0x20000, -++ SYN_LOPT = 0x40000, -++ SYN_ROPT = 0x80000, -++ -++ /* Hardware resources: -++ Current set up allows up to 256 resources for each class -++ defined above. */ -++ HW_GPR = NDS32_MAIN_CORE << 8, -+ HW_USR, -+ HW_DXR, -+ HW_SR, -+@@ -128,14 +138,20 @@ enum -+ HW_AEXT_ARIDX, -+ HW_AEXT_ARIDX2, -+ HW_AEXT_ARIDXI, -++ HW_AEXT_ARIDXI_MX, -+ _HW_LAST, -+ /* TODO: Maybe we should add a new type to distinguish address and -+- const int. Only the former allows symbols and relocations. */ -+- HW_INT, -++ const int. Only the former allows symbols and relocations. */ -++ HW_ACE_BASE = NDS32_ACE << 8, -++ HW_COP0_BASE = NDS32_COP0 << 8, -++ HW_COP1_BASE = NDS32_COP1 << 8, -++ HW_COP2_BASE = NDS32_COP2 << 8, -++ HW_COP3_BASE = NDS32_COP3 << 8, -++ HW_INT = 0x1000, -+ HW_UINT -+ }; -+ -+-/* for audio-extension. */ -++/* For audio-extension. */ -+ enum -+ { -+ N32_AEXT_AMADD = 0, -+@@ -159,7 +175,7 @@ enum -+ N32_AEXT_AMBBS, -+ N32_AEXT_AMBTS, -+ N32_AEXT_AMTBS, -+- N32_AEXT_AMTTS -++ N32_AEXT_AMTTS, -+ }; -+ -+ /* Macro for instruction attribute. */ -+@@ -212,7 +228,7 @@ typedef struct nds32_opcode -+ struct nds32_opcode *next; -+ -+ /* TODO: Extra constrains and verification. -+- For example, `mov55 $sp, $sp' is not allowed in v3. */ -++ For example, `mov55 $sp, $sp' is not allowed in v3. */ -+ } opcode_t; -+ -+ typedef struct nds32_asm_insn -+@@ -266,6 +282,11 @@ typedef struct nds32_field -+ -+ extern void nds32_assemble (nds32_asm_desc_t *, nds32_asm_insn_t *, char *); -+ extern void nds32_asm_init (nds32_asm_desc_t *, int); -++extern int nds32_parse_udi (const char *); -++extern int nds32_parse_cop0 (const char *); -++extern int nds32_parse_cop1 (const char *); -++extern int nds32_parse_cop2 (const char *); -++extern int nds32_parse_cop3 (const char *); -+ -+ #define OP6(op6) (N32_OP6_ ## op6 << 25) -+ -+@@ -277,6 +298,9 @@ extern void nds32_asm_init (nds32_asm_desc_t *, int); -+ #define SIMD(sub) (OP6 (SIMD) | N32_SIMD_ ## sub) -+ #define ALU1(sub) (OP6 (ALU1) | N32_ALU1_ ## sub) -+ #define ALU2(sub) (OP6 (ALU2) | N32_ALU2_ ## sub) -++#define ALU2_1(sub) (OP6 (ALU2) | N32_BIT (6) | N32_ALU2_ ## sub) -++#define ALU2_2(sub) (OP6 (ALU2) | N32_BIT (7) | N32_ALU2_ ## sub) -++#define ALU2_3(sub) (OP6 (ALU2) | N32_BIT (6) | N32_BIT (7) | N32_ALU2_ ## sub) -+ #define MISC(sub) (OP6 (MISC) | N32_MISC_ ## sub) -+ #define MEM(sub) (OP6 (MEM) | N32_MEM_ ## sub) -+ #define FPU_RA_IMMBI(sub) (OP6 (sub) | N32_BIT (12)) -+diff --git binutils-2.30/opcodes/nds32-dis.c binutils-2.30-nds32/opcodes/nds32-dis.c -+index 418019ae87..bb5106f954 100644 -+--- binutils-2.30/opcodes/nds32-dis.c -++++ binutils-2.30-nds32/opcodes/nds32-dis.c -+@@ -35,92 +35,71 @@ -+ /* Get fields macro define. */ -+ #define MASK_OP(insn, mask) ((insn) & (0x3f << 25 | (mask))) -+ -++/* For mapping symbol. */ -++enum map_type -++{ -++ MAP_DATA0, -++ MAP_DATA1, -++ MAP_DATA2, -++ MAP_DATA3, -++ MAP_DATA4, -++ MAP_CODE, -++}; -++ -++struct nds32_private_data -++{ -++ /* Whether any mapping symbols are present in the provided symbol -++ table. -1 if we do not know yet, otherwise 0 or 1. */ -++ int has_mapping_symbols; -++ -++ /* Track the last type (although this doesn't seem to be useful). */ -++ enum map_type last_mapping_type; -++ -++ /* Tracking symbol table information. */ -++ int last_symbol_index; -++ bfd_vma last_addr; -++}; -+ /* Default text to print if an instruction isn't recognized. */ -+ #define UNKNOWN_INSN_MSG _("*unknown*") -++ -+ #define NDS32_PARSE_INSN16 0x01 -+ #define NDS32_PARSE_INSN32 0x02 -+-#define NDS32_PARSE_EX9IT 0x04 -+-#define NDS32_PARSE_EX9TAB 0x08 -+ -++static void print_insn16 (bfd_vma, disassemble_info *, -++ uint32_t, uint32_t); -++static void print_insn32 (bfd_vma, disassemble_info *, uint32_t, -++ uint32_t); -++static uint32_t nds32_mask_opcode (uint32_t); -++static void nds32_special_opcode (uint32_t, struct nds32_opcode **); -++static int get_mapping_symbol_type (struct disassemble_info *, int, -++ enum map_type *); -++static int is_mapping_symbol (struct disassemble_info *, int, -++ enum map_type *); -++ -++extern const field_t *nds32_field_table[NDS32_CORE_COUNT]; -++extern opcode_t *nds32_opcode_table[NDS32_CORE_COUNT]; -++extern keyword_t **nds32_keyword_table[NDS32_CORE_COUNT]; -+ extern struct nds32_opcode nds32_opcodes[]; -+ extern const field_t operand_fields[]; -+-extern const keyword_t *keywords[]; -++extern keyword_t *keywords[]; -+ extern const keyword_t keyword_gpr[]; -+-static void print_insn16 (bfd_vma pc, disassemble_info *info, -+- uint32_t insn, uint32_t parse_mode); -+-static void print_insn32 (bfd_vma pc, disassemble_info *info, uint32_t insn, -+- uint32_t parse_mode); -+-static uint32_t nds32_mask_opcode (uint32_t); -+-static void nds32_special_opcode (uint32_t, struct nds32_opcode **); -+ -+-/* define in objdump.c. */ -++/* Defined in objdump.c. */ -+ struct objdump_disasm_info -+ { -+- bfd * abfd; -+- asection * sec; -+- bfd_boolean require_sec; -+- arelent ** dynrelbuf; -+- long dynrelcount; -++ bfd *abfd; -++ asection *sec; -++ bfd_boolean require_sec; -++ arelent **dynrelbuf; -++ long dynrelcount; -+ disassembler_ftype disassemble_fn; -+- arelent * reloc; -++ arelent *reloc; -+ }; -+ -+-/* file_ptr ex9_filepos=NULL;. */ -+-bfd_byte *ex9_data = NULL; -+-int ex9_ready = 0, ex9_base_offset = 0; -+- -+ /* Hash function for disassemble. */ -+ -+ static htab_t opcode_htab; -+ -+-static void -+-nds32_ex9_info (bfd_vma pc ATTRIBUTE_UNUSED, -+- disassemble_info *info, uint32_t ex9_index) -+-{ -+- uint32_t insn; -+- static asymbol *itb = NULL; -+- bfd_byte buffer[4]; -+- long unsigned int isec_vma; -+- -+- /* Lookup itb symbol. */ -+- if (!itb) -+- { -+- int i; -+- -+- for (i = 0; i < info->symtab_size; i++) -+- if (bfd_asymbol_name (info->symtab[i]) -+- && (strcmp (bfd_asymbol_name (info->symtab[i]), "$_ITB_BASE_") == 0 -+- || strcmp (bfd_asymbol_name (info->symtab[i]), -+- "_ITB_BASE_") == 0)) -+- { -+- itb = info->symtab[i]; -+- break; -+- } -+- -+- /* Lookup it only once, in case _ITB_BASE_ doesn't exist at all. */ -+- if (itb == NULL) -+- itb = (void *) -1; -+- } -+- -+- if (itb == (void *) -1) -+- return; -+- -+- isec_vma = itb->section->vma; -+- isec_vma = itb->section->vma - bfd_asymbol_value (itb); -+- if (!itb->section || !itb->section->owner) -+- return; -+- bfd_get_section_contents (itb->section->owner, itb->section, buffer, -+- ex9_index * 4 - isec_vma, 4); -+- insn = bfd_getb32 (buffer); -+- /* 16-bit instructions in ex9 table. */ -+- if (insn & 0x80000000) -+- print_insn16 (pc, info, (insn & 0x0000FFFF), -+- NDS32_PARSE_INSN16 | NDS32_PARSE_EX9IT); -+- /* 32-bit instructions in ex9 table. */ -+- else -+- print_insn32 (pc, info, insn, NDS32_PARSE_INSN32 | NDS32_PARSE_EX9IT); -+-} -+- -+ /* Find the value map register name. */ -+ -+ static keyword_t * -+@@ -155,7 +134,7 @@ nds32_parse_audio_ext (const field_t *pfd, -+ else -+ int_value = __GF (insn, pfd->bitpos, pfd->bitsize) << pfd->shift; -+ -+- if (int_value < 10) -++ if (int_value < 0) -+ func (stream, "#%d", int_value); -+ else -+ func (stream, "#0x%x", int_value); -+@@ -186,7 +165,7 @@ nds32_parse_audio_ext (const field_t *pfd, -+ { -+ new_value |= 0x04; -+ } -+- /* Rt CONCAT(c, t21, t0). */ -++ /* Rt CONCAT(c, t21, t0). */ -+ else if (strcmp (pfd->name, "a_rt21") == 0) -+ { -+ new_value = (insn & 0x00000020) >> 5; -+@@ -221,12 +200,33 @@ nds32_parse_audio_ext (const field_t *pfd, -+ func (stream, "$%s", psys_reg->name); -+ } -+ -+-/* Dump instruction. If the opcode is unknown, return FALSE. */ -++/* Match instruction opcode with keyword table. */ -++ -++static field_t * -++match_field (char *name) -++{ -++ field_t *pfd; -++ int k; -++ -++ for (k = 0; k < NDS32_CORE_COUNT; k++) -++ { -++ pfd = (field_t *) nds32_field_table[k]; -++ while (1) -++ { -++ if (pfd->name == NULL) -++ break; -++ if (strcmp (name, pfd->name) == 0) -++ return pfd; -++ pfd++; -++ } -++ } -++ -++ return NULL; -++} -+ -+ static void -+ nds32_parse_opcode (struct nds32_opcode *opc, bfd_vma pc ATTRIBUTE_UNUSED, -+- disassemble_info *info, uint32_t insn, -+- uint32_t parse_mode) -++ disassemble_info *info, uint32_t insn, uint32_t parse_mode) -+ { -+ int op = 0; -+ fprintf_ftype func = info->fprintf_func; -+@@ -245,9 +245,6 @@ nds32_parse_opcode (struct nds32_opcode *opc, bfd_vma pc ATTRIBUTE_UNUSED, -+ return; -+ } -+ -+- if (parse_mode & NDS32_PARSE_EX9IT) -+- func (stream, " !"); -+- -+ pstr_src = opc->instruction; -+ if (*pstr_src == 0) -+ { -+@@ -259,7 +256,6 @@ nds32_parse_opcode (struct nds32_opcode *opc, bfd_vma pc ATTRIBUTE_UNUSED, -+ { -+ func (stream, "%s ", opc->opcode); -+ } -+- -+ /* NDS32_PARSE_INSN32. */ -+ else -+ { -+@@ -269,7 +265,7 @@ nds32_parse_opcode (struct nds32_opcode *opc, bfd_vma pc ATTRIBUTE_UNUSED, -+ else if (strstr (opc->instruction, "tito")) -+ func (stream, "%s", opc->opcode); -+ else -+- func (stream, "%s\t", opc->opcode); -++ func (stream, "%s ", opc->opcode); -+ } -+ -+ while (*pstr_src) -+@@ -280,7 +276,7 @@ nds32_parse_opcode (struct nds32_opcode *opc, bfd_vma pc ATTRIBUTE_UNUSED, -+ case '=': -+ case '&': -+ pstr_src++; -+- /* Compare with operand_fields[].name. */ -++ /* Compare name with operand table entries. */ -+ pstr_tmp = &tmp_string[0]; -+ while (*pstr_src) -+ { -+@@ -293,18 +289,9 @@ nds32_parse_opcode (struct nds32_opcode *opc, bfd_vma pc ATTRIBUTE_UNUSED, -+ *pstr_tmp++ = *pstr_src++; -+ } -+ *pstr_tmp = 0; -++ if ((pfd = match_field (&tmp_string[0])) == NULL) -++ return; -+ -+- pfd = (const field_t *) &operand_fields[0]; -+- while (1) -+- { -+- if (pfd->name == NULL) -+- return; -+- else if (strcmp (&tmp_string[0], pfd->name) == 0) -+- break; -+- pfd++; -+- } -+- -+- /* For insn-16. */ -+ if (parse_mode & NDS32_PARSE_INSN16) -+ { -+ if (pfd->hw_res == HW_GPR) -+@@ -331,7 +318,7 @@ nds32_parse_opcode (struct nds32_opcode *opc, bfd_vma pc ATTRIBUTE_UNUSED, -+ if (pfd->hw_res == HW_INT) -+ int_value = -+ N32_IMMS ((insn >> pfd->bitpos), -+- pfd->bitsize) << pfd->shift; -++ pfd->bitsize) << pfd->shift; -+ else -+ int_value = -+ __GF (insn, pfd->bitpos, pfd->bitsize) << pfd->shift; -+@@ -348,12 +335,11 @@ nds32_parse_opcode (struct nds32_opcode *opc, bfd_vma pc ATTRIBUTE_UNUSED, -+ int_value = 0 - (128 - int_value); -+ func (stream, "#%d", int_value); -+ } -+- /* beqz38/bnez38/beqs38/bnes38/j8/beqzs8/bnezs8/ifcall9. */ -++ /* beqz38/bnez38/beqs38/bnes38/j8/beqzs8/bnezs8. */ -+ else if ((opc->value == 0xc000) || (opc->value == 0xc800) -+ || (opc->value == 0xd000) || (opc->value == 0xd800) -+ || (opc->value == 0xd500) || (opc->value == 0xe800) -+- || (opc->value == 0xe900) -+- || (opc->value == 0xf800)) -++ || (opc->value == 0xe900)) -+ { -+ info->print_address_func (int_value + pc, info); -+ } -+@@ -365,28 +351,17 @@ nds32_parse_opcode (struct nds32_opcode *opc, bfd_vma pc ATTRIBUTE_UNUSED, -+ func (stream, "~$%s", keyword_gpr[push25gpr].name); -+ func (stream, ", $fp, $gp, $lp}"); -+ } -+- /* ex9.it. */ -+- else if ((opc->value == 0xdd40) || (opc->value == 0xea00)) -+- { -+- func (stream, "#%d", int_value); -+- nds32_ex9_info (pc, info, int_value); -+- } -+ else if (pfd->hw_res == HW_INT) -+ { -+- if (int_value < 10) -++ if (int_value < 0) -+ func (stream, "#%d", int_value); -+ else -+ func (stream, "#0x%x", int_value); -+ } -+- else /* if (pfd->hw_res == HW_UINT). */ -+- { -+- if (int_value < 10) -+- func (stream, "#%u", int_value); -+- else -+- func (stream, "#0x%x", int_value); -+- } -++ /* if(pfd->hw_res == HW_UINT). */ -++ else -++ func (stream, "#0x%x", int_value); -+ } -+- -+ } -+ /* for audio-ext. */ -+ else if (op == N32_OP6_AEXT) -+@@ -394,12 +369,13 @@ nds32_parse_opcode (struct nds32_opcode *opc, bfd_vma pc ATTRIBUTE_UNUSED, -+ nds32_parse_audio_ext (pfd, info, insn); -+ } -+ /* for insn-32. */ -+- else if (pfd->hw_res < _HW_LAST) -++ else if (pfd->hw_res < HW_INT) -+ { -+ int_value = -+ __GF (insn, pfd->bitpos, pfd->bitsize) << pfd->shift; -+ -+- psys_reg = (keyword_t*) keywords[pfd->hw_res]; -++ psys_reg = *(nds32_keyword_table[pfd->hw_res >> 8] -++ + (pfd->hw_res & 0xff)); -+ -+ psys_reg = nds32_find_reg_keyword (psys_reg, int_value); -+ /* For HW_SR, dump the index when it can't -+@@ -444,15 +420,7 @@ nds32_parse_opcode (struct nds32_opcode *opc, bfd_vma pc ATTRIBUTE_UNUSED, -+ /* FIXME: Handle relocation. */ -+ if (info->flags & INSN_HAS_RELOC) -+ pc = 0; -+- /* Check if insn32 in ex9 table. */ -+- if (parse_mode & NDS32_PARSE_EX9IT) -+- info->print_address_func ((pc & 0xFE000000) | int_value, -+- info); -+- /* Check if decode ex9 table, PC(31,25)|Inst(23,0)<<1. */ -+- else if (parse_mode & NDS32_PARSE_EX9TAB) -+- func (stream, "PC(31,25)|#0x%x", int_value); -+- else -+- info->print_address_func (int_value + pc, info); -++ info->print_address_func (int_value + pc, info); -+ } -+ else if (op == N32_OP6_LSMW) -+ { -+@@ -496,17 +464,14 @@ nds32_parse_opcode (struct nds32_opcode *opc, bfd_vma pc ATTRIBUTE_UNUSED, -+ } -+ else if (pfd->hw_res == HW_INT) -+ { -+- if (int_value < 10) -++ if (int_value < 0) -+ func (stream, "#%d", int_value); -+ else -+ func (stream, "#0x%x", int_value); -+ } -+- else /* if (pfd->hw_res == HW_UINT). */ -++ else /* if(pfd->hw_res == HW_UINT). */ -+ { -+- if (int_value < 10) -+- func (stream, "#%u", int_value); -+- else -+- func (stream, "#0x%x", int_value); -++ func (stream, "#0x%x", int_value); -+ } -+ } -+ break; -+@@ -516,34 +481,13 @@ nds32_parse_opcode (struct nds32_opcode *opc, bfd_vma pc ATTRIBUTE_UNUSED, -+ pstr_src++; -+ break; -+ -+- case ',': -+- func (stream, ", "); -+- pstr_src++; -+- break; -+- -+- case '+': -+- func (stream, " + "); -+- pstr_src++; -+- break; -+- -+- case '<': -+- if (pstr_src[1] == '<') -+- { -+- func (stream, " << "); -+- pstr_src += 2; -+- } -+- else -+- { -+- func (stream, " <"); -+- pstr_src++; -+- } -+- break; -+- -+ default: -+ func (stream, "%c", *pstr_src++); -+ break; -+- } -+- } -++ } /* switch (*pstr_src). */ -++ -++ } /* while (*pstr_src). */ -++ return; -+ } -+ -+ /* Filter instructions with some bits must be fixed. */ -+@@ -571,7 +515,7 @@ nds32_filter_unknown_insn (uint32_t insn, struct nds32_opcode **opc) -+ if (__GF (insn, 5, 5) != 0) -+ *opc = NULL; -+ break; -+- case BR2 (IFCALL): -++ case BR2 (SOP0): -+ if (__GF (insn, 20, 5) != 0) -+ *opc = NULL; -+ break; -+@@ -692,6 +636,7 @@ print_insn16 (bfd_vma pc, disassemble_info *info, -+ } -+ break; -+ } -++ -+ opcode = insn & mask; -+ opc = (struct nds32_opcode *) htab_find (opcode_htab, &opcode); -+ -+@@ -715,6 +660,21 @@ htab_hash_eq (const void *p, const void *q) -+ return (pinsn == qinsn); -+ } -+ -++static uint32_t -++mask_CEXT (uint32_t insn) -++{ -++ opcode_t *opc = nds32_opcode_table[NDS32_ACE], *max_opc = NULL; -++ -++ for (; opc != NULL && opc->opcode != NULL; opc++) -++ { -++ if ((insn & opc->value) == opc->value -++ && (max_opc == NULL || opc->value > max_opc->value)) -++ max_opc = opc; -++ } -++ -++ return max_opc ? max_opc->value : insn; -++} -++ -+ /* Get the format of instruction. */ -+ -+ static uint32_t -+@@ -754,18 +714,26 @@ nds32_mask_opcode (uint32_t insn) -+ case N32_OP6_ORI: -+ case N32_OP6_SLTI: -+ case N32_OP6_SLTSI: -+- case N32_OP6_CEXT: -+ case N32_OP6_BITCI: -+ return MASK_OP (insn, 0); -++ case N32_OP6_CEXT: -++ return mask_CEXT (insn); -+ case N32_OP6_ALU2: -+ /* FFBI */ -+ if (__GF (insn, 0, 7) == (N32_ALU2_FFBI | N32_BIT (6))) -+ return MASK_OP (insn, 0x7f); -+- else if (__GF (insn, 0, 7) == (N32_ALU2_MFUSR | N32_BIT (6)) -+- || __GF (insn, 0, 7) == (N32_ALU2_MTUSR | N32_BIT (6))) -++ else if (__GF (insn, 0, 10) == (N32_ALU2_MFUSR | N32_BIT (6)) -++ || __GF (insn, 0, 10) == (N32_ALU2_MTUSR | N32_BIT (6))) -+ /* RDOV CLROV */ -+ return MASK_OP (insn, 0xf81ff); -+- return MASK_OP (insn, 0x1ff); -++ else if (__GF (insn, 0, 10) == (N32_ALU2_ONEOP | N32_BIT (7))) -++ { -++ /* INSB */ -++ if (__GF (insn, 12, 3) == 4) -++ return MASK_OP (insn, 0x73ff); -++ return MASK_OP (insn, 0x7fff); -++ } -++ return MASK_OP (insn, 0x3ff); -+ case N32_OP6_ALU1: -+ case N32_OP6_SIMD: -+ return MASK_OP (insn, 0x1f); -+@@ -794,113 +762,116 @@ nds32_mask_opcode (uint32_t insn) -+ case N32_OP6_BR1: -+ return MASK_OP (insn, 0x1 << 14); -+ case N32_OP6_BR2: -+- return MASK_OP (insn, 0xf << 16); -++ if (__GF (insn, 16, 4) == 0) -++ return MASK_OP (insn, 0x1ff << 16); -++ else -++ return MASK_OP (insn, 0xf << 16); -+ case N32_OP6_BR3: -+ return MASK_OP (insn, 0x1 << 19); -+ case N32_OP6_MISC: -+- switch (__GF (insn, 0, 5)) -+- { -+- case N32_MISC_MTSR: -+- /* SETGIE and SETEND */ -+- if (__GF (insn, 5, 5) == 0x1 || __GF (insn, 5, 5) == 0x2) -+- return MASK_OP (insn, 0x1fffff); -+- return MASK_OP (insn, 0x1f); -+- case N32_MISC_TLBOP: -+- if (__GF (insn, 5, 5) == 5 || __GF (insn, 5, 5) == 7) -+- /* PB FLUA */ -+- return MASK_OP (insn, 0x3ff); -+- return MASK_OP (insn, 0x1f); -+- default: -+- return MASK_OP (insn, 0x1f); -+- } -++ switch (__GF (insn, 0, 5)) -++ { -++ case N32_MISC_MTSR: -++ /* SETGIE and SETEND */ -++ if (__GF (insn, 5, 5) == 0x1 || __GF (insn, 5, 5) == 0x2) -++ return MASK_OP (insn, 0x1fffff); -++ return MASK_OP (insn, 0x1f); -++ case N32_MISC_TLBOP: -++ if (__GF (insn, 5, 5) == 5 || __GF (insn, 5, 5) == 7) -++ /* PB FLUA */ -++ return MASK_OP (insn, 0x3ff); -++ return MASK_OP (insn, 0x1f); -++ default: -++ return MASK_OP (insn, 0x1f); -++ } -+ case N32_OP6_COP: -+- if (__GF (insn, 4, 2) == 0) -+- { -+- /* FPU */ -+- switch (__GF (insn, 0, 4)) -+- { -+- case 0x0: -+- case 0x8: -+- /* FS1/F2OP FD1/F2OP */ -+- if (__GF (insn, 6, 4) == 0xf) -+- return MASK_OP (insn, 0x7fff); -+- /* FS1 FD1 */ -+- return MASK_OP (insn, 0x3ff); -+- case 0x4: -+- case 0xc: -+- /* FS2 */ -+- return MASK_OP (insn, 0x3ff); -+- case 0x1: -+- case 0x9: -+- /* XR */ -+- if (__GF (insn, 6, 4) == 0xc) -+- return MASK_OP (insn, 0x7fff); -+- /* MFCP MTCP */ -+- return MASK_OP (insn, 0x3ff); -+- default: -+- return MASK_OP (insn, 0xff); -+- } -+- } -+- else if (__GF (insn, 0, 2) == 0) -+- return MASK_OP (insn, 0xf); -+- return MASK_OP (insn, 0xcf); -++ if (__GF (insn, 4, 2) == 0) -++ { -++ /* FPU */ -++ switch (__GF (insn, 0, 4)) -++ { -++ case 0x0: -++ case 0x8: -++ /* FS1/F2OP FD1/F2OP */ -++ if (__GF (insn, 6, 4) == 0xf) -++ return MASK_OP (insn, 0x7fff); -++ /* FS1 FD1 */ -++ return MASK_OP (insn, 0x3ff); -++ case 0x4: -++ case 0xc: -++ /* FS2 */ -++ return MASK_OP (insn, 0x3ff); -++ case 0x1: -++ case 0x9: -++ /* XR */ -++ if (__GF (insn, 6, 4) == 0xc) -++ return MASK_OP (insn, 0x7fff); -++ /* MFCP MTCP */ -++ return MASK_OP (insn, 0x3ff); -++ default: -++ return MASK_OP (insn, 0xff); -++ } -++ } -++ else if (__GF (insn, 0, 2) == 0) -++ return MASK_OP (insn, 0xf); -++ return MASK_OP (insn, 0xcf); -+ case N32_OP6_AEXT: -+- /* AUDIO */ -+- switch (__GF (insn, 23, 2)) -+- { -+- case 0x0: -+- if (__GF (insn, 5, 4) == 0) -+- /* AMxxx AMAyyS AMyyS AMAWzS AMWzS */ -+- return MASK_OP (insn, (0x1f << 20) | 0x1ff); -+- else if (__GF (insn, 5, 4) == 1) -+- /* ALR ASR ALA ASA AUPI */ -+- return MASK_OP (insn, (0x1f << 20) | (0xf << 5)); -+- else if (__GF (insn, 20, 3) == 0 && __GF (insn, 6, 3) == 1) -+- /* ALR2 */ -+- return MASK_OP (insn, (0x1f << 20) | (0x7 << 6)); -+- else if (__GF (insn, 20 ,3) == 2 && __GF (insn, 6, 3) == 1) -+- /* AWEXT ASATS48 */ -+- return MASK_OP (insn, (0x1f << 20) | (0xf << 5)); -+- else if (__GF (insn, 20 ,3) == 3 && __GF (insn, 6, 3) == 1) -+- /* AMTAR AMTAR2 AMFAR AMFAR2 */ -+- return MASK_OP (insn, (0x1f << 20) | (0x1f << 5)); -+- else if (__GF (insn, 7, 2) == 3) -+- /* AMxxxSA */ -+- return MASK_OP (insn, (0x1f << 20) | (0x3 << 7)); -+- else if (__GF (insn, 6, 3) == 2) -+- /* AMxxxL.S */ -+- return MASK_OP (insn, (0x1f << 20) | (0xf << 5)); -+- else -+- /* AmxxxL.l AmxxxL2.S AMxxxL2.L */ -+- return MASK_OP (insn, (0x1f << 20) | (0x7 << 6)); -+- case 0x1: -+- if (__GF (insn, 20, 3) == 0) -+- /* AADDL ASUBL */ -+- return MASK_OP (insn, (0x1f << 20) | (0x1 << 5)); -+- else if (__GF (insn, 20, 3) == 1) -+- /* AMTARI Ix AMTARI Mx */ -+- return MASK_OP (insn, (0x1f << 20)); -+- else if (__GF (insn, 6, 3) == 2) -+- /* AMAWzSl.S AMWzSl.S */ -+- return MASK_OP (insn, (0x1f << 20) | (0xf << 5)); -+- else if (__GF (insn, 7, 2) == 3) -+- /* AMAWzSSA AMWzSSA */ -+- return MASK_OP (insn, (0x1f << 20) | (0x3 << 7)); -+- else -+- /* AMAWzSL.L AMAWzSL2.S AMAWzSL2.L AMWzSL.L AMWzSL.L AMWzSL2.S */ -+- return MASK_OP (insn, (0x1f << 20) | (0x7 << 6)); -+- case 0x2: -+- if (__GF (insn, 6, 3) == 2) -+- /* AMAyySl.S AMWyySl.S */ -+- return MASK_OP (insn, (0x1f << 20) | (0xf << 5)); -+- else if (__GF (insn, 7, 2) == 3) -+- /* AMAWyySSA AMWyySSA */ -+- return MASK_OP (insn, (0x1f << 20) | (0x3 << 7)); -+- else -+- /* AMAWyySL.L AMAWyySL2.S AMAWyySL2.L AMWyySL.L AMWyySL.L AMWyySL2.S */ -+- return MASK_OP (insn, (0x1f << 20) | (0x7 << 6)); -+- } -+- return MASK_OP (insn, 0x1f << 20); -++ /* AUDIO */ -++ switch (__GF (insn, 23, 2)) -++ { -++ case 0x0: -++ if (__GF (insn, 5, 4) == 0) -++ /* AMxxx AMAyyS AMyyS AMAWzS AMWzS */ -++ return MASK_OP (insn, (0x1f << 20) | 0x1ff); -++ else if (__GF (insn, 5, 4) == 1) -++ /* ALR ASR ALA ASA AUPI */ -++ return MASK_OP (insn, (0x1f << 20) | (0xf << 5)); -++ else if (__GF (insn, 20, 3) == 0 && __GF (insn, 6, 3) == 1) -++ /* ALR2 */ -++ return MASK_OP (insn, (0x1f << 20) | (0x7 << 6)); -++ else if (__GF (insn, 20 ,3) == 2 && __GF (insn, 6, 3) == 1) -++ /* AWEXT ASATS48 */ -++ return MASK_OP (insn, (0x1f << 20) | (0xf << 5)); -++ else if (__GF (insn, 20 ,3) == 3 && __GF (insn, 6, 3) == 1) -++ /* AMTAR AMTAR2 AMFAR AMFAR2 */ -++ return MASK_OP (insn, (0x1f << 20) | (0x1f << 5)); -++ else if (__GF (insn, 7, 2) == 3) -++ /* AMxxxSA */ -++ return MASK_OP (insn, (0x1f << 20) | (0x3 << 7)); -++ else if (__GF (insn, 6, 3) == 2) -++ /* AMxxxL.S */ -++ return MASK_OP (insn, (0x1f << 20) | (0xf << 5)); -++ else -++ /* AmxxxL.l AmxxxL2.S AMxxxL2.L */ -++ return MASK_OP (insn, (0x1f << 20) | (0x7 << 6)); -++ case 0x1: -++ if (__GF (insn, 20, 3) == 0) -++ /* AADDL ASUBL */ -++ return MASK_OP (insn, (0x1f << 20) | (0x1 << 5)); -++ else if (__GF (insn, 20, 3) == 1) -++ /* AMTARI Ix AMTARI Mx */ -++ return MASK_OP (insn, (0x1f << 20)); -++ else if (__GF (insn, 6, 3) == 2) -++ /* AMAWzSl.S AMWzSl.S */ -++ return MASK_OP (insn, (0x1f << 20) | (0xf << 5)); -++ else if (__GF (insn, 7, 2) == 3) -++ /* AMAWzSSA AMWzSSA */ -++ return MASK_OP (insn, (0x1f << 20) | (0x3 << 7)); -++ else -++ /* AMAWzSL.L AMAWzSL2.S AMAWzSL2.L AMWzSL.L AMWzSL.L AMWzSL2.S */ -++ return MASK_OP (insn, (0x1f << 20) | (0x7 << 6)); -++ case 0x2: -++ if (__GF (insn, 6, 3) == 2) -++ /* AMAyySl.S AMWyySl.S */ -++ return MASK_OP (insn, (0x1f << 20) | (0xf << 5)); -++ else if (__GF (insn, 7, 2) == 3) -++ /* AMAWyySSA AMWyySSA */ -++ return MASK_OP (insn, (0x1f << 20) | (0x3 << 7)); -++ else -++ /* AMAWyySL.L AMAWyySL2.S AMAWyySL2.L AMWyySL.L AMWyySL.L AMWyySL2.S */ -++ return MASK_OP (insn, (0x1f << 20) | (0x7 << 6)); -++ } -++ return MASK_OP (insn, 0x1f << 20); -+ default: -+ return (1 << 31); -+ } -+@@ -971,11 +942,6 @@ nds32_special_opcode (uint32_t insn, struct nds32_opcode **opc) -+ break; -+ case N32_OP6_COP: -+ break; -+- case 0xea00: -+- /* break16 ex9 */ -+- if (__GF (insn, 5, 4) != 0) -+- string = "ex9"; -+- break; -+ case 0x9200: -+ /* nop16 */ -+ if (__GF (insn, 0, 9) == 0) -+@@ -1005,46 +971,195 @@ print_insn_nds32 (bfd_vma pc, disassemble_info *info) -+ { -+ int status; -+ bfd_byte buf[4]; -++ bfd_byte buf_data[16]; -++ long long given; -++ long long given1; -+ uint32_t insn; -+- static int init = 1; -+- int i = 0; -+- struct nds32_opcode *opc; -+- struct nds32_opcode **slot; -++ int n; -++ int last_symbol_index = -1; -++ bfd_vma addr; -++ int is_data = FALSE; -++ bfd_boolean found = FALSE; -++ struct nds32_private_data *private_data; -++ unsigned int size = 16; -++ enum map_type mapping_type = MAP_CODE; -++ -++ if (info->private_data == NULL) -++ { -++ /* Note: remain lifecycle throughout whole execution. */ -++ static struct nds32_private_data private; -++ private.has_mapping_symbols = -1; /* unknown yet. */ -++ private.last_symbol_index = -1; -++ private.last_addr = 0; -++ info->private_data = &private; -++ } -++ private_data = info->private_data; -+ -+- if (init) -++ if (info->symtab_size != 0) -+ { -+- /* Build opcode table. */ -+- opcode_htab = htab_create_alloc (1024, htab_hash_hash, htab_hash_eq, -+- NULL, xcalloc, free); -++ int start; -++ if (pc == 0) -++ start = 0; -++ else -++ { -++ start = info->symtab_pos; -++ if (start < private_data->last_symbol_index) -++ start = private_data->last_symbol_index; -++ } -+ -+- while (nds32_opcodes[i].opcode != NULL) -++ if (0 > start) -++ start = 0; -++ -++ if (private_data->has_mapping_symbols != 0 -++ && ((strncmp (".text", info->section->name, 5) == 0))) -+ { -+- opc = &nds32_opcodes[i]; -+- slot = -+- (struct nds32_opcode **) htab_find_slot (opcode_htab, &opc->value, -+- INSERT); -+- if (*slot == NULL) -++ for (n = start; n < info->symtab_size; n++) -+ { -+- /* This is the new one. */ -+- *slot = opc; -++ addr = bfd_asymbol_value (info->symtab[n]); -++ if (addr > pc) -++ break; -++ if (get_mapping_symbol_type (info, n, &mapping_type)) -++ { -++ last_symbol_index = n; -++ found = TRUE; -++ } -+ } -+- else -++ -++ if (found) -++ private_data->has_mapping_symbols = 1; -++ else if (!found && private_data->has_mapping_symbols == -1) -++ { -++ /* Make sure there are no any mapping symbol. */ -++ for (n = 0; n < info->symtab_size; n++) -++ { -++ if (is_mapping_symbol (info, n, &mapping_type)) -++ { -++ private_data->has_mapping_symbols = -1; -++ break; -++ } -++ } -++ if (private_data->has_mapping_symbols == -1) -++ private_data->has_mapping_symbols = 0; -++ -++ } -++ -++ private_data->last_symbol_index = last_symbol_index; -++ private_data->last_mapping_type = mapping_type; -++ is_data = (private_data->last_mapping_type == MAP_DATA0 -++ || private_data->last_mapping_type == MAP_DATA1 -++ || private_data->last_mapping_type == MAP_DATA2 -++ || private_data->last_mapping_type == MAP_DATA3 -++ || private_data->last_mapping_type == MAP_DATA4); -++ } -++ } -++ -++ /* Wonder data or instruction. */ -++ if (is_data) -++ { -++ unsigned int i1; -++ -++ /* fix corner case: there is no next mapping symbol, -++ * let mapping type decides size */ -++ if (last_symbol_index + 1 >= info->symtab_size) -++ { -++ if (mapping_type == MAP_DATA0) -++ size = 1; -++ if (mapping_type == MAP_DATA1) -++ size = 2; -++ if (mapping_type == MAP_DATA2) -++ size = 4; -++ if (mapping_type == MAP_DATA3) -++ size = 8; -++ if (mapping_type == MAP_DATA4) -++ size = 16; -++ } -++ for (n = last_symbol_index + 1; n < info->symtab_size; n++) -++ { -++ addr = bfd_asymbol_value (info->symtab[n]); -++ -++ enum map_type fake_mapping_type; -++ if (get_mapping_symbol_type (info, n, &fake_mapping_type)) -++ { -++ if (addr > pc -++ && ((info->section == NULL) -++ || (info->section == info->symtab[n]->section))) -++ { -++ if (addr - pc < size) -++ { -++ size = addr - pc; -++ break; -++ } -++ } -++ } -++ } -++ -++ -++ if (size == 3) -++ size = (pc & 1) ? 1 : 2; -++ -++ -++ /* Read bytes from BFD. */ -++ info->read_memory_func (pc, (bfd_byte *) buf_data, size, info); -++ given = 0; -++ given1 = 0; -++ /* Start assembling data. */ -++ /* Little endian of data. */ -++ if (info->endian == BFD_ENDIAN_LITTLE) -++ { -++ for (i1 = size - 1;; i1--) -+ { -+- /* Already exists. Append to the list. */ -+- opc = *slot; -+- while (opc->next) -+- opc = opc->next; -+- opc->next = &nds32_opcodes[i]; -++ if (i1 >= 8) -++ given1 = buf_data[i1] | (given1 << 8); -++ else -++ given = buf_data[i1] | (given << 8); -++ if (i1 == 0) -++ break; -+ } -+- i++; -+ } -+- init = 0; -++ else -++ { -++ /* Big endian of data. */ -++ for (i1 = 0; i1 < size; i1++) { -++ if (i1 <= 7) -++ given = buf_data[i1] | (given << 8); -++ else -++ given1 = buf_data[i1] | (given1 << 8); -++ } -++ } -++ -++ info->bytes_per_line = 4; -++ -++ if (size == 16) -++ { -++ info->fprintf_func (info->stream, ".qword\t0x%016llx%016llx", -++ given, given1); -++ } -++ else if (size == 8) -++ { -++ info->fprintf_func (info->stream, ".dword\t0x%016llx", given); -++ } -++ else if (size == 4) -++ { -++ info->fprintf_func (info->stream, ".word\t0x%08llx", given); -++ } -++ else if (size == 2) /* short */ -++ { -++ if (mapping_type == MAP_DATA0) -++ info->fprintf_func (info->stream, ".byte\t0x%02llx", given & 0xFF); -++ else -++ info->fprintf_func (info->stream, ".short\t0x%04llx", given); -++ } -++ else -++ { /* byte */ -++ info->fprintf_func (info->stream, ".byte\t0x%02llx", given); -++ } -++ return size; -+ } -+ -+ status = info->read_memory_func (pc, (bfd_byte *) buf, 4, info); -+ if (status) -+ { -+- /* for the last 16-bit instruction. */ -++ /* For the last 16-bit instruction. */ -+ status = info->read_memory_func (pc, (bfd_byte *) buf, 2, info); -+ if (status) -+ { -+@@ -1052,17 +1167,10 @@ print_insn_nds32 (bfd_vma pc, disassemble_info *info) -+ return -1; -+ } -+ } -+- -+ insn = bfd_getb32 (buf); -+ /* 16-bit instruction. */ -+ if (insn & 0x80000000) -+ { -+- if (info->section && strstr (info->section->name, ".ex9.itable") != NULL) -+- { -+- print_insn16 (pc, info, (insn & 0x0000FFFF), -+- NDS32_PARSE_INSN16 | NDS32_PARSE_EX9TAB); -+- return 4; -+- } -+ print_insn16 (pc, info, (insn >> 16), NDS32_PARSE_INSN16); -+ return 2; -+ } -+@@ -1070,11 +1178,206 @@ print_insn_nds32 (bfd_vma pc, disassemble_info *info) -+ /* 32-bit instructions. */ -+ else -+ { -+- if (info->section -+- && strstr (info->section->name, ".ex9.itable") != NULL) -+- print_insn32 (pc, info, insn, NDS32_PARSE_INSN32 | NDS32_PARSE_EX9TAB); -+- else -+- print_insn32 (pc, info, insn, NDS32_PARSE_INSN32); -++ print_insn32 (pc, info, insn, NDS32_PARSE_INSN32); -+ return 4; -+ } -+ } -++ -++/* Ignore disassembling unnecessary name. */ -++ -++static bfd_boolean -++nds32_symbol_is_valid (asymbol *sym, -++ struct disassemble_info *info ATTRIBUTE_UNUSED) -++{ -++ const char *name; -++ -++ if (sym == NULL) -++ return FALSE; -++ -++ name = bfd_asymbol_name (sym); -++ -++ /* Mapping symbol is invalid. */ -++ if (name[0] == '$') -++ return FALSE; -++ return TRUE; -++} -++ -++static void -++nds32_add_opcode_hash_table (unsigned indx) -++{ -++ opcode_t *opc; -++ -++ opc = nds32_opcode_table[indx]; -++ if (opc == NULL) -++ return; -++ -++ while (opc->opcode != NULL) -++ { -++ opcode_t **slot; -++ -++ slot = (opcode_t **) htab_find_slot (opcode_htab, &opc->value, INSERT); -++ if (*slot == NULL) -++ { -++ /* This is the new one. */ -++ *slot = opc; -++ } -++ else -++ { -++ opcode_t *tmp; -++ -++ /* Already exists. Append to the list. */ -++ tmp = *slot; -++ while (tmp->next) -++ tmp = tmp->next; -++ tmp->next = opc; -++ opc->next = NULL; -++ } -++ opc++; -++ } -++} -++ -++void -++disassemble_init_nds32 (struct disassemble_info *info) -++{ -++ static unsigned init_done = 0; -++ const char *ptr; -++ unsigned k; -++ -++ /* Set up symbol checking function. */ -++ info->symbol_is_valid = nds32_symbol_is_valid; -++ -++ /* Only need to initialize once: */ -++ /* High level will call this function for every object file. */ -++ /* For example, when disassemble all members of a library. */ -++ if (init_done) -++ return; -++ -++ /* Setup main core. */ -++ nds32_keyword_table[NDS32_MAIN_CORE] = &keywords[0]; -++ nds32_opcode_table[NDS32_MAIN_CORE] = &nds32_opcodes[0]; -++ nds32_field_table[NDS32_MAIN_CORE] = &operand_fields[0]; -++ -++ /* Process command line options. */ -++ ptr = info->disassembler_options; -++ if (ptr != NULL) -++ { -++ const char *start, *end; -++ do -++ { -++ char name[256]; -++ -++ /* Get one option. */ -++ start = strchr(ptr, '='); -++ end = strchr(ptr, ','); -++ if (start == NULL) -++ fprintf (stderr, "Unknown nds32 disassembler option: %s\n", ptr); -++ else -++ { -++ start++; -++ if (end == NULL) -++ strcpy (name, start); -++ else -++ strncpy (name, start, end - start); -++ -++ /* Parse and process the option. */ -++ if (strncmp (ptr, "ace=", 4) == 0) -++ nds32_parse_udi (name); -++ else if (strncmp (ptr, "cop0=", 5) == 0) -++ nds32_parse_cop0 (name); -++ else if (strncmp (ptr, "cop1=", 5) == 0) -++ nds32_parse_cop1 (name); -++ else if (strncmp (ptr, "cop2=", 5) == 0) -++ nds32_parse_cop2 (name); -++ else if (strncmp (ptr, "cop3=", 5) == 0) -++ nds32_parse_cop3 (name); -++ else -++ fprintf (stderr, "Unknown nds32 disassembler option: %s\n", -++ ptr); -++ -++ if (end == NULL) -++ break; -++ ptr = end + 1; -++ } -++ } while (1); -++ } -++ -++ /* Build opcode table. */ -++ opcode_htab = htab_create_alloc (1024, htab_hash_hash, htab_hash_eq, NULL, -++ xcalloc, free); -++ -++ for (k = 0; k < NDS32_CORE_COUNT; k++) -++ { -++ /* Add op-codes. */ -++ nds32_add_opcode_hash_table (k); -++ } -++ -++ init_done = 1; -++} -++ -++static int -++is_mapping_symbol (struct disassemble_info *info, int n, -++ enum map_type *map_type) -++{ -++ const char *name = NULL; -++ -++ /* Get symbol name. */ -++ name = bfd_asymbol_name (info->symtab[n]); -++ -++ if (name[1] == 'c') -++ { -++ *map_type = MAP_CODE; -++ return TRUE; -++ } -++ else if (name[1] == 'd' && name[2] == '0') -++ { -++ *map_type = MAP_DATA0; -++ return TRUE; -++ } -++ else if (name[1] == 'd' && name[2] == '1') -++ { -++ *map_type = MAP_DATA1; -++ return TRUE; -++ } -++ else if (name[1] == 'd' && name[2] == '2') -++ { -++ *map_type = MAP_DATA2; -++ return TRUE; -++ } -++ else if (name[1] == 'd' && name[2] == '3') -++ { -++ *map_type = MAP_DATA3; -++ return TRUE; -++ } -++ else if (name[1] == 'd' && name[2] == '4') -++ { -++ *map_type = MAP_DATA4; -++ return TRUE; -++ } -++ -++ return FALSE; -++} -++ -++static int -++get_mapping_symbol_type (struct disassemble_info *info, int n, -++ enum map_type *map_type) -++{ -++ /* If the symbol is in a different section, ignore it. */ -++ if (info->section != NULL && info->section != info->symtab[n]->section) -++ return FALSE; -++ -++ return is_mapping_symbol (info, n, map_type); -++} -++ -++void -++print_nds32_disassembler_options (FILE *stream) -++{ -++ fprintf (stream, _("\n\ -++The following Andes specific disassembler options are supported for use with\n\ -++the -M switch:\n")); -++ -++ fprintf (stream, " ace= Support user defined instruction extension\n"); -++ fprintf (stream, " cop0= Support coprocessor 0 extension\n"); -++ fprintf (stream, " cop1= Support coprocessor 1 extension\n"); -++ fprintf (stream, " cop2= Support coprocessor 2 extension\n"); -++ fprintf (stream, " cop3= Support coprocessor 3 extension\n\n"); -++} -diff --git a/util/crossgcc/patches/binutils-2.29.1_no-bfd-doc.patch b/util/crossgcc/patches/binutils-2.30_no-bfd-doc.patch -similarity index 100% -rename from util/crossgcc/patches/binutils-2.29.1_no-bfd-doc.patch -rename to util/crossgcc/patches/binutils-2.30_no-bfd-doc.patch -diff --git a/util/crossgcc/patches/gcc-6.3.0_ada-raise.patch b/util/crossgcc/patches/gcc-6.3.0_ada-raise.patch -deleted file mode 100644 -index a081957615..0000000000 ---- a/util/crossgcc/patches/gcc-6.3.0_ada-raise.patch -+++ /dev/null -@@ -1,11 +0,0 @@ ----- gcc-6.3.0/gcc/ada/raise.c.orig 2017-06-24 07:06:41.524685169 +0200 --+++ gcc-6.3.0/gcc/ada/raise.c 2017-06-24 07:07:12.945162120 +0200 --@@ -55,7 +55,7 @@ -- void -- _gnat_builtin_longjmp (void *ptr, int flag ATTRIBUTE_UNUSED) -- { --- __builtin_longjmp (ptr, 1); --+ __builtin_longjmp ((void **)ptr, 1); -- } -- #endif -- -diff --git a/util/crossgcc/patches/gcc-6.3.0_elf_biarch.patch b/util/crossgcc/patches/gcc-6.3.0_elf_biarch.patch -deleted file mode 100644 -index 226aed941f..0000000000 ---- a/util/crossgcc/patches/gcc-6.3.0_elf_biarch.patch -+++ /dev/null -@@ -1,87 +0,0 @@ --diff -urN gcc-4.9.2/gcc/config/i386/t-elf64 gcc-4.9.2/gcc/config/i386/t-elf64 ----- gcc-4.9.2/gcc/config/i386/t-elf64 1969-12-31 16:00:00.000000000 -0800 --+++ gcc-6.1.0/gcc/config/i386/t-elf64 2015-06-17 11:20:08.032513005 -0700 --@@ -0,0 +1,38 @@ --+# Copyright (C) 2002-2014 Free Software Foundation, Inc. --+# --+# This file is part of GCC. --+# --+# GCC is free software; you can redistribute it and/or modify --+# it under the terms of the GNU General Public License as published by --+# the Free Software Foundation; either version 3, or (at your option) --+# any later version. --+# --+# GCC is distributed in the hope that it will be useful, --+# but WITHOUT ANY WARRANTY; without even the implied warranty of --+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the --+# GNU General Public License for more details. --+# --+# You should have received a copy of the GNU General Public License --+# along with GCC; see the file COPYING3. If not see --+# . --+ --+# On Debian, Ubuntu and other derivative distributions, the 32bit libraries --+# are found in /lib32 and /usr/lib32, /lib64 and /usr/lib64 are symlinks to --+# /lib and /usr/lib, while other distributions install libraries into /lib64 --+# and /usr/lib64. The LSB does not enforce the use of /lib64 and /usr/lib64, --+# it doesn't tell anything about the 32bit libraries on those systems. Set --+# MULTILIB_OSDIRNAMES according to what is found on the target. --+ --+# To support i386, x86-64 and x32 libraries, the directory structrue --+# should be: --+# --+# /lib has i386 libraries. --+# /lib64 has x86-64 libraries. --+# /libx32 has x32 libraries. --+# --+comma=, --+MULTILIB_OPTIONS = $(subst $(comma),/,$(TM_MULTILIB_CONFIG)) --+MULTILIB_DIRNAMES = $(patsubst m%, %, $(subst /, ,$(MULTILIB_OPTIONS))) --+MULTILIB_OSDIRNAMES = m64=../lib64$(call if_multiarch,:x86_64-elf) --+MULTILIB_OSDIRNAMES+= m32=$(if $(wildcard $(shell echo $(SYSTEM_HEADER_DIR))/../../usr/lib32),../lib32,../lib)$(call if_multiarch,:i386-elf) --+MULTILIB_OSDIRNAMES+= mx32=../libx32$(call if_multiarch,:x86_64-elf-x32) --diff -urN gcc-4.9.2/gcc/config.gcc gcc-4.9.2/gcc/config.gcc ----- gcc-4.9.2/gcc/config.gcc 2015-06-17 11:20:57.841008182 -0700 --+++ gcc-6.1.0/gcc/config.gcc 2015-06-17 11:17:24.818890200 -0700 --@@ -1353,6 +1353,30 @@ -- ;; -- x86_64-*-elf*) -- tm_file="${tm_file} i386/unix.h i386/att.h dbxelf.h elfos.h newlib-stdint.h i386/i386elf.h i386/x86-64.h" --+ tmake_file="${tmake_file} i386/t-elf64" --+ x86_multilibs="${with_multilib_list}" --+ if test "$x86_multilibs" = "default"; then --+ case ${with_abi} in --+ x32 | mx32) --+ x86_multilibs="mx32" --+ ;; --+ *) --+ x86_multilibs="m64,m32" --+ ;; --+ esac --+ fi --+ x86_multilibs=`echo $x86_multilibs | sed -e 's/,/ /g'` --+ for x86_multilib in ${x86_multilibs}; do --+ case ${x86_multilib} in --+ m32 | m64 | mx32) --+ TM_MULTILIB_CONFIG="${TM_MULTILIB_CONFIG},${x86_multilib}" --+ ;; --+ *) --+ echo "--with-multilib-list=${x86_with_multilib} not supported." --+ exit 1 --+ esac --+ done --+ TM_MULTILIB_CONFIG=`echo $TM_MULTILIB_CONFIG | sed 's/^,//'` -- ;; -- i[34567]86-*-rdos*) -- tm_file="${tm_file} i386/unix.h i386/att.h dbxelf.h elfos.h newlib-stdint.h i386/i386elf.h i386/rdos.h" ----- gcc-6.1.0/gcc/config/i386/x86-64.h.orig 2015-08-20 17:17:34.555919593 +0200 --+++ gcc-6.1.0/gcc/config/i386/x86-64.h 2015-08-20 17:17:42.615908670 +0200 --@@ -49,7 +49,7 @@ -- #define WCHAR_TYPE_SIZE 32 -- -- #undef ASM_SPEC ---#define ASM_SPEC "%{m32:--32} %{m64:--64} %{mx32:--x32}" --+#define ASM_SPEC "%{m16|m32:--32} %{m64:--64} %{mx32:--x32}" -- -- #undef ASM_OUTPUT_ALIGNED_BSS -- #define ASM_OUTPUT_ALIGNED_BSS(FILE, DECL, NAME, SIZE, ALIGN) \ -diff --git a/util/crossgcc/patches/gcc-6.3.0_memmodel.patch b/util/crossgcc/patches/gcc-6.3.0_memmodel.patch -deleted file mode 100644 -index 62428c5857..0000000000 ---- a/util/crossgcc/patches/gcc-6.3.0_memmodel.patch -+++ /dev/null -@@ -1,416 +0,0 @@ --commit ea36272bdc2602a690019b9612d23594571d3d2b --Author: thopre01 --Date: Mon Sep 26 17:20:39 2016 +0000 -- -- 2016-09-26 Thomas Preud'homme -- -- gcc/ -- * tree.h (memmodel_from_int, memmodel_base, is_mm_relaxed, -- is_mm_consume, is_mm_acquire, is_mm_release, is_mm_acq_rel, -- is_mm_seq_cst, is_mm_sync): Move to ... -- * memmodel.h: This. New file. -- * builtins.c: Include memmodel.h. -- * optabs.c: Likewise. -- * tsan.c: Likewise. -- * config/aarch64/aarch64.c: Likewise. -- * config/alpha/alpha.c: Likewise. -- * config/arm/arm.c: Likewise. -- * config/i386/i386.c: Likewise. -- * config/ia64/ia64.c: Likewise. -- * config/mips/mips.c: Likewise. -- * config/rs6000/rs6000.c: Likewise. -- * config/sparc/sparc.c: Likewise. -- * genconditions.c: Include memmodel.h in generated file. -- * genemit.c: Likewise. -- * genoutput.c: Likewise. -- * genpeep.c: Likewise. -- * genpreds.c: Likewise. -- * genrecog.c: Likewise. -- -- gcc/c-family/ -- * c-common.c: Include memmodel.h. -- -- git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@240504 138bc75d-0d04-0410-961f-82ee72b054a4 -- --diff --git a/gcc/builtins.c b/gcc/builtins.c --index 93cbe15ad3c..04dcf95acd2 100644 ----- a/gcc/builtins.c --+++ b/gcc/builtins.c --@@ -28,6 +28,7 @@ along with GCC; see the file COPYING3. If not see -- #include "target.h" -- #include "rtl.h" -- #include "tree.h" --+#include "memmodel.h" -- #include "gimple.h" -- #include "predict.h" -- #include "tm_p.h" --diff --git a/gcc/c-family/c-common.c b/gcc/c-family/c-common.c --index e9f619fd3af..2652259a312 100644 ----- a/gcc/c-family/c-common.c --+++ b/gcc/c-family/c-common.c --@@ -25,6 +25,7 @@ along with GCC; see the file COPYING3. If not see -- #include "target.h" -- #include "function.h" -- #include "tree.h" --+#include "memmodel.h" -- #include "c-common.h" -- #include "gimple-expr.h" -- #include "tm_p.h" --diff --git a/gcc/config/aarch64/aarch64.c b/gcc/config/aarch64/aarch64.c --index 6078b163548..c65b826b0cc 100644 ----- a/gcc/config/aarch64/aarch64.c --+++ b/gcc/config/aarch64/aarch64.c --@@ -26,6 +26,7 @@ -- #include "target.h" -- #include "rtl.h" -- #include "tree.h" --+#include "memmodel.h" -- #include "gimple.h" -- #include "cfghooks.h" -- #include "cfgloop.h" --diff --git a/gcc/config/alpha/alpha.c b/gcc/config/alpha/alpha.c --index 6d4af04dd7d..d646879e7e8 100644 ----- a/gcc/config/alpha/alpha.c --+++ b/gcc/config/alpha/alpha.c --@@ -26,6 +26,7 @@ along with GCC; see the file COPYING3. If not see -- #include "target.h" -- #include "rtl.h" -- #include "tree.h" --+#include "memmodel.h" -- #include "gimple.h" -- #include "df.h" -- #include "tm_p.h" --diff --git a/gcc/config/arm/arm.c b/gcc/config/arm/arm.c --index 619c3291c87..feb54cbc64a 100644 ----- a/gcc/config/arm/arm.c --+++ b/gcc/config/arm/arm.c --@@ -27,6 +27,7 @@ -- #include "target.h" -- #include "rtl.h" -- #include "tree.h" --+#include "memmodel.h" -- #include "cfghooks.h" -- #include "df.h" -- #include "tm_p.h" --diff --git a/gcc/config/i386/i386.c b/gcc/config/i386/i386.c --index 143b905a341..01e2ad8e1b2 100644 ----- a/gcc/config/i386/i386.c --+++ b/gcc/config/i386/i386.c --@@ -23,6 +23,7 @@ along with GCC; see the file COPYING3. If not see -- #include "backend.h" -- #include "rtl.h" -- #include "tree.h" --+#include "memmodel.h" -- #include "gimple.h" -- #include "cfghooks.h" -- #include "cfgloop.h" --diff --git a/gcc/config/ia64/ia64.c b/gcc/config/ia64/ia64.c --index 5f0bf43a103..573872eb85f 100644 ----- a/gcc/config/ia64/ia64.c --+++ b/gcc/config/ia64/ia64.c --@@ -26,6 +26,7 @@ along with GCC; see the file COPYING3. If not see -- #include "target.h" -- #include "rtl.h" -- #include "tree.h" --+#include "memmodel.h" -- #include "cfghooks.h" -- #include "df.h" -- #include "tm_p.h" --diff --git a/gcc/config/mips/mips.c b/gcc/config/mips/mips.c --index 88f4038224a..3586a1001e7 100644 ----- a/gcc/config/mips/mips.c --+++ b/gcc/config/mips/mips.c --@@ -28,6 +28,7 @@ along with GCC; see the file COPYING3. If not see -- #include "target.h" -- #include "rtl.h" -- #include "tree.h" --+#include "memmodel.h" -- #include "gimple.h" -- #include "cfghooks.h" -- #include "df.h" --diff --git a/gcc/config/rs6000/rs6000.c b/gcc/config/rs6000/rs6000.c --index d76f479d9e5..6897b5c260d 100644 ----- a/gcc/config/rs6000/rs6000.c --+++ b/gcc/config/rs6000/rs6000.c --@@ -24,6 +24,7 @@ -- #include "backend.h" -- #include "rtl.h" -- #include "tree.h" --+#include "memmodel.h" -- #include "gimple.h" -- #include "cfghooks.h" -- #include "cfgloop.h" --diff --git a/gcc/config/sparc/sparc.c b/gcc/config/sparc/sparc.c --index 5efed3dc52f..5936f96bd80 100644 ----- a/gcc/config/sparc/sparc.c --+++ b/gcc/config/sparc/sparc.c --@@ -27,6 +27,7 @@ along with GCC; see the file COPYING3. If not see -- #include "target.h" -- #include "rtl.h" -- #include "tree.h" --+#include "memmodel.h" -- #include "gimple.h" -- #include "df.h" -- #include "tm_p.h" --diff --git a/gcc/genconditions.c b/gcc/genconditions.c --index e4f45b097cd..d8b0ebba56b 100644 ----- a/gcc/genconditions.c --+++ b/gcc/genconditions.c --@@ -94,6 +94,7 @@ write_header (void) -- #include \"resource.h\"\n\ -- #include \"diagnostic-core.h\"\n\ -- #include \"reload.h\"\n\ --+#include \"memmodel.h\"\n\ -- #include \"tm-constrs.h\"\n"); -- -- if (saw_eh_return) --diff --git a/gcc/genemit.c b/gcc/genemit.c --index 33040aac36d..d5e07a97a6d 100644 ----- a/gcc/genemit.c --+++ b/gcc/genemit.c --@@ -792,6 +792,7 @@ from the machine description file `md'. */\n\n"); -- printf ("#include \"reload.h\"\n"); -- printf ("#include \"diagnostic-core.h\"\n"); -- printf ("#include \"regs.h\"\n"); --+ printf ("#include \"memmodel.h\"\n"); -- printf ("#include \"tm-constrs.h\"\n"); -- printf ("#include \"ggc.h\"\n"); -- printf ("#include \"dumpfile.h\"\n"); --diff --git a/gcc/genoutput.c b/gcc/genoutput.c --index f8c25ac4df0..59092580e49 100644 ----- a/gcc/genoutput.c --+++ b/gcc/genoutput.c --@@ -231,6 +231,7 @@ output_prologue (void) -- printf ("#include \"diagnostic-core.h\"\n"); -- printf ("#include \"output.h\"\n"); -- printf ("#include \"target.h\"\n"); --+ printf ("#include \"memmodel.h\"\n"); -- printf ("#include \"tm-constrs.h\"\n"); -- } -- --diff --git a/gcc/genpeep.c b/gcc/genpeep.c --index 132cdced690..e1997e03e47 100644 ----- a/gcc/genpeep.c --+++ b/gcc/genpeep.c --@@ -373,6 +373,7 @@ from the machine description file `md'. */\n\n"); -- printf ("#include \"except.h\"\n"); -- printf ("#include \"diagnostic-core.h\"\n"); -- printf ("#include \"flags.h\"\n"); --+ printf ("#include \"memmodel.h\"\n"); -- printf ("#include \"tm-constrs.h\"\n\n"); -- -- printf ("extern rtx peep_operand[];\n\n"); --diff --git a/gcc/genpreds.c b/gcc/genpreds.c --index d18ebd2ab5a..6db1b7b0301 100644 ----- a/gcc/genpreds.c --+++ b/gcc/genpreds.c --@@ -1580,6 +1580,7 @@ write_insn_preds_c (void) -- #include \"reload.h\"\n\ -- #include \"regs.h\"\n\ -- #include \"emit-rtl.h\"\n\ --+#include \"memmodel.h\"\n\ -- #include \"tm-constrs.h\"\n"); -- -- FOR_ALL_PREDICATES (p) --diff --git a/gcc/genrecog.c b/gcc/genrecog.c --index 056798c82f7..77861074492 100644 ----- a/gcc/genrecog.c --+++ b/gcc/genrecog.c --@@ -4192,6 +4192,7 @@ write_header (void) -- #include \"diagnostic-core.h\"\n\ -- #include \"reload.h\"\n\ -- #include \"regs.h\"\n\ --+#include \"memmodel.h\"\n\ -- #include \"tm-constrs.h\"\n\ -- \n"); -- --diff --git a/gcc/memmodel.h b/gcc/memmodel.h --new file mode 100644 --index 00000000000..d53eb7bc9d9 ----- /dev/null --+++ b/gcc/memmodel.h --@@ -0,0 +1,86 @@ --+/* Prototypes of memory model helper functions. --+ Copyright (C) 2015-2016 Free Software Foundation, Inc. --+ --+This file is part of GCC. --+ --+GCC is free software; you can redistribute it and/or modify it under --+the terms of the GNU General Public License as published by the Free --+Software Foundation; either version 3, or (at your option) any later --+version. --+ --+GCC is distributed in the hope that it will be useful, but WITHOUT ANY --+WARRANTY; without even the implied warranty of MERCHANTABILITY or --+FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License --+for more details. --+ --+You should have received a copy of the GNU General Public License --+along with GCC; see the file COPYING3. If not see --+. */ --+ --+#ifndef GCC_MEMMODEL_H --+#define GCC_MEMMODEL_H --+ --+/* Return the memory model from a host integer. */ --+static inline enum memmodel --+memmodel_from_int (unsigned HOST_WIDE_INT val) --+{ --+ return (enum memmodel) (val & MEMMODEL_MASK); --+} --+ --+/* Return the base memory model from a host integer. */ --+static inline enum memmodel --+memmodel_base (unsigned HOST_WIDE_INT val) --+{ --+ return (enum memmodel) (val & MEMMODEL_BASE_MASK); --+} --+ --+/* Return TRUE if the memory model is RELAXED. */ --+static inline bool --+is_mm_relaxed (enum memmodel model) --+{ --+ return (model & MEMMODEL_BASE_MASK) == MEMMODEL_RELAXED; --+} --+ --+/* Return TRUE if the memory model is CONSUME. */ --+static inline bool --+is_mm_consume (enum memmodel model) --+{ --+ return (model & MEMMODEL_BASE_MASK) == MEMMODEL_CONSUME; --+} --+ --+/* Return TRUE if the memory model is ACQUIRE. */ --+static inline bool --+is_mm_acquire (enum memmodel model) --+{ --+ return (model & MEMMODEL_BASE_MASK) == MEMMODEL_ACQUIRE; --+} --+ --+/* Return TRUE if the memory model is RELEASE. */ --+static inline bool --+is_mm_release (enum memmodel model) --+{ --+ return (model & MEMMODEL_BASE_MASK) == MEMMODEL_RELEASE; --+} --+ --+/* Return TRUE if the memory model is ACQ_REL. */ --+static inline bool --+is_mm_acq_rel (enum memmodel model) --+{ --+ return (model & MEMMODEL_BASE_MASK) == MEMMODEL_ACQ_REL; --+} --+ --+/* Return TRUE if the memory model is SEQ_CST. */ --+static inline bool --+is_mm_seq_cst (enum memmodel model) --+{ --+ return (model & MEMMODEL_BASE_MASK) == MEMMODEL_SEQ_CST; --+} --+ --+/* Return TRUE if the memory model is a SYNC variant. */ --+static inline bool --+is_mm_sync (enum memmodel model) --+{ --+ return (model & MEMMODEL_SYNC); --+} --+ --+#endif /* GCC_MEMMODEL_H */ --diff --git a/gcc/optabs.c b/gcc/optabs.c --index e41747a630f..c5e9b4f8e13 100644 ----- a/gcc/optabs.c --+++ b/gcc/optabs.c --@@ -25,6 +25,7 @@ along with GCC; see the file COPYING3. If not see -- #include "target.h" -- #include "rtl.h" -- #include "tree.h" --+#include "memmodel.h" -- #include "predict.h" -- #include "tm_p.h" -- #include "expmed.h" --diff --git a/gcc/tree.h b/gcc/tree.h --index 0d9ad0198fa..563e6d9e287 100644 ----- a/gcc/tree.h --+++ b/gcc/tree.h --@@ -4675,69 +4675,6 @@ extern void warn_deprecated_use (tree, tree); -- extern void cache_integer_cst (tree); -- extern const char *combined_fn_name (combined_fn); -- ---/* Return the memory model from a host integer. */ ---static inline enum memmodel ---memmodel_from_int (unsigned HOST_WIDE_INT val) ---{ --- return (enum memmodel) (val & MEMMODEL_MASK); ---} --- ---/* Return the base memory model from a host integer. */ ---static inline enum memmodel ---memmodel_base (unsigned HOST_WIDE_INT val) ---{ --- return (enum memmodel) (val & MEMMODEL_BASE_MASK); ---} --- ---/* Return TRUE if the memory model is RELAXED. */ ---static inline bool ---is_mm_relaxed (enum memmodel model) ---{ --- return (model & MEMMODEL_BASE_MASK) == MEMMODEL_RELAXED; ---} --- ---/* Return TRUE if the memory model is CONSUME. */ ---static inline bool ---is_mm_consume (enum memmodel model) ---{ --- return (model & MEMMODEL_BASE_MASK) == MEMMODEL_CONSUME; ---} --- ---/* Return TRUE if the memory model is ACQUIRE. */ ---static inline bool ---is_mm_acquire (enum memmodel model) ---{ --- return (model & MEMMODEL_BASE_MASK) == MEMMODEL_ACQUIRE; ---} --- ---/* Return TRUE if the memory model is RELEASE. */ ---static inline bool ---is_mm_release (enum memmodel model) ---{ --- return (model & MEMMODEL_BASE_MASK) == MEMMODEL_RELEASE; ---} --- ---/* Return TRUE if the memory model is ACQ_REL. */ ---static inline bool ---is_mm_acq_rel (enum memmodel model) ---{ --- return (model & MEMMODEL_BASE_MASK) == MEMMODEL_ACQ_REL; ---} --- ---/* Return TRUE if the memory model is SEQ_CST. */ ---static inline bool ---is_mm_seq_cst (enum memmodel model) ---{ --- return (model & MEMMODEL_BASE_MASK) == MEMMODEL_SEQ_CST; ---} --- ---/* Return TRUE if the memory model is a SYNC variant. */ ---static inline bool ---is_mm_sync (enum memmodel model) ---{ --- return (model & MEMMODEL_SYNC); ---} --- -- /* Compare and hash for any structure which begins with a canonical -- pointer. Assumes all pointers are interchangeable, which is sort -- of already assumed by gcc elsewhere IIRC. */ --diff --git a/gcc/tsan.c b/gcc/tsan.c --index 91dbd41a0b4..cc194749665 100644 ----- a/gcc/tsan.c --+++ b/gcc/tsan.c --@@ -25,6 +25,7 @@ along with GCC; see the file COPYING3. If not see -- #include "backend.h" -- #include "rtl.h" -- #include "tree.h" --+#include "memmodel.h" -- #include "gimple.h" -- #include "tree-pass.h" -- #include "ssa.h" -diff --git a/util/crossgcc/patches/gcc-6.3.0_nds32_ite.patch b/util/crossgcc/patches/gcc-6.3.0_nds32_ite.patch -deleted file mode 100644 -index 50e39691b6..0000000000 ---- a/util/crossgcc/patches/gcc-6.3.0_nds32_ite.patch -+++ /dev/null -@@ -1,73397 +0,0 @@ --diff --git a/gcc/common.opt b/gcc/common.opt --index 67048db..e6f8fd3 100644 ----- a/gcc/common.opt --+++ b/gcc/common.opt --@@ -1281,7 +1281,7 @@ ffast-math -- Common -- -- ffat-lto-objects ---Common Var(flag_fat_lto_objects) --+Common Var(flag_fat_lto_objects) Init(1) -- Output lto objects containing both the intermediate language and binary output. -- -- ffinite-math-only --diff --git a/gcc/common/config/nds32/nds32-common.c b/gcc/common/config/nds32/nds32-common.c --index fb75956..66ea95c 100644 ----- a/gcc/common/config/nds32/nds32-common.c --+++ b/gcc/common/config/nds32/nds32-common.c --@@ -53,6 +53,16 @@ nds32_handle_option (struct gcc_options *opts ATTRIBUTE_UNUSED, -- -- return true; -- --+ case OPT_misr_secure_: --+ /* Check the valid security level: 0 1 2 3. */ --+ if (value < 0 || value > 3) --+ { --+ error_at (loc, "for the option -misr-secure=X, the valid X " --+ "must be: 0, 1, 2, or 3"); --+ return false; --+ } --+ return true; --+ -- case OPT_mcache_block_size_: -- /* Check valid value: 4 8 16 32 64 128 256 512. */ -- if (exact_log2 (value) < 2 || exact_log2 (value) > 9) --@@ -74,15 +84,69 @@ nds32_handle_option (struct gcc_options *opts ATTRIBUTE_UNUSED, -- /* Implement TARGET_OPTION_OPTIMIZATION_TABLE. */ -- static const struct default_options nds32_option_optimization_table[] = -- { --- /* Enable -fomit-frame-pointer by default at -O1 or higher. */ --- { OPT_LEVELS_1_PLUS, OPT_fomit_frame_pointer, NULL, 1 }, --+#ifdef TARGET_DEFAULT_NO_MATH_ERRNO --+ /* Under some configuration, we would like to use -fno-math-errno by default --+ at all optimization levels for performance and code size consideration. --+ Please check gcc/config.gcc for more implementation details. */ --+ { OPT_LEVELS_ALL, OPT_fmath_errno, NULL, 0 }, --+#endif --+#if TARGET_LINUX_ABI == 0 --+ /* Disable -fdelete-null-pointer-checks by default in ELF toolchain. */ --+ { OPT_LEVELS_ALL, OPT_fdelete_null_pointer_checks, --+ NULL, 0 }, --+#endif --+ /* Enable -fsched-pressure by default at -O1 and above. */ --+ { OPT_LEVELS_1_PLUS, OPT_fsched_pressure, NULL, 1 }, --+ /* Enable -fomit-frame-pointer by default at all optimization levels. */ --+ { OPT_LEVELS_ALL, OPT_fomit_frame_pointer, NULL, 1 }, --+ /* Enable -mrelax-hint by default at all optimization levels. */ --+ { OPT_LEVELS_ALL, OPT_mrelax_hint, NULL, 1 }, --+ /* Enable -mabi-compatible by default at all optimization levels. */ --+ { OPT_LEVELS_ALL, OPT_mabi_compatible, NULL, 1 }, --+ /* Enalbe -malways-align by default at -O1 and above, but not -Os or -Og. */ --+ { OPT_LEVELS_1_PLUS_SPEED_ONLY, OPT_malways_align, NULL, 1 }, -- /* Enable -mv3push by default at -Os, but it is useless under V2 ISA. */ --- { OPT_LEVELS_SIZE, OPT_mv3push, NULL, 1 }, --- --- { OPT_LEVELS_NONE, 0, NULL, 0 } --+ { OPT_LEVELS_SIZE, OPT_mv3push, NULL, 1 }, --+ /* Enable -mload-store-opt by default at -Os. */ --+ { OPT_LEVELS_SIZE, OPT_mload_store_opt, NULL, 1 }, --+ /* Enable -mregrename by default at -O1 and above. */ --+ { OPT_LEVELS_1_PLUS, OPT_mregrename, NULL, 1 }, --+ /* Enable -mgcse by default at -O1 and above. */ --+ { OPT_LEVELS_1_PLUS, OPT_mgcse, NULL, 1 }, --+ /* Enable -msign-conversion by default at -O1 and above. */ --+ { OPT_LEVELS_1_PLUS, OPT_msign_conversion, NULL, 1 }, --+ /* Enable -mscalbn-transform by default at -O1 and above. */ --+ { OPT_LEVELS_1_PLUS, OPT_mscalbn_transform, NULL, 1 }, --+ /* Enable -mconst_remeterialization by default at -O1 and above. */ --+ { OPT_LEVELS_1_PLUS, OPT_mconst_remater, NULL, 1 }, --+ /* Enable -mcprop-acc by default at -O1 and above. */ --+ { OPT_LEVELS_1_PLUS, OPT_mcprop_acc, NULL, 1 }, --+#ifdef TARGET_OS_DEFAULT_IFC --+ /* Enable -mifc by default at -Os, but it is useless under V2/V3M ISA. */ --+ { OPT_LEVELS_SIZE, OPT_mifc, NULL, 1 }, --+#endif --+#ifdef TARGET_OS_DEFAULT_EX9 --+ /* Enable -mex9 by default at -Os, but it is useless under V2/V3M ISA. */ --+ { OPT_LEVELS_SIZE, OPT_mex9, NULL, 1 }, --+#endif --+ --+ { OPT_LEVELS_NONE, 0, NULL, 0 } -- }; -- -- /* ------------------------------------------------------------------------ */ --+ --+/* Implement TARGET_EXCEPT_UNWIND_INFO. */ --+static enum unwind_info_type --+nds32_except_unwind_info (struct gcc_options *opts ATTRIBUTE_UNUSED) --+{ --+ if (TARGET_LINUX_ABI) --+ return UI_DWARF2; --+ --+ return UI_SJLJ; --+} --+ --+/* ------------------------------------------------------------------------ */ --+ -- -- /* Run-time Target Specification. */ -- --@@ -95,14 +159,22 @@ static const struct default_options nds32_option_optimization_table[] = -- -- Other MASK_XXX flags are set individually. -- By default we enable --- TARGET_16_BIT : Generate 16/32 bit mixed length instruction. --- TARGET_PERF_EXT : Generate performance extention instrcution. --- TARGET_CMOV : Generate conditional move instruction. */ --+ TARGET_16_BIT : Generate 16/32 bit mixed length instruction. --+ TARGET_EXT_PERF : Generate performance extention instrcution. --+ TARGET_EXT_PERF2 : Generate performance extention version 2 instrcution. --+ TARGET_EXT_STRING : Generate string extention instrcution. --+ TARGET_HW_ABS : Generate hardware abs instruction. --+ TARGET_CMOV : Generate conditional move instruction. */ -- #undef TARGET_DEFAULT_TARGET_FLAGS -- #define TARGET_DEFAULT_TARGET_FLAGS \ -- (TARGET_CPU_DEFAULT \ --+ | TARGET_DEFAULT_FPU_ISA \ --+ | TARGET_DEFAULT_FPU_FMA \ -- | MASK_16_BIT \ --- | MASK_PERF_EXT \ --+ | MASK_EXT_PERF \ --+ | MASK_EXT_PERF2 \ --+ | MASK_EXT_STRING \ --+ | MASK_HW_ABS \ -- | MASK_CMOV) -- -- #undef TARGET_HANDLE_OPTION --@@ -115,7 +187,7 @@ static const struct default_options nds32_option_optimization_table[] = -- /* Defining the Output Assembler Language. */ -- -- #undef TARGET_EXCEPT_UNWIND_INFO ---#define TARGET_EXCEPT_UNWIND_INFO sjlj_except_unwind_info --+#define TARGET_EXCEPT_UNWIND_INFO nds32_except_unwind_info -- -- /* ------------------------------------------------------------------------ */ -- --diff --git a/gcc/config.gcc b/gcc/config.gcc --index 1d5b23f..367a821 100644 ----- a/gcc/config.gcc --+++ b/gcc/config.gcc --@@ -433,8 +433,28 @@ mips*-*-*) -- ;; -- nds32*) -- cpu_type=nds32 --- extra_headers="nds32_intrinsic.h" --- extra_objs="nds32-cost.o nds32-intrinsic.o nds32-isr.o nds32-md-auxiliary.o nds32-pipelines-auxiliary.o nds32-predicates.o nds32-memory-manipulation.o nds32-fp-as-gp.o" --+ extra_headers="nds32_intrinsic.h nds32_isr.h nds32_init.inc" --+ case ${target} in --+ nds32*-*-linux*) --+ extra_options="${extra_options} nds32/nds32-linux.opt" --+ ;; --+ nds32*-*-elf*) --+ extra_options="${extra_options} nds32/nds32-elf.opt" --+ ;; --+ *) --+ ;; --+ esac --+ extra_options="${extra_options} g.opt" --+ extra_objs="nds32-cost.o nds32-intrinsic.o nds32-md-auxiliary.o \ --+ nds32-pipelines-auxiliary.o nds32-predicates.o \ --+ nds32-memory-manipulation.o nds32-fp-as-gp.o \ --+ nds32-load-store-opt.o nds32-soft-fp-comm.o nds32-isr.o \ --+ nds32-regrename.o nds32-gcse.o nds32-relax-opt.o \ --+ nds32-sign-conversion.o \ --+ nds32-scalbn-transform.o nds32-lmwsmw.o \ --+ nds32-reg-utils.o nds32-const-remater.o \ --+ nds32-utils.o nds32-abi-compatible.o \ --+ nds32-cprop-acc.o" -- ;; -- nios2-*-*) -- cpu_type=nios2 --@@ -2265,17 +2285,67 @@ msp430*-*-*) -- tmake_file="${tmake_file} msp430/t-msp430" -- extra_gcc_objs="driver-msp430.o" -- ;; ---nds32le-*-*) --+nds32*-*-*) -- target_cpu_default="0" -- tm_defines="${tm_defines}" --- tm_file="dbxelf.h elfos.h newlib-stdint.h ${tm_file}" --- tmake_file="nds32/t-nds32 nds32/t-mlibs" --- ;; ---nds32be-*-*) --- target_cpu_default="0|MASK_BIG_ENDIAN" --- tm_defines="${tm_defines} TARGET_BIG_ENDIAN_DEFAULT=1" --- tm_file="dbxelf.h elfos.h newlib-stdint.h ${tm_file}" --- tmake_file="nds32/t-nds32 nds32/t-mlibs" --+ case ${target} in --+ nds32le*-*-*) --+ ;; --+ nds32be-*-*) --+ target_cpu_default="${target_cpu_default}|MASK_BIG_ENDIAN" --+ tm_defines="${tm_defines} TARGET_BIG_ENDIAN_DEFAULT=1" --+ ;; --+ esac --+ case ${target} in --+ nds32*-*-elf*) --+ tm_file="dbxelf.h elfos.h newlib-stdint.h ${tm_file} nds32/elf.h nds32/nds32_intrinsic.h" --+ tmake_file="nds32/t-nds32 nds32/t-elf" --+ ;; --+ nds32*-*-linux*) --+ tm_file="dbxelf.h elfos.h ${tm_file} gnu-user.h linux.h glibc-stdint.h nds32/linux.h nds32/nds32_intrinsic.h" --+ tmake_file="${tmake_file} nds32/t-nds32 nds32/t-linux" --+ ;; --+ esac --+ nds32_multilibs="${with_multilib_list}" --+ if test "$nds32_multilibs" = "default"; then --+ nds32_multilibs="" --+ fi --+ nds32_multilibs=`echo $nds32_multilibs | sed -e 's/,/ /g'` --+ for nds32_multilib in ${nds32_multilibs}; do --+ case ${nds32_multilib} in --+ dsp | zol | v3m+ | graywolf ) --+ TM_MULTILIB_CONFIG="${TM_MULTILIB_CONFIG} ${nds32_multilib}" --+ ;; --+ *) --+ echo "--with-multilib-list=${nds32_multilib} not supported." --+ exit 1 --+ esac --+ done --+ --+ # Handle --enable-default-relax setting. --+ if test x${enable_default_relax} = xyes; then --+ tm_defines="${tm_defines} TARGET_DEFAULT_RELAX=1" --+ fi --+ # Handle --enable-Os-default-ifc setting. --+ if test x${enable_Os_default_ifc} = xyes; then --+ tm_defines="${tm_defines} TARGET_OS_DEFAULT_IFC=1" --+ fi --+ # Handle --enable-Os-default-ex9 setting. --+ if test x${enable_Os_default_ex9} = xyes; then --+ tm_defines="${tm_defines} TARGET_OS_DEFAULT_EX9=1" --+ fi --+ # Handle --with-ext-dsp --+ if test x${with_ext_dsp} = xyes; then --+ tm_defines="${tm_defines} TARGET_DEFAULT_EXT_DSP=1" --+ fi --+ if test x${with_ext_zol} = xyes; then --+ tm_defines="${tm_defines} TARGET_DEFAULT_HWLOOP=1" --+ fi --+ # Handle --with-16bit-ext, and default is on --+ if test x${with_ext_16bit} != xno; then --+ tm_defines="${tm_defines} TARGET_DEFAULT_16BIT=1" --+ fi --+ -- ;; -- nios2-*-*) -- tm_file="elfos.h ${tm_file}" --@@ -4097,15 +4167,51 @@ case "${target}" in -- ;; -- -- nds32*-*-*) --- supported_defaults="arch nds32_lib" --+ supported_defaults="arch cpu nds32_lib float fpu_config memory_model" -- -- # process --with-arch -- case "${with_arch}" in --- "" | v2 | v3 | v3m) --+ "" | v3 | v3j) --+ # OK --+ tm_defines="${tm_defines} TARGET_ARCH_DEFAULT=0" --+ tm_defines="${tm_defines} TARGET_DEFAULT_ISR_VECTOR_SIZE=4" --+ ;; --+ v2 | v2j | v3m) --+ # OK --+ tm_defines="${tm_defines} TARGET_ARCH_DEFAULT=0" --+ tm_defines="${tm_defines} TARGET_DEFAULT_ISR_VECTOR_SIZE=16" --+ ;; --+ v3f) --+ tm_defines="${tm_defines} TARGET_ARCH_DEFAULT=1" --+ tm_defines="${tm_defines} TARGET_DEFAULT_ISR_VECTOR_SIZE=4" --+ ;; --+ v3s) --+ tm_defines="${tm_defines} TARGET_ARCH_DEFAULT=2" --+ tm_defines="${tm_defines} TARGET_DEFAULT_ISR_VECTOR_SIZE=4" --+ ;; --+ *) --+ echo "Cannot accept --with-arch=$with_arch, available values are: v2 v2j v3 v3j v3m v3f v3s" 1>&2 --+ exit 1 --+ ;; --+ esac --+ --+ # process --with-memory-model --+ case "${with_memory_model}" in --+ "" | fast | slow) --+ ;; --+ *) --+ echo "Cannot accept --with-memory-model=$with_memory_model, available values are: fast slow" 1>&2 --+ exit 1 --+ ;; --+ esac --+ --+ # process --with-cpu --+ case "${with_cpu}" in --+ "" | n7 | n8 | e8 | s8 | n9 | n10 | d10 | graywolf | n12 | n13 | panther) -- # OK -- ;; -- *) --- echo "Cannot accept --with-arch=$with_arch, available values are: v2 v3 v3m" 1>&2 --+ echo "Cannot accept --with-cpu=$with_cpu, available values are: n7 n8 e8 s8 n9 n10 d10 graywolf n12 n13 panther" 1>&2 -- exit 1 -- ;; -- esac --@@ -4115,31 +4221,56 @@ case "${target}" in -- "") -- # the default library is newlib -- with_nds32_lib=newlib --+ tm_defines="${tm_defines} TARGET_DEFAULT_CTOR_DTOR=1" -- ;; -- newlib) -- # OK --+ tm_defines="${tm_defines} TARGET_DEFAULT_CTOR_DTOR=1" -- ;; -- mculib) -- # OK --+ # for the arch=v3f or arch=v3s under mculib toolchain, --+ # we would like to set -fno-math-errno as default --+ case "${with_arch}" in --+ v3f | v3s) --+ tm_defines="${tm_defines} TARGET_DEFAULT_NO_MATH_ERRNO=1" --+ ;; --+ esac --+ ;; --+ glibc) --+ # OK --+ tm_defines="${tm_defines} TARGET_DEFAULT_TLSDESC_TRAMPOLINE=1" --+ ;; --+ uclibc) -- ;; -- *) --- echo "Cannot accept --with-nds32-lib=$with_nds32_lib, available values are: newlib mculib" 1>&2 --+ echo "Cannot accept --with-nds32-lib=$with_nds32_lib, available values are: newlib mculib glibc uclibc" 1>&2 --+ exit 1 --+ ;; --+ esac --+ --+ # process --with-float --+ case "${with_float}" in --+ "" | soft | hard) --+ # OK --+ ;; --+ *) --+ echo "Cannot accept --with-float=$with_float, available values are: soft hard" 1>&2 --+ exit 1 --+ ;; --+ esac --+ --+ # process --with-config-fpu --+ case "${with_config_fpu}" in --+ "" | 0 | 1 | 2 | 3) --+ # OK --+ ;; --+ *) --+ echo "Cannot accept --with-config-fpu=$with_config_fpu, available values from 0 to 7" 1>&2 -- exit 1 -- ;; -- esac --- ;; -- --- nios2*-*-*) --- supported_defaults="arch" --- case "$with_arch" in --- "" | r1 | r2) --- # OK --- ;; --- *) --- echo "Unknown arch used in --with-arch=$with_arch" 1>&2 --- exit 1 --- ;; --- esac -- ;; -- -- powerpc*-*-* | rs6000-*-*) --@@ -4527,7 +4658,7 @@ case ${target} in -- esac -- -- t= ---all_defaults="abi cpu cpu_32 cpu_64 arch arch_32 arch_64 tune tune_32 tune_64 schedule float mode fpu nan fp_32 odd_spreg_32 divide llsc mips-plt synci tls" --+all_defaults="abi cpu cpu_32 cpu_64 arch arch_32 arch_64 tune tune_32 tune_64 schedule float mode fpu nan fp_32 odd_spreg_32 divide llsc mips-plt synci tls memory_model" -- for option in $all_defaults -- do -- eval "val=\$with_"`echo $option | sed s/-/_/g` --diff --git a/gcc/config/nds32/constants.md b/gcc/config/nds32/constants.md --index bea42ee..6c92412 100644 ----- a/gcc/config/nds32/constants.md --+++ b/gcc/config/nds32/constants.md --@@ -23,25 +23,176 @@ -- (define_constants -- [(R8_REGNUM 8) -- (TA_REGNUM 15) --+ (TP_REGNUM 25) -- (FP_REGNUM 28) -- (GP_REGNUM 29) -- (LP_REGNUM 30) -- (SP_REGNUM 31) --+ (LB_REGNUM 98) --+ (LE_REGNUM 99) --+ (LC_REGNUM 100) -- ]) -- -- --+;; The unpec operation index. --+(define_c_enum "unspec_element" [ --+ UNSPEC_COPYSIGN --+ UNSPEC_FCPYNSD --+ UNSPEC_FCPYNSS --+ UNSPEC_FCPYSD --+ UNSPEC_FCPYSS --+ UNSPEC_CLIP --+ UNSPEC_CLIPS --+ UNSPEC_CLO --+ UNSPEC_PBSAD --+ UNSPEC_PBSADA --+ UNSPEC_BSE --+ UNSPEC_BSE_2 --+ UNSPEC_BSP --+ UNSPEC_BSP_2 --+ UNSPEC_FFB --+ UNSPEC_FFMISM --+ UNSPEC_FLMISM --+ UNSPEC_KDMBB --+ UNSPEC_KDMBT --+ UNSPEC_KDMTB --+ UNSPEC_KDMTT --+ UNSPEC_KHMBB --+ UNSPEC_KHMBT --+ UNSPEC_KHMTB --+ UNSPEC_KHMTT --+ UNSPEC_KSLRAW --+ UNSPEC_KSLRAWU --+ UNSPEC_SVA --+ UNSPEC_SVS --+ UNSPEC_WSBH --+ UNSPEC_LWUP --+ UNSPEC_LBUP --+ UNSPEC_SWUP --+ UNSPEC_SBUP --+ UNSPEC_LMWZB --+ UNSPEC_SMWZB --+ UNSPEC_UALOAD_HW --+ UNSPEC_UALOAD_W --+ UNSPEC_UALOAD_DW --+ UNSPEC_UASTORE_HW --+ UNSPEC_UASTORE_W --+ UNSPEC_UASTORE_DW --+ UNSPEC_GOTINIT --+ UNSPEC_GOT --+ UNSPEC_GOTOFF --+ UNSPEC_PLT --+ UNSPEC_TLSGD --+ UNSPEC_TLSLD --+ UNSPEC_TLSIE --+ UNSPEC_TLSLE --+ UNSPEC_ROUND --+ UNSPEC_VEC_COMPARE --+ UNSPEC_KHM --+ UNSPEC_KHMX --+ UNSPEC_CLIP_OV --+ UNSPEC_CLIPS_OV --+ UNSPEC_BITREV --+ UNSPEC_KABS --+ UNSPEC_LOOP_END --+ UNSPEC_TLS_DESC --+ UNSPEC_TLS_IE --+ UNSPEC_ADD32 --+ UNSPEC_ICT --+]) --+ --+ -- ;; The unspec_volatile operation index. -- (define_c_enum "unspec_volatile_element" [ --- UNSPEC_VOLATILE_FUNC_RETURN --+ UNSPEC_VOLATILE_EH_RETURN -- UNSPEC_VOLATILE_ISYNC -- UNSPEC_VOLATILE_ISB --+ UNSPEC_VOLATILE_DSB --+ UNSPEC_VOLATILE_MSYNC --+ UNSPEC_VOLATILE_MSYNC_ALL --+ UNSPEC_VOLATILE_MSYNC_STORE -- UNSPEC_VOLATILE_MFSR -- UNSPEC_VOLATILE_MFUSR -- UNSPEC_VOLATILE_MTSR -- UNSPEC_VOLATILE_MTUSR -- UNSPEC_VOLATILE_SETGIE_EN -- UNSPEC_VOLATILE_SETGIE_DIS --+ UNSPEC_VOLATILE_FMFCSR --+ UNSPEC_VOLATILE_FMTCSR --+ UNSPEC_VOLATILE_FMFCFG --+ UNSPEC_VOLATILE_JR_ITOFF --+ UNSPEC_VOLATILE_JR_TOFF --+ UNSPEC_VOLATILE_JRAL_ITON --+ UNSPEC_VOLATILE_JRAL_TON --+ UNSPEC_VOLATILE_RET_ITOFF --+ UNSPEC_VOLATILE_RET_TOFF --+ UNSPEC_VOLATILE_STANDBY_NO_WAKE_GRANT --+ UNSPEC_VOLATILE_STANDBY_WAKE_GRANT --+ UNSPEC_VOLATILE_STANDBY_WAKE_DONE --+ UNSPEC_VOLATILE_TEQZ --+ UNSPEC_VOLATILE_TNEZ --+ UNSPEC_VOLATILE_TRAP --+ UNSPEC_VOLATILE_SETEND_BIG --+ UNSPEC_VOLATILE_SETEND_LITTLE --+ UNSPEC_VOLATILE_BREAK --+ UNSPEC_VOLATILE_SYSCALL --+ UNSPEC_VOLATILE_NOP --+ UNSPEC_VOLATILE_RES_DEP --+ UNSPEC_VOLATILE_DATA_DEP --+ UNSPEC_VOLATILE_LLW --+ UNSPEC_VOLATILE_SCW --+ UNSPEC_VOLATILE_CCTL_L1D_INVALALL --+ UNSPEC_VOLATILE_CCTL_L1D_WBALL_ALVL --+ UNSPEC_VOLATILE_CCTL_L1D_WBALL_ONE_LVL --+ UNSPEC_VOLATILE_CCTL_IDX_WRITE --+ UNSPEC_VOLATILE_CCTL_IDX_READ --+ UNSPEC_VOLATILE_CCTL_VA_WBINVAL_L1 --+ UNSPEC_VOLATILE_CCTL_VA_WBINVAL_LA --+ UNSPEC_VOLATILE_CCTL_IDX_WBINVAL --+ UNSPEC_VOLATILE_CCTL_VA_LCK --+ UNSPEC_VOLATILE_DPREF_QW --+ UNSPEC_VOLATILE_DPREF_HW --+ UNSPEC_VOLATILE_DPREF_W --+ UNSPEC_VOLATILE_DPREF_DW --+ UNSPEC_VOLATILE_TLBOP_TRD --+ UNSPEC_VOLATILE_TLBOP_TWR --+ UNSPEC_VOLATILE_TLBOP_RWR --+ UNSPEC_VOLATILE_TLBOP_RWLK --+ UNSPEC_VOLATILE_TLBOP_UNLK --+ UNSPEC_VOLATILE_TLBOP_PB --+ UNSPEC_VOLATILE_TLBOP_INV --+ UNSPEC_VOLATILE_TLBOP_FLUA --+ UNSPEC_VOLATILE_ENABLE_INT --+ UNSPEC_VOLATILE_DISABLE_INT --+ UNSPEC_VOLATILE_SET_PENDING_SWINT --+ UNSPEC_VOLATILE_CLR_PENDING_SWINT --+ UNSPEC_VOLATILE_CLR_PENDING_HWINT --+ UNSPEC_VOLATILE_GET_ALL_PENDING_INT --+ UNSPEC_VOLATILE_GET_PENDING_INT --+ UNSPEC_VOLATILE_SET_INT_PRIORITY --+ UNSPEC_VOLATILE_GET_INT_PRIORITY --+ UNSPEC_VOLATILE_SET_TRIG_LEVEL --+ UNSPEC_VOLATILE_SET_TRIG_EDGE --+ UNSPEC_VOLATILE_GET_TRIG_TYPE --+ UNSPEC_VOLATILE_RELAX_GROUP --+ UNSPEC_VOLATILE_INNERMOST_LOOP_BEGIN --+ UNSPEC_VOLATILE_INNERMOST_LOOP_END --+ UNSPEC_VOLATILE_OMIT_FP_BEGIN --+ UNSPEC_VOLATILE_OMIT_FP_END -- UNSPEC_VOLATILE_POP25_RETURN --+ UNSPEC_VOLATILE_SIGNATURE_BEGIN --+ UNSPEC_VOLATILE_SIGNATURE_END --+ UNSPEC_VOLATILE_NO_HWLOOP --+ UNSPEC_VOLATILE_NO_IFC_BEGIN --+ UNSPEC_VOLATILE_NO_IFC_END --+ UNSPEC_VOLATILE_NO_EX9_BEGIN --+ UNSPEC_VOLATILE_NO_EX9_END --+ UNSPEC_VOLATILE_UNALIGNED_FEATURE --+ UNSPEC_VOLATILE_ENABLE_UNALIGNED --+ UNSPEC_VOLATILE_DISABLE_UNALIGNED --+ UNSPEC_VOLATILE_RDOV --+ UNSPEC_VOLATILE_CLROV --+ UNSPEC_VOLATILE_HWLOOP_LAST_INSN -- ]) -- -- ;; ------------------------------------------------------------------------ --diff --git a/gcc/config/nds32/constraints.md b/gcc/config/nds32/constraints.md --index 1f44a1a..8163f46 100644 ----- a/gcc/config/nds32/constraints.md --+++ b/gcc/config/nds32/constraints.md --@@ -25,9 +25,6 @@ -- ;; Machine-dependent floating: G H -- -- ---(define_register_constraint "w" "(TARGET_ISA_V3 || TARGET_ISA_V3M) ? LOW_REGS : NO_REGS" --- "LOW register class $r0 ~ $r7 constraint for V3/V3M ISA") --- -- (define_register_constraint "l" "LOW_REGS" -- "LOW register class $r0 ~ $r7") -- --@@ -41,9 +38,59 @@ -- (define_register_constraint "t" "R15_TA_REG" -- "Temporary Assist register $ta (i.e. $r15)") -- --+(define_register_constraint "e" "R8_REG" --+ "Function Entry register $r8)") --+ -- (define_register_constraint "k" "STACK_REG" -- "Stack register $sp") -- --+(define_register_constraint "v" "R5_REG" --+ "Register $r5") --+ --+(define_register_constraint "x" "FRAME_POINTER_REG" --+ "Frame pointer register $fp") --+ --+(define_register_constraint "f" --+ "(TARGET_FPU_SINGLE || TARGET_FPU_DOUBLE) ? FP_REGS : NO_REGS" --+ "The Floating point registers $fs0 ~ $fs31") --+ --+(define_register_constraint "A" "LOOP_REGS" --+ "Loop register class") --+ --+(define_constraint "Iv00" --+ "Constant value 0" --+ (and (match_code "const_int") --+ (match_test "ival == 0"))) --+ --+(define_constraint "Iv01" --+ "Constant value 1" --+ (and (match_code "const_int") --+ (match_test "ival == 1"))) --+ --+(define_constraint "Iv02" --+ "Constant value 2" --+ (and (match_code "const_int") --+ (match_test "ival == 2"))) --+ --+(define_constraint "Iv04" --+ "Constant value 4" --+ (and (match_code "const_int") --+ (match_test "ival == 4"))) --+ --+(define_constraint "Iv08" --+ "Constant value 8" --+ (and (match_code "const_int") --+ (match_test "ival == 8"))) --+ --+(define_constraint "Iu01" --+ "Unsigned immediate 1-bit value" --+ (and (match_code "const_int") --+ (match_test "ival == 1 || ival == 0"))) --+ --+(define_constraint "Iu02" --+ "Unsigned immediate 2-bit value" --+ (and (match_code "const_int") --+ (match_test "ival < (1 << 2) && ival >= 0"))) -- -- (define_constraint "Iu03" -- "Unsigned immediate 3-bit value" --@@ -65,6 +112,11 @@ -- (and (match_code "const_int") -- (match_test "ival < (1 << 4) && ival >= -(1 << 4)"))) -- --+(define_constraint "Cs05" --+ "Signed immediate 5-bit value" --+ (and (match_code "const_double") --+ (match_test "nds32_const_double_range_ok_p (op, SFmode, -(1 << 4), (1 << 4))"))) --+ -- (define_constraint "Iu05" -- "Unsigned immediate 5-bit value" -- (and (match_code "const_int") --@@ -75,6 +127,11 @@ -- (and (match_code "const_int") -- (match_test "IN_RANGE (ival, -31, 0)"))) -- --+(define_constraint "Iu06" --+ "Unsigned immediate 6-bit value" --+ (and (match_code "const_int") --+ (match_test "ival < (1 << 6) && ival >= 0"))) --+ -- ;; Ip05 is special and dedicated for v3 movpi45 instruction. -- ;; movpi45 has imm5u field but the range is 16 ~ 47. -- (define_constraint "Ip05" --@@ -84,10 +141,10 @@ -- && ival >= (0 + 16) -- && (TARGET_ISA_V3 || TARGET_ISA_V3M)"))) -- ---(define_constraint "Iu06" --+(define_constraint "IU06" -- "Unsigned immediate 6-bit value constraint for addri36.sp instruction" -- (and (match_code "const_int") --- (match_test "ival < (1 << 6) --+ (match_test "ival < (1 << 8) -- && ival >= 0 -- && (ival % 4 == 0) -- && (TARGET_ISA_V3 || TARGET_ISA_V3M)"))) --@@ -103,6 +160,11 @@ -- (match_test "ival < (1 << 9) && ival >= 0"))) -- -- --+(define_constraint "Is08" --+ "Signed immediate 8-bit value" --+ (and (match_code "const_int") --+ (match_test "ival < (1 << 7) && ival >= -(1 << 7)"))) --+ -- (define_constraint "Is10" -- "Signed immediate 10-bit value" -- (and (match_code "const_int") --@@ -113,6 +175,10 @@ -- (and (match_code "const_int") -- (match_test "ival < (1 << 10) && ival >= -(1 << 10)"))) -- --+(define_constraint "Is14" --+ "Signed immediate 14-bit value" --+ (and (match_code "const_int") --+ (match_test "ival < (1 << 13) && ival >= -(1 << 13)"))) -- -- (define_constraint "Is15" -- "Signed immediate 15-bit value" --@@ -194,12 +260,21 @@ -- (and (match_code "const_int") -- (match_test "ival < (1 << 19) && ival >= -(1 << 19)"))) -- --+(define_constraint "Cs20" --+ "Signed immediate 20-bit value" --+ (and (match_code "const_double") --+ (match_test "nds32_const_double_range_ok_p (op, SFmode, -(1 << 19), (1 << 19))"))) -- -- (define_constraint "Ihig" -- "The immediate value that can be simply set high 20-bit" -- (and (match_code "const_int") -- (match_test "(ival != 0) && ((ival & 0xfff) == 0)"))) -- --+(define_constraint "Chig" --+ "The immediate value that can be simply set high 20-bit" --+ (and (match_code "high") --+ (match_test "GET_CODE (XEXP (op, 0)) == CONST_DOUBLE"))) --+ -- (define_constraint "Izeb" -- "The immediate value 0xff" -- (and (match_code "const_int") --@@ -213,12 +288,12 @@ -- (define_constraint "Ixls" -- "The immediate value 0x01" -- (and (match_code "const_int") --- (match_test "TARGET_PERF_EXT && (ival == 0x1)"))) --+ (match_test "TARGET_EXT_PERF && (ival == 0x1)"))) -- -- (define_constraint "Ix11" -- "The immediate value 0x7ff" -- (and (match_code "const_int") --- (match_test "TARGET_PERF_EXT && (ival == 0x7ff)"))) --+ (match_test "TARGET_EXT_PERF && (ival == 0x7ff)"))) -- -- (define_constraint "Ibms" -- "The immediate value with power of 2" --@@ -232,23 +307,70 @@ -- (match_test "(TARGET_ISA_V3 || TARGET_ISA_V3M) -- && (IN_RANGE (exact_log2 (ival + 1), 1, 8))"))) -- --+(define_constraint "CVp5" --+ "Unsigned immediate 5-bit value for movpi45 instruction with range 16-47" --+ (and (match_code "const_vector") --+ (match_test "nds32_valid_CVp5_p (op)"))) --+ --+(define_constraint "CVs5" --+ "Signed immediate 5-bit value" --+ (and (match_code "const_vector") --+ (match_test "nds32_valid_CVs5_p (op)"))) --+ --+(define_constraint "CVs2" --+ "Signed immediate 20-bit value" --+ (and (match_code "const_vector") --+ (match_test "nds32_valid_CVs2_p (op)"))) --+ --+(define_constraint "CVhi" --+ "The immediate value that can be simply set high 20-bit" --+ (and (match_code "const_vector") --+ (match_test "nds32_valid_CVhi_p (op)"))) -- -- (define_memory_constraint "U33" -- "Memory constraint for 333 format" -- (and (match_code "mem") --- (match_test "nds32_mem_format (op) == ADDRESS_LO_REG_IMM3U"))) --+ (match_test "nds32_mem_format (op) == ADDRESS_POST_INC_LO_REG_IMM3U --+ || nds32_mem_format (op) == ADDRESS_POST_MODIFY_LO_REG_IMM3U --+ || nds32_mem_format (op) == ADDRESS_LO_REG_IMM3U"))) -- -- (define_memory_constraint "U45" -- "Memory constraint for 45 format" -- (and (match_code "mem") -- (match_test "(nds32_mem_format (op) == ADDRESS_REG) --- && (GET_MODE (op) == SImode)"))) --+ && ((GET_MODE (op) == SImode) --+ || (GET_MODE (op) == SFmode))"))) --+ --+(define_memory_constraint "Ufe" --+ "Memory constraint for fe format" --+ (and (match_code "mem") --+ (match_test "nds32_mem_format (op) == ADDRESS_R8_IMM7U --+ && (GET_MODE (op) == SImode --+ || GET_MODE (op) == SFmode)"))) -- -- (define_memory_constraint "U37" -- "Memory constraint for 37 format" -- (and (match_code "mem") -- (match_test "(nds32_mem_format (op) == ADDRESS_SP_IMM7U -- || nds32_mem_format (op) == ADDRESS_FP_IMM7U) --- && (GET_MODE (op) == SImode)"))) --+ && (GET_MODE (op) == SImode --+ || GET_MODE (op) == SFmode)"))) --+ --+(define_memory_constraint "Umw" --+ "Memory constraint for lwm/smw" --+ (and (match_code "mem") --+ (match_test "nds32_valid_smw_lwm_base_p (op)"))) --+ --+(define_memory_constraint "Da" --+ "Memory constraint for non-offset loads/stores" --+ (and (match_code "mem") --+ (match_test "REG_P (XEXP (op, 0)) --+ || (GET_CODE (XEXP (op, 0)) == POST_INC)"))) --+ --+(define_memory_constraint "Q" --+ "Memory constraint for no symbol_ref and const" --+ (and (match_code "mem") --+ (match_test "(TARGET_FPU_SINGLE || TARGET_FPU_DOUBLE) --+ && nds32_float_mem_operand_p (op)"))) -- -- ;; ------------------------------------------------------------------------ --diff --git a/gcc/config/nds32/elf.h b/gcc/config/nds32/elf.h --new file mode 100644 --index 0000000..315dcd8 ----- /dev/null --+++ b/gcc/config/nds32/elf.h --@@ -0,0 +1,83 @@ --+/* Definitions of target machine of Andes NDS32 cpu for GNU compiler --+ Copyright (C) 2012-2016 Free Software Foundation, Inc. --+ Contributed by Andes Technology Corporation. --+ --+ This file is part of GCC. --+ --+ GCC is free software; you can redistribute it and/or modify it --+ under the terms of the GNU General Public License as published --+ by the Free Software Foundation; either version 3, or (at your --+ option) any later version. --+ --+ GCC is distributed in the hope that it will be useful, but WITHOUT --+ ANY WARRANTY; without even the implied warranty of MERCHANTABILITY --+ or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public --+ License for more details. --+ --+ You should have received a copy of the GNU General Public License --+ along with GCC; see the file COPYING3. If not see --+ . */ --+ --+ --+/* ------------------------------------------------------------------------ */ --+ --+#define TARGET_LINUX_ABI 0 --+ --+/* In the configure stage we may use options --enable-default-relax, --+ --enable-Os-default-ifc and --enable-Os-default-ex9. They effect --+ the default spec of passing --relax, --mifc, and --mex9 to linker. --+ We use NDS32_RELAX_SPEC, NDS32_IFC_SPEC, and NDS32_EX9_SPEC --+ so that we can customize them conveniently. */ --+#define LINK_SPEC \ --+ " %{G*}" \ --+ " %{mbig-endian:-EB} %{mlittle-endian:-EL}" \ --+ " %{shared:-shared}" \ --+ NDS32_RELAX_SPEC \ --+ NDS32_IFC_SPEC \ --+ NDS32_EX9_SPEC --+ --+#define LIB_SPEC \ --+ " -lc -lgloss" --+ --+#define LIBGCC_SPEC \ --+ " -lgcc" --+ --+/* The option -mno-ctor-dtor can disable constructor/destructor feature --+ by applying different crt stuff. In the convention, crt0.o is the --+ startup file without constructor/destructor; --+ crt1.o, crti.o, crtbegin.o, crtend.o, and crtn.o are the --+ startup files with constructor/destructor. --+ Note that crt0.o, crt1.o, crti.o, and crtn.o are provided --+ by newlib/mculib/glibc/ublic, while crtbegin.o and crtend.o are --+ currently provided by GCC for nds32 target. --+ --+ For nds32 target so far: --+ If -mno-ctor-dtor, we are going to link --+ "crt0.o [user objects]". --+ If -mctor-dtor, we are going to link --+ "crt1.o crtbegin1.o [user objects] crtend1.o". --+ --+ Note that the TARGET_DEFAULT_CTOR_DTOR would effect the --+ default behavior. Check gcc/config.gcc for more information. */ --+#ifdef TARGET_DEFAULT_CTOR_DTOR --+ #define STARTFILE_SPEC \ --+ " %{!mno-ctor-dtor:crt1.o%s;:crt0.o%s}" \ --+ " %{!mno-ctor-dtor:crtbegin1.o%s}" \ --+ " %{mcrt-arg:crtarg.o%s}" --+ #define ENDFILE_SPEC \ --+ " %{!mno-ctor-dtor:crtend1.o%s}" --+#else --+ #define STARTFILE_SPEC \ --+ " %{mctor-dtor|coverage:crt1.o%s;:crt0.o%s}" \ --+ " %{mctor-dtor|coverage:crtbegin1.o%s}" \ --+ " %{mcrt-arg:crtarg.o%s}" --+ #define ENDFILE_SPEC \ --+ " %{mctor-dtor|coverage:crtend1.o%s}" --+#endif --+ --+#define STARTFILE_CXX_SPEC \ --+ " %{!mno-ctor-dtor:crt1.o%s;:crt0.o%s}" \ --+ " %{!mno-ctor-dtor:crtbegin1.o%s}" \ --+ " %{mcrt-arg:crtarg.o%s}" --+#define ENDFILE_CXX_SPEC \ --+ " %{!mno-ctor-dtor:crtend1.o%s}" --diff --git a/gcc/config/nds32/iterators.md b/gcc/config/nds32/iterators.md --index ab0f103..6023b9c 100644 ----- a/gcc/config/nds32/iterators.md --+++ b/gcc/config/nds32/iterators.md --@@ -26,30 +26,99 @@ -- ;; A list of integer modes that are up to one word long. -- (define_mode_iterator QIHISI [QI HI SI]) -- --+;; A list of integer modes for one word and double word. --+(define_mode_iterator SIDI [SI DI]) --+ -- ;; A list of integer modes that are up to one half-word long. -- (define_mode_iterator QIHI [QI HI]) -- -- ;; A list of the modes that are up to double-word long. -- (define_mode_iterator DIDF [DI DF]) -- --+;; A list of the modes that are up to one word long vector. --+(define_mode_iterator VQIHI [V4QI V2HI]) --+ --+;; A list of the modes that are up to one word long vector and scalar. --+(define_mode_iterator VSQIHI [V4QI V2HI QI HI]) --+ --+(define_mode_iterator VSQIHIDI [V4QI V2HI QI HI DI]) --+ --+(define_mode_iterator VQIHIDI [V4QI V2HI DI]) --+ --+;; A list of the modes that are up to one word long vector --+;; and scalar for HImode. --+(define_mode_iterator VSHI [V2HI HI]) --+ --+;; A list of the modes that are up to double-word long. --+(define_mode_iterator ANYF [(SF "TARGET_FPU_SINGLE") --+ (DF "TARGET_FPU_DOUBLE")]) -- -- ;;---------------------------------------------------------------------------- -- ;; Mode attributes. -- ;;---------------------------------------------------------------------------- -- ---(define_mode_attr size [(QI "b") (HI "h") (SI "w")]) --+(define_mode_attr size [(QI "b") (HI "h") (SI "w") (SF "s") (DF "d")]) -- ---(define_mode_attr byte [(QI "1") (HI "2") (SI "4")]) --+(define_mode_attr byte [(QI "1") (HI "2") (SI "4") (V4QI "4") (V2HI "4")]) -- --+(define_mode_attr bits [(V4QI "8") (QI "8") (V2HI "16") (HI "16") (DI "64")]) --+ --+(define_mode_attr VELT [(V4QI "QI") (V2HI "HI")]) -- -- ;;---------------------------------------------------------------------------- -- ;; Code iterators. -- ;;---------------------------------------------------------------------------- -- --+;; shifts --+(define_code_iterator shift_rotate [ashift ashiftrt lshiftrt rotatert]) --+ --+(define_code_iterator shifts [ashift ashiftrt lshiftrt]) --+ --+(define_code_iterator shiftrt [ashiftrt lshiftrt]) --+ --+(define_code_iterator sat_plus [ss_plus us_plus]) --+ --+(define_code_iterator all_plus [plus ss_plus us_plus]) --+ --+(define_code_iterator sat_minus [ss_minus us_minus]) --+ --+(define_code_iterator all_minus [minus ss_minus us_minus]) --+ --+(define_code_iterator plus_minus [plus minus]) --+ --+(define_code_iterator extend [sign_extend zero_extend]) --+ --+(define_code_iterator sumax [smax umax]) --+ --+(define_code_iterator sumin [smin umin]) --+ --+(define_code_iterator sumin_max [smax umax smin umin]) -- -- ;;---------------------------------------------------------------------------- -- ;; Code attributes. -- ;;---------------------------------------------------------------------------- -- --+;; shifts --+(define_code_attr shift --+ [(ashift "ashl") (ashiftrt "ashr") (lshiftrt "lshr") (rotatert "rotr")]) --+ --+(define_code_attr su --+ [(ashiftrt "") (lshiftrt "u") (sign_extend "s") (zero_extend "u")]) --+ --+(define_code_attr zs --+ [(sign_extend "s") (zero_extend "z")]) --+ --+(define_code_attr uk --+ [(plus "") (ss_plus "k") (us_plus "uk") --+ (minus "") (ss_minus "k") (us_minus "uk")]) --+ --+(define_code_attr opcode --+ [(plus "add") (minus "sub") (smax "smax") (umax "umax") (smin "smin") (umin "umin")]) --+ --+(define_code_attr add_rsub --+ [(plus "a") (minus "rs")]) --+ --+(define_code_attr add_sub --+ [(plus "a") (minus "s")]) -- -- ;;---------------------------------------------------------------------------- --diff --git a/gcc/config/nds32/linux.h b/gcc/config/nds32/linux.h --new file mode 100644 --index 0000000..36ddf2f ----- /dev/null --+++ b/gcc/config/nds32/linux.h --@@ -0,0 +1,78 @@ --+/* Definitions of target machine of Andes NDS32 cpu for GNU compiler --+ Copyright (C) 2012-2016 Free Software Foundation, Inc. --+ Contributed by Andes Technology Corporation. --+ --+ This file is part of GCC. --+ --+ GCC is free software; you can redistribute it and/or modify it --+ under the terms of the GNU General Public License as published --+ by the Free Software Foundation; either version 3, or (at your --+ option) any later version. --+ --+ GCC is distributed in the hope that it will be useful, but WITHOUT --+ ANY WARRANTY; without even the implied warranty of MERCHANTABILITY --+ or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public --+ License for more details. --+ --+ You should have received a copy of the GNU General Public License --+ along with GCC; see the file COPYING3. If not see --+ . */ --+ --+ --+/* ------------------------------------------------------------------------ */ --+ --+#define TARGET_LINUX_ABI 1 --+ --+#undef SIZE_TYPE --+#define SIZE_TYPE "unsigned int" --+ --+#undef PTRDIFF_TYPE --+#define PTRDIFF_TYPE "int" --+ --+#ifdef TARGET_DEFAULT_TLSDESC_TRAMPOLINE --+ #define NDS32_TLSDESC_TRAMPOLINE_SPEC \ --+ " %{!mno-tlsdesc-trampoline:--mtlsdesc-trampoline}" --+#else --+ #define NDS32_TLSDESC_TRAMPOLINE_SPEC "" --+#endif --+ --+#define TARGET_OS_CPP_BUILTINS() \ --+ do \ --+ { \ --+ GNU_USER_TARGET_OS_CPP_BUILTINS(); \ --+ } \ --+ while (0) --+ --+#define GLIBC_DYNAMIC_LINKER "/lib/ld.so.1" --+ --+/* In the configure stage we may use options --enable-default-relax, --+ --enable-Os-default-ifc and --enable-Os-default-ex9. They effect --+ the default spec of passing --relax, --mifc, and --mex9 to linker. --+ We use NDS32_RELAX_SPEC, NDS32_IFC_SPEC, and NDS32_EX9_SPEC --+ so that we can customize them conveniently. */ --+#define LINK_SPEC \ --+ " %{G*}" \ --+ " %{mbig-endian:-EB} %{mlittle-endian:-EL}" \ --+ " %{shared:-shared} \ --+ %{!shared: \ --+ %{!static: \ --+ %{rdynamic:-export-dynamic} \ --+ -dynamic-linker " GNU_USER_DYNAMIC_LINKER "} \ --+ %{static:-static}}" \ --+ NDS32_RELAX_SPEC \ --+ NDS32_IFC_SPEC \ --+ NDS32_EX9_SPEC \ --+ NDS32_TLSDESC_TRAMPOLINE_SPEC --+ --+#define LINK_PIE_SPEC "%{pie:%{!fno-pie:%{!fno-PIE:%{!static:-pie}}}} " --+ --+ --+/* The SYNC operations are implemented as library functions, not --+ INSN patterns. As a result, the HAVE defines for the patterns are --+ not defined. We need to define them to generate the corresponding --+ __GCC_HAVE_SYNC_COMPARE_AND_SWAP_* and __GCC_ATOMIC_*_LOCK_FREE --+ defines. --+ Ref: https://sourceware.org/ml/libc-alpha/2014-09/msg00322.html */ --+#define HAVE_sync_compare_and_swapqi 1 --+#define HAVE_sync_compare_and_swaphi 1 --+#define HAVE_sync_compare_and_swapsi 1 --diff --git a/gcc/config/nds32/nds32-abi-compatible.c b/gcc/config/nds32/nds32-abi-compatible.c --new file mode 100644 --index 0000000..f2ed006 ----- /dev/null --+++ b/gcc/config/nds32/nds32-abi-compatible.c --@@ -0,0 +1,315 @@ --+/* A Gimple-level pass of Andes NDS32 cpu for GNU compiler. --+ This pass collects the usage of float-point. --+ --+ Copyright (C) 2012-2016 Free Software Foundation, Inc. --+ Contributed by Andes Technology Corporation. --+ --+This file is part of GCC. --+ --+GCC is free software; you can redistribute it and/or modify it under --+the terms of the GNU General Public License as published by the Free --+Software Foundation; either version 3, or (at your option) any later --+version. --+ --+GCC is distributed in the hope that it will be useful, but WITHOUT ANY --+WARRANTY; without even the implied warranty of MERCHANTABILITY or --+FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License --+for more details. --+ --+You should have received a copy of the GNU General Public License --+along with GCC; see the file COPYING3. If not see --+. */ --+ --+ --+#include "config.h" --+#include "system.h" --+#include "coretypes.h" --+#include "tm.h" --+#include "hash-set.h" --+#include "machmode.h" --+#include "vec.h" --+#include "double-int.h" --+#include "input.h" --+#include "alias.h" --+#include "symtab.h" --+#include "wide-int.h" --+#include "inchash.h" --+#include "tree.h" --+#include "stor-layout.h" --+#include "varasm.h" --+#include "calls.h" --+#include "rtl.h" --+#include "regs.h" --+#include "hard-reg-set.h" --+#include "insn-config.h" /* Required by recog.h. */ --+#include "conditions.h" --+#include "output.h" --+#include "insn-attr.h" /* For DFA state_t. */ --+#include "insn-codes.h" /* For CODE_FOR_xxx. */ --+#include "reload.h" /* For push_reload (). */ --+#include "flags.h" --+#include "input.h" --+#include "function.h" --+#include "expr.h" --+#include "recog.h" --+#include "diagnostic-core.h" --+#include "dominance.h" --+#include "cfg.h" --+#include "cfgrtl.h" --+#include "cfganal.h" --+#include "lcm.h" --+#include "cfgbuild.h" --+#include "cfgcleanup.h" --+#include "predict.h" --+#include "basic-block.h" --+#include "bitmap.h" --+#include "df.h" --+#include "tm_p.h" --+#include "tm-constrs.h" --+#include "optabs.h" /* For GEN_FCN. */ --+#include "target.h" --+#include "langhooks.h" /* For add_builtin_function (). */ --+#include "ggc.h" --+#include "tree-pass.h" --+#include "tree-ssa-alias.h" --+#include "fold-const.h" --+#include "gimple-expr.h" --+#include "is-a.h" --+#include "gimple.h" --+#include "gimplify.h" --+#include "gimple-iterator.h" --+#include "gimplify-me.h" --+#include "gimple-ssa.h" --+#include "ipa-ref.h" --+#include "lto-streamer.h" --+#include "cgraph.h" --+#include "tree-cfg.h" --+#include "tree-phinodes.h" --+#include "stringpool.h" --+#include "tree-ssanames.h" --+#include "tree-pass.h" --+#include "gimple-pretty-print.h" --+#include "gimple-walk.h" --+ --+/* Indicate the translation unit whether including floating-point arithmetic --+ or not. */ --+bool nds32_include_fp_arith = false; --+ --+/* Return true if the return type and argument types of current function --+ pass the insepction. Furthermore, the global value NDS32_INCLUDE_FP_ARITH --+ is modified. */ --+ --+static bool --+nds32_acd_func_rtn_args_check (tree fn_decl) --+{ --+ tree fn_type = TREE_TYPE (fn_decl); --+ function_args_iterator iter; --+ tree arg_type = NULL_TREE; --+ tree rtn_type = NULL_TREE; --+ unsigned argno = 1; --+ --+ gcc_assert (fn_type); --+ --+ rtn_type = TREE_TYPE (fn_type); --+ if (dump_file) --+ { --+ fprintf (dump_file, --+ " Check the return & arguments for function %s\n" --+ " Prototype:", --+ fndecl_name (fn_decl)); --+ print_generic_decl (dump_file, fn_decl, 0); --+ fprintf (dump_file, "\n"); --+ } --+ --+ /* Check the return type. */ --+ if (FLOAT_TYPE_P (rtn_type) --+ || RECORD_OR_UNION_TYPE_P (rtn_type)) --+ { --+ if (dump_file) --+ fprintf (dump_file, " ! Return type is FP or record/union type\n"); --+ nds32_include_fp_arith = true; --+ --+ return false; --+ } --+ --+ /* Check if the function has a variable argument list. */ --+ if (stdarg_p (fn_type)) --+ { --+ if (dump_file) --+ fprintf (dump_file, " ! Has variable argument list (i.e. ,...)\n"); --+ nds32_include_fp_arith = true; --+ --+ return false; --+ } --+ --+ /* Check the arguments. */ --+ FOREACH_FUNCTION_ARGS (fn_type, arg_type, iter) --+ { --+ if (arg_type == void_type_node) --+ break; --+ --+ if (FLOAT_TYPE_P (arg_type) --+ || RECORD_OR_UNION_TYPE_P (arg_type)) --+ { --+ if (dump_file) --+ fprintf (dump_file, --+ " ! No.%d argument is FP or record/union type\n", --+ argno); --+ nds32_include_fp_arith = true; --+ --+ return false; --+ } --+ argno++; --+ } --+ --+ if (dump_file) --+ fprintf (dump_file, --+ " >> Pass the inspection of return & arguments type\n"); --+ --+ return true; --+} --+ --+/* Helper for nds32_abi_compatible. Return *TP if it is a floating-point --+ -related operand. */ --+ --+static tree --+nds32_acd_walk_op_fn (tree *tp, int *walk_subtrees, void *data ATTRIBUTE_UNUSED) --+{ --+ tree t = *tp; --+ --+ if (t && TREE_TYPE (t) --+ && (FLOAT_TYPE_P (TREE_TYPE (t)) --+ || TREE_CODE (t) == REAL_CST --+ || TREE_CODE (t) == COMPLEX_CST --+ || TREE_CODE (t) == FLOAT_EXPR --+ || TREE_CODE (t) == REALPART_EXPR)) --+ { --+ *walk_subtrees = 0; --+ return t; --+ } --+ --+ return NULL_TREE; --+} --+ --+/* Helper for nds32_abi_compatible. Return non-NULL tree and set --+ *HANDLED_OPS_P to true if *GSI_P is an ASM stmt. */ --+ --+static tree --+nds32_acd_walk_stmt_fn (gimple_stmt_iterator *gsi_p, bool *handled_ops_p, --+ struct walk_stmt_info *wi ATTRIBUTE_UNUSED) --+{ --+ gimple *stmt = gsi_stmt (*gsi_p); --+ --+ switch (gimple_code (stmt)) --+ { --+ case GIMPLE_DEBUG: --+ *handled_ops_p = true; --+ break; --+ --+ case GIMPLE_ASM: --+ *handled_ops_p = true; --+ return (tree) -1; --+ break; --+ --+ case GIMPLE_CALL: --+ { --+ tree call_decl = gimple_call_fndecl (stmt); --+ if (!call_decl --+ || !nds32_acd_func_rtn_args_check (call_decl)) --+ { --+ *handled_ops_p = true; --+ return call_decl; --+ } --+ } --+ break; --+ --+ default: --+ break; --+ } --+ --+ return NULL_TREE; --+} --+ --+/* This function is the entry of ABI compatible detection pass. */ --+ --+static int --+nds32_abi_compatible (void) --+{ --+ basic_block bb; --+ struct walk_stmt_info wi; --+ --+ memset (&wi, 0, sizeof (wi)); --+ --+ if (!nds32_acd_func_rtn_args_check (current_function_decl)) --+ return 0; --+ --+ if (dump_file) --+ fprintf (dump_file, "Check function body %s\n", --+ function_name (cfun)); --+ --+ FOR_EACH_BB_FN (bb, cfun) --+ { --+ gimple *ret; --+ gimple_seq seq = bb_seq (bb); --+ --+ ret = walk_gimple_seq (seq, --+ nds32_acd_walk_stmt_fn, --+ nds32_acd_walk_op_fn, --+ &wi); --+ if (ret != NULL) --+ { --+ if (dump_file) --+ { --+ fprintf (dump_file, " ! NO PASS: "); --+ print_gimple_stmt (dump_file, ret, 0, TDF_SLIM|TDF_RAW); --+ } --+ nds32_include_fp_arith = true; --+ break; --+ } --+ } --+ --+ if (dump_file) --+ if (!nds32_include_fp_arith) --+ fprintf (dump_file, --+ " >> Pass the inspection of FP operand for function body\n"); --+ --+ return 0; --+} --+ --+static bool --+gate_nds32_abi_compatible (void) --+{ --+ return flag_nds32_abi_compatible --+ && !nds32_include_fp_arith; --+} --+ --+const pass_data pass_data_nds32_abi_compatible = --+{ --+ GIMPLE_PASS, /* type */ --+ "abi_compatible", /* name */ --+ OPTGROUP_NONE, /* optinfo_flags */ --+ TV_MACH_DEP, /* tv_id */ --+ ( PROP_cfg | PROP_ssa ), /* properties_required */ --+ 0, /* properties_provided */ --+ 0, /* properties_destroyed */ --+ 0, /* todo_flags_start */ --+ 0, /* todo_flags_finish */ --+}; --+ --+class pass_nds32_abi_compatible : public gimple_opt_pass --+{ --+public: --+ pass_nds32_abi_compatible (gcc::context *ctxt) --+ : gimple_opt_pass (pass_data_nds32_abi_compatible, ctxt) --+ {} --+ --+ /* opt_pass methods: */ --+ bool gate (function *) { return gate_nds32_abi_compatible (); } --+ unsigned int execute (function *) { return nds32_abi_compatible (); } --+}; --+ --+gimple_opt_pass * --+make_pass_nds32_abi_compatible (gcc::context *ctxt) --+{ --+ return new pass_nds32_abi_compatible (ctxt); --+} --diff --git a/gcc/config/nds32/nds32-const-remater.c b/gcc/config/nds32/nds32-const-remater.c --new file mode 100644 --index 0000000..760e567 ----- /dev/null --+++ b/gcc/config/nds32/nds32-const-remater.c --@@ -0,0 +1,461 @@ --+/* Global CSE pass of Andes NDS32 cpu for GNU compiler --+ Copyright (C) 2012-2016 Free Software Foundation, Inc. --+ Contributed by Andes Technology Corporation. --+ --+ This file is part of GCC. --+ --+ GCC is free software; you can redistribute it and/or modify it --+ under the terms of the GNU General Public License as published --+ by the Free Software Foundation; either version 3, or (at your --+ option) any later version. --+ --+ GCC is distributed in the hope that it will be useful, but WITHOUT --+ ANY WARRANTY; without even the implied warranty of MERCHANTABILITY --+ or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public --+ License for more details. --+ --+ You should have received a copy of the GNU General Public License --+ along with GCC; see the file COPYING3. If not see --+ . */ --+ --+/* ------------------------------------------------------------------------ */ --+ --+#include "config.h" --+#include "system.h" --+#include "coretypes.h" --+#include "backend.h" --+#include "tree.h" --+#include "rtl.h" --+#include "df.h" --+#include "alias.h" --+#include "stor-layout.h" --+#include "varasm.h" --+#include "calls.h" --+#include "regs.h" --+#include "insn-config.h" /* Required by recog.h. */ --+#include "conditions.h" --+#include "output.h" --+#include "insn-attr.h" /* For DFA state_t. */ --+#include "insn-codes.h" /* For CODE_FOR_xxx. */ --+#include "reload.h" /* For push_reload(). */ --+#include "flags.h" --+#include "insn-config.h" --+#include "expmed.h" --+#include "dojump.h" --+#include "explow.h" --+#include "emit-rtl.h" --+#include "stmt.h" --+#include "expr.h" --+#include "recog.h" --+#include "diagnostic-core.h" --+#include "cfgrtl.h" --+#include "cfganal.h" --+#include "lcm.h" --+#include "cfgbuild.h" --+#include "cfgcleanup.h" --+#include "tm_p.h" --+#include "tm-constrs.h" --+#include "optabs.h" /* For GEN_FCN. */ --+#include "target.h" --+#include "langhooks.h" /* For add_builtin_function(). */ --+#include "builtins.h" --+#include "cpplib.h" --+#include "params.h" --+#include "tree-pass.h" --+#include "dbgcnt.h" --+#include "df.h" --+#include "tm-constrs.h" --+ --+/* ------------------------------------------------------------------------ */ --+ --+typedef struct reg_avail_info --+{ --+ rtx insn; --+ unsigned int uint; --+ unsigned int regno; --+} reg_avail_info_t; --+ --+ --+static void find_common_const (void); --+static bool try_rematerialize (rtx_insn *, unsigned int, --+ auto_vec *); --+static void clean_reg_avail_info (rtx ,const_rtx, void *); --+static rtx get_const (rtx); --+static bool addsi3_format_p (rtx); --+ --+/* Search the register records. */ --+static bool --+try_rematerialize (rtx_insn *insn, unsigned int uint_r, --+ auto_vec *reg_avail_infos) --+{ --+ unsigned int i, uint_i, cl_i, cl_r, ct_i, ct_r; --+ rtx pat, src, dest, new_insn; --+ bool done = FALSE; --+ df_ref df_rec; --+ df_link *link; --+ --+ cl_r = __builtin_clz (uint_r); --+ ct_r = __builtin_ctz (uint_r); --+ for (i = 0; i < reg_avail_infos->length (); ++i) --+ { --+ if ((*reg_avail_infos)[i].uint != uint_r) --+ { --+ uint_i = (*reg_avail_infos)[i].uint; --+ if (dump_file) --+ fprintf (dump_file, "Try rematerialize %08x with const %08x\n", --+ uint_r, uint_i); --+ cl_i = __builtin_clz (uint_i); --+ ct_i = __builtin_ctz (uint_i); --+ src = SET_DEST (PATTERN ((*reg_avail_infos)[i].insn)); --+ dest = SET_DEST (PATTERN (insn)); --+ --+ if (cl_r > cl_i --+ && (uint_i >> (cl_r - cl_i)) == uint_r) --+ { --+ /* Right shift logical. */ --+ pat = gen_rtx_LSHIFTRT (SImode, src, GEN_INT (cl_r - cl_i)); --+ done = TRUE; --+ if (dump_file) --+ fprintf (dump_file, --+ "Rematerialize %08x with const %08x by l>> %d\n", --+ uint_r, uint_i, (cl_r - cl_i)); --+ } --+ else if (ct_i >= ct_r --+ && ((int) uint_i >> (ct_i - ct_r)) == (int) uint_r) --+ { --+ /* Right shift arithmetic. */ --+ pat = gen_rtx_ASHIFTRT (SImode, src, GEN_INT (ct_i - ct_r)); --+ done = TRUE; --+ if (dump_file) --+ fprintf (dump_file, --+ "Rematerialize %08x with const %08x by a>> %d\n", --+ uint_r, uint_i, (cl_r - cl_i)); --+ } --+ else if (ct_r > ct_i --+ && (uint_i << (ct_r - ct_i)) == uint_r) --+ { --+ /* Left shift. */ --+ pat = gen_rtx_ASHIFT (SImode, src, GEN_INT (ct_r - ct_i)); --+ done = TRUE; --+ if (dump_file) --+ fprintf (dump_file, --+ "Rematerialize %08x with const %08x by << %d\n", --+ uint_r, uint_i, (ct_r - ct_i)); --+ } --+ else if (TARGET_EXT_PERF && __builtin_popcount (uint_r ^ uint_i) == 1) --+ { --+ unsigned int val = uint_r ^ uint_i; --+ if ((uint_r & (uint_r ^ uint_i)) != 0) --+ { --+ if (val > (1 << 5)) --+ { --+ /* Bit set. */ --+ pat = gen_rtx_IOR (SImode, src, GEN_INT (val)); --+ done = TRUE; --+ if (dump_file) --+ fprintf (dump_file, --+ "Rematerialize %08x with const %08x by | %08x\n", --+ uint_r, uint_i, uint_r ^ uint_i); --+ } --+ else --+ { --+ /* Transform to plus if immediate can fit addi45. */ --+ pat = gen_rtx_PLUS (SImode, src, GEN_INT (val)); --+ done = TRUE; --+ if (dump_file) --+ fprintf (dump_file, --+ "Rematerialize %08x with const %08x by | %08x\n", --+ uint_r, uint_i, uint_r ^ uint_i); --+ } --+ } --+ else --+ { --+ if (val > (1 << 5)) --+ { --+ /* Bit clear. */ --+ pat = gen_rtx_AND (SImode, src, GEN_INT (~(uint_r ^ uint_i))); --+ done = TRUE; --+ if (dump_file) --+ fprintf (dump_file, --+ "Rematerialize %08x with const %08x by & %08x\n", --+ uint_r, uint_i, ~(uint_r ^ uint_i)); --+ } --+ else --+ { --+ /* Transform to plus if immediate can fit subi45. */ --+ pat = gen_rtx_PLUS (SImode, src, GEN_INT ((int) -val)); --+ done = TRUE; --+ if (dump_file) --+ fprintf (dump_file, --+ "Rematerialize %08x with const %08x by | %08x\n", --+ uint_r, uint_i, uint_r ^ uint_i); --+ } --+ } --+ } --+ else if ((uint_r > uint_i ? uint_r - uint_i --+ : uint_i - uint_r) < 0x4000) --+ { --+ /* Check insn_info existence because the instruction --+ maybe be deleted.*/ --+ if (DF_INSN_INFO_GET ((*reg_avail_infos)[i].insn)) --+ { --+ df_rec = DF_INSN_DEFS ((*reg_avail_infos)[i].insn); --+ link = DF_REF_CHAIN (df_rec); --+ --+ /* Do not use the dead instruction. */ --+ /* Do not use the original matched sethi. */ --+ if (!link) --+ continue; --+ for (link = DF_REF_CHAIN (df_rec); link; link = link->next) --+ { --+ if (DF_REF_REGNO (link->ref) == 0 --+ || !DF_REF_INSN_INFO (link->ref) --+ || DF_REF_INSN (link->ref) == insn) --+ break; --+ } --+ if (link) --+ continue; --+ } --+ --+ /* Add. */ --+ if (uint_r > uint_i) --+ { --+ pat = gen_rtx_PLUS (SImode, src, GEN_INT (uint_r - uint_i)); --+ done = TRUE; --+ } --+ else --+ { --+ pat = gen_rtx_PLUS (SImode, src, GEN_INT ((HOST_WIDE_INT) --+ uint_r - uint_i)); --+ done = TRUE; --+ } --+ } --+ --+ if (done) --+ { --+ /* Emit the new instruction. */ --+ new_insn = gen_move_insn (dest, pat); --+ emit_insn_before (new_insn, insn); --+ set_dst_reg_note (new_insn, REG_EQUAL, GEN_INT (uint_r), dest); --+ return TRUE; --+ } --+ } --+ } --+ return FALSE; --+} --+ --+/* Clean the reg_avail_info value. */ --+static void --+clean_reg_avail_info (rtx dest, const_rtx setter ATTRIBUTE_UNUSED, --+ void *data) --+{ --+ unsigned int i; --+ auto_vec *reg_avail_infos = --+ (auto_vec *) data; --+ --+ if (GET_CODE (dest) == SUBREG) --+ dest = SUBREG_REG (dest); --+ --+ if (REG_P (dest)) --+ for (i = 0; i < reg_avail_infos->length (); ++i) --+ if ((*reg_avail_infos)[i].regno == REGNO (dest) --+ || (GET_MODE_SIZE (GET_MODE (dest)) == 8 --+ && (*reg_avail_infos)[i].regno == REGNO (dest) + 1)) --+ reg_avail_infos->unordered_remove (i--); --+} --+ --+/* Return the const if the setting value is a constant integer. */ --+static rtx --+get_const (rtx insn) --+{ --+ rtx note; --+ --+ if (GET_CODE (PATTERN (insn)) != SET --+ || !REG_P (SET_DEST (PATTERN (insn))) --+ || GET_MODE (SET_DEST (PATTERN (insn))) != SImode) --+ return NULL_RTX; --+ --+ /* Constant move instruction. */ --+ if (CONST_INT_P (XEXP (PATTERN (insn), 1))) --+ return XEXP (PATTERN (insn), 1); --+ --+ note = find_reg_note (insn, REG_EQUAL, NULL_RTX); --+ if (!note) --+ note = find_reg_note (insn, REG_EQUIV, NULL_RTX); --+ --+ if (note && CONST_INT_P (XEXP (note, 0))) --+ return XEXP (note, 0); --+ --+ return NULL_RTX; --+} --+ --+/* Return true if the instruction is addi format. */ --+static bool --+addsi3_format_p (rtx insn) --+{ --+ if (GET_CODE (XEXP (PATTERN (insn), 1)) == PLUS --+ && GET_CODE (XEXP (XEXP (PATTERN (insn), 1), 1)) == CONST_INT) --+ return TRUE; --+ --+ return FALSE; --+} --+ --+/* Return true if the instruction is sethi format. */ --+static bool --+sethi_format_p (rtx insn) --+{ --+ if (GET_CODE (PATTERN (insn)) == SET --+ && GET_CODE (XEXP (PATTERN (insn), 1)) == CONST_INT --+ && satisfies_constraint_Ihig (XEXP (PATTERN (insn), 1))) --+ return TRUE; --+ return FALSE; --+} --+ --+/* Return true if the register definition only be used by insn. */ --+static bool --+use_only_p (rtx insn) --+{ --+ rtx def_insn; --+ df_ref rec; --+ df_link *link; --+ rec = DF_INSN_USES (insn); --+ link = DF_REF_CHAIN (rec); --+ --+ if (!link --+ || DF_REF_REGNO (link->ref) == 0 --+ || !DF_REF_INSN_INFO (link->ref)) --+ return FALSE; --+ --+ def_insn = DF_REF_INSN (link->ref); --+ --+ if (!sethi_format_p (def_insn)) --+ return FALSE; --+ --+ rec = DF_INSN_DEFS (def_insn); --+ link = DF_REF_CHAIN (rec); --+ --+ if (!link --+ || link->next --+ || DF_REF_REGNO (link->ref) == 0 --+ || !DF_REF_INSN_INFO (link->ref)) --+ return FALSE; --+ --+ return TRUE; --+} --+ --+/* Traverse instructions in each basic block, and save the value of --+ setting constant instructions. */ --+static void --+find_common_const (void) --+{ --+ basic_block bb; --+ unsigned int i; --+ --+ /* Save register constant value. */ --+ auto_vec reg_avail_infos; --+ reg_avail_info_t reg_avail_info; --+ --+ --+ FOR_EACH_BB_FN (bb, cfun) --+ { --+ rtx_insn *insn; --+ rtx dest, cst; --+ --+ /* Clear the vector. */ --+ while (!reg_avail_infos.is_empty ()) --+ reg_avail_infos.pop (); --+ --+ FOR_BB_INSNS (bb, insn) --+ { --+ if (!NONDEBUG_INSN_P (insn)) --+ continue; --+ --+ if (CALL_P (insn)) --+ { --+ /* Clean hard register. */ --+ for (i = 0; i < reg_avail_infos.length ();) --+ { --+ if (HARD_REGISTER_NUM_P (reg_avail_infos[i].regno) --+ && call_used_regs[reg_avail_infos[i].regno]) --+ reg_avail_infos.unordered_remove (i); --+ else --+ ++i; --+ } --+ } --+ --+ cst = get_const (insn); --+ if (cst == NULL_RTX) --+ { --+ note_stores (PATTERN (insn), clean_reg_avail_info, --+ ®_avail_infos); --+ continue; --+ } --+ --+ dest = SET_DEST (PATTERN (insn)); --+ --+ if (addsi3_format_p (insn) --+ && use_only_p (insn) --+ && try_rematerialize (insn, XUINT (cst, 0), ®_avail_infos)) --+ { --+ delete_insn (insn); --+ df_insn_rescan_all (); --+ } --+ --+ note_stores (PATTERN (insn), clean_reg_avail_info, ®_avail_infos); --+ reg_avail_info.insn = insn; --+ reg_avail_info.uint = XUINT (cst, 0); --+ reg_avail_info.regno = REGNO (dest); --+ if (dump_file) --+ fprintf (dump_file, "Find const %08x on %u\n", --+ reg_avail_info.uint, reg_avail_info.regno); --+ reg_avail_infos.safe_push (reg_avail_info); --+ } --+ } --+} --+ --+static unsigned int --+nds32_const_remater_opt (void) --+{ --+ df_chain_add_problem (DF_DU_CHAIN + DF_UD_CHAIN); --+ df_note_add_problem (); --+ df_insn_rescan_all (); --+ df_analyze (); --+ --+ find_common_const (); --+ --+ df_insn_rescan_all (); --+ return 0; --+} --+ --+const pass_data pass_data_nds32_const_remater_opt = --+{ --+ RTL_PASS, /* type */ --+ "const_remater_opt", /* name */ --+ OPTGROUP_NONE, /* optinfo_flags */ --+ TV_MACH_DEP, /* tv_id */ --+ 0, /* properties_required */ --+ 0, /* properties_provided */ --+ 0, /* properties_destroyed */ --+ 0, /* todo_flags_start */ --+ TODO_df_finish, /* todo_flags_finish */ --+}; --+ --+class pass_nds32_const_remater_opt : public rtl_opt_pass --+{ --+public: --+ pass_nds32_const_remater_opt (gcc::context *ctxt) --+ : rtl_opt_pass (pass_data_nds32_const_remater_opt, ctxt) --+ {} --+ --+ /* opt_pass methods: */ --+ bool gate (function *) { return flag_nds32_const_remater_opt; } --+ unsigned int execute (function *) { return nds32_const_remater_opt (); } --+}; --+ --+rtl_opt_pass * --+make_pass_nds32_const_remater_opt (gcc::context *ctxt) --+{ --+ return new pass_nds32_const_remater_opt (ctxt); --+} --+ --+/* ------------------------------------------------------------------------ */ --diff --git a/gcc/config/nds32/nds32-cost.c b/gcc/config/nds32/nds32-cost.c --index e6a29fc..881d086 100644 ----- a/gcc/config/nds32/nds32-cost.c --+++ b/gcc/config/nds32/nds32-cost.c --@@ -24,73 +24,447 @@ -- #include "system.h" -- #include "coretypes.h" -- #include "backend.h" ---#include "target.h" ---#include "rtl.h" -- #include "tree.h" ---#include "tm_p.h" ---#include "optabs.h" /* For GEN_FCN. */ --+#include "rtl.h" --+#include "df.h" --+#include "alias.h" --+#include "stor-layout.h" --+#include "varasm.h" --+#include "calls.h" --+#include "regs.h" --+#include "insn-config.h" /* Required by recog.h. */ --+#include "conditions.h" --+#include "output.h" --+#include "insn-attr.h" /* For DFA state_t. */ --+#include "insn-codes.h" /* For CODE_FOR_xxx. */ --+#include "reload.h" /* For push_reload(). */ --+#include "flags.h" --+#include "insn-config.h" --+#include "expmed.h" --+#include "dojump.h" --+#include "explow.h" --+#include "emit-rtl.h" --+#include "stmt.h" --+#include "expr.h" -- #include "recog.h" --+#include "diagnostic-core.h" --+#include "cfgrtl.h" --+#include "cfganal.h" --+#include "lcm.h" --+#include "cfgbuild.h" --+#include "cfgcleanup.h" --+#include "tm_p.h" -- #include "tm-constrs.h" --+#include "optabs.h" /* For GEN_FCN. */ --+#include "target.h" --+#include "langhooks.h" /* For add_builtin_function(). */ --+#include "builtins.h" --+#include "tree-pass.h" -- -- /* ------------------------------------------------------------------------ */ -- ---bool ---nds32_rtx_costs_impl (rtx x, --- machine_mode mode ATTRIBUTE_UNUSED, --- int outer_code, --- int opno ATTRIBUTE_UNUSED, --- int *total, --- bool speed) ---{ --- int code = GET_CODE (x); --+typedef bool (*rtx_cost_func) (rtx, int, int, int, int*); -- --- /* According to 'speed', goto suitable cost model section. */ --- if (speed) --- goto performance_cost; --- else --- goto size_cost; --+struct rtx_cost_model_t { --+ rtx_cost_func speed_prefer; --+ rtx_cost_func size_prefer; --+}; -- --+static rtx_cost_model_t rtx_cost_model; -- ---performance_cost: --- /* This is section for performance cost model. */ --+static int insn_size_16bit; /* Initial at nds32_init_rtx_costs. */ --+static const int insn_size_32bit = 4; --+ --+static bool --+nds32_rtx_costs_speed_prefer (rtx x ATTRIBUTE_UNUSED, --+ int code, --+ int outer_code ATTRIBUTE_UNUSED, --+ int opno ATTRIBUTE_UNUSED, --+ int *total) --+{ --+ rtx op0; --+ rtx op1; --+ enum machine_mode mode = GET_MODE (x); --+ /* Scale cost by mode size. */ --+ int cost = COSTS_N_INSNS (GET_MODE_SIZE (mode) / GET_MODE_SIZE (SImode)); -- --- /* In gcc/rtl.h, the default value of COSTS_N_INSNS(N) is N*4. --- We treat it as 4-cycle cost for each instruction --- under performance consideration. */ -- switch (code) -- { --- case SET: --- /* For 'SET' rtx, we need to return false --- so that it can recursively calculate costs. */ --- return false; --- -- case USE: -- /* Used in combine.c as a marker. */ -- *total = 0; --- break; --+ return true; --+ --+ case CONST_INT: --+ /* When not optimizing for size, we care more about the cost --+ of hot code, and hot code is often in a loop. If a constant --+ operand needs to be forced into a register, we will often be --+ able to hoist the constant load out of the loop, so the load --+ should not contribute to the cost. */ --+ if (outer_code == SET || outer_code == PLUS) --+ *total = satisfies_constraint_Is20 (x) ? 0 : 4; --+ else if (outer_code == AND || outer_code == IOR || outer_code == XOR --+ || outer_code == MINUS) --+ *total = satisfies_constraint_Iu15 (x) ? 0 : 4; --+ else if (outer_code == ASHIFT || outer_code == ASHIFTRT --+ || outer_code == LSHIFTRT) --+ *total = satisfies_constraint_Iu05 (x) ? 0 : 4; --+ else if (GET_RTX_CLASS (outer_code) == RTX_COMPARE --+ || GET_RTX_CLASS (outer_code) == RTX_COMM_COMPARE) --+ *total = satisfies_constraint_Is16 (x) ? 0 : 4; --+ else --+ *total = COSTS_N_INSNS (1); --+ return true; --+ --+ case CONST: --+ case LO_SUM: --+ case HIGH: --+ case SYMBOL_REF: --+ *total = COSTS_N_INSNS (1); --+ return true; --+ --+ case MEM: --+ *total = COSTS_N_INSNS (1); --+ return true; --+ --+ case SET: --+ op0 = SET_DEST (x); --+ op1 = SET_SRC (x); --+ mode = GET_MODE (op0); --+ /* Scale cost by mode size. */ --+ cost = COSTS_N_INSNS (GET_MODE_SIZE (mode) / GET_MODE_SIZE (SImode)); --+ --+ switch (GET_CODE (op1)) --+ { --+ case REG: --+ case SUBREG: --+ /* Register move and Store instructions. */ --+ if ((REG_P (op0) || MEM_P (op0)) --+ && GET_MODE_SIZE (mode) <= GET_MODE_SIZE (DImode)) --+ *total = COSTS_N_INSNS (1); --+ else --+ *total = cost; --+ return true; --+ --+ case MEM: --+ /* Load instructions. */ --+ if (REG_P (op0) && GET_MODE_SIZE (mode) <= GET_MODE_SIZE (DImode)) --+ *total = COSTS_N_INSNS (1); --+ else --+ *total = cost; --+ return true; --+ --+ case CONST_INT: --+ /* movi instruction. */ --+ if (REG_P (op0) && GET_MODE_SIZE (mode) < GET_MODE_SIZE (DImode)) --+ { --+ if (satisfies_constraint_Is20 (op1)) --+ *total = COSTS_N_INSNS (1) - 1; --+ else --+ *total = COSTS_N_INSNS (2); --+ } --+ else --+ *total = cost; --+ return true; --+ --+ case CONST: --+ case SYMBOL_REF: --+ case LABEL_REF: --+ /* la instruction. */ --+ if (REG_P (op0) && GET_MODE_SIZE (mode) < GET_MODE_SIZE (DImode)) --+ *total = COSTS_N_INSNS (1) - 1; --+ else --+ *total = cost; --+ return true; --+ case VEC_SELECT: --+ *total = cost; --+ return true; --+ --+ default: --+ *total = cost; --+ return true; --+ } --+ --+ case PLUS: --+ op0 = XEXP (x, 0); --+ op1 = XEXP (x, 1); --+ --+ if (GET_MODE_SIZE (mode) >= GET_MODE_SIZE (DImode)) --+ *total = cost; --+ else if (GET_CODE (op0) == MULT || GET_CODE (op0) == LSHIFTRT --+ || GET_CODE (op1) == MULT || GET_CODE (op1) == LSHIFTRT) --+ { --+ /* ALU_SHIFT */ --+ if (TARGET_PIPELINE_PANTHER) --+ *total = COSTS_N_INSNS (1); --+ else --+ *total = COSTS_N_INSNS (2); --+ } --+ else if ((GET_CODE (op1) == CONST_INT --+ && satisfies_constraint_Is15 (op1)) --+ || REG_P (op1)) --+ /* ADD instructions */ --+ *total = COSTS_N_INSNS (1); --+ else --+ /* ADD instructions: IMM out of range. */ --+ *total = COSTS_N_INSNS (2); --+ return true; --+ --+ case MINUS: --+ op0 = XEXP (x, 0); --+ op1 = XEXP (x, 1); --+ --+ if (GET_MODE_SIZE (mode) >= GET_MODE_SIZE (DImode)) --+ *total = cost; --+ else if (GET_CODE (op0) == MULT || GET_CODE (op0) == LSHIFTRT --+ || GET_CODE (op1) == MULT || GET_CODE (op1) == LSHIFTRT) --+ { --+ /* ALU_SHIFT */ --+ if (TARGET_PIPELINE_PANTHER) --+ *total = COSTS_N_INSNS (1); --+ else --+ *total = COSTS_N_INSNS (2); --+ } --+ else if ((GET_CODE (op0) == CONST_INT --+ && satisfies_constraint_Is15 (op0)) --+ || REG_P (op0)) --+ /* SUB instructions */ --+ *total = COSTS_N_INSNS (1); --+ else --+ /* SUB instructions: IMM out of range. */ --+ *total = COSTS_N_INSNS (2); --+ return true; --+ --+ case TRUNCATE: --+ /* TRUNCATE and AND behavior is same. */ --+ *total = COSTS_N_INSNS (1); --+ return true; --+ --+ case AND: --+ case IOR: --+ case XOR: --+ op0 = XEXP (x, 0); --+ op1 = XEXP (x, 1); --+ --+ if (NDS32_EXT_DSP_P ()) --+ { --+ /* We prefer (and (ior) (ior)) than (ior (and) (and)) for --+ synthetize pk** and insb instruction. */ --+ if (code == AND && GET_CODE (op0) == IOR && GET_CODE (op1) == IOR) --+ return COSTS_N_INSNS (1); --+ --+ if (code == IOR && GET_CODE (op0) == AND && GET_CODE (op1) == AND) --+ return COSTS_N_INSNS (10); --+ } --+ --+ if (GET_MODE_SIZE (mode) >= GET_MODE_SIZE (DImode)) --+ *total = cost; --+ else if (GET_CODE (op0) == ASHIFT || GET_CODE (op0) == LSHIFTRT) --+ { --+ /* ALU_SHIFT */ --+ if (TARGET_PIPELINE_PANTHER) --+ *total = COSTS_N_INSNS (1); --+ else --+ *total = COSTS_N_INSNS (2); --+ } --+ else if ((GET_CODE (op1) == CONST_INT --+ && satisfies_constraint_Iu15 (op1)) --+ || REG_P (op1)) --+ /* AND, OR, XOR instructions */ --+ *total = COSTS_N_INSNS (1); --+ else if (code == AND || GET_CODE (op0) == NOT) --+ /* BITC instruction */ --+ *total = COSTS_N_INSNS (1); --+ else --+ /* AND, OR, XOR instructions: IMM out of range. */ --+ *total = COSTS_N_INSNS (2); --+ return true; -- -- case MULT: --+ if (GET_MODE (x) == DImode --+ || GET_CODE (XEXP (x, 1)) == SIGN_EXTEND --+ || GET_CODE (XEXP (x, 1)) == ZERO_EXTEND) --+ /* MUL instructions */ --+ *total = COSTS_N_INSNS (1); --+ else if (GET_MODE_SIZE (mode) >= GET_MODE_SIZE (DImode)) --+ *total = cost; --+ else if (outer_code == PLUS || outer_code == MINUS) --+ { --+ /* ALU_SHIFT */ --+ if (TARGET_PIPELINE_PANTHER) --+ *total = COSTS_N_INSNS (1); --+ else --+ *total = COSTS_N_INSNS (2); --+ } --+ else if ((GET_CODE (XEXP (x, 1)) == CONST_INT --+ && satisfies_constraint_Iu05 (XEXP (x, 1))) --+ || REG_P (XEXP (x, 1))) --+ /* MUL instructions */ --+ *total = COSTS_N_INSNS (1); --+ else --+ /* MUL instructions: IMM out of range. */ --+ *total = COSTS_N_INSNS (2); --+ --+ if (TARGET_MUL_SLOW) --+ *total += COSTS_N_INSNS (4); --+ --+ return true; --+ --+ case LSHIFTRT: --+ if (GET_MODE_SIZE (mode) >= GET_MODE_SIZE (DImode)) --+ *total = cost; --+ else if (outer_code == PLUS || outer_code == MINUS --+ || outer_code == AND || outer_code == IOR --+ || outer_code == XOR) --+ { --+ /* ALU_SHIFT */ --+ if (TARGET_PIPELINE_PANTHER) --+ *total = COSTS_N_INSNS (1); --+ else --+ *total = COSTS_N_INSNS (2); --+ } --+ else if ((GET_CODE (XEXP (x, 1)) == CONST_INT --+ && satisfies_constraint_Iu05 (XEXP (x, 1))) --+ || REG_P (XEXP (x, 1))) --+ /* SRL instructions */ --+ *total = COSTS_N_INSNS (1); --+ else --+ /* SRL instructions: IMM out of range. */ --+ *total = COSTS_N_INSNS (2); --+ return true; --+ --+ case ASHIFT: --+ if (GET_MODE_SIZE (mode) >= GET_MODE_SIZE (DImode)) --+ *total = cost; --+ else if (outer_code == AND || outer_code == IOR --+ || outer_code == XOR) --+ { --+ /* ALU_SHIFT */ --+ if (TARGET_PIPELINE_PANTHER) --+ *total = COSTS_N_INSNS (1); --+ else --+ *total = COSTS_N_INSNS (2); --+ } --+ else if ((GET_CODE (XEXP (x, 1)) == CONST_INT --+ && satisfies_constraint_Iu05 (XEXP (x, 1))) --+ || REG_P (XEXP (x, 1))) --+ /* SLL instructions */ --+ *total = COSTS_N_INSNS (1); --+ else --+ /* SLL instructions: IMM out of range. */ --+ *total = COSTS_N_INSNS (2); --+ return true; --+ --+ case ASHIFTRT: --+ case ROTATERT: --+ if (GET_MODE_SIZE (mode) >= GET_MODE_SIZE (DImode)) --+ *total = cost; --+ else if ((GET_CODE (XEXP (x, 1)) == CONST_INT --+ && satisfies_constraint_Iu05 (XEXP (x, 1))) --+ || REG_P (XEXP (x, 1))) --+ /* ROTR, SLL instructions */ --+ *total = COSTS_N_INSNS (1); --+ else --+ /* ROTR, SLL instructions: IMM out of range. */ --+ *total = COSTS_N_INSNS (2); --+ return true; --+ --+ case LT: --+ case LTU: --+ if (outer_code == SET) --+ { --+ if ((GET_CODE (XEXP (x, 1)) == CONST_INT --+ && satisfies_constraint_Iu15 (XEXP (x, 1))) --+ || REG_P (XEXP (x, 1))) --+ /* SLT, SLTI instructions */ --+ *total = COSTS_N_INSNS (1); --+ else --+ /* SLT, SLT instructions: IMM out of range. */ --+ *total = COSTS_N_INSNS (2); --+ } --+ else --+ /* branch */ --+ *total = COSTS_N_INSNS (2); --+ return true; --+ --+ case EQ: --+ case NE: --+ case GE: --+ case LE: --+ case GT: --+ /* branch */ --+ *total = COSTS_N_INSNS (2); --+ return true; --+ --+ case IF_THEN_ELSE: --+ if (GET_CODE (XEXP (x, 1)) == LABEL_REF) --+ /* branch */ --+ *total = COSTS_N_INSNS (2); --+ else --+ /* cmovz, cmovn instructions */ --+ *total = COSTS_N_INSNS (1); --+ return true; --+ --+ case LABEL_REF: --+ if (outer_code == IF_THEN_ELSE) --+ /* branch */ --+ *total = COSTS_N_INSNS (2); --+ else --+ *total = COSTS_N_INSNS (1); --+ return true; --+ --+ case ZERO_EXTEND: --+ case SIGN_EXTEND: --+ if (MEM_P (XEXP (x, 0))) --+ /* Using memory access. */ --+ *total = COSTS_N_INSNS (1); --+ else --+ /* Zero extend and sign extend instructions. */ --+ *total = COSTS_N_INSNS (1); --+ return true; --+ --+ case NEG: --+ case NOT: -- *total = COSTS_N_INSNS (1); --- break; --+ return true; -- -- case DIV: -- case UDIV: -- case MOD: -- case UMOD: --- *total = COSTS_N_INSNS (7); --- break; --+ *total = COSTS_N_INSNS (20); --+ return true; -- --- default: --+ case CALL: --+ *total = COSTS_N_INSNS (2); --+ return true; --+ --+ case CLZ: --+ case SMIN: --+ case SMAX: --+ case ZERO_EXTRACT: --+ if (TARGET_EXT_PERF) --+ *total = COSTS_N_INSNS (1); --+ else --+ *total = COSTS_N_INSNS (3); --+ return true; --+ case VEC_SELECT: -- *total = COSTS_N_INSNS (1); --- break; --- } --- --- return true; --- --+ return true; -- ---size_cost: --- /* This is section for size cost model. */ --+ default: --+ *total = COSTS_N_INSNS (3); --+ return true; --+ } --+} -- --+static bool --+nds32_rtx_costs_size_prefer (rtx x, --+ int code, --+ int outer_code, --+ int opno ATTRIBUTE_UNUSED, --+ int *total) --+{ -- /* In gcc/rtl.h, the default value of COSTS_N_INSNS(N) is N*4. -- We treat it as 4-byte cost for each instruction -- under code size consideration. */ --@@ -98,7 +472,7 @@ size_cost: -- { -- case SET: -- /* For 'SET' rtx, we need to return false --- so that it can recursively calculate costs. */ --+ so that it can recursively calculate costs. */ -- return false; -- -- case USE: --@@ -108,92 +482,169 @@ size_cost: -- -- case CONST_INT: -- /* All instructions involving constant operation --- need to be considered for cost evaluation. */ --+ need to be considered for cost evaluation. */ -- if (outer_code == SET) -- { -- /* (set X imm5s), use movi55, 2-byte cost. -- (set X imm20s), use movi, 4-byte cost. -- (set X BIG_INT), use sethi/ori, 8-byte cost. */ -- if (satisfies_constraint_Is05 (x)) --- *total = COSTS_N_INSNS (1) - 2; --+ *total = insn_size_16bit; -- else if (satisfies_constraint_Is20 (x)) --- *total = COSTS_N_INSNS (1); --+ *total = insn_size_32bit; -- else --- *total = COSTS_N_INSNS (2); --+ *total = insn_size_32bit * 2; -- } -- else if (outer_code == PLUS || outer_code == MINUS) -- { -- /* Possible addi333/subi333 or subi45/addi45, 2-byte cost. -- General case, cost 1 instruction with 4-byte. */ -- if (satisfies_constraint_Iu05 (x)) --- *total = COSTS_N_INSNS (1) - 2; --+ *total = insn_size_16bit; -- else --- *total = COSTS_N_INSNS (1); --+ *total = insn_size_32bit; -- } -- else if (outer_code == ASHIFT) -- { -- /* Possible slli333, 2-byte cost. -- General case, cost 1 instruction with 4-byte. */ -- if (satisfies_constraint_Iu03 (x)) --- *total = COSTS_N_INSNS (1) - 2; --+ *total = insn_size_16bit; -- else --- *total = COSTS_N_INSNS (1); --+ *total = insn_size_32bit; -- } -- else if (outer_code == ASHIFTRT || outer_code == LSHIFTRT) -- { -- /* Possible srai45 or srli45, 2-byte cost. -- General case, cost 1 instruction with 4-byte. */ -- if (satisfies_constraint_Iu05 (x)) --- *total = COSTS_N_INSNS (1) - 2; --+ *total = insn_size_16bit; -- else --- *total = COSTS_N_INSNS (1); --+ *total = insn_size_32bit; -- } -- else -- { -- /* For other cases, simply set it 4-byte cost. */ --- *total = COSTS_N_INSNS (1); --+ *total = insn_size_32bit; -- } -- break; -- -- case CONST_DOUBLE: -- /* It requires high part and low part processing, set it 8-byte cost. */ --- *total = COSTS_N_INSNS (2); --+ *total = insn_size_32bit * 2; --+ break; --+ --+ case CONST: --+ case SYMBOL_REF: --+ *total = insn_size_32bit * 2; -- break; -- -- default: -- /* For other cases, generally we set it 4-byte cost --- and stop resurively traversing. */ --- *total = COSTS_N_INSNS (1); --+ and stop resurively traversing. */ --+ *total = insn_size_32bit; -- break; -- } -- -- return true; -- } -- ---int ---nds32_address_cost_impl (rtx address, --- machine_mode mode ATTRIBUTE_UNUSED, --- addr_space_t as ATTRIBUTE_UNUSED, --- bool speed) --+void --+nds32_init_rtx_costs (void) --+{ --+ rtx_cost_model.speed_prefer = nds32_rtx_costs_speed_prefer; --+ rtx_cost_model.size_prefer = nds32_rtx_costs_size_prefer; --+ --+ if (TARGET_16_BIT) --+ insn_size_16bit = 2; --+ else --+ insn_size_16bit = 4; --+} --+ --+/* This target hook describes the relative costs of RTL expressions. --+ Return 'true' when all subexpressions of x have been processed. --+ Return 'false' to sum the costs of sub-rtx, plus cost of this operation. --+ Refer to gcc/rtlanal.c for more information. */ --+bool --+nds32_rtx_costs_impl (rtx x, --+ machine_mode mode ATTRIBUTE_UNUSED, --+ int outer_code, --+ int opno, --+ int *total, --+ bool speed) --+{ --+ int code = GET_CODE (x); --+ --+ /* According to 'speed', use suitable cost model section. */ --+ if (speed) --+ return rtx_cost_model.speed_prefer(x, code, outer_code, opno, total); --+ else --+ return rtx_cost_model.size_prefer(x, code, outer_code, opno, total); --+} --+ --+ --+int nds32_address_cost_speed_prefer (rtx address) -- { -- rtx plus0, plus1; -- enum rtx_code code; -- -- code = GET_CODE (address); -- --- /* According to 'speed', goto suitable cost model section. */ --- if (speed) --- goto performance_cost; --- else --- goto size_cost; --+ switch (code) --+ { --+ case POST_MODIFY: --+ case POST_INC: --+ case POST_DEC: --+ /* We encourage that rtx contains --+ POST_MODIFY/POST_INC/POST_DEC behavior. */ --+ return COSTS_N_INSNS (1) - 2; --+ --+ case SYMBOL_REF: --+ /* We can have gp-relative load/store for symbol_ref. --+ Have it 4-byte cost. */ --+ return COSTS_N_INSNS (2); --+ --+ case CONST: --+ /* It is supposed to be the pattern (const (plus symbol_ref const_int)). --+ Have it 4-byte cost. */ --+ return COSTS_N_INSNS (2); --+ --+ case REG: --+ /* Simply return 4-byte costs. */ --+ return COSTS_N_INSNS (1) - 2; --+ --+ case PLUS: --+ /* We do not need to check if the address is a legitimate address, --+ because this hook is never called with an invalid address. --+ But we better check the range of --+ const_int value for cost, if it exists. */ --+ plus0 = XEXP (address, 0); --+ plus1 = XEXP (address, 1); --+ --+ if (REG_P (plus0) && CONST_INT_P (plus1)) --+ return COSTS_N_INSNS (1) - 2; --+ else if (ARITHMETIC_P (plus0) || ARITHMETIC_P (plus1)) --+ return COSTS_N_INSNS (1) - 1; --+ else if (REG_P (plus0) && REG_P (plus1)) --+ return COSTS_N_INSNS (1); --+ --+ /* For other 'plus' situation, make it cost 4-byte. */ --+ return COSTS_N_INSNS (1); -- ---performance_cost: --- /* This is section for performance cost model. */ --+ default: --+ break; --+ } -- --- /* FALLTHRU, currently we use same cost model as size_cost. */ --+ return COSTS_N_INSNS (4); -- ---size_cost: --- /* This is section for size cost model. */ --+} --+ --+int nds32_address_cost_speed_fwprop (rtx address) --+{ --+ rtx plus0, plus1; --+ enum rtx_code code; --+ --+ code = GET_CODE (address); -- -- switch (code) -- { --@@ -201,18 +652,18 @@ size_cost: -- case POST_INC: -- case POST_DEC: -- /* We encourage that rtx contains --- POST_MODIFY/POST_INC/POST_DEC behavior. */ --+ POST_MODIFY/POST_INC/POST_DEC behavior. */ -- return 0; -- -- case SYMBOL_REF: -- /* We can have gp-relative load/store for symbol_ref. --- Have it 4-byte cost. */ --- return COSTS_N_INSNS (1); --+ Have it 4-byte cost. */ --+ return COSTS_N_INSNS (2); -- -- case CONST: -- /* It is supposed to be the pattern (const (plus symbol_ref const_int)). --- Have it 4-byte cost. */ --- return COSTS_N_INSNS (1); --+ Have it 4-byte cost. */ --+ return COSTS_N_INSNS (2); -- -- case REG: -- /* Simply return 4-byte costs. */ --@@ -220,21 +671,25 @@ size_cost: -- -- case PLUS: -- /* We do not need to check if the address is a legitimate address, --- because this hook is never called with an invalid address. --- But we better check the range of --- const_int value for cost, if it exists. */ --+ because this hook is never called with an invalid address. --+ But we better check the range of --+ const_int value for cost, if it exists. */ -- plus0 = XEXP (address, 0); -- plus1 = XEXP (address, 1); -- -- if (REG_P (plus0) && CONST_INT_P (plus1)) --- { --+ { -- /* If it is possible to be lwi333/swi333 form, -- make it 2-byte cost. */ --- if (satisfies_constraint_Iu05 (plus1)) --+ if (satisfies_constraint_Iu03 (plus1)) -- return (COSTS_N_INSNS (1) - 2); -- else -- return COSTS_N_INSNS (1); -- } --+ if (ARITHMETIC_P (plus0) || ARITHMETIC_P (plus1)) --+ return COSTS_N_INSNS (1) - 2; --+ else if (REG_P (plus0) && REG_P (plus1)) --+ return COSTS_N_INSNS (1); -- -- /* For other 'plus' situation, make it cost 4-byte. */ -- return COSTS_N_INSNS (1); --@@ -246,4 +701,84 @@ size_cost: -- return COSTS_N_INSNS (4); -- } -- --+ --+int nds32_address_cost_size_prefer (rtx address) --+{ --+ rtx plus0, plus1; --+ enum rtx_code code; --+ --+ code = GET_CODE (address); --+ --+ switch (code) --+ { --+ case POST_MODIFY: --+ case POST_INC: --+ case POST_DEC: --+ /* We encourage that rtx contains --+ POST_MODIFY/POST_INC/POST_DEC behavior. */ --+ return 0; --+ --+ case SYMBOL_REF: --+ /* We can have gp-relative load/store for symbol_ref. --+ Have it 4-byte cost. */ --+ return COSTS_N_INSNS (2); --+ --+ case CONST: --+ /* It is supposed to be the pattern (const (plus symbol_ref const_int)). --+ Have it 4-byte cost. */ --+ return COSTS_N_INSNS (2); --+ --+ case REG: --+ /* Simply return 4-byte costs. */ --+ return COSTS_N_INSNS (1) - 1; --+ --+ case PLUS: --+ /* We do not need to check if the address is a legitimate address, --+ because this hook is never called with an invalid address. --+ But we better check the range of --+ const_int value for cost, if it exists. */ --+ plus0 = XEXP (address, 0); --+ plus1 = XEXP (address, 1); --+ --+ if (REG_P (plus0) && CONST_INT_P (plus1)) --+ { --+ /* If it is possible to be lwi333/swi333 form, --+ make it 2-byte cost. */ --+ if (satisfies_constraint_Iu03 (plus1)) --+ return (COSTS_N_INSNS (1) - 2); --+ else --+ return COSTS_N_INSNS (1) - 1; --+ } --+ --+ /* (plus (reg) (mult (reg) (const))) */ --+ if (ARITHMETIC_P (plus0) || ARITHMETIC_P (plus1)) --+ return (COSTS_N_INSNS (1) - 1); --+ --+ /* For other 'plus' situation, make it cost 4-byte. */ --+ return COSTS_N_INSNS (1); --+ --+ default: --+ break; --+ } --+ --+ return COSTS_N_INSNS (4); --+ --+} --+ --+int nds32_address_cost_impl (rtx address, --+ enum machine_mode mode ATTRIBUTE_UNUSED, --+ addr_space_t as ATTRIBUTE_UNUSED, --+ bool speed_p) --+{ --+ if (speed_p) --+ { --+ if (current_pass->tv_id == TV_FWPROP) --+ return nds32_address_cost_speed_fwprop (address); --+ else --+ return nds32_address_cost_speed_prefer (address); --+ } --+ else --+ return nds32_address_cost_size_prefer (address); --+} --+ -- /* ------------------------------------------------------------------------ */ --diff --git a/gcc/config/nds32/nds32-cprop-acc.c b/gcc/config/nds32/nds32-cprop-acc.c --new file mode 100644 --index 0000000..0852095 ----- /dev/null --+++ b/gcc/config/nds32/nds32-cprop-acc.c --@@ -0,0 +1,845 @@ --+/* Copy propagation on hard registers for accumulate style instruction. --+ Copyright (C) 2000-2014 Free Software Foundation, Inc. --+ --+ This file is part of GCC. --+ --+ GCC is free software; you can redistribute it and/or modify it --+ under the terms of the GNU General Public License as published by --+ the Free Software Foundation; either version 3, or (at your option) --+ any later version. --+ --+ GCC is distributed in the hope that it will be useful, but WITHOUT --+ ANY WARRANTY; without even the implied warranty of MERCHANTABILITY --+ or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public --+ License for more details. --+ --+ You should have received a copy of the GNU General Public License --+ along with GCC; see the file COPYING3. If not see --+ . */ --+ --+#include "config.h" --+#include "system.h" --+#include "coretypes.h" --+#include "tm.h" --+#include "rtl.h" --+#include "tm_p.h" --+#include "insn-config.h" --+#include "regs.h" --+#include "addresses.h" --+#include "predict.h" --+#include "basic-block.h" --+#include "reload.h" --+#include "hash-set.h" --+#include "dominance.h" --+#include "cfg.h" --+#include "function.h" --+#include "recog.h" --+#include "cfgrtl.h" --+#include "flags.h" --+#include "diagnostic-core.h" --+#include "obstack.h" --+#include "tree-pass.h" --+#include "bitmap.h" --+#include "df.h" --+#include "output.h" --+#include "emit-rtl.h" --+#include --+ --+/* For each move instruction, we have a two-dimensional vector that record --+ what insns need to replace the operands when the move instruction is --+ propagated. */ --+ --+typedef std::vector insn_list; --+ --+/* Function called by note_uses to replace used subexpressions. */ --+ --+struct replace_src_operands_data --+{ --+ rtx dst_reg; --+ rtx src_reg; --+ unsigned int old_regno; --+ unsigned int new_regno; --+ rtx_insn *insn; --+}; --+ --+/* Return true if a mode change from ORIG to NEW is allowed for REGNO. --+ Adapted from mode_change_ok in regcprop. */ --+ --+static bool --+nds32_mode_change_ok (enum machine_mode orig_mode, enum machine_mode new_mode, --+ unsigned int regno ATTRIBUTE_UNUSED) --+{ --+ if (GET_MODE_SIZE (orig_mode) < GET_MODE_SIZE (new_mode)) --+ return false; --+ --+#ifdef CANNOT_CHANGE_MODE_CLASS --+ return !REG_CANNOT_CHANGE_MODE_P (regno, orig_mode, new_mode); --+#endif --+ --+ return true; --+} --+ --+/* Register REGNO was originally set in ORIG_MODE. It - or a copy of it - --+ was copied in COPY_MODE to COPY_REGNO, and then COPY_REGNO was accessed --+ in NEW_MODE. --+ Return a NEW_MODE rtx for REGNO if that's OK, otherwise return NULL_RTX. --+ Adapted from maybe_mode_change in regcprop. */ --+ --+static rtx --+nds32_mode_change_reg (enum machine_mode orig_mode, enum machine_mode copy_mode, --+ enum machine_mode new_mode, unsigned int regno, --+ unsigned int copy_regno ATTRIBUTE_UNUSED) --+{ --+ if (GET_MODE_SIZE (copy_mode) < GET_MODE_SIZE (orig_mode) --+ && GET_MODE_SIZE (copy_mode) < GET_MODE_SIZE (new_mode)) --+ return NULL_RTX; --+ --+ if (orig_mode == new_mode) --+ return gen_raw_REG (new_mode, regno); --+ else if (nds32_mode_change_ok (orig_mode, new_mode, regno)) --+ { --+ int copy_nregs = hard_regno_nregs[copy_regno][copy_mode]; --+ int use_nregs = hard_regno_nregs[copy_regno][new_mode]; --+ int copy_offset --+ = GET_MODE_SIZE (copy_mode) / copy_nregs * (copy_nregs - use_nregs); --+ int offset --+ = GET_MODE_SIZE (orig_mode) - GET_MODE_SIZE (new_mode) - copy_offset; --+ int byteoffset = offset % UNITS_PER_WORD; --+ int wordoffset = offset - byteoffset; --+ --+ offset = ((WORDS_BIG_ENDIAN ? wordoffset : 0) --+ + (BYTES_BIG_ENDIAN ? byteoffset : 0)); --+ regno += subreg_regno_offset (regno, orig_mode, offset, new_mode); --+ if (HARD_REGNO_MODE_OK (regno, new_mode)) --+ return gen_raw_REG (new_mode, regno); --+ } --+ return NULL_RTX; --+} --+ --+/* Return true if INSN is a register-based move instruction, false --+ otherwise. */ --+ --+static bool --+nds32_is_reg_mov_p (rtx_insn *insn) --+{ --+ rtx pat = PATTERN (insn); --+ --+ if (GET_CODE (pat) != SET) --+ return false; --+ --+ rtx src_reg = SET_SRC (pat); --+ rtx dst_reg = SET_DEST (pat); --+ --+ if (REG_P (dst_reg) && REG_P (src_reg) && can_copy_p (GET_MODE (dst_reg))) --+ return true; --+ else --+ return false; --+} --+ --+ --+/* Return accumulated register if INSN is an accumulate style instruction, --+ otherwise return NULL_RTX. */ --+ --+static rtx --+nds32_is_acc_insn_p (rtx_insn *insn) --+{ --+ int i; --+ const operand_alternative *op_alt; --+ rtx pat; --+ --+ if (get_attr_length (insn) != 4) --+ return NULL_RTX; --+ --+ pat = PATTERN (insn); --+ if (GET_CODE (pat) != SET) --+ return NULL_RTX; --+ --+ /* Try to get the insn data from recog_data. */ --+ recog_memoized (insn); --+ extract_constrain_insn (insn); --+ /* Transform the constraint strings into a more usable form, --+ recog_op_alt. */ --+ preprocess_constraints (insn); --+ op_alt = which_op_alt (); --+ --+ /* Check all operands whether the output operand is identical to --+ another input operand */ --+ for (i = 0; i < recog_data.n_operands; ++i) --+ { --+ int matches = op_alt[i].matches; --+ int matched = op_alt[i].matched; --+ if ((matches >= 0 --+ && (recog_data.operand_type[i] != OP_IN --+ || recog_data.operand_type[matches] != OP_IN)) --+ || (matched >= 0 --+ && (recog_data.operand_type[i] != OP_IN --+ || recog_data.operand_type[matched] != OP_IN))) --+ return recog_data.operand[i]; --+ } --+ --+ return NULL_RTX; --+} --+ --+/* Finds the reference corresponding to the definition of register whose --+ register number is REGNO in INSN. DF is the dataflow object. --+ Adapted from df_find_def in df-core. */ --+ --+static df_ref --+nds32_df_find_regno_def (rtx_insn *insn, unsigned int regno) --+{ --+ df_ref def; --+ --+ FOR_EACH_INSN_DEF (def, insn) --+ if (DF_REF_REGNO (def) == regno) --+ return def; --+ --+ return NULL; --+ } --+ --+/* Return true if the REG in INSN is only defined by one insn whose uid --+ is DEF_UID, otherwise return false. */ --+ --+static bool --+nds32_is_single_def_p (rtx_insn *insn, rtx reg, unsigned int def_uid) --+{ --+ df_ref use; --+ --+ FOR_EACH_INSN_USE (use, insn) --+ { --+ df_link *link; --+ unsigned int uid; --+ --+ if (DF_REF_REGNO (use) >= REGNO (reg) --+ && DF_REF_REGNO (use) < END_REGNO (reg)) --+ { --+ link = DF_REF_CHAIN (use); --+ if (link->next --+ || DF_REF_IS_ARTIFICIAL (link->ref)) --+ return false; --+ --+ uid = DF_REF_INSN_UID (link->ref); --+ if (uid != def_uid) --+ return false; --+ } --+ } --+ --+ return true; --+} --+ --+/* Return true if there is no definition of REG on any path from the insn --+ whose uid is FROM_UID (called FROM) to insn TO, otherwise return false. --+ This function collects the reaching definitions bitmap at insn TO, and --+ check if all uses of REG in insn FROM can reach insn TO. */ --+ --+static bool --+nds32_no_define_reg_p (rtx to, rtx reg, unsigned int from_uid) --+{ --+ basic_block bb = BLOCK_FOR_INSN (to); --+ struct df_rd_bb_info *bb_info = DF_RD_BB_INFO (bb); --+ bitmap_head rd_local; --+ bool result = true; --+ rtx_insn *insn; --+ df_ref use; --+ df_insn_info *insn_info; --+ --+ bitmap_initialize (&rd_local, &bitmap_default_obstack); --+ bitmap_copy (&rd_local, &bb_info->in); --+ df_rd_simulate_artificial_defs_at_top (bb, &rd_local); --+ --+ for (insn = BB_HEAD (bb); insn != to; insn = NEXT_INSN (insn)) --+ if (INSN_P (insn)) --+ df_rd_simulate_one_insn (bb, insn, &rd_local); --+ --+ if (dump_file) --+ { --+ fprintf (dump_file, "scan reach define:"); --+ print_rtl_single (dump_file, to); --+ --+ fprintf (dump_file, "bb rd in:\n"); --+ dump_bitmap (dump_file, &bb_info->in); --+ --+ fprintf (dump_file, "reach def:\n"); --+ dump_bitmap (dump_file, &rd_local); --+ } --+ --+ insn_info = DF_INSN_UID_GET (from_uid); --+ FOR_EACH_INSN_INFO_USE (use, insn_info) --+ { --+ df_link *link; --+ --+ if (DF_REF_REGNO (use) >= REGNO (reg) --+ && DF_REF_REGNO (use) < END_REGNO (reg)) --+ for (link = DF_REF_CHAIN (use); link; link = link->next) --+ { --+ if (dump_file) --+ { --+ fprintf (dump_file, "use ID %d\n", DF_REF_ID (link->ref)); --+ if (DF_REF_IS_ARTIFICIAL (link->ref)) --+ fprintf (dump_file, "use ref is artificial\n"); --+ else --+ { --+ fprintf (dump_file, "use from insn:"); --+ print_rtl_single (dump_file, DF_REF_INSN (link->ref)); --+ } --+ } --+ result &= --+ (bitmap_bit_p (&rd_local, DF_REF_ID (link->ref))) --+ ? true --+ : false; --+ } --+ } --+ --+ bitmap_clear (&rd_local); --+ return result; --+} --+ --+/* Return true if the value held by REG is no longer needed before INSN --+ (i.e. REG is dead before INSN), otherwise return false. */ --+ --+static bool --+nds32_is_dead_reg_p (rtx_insn *insn, rtx reg) --+{ --+ basic_block bb = BLOCK_FOR_INSN (insn); --+ bitmap live = BITMAP_ALLOC (®_obstack); --+ bool result = true; --+ rtx_insn *i; --+ unsigned int rn; --+ --+ bitmap_copy (live, DF_LR_IN (bb)); --+ df_simulate_initialize_forwards (bb, live); --+ --+ for (i = BB_HEAD (bb); i != insn; i = NEXT_INSN (i)) --+ df_simulate_one_insn_forwards (bb, i, live); --+ --+ if (dump_file) --+ { --+ fprintf (dump_file, "scan live regs:"); --+ print_rtl_single (dump_file, insn); --+ --+ fprintf (dump_file, "bb lr in:\n"); --+ dump_bitmap (dump_file, DF_LR_IN (bb)); --+ --+ fprintf (dump_file, "live:\n"); --+ dump_bitmap (dump_file, live); --+ } --+ --+ for (rn = REGNO (reg); rn < END_REGNO (reg); ++rn) --+ result &= (bitmap_bit_p (live, rn)) ? false : true; --+ --+ BITMAP_FREE (live); --+ return result; --+} --+ --+/* Return true if START can do propagation. Notice START maybe a move --+ instruction or an accumulate style instruction. --+ MOV_UID is the uid of beginning move instruction that is only used by --+ function nds32_no_define_reg_p. --+ DST_REG & SRC_REG is the SET_DEST and SET_SRC of a move instruction that --+ maybe real or unreal, respectively. --+ INDEX indicates what number sequence is currently considered rank as --+ consecutive hard registers. Simultaneously, INDEX is the index of row in --+ INSN_LISTS. */ --+ --+static bool --+nds32_can_cprop_acc_1 (rtx_insn *start, unsigned int mov_uid, --+ rtx dst_reg, rtx src_reg, --+ unsigned int index, --+ std::vector &insn_lists) --+{ --+ unsigned int lead_regno = REGNO (dst_reg) + index; --+ unsigned int new_regno = REGNO (src_reg) + index; --+ df_ref def_rec; --+ df_link *link; --+ --+ def_rec = nds32_df_find_regno_def (start, lead_regno); --+ gcc_assert (def_rec); --+ --+ for (link = DF_REF_CHAIN (def_rec); link; link = link->next) --+ { --+ rtx *use_loc; --+ unsigned int use_regno; --+ enum machine_mode use_mode; --+ rtx_insn *use_insn; --+ rtx acc_reg, new_src; --+ --+ if (DF_REF_IS_ARTIFICIAL (link->ref)) --+ return false; --+ --+ use_loc = DF_REF_LOC (link->ref); --+ gcc_assert (use_loc && REG_P (*use_loc)); --+ --+ use_regno = REGNO (*use_loc); --+ /* Do not propagate when any insns use register that regno is --+ smaller than DST_REG. */ --+ if (use_regno < REGNO (dst_reg)) --+ return false; --+ --+ /* This status should be handled by previous call. */ --+ if (use_regno < lead_regno) --+ continue; --+ --+ /* Do not propagate because not all of the pieces of the copy came --+ from DST_REG. */ --+ if (END_REGNO (*use_loc) > END_REGNO (dst_reg)) --+ return false; --+ --+ use_insn = DF_REF_INSN (link->ref); --+ /* Do not propagate since call-used registers can't be replaced. */ --+ if (CALL_P (use_insn)) --+ return false; --+ --+ /* Do not replace in asms intentionally referencing hard registers. */ --+ if (asm_noperands (PATTERN (use_insn)) >= 0 --+ && use_regno == ORIGINAL_REGNO (*use_loc)) --+ return false; --+ --+ /* Do not propagate when the register is defined by more than one --+ instruction. */ --+ if (!nds32_is_single_def_p (use_insn, *use_loc, INSN_UID (start))) --+ return false; --+ --+ use_mode = GET_MODE (*use_loc); --+ new_src = nds32_mode_change_reg (GET_MODE (src_reg), --+ GET_MODE (dst_reg), --+ use_mode, --+ new_regno, --+ use_regno); --+ /* Do not propagate if we can't generate a new register with new mode. */ --+ if (!new_src) --+ return false; --+ --+ /* Can not replace DST_REG with SRC_REG when SRC_REG is redefined between --+ START and use insn of START. */ --+ if (!nds32_no_define_reg_p (use_insn, new_src, mov_uid)) --+ return false; --+ --+ acc_reg = nds32_is_acc_insn_p (use_insn); --+ /* Handle the accumulate style instruction that accumulate register --+ may be replaced. --+ Also handle the AUTO_INC register that is another form of accumulated --+ register. */ --+ if ((acc_reg && rtx_equal_p (acc_reg, *use_loc)) --+ || FIND_REG_INC_NOTE (use_insn, *use_loc)) --+ { --+ unsigned int i, use_nregs; --+ --+ /* ACC_REG can't be replaced since the SRC_REG can't be --+ overwritten. */ --+ if (!nds32_is_dead_reg_p (use_insn, new_src)) --+ return false; --+ --+ /* Once we confirm that ACC_REG can be replaced, the unreal move --+ instruction is generated. For example: --+ mov r0, r1 mov r0, r1 --+ cmovn r0, r2, r3 -> cmovn r1, r2, r3 --+ mov r0, r1 --+ If the unreal move instruction can do propagation, the ACC_REG --+ can be replaced. We check it in a recursive way. */ --+ use_nregs = hard_regno_nregs [use_regno][(int) use_mode]; --+ for (i = 0; i < use_nregs; ++i) --+ if (!nds32_can_cprop_acc_1 (use_insn, mov_uid, --+ *use_loc, new_src, --+ i, insn_lists)) --+ return false; --+ } --+ insn_lists[index].push_back (use_insn); --+ } --+ --+ return true; --+} --+ --+/* Return true if MOV can do propagation, otherwise return false. --+ INSN_LISTS is used to record what insns need to replace the operands. */ --+ --+static bool --+nds32_can_cprop_acc (rtx_insn *mov, std::vector &insn_lists) --+{ --+ rtx dst_reg = SET_DEST (PATTERN (mov)); --+ rtx src_reg = SET_SRC (PATTERN (mov)); --+ unsigned int dst_regno = REGNO (dst_reg); --+ enum machine_mode dst_mode = GET_MODE (dst_reg); --+ unsigned int dst_nregs = hard_regno_nregs[dst_regno][(int) dst_mode]; --+ unsigned int index; --+ --+ insn_lists.resize (dst_nregs); --+ for (index = 0; index < dst_nregs; ++index) --+ if (!nds32_can_cprop_acc_1 (mov, INSN_UID (mov), --+ dst_reg, src_reg, --+ index, insn_lists)) --+ return false; --+ --+ return true; --+} --+ --+/* Replace every occurrence of OLD_REGNO in LOC with NEW_REGNO. LOC maybe a --+ part of INSN. --+ DST_REG & SRC_REG are used by function nds32_mode_change_reg. --+ Mark each change with validate_change passing INSN. */ --+ --+static void --+nds32_replace_partial_operands (rtx *loc, rtx dst_reg, rtx src_reg, --+ unsigned int old_regno, unsigned int new_regno, --+ rtx_insn *insn) --+{ --+ int i, j; --+ rtx x = *loc; --+ enum rtx_code code; --+ const char *fmt; --+ --+ if (!x) --+ return; --+ --+ code = GET_CODE (x); --+ fmt = GET_RTX_FORMAT (code); --+ --+ if (REG_P (x) && REGNO (x) == old_regno) --+ { --+ rtx new_reg = nds32_mode_change_reg (GET_MODE (src_reg), --+ GET_MODE (dst_reg), --+ GET_MODE (x), --+ new_regno, --+ old_regno); --+ --+ gcc_assert (new_reg); --+ --+ ORIGINAL_REGNO (new_reg) = ORIGINAL_REGNO (x); --+ REG_ATTRS (new_reg) = REG_ATTRS (x); --+ REG_POINTER (new_reg) = REG_POINTER (x); --+ --+ /* ??? unshare or not? */ --+ validate_change (insn, loc, new_reg, 1); --+ return; --+ } --+ --+ /* Call ourself recursively to perform the replacements. */ --+ for (i = GET_RTX_LENGTH (code) - 1; i >= 0; i--) --+ { --+ if (fmt[i] == 'e') --+ nds32_replace_partial_operands (&XEXP (x, i), dst_reg, src_reg, --+ old_regno, new_regno, insn); --+ else if (fmt[i] == 'E') /* ??? how about V? */ --+ for (j = XVECLEN (x, i) - 1; j >= 0; j--) --+ nds32_replace_partial_operands (&XVECEXP (x, i, j), dst_reg, src_reg, --+ old_regno, new_regno, insn); --+ } --+} --+ --+/* Try replacing every occurrence of OLD_REGNO in INSN with NEW_REGNO. */ --+ --+static void --+nds32_replace_all_operands (rtx dst_reg, rtx src_reg, --+ unsigned int old_regno, unsigned int new_regno, --+ rtx_insn *insn) --+{ --+ nds32_replace_partial_operands (&PATTERN (insn), dst_reg, src_reg, --+ old_regno, new_regno, insn); --+} --+ --+/* Called via note_uses in function nds32_replace_src_operands, for all used --+ rtx do replacement. */ --+ --+static void --+nds32_replace_src_operands_1 (rtx *loc, void *data) --+{ --+ struct replace_src_operands_data *d --+ = (struct replace_src_operands_data *) data; --+ --+ nds32_replace_partial_operands (loc, d->dst_reg, d->src_reg, --+ d->old_regno, d->new_regno, d->insn); --+} --+ --+/* Try replacing every occurrence of OLD_REGNO in INSN with NEW_REGNO, --+ avoiding SET_DESTs. */ --+ --+static void --+nds32_replace_src_operands (rtx dst_reg, rtx src_reg, --+ unsigned int old_regno, unsigned int new_regno, --+ rtx_insn *insn) --+{ --+ struct replace_src_operands_data d --+ = {dst_reg, src_reg, old_regno, new_regno, insn}; --+ --+ note_uses (&PATTERN (insn), nds32_replace_src_operands_1, &d); --+} --+ --+/* Try replacing every occurrence of SRC_REG (include its consecutive hard --+ registers) in each insn of INSN_LISTS with DST_REG. */ --+ --+static bool --+nds32_try_replace_operands (rtx dst_reg, rtx src_reg, --+ std::vector &insn_lists) --+{ --+ unsigned int i; --+ std::vector::iterator ritr; --+ unsigned int old_regno, new_regno; --+ --+ old_regno = REGNO (dst_reg); --+ new_regno = REGNO (src_reg); --+ --+ for (i = 0; i < insn_lists.size (); ++i, ++old_regno, ++new_regno) --+ for (ritr = insn_lists[i].begin (); ritr != insn_lists[i].end (); ++ritr) --+ { --+ rtx_insn *insn = *ritr; --+ rtx acc_reg; --+ --+ acc_reg = nds32_is_acc_insn_p (insn); --+ if (acc_reg && REGNO (acc_reg) == old_regno) --+ { --+ /* Replace OP_OUT & OP_INOUT */ --+ nds32_replace_all_operands (dst_reg, src_reg, --+ old_regno, new_regno, insn); --+ --+ } --+ else --+ { --+ /* Replace OP_IN */ --+ nds32_replace_src_operands (dst_reg, src_reg, --+ old_regno, new_regno, insn); --+ } --+ } --+ --+ if (!apply_change_group ()) --+ return false; --+ else --+ { --+ df_analyze (); --+ return true; --+ } --+} --+ --+/* Check if each move instruction in WORK_LIST can do propagation, and --+ then try to replace operands if necessary. */ --+ --+static int --+nds32_do_cprop_acc (auto_vec &work_list) --+{ --+ int n_replace = 0; --+ int i; --+ rtx_insn *mov; --+ std::vector insn_lists; --+ --+ FOR_EACH_VEC_ELT (work_list, i, mov) --+ { --+ if (nds32_can_cprop_acc (mov, insn_lists)) --+ { --+ if (dump_file) --+ fprintf (dump_file, "\n [CPROP_ACC] insn %d will be cprop. \n", --+ INSN_UID (mov)); --+ --+ if (nds32_try_replace_operands (SET_DEST (PATTERN (mov)), --+ SET_SRC (PATTERN (mov)), --+ insn_lists)) --+ n_replace++; --+ } --+ insn_lists.clear (); --+ } --+ --+ return n_replace; --+} --+ --+/* Return true if MOV meets the conditions of propagation about move --+ instruction, otherwise return false. */ --+ --+static bool --+nds32_is_target_mov_p (rtx mov) --+{ --+ rtx dst = SET_DEST (PATTERN (mov)); --+ rtx src = SET_SRC (PATTERN (mov)); --+ unsigned int dst_regno, src_regno; --+ unsigned int dst_nregs, src_nregs; --+ bool dst_is_general, src_is_general; --+ --+ gcc_assert (REG_P (dst) && REG_P (src)); --+ --+ dst_regno = REGNO (dst); --+ src_regno = REGNO (src); --+ dst_nregs = hard_regno_nregs[dst_regno][GET_MODE (dst)]; --+ src_nregs = hard_regno_nregs[src_regno][GET_MODE (src)]; --+ --+ /* Do not propagate to the stack pointer, as that can leave memory accesses --+ with no scheduling dependency on the stack update. --+ Adapted from regcprop. */ --+ if (dst_regno == STACK_POINTER_REGNUM) --+ return false; --+ --+ /* Likewise with the frame pointer, if we're using one. --+ Adapted from regcprop. */ --+ if (frame_pointer_needed && dst_regno == HARD_FRAME_POINTER_REGNUM) --+ return false; --+ --+ /* Do not propagate to fixed or global registers, patterns can be relying --+ to see particular fixed register or users can expect the chosen global --+ register in asm. --+ Adapted from regcprop. */ --+ if (fixed_regs[dst_regno] || global_regs[dst_regno]) --+ return false; --+ --+ /* Make sure the all consecutive registers of SET_DEST are only defined by --+ SET_SRC. */ --+ if (dst_nregs > src_nregs) --+ return false; --+ --+ /* Narrowing on big endian will result in the invalid transformation. */ --+ if (dst_nregs < src_nregs --+ && (GET_MODE_SIZE (GET_MODE (src)) > UNITS_PER_WORD --+ ? WORDS_BIG_ENDIAN : BYTES_BIG_ENDIAN)) --+ return false; --+ --+ dst_is_general = in_hard_reg_set_p (reg_class_contents[GENERAL_REGS], --+ GET_MODE (dst), REGNO (dst)); --+ src_is_general = in_hard_reg_set_p (reg_class_contents[GENERAL_REGS], --+ GET_MODE (src), REGNO (src)); --+ /* Make sure the register class of SET_DEST & SET_SRC are the same. */ --+ if (dst_is_general ^ src_is_general) --+ return false; --+ --+ return true; --+} --+ --+/* Collect the move instructions that are the uses of accumulated register --+ in WORK_LIST */ --+ --+static void --+nds32_cprop_acc_find_target_mov (auto_vec &work_list) --+{ --+ basic_block bb; --+ rtx_insn *insn; --+ rtx acc_reg; --+ --+ FOR_EACH_BB_FN (bb, cfun) --+ FOR_BB_INSNS (bb, insn) --+ if (INSN_P (insn)) --+ { --+ acc_reg = nds32_is_acc_insn_p (insn); --+ if (acc_reg) --+ { --+ unsigned int acc_regno; --+ enum machine_mode acc_mode; --+ df_ref use; --+ df_link *link; --+ rtx_insn *def_insn; --+ --+ if (!single_set (insn) || !REG_P (acc_reg)) --+ continue; --+ --+ acc_regno = REGNO (acc_reg); --+ /* Don't replace in asms intentionally referencing hard regs. */ --+ if (asm_noperands (PATTERN (insn)) >= 0 --+ && acc_regno == ORIGINAL_REGNO (acc_reg)) --+ continue; --+ --+ if (dump_file) --+ fprintf (dump_file, --+ "\n [CPROP_ACC] " --+ "RTL_UID %d is an exchangeable ACC insn. \n", --+ INSN_UID (insn)); --+ --+ use = df_find_use (insn, acc_reg); --+ gcc_assert (use); --+ link = DF_REF_CHAIN (use); --+ --+ if (link->next --+ || DF_REF_IS_ARTIFICIAL (link->ref)) --+ continue; --+ --+ acc_mode = GET_MODE (acc_reg); --+ def_insn = DF_REF_INSN (link->ref); --+ if (nds32_is_reg_mov_p (def_insn)) --+ { --+ rtx *loc = DF_REF_LOC (link->ref); --+ enum machine_mode loc_mode = GET_MODE (*loc); --+ --+ /* If the move instruction can't define whole accumulated --+ register, the replacement is invalid. */ --+ if (loc_mode != acc_mode) --+ if (hard_regno_nregs[acc_regno][acc_mode] --+ > hard_regno_nregs[acc_regno][loc_mode]) --+ continue; --+ --+ if (nds32_is_target_mov_p (def_insn)) --+ work_list.safe_push (def_insn); --+ } --+ } --+ } --+} --+ --+/* Main entry point for the forward copy propagation optimization for --+ accumulate style instruction. */ --+ --+static int --+nds32_cprop_acc_opt (void) --+{ --+ df_chain_add_problem (DF_DU_CHAIN + DF_UD_CHAIN); --+ df_note_add_problem (); --+ df_set_flags (DF_RD_PRUNE_DEAD_DEFS); --+ df_insn_rescan_all (); --+ df_analyze (); --+ --+ auto_vec work_list; --+ --+ nds32_cprop_acc_find_target_mov (work_list); --+ if (work_list.is_empty()) --+ { --+ if (dump_file) --+ fprintf (dump_file, "\n [CPROP_ACC] The work_list is empty. \n"); --+ return 0; --+ } --+ --+ if (dump_file) --+ { --+ int i; --+ rtx_insn *mov; --+ --+ fprintf (dump_file, "\n [CPROP_ACC] The content of work_list:"); --+ FOR_EACH_VEC_ELT (work_list, i, mov) --+ fprintf (dump_file, " %d", INSN_UID (mov)); --+ fprintf (dump_file, "\n"); --+ } --+ --+ compute_bb_for_insn (); --+ --+ int n_replace = nds32_do_cprop_acc (work_list); --+ --+ if (dump_file) --+ { --+ fprintf (dump_file, "\n [CPROP_ACC] Result: "); --+ if (n_replace == 0) --+ fprintf (dump_file, "No move can do cprop. \n"); --+ else --+ fprintf (dump_file, "Do cprop for %d move. \n", n_replace); --+ } --+ --+ work_list.release (); --+ return 1; --+} --+ --+const pass_data pass_data_nds32_cprop_acc_opt = --+{ --+ RTL_PASS, /* type */ --+ "cprop_acc", /* name */ --+ OPTGROUP_NONE, /* optinfo_flags */ --+ TV_MACH_DEP, /* tv_id */ --+ 0, /* properties_required */ --+ 0, /* properties_provided */ --+ 0, /* properties_destroyed */ --+ 0, /* todo_flags_start */ --+ TODO_df_finish, /* todo_flags_finish */ --+}; --+ --+class pass_nds32_cprop_acc_opt : public rtl_opt_pass --+{ --+public: --+ pass_nds32_cprop_acc_opt (gcc::context *ctxt) --+ : rtl_opt_pass (pass_data_nds32_cprop_acc_opt, ctxt) --+ {} --+ --+ /* opt_pass methods: */ --+ bool gate (function *) { return optimize > 0 && flag_nds32_cprop_acc; } --+ unsigned int execute (function *) { return nds32_cprop_acc_opt (); } --+}; --+ --+rtl_opt_pass * --+make_pass_nds32_cprop_acc_opt (gcc::context *ctxt) --+{ --+ return new pass_nds32_cprop_acc_opt (ctxt); --+} --diff --git a/gcc/config/nds32/nds32-doubleword.md b/gcc/config/nds32/nds32-doubleword.md --index 23a9f25..7c9dfb9 100644 ----- a/gcc/config/nds32/nds32-doubleword.md --+++ b/gcc/config/nds32/nds32-doubleword.md --@@ -23,7 +23,8 @@ -- ;; Move DImode/DFmode instructions. -- ;; ------------------------------------------------------------- -- --- --+;; Do *NOT* try to split DI/DFmode before reload since LRA seem --+;; still buggy for such behavior at least at gcc 4.8.2... -- (define_expand "movdi" -- [(set (match_operand:DI 0 "general_operand" "") -- (match_operand:DI 1 "general_operand" ""))] --@@ -46,149 +47,100 @@ -- -- -- (define_insn "move_" --- [(set (match_operand:DIDF 0 "nonimmediate_operand" "=r, r, r, m") --- (match_operand:DIDF 1 "general_operand" " r, i, m, r"))] --- "" --+ [(set (match_operand:DIDF 0 "nonimmediate_operand" "=r, r, r, r, Da, m, f, Q, f, *r, *f") --+ (match_operand:DIDF 1 "general_operand" " r, i, Da, m, r, r, Q, f, f, *f, *r"))] --+ "register_operand(operands[0], mode) --+ || register_operand(operands[1], mode)" -- { --- rtx addr; --- rtx otherops[5]; --- -- switch (which_alternative) -- { -- case 0: -- return "movd44\t%0, %1"; --- -- case 1: -- /* reg <- const_int, we ask gcc to split instruction. */ -- return "#"; --- -- case 2: --- /* Refer to nds32_legitimate_address_p() in nds32.c, --- we only allow "reg", "symbol_ref", "const", and "reg + const_int" --- as address rtx for DImode/DFmode memory access. */ --- addr = XEXP (operands[1], 0); --- --- otherops[0] = gen_rtx_REG (SImode, REGNO (operands[0])); --- otherops[1] = gen_rtx_REG (SImode, REGNO (operands[0]) + 1); --- otherops[2] = addr; --- --- if (REG_P (addr)) --- { --- /* (reg) <- (mem (reg)) */ --- output_asm_insn ("lmw.bi\t%0, [%2], %1, 0", otherops); --- } --- else if (GET_CODE (addr) == PLUS) --- { --- /* (reg) <- (mem (plus (reg) (const_int))) */ --- rtx op0 = XEXP (addr, 0); --- rtx op1 = XEXP (addr, 1); --- --- if (REG_P (op0)) --- { --- otherops[2] = op0; --- otherops[3] = op1; --- otherops[4] = gen_int_mode (INTVAL (op1) + 4, SImode); --- } --- else --- { --- otherops[2] = op1; --- otherops[3] = op0; --- otherops[4] = gen_int_mode (INTVAL (op0) + 4, SImode); --- } --- --- /* To avoid base overwrite when REGNO(%0) == REGNO(%2). */ --- if (REGNO (otherops[0]) != REGNO (otherops[2])) --- { --- output_asm_insn ("lwi\t%0, [%2 + (%3)]", otherops); --- output_asm_insn ("lwi\t%1, [%2 + (%4)]", otherops); --- } --- else --- { --- output_asm_insn ("lwi\t%1, [%2 + (%4)]", otherops); --- output_asm_insn ("lwi\t%0,[ %2 + (%3)]", otherops); --- } --- } --- else --- { --- /* (reg) <- (mem (symbol_ref ...)) --- (reg) <- (mem (const ...)) */ --- output_asm_insn ("lwi.gp\t%0, [ + %2]", otherops); --- output_asm_insn ("lwi.gp\t%1, [ + %2 + 4]", otherops); --- } --- --- /* We have already used output_asm_insn() by ourself, --- so return an empty string. */ --- return ""; --- --+ /* The memory format is (mem (reg)), --+ we can generate 'lmw.bi' instruction. */ --+ return nds32_output_double (operands, true); -- case 3: --- /* Refer to nds32_legitimate_address_p() in nds32.c, --- we only allow "reg", "symbol_ref", "const", and "reg + const_int" --- as address rtx for DImode/DFmode memory access. */ --- addr = XEXP (operands[0], 0); --- --- otherops[0] = gen_rtx_REG (SImode, REGNO (operands[1])); --- otherops[1] = gen_rtx_REG (SImode, REGNO (operands[1]) + 1); --- otherops[2] = addr; --- --- if (REG_P (addr)) --- { --- /* (mem (reg)) <- (reg) */ --- output_asm_insn ("smw.bi\t%0, [%2], %1, 0", otherops); --- } --- else if (GET_CODE (addr) == PLUS) --- { --- /* (mem (plus (reg) (const_int))) <- (reg) */ --- rtx op0 = XEXP (addr, 0); --- rtx op1 = XEXP (addr, 1); --- --- if (REG_P (op0)) --- { --- otherops[2] = op0; --- otherops[3] = op1; --- otherops[4] = gen_int_mode (INTVAL (op1) + 4, SImode); --- } --- else --- { --- otherops[2] = op1; --- otherops[3] = op0; --- otherops[4] = gen_int_mode (INTVAL (op0) + 4, SImode); --- } --- --- /* To avoid base overwrite when REGNO(%0) == REGNO(%2). */ --- if (REGNO (otherops[0]) != REGNO (otherops[2])) --- { --- output_asm_insn ("swi\t%0, [%2 + (%3)]", otherops); --- output_asm_insn ("swi\t%1, [%2 + (%4)]", otherops); --- } --- else --- { --- output_asm_insn ("swi\t%1, [%2 + (%4)]", otherops); --- output_asm_insn ("swi\t%0, [%2 + (%3)]", otherops); --- } --- } --- else --- { --- /* (mem (symbol_ref ...)) <- (reg) --- (mem (const ...)) <- (reg) */ --- output_asm_insn ("swi.gp\t%0, [ + %2]", otherops); --- output_asm_insn ("swi.gp\t%1, [ + %2 + 4]", otherops); --- } --- --- /* We have already used output_asm_insn() by ourself, --- so return an empty string. */ --- return ""; --- --+ /* We haven't 64-bit load instruction, --+ we split this pattern to two SImode pattern. */ --+ return "#"; --+ case 4: --+ /* The memory format is (mem (reg)), --+ we can generate 'smw.bi' instruction. */ --+ return nds32_output_double (operands, false); --+ case 5: --+ /* We haven't 64-bit store instruction, --+ we split this pattern to two SImode pattern. */ --+ return "#"; --+ case 6: --+ return nds32_output_float_load (operands); --+ case 7: --+ return nds32_output_float_store (operands); --+ case 8: --+ return "fcpysd\t%0, %1, %1"; --+ case 9: --+ return "fmfdr\t%0, %1"; --+ case 10: --+ return "fmtdr\t%1, %0"; -- default: -- gcc_unreachable (); -- } -- } --- [(set_attr "type" "move,move,move,move") --- (set_attr "length" " 4, 16, 8, 8")]) --+ [(set_attr "type" "alu,alu,load,load,store,store,fload,fstore,fcpy,fmfdr,fmtdr") --+ (set_attr_alternative "length" --+ [ --+ ;; Alternative 0 --+ (if_then_else (match_test "!TARGET_16_BIT") --+ (const_int 4) --+ (const_int 2)) --+ ;; Alternative 1 --+ (const_int 16) --+ ;; Alternative 2 --+ (const_int 4) --+ ;; Alternative 3 --+ (const_int 8) --+ ;; Alternative 4 --+ (const_int 4) --+ ;; Alternative 5 --+ (const_int 8) --+ ;; Alternative 6 --+ (const_int 4) --+ ;; Alternative 7 --+ (const_int 4) --+ ;; Alternative 8 --+ (const_int 4) --+ ;; Alternative 9 --+ (const_int 4) --+ ;; Alternative 10 --+ (const_int 4) --+ ]) --+ (set_attr "feature" " v1, v1, v1, v1, v1, v1, fpu, fpu, fpu, fpu, fpu")]) --+ --+;; Split move_di pattern when the hard register is odd. --+(define_split --+ [(set (match_operand:DIDF 0 "register_operand" "") --+ (match_operand:DIDF 1 "register_operand" ""))] --+ "(NDS32_IS_GPR_REGNUM (REGNO (operands[0])) --+ && ((REGNO (operands[0]) & 0x1) == 1)) --+ || (NDS32_IS_GPR_REGNUM (REGNO (operands[1])) --+ && ((REGNO (operands[1]) & 0x1) == 1))" --+ [(set (match_dup 2) (match_dup 3)) --+ (set (match_dup 4) (match_dup 5))] --+ { --+ operands[2] = gen_lowpart (SImode, operands[0]); --+ operands[4] = gen_highpart (SImode, operands[0]); --+ operands[3] = gen_lowpart (SImode, operands[1]); --+ operands[5] = gen_highpart (SImode, operands[1]); --+ } --+) -- -- (define_split -- [(set (match_operand:DIDF 0 "register_operand" "") -- (match_operand:DIDF 1 "const_double_operand" ""))] --- "reload_completed" --+ "flag_pic || reload_completed" -- [(set (match_dup 2) (match_dup 3)) -- (set (match_dup 4) (match_dup 5))] -- { --@@ -207,7 +159,12 @@ -- /* Actually we would like to create move behavior by ourself. -- So that movsi expander could have chance to split large constant. */ -- emit_move_insn (operands[2], operands[3]); --- emit_move_insn (operands[4], operands[5]); --+ --+ unsigned HOST_WIDE_INT mask = GET_MODE_MASK (SImode); --+ if ((UINTVAL (operands[3]) & mask) == (UINTVAL (operands[5]) & mask)) --+ emit_move_insn (operands[4], operands[2]); --+ else --+ emit_move_insn (operands[4], operands[5]); -- DONE; -- }) -- --@@ -217,7 +174,9 @@ -- [(set (match_operand:DIDF 0 "register_operand" "") -- (match_operand:DIDF 1 "register_operand" ""))] -- "reload_completed --- && (TARGET_ISA_V2 || !TARGET_16_BIT)" --+ && (TARGET_ISA_V2 || !TARGET_16_BIT) --+ && NDS32_IS_GPR_REGNUM (REGNO (operands[0])) --+ && NDS32_IS_GPR_REGNUM (REGNO (operands[1]))" -- [(set (match_dup 0) (match_dup 1)) -- (set (match_dup 2) (match_dup 3))] -- { --@@ -239,6 +198,28 @@ -- } -- }) -- --+(define_split --+ [(set (match_operand:DIDF 0 "nds32_general_register_operand" "") --+ (match_operand:DIDF 1 "memory_operand" ""))] --+ "reload_completed --+ && nds32_split_double_word_load_store_p (operands, true)" --+ [(set (match_dup 2) (match_dup 3)) --+ (set (match_dup 4) (match_dup 5))] --+{ --+ nds32_spilt_doubleword (operands, true); --+}) --+ --+(define_split --+ [(set (match_operand:DIDF 0 "memory_operand" "") --+ (match_operand:DIDF 1 "nds32_general_register_operand" ""))] --+ "reload_completed --+ && nds32_split_double_word_load_store_p (operands, false)" --+ [(set (match_dup 2) (match_dup 3)) --+ (set (match_dup 4) (match_dup 5))] --+{ --+ nds32_spilt_doubleword (operands, false); --+}) --+ -- ;; ------------------------------------------------------------- -- ;; Boolean DImode instructions. -- ;; ------------------------------------------------------------- --diff --git a/gcc/config/nds32/nds32-dspext.md b/gcc/config/nds32/nds32-dspext.md --new file mode 100644 --index 0000000..6ec2137 ----- /dev/null --+++ b/gcc/config/nds32/nds32-dspext.md --@@ -0,0 +1,5280 @@ --+;; Machine description of Andes NDS32 cpu for GNU compiler --+;; Copyright (C) 2012-2016 Free Software Foundation, Inc. --+;; Contributed by Andes Technology Corporation. --+;; --+;; This file is part of GCC. --+;; --+;; GCC is free software; you can redistribute it and/or modify it --+;; under the terms of the GNU General Public License as published --+;; by the Free Software Foundation; either version 3, or (at your --+;; option) any later version. --+;; --+;; GCC is distributed in the hope that it will be useful, but WITHOUT --+;; ANY WARRANTY; without even the implied warranty of MERCHANTABILITY --+;; or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public --+;; License for more details. --+;; --+;; You should have received a copy of the GNU General Public License --+;; along with GCC; see the file COPYING3. If not see --+;; . --+ --+(define_expand "mov" --+ [(set (match_operand:VQIHI 0 "general_operand" "") --+ (match_operand:VQIHI 1 "general_operand" ""))] --+ "NDS32_EXT_DSP_P ()" --+{ --+ /* Need to force register if mem <- !reg. */ --+ if (MEM_P (operands[0]) && !REG_P (operands[1])) --+ operands[1] = force_reg (mode, operands[1]); --+ --+ /* If operands[1] is a large constant and cannot be performed --+ by a single instruction, we need to split it. */ --+ if (GET_CODE (operands[1]) == CONST_VECTOR --+ && !satisfies_constraint_CVs2 (operands[1]) --+ && !satisfies_constraint_CVhi (operands[1])) --+ { --+ HOST_WIDE_INT ival = const_vector_to_hwint (operands[1]); --+ rtx tmp_rtx; --+ --+ tmp_rtx = can_create_pseudo_p () --+ ? gen_reg_rtx (SImode) --+ : simplify_gen_subreg (SImode, operands[0], mode, 0); --+ --+ emit_move_insn (tmp_rtx, gen_int_mode (ival, SImode)); --+ convert_move (operands[0], tmp_rtx, false); --+ DONE; --+ } --+ --+ if (REG_P (operands[0]) && SYMBOLIC_CONST_P (operands[1])) --+ { --+ if (nds32_tls_referenced_p (operands [1])) --+ { --+ nds32_expand_tls_move (operands); --+ DONE; --+ } --+ else if (flag_pic) --+ { --+ nds32_expand_pic_move (operands); --+ DONE; --+ } --+ } --+}) --+ --+(define_insn "*mov" --+ [(set (match_operand:VQIHI 0 "nonimmediate_operand" "=r, r,$U45,$U33,$U37,$U45, m,$ l,$ l,$ l,$ d, d, r,$ d, r, r, r, *f, *f, r, *f, Q, A") --+ (match_operand:VQIHI 1 "nds32_vmove_operand" " r, r, l, l, l, d, r, U45, U33, U37, U45,Ufe, m, CVp5, CVs5, CVs2, CVhi, *f, r, *f, Q, *f, r"))] --+ "NDS32_EXT_DSP_P () --+ && (register_operand(operands[0], mode) --+ || register_operand(operands[1], mode))" --+{ --+ switch (which_alternative) --+ { --+ case 0: --+ return "mov55\t%0, %1"; --+ case 1: --+ return "ori\t%0, %1, 0"; --+ case 2: --+ case 3: --+ case 4: --+ case 5: --+ return nds32_output_16bit_store (operands, ); --+ case 6: --+ return nds32_output_32bit_store (operands, ); --+ case 7: --+ case 8: --+ case 9: --+ case 10: --+ case 11: --+ return nds32_output_16bit_load (operands, ); --+ case 12: --+ return nds32_output_32bit_load (operands, ); --+ case 13: --+ return "movpi45\t%0, %1"; --+ case 14: --+ return "movi55\t%0, %1"; --+ case 15: --+ return "movi\t%0, %1"; --+ case 16: --+ return "sethi\t%0, hi20(%1)"; --+ case 17: --+ if (TARGET_FPU_SINGLE) --+ return "fcpyss\t%0, %1, %1"; --+ else --+ return "#"; --+ case 18: --+ return "fmtsr\t%1, %0"; --+ case 19: --+ return "fmfsr\t%0, %1"; --+ case 20: --+ return nds32_output_float_load (operands); --+ case 21: --+ return nds32_output_float_store (operands); --+ case 22: --+ return "mtusr\t%1, %0"; --+ default: --+ gcc_unreachable (); --+ } --+} --+ [(set_attr "type" "alu,alu,store,store,store,store,store,load,load,load,load,load,load,alu,alu,alu,alu,fcpy,fmtsr,fmfsr,fload,fstore,alu") --+ (set_attr "length" " 2, 4, 2, 2, 2, 2, 4, 2, 2, 2, 2, 2, 4, 2, 2, 4, 4, 4, 4, 4, 4, 4, 4") --+ (set_attr "feature" " v1, v1, v1, v1, v1, v1, v1, v1, v1, v1, v1, v3m, v1, v1, v1, v1, v1, fpu, fpu, fpu, fpu, fpu, v1")]) --+ --+(define_expand "movv2si" --+ [(set (match_operand:V2SI 0 "general_operand" "") --+ (match_operand:V2SI 1 "general_operand" ""))] --+ "NDS32_EXT_DSP_P ()" --+{ --+ /* Need to force register if mem <- !reg. */ --+ if (MEM_P (operands[0]) && !REG_P (operands[1])) --+ operands[1] = force_reg (V2SImode, operands[1]); --+}) --+ --+(define_insn "*movv2si" --+ [(set (match_operand:V2SI 0 "nonimmediate_operand" "=r, r, r, r, Da, m, f, Q, f, r, f") --+ (match_operand:V2SI 1 "general_operand" " r, i, Da, m, r, r, Q, f, f, f, r"))] --+ "NDS32_EXT_DSP_P () --+ && (register_operand(operands[0], V2SImode) --+ || register_operand(operands[1], V2SImode))" --+{ --+ switch (which_alternative) --+ { --+ case 0: --+ return "movd44\t%0, %1"; --+ case 1: --+ /* reg <- const_int, we ask gcc to split instruction. */ --+ return "#"; --+ case 2: --+ /* The memory format is (mem (reg)), --+ we can generate 'lmw.bi' instruction. */ --+ return nds32_output_double (operands, true); --+ case 3: --+ /* We haven't 64-bit load instruction, --+ we split this pattern to two SImode pattern. */ --+ return "#"; --+ case 4: --+ /* The memory format is (mem (reg)), --+ we can generate 'smw.bi' instruction. */ --+ return nds32_output_double (operands, false); --+ case 5: --+ /* We haven't 64-bit store instruction, --+ we split this pattern to two SImode pattern. */ --+ return "#"; --+ case 6: --+ return nds32_output_float_load (operands); --+ case 7: --+ return nds32_output_float_store (operands); --+ case 8: --+ return "fcpysd\t%0, %1, %1"; --+ case 9: --+ return "fmfdr\t%0, %1"; --+ case 10: --+ return "fmtdr\t%1, %0"; --+ default: --+ gcc_unreachable (); --+ } --+} --+ [(set_attr "type" "alu,alu,load,load,store,store,unknown,unknown,unknown,unknown,unknown") --+ (set_attr_alternative "length" --+ [ --+ ;; Alternative 0 --+ (if_then_else (match_test "!TARGET_16_BIT") --+ (const_int 4) --+ (const_int 2)) --+ ;; Alternative 1 --+ (const_int 16) --+ ;; Alternative 2 --+ (const_int 4) --+ ;; Alternative 3 --+ (const_int 8) --+ ;; Alternative 4 --+ (const_int 4) --+ ;; Alternative 5 --+ (const_int 8) --+ ;; Alternative 6 --+ (const_int 4) --+ ;; Alternative 7 --+ (const_int 4) --+ ;; Alternative 8 --+ (const_int 4) --+ ;; Alternative 9 --+ (const_int 4) --+ ;; Alternative 10 --+ (const_int 4) --+ ]) --+ (set_attr "feature" " v1, v1, v1, v1, v1, v1, fpu, fpu, fpu, fpu, fpu")]) --+ --+(define_expand "movmisalign" --+ [(set (match_operand:VQIHI 0 "general_operand" "") --+ (match_operand:VQIHI 1 "general_operand" ""))] --+ "NDS32_EXT_DSP_P ()" --+{ --+ rtx addr; --+ if (MEM_P (operands[0]) && !REG_P (operands[1])) --+ operands[1] = force_reg (mode, operands[1]); --+ --+ if (MEM_P (operands[0])) --+ { --+ addr = force_reg (Pmode, XEXP (operands[0], 0)); --+ emit_insn (gen_unaligned_store (addr, operands[1])); --+ } --+ else --+ { --+ addr = force_reg (Pmode, XEXP (operands[1], 0)); --+ emit_insn (gen_unaligned_load (operands[0], addr)); --+ } --+ DONE; --+}) --+ --+(define_expand "unaligned_load" --+ [(set (match_operand:VQIHI 0 "register_operand" "=r") --+ (unspec:VQIHI [(mem:VQIHI (match_operand:SI 1 "register_operand" "r"))] UNSPEC_UALOAD_W))] --+ "NDS32_EXT_DSP_P ()" --+{ --+ if (TARGET_ISA_V3M) --+ nds32_expand_unaligned_load (operands, mode); --+ else --+ emit_insn (gen_unaligned_load_w (operands[0], gen_rtx_MEM (mode, operands[1]))); --+ DONE; --+}) --+ --+(define_insn "unaligned_load_w" --+ [(set (match_operand:VQIHI 0 "register_operand" "= r") --+ (unspec:VQIHI [(match_operand:VQIHI 1 "nds32_lmw_smw_base_operand" " Umw")] UNSPEC_UALOAD_W))] --+ "NDS32_EXT_DSP_P ()" --+{ --+ return nds32_output_lmw_single_word (operands); --+} --+ [(set_attr "type" "load") --+ (set_attr "length" "4")] --+) --+ --+(define_expand "unaligned_store" --+ [(set (mem:VQIHI (match_operand:SI 0 "register_operand" "r")) --+ (unspec:VQIHI [(match_operand:VQIHI 1 "register_operand" "r")] UNSPEC_UASTORE_W))] --+ "NDS32_EXT_DSP_P ()" --+{ --+ if (TARGET_ISA_V3M) --+ nds32_expand_unaligned_store (operands, mode); --+ else --+ emit_insn (gen_unaligned_store_w (gen_rtx_MEM (mode, operands[0]), operands[1])); --+ DONE; --+}) --+ --+(define_insn "unaligned_store_w" --+ [(set (match_operand:VQIHI 0 "nds32_lmw_smw_base_operand" "=Umw") --+ (unspec:VQIHI [(match_operand:VQIHI 1 "register_operand" " r")] UNSPEC_UASTORE_W))] --+ "NDS32_EXT_DSP_P ()" --+{ --+ return nds32_output_smw_single_word (operands); --+} --+ [(set_attr "type" "store") --+ (set_attr "length" "4")] --+) --+ --+(define_insn "add3" --+ [(set (match_operand:VQIHI 0 "register_operand" "=r") --+ (all_plus:VQIHI (match_operand:VQIHI 1 "register_operand" " r") --+ (match_operand:VQIHI 2 "register_operand" " r")))] --+ "NDS32_EXT_DSP_P ()" --+ "add %0, %1, %2" --+ [(set_attr "type" "dalu") --+ (set_attr "length" "4") --+ (set_attr "feature" "v1")]) --+ --+(define_insn "adddi3" --+ [(set (match_operand:DI 0 "register_operand" "=r") --+ (all_plus:DI (match_operand:DI 1 "register_operand" " r") --+ (match_operand:DI 2 "register_operand" " r")))] --+ "NDS32_EXT_DSP_P ()" --+ "add64 %0, %1, %2" --+ [(set_attr "type" "dalu64") --+ (set_attr "length" "4") --+ (set_attr "feature" "v1")]) --+ --+(define_insn "raddv4qi3" --+ [(set (match_operand:V4QI 0 "register_operand" "=r") --+ (truncate:V4QI --+ (ashiftrt:V4HI --+ (plus:V4HI (sign_extend:V4HI (match_operand:V4QI 1 "register_operand" " r")) --+ (sign_extend:V4HI (match_operand:V4QI 2 "register_operand" " r"))) --+ (const_int 1))))] --+ "NDS32_EXT_DSP_P ()" --+ "radd8\t%0, %1, %2" --+ [(set_attr "type" "dalu") --+ (set_attr "length" "4") --+ (set_attr "feature" "v1")]) --+ --+ --+(define_insn "uraddv4qi3" --+ [(set (match_operand:V4QI 0 "register_operand" "=r") --+ (truncate:V4QI --+ (lshiftrt:V4HI --+ (plus:V4HI (zero_extend:V4HI (match_operand:V4QI 1 "register_operand" " r")) --+ (zero_extend:V4HI (match_operand:V4QI 2 "register_operand" " r"))) --+ (const_int 1))))] --+ "NDS32_EXT_DSP_P ()" --+ "uradd8\t%0, %1, %2" --+ [(set_attr "type" "dalu") --+ (set_attr "length" "4") --+ (set_attr "feature" "v1")]) --+ --+(define_insn "raddv2hi3" --+ [(set (match_operand:V2HI 0 "register_operand" "=r") --+ (truncate:V2HI --+ (ashiftrt:V2SI --+ (plus:V2SI (sign_extend:V2SI (match_operand:V2HI 1 "register_operand" " r")) --+ (sign_extend:V2SI (match_operand:V2HI 2 "register_operand" " r"))) --+ (const_int 1))))] --+ "NDS32_EXT_DSP_P ()" --+ "radd16\t%0, %1, %2" --+ [(set_attr "type" "dalu") --+ (set_attr "length" "4") --+ (set_attr "feature" "v1")]) --+ --+(define_insn "uraddv2hi3" --+ [(set (match_operand:V2HI 0 "register_operand" "=r") --+ (truncate:V2HI --+ (lshiftrt:V2SI --+ (plus:V2SI (zero_extend:V2SI (match_operand:V2HI 1 "register_operand" " r")) --+ (zero_extend:V2SI (match_operand:V2HI 2 "register_operand" " r"))) --+ (const_int 1))))] --+ "NDS32_EXT_DSP_P ()" --+ "uradd16\t%0, %1, %2" --+ [(set_attr "type" "dalu") --+ (set_attr "length" "4") --+ (set_attr "feature" "v1")]) --+ --+(define_insn "radddi3" --+ [(set (match_operand:DI 0 "register_operand" "=r") --+ (truncate:DI --+ (ashiftrt:TI --+ (plus:TI (sign_extend:TI (match_operand:DI 1 "register_operand" " r")) --+ (sign_extend:TI (match_operand:DI 2 "register_operand" " r"))) --+ (const_int 1))))] --+ "NDS32_EXT_DSP_P ()" --+ "radd64\t%0, %1, %2" --+ [(set_attr "type" "dalu64") --+ (set_attr "length" "4") --+ (set_attr "feature" "v1")]) --+ --+ --+(define_insn "uradddi3" --+ [(set (match_operand:DI 0 "register_operand" "=r") --+ (truncate:DI --+ (lshiftrt:TI --+ (plus:TI (zero_extend:TI (match_operand:DI 1 "register_operand" " r")) --+ (zero_extend:TI (match_operand:DI 2 "register_operand" " r"))) --+ (const_int 1))))] --+ "NDS32_EXT_DSP_P ()" --+ "uradd64\t%0, %1, %2" --+ [(set_attr "type" "dalu64") --+ (set_attr "length" "4") --+ (set_attr "feature" "v1")]) --+ --+(define_insn "sub3" --+ [(set (match_operand:VQIHI 0 "register_operand" "=r") --+ (all_minus:VQIHI (match_operand:VQIHI 1 "register_operand" " r") --+ (match_operand:VQIHI 2 "register_operand" " r")))] --+ "NDS32_EXT_DSP_P ()" --+ "sub %0, %1, %2" --+ [(set_attr "type" "dalu") --+ (set_attr "length" "4") --+ (set_attr "feature" "v1")]) --+ --+(define_insn "subdi3" --+ [(set (match_operand:DI 0 "register_operand" "=r") --+ (all_minus:DI (match_operand:DI 1 "register_operand" " r") --+ (match_operand:DI 2 "register_operand" " r")))] --+ "NDS32_EXT_DSP_P ()" --+ "sub64 %0, %1, %2" --+ [(set_attr "type" "dalu64") --+ (set_attr "length" "4") --+ (set_attr "feature" "v1")]) --+ --+(define_insn "rsubv4qi3" --+ [(set (match_operand:V4QI 0 "register_operand" "=r") --+ (truncate:V4QI --+ (ashiftrt:V4HI --+ (minus:V4HI (sign_extend:V4HI (match_operand:V4QI 1 "register_operand" " r")) --+ (sign_extend:V4HI (match_operand:V4QI 2 "register_operand" " r"))) --+ (const_int 1))))] --+ "NDS32_EXT_DSP_P ()" --+ "rsub8\t%0, %1, %2" --+ [(set_attr "type" "dalu") --+ (set_attr "length" "4")]) --+ --+(define_insn "ursubv4qi3" --+ [(set (match_operand:V4QI 0 "register_operand" "=r") --+ (truncate:V4QI --+ (lshiftrt:V4HI --+ (minus:V4HI (zero_extend:V4HI (match_operand:V4QI 1 "register_operand" " r")) --+ (zero_extend:V4HI (match_operand:V4QI 2 "register_operand" " r"))) --+ (const_int 1))))] --+ "NDS32_EXT_DSP_P ()" --+ "ursub8\t%0, %1, %2" --+ [(set_attr "type" "dalu") --+ (set_attr "length" "4")]) --+ --+(define_insn "rsubv2hi3" --+ [(set (match_operand:V2HI 0 "register_operand" "=r") --+ (truncate:V2HI --+ (ashiftrt:V2SI --+ (minus:V2SI (sign_extend:V2SI (match_operand:V2HI 1 "register_operand" " r")) --+ (sign_extend:V2SI (match_operand:V2HI 2 "register_operand" " r"))) --+ (const_int 1))))] --+ "NDS32_EXT_DSP_P ()" --+ "rsub16\t%0, %1, %2" --+ [(set_attr "type" "dalu") --+ (set_attr "length" "4")]) --+ --+(define_insn "ursubv2hi3" --+ [(set (match_operand:V2HI 0 "register_operand" "=r") --+ (truncate:V2HI --+ (lshiftrt:V2SI --+ (minus:V2SI (zero_extend:V2SI (match_operand:V2HI 1 "register_operand" " r")) --+ (zero_extend:V2SI (match_operand:V2HI 2 "register_operand" " r"))) --+ (const_int 1))))] --+ "NDS32_EXT_DSP_P ()" --+ "ursub16\t%0, %1, %2" --+ [(set_attr "type" "dalu") --+ (set_attr "length" "4")]) --+ --+(define_insn "rsubdi3" --+ [(set (match_operand:DI 0 "register_operand" "=r") --+ (truncate:DI --+ (ashiftrt:TI --+ (minus:TI (sign_extend:TI (match_operand:DI 1 "register_operand" " r")) --+ (sign_extend:TI (match_operand:DI 2 "register_operand" " r"))) --+ (const_int 1))))] --+ "NDS32_EXT_DSP_P ()" --+ "rsub64\t%0, %1, %2" --+ [(set_attr "type" "dalu64") --+ (set_attr "length" "4")]) --+ --+ --+(define_insn "ursubdi3" --+ [(set (match_operand:DI 0 "register_operand" "=r") --+ (truncate:DI --+ (lshiftrt:TI --+ (minus:TI (zero_extend:TI (match_operand:DI 1 "register_operand" " r")) --+ (zero_extend:TI (match_operand:DI 2 "register_operand" " r"))) --+ (const_int 1))))] --+ "NDS32_EXT_DSP_P ()" --+ "ursub64\t%0, %1, %2" --+ [(set_attr "type" "dalu64") --+ (set_attr "length" "4")]) --+ --+(define_expand "cras16_1" --+ [(match_operand:V2HI 0 "register_operand" "") --+ (match_operand:V2HI 1 "register_operand" "") --+ (match_operand:V2HI 2 "register_operand" "")] --+ "NDS32_EXT_DSP_P ()" --+{ --+ if (TARGET_BIG_ENDIAN) --+ emit_insn (gen_cras16_1_be (operands[0], operands[1], operands[2])); --+ else --+ emit_insn (gen_cras16_1_le (operands[0], operands[1], operands[2])); --+ DONE; --+}) --+ --+(define_insn "cras16_1_le" --+ [(set (match_operand:V2HI 0 "register_operand" "=r") --+ (vec_merge:V2HI --+ (vec_duplicate:V2HI --+ (minus:HI --+ (vec_select:HI --+ (match_operand:V2HI 1 "register_operand" " r") --+ (parallel [(const_int 0)])) --+ (vec_select:HI --+ (match_operand:V2HI 2 "register_operand" " r") --+ (parallel [(const_int 1)])))) --+ (vec_duplicate:V2HI --+ (plus:HI --+ (vec_select:HI --+ (match_dup 2) --+ (parallel [(const_int 0)])) --+ (vec_select:HI --+ (match_dup 1) --+ (parallel [(const_int 1)])))) --+ (const_int 1)))] --+ "NDS32_EXT_DSP_P () && !TARGET_BIG_ENDIAN" --+ "cras16\t%0, %1, %2" --+ [(set_attr "type" "dalu")] --+) --+ --+(define_insn "cras16_1_be" --+ [(set (match_operand:V2HI 0 "register_operand" "=r") --+ (vec_merge:V2HI --+ (vec_duplicate:V2HI --+ (minus:HI --+ (vec_select:HI --+ (match_operand:V2HI 1 "register_operand" " r") --+ (parallel [(const_int 1)])) --+ (vec_select:HI --+ (match_operand:V2HI 2 "register_operand" " r") --+ (parallel [(const_int 0)])))) --+ (vec_duplicate:V2HI --+ (plus:HI --+ (vec_select:HI --+ (match_dup 2) --+ (parallel [(const_int 1)])) --+ (vec_select:HI --+ (match_dup 1) --+ (parallel [(const_int 0)])))) --+ (const_int 2)))] --+ "NDS32_EXT_DSP_P () && TARGET_BIG_ENDIAN" --+ "cras16\t%0, %1, %2" --+ [(set_attr "type" "dalu")] --+) --+ --+(define_expand "kcras16_1" --+ [(match_operand:V2HI 0 "register_operand" "") --+ (match_operand:V2HI 1 "register_operand" "") --+ (match_operand:V2HI 2 "register_operand" "")] --+ "NDS32_EXT_DSP_P ()" --+{ --+ if (TARGET_BIG_ENDIAN) --+ emit_insn (gen_kcras16_1_be (operands[0], operands[1], operands[2])); --+ else --+ emit_insn (gen_kcras16_1_le (operands[0], operands[1], operands[2])); --+ DONE; --+}) --+ --+(define_insn "kcras16_1_le" --+ [(set (match_operand:V2HI 0 "register_operand" "=r") --+ (vec_merge:V2HI --+ (vec_duplicate:V2HI --+ (ss_minus:HI --+ (vec_select:HI --+ (match_operand:V2HI 1 "register_operand" " r") --+ (parallel [(const_int 0)])) --+ (vec_select:HI --+ (match_operand:V2HI 2 "register_operand" " r") --+ (parallel [(const_int 1)])))) --+ (vec_duplicate:V2HI --+ (ss_plus:HI --+ (vec_select:HI --+ (match_dup 2) --+ (parallel [(const_int 0)])) --+ (vec_select:HI --+ (match_dup 1) --+ (parallel [(const_int 1)])))) --+ (const_int 1)))] --+ "NDS32_EXT_DSP_P () && !TARGET_BIG_ENDIAN" --+ "kcras16\t%0, %1, %2" --+ [(set_attr "type" "dalu")] --+) --+ --+(define_insn "kcras16_1_be" --+ [(set (match_operand:V2HI 0 "register_operand" "=r") --+ (vec_merge:V2HI --+ (vec_duplicate:V2HI --+ (ss_minus:HI --+ (vec_select:HI --+ (match_operand:V2HI 1 "register_operand" " r") --+ (parallel [(const_int 1)])) --+ (vec_select:HI --+ (match_operand:V2HI 2 "register_operand" " r") --+ (parallel [(const_int 0)])))) --+ (vec_duplicate:V2HI --+ (ss_plus:HI --+ (vec_select:HI --+ (match_dup 2) --+ (parallel [(const_int 1)])) --+ (vec_select:HI --+ (match_dup 1) --+ (parallel [(const_int 0)])))) --+ (const_int 2)))] --+ "NDS32_EXT_DSP_P () && TARGET_BIG_ENDIAN" --+ "kcras16\t%0, %1, %2" --+ [(set_attr "type" "dalu")] --+) --+ --+(define_expand "ukcras16_1" --+ [(match_operand:V2HI 0 "register_operand" "") --+ (match_operand:V2HI 1 "register_operand" "") --+ (match_operand:V2HI 2 "register_operand" "")] --+ "NDS32_EXT_DSP_P ()" --+{ --+ if (TARGET_BIG_ENDIAN) --+ emit_insn (gen_ukcras16_1_be (operands[0], operands[1], operands[2])); --+ else --+ emit_insn (gen_ukcras16_1_le (operands[0], operands[1], operands[2])); --+ DONE; --+}) --+ --+(define_insn "ukcras16_1_le" --+ [(set (match_operand:V2HI 0 "register_operand" "=r") --+ (vec_merge:V2HI --+ (vec_duplicate:V2HI --+ (us_minus:HI --+ (vec_select:HI --+ (match_operand:V2HI 1 "register_operand" " r") --+ (parallel [(const_int 0)])) --+ (vec_select:HI --+ (match_operand:V2HI 2 "register_operand" " r") --+ (parallel [(const_int 1)])))) --+ (vec_duplicate:V2HI --+ (us_plus:HI --+ (vec_select:HI --+ (match_dup 2) --+ (parallel [(const_int 0)])) --+ (vec_select:HI --+ (match_dup 1) --+ (parallel [(const_int 1)])))) --+ (const_int 1)))] --+ "NDS32_EXT_DSP_P () && !TARGET_BIG_ENDIAN" --+ "ukcras16\t%0, %1, %2" --+ [(set_attr "type" "dalu")] --+) --+ --+(define_insn "ukcras16_1_be" --+ [(set (match_operand:V2HI 0 "register_operand" "=r") --+ (vec_merge:V2HI --+ (vec_duplicate:V2HI --+ (us_minus:HI --+ (vec_select:HI --+ (match_operand:V2HI 1 "register_operand" " r") --+ (parallel [(const_int 1)])) --+ (vec_select:HI --+ (match_operand:V2HI 2 "register_operand" " r") --+ (parallel [(const_int 0)])))) --+ (vec_duplicate:V2HI --+ (us_plus:HI --+ (vec_select:HI --+ (match_dup 2) --+ (parallel [(const_int 1)])) --+ (vec_select:HI --+ (match_dup 1) --+ (parallel [(const_int 0)])))) --+ (const_int 2)))] --+ "NDS32_EXT_DSP_P () && TARGET_BIG_ENDIAN" --+ "ukcras16\t%0, %1, %2" --+ [(set_attr "type" "dalu")] --+) --+ --+(define_expand "crsa16_1" --+ [(match_operand:V2HI 0 "register_operand" "") --+ (match_operand:V2HI 1 "register_operand" "") --+ (match_operand:V2HI 2 "register_operand" "")] --+ "NDS32_EXT_DSP_P ()" --+{ --+ if (TARGET_BIG_ENDIAN) --+ emit_insn (gen_crsa16_1_be (operands[0], operands[1], operands[2])); --+ else --+ emit_insn (gen_crsa16_1_le (operands[0], operands[1], operands[2])); --+ DONE; --+}) --+ --+(define_insn "crsa16_1_le" --+ [(set (match_operand:V2HI 0 "register_operand" "=r") --+ (vec_merge:V2HI --+ (vec_duplicate:V2HI --+ (minus:HI --+ (vec_select:HI --+ (match_operand:V2HI 1 "register_operand" " r") --+ (parallel [(const_int 1)])) --+ (vec_select:HI --+ (match_operand:V2HI 2 "register_operand" " r") --+ (parallel [(const_int 0)])))) --+ (vec_duplicate:V2HI --+ (plus:HI --+ (vec_select:HI --+ (match_dup 1) --+ (parallel [(const_int 0)])) --+ (vec_select:HI --+ (match_dup 2) --+ (parallel [(const_int 1)])))) --+ (const_int 2)))] --+ "NDS32_EXT_DSP_P () && !TARGET_BIG_ENDIAN" --+ "crsa16\t%0, %1, %2" --+ [(set_attr "type" "dalu")] --+) --+ --+(define_insn "crsa16_1_be" --+ [(set (match_operand:V2HI 0 "register_operand" "=r") --+ (vec_merge:V2HI --+ (vec_duplicate:V2HI --+ (minus:HI --+ (vec_select:HI --+ (match_operand:V2HI 1 "register_operand" " r") --+ (parallel [(const_int 0)])) --+ (vec_select:HI --+ (match_operand:V2HI 2 "register_operand" " r") --+ (parallel [(const_int 1)])))) --+ (vec_duplicate:V2HI --+ (plus:HI --+ (vec_select:HI --+ (match_dup 1) --+ (parallel [(const_int 1)])) --+ (vec_select:HI --+ (match_dup 2) --+ (parallel [(const_int 0)])))) --+ (const_int 1)))] --+ "NDS32_EXT_DSP_P () && TARGET_BIG_ENDIAN" --+ "crsa16\t%0, %1, %2" --+ [(set_attr "type" "dalu")] --+) --+ --+(define_expand "kcrsa16_1" --+ [(match_operand:V2HI 0 "register_operand" "") --+ (match_operand:V2HI 1 "register_operand" "") --+ (match_operand:V2HI 2 "register_operand" "")] --+ "NDS32_EXT_DSP_P ()" --+{ --+ if (TARGET_BIG_ENDIAN) --+ emit_insn (gen_kcrsa16_1_be (operands[0], operands[1], operands[2])); --+ else --+ emit_insn (gen_kcrsa16_1_le (operands[0], operands[1], operands[2])); --+ DONE; --+}) --+ --+(define_insn "kcrsa16_1_le" --+ [(set (match_operand:V2HI 0 "register_operand" "=r") --+ (vec_merge:V2HI --+ (vec_duplicate:V2HI --+ (ss_minus:HI --+ (vec_select:HI --+ (match_operand:V2HI 1 "register_operand" " r") --+ (parallel [(const_int 1)])) --+ (vec_select:HI --+ (match_operand:V2HI 2 "register_operand" " r") --+ (parallel [(const_int 0)])))) --+ (vec_duplicate:V2HI --+ (ss_plus:HI --+ (vec_select:HI --+ (match_dup 1) --+ (parallel [(const_int 0)])) --+ (vec_select:HI --+ (match_dup 2) --+ (parallel [(const_int 1)])))) --+ (const_int 2)))] --+ "NDS32_EXT_DSP_P () && !TARGET_BIG_ENDIAN" --+ "kcrsa16\t%0, %1, %2" --+ [(set_attr "type" "dalu")] --+) --+ --+(define_insn "kcrsa16_1_be" --+ [(set (match_operand:V2HI 0 "register_operand" "=r") --+ (vec_merge:V2HI --+ (vec_duplicate:V2HI --+ (ss_minus:HI --+ (vec_select:HI --+ (match_operand:V2HI 1 "register_operand" " r") --+ (parallel [(const_int 0)])) --+ (vec_select:HI --+ (match_operand:V2HI 2 "register_operand" " r") --+ (parallel [(const_int 1)])))) --+ (vec_duplicate:V2HI --+ (ss_plus:HI --+ (vec_select:HI --+ (match_dup 1) --+ (parallel [(const_int 1)])) --+ (vec_select:HI --+ (match_dup 2) --+ (parallel [(const_int 0)])))) --+ (const_int 1)))] --+ "NDS32_EXT_DSP_P () && TARGET_BIG_ENDIAN" --+ "kcrsa16\t%0, %1, %2" --+ [(set_attr "type" "dalu")] --+) --+ --+(define_expand "ukcrsa16_1" --+ [(match_operand:V2HI 0 "register_operand" "") --+ (match_operand:V2HI 1 "register_operand" "") --+ (match_operand:V2HI 2 "register_operand" "")] --+ "NDS32_EXT_DSP_P ()" --+{ --+ if (TARGET_BIG_ENDIAN) --+ emit_insn (gen_ukcrsa16_1_be (operands[0], operands[1], operands[2])); --+ else --+ emit_insn (gen_ukcrsa16_1_le (operands[0], operands[1], operands[2])); --+ DONE; --+}) --+ --+(define_insn "ukcrsa16_1_le" --+ [(set (match_operand:V2HI 0 "register_operand" "=r") --+ (vec_merge:V2HI --+ (vec_duplicate:V2HI --+ (us_minus:HI --+ (vec_select:HI --+ (match_operand:V2HI 1 "register_operand" " r") --+ (parallel [(const_int 1)])) --+ (vec_select:HI --+ (match_operand:V2HI 2 "register_operand" " r") --+ (parallel [(const_int 0)])))) --+ (vec_duplicate:V2HI --+ (us_plus:HI --+ (vec_select:HI --+ (match_dup 1) --+ (parallel [(const_int 0)])) --+ (vec_select:HI --+ (match_dup 2) --+ (parallel [(const_int 1)])))) --+ (const_int 2)))] --+ "NDS32_EXT_DSP_P () && !TARGET_BIG_ENDIAN" --+ "ukcrsa16\t%0, %1, %2" --+ [(set_attr "type" "dalu")] --+) --+ --+(define_insn "ukcrsa16_1_be" --+ [(set (match_operand:V2HI 0 "register_operand" "=r") --+ (vec_merge:V2HI --+ (vec_duplicate:V2HI --+ (us_minus:HI --+ (vec_select:HI --+ (match_operand:V2HI 1 "register_operand" " r") --+ (parallel [(const_int 0)])) --+ (vec_select:HI --+ (match_operand:V2HI 2 "register_operand" " r") --+ (parallel [(const_int 1)])))) --+ (vec_duplicate:V2HI --+ (us_plus:HI --+ (vec_select:HI --+ (match_dup 1) --+ (parallel [(const_int 1)])) --+ (vec_select:HI --+ (match_dup 2) --+ (parallel [(const_int 0)])))) --+ (const_int 1)))] --+ "NDS32_EXT_DSP_P () && TARGET_BIG_ENDIAN" --+ "ukcrsa16\t%0, %1, %2" --+ [(set_attr "type" "dalu")] --+) --+ --+(define_expand "rcras16_1" --+ [(match_operand:V2HI 0 "register_operand" "") --+ (match_operand:V2HI 1 "register_operand" "") --+ (match_operand:V2HI 2 "register_operand" "")] --+ "NDS32_EXT_DSP_P ()" --+{ --+ if (TARGET_BIG_ENDIAN) --+ emit_insn (gen_rcras16_1_be (operands[0], operands[1], operands[2])); --+ else --+ emit_insn (gen_rcras16_1_le (operands[0], operands[1], operands[2])); --+ DONE; --+}) --+ --+(define_insn "rcras16_1_le" --+ [(set (match_operand:V2HI 0 "register_operand" "=r") --+ (vec_merge:V2HI --+ (vec_duplicate:V2HI --+ (truncate:HI --+ (ashiftrt:SI --+ (minus:SI --+ (sign_extend:SI --+ (vec_select:HI --+ (match_operand:V2HI 1 "register_operand" " r") --+ (parallel [(const_int 0)]))) --+ (sign_extend:SI --+ (vec_select:HI --+ (match_operand:V2HI 2 "register_operand" " r") --+ (parallel [(const_int 1)])))) --+ (const_int 1)))) --+ (vec_duplicate:V2HI --+ (truncate:HI --+ (ashiftrt:SI --+ (plus:SI --+ (sign_extend:SI --+ (vec_select:HI --+ (match_dup 2) --+ (parallel [(const_int 0)]))) --+ (sign_extend:SI --+ (vec_select:HI --+ (match_dup 1) --+ (parallel [(const_int 1)])))) --+ (const_int 1)))) --+ (const_int 1)))] --+ "NDS32_EXT_DSP_P () && !TARGET_BIG_ENDIAN" --+ "rcras16\t%0, %1, %2" --+ [(set_attr "type" "dalu")] --+) --+ --+(define_insn "rcras16_1_be" --+ [(set (match_operand:V2HI 0 "register_operand" "=r") --+ (vec_merge:V2HI --+ (vec_duplicate:V2HI --+ (truncate:HI --+ (ashiftrt:SI --+ (minus:SI --+ (sign_extend:SI --+ (vec_select:HI --+ (match_operand:V2HI 1 "register_operand" " r") --+ (parallel [(const_int 1)]))) --+ (sign_extend:SI --+ (vec_select:HI --+ (match_operand:V2HI 2 "register_operand" " r") --+ (parallel [(const_int 0)])))) --+ (const_int 1)))) --+ (vec_duplicate:V2HI --+ (truncate:HI --+ (ashiftrt:SI --+ (plus:SI --+ (sign_extend:SI --+ (vec_select:HI --+ (match_dup 2) --+ (parallel [(const_int 1)]))) --+ (sign_extend:SI --+ (vec_select:HI --+ (match_dup 1) --+ (parallel [(const_int 0)])))) --+ (const_int 1)))) --+ (const_int 2)))] --+ "NDS32_EXT_DSP_P () && TARGET_BIG_ENDIAN" --+ "rcras16\t%0, %1, %2" --+ [(set_attr "type" "dalu")] --+) --+ --+(define_expand "urcras16_1" --+ [(match_operand:V2HI 0 "register_operand" "") --+ (match_operand:V2HI 1 "register_operand" "") --+ (match_operand:V2HI 2 "register_operand" "")] --+ "NDS32_EXT_DSP_P ()" --+{ --+ if (TARGET_BIG_ENDIAN) --+ emit_insn (gen_urcras16_1_be (operands[0], operands[1], operands[2])); --+ else --+ emit_insn (gen_urcras16_1_le (operands[0], operands[1], operands[2])); --+ DONE; --+}) --+ --+(define_insn "urcras16_1_le" --+ [(set (match_operand:V2HI 0 "register_operand" "=r") --+ (vec_merge:V2HI --+ (vec_duplicate:V2HI --+ (truncate:HI --+ (lshiftrt:SI --+ (minus:SI --+ (zero_extend:SI --+ (vec_select:HI --+ (match_operand:V2HI 1 "register_operand" " r") --+ (parallel [(const_int 0)]))) --+ (zero_extend:SI --+ (vec_select:HI --+ (match_operand:V2HI 2 "register_operand" " r") --+ (parallel [(const_int 1)])))) --+ (const_int 1)))) --+ (vec_duplicate:V2HI --+ (truncate:HI --+ (lshiftrt:SI --+ (plus:SI --+ (zero_extend:SI --+ (vec_select:HI --+ (match_dup 2) --+ (parallel [(const_int 0)]))) --+ (zero_extend:SI --+ (vec_select:HI --+ (match_dup 1) --+ (parallel [(const_int 1)])))) --+ (const_int 1)))) --+ (const_int 1)))] --+ "NDS32_EXT_DSP_P () && !TARGET_BIG_ENDIAN" --+ "urcras16\t%0, %1, %2" --+ [(set_attr "type" "dalu")] --+) --+ --+(define_insn "urcras16_1_be" --+ [(set (match_operand:V2HI 0 "register_operand" "=r") --+ (vec_merge:V2HI --+ (vec_duplicate:V2HI --+ (truncate:HI --+ (lshiftrt:SI --+ (minus:SI --+ (zero_extend:SI --+ (vec_select:HI --+ (match_operand:V2HI 1 "register_operand" " r") --+ (parallel [(const_int 1)]))) --+ (zero_extend:SI --+ (vec_select:HI --+ (match_operand:V2HI 2 "register_operand" " r") --+ (parallel [(const_int 0)])))) --+ (const_int 1)))) --+ (vec_duplicate:V2HI --+ (truncate:HI --+ (lshiftrt:SI --+ (plus:SI --+ (zero_extend:SI --+ (vec_select:HI --+ (match_dup 2) --+ (parallel [(const_int 1)]))) --+ (zero_extend:SI --+ (vec_select:HI --+ (match_dup 1) --+ (parallel [(const_int 0)])))) --+ (const_int 1)))) --+ (const_int 2)))] --+ "NDS32_EXT_DSP_P () && TARGET_BIG_ENDIAN" --+ "urcras16\t%0, %1, %2" --+ [(set_attr "type" "dalu")] --+) --+ --+(define_expand "rcrsa16_1" --+ [(match_operand:V2HI 0 "register_operand" "") --+ (match_operand:V2HI 1 "register_operand" "") --+ (match_operand:V2HI 2 "register_operand" "")] --+ "NDS32_EXT_DSP_P ()" --+{ --+ if (TARGET_BIG_ENDIAN) --+ emit_insn (gen_rcrsa16_1_be (operands[0], operands[1], operands[2])); --+ else --+ emit_insn (gen_rcrsa16_1_le (operands[0], operands[1], operands[2])); --+ DONE; --+}) --+ --+(define_insn "rcrsa16_1_le" --+ [(set (match_operand:V2HI 0 "register_operand" "=r") --+ (vec_merge:V2HI --+ (vec_duplicate:V2HI --+ (truncate:HI --+ (ashiftrt:SI --+ (minus:SI --+ (sign_extend:SI --+ (vec_select:HI --+ (match_operand:V2HI 1 "register_operand" " r") --+ (parallel [(const_int 1)]))) --+ (sign_extend:SI --+ (vec_select:HI --+ (match_operand:V2HI 2 "register_operand" " r") --+ (parallel [(const_int 0)])))) --+ (const_int 1)))) --+ (vec_duplicate:V2HI --+ (truncate:HI --+ (ashiftrt:SI --+ (plus:SI --+ (sign_extend:SI --+ (vec_select:HI --+ (match_dup 1) --+ (parallel [(const_int 0)]))) --+ (sign_extend:SI --+ (vec_select:HI --+ (match_dup 2) --+ (parallel [(const_int 1)])))) --+ (const_int 1)))) --+ (const_int 2)))] --+ "NDS32_EXT_DSP_P () && !TARGET_BIG_ENDIAN" --+ "rcrsa16\t%0, %1, %2" --+ [(set_attr "type" "dalu")] --+) --+ --+(define_insn "rcrsa16_1_be" --+ [(set (match_operand:V2HI 0 "register_operand" "=r") --+ (vec_merge:V2HI --+ (vec_duplicate:V2HI --+ (truncate:HI --+ (ashiftrt:SI --+ (minus:SI --+ (sign_extend:SI --+ (vec_select:HI --+ (match_operand:V2HI 1 "register_operand" " r") --+ (parallel [(const_int 0)]))) --+ (sign_extend:SI --+ (vec_select:HI --+ (match_operand:V2HI 2 "register_operand" " r") --+ (parallel [(const_int 1)])))) --+ (const_int 1)))) --+ (vec_duplicate:V2HI --+ (truncate:HI --+ (ashiftrt:SI --+ (plus:SI --+ (sign_extend:SI --+ (vec_select:HI --+ (match_dup 1) --+ (parallel [(const_int 1)]))) --+ (sign_extend:SI --+ (vec_select:HI --+ (match_dup 2) --+ (parallel [(const_int 0)])))) --+ (const_int 1)))) --+ (const_int 1)))] --+ "NDS32_EXT_DSP_P () && TARGET_BIG_ENDIAN" --+ "rcrsa16\t%0, %1, %2" --+ [(set_attr "type" "dalu")] --+) --+ --+(define_expand "urcrsa16_1" --+ [(match_operand:V2HI 0 "register_operand" "") --+ (match_operand:V2HI 1 "register_operand" "") --+ (match_operand:V2HI 2 "register_operand" "")] --+ "NDS32_EXT_DSP_P ()" --+{ --+ if (TARGET_BIG_ENDIAN) --+ emit_insn (gen_urcrsa16_1_be (operands[0], operands[1], operands[2])); --+ else --+ emit_insn (gen_urcrsa16_1_le (operands[0], operands[1], operands[2])); --+ DONE; --+}) --+ --+(define_insn "urcrsa16_1_le" --+ [(set (match_operand:V2HI 0 "register_operand" "=r") --+ (vec_merge:V2HI --+ (vec_duplicate:V2HI --+ (truncate:HI --+ (lshiftrt:SI --+ (minus:SI --+ (zero_extend:SI --+ (vec_select:HI --+ (match_operand:V2HI 1 "register_operand" " r") --+ (parallel [(const_int 1)]))) --+ (zero_extend:SI --+ (vec_select:HI --+ (match_operand:V2HI 2 "register_operand" " r") --+ (parallel [(const_int 0)])))) --+ (const_int 1)))) --+ (vec_duplicate:V2HI --+ (truncate:HI --+ (lshiftrt:SI --+ (plus:SI --+ (zero_extend:SI --+ (vec_select:HI --+ (match_dup 1) --+ (parallel [(const_int 0)]))) --+ (zero_extend:SI --+ (vec_select:HI --+ (match_dup 2) --+ (parallel [(const_int 1)])))) --+ (const_int 1)))) --+ (const_int 2)))] --+ "NDS32_EXT_DSP_P () && !TARGET_BIG_ENDIAN" --+ "urcrsa16\t%0, %1, %2" --+ [(set_attr "type" "dalu")] --+) --+ --+(define_insn "urcrsa16_1_be" --+ [(set (match_operand:V2HI 0 "register_operand" "=r") --+ (vec_merge:V2HI --+ (vec_duplicate:V2HI --+ (truncate:HI --+ (lshiftrt:SI --+ (minus:SI --+ (zero_extend:SI --+ (vec_select:HI --+ (match_operand:V2HI 1 "register_operand" " r") --+ (parallel [(const_int 0)]))) --+ (zero_extend:SI --+ (vec_select:HI --+ (match_operand:V2HI 2 "register_operand" " r") --+ (parallel [(const_int 1)])))) --+ (const_int 1)))) --+ (vec_duplicate:V2HI --+ (truncate:HI --+ (lshiftrt:SI --+ (plus:SI --+ (zero_extend:SI --+ (vec_select:HI --+ (match_dup 1) --+ (parallel [(const_int 1)]))) --+ (zero_extend:SI --+ (vec_select:HI --+ (match_dup 2) --+ (parallel [(const_int 0)])))) --+ (const_int 1)))) --+ (const_int 1)))] --+ "NDS32_EXT_DSP_P () && TARGET_BIG_ENDIAN" --+ "urcrsa16\t%0, %1, %2" --+ [(set_attr "type" "dalu")] --+) --+ --+(define_expand "v2hi3" --+ [(set (match_operand:V2HI 0 "register_operand" "") --+ (shifts:V2HI (match_operand:V2HI 1 "register_operand" "") --+ (match_operand:SI 2 "nds32_rimm4u_operand" "")))] --+ "NDS32_EXT_DSP_P ()" --+{ --+ if (operands[2] == const0_rtx) --+ { --+ emit_move_insn (operands[0], operands[1]); --+ DONE; --+ } --+}) --+ --+(define_insn "*ashlv2hi3" --+ [(set (match_operand:V2HI 0 "register_operand" "= r, r") --+ (ashift:V2HI (match_operand:V2HI 1 "register_operand" " r, r") --+ (match_operand:SI 2 "nds32_rimm4u_operand" " Iu04, r")))] --+ "NDS32_EXT_DSP_P ()" --+ "@ --+ slli16\t%0, %1, %2 --+ sll16\t%0, %1, %2" --+ [(set_attr "type" "dalu,dalu") --+ (set_attr "length" " 4, 4")]) --+ --+(define_insn "kslli16" --+ [(set (match_operand:V2HI 0 "register_operand" "= r, r") --+ (ss_ashift:V2HI (match_operand:V2HI 1 "register_operand" " r, r") --+ (match_operand:SI 2 "nds32_rimm4u_operand" " Iu04, r")))] --+ "NDS32_EXT_DSP_P ()" --+ "@ --+ kslli16\t%0, %1, %2 --+ ksll16\t%0, %1, %2" --+ [(set_attr "type" "dalu,dalu") --+ (set_attr "length" " 4, 4")]) --+ --+(define_insn "*ashrv2hi3" --+ [(set (match_operand:V2HI 0 "register_operand" "= r, r") --+ (ashiftrt:V2HI (match_operand:V2HI 1 "register_operand" " r, r") --+ (match_operand:SI 2 "nds32_rimm4u_operand" " Iu04, r")))] --+ "NDS32_EXT_DSP_P ()" --+ "@ --+ srai16\t%0, %1, %2 --+ sra16\t%0, %1, %2" --+ [(set_attr "type" "dalu,dalu") --+ (set_attr "length" " 4, 4")]) --+ --+(define_insn "sra16_round" --+ [(set (match_operand:V2HI 0 "register_operand" "= r, r") --+ (unspec:V2HI [(ashiftrt:V2HI (match_operand:V2HI 1 "register_operand" " r, r") --+ (match_operand:SI 2 "nds32_rimm4u_operand" " Iu04, r"))] --+ UNSPEC_ROUND))] --+ "NDS32_EXT_DSP_P ()" --+ "@ --+ srai16.u\t%0, %1, %2 --+ sra16.u\t%0, %1, %2" --+ [(set_attr "type" "daluround,daluround") --+ (set_attr "length" " 4, 4")]) --+ --+(define_insn "*lshrv2hi3" --+ [(set (match_operand:V2HI 0 "register_operand" "= r, r") --+ (lshiftrt:V2HI (match_operand:V2HI 1 "register_operand" " r, r") --+ (match_operand:SI 2 "nds32_rimm4u_operand" " Iu04, r")))] --+ "NDS32_EXT_DSP_P ()" --+ "@ --+ srli16\t%0, %1, %2 --+ srl16\t%0, %1, %2" --+ [(set_attr "type" "dalu,dalu") --+ (set_attr "length" " 4, 4")]) --+ --+(define_insn "srl16_round" --+ [(set (match_operand:V2HI 0 "register_operand" "= r, r") --+ (unspec:V2HI [(lshiftrt:V2HI (match_operand:V2HI 1 "register_operand" " r, r") --+ (match_operand:SI 2 "nds32_rimm4u_operand" " Iu04, r"))] --+ UNSPEC_ROUND))] --+ "NDS32_EXT_DSP_P ()" --+ "@ --+ srli16.u\t%0, %1, %2 --+ srl16.u\t%0, %1, %2" --+ [(set_attr "type" "daluround,daluround") --+ (set_attr "length" " 4, 4")]) --+ --+(define_insn "kslra16" --+ [(set (match_operand:V2HI 0 "register_operand" "=r") --+ (if_then_else:V2HI --+ (lt:SI (match_operand:SI 2 "register_operand" " r") --+ (const_int 0)) --+ (ashiftrt:V2HI (match_operand:V2HI 1 "register_operand" " r") --+ (neg:SI (match_dup 2))) --+ (ashift:V2HI (match_dup 1) --+ (match_dup 2))))] --+ "NDS32_EXT_DSP_P ()" --+ "kslra16\t%0, %1, %2" --+ [(set_attr "type" "dalu") --+ (set_attr "length" "4")]) --+ --+(define_insn "kslra16_round" --+ [(set (match_operand:V2HI 0 "register_operand" "=r") --+ (if_then_else:V2HI --+ (lt:SI (match_operand:SI 2 "register_operand" " r") --+ (const_int 0)) --+ (unspec:V2HI [(ashiftrt:V2HI (match_operand:V2HI 1 "register_operand" " r") --+ (neg:SI (match_dup 2)))] --+ UNSPEC_ROUND) --+ (ashift:V2HI (match_dup 1) --+ (match_dup 2))))] --+ "NDS32_EXT_DSP_P ()" --+ "kslra16.u\t%0, %1, %2" --+ [(set_attr "type" "daluround") --+ (set_attr "length" "4")]) --+ --+(define_insn "cmpeq" --+ [(set (match_operand:SI 0 "register_operand" "=r") --+ (unspec:SI [(eq:SI (match_operand:VQIHI 1 "register_operand" " r") --+ (match_operand:VQIHI 2 "register_operand" " r"))] --+ UNSPEC_VEC_COMPARE))] --+ "NDS32_EXT_DSP_P ()" --+ "cmpeq\t%0, %1, %2" --+ [(set_attr "type" "dcmp") --+ (set_attr "length" "4")]) --+ --+(define_insn "scmplt" --+ [(set (match_operand:SI 0 "register_operand" "=r") --+ (unspec:SI [(lt:SI (match_operand:VQIHI 1 "register_operand" " r") --+ (match_operand:VQIHI 2 "register_operand" " r"))] --+ UNSPEC_VEC_COMPARE))] --+ "NDS32_EXT_DSP_P ()" --+ "scmplt\t%0, %1, %2" --+ [(set_attr "type" "dcmp") --+ (set_attr "length" "4")]) --+ --+(define_insn "scmple" --+ [(set (match_operand:SI 0 "register_operand" "=r") --+ (unspec:SI [(le:SI (match_operand:VQIHI 1 "register_operand" " r") --+ (match_operand:VQIHI 2 "register_operand" " r"))] --+ UNSPEC_VEC_COMPARE))] --+ "NDS32_EXT_DSP_P ()" --+ "scmple\t%0, %1, %2" --+ [(set_attr "type" "dcmp") --+ (set_attr "length" "4")]) --+ --+(define_insn "ucmplt" --+ [(set (match_operand:SI 0 "register_operand" "=r") --+ (unspec:SI [(ltu:SI (match_operand:VQIHI 1 "register_operand" " r") --+ (match_operand:VQIHI 2 "register_operand" " r"))] --+ UNSPEC_VEC_COMPARE))] --+ "NDS32_EXT_DSP_P ()" --+ "ucmplt\t%0, %1, %2" --+ [(set_attr "type" "dcmp") --+ (set_attr "length" "4")]) --+ --+(define_insn "ucmple" --+ [(set (match_operand:SI 0 "register_operand" "=r") --+ (unspec:SI [(leu:SI (match_operand:VQIHI 1 "register_operand" " r") --+ (match_operand:VQIHI 2 "register_operand" " r"))] --+ UNSPEC_VEC_COMPARE))] --+ "NDS32_EXT_DSP_P ()" --+ "ucmple\t%0, %1, %2" --+ [(set_attr "type" "dcmp") --+ (set_attr "length" "4")]) --+ --+(define_insn "sclip16" --+ [(set (match_operand:V2HI 0 "register_operand" "= r") --+ (unspec:V2HI [(match_operand:V2HI 1 "register_operand" " r") --+ (match_operand:SI 2 "nds32_imm4u_operand" " Iu04")] --+ UNSPEC_CLIPS))] --+ "NDS32_EXT_DSP_P ()" --+ "sclip16\t%0, %1, %2" --+ [(set_attr "type" "dclip") --+ (set_attr "length" "4")]) --+ --+(define_insn "uclip16" --+ [(set (match_operand:V2HI 0 "register_operand" "= r") --+ (unspec:V2HI [(match_operand:V2HI 1 "register_operand" " r") --+ (match_operand:SI 2 "nds32_imm4u_operand" " Iu04")] --+ UNSPEC_CLIP))] --+ "NDS32_EXT_DSP_P ()" --+ "uclip16\t%0, %1, %2" --+ [(set_attr "type" "dclip") --+ (set_attr "length" "4")]) --+ --+(define_insn "khm16" --+ [(set (match_operand:V2HI 0 "register_operand" "=r") --+ (unspec:V2HI [(match_operand:V2HI 1 "register_operand" " r") --+ (match_operand:V2HI 2 "register_operand" " r")] --+ UNSPEC_KHM))] --+ "NDS32_EXT_DSP_P ()" --+ "khm16\t%0, %1, %2" --+ [(set_attr "type" "dmul") --+ (set_attr "length" "4")]) --+ --+(define_insn "khmx16" --+ [(set (match_operand:V2HI 0 "register_operand" "=r") --+ (unspec:V2HI [(match_operand:V2HI 1 "register_operand" " r") --+ (match_operand:V2HI 2 "register_operand" " r")] --+ UNSPEC_KHMX))] --+ "NDS32_EXT_DSP_P ()" --+ "khmx16\t%0, %1, %2" --+ [(set_attr "type" "dmul") --+ (set_attr "length" "4")]) --+ --+(define_expand "vec_setv4qi" --+ [(match_operand:V4QI 0 "register_operand" "") --+ (match_operand:QI 1 "register_operand" "") --+ (match_operand:SI 2 "immediate_operand" "")] --+ "NDS32_EXT_DSP_P ()" --+{ --+ HOST_WIDE_INT pos = INTVAL (operands[2]); --+ if (pos > 4) --+ gcc_unreachable (); --+ HOST_WIDE_INT elem = (HOST_WIDE_INT) 1 << pos; --+ emit_insn (gen_vec_setv4qi_internal (operands[0], operands[1], --+ operands[0], GEN_INT (elem))); --+ DONE; --+}) --+ --+(define_expand "insb" --+ [(match_operand:V4QI 0 "register_operand" "") --+ (match_operand:V4QI 1 "register_operand" "") --+ (match_operand:SI 2 "register_operand" "") --+ (match_operand:SI 3 "const_int_operand" "")] --+ "NDS32_EXT_DSP_P ()" --+{ --+ if (INTVAL (operands[3]) > 3 || INTVAL (operands[3]) < 0) --+ gcc_unreachable (); --+ --+ rtx src = gen_reg_rtx (QImode); --+ --+ convert_move (src, operands[2], false); --+ --+ HOST_WIDE_INT selector_index; --+ /* Big endian need reverse index. */ --+ if (TARGET_BIG_ENDIAN) --+ selector_index = 4 - INTVAL (operands[3]) - 1; --+ else --+ selector_index = INTVAL (operands[3]); --+ rtx selector = gen_int_mode (1 << selector_index, SImode); --+ emit_insn (gen_vec_setv4qi_internal (operands[0], src, --+ operands[1], selector)); --+ DONE; --+}) --+ --+(define_expand "insvsi" --+ [(set (zero_extract:SI (match_operand:SI 0 "register_operand" "") --+ (match_operand:SI 1 "const_int_operand" "") --+ (match_operand:SI 2 "nds32_insv_operand" "")) --+ (match_operand:SI 3 "register_operand" ""))] --+ "NDS32_EXT_DSP_P ()" --+{ --+ if (INTVAL (operands[1]) != 8) --+ FAIL; --+} --+ [(set_attr "type" "dinsb") --+ (set_attr "length" "4")]) --+ --+ --+(define_insn "insvsi_internal" --+ [(set (zero_extract:SI (match_operand:SI 0 "register_operand" "+r") --+ (const_int 8) --+ (match_operand:SI 1 "nds32_insv_operand" "i")) --+ (match_operand:SI 2 "register_operand" "r"))] --+ "NDS32_EXT_DSP_P ()" --+ "insb\t%0, %2, %v1" --+ [(set_attr "type" "dinsb") --+ (set_attr "length" "4")]) --+ --+(define_insn "insvsiqi_internal" --+ [(set (zero_extract:SI (match_operand:SI 0 "register_operand" "+r") --+ (const_int 8) --+ (match_operand:SI 1 "nds32_insv_operand" "i")) --+ (zero_extend:SI (match_operand:QI 2 "register_operand" "r")))] --+ "NDS32_EXT_DSP_P ()" --+ "insb\t%0, %2, %v1" --+ [(set_attr "type" "dinsb") --+ (set_attr "length" "4")]) --+ --+;; Intermedium pattern for synthetize insvsiqi_internal --+;; v0 = ((v1 & 0xff) << 8) --+(define_insn_and_split "and0xff_s8" --+ [(set (match_operand:SI 0 "register_operand" "=r") --+ (and:SI (ashift:SI (match_operand:SI 1 "register_operand" "r") --+ (const_int 8)) --+ (const_int 65280)))] --+ "NDS32_EXT_DSP_P () && !reload_completed" --+ "#" --+ "NDS32_EXT_DSP_P () && !reload_completed" --+ [(const_int 1)] --+{ --+ rtx tmp = gen_reg_rtx (SImode); --+ emit_insn (gen_ashlsi3 (tmp, operands[1], gen_int_mode (8, SImode))); --+ emit_insn (gen_andsi3 (operands[0], tmp, gen_int_mode (0xffff, SImode))); --+ DONE; --+}) --+ --+;; v0 = (v1 & 0xff00ffff) | ((v2 << 16) | 0xff0000) --+(define_insn_and_split "insbsi2" --+ [(set (match_operand:SI 0 "register_operand" "=r") --+ (ior:SI (and:SI (match_operand:SI 1 "register_operand" "0") --+ (const_int -16711681)) --+ (and:SI (ashift:SI (match_operand:SI 2 "register_operand" "r") --+ (const_int 16)) --+ (const_int 16711680))))] --+ "NDS32_EXT_DSP_P () && !reload_completed" --+ "#" --+ "NDS32_EXT_DSP_P () && !reload_completed" --+ [(const_int 1)] --+{ --+ rtx tmp = gen_reg_rtx (SImode); --+ emit_move_insn (tmp, operands[1]); --+ emit_insn (gen_insvsi_internal (tmp, gen_int_mode(16, SImode), operands[2])); --+ emit_move_insn (operands[0], tmp); --+ DONE; --+}) --+ --+;; v0 = (v1 & 0xff00ffff) | v2 --+(define_insn_and_split "ior_and0xff00ffff_reg" --+ [(set (match_operand:SI 0 "register_operand" "=r") --+ (ior:SI (and:SI (match_operand:SI 1 "register_operand" "r") --+ (const_int -16711681)) --+ (match_operand:SI 2 "register_operand" "r")))] --+ "NDS32_EXT_DSP_P () && !reload_completed" --+ "#" --+ "NDS32_EXT_DSP_P () && !reload_completed" --+ [(const_int 1)] --+{ --+ rtx tmp = gen_reg_rtx (SImode); --+ emit_insn (gen_andsi3 (tmp, operands[1], gen_int_mode (0xff00ffff, SImode))); --+ emit_insn (gen_iorsi3 (operands[0], tmp, operands[2])); --+ DONE; --+}) --+ --+(define_insn "vec_setv4qi_internal" --+ [(set (match_operand:V4QI 0 "register_operand" "= r, r, r, r") --+ (vec_merge:V4QI --+ (vec_duplicate:V4QI --+ (match_operand:QI 1 "register_operand" " r, r, r, r")) --+ (match_operand:V4QI 2 "register_operand" " 0, 0, 0, 0") --+ (match_operand:SI 3 "nds32_imm_1_2_4_8_operand" " Iv01, Iv02, Iv04, Iv08")))] --+ "NDS32_EXT_DSP_P ()" --+{ --+ if (TARGET_BIG_ENDIAN) --+ { --+ const char *pats[] = { "insb\t%0, %1, 3", --+ "insb\t%0, %1, 2", --+ "insb\t%0, %1, 1", --+ "insb\t%0, %1, 0" }; --+ return pats[which_alternative]; --+ } --+ else --+ { --+ const char *pats[] = { "insb\t%0, %1, 0", --+ "insb\t%0, %1, 1", --+ "insb\t%0, %1, 2", --+ "insb\t%0, %1, 3" }; --+ return pats[which_alternative]; --+ } --+} --+ [(set_attr "type" "dinsb") --+ (set_attr "length" "4")]) --+ --+(define_insn "vec_setv4qi_internal_vec" --+ [(set (match_operand:V4QI 0 "register_operand" "= r, r, r, r") --+ (vec_merge:V4QI --+ (vec_duplicate:V4QI --+ (vec_select:QI --+ (match_operand:V4QI 1 "register_operand" " r, r, r, r") --+ (parallel [(const_int 0)]))) --+ (match_operand:V4QI 2 "register_operand" " 0, 0, 0, 0") --+ (match_operand:SI 3 "nds32_imm_1_2_4_8_operand" " Iv01, Iv02, Iv04, Iv08")))] --+ "NDS32_EXT_DSP_P () && !TARGET_BIG_ENDIAN" --+ "@ --+ insb\t%0, %1, 0 --+ insb\t%0, %1, 1 --+ insb\t%0, %1, 2 --+ insb\t%0, %1, 3" --+ [(set_attr "type" "dinsb") --+ (set_attr "length" "4")]) --+ --+(define_insn "vec_mergev4qi_and_cv0_1" --+ [(set (match_operand:V4QI 0 "register_operand" "=$l,r") --+ (vec_merge:V4QI --+ (vec_duplicate:V4QI --+ (vec_select:QI --+ (match_operand:V4QI 1 "register_operand" " l,r") --+ (parallel [(const_int 0)]))) --+ (const_vector:V4QI [ --+ (const_int 0) --+ (const_int 0) --+ (const_int 0) --+ (const_int 0)]) --+ (const_int 1)))] --+ "NDS32_EXT_DSP_P () && !TARGET_BIG_ENDIAN" --+ "@ --+ zeb33\t%0, %1 --+ zeb\t%0, %1" --+ [(set_attr "type" "alu,alu") --+ (set_attr "length" " 2, 4")]) --+ --+(define_insn "vec_mergev4qi_and_cv0_2" --+ [(set (match_operand:V4QI 0 "register_operand" "=$l,r") --+ (vec_merge:V4QI --+ (const_vector:V4QI [ --+ (const_int 0) --+ (const_int 0) --+ (const_int 0) --+ (const_int 0)]) --+ (vec_duplicate:V4QI --+ (vec_select:QI --+ (match_operand:V4QI 1 "register_operand" " l,r") --+ (parallel [(const_int 0)]))) --+ (const_int 2)))] --+ "NDS32_EXT_DSP_P () && !TARGET_BIG_ENDIAN" --+ "@ --+ zeb33\t%0, %1 --+ zeb\t%0, %1" --+ [(set_attr "type" "alu,alu") --+ (set_attr "length" " 2, 4")]) --+ --+(define_insn "vec_mergeqi_and_cv0_1" --+ [(set (match_operand:V4QI 0 "register_operand" "=$l,r") --+ (vec_merge:V4QI --+ (vec_duplicate:V4QI (match_operand:QI 1 "register_operand" " l,r")) --+ (const_vector:V4QI [ --+ (const_int 0) --+ (const_int 0) --+ (const_int 0) --+ (const_int 0)]) --+ (const_int 1)))] --+ "NDS32_EXT_DSP_P () && !TARGET_BIG_ENDIAN" --+ "@ --+ zeb33\t%0, %1 --+ zeb\t%0, %1" --+ [(set_attr "type" "alu,alu") --+ (set_attr "length" " 2, 4")]) --+ --+(define_insn "vec_mergeqi_and_cv0_2" --+ [(set (match_operand:V4QI 0 "register_operand" "=$l,r") --+ (vec_merge:V4QI --+ (const_vector:V4QI [ --+ (const_int 0) --+ (const_int 0) --+ (const_int 0) --+ (const_int 0)]) --+ (vec_duplicate:V4QI (match_operand:QI 1 "register_operand" " l,r")) --+ (const_int 2)))] --+ "NDS32_EXT_DSP_P () && !TARGET_BIG_ENDIAN" --+ "@ --+ zeb33\t%0, %1 --+ zeb\t%0, %1" --+ [(set_attr "type" "alu,alu") --+ (set_attr "length" " 2, 4")]) --+ --+(define_expand "vec_setv2hi" --+ [(match_operand:V2HI 0 "register_operand" "") --+ (match_operand:HI 1 "register_operand" "") --+ (match_operand:SI 2 "immediate_operand" "")] --+ "NDS32_EXT_DSP_P ()" --+{ --+ HOST_WIDE_INT pos = INTVAL (operands[2]); --+ if (pos > 2) --+ gcc_unreachable (); --+ HOST_WIDE_INT elem = (HOST_WIDE_INT) 1 << pos; --+ emit_insn (gen_vec_setv2hi_internal (operands[0], operands[1], --+ operands[0], GEN_INT (elem))); --+ DONE; --+}) --+ --+(define_insn "vec_setv2hi_internal" --+ [(set (match_operand:V2HI 0 "register_operand" "= r, r") --+ (vec_merge:V2HI --+ (vec_duplicate:V2HI --+ (match_operand:HI 1 "register_operand" " r, r")) --+ (match_operand:V2HI 2 "register_operand" " r, r") --+ (match_operand:SI 3 "nds32_imm_1_2_operand" " Iv01, Iv02")))] --+ "NDS32_EXT_DSP_P ()" --+{ --+ if (TARGET_BIG_ENDIAN) --+ { --+ const char *pats[] = { "pkbb16\t%0, %1, %2", --+ "pktb16\t%0, %2, %1" }; --+ return pats[which_alternative]; --+ } --+ else --+ { --+ const char *pats[] = { "pktb16\t%0, %2, %1", --+ "pkbb16\t%0, %1, %2" }; --+ return pats[which_alternative]; --+ } --+} --+ [(set_attr "type" "dpack") --+ (set_attr "length" "4")]) --+ --+(define_insn "vec_mergev2hi_and_cv0_1" --+ [(set (match_operand:V2HI 0 "register_operand" "=$l,r") --+ (vec_merge:V2HI --+ (vec_duplicate:V2HI --+ (vec_select:HI --+ (match_operand:V2HI 1 "register_operand" " l,r") --+ (parallel [(const_int 0)]))) --+ (const_vector:V2HI [ --+ (const_int 0) --+ (const_int 0)]) --+ (const_int 1)))] --+ "NDS32_EXT_DSP_P () && !TARGET_BIG_ENDIAN" --+ "@ --+ zeh33\t%0, %1 --+ zeh\t%0, %1" --+ [(set_attr "type" "alu,alu") --+ (set_attr "length" " 2, 4")]) --+ --+(define_insn "vec_mergev2hi_and_cv0_2" --+ [(set (match_operand:V2HI 0 "register_operand" "=$l,r") --+ (vec_merge:V2HI --+ (const_vector:V2HI [ --+ (const_int 0) --+ (const_int 0)]) --+ (vec_duplicate:V2HI --+ (vec_select:HI --+ (match_operand:V2HI 1 "register_operand" " l,r") --+ (parallel [(const_int 0)]))) --+ (const_int 2)))] --+ "NDS32_EXT_DSP_P () && !TARGET_BIG_ENDIAN" --+ "@ --+ zeh33\t%0, %1 --+ zeh\t%0, %1" --+ [(set_attr "type" "alu,alu") --+ (set_attr "length" " 2, 4")]) --+ --+(define_insn "vec_mergehi_and_cv0_1" --+ [(set (match_operand:V2HI 0 "register_operand" "=$l,r") --+ (vec_merge:V2HI --+ (vec_duplicate:V2HI (match_operand:HI 1 "register_operand" " l,r")) --+ (const_vector:V2HI [ --+ (const_int 0) --+ (const_int 0)]) --+ (const_int 1)))] --+ "NDS32_EXT_DSP_P () && !TARGET_BIG_ENDIAN" --+ "@ --+ zeh33\t%0, %1 --+ zeh\t%0, %1" --+ [(set_attr "type" "alu,alu") --+ (set_attr "length" " 2, 4")]) --+ --+(define_insn "vec_mergehi_and_cv0_2" --+ [(set (match_operand:V2HI 0 "register_operand" "=$l,r") --+ (vec_merge:V2HI --+ (const_vector:V2HI [ --+ (const_int 0) --+ (const_int 0)]) --+ (vec_duplicate:V2HI (match_operand:HI 1 "register_operand" " l,r")) --+ (const_int 2)))] --+ "NDS32_EXT_DSP_P () && !TARGET_BIG_ENDIAN" --+ "@ --+ zeh33\t%0, %1 --+ zeh\t%0, %1" --+ [(set_attr "type" "alu,alu") --+ (set_attr "length" " 2, 4")]) --+ --+(define_expand "pkbb" --+ [(match_operand:V2HI 0 "register_operand") --+ (match_operand:V2HI 1 "register_operand") --+ (match_operand:V2HI 2 "register_operand")] --+ "NDS32_EXT_DSP_P ()" --+{ --+ if (TARGET_BIG_ENDIAN) --+ { --+ emit_insn (gen_vec_mergevv (operands[0], operands[1], operands[2], --+ GEN_INT (1), GEN_INT (1), GEN_INT (1))); --+ } --+ else --+ { --+ emit_insn (gen_vec_mergevv (operands[0], operands[1], operands[2], --+ GEN_INT (2), GEN_INT (0), GEN_INT (0))); --+ } --+ DONE; --+}) --+ --+(define_insn "pkbbsi_1" --+ [(set (match_operand:SI 0 "register_operand" "=r") --+ (ior:SI (and:SI (match_operand:SI 1 "register_operand" "r") --+ (const_int 65535)) --+ (ashift:SI (match_operand:SI 2 "register_operand" "r") --+ (const_int 16))))] --+ "NDS32_EXT_DSP_P ()" --+ "pkbb16\t%0, %2, %1" --+ [(set_attr "type" "dpack") --+ (set_attr "length" "4")]) --+ --+(define_insn "pkbbsi_2" --+ [(set (match_operand:SI 0 "register_operand" "=r") --+ (ior:SI (ashift:SI (match_operand:SI 2 "register_operand" "r") --+ (const_int 16)) --+ (and:SI (match_operand:SI 1 "register_operand" "r") --+ (const_int 65535))))] --+ "NDS32_EXT_DSP_P ()" --+ "pkbb16\t%0, %2, %1" --+ [(set_attr "type" "dpack") --+ (set_attr "length" "4")]) --+ --+(define_insn "pkbbsi_3" --+ [(set (match_operand:SI 0 "register_operand" "=r") --+ (ior:SI (zero_extend:SI (match_operand:HI 1 "register_operand" "r")) --+ (ashift:SI (match_operand:SI 2 "register_operand" "r") --+ (const_int 16))))] --+ "NDS32_EXT_DSP_P ()" --+ "pkbb16\t%0, %2, %1" --+ [(set_attr "type" "dpack") --+ (set_attr "length" "4")]) --+ --+(define_insn "pkbbsi_4" --+ [(set (match_operand:SI 0 "register_operand" "=r") --+ (ior:SI (ashift:SI (match_operand:SI 2 "register_operand" "r") --+ (const_int 16)) --+ (zero_extend:SI (match_operand:HI 1 "register_operand" "r"))))] --+ "NDS32_EXT_DSP_P ()" --+ "pkbb16\t%0, %2, %1" --+ [(set_attr "type" "dpack") --+ (set_attr "length" "4")]) --+ --+;; v0 = (v1 & 0xffff0000) | (v2 & 0xffff) --+(define_insn "pktbsi_1" --+ [(set (match_operand:SI 0 "register_operand" "=r") --+ (ior:SI (and:SI (match_operand:SI 1 "register_operand" "r") --+ (const_int -65536)) --+ (zero_extend:SI (match_operand:HI 2 "register_operand" "r"))))] --+ "NDS32_EXT_DSP_P ()" --+ "pktb16\t%0, %1, %2" --+ [(set_attr "type" "dpack") --+ (set_attr "length" "4")]) --+ --+(define_insn "pktbsi_2" --+ [(set (match_operand:SI 0 "register_operand" "=r") --+ (ior:SI (and:SI (match_operand:SI 1 "register_operand" "r") --+ (const_int -65536)) --+ (and:SI (match_operand:SI 2 "register_operand" "r") --+ (const_int 65535))))] --+ "NDS32_EXT_DSP_P ()" --+ "pktb16\t%0, %1, %2" --+ [(set_attr "type" "alu") --+ (set_attr "length" "4")]) --+ --+(define_insn "pktbsi_3" --+ [(set (zero_extract:SI (match_operand:SI 0 "register_operand" "+r") --+ (const_int 16 ) --+ (const_int 0)) --+ (match_operand:SI 1 "register_operand" " r"))] --+ "NDS32_EXT_DSP_P ()" --+ "pktb16\t%0, %0, %1" --+ [(set_attr "type" "dpack") --+ (set_attr "length" "4")]) --+ --+(define_insn "pktbsi_4" --+ [(set (zero_extract:SI (match_operand:SI 0 "register_operand" "+r") --+ (const_int 16 ) --+ (const_int 0)) --+ (zero_extend:SI (match_operand:HI 1 "register_operand" " r")))] --+ "NDS32_EXT_DSP_P ()" --+ "pktb16\t%0, %0, %1" --+ [(set_attr "type" "dpack") --+ (set_attr "length" "4")]) --+ --+(define_insn "pkttsi" --+ [(set (match_operand:SI 0 "register_operand" "=r") --+ (ior:SI (and:SI (match_operand:SI 1 "register_operand" " r") --+ (const_int -65536)) --+ (lshiftrt:SI (match_operand:SI 2 "register_operand" " r") --+ (const_int 16))))] --+ "NDS32_EXT_DSP_P ()" --+ "pktt16\t%0, %1, %2" --+ [(set_attr "type" "dpack") --+ (set_attr "length" "4")]) --+ --+(define_expand "pkbt" --+ [(match_operand:V2HI 0 "register_operand") --+ (match_operand:V2HI 1 "register_operand") --+ (match_operand:V2HI 2 "register_operand")] --+ "NDS32_EXT_DSP_P ()" --+{ --+ if (TARGET_BIG_ENDIAN) --+ { --+ emit_insn (gen_vec_mergevv (operands[0], operands[1], operands[2], --+ GEN_INT (1), GEN_INT (1), GEN_INT (0))); --+ } --+ else --+ { --+ emit_insn (gen_vec_mergevv (operands[0], operands[1], operands[2], --+ GEN_INT (2), GEN_INT (0), GEN_INT (1))); --+ } --+ DONE; --+}) --+ --+(define_expand "pktt" --+ [(match_operand:V2HI 0 "register_operand") --+ (match_operand:V2HI 1 "register_operand") --+ (match_operand:V2HI 2 "register_operand")] --+ "NDS32_EXT_DSP_P ()" --+{ --+ if (TARGET_BIG_ENDIAN) --+ { --+ emit_insn (gen_vec_mergevv (operands[0], operands[1], operands[2], --+ GEN_INT (1), GEN_INT (0), GEN_INT (0))); --+ } --+ else --+ { --+ emit_insn (gen_vec_mergevv (operands[0], operands[1], operands[2], --+ GEN_INT (2), GEN_INT (1), GEN_INT (1))); --+ } --+ DONE; --+}) --+ --+(define_expand "pktb" --+ [(match_operand:V2HI 0 "register_operand") --+ (match_operand:V2HI 1 "register_operand") --+ (match_operand:V2HI 2 "register_operand")] --+ "NDS32_EXT_DSP_P ()" --+{ --+ if (TARGET_BIG_ENDIAN) --+ { --+ emit_insn (gen_vec_mergevv (operands[0], operands[1], operands[2], --+ GEN_INT (1), GEN_INT (0), GEN_INT (1))); --+ } --+ else --+ { --+ emit_insn (gen_vec_mergevv (operands[0], operands[1], operands[2], --+ GEN_INT (2), GEN_INT (1), GEN_INT (0))); --+ } --+ DONE; --+}) --+ --+(define_insn "vec_mergerr" --+ [(set (match_operand:V2HI 0 "register_operand" "= r, r") --+ (vec_merge:V2HI --+ (vec_duplicate:V2HI --+ (match_operand:HI 1 "register_operand" " r, r")) --+ (vec_duplicate:V2HI --+ (match_operand:HI 2 "register_operand" " r, r")) --+ (match_operand:SI 3 "nds32_imm_1_2_operand" " Iv01, Iv02")))] --+ "NDS32_EXT_DSP_P () && !TARGET_BIG_ENDIAN" --+ "@ --+ pkbb16\t%0, %2, %1 --+ pkbb16\t%0, %1, %2" --+ [(set_attr "type" "dpack") --+ (set_attr "length" "4")]) --+ --+ --+(define_insn "vec_merge" --+ [(set (match_operand:V2HI 0 "register_operand" "= r, r") --+ (vec_merge:V2HI --+ (match_operand:V2HI 1 "register_operand" " r, r") --+ (match_operand:V2HI 2 "register_operand" " r, r") --+ (match_operand:SI 3 "nds32_imm_1_2_operand" " Iv01, Iv02")))] --+ "NDS32_EXT_DSP_P ()" --+{ --+ if (TARGET_BIG_ENDIAN) --+ { --+ const char *pats[] = { "pktb16\t%0, %1, %2", --+ "pktb16\t%0, %2, %1" }; --+ return pats[which_alternative]; --+ } --+ else --+ { --+ const char *pats[] = { "pktb16\t%0, %2, %1", --+ "pktb16\t%0, %1, %2" }; --+ return pats[which_alternative]; --+ } --+} --+ [(set_attr "type" "dpack") --+ (set_attr "length" "4")]) --+ --+(define_insn "vec_mergerv" --+ [(set (match_operand:V2HI 0 "register_operand" "= r, r, r, r") --+ (vec_merge:V2HI --+ (vec_duplicate:V2HI --+ (match_operand:HI 1 "register_operand" " r, r, r, r")) --+ (vec_duplicate:V2HI --+ (vec_select:HI --+ (match_operand:V2HI 2 "register_operand" " r, r, r, r") --+ (parallel [(match_operand:SI 4 "nds32_imm_0_1_operand" " Iv00, Iv01, Iv00, Iv01")]))) --+ (match_operand:SI 3 "nds32_imm_1_2_operand" " Iv01, Iv01, Iv02, Iv02")))] --+ "NDS32_EXT_DSP_P () && !TARGET_BIG_ENDIAN" --+ "@ --+ pkbb16\t%0, %2, %1 --+ pktb16\t%0, %2, %1 --+ pkbb16\t%0, %1, %2 --+ pkbt16\t%0, %1, %2" --+ [(set_attr "type" "dpack") --+ (set_attr "length" "4")]) --+ --+(define_insn "vec_mergevr" --+ [(set (match_operand:V2HI 0 "register_operand" "= r, r, r, r") --+ (vec_merge:V2HI --+ (vec_duplicate:V2HI --+ (vec_select:HI --+ (match_operand:V2HI 1 "register_operand" " r, r, r, r") --+ (parallel [(match_operand:SI 4 "nds32_imm_0_1_operand" " Iv00, Iv01, Iv00, Iv01")]))) --+ (vec_duplicate:V2HI --+ (match_operand:HI 2 "register_operand" " r, r, r, r")) --+ (match_operand:SI 3 "nds32_imm_1_2_operand" " Iv01, Iv01, Iv02, Iv02")))] --+ "NDS32_EXT_DSP_P () && !TARGET_BIG_ENDIAN" --+ "@ --+ pkbb16\t%0, %2, %1 --+ pkbt16\t%0, %2, %1 --+ pkbb16\t%0, %1, %2 --+ pktb16\t%0, %1, %2" --+ [(set_attr "type" "dpack") --+ (set_attr "length" "4")]) --+ --+(define_insn "vec_mergevv" --+ [(set (match_operand:V2HI 0 "register_operand" "= r, r, r, r, r, r, r, r") --+ (vec_merge:V2HI --+ (vec_duplicate:V2HI --+ (vec_select:HI --+ (match_operand:V2HI 1 "register_operand" " r, r, r, r, r, r, r, r") --+ (parallel [(match_operand:SI 4 "nds32_imm_0_1_operand" " Iv00, Iv00, Iv01, Iv01, Iv00, Iv00, Iv01, Iv01")]))) --+ (vec_duplicate:V2HI --+ (vec_select:HI --+ (match_operand:V2HI 2 "register_operand" " r, r, r, r, r, r, r, r") --+ (parallel [(match_operand:SI 5 "nds32_imm_0_1_operand" " Iv00, Iv01, Iv01, Iv00, Iv00, Iv01, Iv01, Iv00")]))) --+ (match_operand:SI 3 "nds32_imm_1_2_operand" " Iv01, Iv01, Iv01, Iv01, Iv02, Iv02, Iv02, Iv02")))] --+ "NDS32_EXT_DSP_P ()" --+{ --+ if (TARGET_BIG_ENDIAN) --+ { --+ const char *pats[] = { "pktt16\t%0, %1, %2", --+ "pktb16\t%0, %1, %2", --+ "pkbb16\t%0, %1, %2", --+ "pkbt16\t%0, %1, %2", --+ "pktt16\t%0, %2, %1", --+ "pkbt16\t%0, %2, %1", --+ "pkbb16\t%0, %2, %1", --+ "pktb16\t%0, %2, %1" }; --+ return pats[which_alternative]; --+ } --+ else --+ { --+ const char *pats[] = { "pkbb16\t%0, %2, %1", --+ "pktb16\t%0, %2, %1", --+ "pktt16\t%0, %2, %1", --+ "pkbt16\t%0, %2, %1", --+ "pkbb16\t%0, %1, %2", --+ "pkbt16\t%0, %1, %2", --+ "pktt16\t%0, %1, %2", --+ "pktb16\t%0, %1, %2" }; --+ return pats[which_alternative]; --+ } --+} --+ [(set_attr "type" "dpack") --+ (set_attr "length" "4")]) --+ --+(define_expand "vec_extractv4qi" --+ [(set (match_operand:QI 0 "register_operand" "") --+ (vec_select:QI --+ (match_operand:V4QI 1 "nonimmediate_operand" "") --+ (parallel [(match_operand:SI 2 "const_int_operand" "")])))] --+ "NDS32_EXT_DSP_P () && !TARGET_BIG_ENDIAN" --+{ --+ if (INTVAL (operands[2]) != 0 --+ && INTVAL (operands[2]) != 1 --+ && INTVAL (operands[2]) != 2 --+ && INTVAL (operands[2]) != 3) --+ gcc_unreachable (); --+ --+ if (INTVAL (operands[2]) != 0 && MEM_P (operands[0])) --+ FAIL; --+}) --+ --+(define_insn "vec_extractv4qi0" --+ [(set (match_operand:QI 0 "register_operand" "=l,r,r") --+ (vec_select:QI --+ (match_operand:V4QI 1 "nonimmediate_operand" " l,r,m") --+ (parallel [(const_int 0)])))] --+ "NDS32_EXT_DSP_P () && !TARGET_BIG_ENDIAN" --+{ --+ switch (which_alternative) --+ { --+ case 0: --+ return "zeb33\t%0, %1"; --+ case 1: --+ return "zeb\t%0, %1"; --+ case 2: --+ return nds32_output_32bit_load (operands, 1); --+ default: --+ gcc_unreachable (); --+ } --+} --+ [(set_attr "type" "alu") --+ (set_attr "length" "4")]) --+ --+(define_insn "vec_extractv4qi0_ze" --+ [(set (match_operand:SI 0 "register_operand" "=l,r,r") --+ (zero_extend:SI --+ (vec_select:QI --+ (match_operand:V4QI 1 "nonimmediate_operand" " l,r,m") --+ (parallel [(const_int 0)]))))] --+ "NDS32_EXT_DSP_P () && !TARGET_BIG_ENDIAN" --+{ --+ switch (which_alternative) --+ { --+ case 0: --+ return "zeb33\t%0, %1"; --+ case 1: --+ return "zeb\t%0, %1"; --+ case 2: --+ return nds32_output_32bit_load (operands, 1); --+ default: --+ gcc_unreachable (); --+ } --+} --+ [(set_attr "type" "alu") --+ (set_attr "length" "4")]) --+ --+(define_insn "vec_extractv4qi0_se" --+ [(set (match_operand:SI 0 "register_operand" "=l,r,r") --+ (sign_extend:SI --+ (vec_select:QI --+ (match_operand:V4QI 1 "nonimmediate_operand" " l,r,m") --+ (parallel [(const_int 0)]))))] --+ "NDS32_EXT_DSP_P () && !TARGET_BIG_ENDIAN" --+{ --+ switch (which_alternative) --+ { --+ case 0: --+ return "seb33\t%0, %1"; --+ case 1: --+ return "seb\t%0, %1"; --+ case 2: --+ return nds32_output_32bit_load_se (operands, 1); --+ default: --+ gcc_unreachable (); --+ } --+} --+ [(set_attr "type" "alu") --+ (set_attr "length" "4")]) --+ --+(define_insn_and_split "vec_extractv4qi1" --+ [(set (match_operand:QI 0 "register_operand" "=r") --+ (vec_select:QI --+ (match_operand:V4QI 1 "register_operand" " r") --+ (parallel [(const_int 1)])))] --+ "NDS32_EXT_DSP_P () && !reload_completed && !TARGET_BIG_ENDIAN" --+ "#" --+ "NDS32_EXT_DSP_P () && !reload_completed" --+ [(const_int 1)] --+{ --+ rtx tmp = gen_reg_rtx (V4QImode); --+ emit_insn (gen_rotrv4qi_1 (tmp, operands[1])); --+ emit_insn (gen_vec_extractv4qi0 (operands[0], tmp)); --+ DONE; --+} --+ [(set_attr "type" "alu") --+ (set_attr "length" "4")]) --+ --+(define_insn_and_split "vec_extractv4qi2" --+ [(set (match_operand:QI 0 "register_operand" "=r") --+ (vec_select:QI --+ (match_operand:V4QI 1 "register_operand" " r") --+ (parallel [(const_int 2)])))] --+ "NDS32_EXT_DSP_P () && !reload_completed && !TARGET_BIG_ENDIAN" --+ "#" --+ "NDS32_EXT_DSP_P () && !reload_completed" --+ [(const_int 1)] --+{ --+ rtx tmp = gen_reg_rtx (V4QImode); --+ emit_insn (gen_rotrv4qi_2 (tmp, operands[1])); --+ emit_insn (gen_vec_extractv4qi0 (operands[0], tmp)); --+ DONE; --+} --+ [(set_attr "type" "alu") --+ (set_attr "length" "4")]) --+ --+(define_insn_and_split "vec_extractv4qi3" --+ [(set (match_operand:QI 0 "register_operand" "=r") --+ (vec_select:QI --+ (match_operand:V4QI 1 "register_operand" " r") --+ (parallel [(const_int 3)])))] --+ "NDS32_EXT_DSP_P () && !reload_completed && !TARGET_BIG_ENDIAN" --+ "#" --+ "NDS32_EXT_DSP_P () && !reload_completed" --+ [(const_int 1)] --+{ --+ rtx tmp = gen_reg_rtx (V4QImode); --+ emit_insn (gen_rotrv4qi_3 (tmp, operands[1])); --+ emit_insn (gen_vec_extractv4qi0 (operands[0], tmp)); --+ DONE; --+} --+ [(set_attr "type" "alu") --+ (set_attr "length" "4")]) --+ --+(define_insn "vec_extractv4qi3_se" --+ [(set (match_operand:SI 0 "register_operand" "=$d,r") --+ (sign_extend:SI --+ (vec_select:QI --+ (match_operand:V4QI 1 "register_operand" " 0,r") --+ (parallel [(const_int 3)]))))] --+ "NDS32_EXT_DSP_P () && !TARGET_BIG_ENDIAN" --+ "@ --+ srai45\t%0, 24 --+ srai\t%0, %1, 24" --+ [(set_attr "type" "alu,alu") --+ (set_attr "length" " 2, 4")]) --+ --+(define_insn "vec_extractv4qi3_ze" --+ [(set (match_operand:SI 0 "register_operand" "=$d,r") --+ (zero_extend:SI --+ (vec_select:QI --+ (match_operand:V4QI 1 "register_operand" " 0,r") --+ (parallel [(const_int 3)]))))] --+ "NDS32_EXT_DSP_P () && !TARGET_BIG_ENDIAN" --+ "@ --+ srli45\t%0, 24 --+ srli\t%0, %1, 24" --+ [(set_attr "type" "alu,alu") --+ (set_attr "length" " 2, 4")]) --+ --+(define_insn_and_split "vec_extractv4qihi0" --+ [(set (match_operand:HI 0 "register_operand" "=r") --+ (sign_extend:HI --+ (vec_select:QI --+ (match_operand:V4QI 1 "register_operand" " r") --+ (parallel [(const_int 0)]))))] --+ "NDS32_EXT_DSP_P () && !reload_completed && !TARGET_BIG_ENDIAN" --+ "#" --+ "NDS32_EXT_DSP_P () && !reload_completed" --+ [(const_int 1)] --+{ --+ rtx tmp = gen_reg_rtx (QImode); --+ emit_insn (gen_vec_extractv4qi0 (tmp, operands[1])); --+ emit_insn (gen_extendqihi2 (operands[0], tmp)); --+ DONE; --+} --+ [(set_attr "type" "alu") --+ (set_attr "length" "4")]) --+ --+(define_insn_and_split "vec_extractv4qihi1" --+ [(set (match_operand:HI 0 "register_operand" "=r") --+ (sign_extend:HI --+ (vec_select:QI --+ (match_operand:V4QI 1 "register_operand" " r") --+ (parallel [(const_int 1)]))))] --+ "NDS32_EXT_DSP_P () && !reload_completed && !TARGET_BIG_ENDIAN" --+ "#" --+ "NDS32_EXT_DSP_P () && !reload_completed" --+ [(const_int 1)] --+{ --+ rtx tmp = gen_reg_rtx (QImode); --+ emit_insn (gen_vec_extractv4qi1 (tmp, operands[1])); --+ emit_insn (gen_extendqihi2 (operands[0], tmp)); --+ DONE; --+} --+ [(set_attr "type" "alu") --+ (set_attr "length" "4")]) --+ --+(define_insn_and_split "vec_extractv4qihi2" --+ [(set (match_operand:HI 0 "register_operand" "=r") --+ (sign_extend:HI --+ (vec_select:QI --+ (match_operand:V4QI 1 "register_operand" " r") --+ (parallel [(const_int 2)]))))] --+ "NDS32_EXT_DSP_P () && !reload_completed && !TARGET_BIG_ENDIAN" --+ "#" --+ "NDS32_EXT_DSP_P () && !reload_completed" --+ [(const_int 1)] --+{ --+ rtx tmp = gen_reg_rtx (QImode); --+ emit_insn (gen_vec_extractv4qi2 (tmp, operands[1])); --+ emit_insn (gen_extendqihi2 (operands[0], tmp)); --+ DONE; --+} --+ [(set_attr "type" "alu") --+ (set_attr "length" "4")]) --+ --+(define_insn_and_split "vec_extractv4qihi3" --+ [(set (match_operand:HI 0 "register_operand" "=r") --+ (sign_extend:HI --+ (vec_select:QI --+ (match_operand:V4QI 1 "register_operand" " r") --+ (parallel [(const_int 3)]))))] --+ "NDS32_EXT_DSP_P () && !reload_completed && !TARGET_BIG_ENDIAN" --+ "#" --+ "NDS32_EXT_DSP_P () && !reload_completed" --+ [(const_int 1)] --+{ --+ rtx tmp = gen_reg_rtx (QImode); --+ emit_insn (gen_vec_extractv4qi3 (tmp, operands[1])); --+ emit_insn (gen_extendqihi2 (operands[0], tmp)); --+ DONE; --+} --+ [(set_attr "type" "alu") --+ (set_attr "length" "4")]) --+ --+(define_expand "vec_extractv2hi" --+ [(set (match_operand:HI 0 "register_operand" "") --+ (vec_select:HI --+ (match_operand:V2HI 1 "nonimmediate_operand" "") --+ (parallel [(match_operand:SI 2 "const_int_operand" "")])))] --+ "NDS32_EXT_DSP_P ()" --+{ --+ if (INTVAL (operands[2]) != 0 --+ && INTVAL (operands[2]) != 1) --+ gcc_unreachable (); --+ --+ if (INTVAL (operands[2]) != 0 && MEM_P (operands[0])) --+ FAIL; --+}) --+ --+(define_insn "vec_extractv2hi0" --+ [(set (match_operand:HI 0 "register_operand" "=$l,r,r") --+ (vec_select:HI --+ (match_operand:V2HI 1 "nonimmediate_operand" " l,r,m") --+ (parallel [(const_int 0)])))] --+ "NDS32_EXT_DSP_P () && !TARGET_BIG_ENDIAN" --+{ --+ switch (which_alternative) --+ { --+ case 0: --+ return "seh33\t%0, %1"; --+ case 1: --+ return "seh\t%0, %1"; --+ case 2: --+ return nds32_output_32bit_load_se (operands, 2); --+ --+ default: --+ gcc_unreachable (); --+ } --+} --+ [(set_attr "type" "alu,alu,load") --+ (set_attr "length" " 2, 4, 4")]) --+ --+(define_insn "vec_extractv2hi0_ze" --+ [(set (match_operand:SI 0 "register_operand" "=$l, r,$ l, *r") --+ (zero_extend:SI --+ (vec_select:HI --+ (match_operand:V2HI 1 "nonimmediate_operand" " l, r, U33, m") --+ (parallel [(const_int 0)]))))] --+ "NDS32_EXT_DSP_P () && !TARGET_BIG_ENDIAN" --+{ --+ switch (which_alternative) --+ { --+ case 0: --+ return "zeh33\t%0, %1"; --+ case 1: --+ return "zeh\t%0, %1"; --+ case 2: --+ return nds32_output_16bit_load (operands, 2); --+ case 3: --+ return nds32_output_32bit_load (operands, 2); --+ --+ default: --+ gcc_unreachable (); --+ } --+} --+ [(set_attr "type" "alu,alu,load,load") --+ (set_attr "length" " 2, 4, 2, 4")]) --+ --+(define_insn "vec_extractv2hi0_se" --+ [(set (match_operand:SI 0 "register_operand" "=$l, r, r") --+ (sign_extend:SI --+ (vec_select:HI --+ (match_operand:V2HI 1 "nonimmediate_operand" " l,r,m") --+ (parallel [(const_int 0)]))))] --+ "NDS32_EXT_DSP_P () && !TARGET_BIG_ENDIAN" --+{ --+ switch (which_alternative) --+ { --+ case 0: --+ return "seh33\t%0, %1"; --+ case 1: --+ return "seh\t%0, %1"; --+ case 2: --+ return nds32_output_32bit_load_se (operands, 2); --+ --+ default: --+ gcc_unreachable (); --+ } --+} --+ [(set_attr "type" "alu,alu,load") --+ (set_attr "length" " 2, 4, 4")]) --+ --+(define_insn "vec_extractv2hi0_be" --+ [(set (match_operand:HI 0 "register_operand" "=$d,r") --+ (vec_select:HI --+ (match_operand:V2HI 1 "register_operand" " 0,r") --+ (parallel [(const_int 0)])))] --+ "NDS32_EXT_DSP_P () && TARGET_BIG_ENDIAN" --+ "@ --+ srai45\t%0, 16 --+ srai\t%0, %1, 16" --+ [(set_attr "type" "alu,alu") --+ (set_attr "length" " 2, 4")]) --+ --+(define_insn "vec_extractv2hi1" --+ [(set (match_operand:HI 0 "register_operand" "=$d,r") --+ (vec_select:HI --+ (match_operand:V2HI 1 "register_operand" " 0,r") --+ (parallel [(const_int 1)])))] --+ "NDS32_EXT_DSP_P () && !TARGET_BIG_ENDIAN" --+ "@ --+ srai45\t%0, 16 --+ srai\t%0, %1, 16" --+ [(set_attr "type" "alu,alu") --+ (set_attr "length" " 2, 4")]) --+ --+(define_insn "vec_extractv2hi1_se" --+ [(set (match_operand:SI 0 "register_operand" "=$d,r") --+ (sign_extend:SI --+ (vec_select:HI --+ (match_operand:V2HI 1 "register_operand" " 0,r") --+ (parallel [(const_int 1)]))))] --+ "NDS32_EXT_DSP_P () && !TARGET_BIG_ENDIAN" --+ "@ --+ srai45\t%0, 16 --+ srai\t%0, %1, 16" --+ [(set_attr "type" "alu,alu") --+ (set_attr "length" " 2, 4")]) --+ --+(define_insn "vec_extractv2hi1_ze" --+ [(set (match_operand:SI 0 "register_operand" "=$d,r") --+ (zero_extend:SI --+ (vec_select:HI --+ (match_operand:V2HI 1 "register_operand" " 0,r") --+ (parallel [(const_int 1)]))))] --+ "NDS32_EXT_DSP_P () && !TARGET_BIG_ENDIAN" --+ "@ --+ srli45\t%0, 16 --+ srli\t%0, %1, 16" --+ [(set_attr "type" "alu,alu") --+ (set_attr "length" " 2, 4")]) --+ --+(define_insn "vec_extractv2hi1_be" --+ [(set (match_operand:HI 0 "register_operand" "=$l,r,r") --+ (vec_select:HI --+ (match_operand:V2HI 1 "nonimmediate_operand" " l,r,m") --+ (parallel [(const_int 1)])))] --+ "NDS32_EXT_DSP_P () && TARGET_BIG_ENDIAN" --+{ --+ switch (which_alternative) --+ { --+ case 0: --+ return "seh33\t%0, %1"; --+ case 1: --+ return "seh\t%0, %1"; --+ case 2: --+ return nds32_output_32bit_load_se (operands, 2); --+ --+ default: --+ gcc_unreachable (); --+ } --+} --+ [(set_attr "type" "alu,alu,load") --+ (set_attr "length" " 2, 4, 4")]) --+ --+(define_insn "mul16" --+ [(set (match_operand:V2SI 0 "register_operand" "=r") --+ (mult:V2SI (extend:V2SI (match_operand:V2HI 1 "register_operand" "%r")) --+ (extend:V2SI (match_operand:V2HI 2 "register_operand" " r"))))] --+ "NDS32_EXT_DSP_P ()" --+ "mul16\t%0, %1, %2" --+ [(set_attr "type" "dmul") --+ (set_attr "length" "4")]) --+ --+(define_insn "mulx16" --+ [(set (match_operand:V2SI 0 "register_operand" "=r") --+ (vec_merge:V2SI --+ (vec_duplicate:V2SI --+ (mult:SI --+ (extend:SI --+ (vec_select:HI --+ (match_operand:V2HI 1 "register_operand" " r") --+ (parallel [(const_int 0)]))) --+ (extend:SI --+ (vec_select:HI --+ (match_operand:V2HI 2 "register_operand" " r") --+ (parallel [(const_int 1)]))))) --+ (vec_duplicate:V2SI --+ (mult:SI --+ (extend:SI --+ (vec_select:HI --+ (match_dup 1) --+ (parallel [(const_int 1)]))) --+ (extend:SI --+ (vec_select:HI --+ (match_dup 2) --+ (parallel [(const_int 0)]))))) --+ (const_int 1)))] --+ "NDS32_EXT_DSP_P ()" --+ "mulx16\t%0, %1, %2" --+ [(set_attr "type" "dmul") --+ (set_attr "length" "4")]) --+ --+(define_insn "rotrv2hi_1" --+ [(set (match_operand:V2HI 0 "register_operand" "=r") --+ (vec_select:V2HI --+ (match_operand:V2HI 1 "register_operand" " r") --+ (parallel [(const_int 1) (const_int 0)])))] --+ "NDS32_EXT_DSP_P () && !TARGET_BIG_ENDIAN" --+ "rotri\t%0, %1, 16" --+ [(set_attr "type" "alu") --+ (set_attr "length" "4")]) --+ --+(define_insn "rotrv2hi_1_be" --+ [(set (match_operand:V2HI 0 "register_operand" "=r") --+ (vec_select:V2HI --+ (match_operand:V2HI 1 "register_operand" " r") --+ (parallel [(const_int 0) (const_int 1)])))] --+ "NDS32_EXT_DSP_P () && TARGET_BIG_ENDIAN" --+ "rotri\t%0, %1, 16" --+ [(set_attr "type" "alu") --+ (set_attr "length" "4")]) --+ --+(define_insn "rotrv4qi_1" --+ [(set (match_operand:V4QI 0 "register_operand" "=r") --+ (vec_select:V4QI --+ (match_operand:V4QI 1 "register_operand" " r") --+ (parallel [(const_int 1) (const_int 2) (const_int 3) (const_int 0)])))] --+ "NDS32_EXT_DSP_P () && !TARGET_BIG_ENDIAN" --+ "rotri\t%0, %1, 8" --+ [(set_attr "type" "alu") --+ (set_attr "length" "4")]) --+ --+(define_insn "rotrv4qi_1_be" --+ [(set (match_operand:V4QI 0 "register_operand" "=r") --+ (vec_select:V4QI --+ (match_operand:V4QI 1 "register_operand" " r") --+ (parallel [(const_int 2) (const_int 1) (const_int 0) (const_int 3)])))] --+ "NDS32_EXT_DSP_P () && TARGET_BIG_ENDIAN" --+ "rotri\t%0, %1, 8" --+ [(set_attr "type" "alu") --+ (set_attr "length" "4")]) --+ --+(define_insn "rotrv4qi_2" --+ [(set (match_operand:V4QI 0 "register_operand" "=r") --+ (vec_select:V4QI --+ (match_operand:V4QI 1 "register_operand" " r") --+ (parallel [(const_int 2) (const_int 3) (const_int 0) (const_int 1)])))] --+ "NDS32_EXT_DSP_P () && !TARGET_BIG_ENDIAN" --+ "rotri\t%0, %1, 16" --+ [(set_attr "type" "alu") --+ (set_attr "length" "4")]) --+ --+(define_insn "rotrv4qi_2_be" --+ [(set (match_operand:V4QI 0 "register_operand" "=r") --+ (vec_select:V4QI --+ (match_operand:V4QI 1 "register_operand" " r") --+ (parallel [(const_int 1) (const_int 0) (const_int 3) (const_int 2)])))] --+ "NDS32_EXT_DSP_P () && TARGET_BIG_ENDIAN" --+ "rotri\t%0, %1, 16" --+ [(set_attr "type" "alu") --+ (set_attr "length" "4")]) --+ --+(define_insn "rotrv4qi_3" --+ [(set (match_operand:V4QI 0 "register_operand" "=r") --+ (vec_select:V4QI --+ (match_operand:V4QI 1 "register_operand" " r") --+ (parallel [(const_int 3) (const_int 0) (const_int 1) (const_int 2)])))] --+ "NDS32_EXT_DSP_P () && !TARGET_BIG_ENDIAN" --+ "rotri\t%0, %1, 24" --+ [(set_attr "type" "alu") --+ (set_attr "length" "4")]) --+ --+(define_insn "rotrv4qi_3_be" --+ [(set (match_operand:V4QI 0 "register_operand" "=r") --+ (vec_select:V4QI --+ (match_operand:V4QI 1 "register_operand" " r") --+ (parallel [(const_int 0) (const_int 3) (const_int 2) (const_int 1)])))] --+ "NDS32_EXT_DSP_P () && TARGET_BIG_ENDIAN" --+ "rotri\t%0, %1, 24" --+ [(set_attr "type" "alu") --+ (set_attr "length" "4")]) --+ --+(define_insn "v4qi_dup_10" --+ [(set (match_operand:V4QI 0 "register_operand" "=r") --+ (vec_select:V4QI --+ (match_operand:V4QI 1 "register_operand" " r") --+ (parallel [(const_int 0) (const_int 1) (const_int 0) (const_int 1)])))] --+ "NDS32_EXT_DSP_P () && !TARGET_BIG_ENDIAN" --+ "pkbb\t%0, %1, %1" --+ [(set_attr "type" "dpack") --+ (set_attr "length" "4")]) --+ --+(define_insn "v4qi_dup_32" --+ [(set (match_operand:V4QI 0 "register_operand" "=r") --+ (vec_select:V4QI --+ (match_operand:V4QI 1 "register_operand" " r") --+ (parallel [(const_int 2) (const_int 3) (const_int 2) (const_int 3)])))] --+ "NDS32_EXT_DSP_P () && !TARGET_BIG_ENDIAN" --+ "pktt\t%0, %1, %1" --+ [(set_attr "type" "dpack") --+ (set_attr "length" "4")]) --+ --+(define_expand "vec_unpacks_lo_v4qi" --+ [(match_operand:V2HI 0 "register_operand" "=r") --+ (match_operand:V4QI 1 "register_operand" " r")] --+ "NDS32_EXT_DSP_P () && !TARGET_BIG_ENDIAN" --+{ --+ emit_insn (gen_sunpkd810 (operands[0], operands[1])); --+ DONE; --+}) --+ --+(define_expand "sunpkd810" --+ [(match_operand:V2HI 0 "register_operand") --+ (match_operand:V4QI 1 "register_operand")] --+ "NDS32_EXT_DSP_P ()" --+{ --+ if (TARGET_BIG_ENDIAN) --+ emit_insn (gen_sunpkd810_imp_be (operands[0], operands[1])); --+ else --+ emit_insn (gen_sunpkd810_imp (operands[0], operands[1])); --+ DONE; --+}) --+ --+(define_insn "unpkd810_imp" --+ [(set (match_operand:V2HI 0 "register_operand" "=r") --+ (vec_merge:V2HI --+ (vec_duplicate:V2HI --+ (extend:HI --+ (vec_select:QI --+ (match_operand:V4QI 1 "register_operand" " r") --+ (parallel [(const_int 1)])))) --+ (vec_duplicate:V2HI --+ (extend:HI --+ (vec_select:QI --+ (match_dup 1) --+ (parallel [(const_int 0)])))) --+ (const_int 2)))] --+ "NDS32_EXT_DSP_P () && !TARGET_BIG_ENDIAN" --+ "unpkd810\t%0, %1" --+ [(set_attr "type" "dpack") --+ (set_attr "length" "4")]) --+ --+(define_insn "unpkd810_imp_inv" --+ [(set (match_operand:V2HI 0 "register_operand" "=r") --+ (vec_merge:V2HI --+ (vec_duplicate:V2HI --+ (extend:HI --+ (vec_select:QI --+ (match_operand:V4QI 1 "register_operand" " r") --+ (parallel [(const_int 0)])))) --+ (vec_duplicate:V2HI --+ (extend:HI --+ (vec_select:QI --+ (match_dup 1) --+ (parallel [(const_int 1)])))) --+ (const_int 1)))] --+ "NDS32_EXT_DSP_P () && !TARGET_BIG_ENDIAN" --+ "unpkd810\t%0, %1" --+ [(set_attr "type" "dpack") --+ (set_attr "length" "4")]) --+ --+(define_insn "unpkd810_imp_be" --+ [(set (match_operand:V2HI 0 "register_operand" "=r") --+ (vec_merge:V2HI --+ (vec_duplicate:V2HI --+ (extend:HI --+ (vec_select:QI --+ (match_operand:V4QI 1 "register_operand" " r") --+ (parallel [(const_int 2)])))) --+ (vec_duplicate:V2HI --+ (extend:HI --+ (vec_select:QI --+ (match_dup 1) --+ (parallel [(const_int 3)])))) --+ (const_int 1)))] --+ "NDS32_EXT_DSP_P () && TARGET_BIG_ENDIAN" --+ "unpkd810\t%0, %1" --+ [(set_attr "type" "dpack") --+ (set_attr "length" "4")]) --+ --+(define_insn "unpkd810_imp_inv_be" --+ [(set (match_operand:V2HI 0 "register_operand" "=r") --+ (vec_merge:V2HI --+ (vec_duplicate:V2HI --+ (extend:HI --+ (vec_select:QI --+ (match_operand:V4QI 1 "register_operand" " r") --+ (parallel [(const_int 3)])))) --+ (vec_duplicate:V2HI --+ (extend:HI --+ (vec_select:QI --+ (match_dup 1) --+ (parallel [(const_int 2)])))) --+ (const_int 2)))] --+ "NDS32_EXT_DSP_P () && TARGET_BIG_ENDIAN" --+ "unpkd810\t%0, %1" --+ [(set_attr "type" "dpack") --+ (set_attr "length" "4")]) --+ --+(define_expand "sunpkd820" --+ [(match_operand:V2HI 0 "register_operand") --+ (match_operand:V4QI 1 "register_operand")] --+ "NDS32_EXT_DSP_P ()" --+{ --+ if (TARGET_BIG_ENDIAN) --+ emit_insn (gen_sunpkd820_imp_be (operands[0], operands[1])); --+ else --+ emit_insn (gen_sunpkd820_imp (operands[0], operands[1])); --+ DONE; --+}) --+ --+(define_insn "unpkd820_imp" --+ [(set (match_operand:V2HI 0 "register_operand" "=r") --+ (vec_merge:V2HI --+ (vec_duplicate:V2HI --+ (extend:HI --+ (vec_select:QI --+ (match_operand:V4QI 1 "register_operand" " r") --+ (parallel [(const_int 2)])))) --+ (vec_duplicate:V2HI --+ (extend:HI --+ (vec_select:QI --+ (match_dup 1) --+ (parallel [(const_int 0)])))) --+ (const_int 2)))] --+ "NDS32_EXT_DSP_P () && !TARGET_BIG_ENDIAN" --+ "unpkd820\t%0, %1" --+ [(set_attr "type" "dpack") --+ (set_attr "length" "4")]) --+ --+(define_insn "unpkd820_imp_inv" --+ [(set (match_operand:V2HI 0 "register_operand" "=r") --+ (vec_merge:V2HI --+ (vec_duplicate:V2HI --+ (extend:HI --+ (vec_select:QI --+ (match_operand:V4QI 1 "register_operand" " r") --+ (parallel [(const_int 0)])))) --+ (vec_duplicate:V2HI --+ (extend:HI --+ (vec_select:QI --+ (match_dup 1) --+ (parallel [(const_int 2)])))) --+ (const_int 1)))] --+ "NDS32_EXT_DSP_P () && !TARGET_BIG_ENDIAN" --+ "unpkd820\t%0, %1" --+ [(set_attr "type" "dpack") --+ (set_attr "length" "4")]) --+ --+(define_insn "unpkd820_imp_be" --+ [(set (match_operand:V2HI 0 "register_operand" "=r") --+ (vec_merge:V2HI --+ (vec_duplicate:V2HI --+ (extend:HI --+ (vec_select:QI --+ (match_operand:V4QI 1 "register_operand" " r") --+ (parallel [(const_int 1)])))) --+ (vec_duplicate:V2HI --+ (extend:HI --+ (vec_select:QI --+ (match_dup 1) --+ (parallel [(const_int 3)])))) --+ (const_int 1)))] --+ "NDS32_EXT_DSP_P () && TARGET_BIG_ENDIAN" --+ "unpkd820\t%0, %1" --+ [(set_attr "type" "dpack") --+ (set_attr "length" "4")]) --+ --+(define_insn "unpkd820_imp_inv_be" --+ [(set (match_operand:V2HI 0 "register_operand" "=r") --+ (vec_merge:V2HI --+ (vec_duplicate:V2HI --+ (extend:HI --+ (vec_select:QI --+ (match_operand:V4QI 1 "register_operand" " r") --+ (parallel [(const_int 3)])))) --+ (vec_duplicate:V2HI --+ (extend:HI --+ (vec_select:QI --+ (match_dup 1) --+ (parallel [(const_int 1)])))) --+ (const_int 2)))] --+ "NDS32_EXT_DSP_P () && TARGET_BIG_ENDIAN" --+ "unpkd820\t%0, %1" --+ [(set_attr "type" "dpack") --+ (set_attr "length" "4")]) --+ --+(define_expand "sunpkd830" --+ [(match_operand:V2HI 0 "register_operand") --+ (match_operand:V4QI 1 "register_operand")] --+ "NDS32_EXT_DSP_P ()" --+{ --+ if (TARGET_BIG_ENDIAN) --+ emit_insn (gen_sunpkd830_imp_be (operands[0], operands[1])); --+ else --+ emit_insn (gen_sunpkd830_imp (operands[0], operands[1])); --+ DONE; --+}) --+ --+(define_insn "unpkd830_imp" --+ [(set (match_operand:V2HI 0 "register_operand" "=r") --+ (vec_merge:V2HI --+ (vec_duplicate:V2HI --+ (extend:HI --+ (vec_select:QI --+ (match_operand:V4QI 1 "register_operand" " r") --+ (parallel [(const_int 3)])))) --+ (vec_duplicate:V2HI --+ (extend:HI --+ (vec_select:QI --+ (match_dup 1) --+ (parallel [(const_int 0)])))) --+ (const_int 2)))] --+ "NDS32_EXT_DSP_P () && !TARGET_BIG_ENDIAN" --+ "unpkd830\t%0, %1" --+ [(set_attr "type" "dpack") --+ (set_attr "length" "4")]) --+ --+(define_insn "unpkd830_imp_inv" --+ [(set (match_operand:V2HI 0 "register_operand" "=r") --+ (vec_merge:V2HI --+ (vec_duplicate:V2HI --+ (extend:HI --+ (vec_select:QI --+ (match_operand:V4QI 1 "register_operand" " r") --+ (parallel [(const_int 0)])))) --+ (vec_duplicate:V2HI --+ (extend:HI --+ (vec_select:QI --+ (match_dup 1) --+ (parallel [(const_int 3)])))) --+ (const_int 1)))] --+ "NDS32_EXT_DSP_P () && !TARGET_BIG_ENDIAN" --+ "unpkd830\t%0, %1" --+ [(set_attr "type" "dpack") --+ (set_attr "length" "4")]) --+ --+(define_insn "unpkd830_imp_be" --+ [(set (match_operand:V2HI 0 "register_operand" "=r") --+ (vec_merge:V2HI --+ (vec_duplicate:V2HI --+ (extend:HI --+ (vec_select:QI --+ (match_operand:V4QI 1 "register_operand" " r") --+ (parallel [(const_int 0)])))) --+ (vec_duplicate:V2HI --+ (extend:HI --+ (vec_select:QI --+ (match_dup 1) --+ (parallel [(const_int 3)])))) --+ (const_int 1)))] --+ "NDS32_EXT_DSP_P () && TARGET_BIG_ENDIAN" --+ "unpkd830\t%0, %1" --+ [(set_attr "type" "dpack") --+ (set_attr "length" "4")]) --+ --+(define_insn "unpkd830_imp_inv_be" --+ [(set (match_operand:V2HI 0 "register_operand" "=r") --+ (vec_merge:V2HI --+ (vec_duplicate:V2HI --+ (extend:HI --+ (vec_select:QI --+ (match_operand:V4QI 1 "register_operand" " r") --+ (parallel [(const_int 3)])))) --+ (vec_duplicate:V2HI --+ (extend:HI --+ (vec_select:QI --+ (match_dup 1) --+ (parallel [(const_int 0)])))) --+ (const_int 2)))] --+ "NDS32_EXT_DSP_P () && TARGET_BIG_ENDIAN" --+ "unpkd830\t%0, %1" --+ [(set_attr "type" "dpack") --+ (set_attr "length" "4")]) --+ --+(define_expand "sunpkd831" --+ [(match_operand:V2HI 0 "register_operand") --+ (match_operand:V4QI 1 "register_operand")] --+ "NDS32_EXT_DSP_P ()" --+{ --+ if (TARGET_BIG_ENDIAN) --+ emit_insn (gen_sunpkd831_imp_be (operands[0], operands[1])); --+ else --+ emit_insn (gen_sunpkd831_imp (operands[0], operands[1])); --+ DONE; --+}) --+ --+(define_insn "unpkd831_imp" --+ [(set (match_operand:V2HI 0 "register_operand" "=r") --+ (vec_merge:V2HI --+ (vec_duplicate:V2HI --+ (extend:HI --+ (vec_select:QI --+ (match_operand:V4QI 1 "register_operand" " r") --+ (parallel [(const_int 3)])))) --+ (vec_duplicate:V2HI --+ (extend:HI --+ (vec_select:QI --+ (match_dup 1) --+ (parallel [(const_int 1)])))) --+ (const_int 2)))] --+ "NDS32_EXT_DSP_P () && !TARGET_BIG_ENDIAN" --+ "unpkd831\t%0, %1" --+ [(set_attr "type" "dpack") --+ (set_attr "length" "4")]) --+ --+(define_insn "unpkd831_imp_inv" --+ [(set (match_operand:V2HI 0 "register_operand" "=r") --+ (vec_merge:V2HI --+ (vec_duplicate:V2HI --+ (extend:HI --+ (vec_select:QI --+ (match_operand:V4QI 1 "register_operand" " r") --+ (parallel [(const_int 1)])))) --+ (vec_duplicate:V2HI --+ (extend:HI --+ (vec_select:QI --+ (match_dup 1) --+ (parallel [(const_int 3)])))) --+ (const_int 1)))] --+ "NDS32_EXT_DSP_P () && !TARGET_BIG_ENDIAN" --+ "unpkd831\t%0, %1" --+ [(set_attr "type" "dpack") --+ (set_attr "length" "4")]) --+ --+(define_insn "unpkd831_imp_be" --+ [(set (match_operand:V2HI 0 "register_operand" "=r") --+ (vec_merge:V2HI --+ (vec_duplicate:V2HI --+ (extend:HI --+ (vec_select:QI --+ (match_operand:V4QI 1 "register_operand" " r") --+ (parallel [(const_int 0)])))) --+ (vec_duplicate:V2HI --+ (extend:HI --+ (vec_select:QI --+ (match_dup 1) --+ (parallel [(const_int 2)])))) --+ (const_int 1)))] --+ "NDS32_EXT_DSP_P () && TARGET_BIG_ENDIAN" --+ "unpkd831\t%0, %1" --+ [(set_attr "type" "dpack") --+ (set_attr "length" "4")]) --+ --+(define_insn "unpkd831_imp_inv_be" --+ [(set (match_operand:V2HI 0 "register_operand" "=r") --+ (vec_merge:V2HI --+ (vec_duplicate:V2HI --+ (extend:HI --+ (vec_select:QI --+ (match_operand:V4QI 1 "register_operand" " r") --+ (parallel [(const_int 2)])))) --+ (vec_duplicate:V2HI --+ (extend:HI --+ (vec_select:QI --+ (match_dup 1) --+ (parallel [(const_int 0)])))) --+ (const_int 2)))] --+ "NDS32_EXT_DSP_P () && TARGET_BIG_ENDIAN" --+ "unpkd831\t%0, %1" --+ [(set_attr "type" "dpack") --+ (set_attr "length" "4")]) --+ --+(define_expand "zunpkd810" --+ [(match_operand:V2HI 0 "register_operand") --+ (match_operand:V4QI 1 "register_operand")] --+ "NDS32_EXT_DSP_P ()" --+{ --+ if (TARGET_BIG_ENDIAN) --+ emit_insn (gen_zunpkd810_imp_be (operands[0], operands[1])); --+ else --+ emit_insn (gen_zunpkd810_imp (operands[0], operands[1])); --+ DONE; --+}) --+ --+(define_expand "zunpkd820" --+ [(match_operand:V2HI 0 "register_operand") --+ (match_operand:V4QI 1 "register_operand")] --+ "NDS32_EXT_DSP_P ()" --+{ --+ if (TARGET_BIG_ENDIAN) --+ emit_insn (gen_zunpkd820_imp_be (operands[0], operands[1])); --+ else --+ emit_insn (gen_zunpkd820_imp (operands[0], operands[1])); --+ DONE; --+}) --+ --+(define_expand "zunpkd830" --+ [(match_operand:V2HI 0 "register_operand") --+ (match_operand:V4QI 1 "register_operand")] --+ "NDS32_EXT_DSP_P ()" --+{ --+ if (TARGET_BIG_ENDIAN) --+ emit_insn (gen_zunpkd830_imp_be (operands[0], operands[1])); --+ else --+ emit_insn (gen_zunpkd830_imp (operands[0], operands[1])); --+ DONE; --+}) --+ --+(define_expand "zunpkd831" --+ [(match_operand:V2HI 0 "register_operand") --+ (match_operand:V4QI 1 "register_operand")] --+ "NDS32_EXT_DSP_P ()" --+{ --+ if (TARGET_BIG_ENDIAN) --+ emit_insn (gen_zunpkd831_imp_be (operands[0], operands[1])); --+ else --+ emit_insn (gen_zunpkd831_imp (operands[0], operands[1])); --+ DONE; --+}) --+ --+(define_expand "smbb" --+ [(match_operand:SI 0 "register_operand" "") --+ (match_operand:V2HI 1 "register_operand" "") --+ (match_operand:V2HI 2 "register_operand" "")] --+ "NDS32_EXT_DSP_P ()" --+{ --+ if (TARGET_BIG_ENDIAN) --+ emit_insn (gen_mulhisi3v (operands[0], operands[1], operands[2], --+ GEN_INT (1), GEN_INT (1))); --+ else --+ emit_insn (gen_mulhisi3v (operands[0], operands[1], operands[2], --+ GEN_INT (0), GEN_INT (0))); --+ DONE; --+}) --+ --+(define_expand "smbt" --+ [(match_operand:SI 0 "register_operand" "") --+ (match_operand:V2HI 1 "register_operand" "") --+ (match_operand:V2HI 2 "register_operand" "")] --+ "NDS32_EXT_DSP_P ()" --+{ --+ if (TARGET_BIG_ENDIAN) --+ emit_insn (gen_mulhisi3v (operands[0], operands[1], operands[2], --+ GEN_INT (1), GEN_INT (0))); --+ else --+ emit_insn (gen_mulhisi3v (operands[0], operands[1], operands[2], --+ GEN_INT (0), GEN_INT (1))); --+ DONE; --+}) --+ --+(define_expand "smtt" --+ [(match_operand:SI 0 "register_operand" "") --+ (match_operand:V2HI 1 "register_operand" "") --+ (match_operand:V2HI 2 "register_operand" "")] --+ "NDS32_EXT_DSP_P ()" --+{ --+ if (TARGET_BIG_ENDIAN) --+ emit_insn (gen_mulhisi3v (operands[0], operands[1], operands[2], --+ GEN_INT (0), GEN_INT (0))); --+ else --+ emit_insn (gen_mulhisi3v (operands[0], operands[1], operands[2], --+ GEN_INT (1), GEN_INT (1))); --+ DONE; --+}) --+ --+(define_insn "mulhisi3v" --+ [(set (match_operand:SI 0 "register_operand" "= r, r, r, r") --+ (mult:SI --+ (sign_extend:SI --+ (vec_select:HI --+ (match_operand:V2HI 1 "register_operand" " r, r, r, r") --+ (parallel [(match_operand:SI 3 "nds32_imm_0_1_operand" " Iv00, Iv00, Iv01, Iv01")]))) --+ (sign_extend:SI (vec_select:HI --+ (match_operand:V2HI 2 "register_operand" " r, r, r, r") --+ (parallel [(match_operand:SI 4 "nds32_imm_0_1_operand" " Iv00, Iv01, Iv01, Iv00")])))))] --+ "NDS32_EXT_DSP_P ()" --+{ --+ if (TARGET_BIG_ENDIAN) --+ { --+ const char *pats[] = { "smtt\t%0, %1, %2", --+ "smbt\t%0, %2, %1", --+ "smbb\t%0, %1, %2", --+ "smbt\t%0, %1, %2" }; --+ return pats[which_alternative]; --+ } --+ else --+ { --+ const char *pats[] = { "smbb\t%0, %1, %2", --+ "smbt\t%0, %1, %2", --+ "smtt\t%0, %1, %2", --+ "smbt\t%0, %2, %1" }; --+ return pats[which_alternative]; --+ } --+} --+ [(set_attr "type" "dmul") --+ (set_attr "length" "4")]) --+ --+(define_expand "kmabb" --+ [(match_operand:SI 0 "register_operand" "") --+ (match_operand:SI 1 "register_operand" "") --+ (match_operand:V2HI 2 "register_operand" "") --+ (match_operand:V2HI 3 "register_operand" "")] --+ "NDS32_EXT_DSP_P ()" --+{ --+ if (TARGET_BIG_ENDIAN) --+ emit_insn (gen_kma_internal (operands[0], operands[2], operands[3], --+ GEN_INT (1), GEN_INT (1), --+ operands[1])); --+ else --+ emit_insn (gen_kma_internal (operands[0], operands[2], operands[3], --+ GEN_INT (0), GEN_INT (0), --+ operands[1])); --+ DONE; --+}) --+ --+(define_expand "kmabt" --+ [(match_operand:SI 0 "register_operand" "") --+ (match_operand:SI 1 "register_operand" "") --+ (match_operand:V2HI 2 "register_operand" "") --+ (match_operand:V2HI 3 "register_operand" "")] --+ "NDS32_EXT_DSP_P ()" --+{ --+ if (TARGET_BIG_ENDIAN) --+ emit_insn (gen_kma_internal (operands[0], operands[2], operands[3], --+ GEN_INT (1), GEN_INT (0), --+ operands[1])); --+ else --+ emit_insn (gen_kma_internal (operands[0], operands[2], operands[3], --+ GEN_INT (0), GEN_INT (1), --+ operands[1])); --+ DONE; --+}) --+ --+(define_expand "kmatt" --+ [(match_operand:SI 0 "register_operand" "") --+ (match_operand:SI 1 "register_operand" "") --+ (match_operand:V2HI 2 "register_operand" "") --+ (match_operand:V2HI 3 "register_operand" "")] --+ "NDS32_EXT_DSP_P ()" --+{ --+ if (TARGET_BIG_ENDIAN) --+ emit_insn (gen_kma_internal (operands[0], operands[2], operands[3], --+ GEN_INT (0), GEN_INT (0), --+ operands[1])); --+ else --+ emit_insn (gen_kma_internal (operands[0], operands[2], operands[3], --+ GEN_INT (1), GEN_INT (1), --+ operands[1])); --+ DONE; --+}) --+ --+(define_insn "kma_internal" --+ [(set (match_operand:SI 0 "register_operand" "= r, r, r, r") --+ (ss_plus:SI --+ (mult:SI --+ (sign_extend:SI --+ (vec_select:HI --+ (match_operand:V2HI 1 "register_operand" " r, r, r, r") --+ (parallel [(match_operand:SI 3 "nds32_imm_0_1_operand" " Iv00, Iv00, Iv01, Iv01")]))) --+ (sign_extend:SI --+ (vec_select:HI --+ (match_operand:V2HI 2 "register_operand" " r, r, r, r") --+ (parallel [(match_operand:SI 4 "nds32_imm_0_1_operand" " Iv00, Iv01, Iv01, Iv00")])))) --+ (match_operand:SI 5 "register_operand" " 0, 0, 0, 0")))] --+ "NDS32_EXT_DSP_P ()" --+{ --+ if (TARGET_BIG_ENDIAN) --+ { --+ const char *pats[] = { "kmatt\t%0, %1, %2", --+ "kmabt\t%0, %2, %1", --+ "kmabb\t%0, %1, %2", --+ "kmabt\t%0, %1, %2" }; --+ return pats[which_alternative]; --+ } --+ else --+ { --+ const char *pats[] = { "kmabb\t%0, %1, %2", --+ "kmabt\t%0, %1, %2", --+ "kmatt\t%0, %1, %2", --+ "kmabt\t%0, %2, %1" }; --+ return pats[which_alternative]; --+ } --+} --+ [(set_attr "type" "dmac") --+ (set_attr "length" "4")]) --+ --+(define_expand "smds" --+ [(match_operand:SI 0 "register_operand" "") --+ (match_operand:V2HI 1 "register_operand" "") --+ (match_operand:V2HI 2 "register_operand" "")] --+ "NDS32_EXT_DSP_P ()" --+{ --+ if (TARGET_BIG_ENDIAN) --+ emit_insn (gen_smds_be (operands[0], operands[1], operands[2])); --+ else --+ emit_insn (gen_smds_le (operands[0], operands[1], operands[2])); --+ DONE; --+}) --+ --+(define_expand "smds_le" --+ [(set (match_operand:SI 0 "register_operand" "=r") --+ (minus:SI --+ (mult:SI --+ (sign_extend:SI (vec_select:HI --+ (match_operand:V2HI 1 "register_operand" " r") --+ (parallel [(const_int 1)]))) --+ (sign_extend:SI (vec_select:HI --+ (match_operand:V2HI 2 "register_operand" " r") --+ (parallel [(const_int 1)])))) --+ (mult:SI --+ (sign_extend:SI (vec_select:HI --+ (match_dup 1) --+ (parallel [(const_int 0)]))) --+ (sign_extend:SI (vec_select:HI --+ (match_dup 2) --+ (parallel [(const_int 0)]))))))] --+ "NDS32_EXT_DSP_P ()" --+{ --+}) --+ --+(define_expand "smds_be" --+ [(set (match_operand:SI 0 "register_operand" "=r") --+ (minus:SI --+ (mult:SI --+ (sign_extend:SI (vec_select:HI --+ (match_operand:V2HI 1 "register_operand" " r") --+ (parallel [(const_int 0)]))) --+ (sign_extend:SI (vec_select:HI --+ (match_operand:V2HI 2 "register_operand" " r") --+ (parallel [(const_int 0)])))) --+ (mult:SI --+ (sign_extend:SI (vec_select:HI --+ (match_dup 1) --+ (parallel [(const_int 1)]))) --+ (sign_extend:SI (vec_select:HI --+ (match_dup 2) --+ (parallel [(const_int 1)]))))))] --+ "NDS32_EXT_DSP_P ()" --+{ --+}) --+ --+(define_expand "smdrs" --+ [(match_operand:SI 0 "register_operand" "") --+ (match_operand:V2HI 1 "register_operand" "") --+ (match_operand:V2HI 2 "register_operand" "")] --+ "NDS32_EXT_DSP_P ()" --+{ --+ if (TARGET_BIG_ENDIAN) --+ emit_insn (gen_smdrs_be (operands[0], operands[1], operands[2])); --+ else --+ emit_insn (gen_smdrs_le (operands[0], operands[1], operands[2])); --+ DONE; --+}) --+ --+(define_expand "smdrs_le" --+ [(set (match_operand:SI 0 "register_operand" "=r") --+ (minus:SI --+ (mult:SI --+ (sign_extend:SI (vec_select:HI --+ (match_operand:V2HI 1 "register_operand" " r") --+ (parallel [(const_int 0)]))) --+ (sign_extend:SI (vec_select:HI --+ (match_operand:V2HI 2 "register_operand" " r") --+ (parallel [(const_int 0)])))) --+ (mult:SI --+ (sign_extend:SI (vec_select:HI --+ (match_dup 1) --+ (parallel [(const_int 1)]))) --+ (sign_extend:SI (vec_select:HI --+ (match_dup 2) --+ (parallel [(const_int 1)]))))))] --+ "NDS32_EXT_DSP_P ()" --+{ --+}) --+ --+(define_expand "smdrs_be" --+ [(set (match_operand:SI 0 "register_operand" "=r") --+ (minus:SI --+ (mult:SI --+ (sign_extend:SI (vec_select:HI --+ (match_operand:V2HI 1 "register_operand" " r") --+ (parallel [(const_int 1)]))) --+ (sign_extend:SI (vec_select:HI --+ (match_operand:V2HI 2 "register_operand" " r") --+ (parallel [(const_int 1)])))) --+ (mult:SI --+ (sign_extend:SI (vec_select:HI --+ (match_dup 1) --+ (parallel [(const_int 0)]))) --+ (sign_extend:SI (vec_select:HI --+ (match_dup 2) --+ (parallel [(const_int 0)]))))))] --+ "NDS32_EXT_DSP_P ()" --+{ --+}) --+ --+(define_expand "smxdsv" --+ [(match_operand:SI 0 "register_operand" "") --+ (match_operand:V2HI 1 "register_operand" "") --+ (match_operand:V2HI 2 "register_operand" "")] --+ "NDS32_EXT_DSP_P ()" --+{ --+ if (TARGET_BIG_ENDIAN) --+ emit_insn (gen_smxdsv_be (operands[0], operands[1], operands[2])); --+ else --+ emit_insn (gen_smxdsv_le (operands[0], operands[1], operands[2])); --+ DONE; --+}) --+ --+ --+(define_expand "smxdsv_le" --+ [(set (match_operand:SI 0 "register_operand" "=r") --+ (minus:SI --+ (mult:SI --+ (sign_extend:SI (vec_select:HI --+ (match_operand:V2HI 1 "register_operand" " r") --+ (parallel [(const_int 1)]))) --+ (sign_extend:SI (vec_select:HI --+ (match_operand:V2HI 2 "register_operand" " r") --+ (parallel [(const_int 0)])))) --+ (mult:SI --+ (sign_extend:SI (vec_select:HI --+ (match_dup 1) --+ (parallel [(const_int 0)]))) --+ (sign_extend:SI (vec_select:HI --+ (match_dup 2) --+ (parallel [(const_int 1)]))))))] --+ "NDS32_EXT_DSP_P ()" --+{ --+}) --+ --+(define_expand "smxdsv_be" --+ [(set (match_operand:SI 0 "register_operand" "=r") --+ (minus:SI --+ (mult:SI --+ (sign_extend:SI (vec_select:HI --+ (match_operand:V2HI 1 "register_operand" " r") --+ (parallel [(const_int 0)]))) --+ (sign_extend:SI (vec_select:HI --+ (match_operand:V2HI 2 "register_operand" " r") --+ (parallel [(const_int 1)])))) --+ (mult:SI --+ (sign_extend:SI (vec_select:HI --+ (match_dup 1) --+ (parallel [(const_int 1)]))) --+ (sign_extend:SI (vec_select:HI --+ (match_dup 2) --+ (parallel [(const_int 0)]))))))] --+ "NDS32_EXT_DSP_P ()" --+{ --+}) --+ --+(define_insn "smal1" --+ [(set (match_operand:DI 0 "register_operand" "=r") --+ (plus:DI (match_operand:DI 1 "register_operand" " r") --+ (sign_extend:DI --+ (mult:SI --+ (sign_extend:SI --+ (vec_select:HI --+ (match_operand:V2HI 2 "register_operand" " r") --+ (parallel [(const_int 0)]))) --+ (sign_extend:SI --+ (vec_select:HI --+ (match_dup 2) --+ (parallel [(const_int 1)])))))))] --+ "NDS32_EXT_DSP_P ()" --+ "smal\t%0, %1, %2" --+ [(set_attr "type" "dmac") --+ (set_attr "length" "4")]) --+ --+(define_insn "smal2" --+ [(set (match_operand:DI 0 "register_operand" "=r") --+ (plus:DI (match_operand:DI 1 "register_operand" " r") --+ (mult:DI --+ (sign_extend:DI --+ (vec_select:HI --+ (match_operand:V2HI 2 "register_operand" " r") --+ (parallel [(const_int 0)]))) --+ (sign_extend:DI --+ (vec_select:HI --+ (match_dup 2) --+ (parallel [(const_int 1)]))))))] --+ "NDS32_EXT_DSP_P ()" --+ "smal\t%0, %1, %2" --+ [(set_attr "type" "dmac") --+ (set_attr "length" "4")]) --+ --+(define_insn "smal3" --+ [(set (match_operand:DI 0 "register_operand" "=r") --+ (plus:DI (match_operand:DI 1 "register_operand" " r") --+ (sign_extend:DI --+ (mult:SI --+ (sign_extend:SI --+ (vec_select:HI --+ (match_operand:V2HI 2 "register_operand" " r") --+ (parallel [(const_int 1)]))) --+ (sign_extend:SI --+ (vec_select:HI --+ (match_dup 2) --+ (parallel [(const_int 0)])))))))] --+ "NDS32_EXT_DSP_P ()" --+ "smal\t%0, %1, %2" --+ [(set_attr "type" "dmac") --+ (set_attr "length" "4")]) --+ --+(define_insn "smal4" --+ [(set (match_operand:DI 0 "register_operand" "=r") --+ (plus:DI (match_operand:DI 1 "register_operand" " r") --+ (mult:DI --+ (sign_extend:DI --+ (vec_select:HI --+ (match_operand:V2HI 2 "register_operand" " r") --+ (parallel [(const_int 1)]))) --+ (sign_extend:DI --+ (vec_select:HI --+ (match_dup 2) --+ (parallel [(const_int 0)]))))))] --+ "NDS32_EXT_DSP_P ()" --+ "smal\t%0, %1, %2" --+ [(set_attr "type" "dmac") --+ (set_attr "length" "4")]) --+ --+(define_insn "smal5" --+ [(set (match_operand:DI 0 "register_operand" "=r") --+ (plus:DI --+ (sign_extend:DI --+ (mult:SI --+ (sign_extend:SI --+ (vec_select:HI --+ (match_operand:V2HI 2 "register_operand" " r") --+ (parallel [(const_int 0)]))) --+ (sign_extend:SI --+ (vec_select:HI --+ (match_dup 2) --+ (parallel [(const_int 1)]))))) --+ (match_operand:DI 1 "register_operand" " r")))] --+ "NDS32_EXT_DSP_P ()" --+ "smal\t%0, %1, %2" --+ [(set_attr "type" "dmac") --+ (set_attr "length" "4")]) --+ --+(define_insn "smal6" --+ [(set (match_operand:DI 0 "register_operand" "=r") --+ (plus:DI --+ (mult:DI --+ (sign_extend:DI --+ (vec_select:HI --+ (match_operand:V2HI 2 "register_operand" " r") --+ (parallel [(const_int 0)]))) --+ (sign_extend:DI --+ (vec_select:HI --+ (match_dup 2) --+ (parallel [(const_int 1)])))) --+ (match_operand:DI 1 "register_operand" " r")))] --+ "NDS32_EXT_DSP_P ()" --+ "smal\t%0, %1, %2" --+ [(set_attr "type" "dmac") --+ (set_attr "length" "4")]) --+ --+(define_insn "smal7" --+ [(set (match_operand:DI 0 "register_operand" "=r") --+ (plus:DI --+ (sign_extend:DI --+ (mult:SI --+ (sign_extend:SI --+ (vec_select:HI --+ (match_operand:V2HI 2 "register_operand" " r") --+ (parallel [(const_int 1)]))) --+ (sign_extend:SI --+ (vec_select:HI --+ (match_dup 2) --+ (parallel [(const_int 0)]))))) --+ (match_operand:DI 1 "register_operand" " r")))] --+ "NDS32_EXT_DSP_P ()" --+ "smal\t%0, %1, %2" --+ [(set_attr "type" "dmac") --+ (set_attr "length" "4")]) --+ --+(define_insn "smal8" --+ [(set (match_operand:DI 0 "register_operand" "=r") --+ (plus:DI --+ (mult:DI --+ (sign_extend:DI --+ (vec_select:HI --+ (match_operand:V2HI 2 "register_operand" " r") --+ (parallel [(const_int 1)]))) --+ (sign_extend:DI --+ (vec_select:HI --+ (match_dup 2) --+ (parallel [(const_int 0)])))) --+ (match_operand:DI 1 "register_operand" " r")))] --+ "NDS32_EXT_DSP_P ()" --+ "smal\t%0, %1, %2" --+ [(set_attr "type" "dmac") --+ (set_attr "length" "4")]) --+ --+;; We need this dummy pattern for smal --+(define_insn_and_split "extendsidi2" --+ [(set (match_operand:DI 0 "register_operand" "") --+ (sign_extend:DI (match_operand:SI 1 "nds32_move_operand" "")))] --+ "NDS32_EXT_DSP_P ()" --+ "#" --+ "NDS32_EXT_DSP_P ()" --+ [(const_int 0)] --+{ --+ rtx high_part_dst, low_part_dst; --+ --+ low_part_dst = nds32_di_low_part_subreg (operands[0]); --+ high_part_dst = nds32_di_high_part_subreg (operands[0]); --+ --+ emit_move_insn (low_part_dst, operands[1]); --+ emit_insn (gen_ashrsi3 (high_part_dst, low_part_dst, GEN_INT (31))); --+ DONE; --+} --+ [(set_attr "type" "alu") --+ (set_attr "length" "4")]) --+ --+;; We need this dummy pattern for usmar64/usmsr64 --+(define_insn_and_split "zero_extendsidi2" --+ [(set (match_operand:DI 0 "register_operand" "") --+ (zero_extend:DI (match_operand:SI 1 "nds32_move_operand" "")))] --+ "NDS32_EXT_DSP_P ()" --+ "#" --+ "NDS32_EXT_DSP_P ()" --+ [(const_int 0)] --+{ --+ rtx high_part_dst, low_part_dst; --+ --+ low_part_dst = nds32_di_low_part_subreg (operands[0]); --+ high_part_dst = nds32_di_high_part_subreg (operands[0]); --+ --+ emit_move_insn (low_part_dst, operands[1]); --+ emit_move_insn (high_part_dst, const0_rtx); --+ DONE; --+} --+ [(set_attr "type" "alu") --+ (set_attr "length" "4")]) --+ --+(define_insn_and_split "extendhidi2" --+ [(set (match_operand:DI 0 "register_operand" "") --+ (sign_extend:DI (match_operand:HI 1 "nonimmediate_operand" "")))] --+ "NDS32_EXT_DSP_P ()" --+ "#" --+ "NDS32_EXT_DSP_P ()" --+ [(const_int 0)] --+{ --+ rtx high_part_dst, low_part_dst; --+ --+ low_part_dst = nds32_di_low_part_subreg (operands[0]); --+ high_part_dst = nds32_di_high_part_subreg (operands[0]); --+ --+ --+ emit_insn (gen_extendhisi2 (low_part_dst, operands[1])); --+ emit_insn (gen_ashrsi3 (high_part_dst, low_part_dst, GEN_INT (31))); --+ DONE; --+} --+ [(set_attr "type" "alu") --+ (set_attr "length" "4")]) --+ --+(define_insn "extendqihi2" --+ [(set (match_operand:HI 0 "register_operand" "=r") --+ (sign_extend:HI (match_operand:QI 1 "register_operand" " r")))] --+ "NDS32_EXT_DSP_P ()" --+ "sunpkd820\t%0, %1" --+ [(set_attr "type" "dpack") --+ (set_attr "length" "4")]) --+ --+(define_insn "smulsi3_highpart" --+ [(set (match_operand:SI 0 "register_operand" "=r") --+ (truncate:SI --+ (lshiftrt:DI --+ (mult:DI --+ (sign_extend:DI (match_operand:SI 1 "register_operand" " r")) --+ (sign_extend:DI (match_operand:SI 2 "register_operand" " r"))) --+ (const_int 32))))] --+ "NDS32_EXT_DSP_P ()" --+ "smmul\t%0, %1, %2" --+ [(set_attr "type" "dmul") --+ (set_attr "length" "4")]) --+ --+(define_insn "smmul_round" --+ [(set (match_operand:SI 0 "register_operand" "=r") --+ (truncate:SI --+ (lshiftrt:DI --+ (unspec:DI [(mult:DI --+ (sign_extend:DI (match_operand:SI 1 "register_operand" " r")) --+ (sign_extend:DI (match_operand:SI 2 "register_operand" " r")))] --+ UNSPEC_ROUND) --+ (const_int 32))))] --+ "NDS32_EXT_DSP_P ()" --+ "smmul.u\t%0, %1, %2" --+ [(set_attr "type" "dmul") --+ (set_attr "length" "4")]) --+ --+(define_insn "kmmac" --+ [(set (match_operand:SI 0 "register_operand" "=r") --+ (ss_plus:SI (match_operand:SI 1 "register_operand" " 0") --+ (truncate:SI --+ (lshiftrt:DI --+ (mult:DI --+ (sign_extend:DI (match_operand:SI 2 "register_operand" " r")) --+ (sign_extend:DI (match_operand:SI 3 "register_operand" " r"))) --+ (const_int 32)))))] --+ "NDS32_EXT_DSP_P ()" --+ "kmmac\t%0, %2, %3" --+ [(set_attr "type" "dmac") --+ (set_attr "length" "4")]) --+ --+(define_insn "kmmac_round" --+ [(set (match_operand:SI 0 "register_operand" "=r") --+ (ss_plus:SI (match_operand:SI 1 "register_operand" " 0") --+ (truncate:SI --+ (lshiftrt:DI --+ (unspec:DI [(mult:DI --+ (sign_extend:DI (match_operand:SI 2 "register_operand" " r")) --+ (sign_extend:DI (match_operand:SI 3 "register_operand" " r")))] --+ UNSPEC_ROUND) --+ (const_int 32)))))] --+ "NDS32_EXT_DSP_P ()" --+ "kmmac.u\t%0, %2, %3" --+ [(set_attr "type" "dmac") --+ (set_attr "length" "4")]) --+ --+(define_insn "kmmsb" --+ [(set (match_operand:SI 0 "register_operand" "=r") --+ (ss_minus:SI (match_operand:SI 1 "register_operand" " 0") --+ (truncate:SI --+ (lshiftrt:DI --+ (mult:DI --+ (sign_extend:DI (match_operand:SI 2 "register_operand" " r")) --+ (sign_extend:DI (match_operand:SI 3 "register_operand" " r"))) --+ (const_int 32)))))] --+ "NDS32_EXT_DSP_P ()" --+ "kmmsb\t%0, %2, %3" --+ [(set_attr "type" "dmac") --+ (set_attr "length" "4")]) --+ --+(define_insn "kmmsb_round" --+ [(set (match_operand:SI 0 "register_operand" "=r") --+ (ss_minus:SI (match_operand:SI 1 "register_operand" " 0") --+ (truncate:SI --+ (lshiftrt:DI --+ (unspec:DI [(mult:DI --+ (sign_extend:DI (match_operand:SI 2 "register_operand" " r")) --+ (sign_extend:DI (match_operand:SI 3 "register_operand" " r")))] --+ UNSPEC_ROUND) --+ (const_int 32)))))] --+ "NDS32_EXT_DSP_P ()" --+ "kmmsb.u\t%0, %2, %3" --+ [(set_attr "type" "dmac") --+ (set_attr "length" "4")]) --+ --+(define_insn "kwmmul" --+ [(set (match_operand:SI 0 "register_operand" "=r") --+ (truncate:SI --+ (lshiftrt:DI --+ (ss_mult:DI --+ (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" " r")) (const_int 2)) --+ (mult:DI (sign_extend:DI (match_operand:SI 2 "register_operand" " r")) (const_int 2))) --+ (const_int 32))))] --+ "NDS32_EXT_DSP_P ()" --+ "kwmmul\t%0, %1, %2" --+ [(set_attr "type" "dmul") --+ (set_attr "length" "4")]) --+ --+(define_insn "kwmmul_round" --+ [(set (match_operand:SI 0 "register_operand" "=r") --+ (truncate:SI --+ (lshiftrt:DI --+ (unspec:DI [ --+ (ss_mult:DI --+ (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" " r")) (const_int 2)) --+ (mult:DI (sign_extend:DI (match_operand:SI 2 "register_operand" " r")) (const_int 2)))] --+ UNSPEC_ROUND) --+ (const_int 32))))] --+ "NDS32_EXT_DSP_P ()" --+ "kwmmul.u\t%0, %1, %2" --+ [(set_attr "type" "dmul") --+ (set_attr "length" "4")]) --+ --+(define_expand "smmwb" --+ [(match_operand:SI 0 "register_operand" "") --+ (match_operand:SI 1 "register_operand" "") --+ (match_operand:V2HI 2 "register_operand" "")] --+ "NDS32_EXT_DSP_P ()" --+{ --+ if (TARGET_BIG_ENDIAN) --+ emit_insn (gen_smulhisi3_highpart_1 (operands[0], operands[1], operands[2], GEN_INT (1))); --+ else --+ emit_insn (gen_smulhisi3_highpart_1 (operands[0], operands[1], operands[2], GEN_INT (0))); --+ DONE; --+}) --+ --+(define_expand "smmwt" --+ [(match_operand:SI 0 "register_operand" "") --+ (match_operand:SI 1 "register_operand" "") --+ (match_operand:V2HI 2 "register_operand" "")] --+ "NDS32_EXT_DSP_P ()" --+{ --+ if (TARGET_BIG_ENDIAN) --+ emit_insn (gen_smulhisi3_highpart_1 (operands[0], operands[1], operands[2], GEN_INT (0))); --+ else --+ emit_insn (gen_smulhisi3_highpart_1 (operands[0], operands[1], operands[2], GEN_INT (1))); --+ DONE; --+}) --+ --+(define_insn "smulhisi3_highpart_1" --+ [(set (match_operand:SI 0 "register_operand" "= r, r") --+ (truncate:SI --+ (lshiftrt:DI --+ (mult:DI --+ (sign_extend:DI (match_operand:SI 1 "register_operand" " r, r")) --+ (sign_extend:DI --+ (vec_select:HI --+ (match_operand:V2HI 2 "register_operand" " r, r") --+ (parallel [(match_operand:SI 3 "nds32_imm_0_1_operand" " Iv00, Iv01")])))) --+ (const_int 16))))] --+ "NDS32_EXT_DSP_P ()" --+{ --+ if (TARGET_BIG_ENDIAN) --+ { --+ const char *pats[] = { "smmwt\t%0, %1, %2", --+ "smmwb\t%0, %1, %2" }; --+ return pats[which_alternative]; --+ } --+ else --+ { --+ const char *pats[] = { "smmwb\t%0, %1, %2", --+ "smmwt\t%0, %1, %2" }; --+ return pats[which_alternative]; --+ } --+} --+ [(set_attr "type" "dmul") --+ (set_attr "length" "4")]) --+ --+(define_insn "smulhisi3_highpart_2" --+ [(set (match_operand:SI 0 "register_operand" "= r, r") --+ (truncate:SI --+ (lshiftrt:DI --+ (mult:DI --+ (sign_extend:DI --+ (vec_select:HI --+ (match_operand:V2HI 1 "register_operand" " r, r") --+ (parallel [(match_operand:SI 3 "nds32_imm_0_1_operand" " Iv00, Iv01")]))) --+ (sign_extend:DI (match_operand:SI 2 "register_operand" " r, r"))) --+ (const_int 16))))] --+ "NDS32_EXT_DSP_P ()" --+{ --+ if (TARGET_BIG_ENDIAN) --+ { --+ const char *pats[] = { "smmwt\t%0, %1, %2", --+ "smmwb\t%0, %1, %2" }; --+ return pats[which_alternative]; --+ } --+ else --+ { --+ const char *pats[] = { "smmwb\t%0, %1, %2", --+ "smmwt\t%0, %1, %2" }; --+ return pats[which_alternative]; --+ } --+} --+ [(set_attr "type" "dmul") --+ (set_attr "length" "4")]) --+ --+(define_expand "smmwb_round" --+ [(match_operand:SI 0 "register_operand" "") --+ (match_operand:SI 1 "register_operand" "") --+ (match_operand:V2HI 2 "register_operand" "")] --+ "NDS32_EXT_DSP_P ()" --+{ --+ if (TARGET_BIG_ENDIAN) --+ emit_insn (gen_smmw_round_internal (operands[0], operands[1], operands[2], GEN_INT (1))); --+ else --+ emit_insn (gen_smmw_round_internal (operands[0], operands[1], operands[2], GEN_INT (0))); --+ DONE; --+}) --+ --+(define_expand "smmwt_round" --+ [(match_operand:SI 0 "register_operand" "") --+ (match_operand:SI 1 "register_operand" "") --+ (match_operand:V2HI 2 "register_operand" "")] --+ "NDS32_EXT_DSP_P ()" --+{ --+ if (TARGET_BIG_ENDIAN) --+ emit_insn (gen_smmw_round_internal (operands[0], operands[1], operands[2], GEN_INT (0))); --+ else --+ emit_insn (gen_smmw_round_internal (operands[0], operands[1], operands[2], GEN_INT (1))); --+ DONE; --+}) --+ --+(define_insn "smmw_round_internal" --+ [(set (match_operand:SI 0 "register_operand" "= r, r") --+ (truncate:SI --+ (lshiftrt:DI --+ (unspec:DI --+ [(mult:DI --+ (sign_extend:DI (match_operand:SI 1 "register_operand" " r, r")) --+ (sign_extend:DI --+ (vec_select:HI --+ (match_operand:V2HI 2 "register_operand" " r, r") --+ (parallel [(match_operand:SI 3 "nds32_imm_0_1_operand" " Iv00, Iv01")]))))] --+ UNSPEC_ROUND) --+ (const_int 16))))] --+ "NDS32_EXT_DSP_P ()" --+{ --+ if (TARGET_BIG_ENDIAN) --+ { --+ const char *pats[] = { "smmwt.u\t%0, %1, %2", --+ "smmwb.u\t%0, %1, %2" }; --+ return pats[which_alternative]; --+ } --+ else --+ { --+ const char *pats[] = { "smmwb.u\t%0, %1, %2", --+ "smmwt.u\t%0, %1, %2" }; --+ return pats[which_alternative]; --+ } --+} --+ [(set_attr "type" "dmul") --+ (set_attr "length" "4")]) --+ --+(define_expand "kmmawb" --+ [(match_operand:SI 0 "register_operand" "") --+ (match_operand:SI 1 "register_operand" "") --+ (match_operand:SI 2 "register_operand" "") --+ (match_operand:V2HI 3 "register_operand" "")] --+ "NDS32_EXT_DSP_P ()" --+{ --+ if (TARGET_BIG_ENDIAN) --+ emit_insn (gen_kmmaw_internal (operands[0], operands[2], operands[3], GEN_INT (1), operands[1])); --+ else --+ emit_insn (gen_kmmaw_internal (operands[0], operands[2], operands[3], GEN_INT (0), operands[1])); --+ DONE; --+}) --+ --+(define_expand "kmmawt" --+ [(match_operand:SI 0 "register_operand" "") --+ (match_operand:SI 1 "register_operand" "") --+ (match_operand:SI 2 "register_operand" "") --+ (match_operand:V2HI 3 "register_operand" "")] --+ "NDS32_EXT_DSP_P ()" --+{ --+ if (TARGET_BIG_ENDIAN) --+ emit_insn (gen_kmmaw_internal (operands[0], operands[2], operands[3], GEN_INT (0), operands[1])); --+ else --+ emit_insn (gen_kmmaw_internal (operands[0], operands[2], operands[3], GEN_INT (1), operands[1])); --+ DONE; --+}) --+ --+(define_insn "kmmaw_internal" --+ [(set (match_operand:SI 0 "register_operand" "= r, r") --+ (ss_plus:SI --+ (match_operand:SI 4 "register_operand" " 0, 0") --+ (truncate:SI --+ (lshiftrt:DI --+ (mult:DI --+ (sign_extend:DI (match_operand:SI 1 "register_operand" " r, r")) --+ (sign_extend:DI --+ (vec_select:HI --+ (match_operand:V2HI 2 "register_operand" " r, r") --+ (parallel [(match_operand:SI 3 "nds32_imm_0_1_operand" " Iv00, Iv01")])))) --+ (const_int 16)))))] --+ "NDS32_EXT_DSP_P ()" --+{ --+ if (TARGET_BIG_ENDIAN) --+ { --+ const char *pats[] = { "kmmawt\t%0, %1, %2", --+ "kmmawb\t%0, %1, %2" }; --+ return pats[which_alternative]; --+ } --+ else --+ { --+ const char *pats[] = { "kmmawb\t%0, %1, %2", --+ "kmmawt\t%0, %1, %2" }; --+ return pats[which_alternative]; --+ } --+} --+ [(set_attr "type" "dmac") --+ (set_attr "length" "4")]) --+ --+(define_expand "kmmawb_round" --+ [(match_operand:SI 0 "register_operand" "") --+ (match_operand:SI 1 "register_operand" "") --+ (match_operand:SI 2 "register_operand" "") --+ (match_operand:V2HI 3 "register_operand" "")] --+ "NDS32_EXT_DSP_P ()" --+{ --+ if (TARGET_BIG_ENDIAN) --+ emit_insn (gen_kmmaw_round_internal (operands[0], operands[2], operands[3], GEN_INT (1), operands[1])); --+ else --+ emit_insn (gen_kmmaw_round_internal (operands[0], operands[2], operands[3], GEN_INT (0), operands[1])); --+ DONE; --+} --+ [(set_attr "type" "alu") --+ (set_attr "length" "4")]) --+ --+(define_expand "kmmawt_round" --+ [(match_operand:SI 0 "register_operand" "") --+ (match_operand:SI 1 "register_operand" "") --+ (match_operand:SI 2 "register_operand" "") --+ (match_operand:V2HI 3 "register_operand" "")] --+ "NDS32_EXT_DSP_P ()" --+{ --+ if (TARGET_BIG_ENDIAN) --+ emit_insn (gen_kmmaw_round_internal (operands[0], operands[2], operands[3], GEN_INT (0), operands[1])); --+ else --+ emit_insn (gen_kmmaw_round_internal (operands[0], operands[2], operands[3], GEN_INT (1), operands[1])); --+ DONE; --+} --+ [(set_attr "type" "dmac") --+ (set_attr "length" "4")]) --+ --+ --+(define_insn "kmmaw_round_internal" --+ [(set (match_operand:SI 0 "register_operand" "= r, r") --+ (ss_plus:SI --+ (match_operand:SI 4 "register_operand" " 0, 0") --+ (truncate:SI --+ (lshiftrt:DI --+ (unspec:DI --+ [(mult:DI --+ (sign_extend:DI (match_operand:SI 1 "register_operand" " r, r")) --+ (sign_extend:DI --+ (vec_select:HI --+ (match_operand:V2HI 2 "register_operand" " r, r") --+ (parallel [(match_operand:SI 3 "nds32_imm_0_1_operand" " Iv00, Iv01")]))))] --+ UNSPEC_ROUND) --+ (const_int 16)))))] --+ "NDS32_EXT_DSP_P ()" --+{ --+ if (TARGET_BIG_ENDIAN) --+ { --+ const char *pats[] = { "kmmawt.u\t%0, %1, %2", --+ "kmmawb.u\t%0, %1, %2" }; --+ return pats[which_alternative]; --+ } --+ else --+ { --+ const char *pats[] = { "kmmawb.u\t%0, %1, %2", --+ "kmmawt.u\t%0, %1, %2" }; --+ return pats[which_alternative]; --+ } --+} --+ [(set_attr "type" "dmac") --+ (set_attr "length" "4")]) --+ --+(define_expand "smalbb" --+ [(match_operand:DI 0 "register_operand" "") --+ (match_operand:DI 1 "register_operand" "") --+ (match_operand:V2HI 2 "register_operand" "") --+ (match_operand:V2HI 3 "register_operand" "")] --+ "NDS32_EXT_DSP_P ()" --+{ --+ if (TARGET_BIG_ENDIAN) --+ emit_insn (gen_smaddhidi (operands[0], operands[2], --+ operands[3], operands[1], --+ GEN_INT (1), GEN_INT (1))); --+ else --+ emit_insn (gen_smaddhidi (operands[0], operands[2], --+ operands[3], operands[1], --+ GEN_INT (0), GEN_INT (0))); --+ DONE; --+}) --+ --+(define_expand "smalbt" --+ [(match_operand:DI 0 "register_operand" "") --+ (match_operand:DI 1 "register_operand" "") --+ (match_operand:V2HI 2 "register_operand" "") --+ (match_operand:V2HI 3 "register_operand" "")] --+ "NDS32_EXT_DSP_P ()" --+{ --+ if (TARGET_BIG_ENDIAN) --+ emit_insn (gen_smaddhidi (operands[0], operands[2], --+ operands[3], operands[1], --+ GEN_INT (1), GEN_INT (0))); --+ else --+ emit_insn (gen_smaddhidi (operands[0], operands[2], --+ operands[3], operands[1], --+ GEN_INT (0), GEN_INT (1))); --+ DONE; --+}) --+ --+(define_expand "smaltt" --+ [(match_operand:DI 0 "register_operand" "") --+ (match_operand:DI 1 "register_operand" "") --+ (match_operand:V2HI 2 "register_operand" "") --+ (match_operand:V2HI 3 "register_operand" "")] --+ "NDS32_EXT_DSP_P ()" --+{ --+ if (TARGET_BIG_ENDIAN) --+ emit_insn (gen_smaddhidi (operands[0], operands[2], --+ operands[3], operands[1], --+ GEN_INT (0), GEN_INT (0))); --+ else --+ emit_insn (gen_smaddhidi (operands[0], operands[2], --+ operands[3], operands[1], --+ GEN_INT (1), GEN_INT (1))); --+ DONE; --+}) --+ --+(define_insn "smaddhidi" --+ [(set (match_operand:DI 0 "register_operand" "= r, r, r, r") --+ (plus:DI --+ (match_operand:DI 3 "register_operand" " 0, 0, 0, 0") --+ (mult:DI --+ (sign_extend:DI --+ (vec_select:HI --+ (match_operand:V2HI 1 "register_operand" " r, r, r, r") --+ (parallel [(match_operand:SI 4 "nds32_imm_0_1_operand" " Iv00, Iv00, Iv01, Iv01")]))) --+ (sign_extend:DI --+ (vec_select:HI --+ (match_operand:V2HI 2 "register_operand" " r, r, r, r") --+ (parallel [(match_operand:SI 5 "nds32_imm_0_1_operand" " Iv00, Iv01, Iv01, Iv00")]))))))] --+ "NDS32_EXT_DSP_P ()" --+{ --+ if (TARGET_BIG_ENDIAN) --+ { --+ const char *pats[] = { "smaltt\t%0, %1, %2", --+ "smalbt\t%0, %2, %1", --+ "smalbb\t%0, %1, %2", --+ "smalbt\t%0, %1, %2" }; --+ return pats[which_alternative]; --+ } --+ else --+ { --+ const char *pats[] = { "smalbb\t%0, %1, %2", --+ "smalbt\t%0, %1, %2", --+ "smaltt\t%0, %1, %2", --+ "smalbt\t%0, %2, %1" }; --+ return pats[which_alternative]; --+ } --+} --+ [(set_attr "type" "dmac") --+ (set_attr "length" "4")]) --+ --+(define_insn "smaddhidi2" --+ [(set (match_operand:DI 0 "register_operand" "= r, r, r, r") --+ (plus:DI --+ (mult:DI --+ (sign_extend:DI --+ (vec_select:HI --+ (match_operand:V2HI 1 "register_operand" " r, r, r, r") --+ (parallel [(match_operand:SI 4 "nds32_imm_0_1_operand" " Iv00, Iv00, Iv01, Iv01")]))) --+ (sign_extend:DI --+ (vec_select:HI --+ (match_operand:V2HI 2 "register_operand" " r, r, r, r") --+ (parallel [(match_operand:SI 5 "nds32_imm_0_1_operand" " Iv00, Iv01, Iv01, Iv00")])))) --+ (match_operand:DI 3 "register_operand" " 0, 0, 0, 0")))] --+ "NDS32_EXT_DSP_P ()" --+{ --+ if (TARGET_BIG_ENDIAN) --+ { --+ const char *pats[] = { "smaltt\t%0, %1, %2", --+ "smalbt\t%0, %2, %1", --+ "smalbb\t%0, %1, %2", --+ "smalbt\t%0, %1, %2" }; --+ return pats[which_alternative]; --+ } --+ else --+ { --+ const char *pats[] = { "smalbb\t%0, %1, %2", --+ "smalbt\t%0, %1, %2", --+ "smaltt\t%0, %1, %2", --+ "smalbt\t%0, %2, %1" }; --+ return pats[which_alternative]; --+ } --+} --+ [(set_attr "type" "dmac") --+ (set_attr "length" "4")]) --+ --+(define_expand "smalda1" --+ [(match_operand:DI 0 "register_operand" "") --+ (match_operand:DI 1 "register_operand" "") --+ (match_operand:V2HI 2 "register_operand" " r") --+ (match_operand:V2HI 3 "register_operand" " r")] --+ "NDS32_EXT_DSP_P ()" --+{ --+ if (TARGET_BIG_ENDIAN) --+ emit_insn (gen_smalda1_be (operands[0], operands[1], operands[2], operands[3])); --+ else --+ emit_insn (gen_smalda1_le (operands[0], operands[1], operands[2], operands[3])); --+ DONE; --+}) --+ --+(define_expand "smalds1" --+ [(match_operand:DI 0 "register_operand" "") --+ (match_operand:DI 1 "register_operand" "") --+ (match_operand:V2HI 2 "register_operand" " r") --+ (match_operand:V2HI 3 "register_operand" " r")] --+ "NDS32_EXT_DSP_P ()" --+{ --+ if (TARGET_BIG_ENDIAN) --+ emit_insn (gen_smalds1_be (operands[0], operands[1], operands[2], operands[3])); --+ else --+ emit_insn (gen_smalds1_le (operands[0], operands[1], operands[2], operands[3])); --+ DONE; --+}) --+ --+(define_insn "smalda1_le" --+ [(set (match_operand:DI 0 "register_operand" "=r") --+ (plus:DI --+ (match_operand:DI 1 "register_operand" " 0") --+ (sign_extend:DI --+ (plus:SI --+ (mult:SI --+ (sign_extend:SI (vec_select:HI --+ (match_operand:V2HI 2 "register_operand" " r") --+ (parallel [(const_int 1)]))) --+ (sign_extend:SI (vec_select:HI --+ (match_operand:V2HI 3 "register_operand" " r") --+ (parallel [(const_int 1)])))) --+ (mult:SI --+ (sign_extend:SI (vec_select:HI --+ (match_dup 2) --+ (parallel [(const_int 0)]))) --+ (sign_extend:SI (vec_select:HI --+ (match_dup 3) --+ (parallel [(const_int 0)]))))))))] --+ "NDS32_EXT_DSP_P () && !TARGET_BIG_ENDIAN" --+ "smalda\t%0, %2, %3" --+ [(set_attr "type" "dmac") --+ (set_attr "length" "4")]) --+ --+(define_insn "smalds1_le" --+ [(set (match_operand:DI 0 "register_operand" "=r") --+ (plus:DI --+ (match_operand:DI 1 "register_operand" " 0") --+ (sign_extend:DI --+ (minus:SI --+ (mult:SI --+ (sign_extend:SI (vec_select:HI --+ (match_operand:V2HI 2 "register_operand" " r") --+ (parallel [(const_int 1)]))) --+ (sign_extend:SI (vec_select:HI --+ (match_operand:V2HI 3 "register_operand" " r") --+ (parallel [(const_int 1)])))) --+ (mult:SI --+ (sign_extend:SI (vec_select:HI --+ (match_dup 2) --+ (parallel [(const_int 0)]))) --+ (sign_extend:SI (vec_select:HI --+ (match_dup 3) --+ (parallel [(const_int 0)]))))))))] --+ "NDS32_EXT_DSP_P () && !TARGET_BIG_ENDIAN" --+ "smalds\t%0, %2, %3" --+ [(set_attr "type" "dmac") --+ (set_attr "length" "4")]) --+ --+(define_insn "smalda1_be" --+ [(set (match_operand:DI 0 "register_operand" "=r") --+ (plus:DI --+ (match_operand:DI 1 "register_operand" " 0") --+ (sign_extend:DI --+ (plus:SI --+ (mult:SI --+ (sign_extend:SI (vec_select:HI --+ (match_operand:V2HI 2 "register_operand" " r") --+ (parallel [(const_int 0)]))) --+ (sign_extend:SI (vec_select:HI --+ (match_operand:V2HI 3 "register_operand" " r") --+ (parallel [(const_int 0)])))) --+ (mult:SI --+ (sign_extend:SI (vec_select:HI --+ (match_dup 2) --+ (parallel [(const_int 1)]))) --+ (sign_extend:SI (vec_select:HI --+ (match_dup 3) --+ (parallel [(const_int 1)]))))))))] --+ "NDS32_EXT_DSP_P () && TARGET_BIG_ENDIAN" --+ "smalda\t%0, %2, %3" --+ [(set_attr "type" "dmac") --+ (set_attr "length" "4")]) --+ --+(define_insn "smalds1_be" --+ [(set (match_operand:DI 0 "register_operand" "=r") --+ (plus:DI --+ (match_operand:DI 1 "register_operand" " 0") --+ (sign_extend:DI --+ (minus:SI --+ (mult:SI --+ (sign_extend:SI (vec_select:HI --+ (match_operand:V2HI 2 "register_operand" " r") --+ (parallel [(const_int 0)]))) --+ (sign_extend:SI (vec_select:HI --+ (match_operand:V2HI 3 "register_operand" " r") --+ (parallel [(const_int 0)])))) --+ (mult:SI --+ (sign_extend:SI (vec_select:HI --+ (match_dup 2) --+ (parallel [(const_int 1)]))) --+ (sign_extend:SI (vec_select:HI --+ (match_dup 3) --+ (parallel [(const_int 1)]))))))))] --+ "NDS32_EXT_DSP_P () && TARGET_BIG_ENDIAN" --+ "smalds\t%0, %2, %3" --+ [(set_attr "type" "dmac") --+ (set_attr "length" "4")]) --+ --+(define_expand "smaldrs3" --+ [(match_operand:DI 0 "register_operand" "") --+ (match_operand:DI 1 "register_operand" "") --+ (match_operand:V2HI 2 "register_operand" " r") --+ (match_operand:V2HI 3 "register_operand" " r")] --+ "NDS32_EXT_DSP_P ()" --+{ --+ if (TARGET_BIG_ENDIAN) --+ emit_insn (gen_smaldrs3_be (operands[0], operands[1], operands[2], operands[3])); --+ else --+ emit_insn (gen_smaldrs3_le (operands[0], operands[1], operands[2], operands[3])); --+ DONE; --+}) --+ --+(define_insn "smaldrs3_le" --+ [(set (match_operand:DI 0 "register_operand" "=r") --+ (plus:DI --+ (match_operand:DI 1 "register_operand" " 0") --+ (sign_extend:DI --+ (minus:SI --+ (mult:SI --+ (sign_extend:SI (vec_select:HI --+ (match_operand:V2HI 2 "register_operand" " r") --+ (parallel [(const_int 0)]))) --+ (sign_extend:SI (vec_select:HI --+ (match_operand:V2HI 3 "register_operand" " r") --+ (parallel [(const_int 0)])))) --+ (mult:SI --+ (sign_extend:SI (vec_select:HI --+ (match_dup 2) --+ (parallel [(const_int 1)]))) --+ (sign_extend:SI (vec_select:HI --+ (match_dup 3) --+ (parallel [(const_int 1)]))))))))] --+ "NDS32_EXT_DSP_P () && !TARGET_BIG_ENDIAN" --+ "smaldrs\t%0, %2, %3" --+ [(set_attr "type" "dmac") --+ (set_attr "length" "4")]) --+ --+(define_insn "smaldrs3_be" --+ [(set (match_operand:DI 0 "register_operand" "=r") --+ (plus:DI --+ (match_operand:DI 1 "register_operand" " 0") --+ (sign_extend:DI --+ (minus:SI --+ (mult:SI --+ (sign_extend:SI (vec_select:HI --+ (match_operand:V2HI 2 "register_operand" " r") --+ (parallel [(const_int 1)]))) --+ (sign_extend:SI (vec_select:HI --+ (match_operand:V2HI 3 "register_operand" " r") --+ (parallel [(const_int 1)])))) --+ (mult:SI --+ (sign_extend:SI (vec_select:HI --+ (match_dup 2) --+ (parallel [(const_int 0)]))) --+ (sign_extend:SI (vec_select:HI --+ (match_dup 3) --+ (parallel [(const_int 0)]))))))))] --+ "NDS32_EXT_DSP_P () && TARGET_BIG_ENDIAN" --+ "smaldrs\t%0, %2, %3" --+ [(set_attr "type" "dmac") --+ (set_attr "length" "4")]) --+ --+(define_expand "smalxda1" --+ [(match_operand:DI 0 "register_operand" "") --+ (match_operand:DI 1 "register_operand" "") --+ (match_operand:V2HI 2 "register_operand" " r") --+ (match_operand:V2HI 3 "register_operand" " r")] --+ "NDS32_EXT_DSP_P ()" --+{ --+ if (TARGET_BIG_ENDIAN) --+ emit_insn (gen_smalxda1_be (operands[0], operands[1], operands[2], operands[3])); --+ else --+ emit_insn (gen_smalxda1_le (operands[0], operands[1], operands[2], operands[3])); --+ DONE; --+}) --+ --+(define_expand "smalxds1" --+ [(match_operand:DI 0 "register_operand" "") --+ (match_operand:DI 1 "register_operand" "") --+ (match_operand:V2HI 2 "register_operand" " r") --+ (match_operand:V2HI 3 "register_operand" " r")] --+ "NDS32_EXT_DSP_P ()" --+{ --+ if (TARGET_BIG_ENDIAN) --+ emit_insn (gen_smalxds1_be (operands[0], operands[1], operands[2], operands[3])); --+ else --+ emit_insn (gen_smalxds1_le (operands[0], operands[1], operands[2], operands[3])); --+ DONE; --+}) --+ --+(define_insn "smalxd1_le" --+ [(set (match_operand:DI 0 "register_operand" "=r") --+ (plus:DI --+ (match_operand:DI 1 "register_operand" " 0") --+ (sign_extend:DI --+ (plus_minus:SI --+ (mult:SI --+ (sign_extend:SI (vec_select:HI --+ (match_operand:V2HI 2 "register_operand" " r") --+ (parallel [(const_int 1)]))) --+ (sign_extend:SI (vec_select:HI --+ (match_operand:V2HI 3 "register_operand" " r") --+ (parallel [(const_int 0)])))) --+ (mult:SI --+ (sign_extend:SI (vec_select:HI --+ (match_dup 2) --+ (parallel [(const_int 0)]))) --+ (sign_extend:SI (vec_select:HI --+ (match_dup 3) --+ (parallel [(const_int 1)]))))))))] --+ "NDS32_EXT_DSP_P () && !TARGET_BIG_ENDIAN" --+ "smalxd\t%0, %2, %3" --+ [(set_attr "type" "dmac") --+ (set_attr "length" "4")]) --+ --+ --+(define_insn "smalxd1_be" --+ [(set (match_operand:DI 0 "register_operand" "=r") --+ (plus:DI --+ (match_operand:DI 1 "register_operand" " 0") --+ (sign_extend:DI --+ (plus_minus:SI --+ (mult:SI --+ (sign_extend:SI (vec_select:HI --+ (match_operand:V2HI 2 "register_operand" " r") --+ (parallel [(const_int 0)]))) --+ (sign_extend:SI (vec_select:HI --+ (match_operand:V2HI 3 "register_operand" " r") --+ (parallel [(const_int 1)])))) --+ (mult:SI --+ (sign_extend:SI (vec_select:HI --+ (match_dup 2) --+ (parallel [(const_int 1)]))) --+ (sign_extend:SI (vec_select:HI --+ (match_dup 3) --+ (parallel [(const_int 0)]))))))))] --+ "NDS32_EXT_DSP_P () && TARGET_BIG_ENDIAN" --+ "smalxd\t%0, %2, %3" --+ [(set_attr "type" "dmac") --+ (set_attr "length" "4")]) --+ --+(define_insn "smslda1" --+ [(set (match_operand:DI 0 "register_operand" "=r") --+ (minus:DI --+ (minus:DI --+ (match_operand:DI 1 "register_operand" " 0") --+ (sign_extend:DI --+ (mult:SI --+ (sign_extend:SI (vec_select:HI --+ (match_operand:V2HI 2 "register_operand" " r") --+ (parallel [(const_int 1)]))) --+ (sign_extend:SI (vec_select:HI --+ (match_operand:V2HI 3 "register_operand" " r") --+ (parallel [(const_int 1)])))))) --+ (sign_extend:DI --+ (mult:SI --+ (sign_extend:SI (vec_select:HI --+ (match_dup 2) --+ (parallel [(const_int 0)]))) --+ (sign_extend:SI (vec_select:HI --+ (match_dup 3) --+ (parallel [(const_int 0)])))))))] --+ "NDS32_EXT_DSP_P ()" --+ "smslda\t%0, %2, %3" --+ [(set_attr "type" "dmac") --+ (set_attr "length" "4")]) --+ --+(define_insn "smslxda1" --+ [(set (match_operand:DI 0 "register_operand" "=r") --+ (minus:DI --+ (minus:DI --+ (match_operand:DI 1 "register_operand" " 0") --+ (sign_extend:DI --+ (mult:SI --+ (sign_extend:SI (vec_select:HI --+ (match_operand:V2HI 2 "register_operand" " r") --+ (parallel [(const_int 1)]))) --+ (sign_extend:SI (vec_select:HI --+ (match_operand:V2HI 3 "register_operand" " r") --+ (parallel [(const_int 0)])))))) --+ (sign_extend:DI --+ (mult:SI --+ (sign_extend:SI (vec_select:HI --+ (match_dup 2) --+ (parallel [(const_int 0)]))) --+ (sign_extend:SI (vec_select:HI --+ (match_dup 3) --+ (parallel [(const_int 1)])))))))] --+ "NDS32_EXT_DSP_P ()" --+ "smslxda\t%0, %2, %3" --+ [(set_attr "type" "dmac") --+ (set_attr "length" "4")]) --+ --+;; mada for synthetize smalda --+(define_insn_and_split "mada1" --+ [(set (match_operand:SI 0 "register_operand" "=r") --+ (plus:SI --+ (mult:SI --+ (sign_extend:SI (vec_select:HI --+ (match_operand:V2HI 1 "register_operand" "r") --+ (parallel [(match_operand:SI 3 "nds32_imm_0_1_operand" " Iu01")]))) --+ (sign_extend:SI (vec_select:HI --+ (match_operand:V2HI 2 "register_operand" "r") --+ (parallel [(match_operand:SI 4 "nds32_imm_0_1_operand" " Iu01")])))) --+ (mult:SI --+ (sign_extend:SI (vec_select:HI --+ (match_dup 1) --+ (parallel [(match_operand:SI 5 "nds32_imm_0_1_operand" " Iu01")]))) --+ (sign_extend:SI (vec_select:HI --+ (match_dup 2) --+ (parallel [(match_operand:SI 6 "nds32_imm_0_1_operand" " Iu01")]))))))] --+ "NDS32_EXT_DSP_P () && !reload_completed" --+ "#" --+ "NDS32_EXT_DSP_P () && !reload_completed" --+ [(const_int 1)] --+{ --+ rtx result0 = gen_reg_rtx (SImode); --+ rtx result1 = gen_reg_rtx (SImode); --+ emit_insn (gen_mulhisi3v (result0, operands[1], operands[2], --+ operands[3], operands[4])); --+ emit_insn (gen_mulhisi3v (result1, operands[1], operands[2], --+ operands[5], operands[6])); --+ emit_insn (gen_addsi3 (operands[0], result0, result1)); --+ DONE; --+}) --+ --+(define_insn_and_split "mada2" --+ [(set (match_operand:SI 0 "register_operand" "=r") --+ (plus:SI --+ (mult:SI --+ (sign_extend:SI (vec_select:HI --+ (match_operand:V2HI 1 "register_operand" "r") --+ (parallel [(match_operand:SI 3 "nds32_imm_0_1_operand" " Iu01")]))) --+ (sign_extend:SI (vec_select:HI --+ (match_operand:V2HI 2 "register_operand" "r") --+ (parallel [(match_operand:SI 4 "nds32_imm_0_1_operand" " Iu01")])))) --+ (mult:SI --+ (sign_extend:SI (vec_select:HI --+ (match_dup 2) --+ (parallel [(match_operand:SI 5 "nds32_imm_0_1_operand" " Iu01")]))) --+ (sign_extend:SI (vec_select:HI --+ (match_dup 1) --+ (parallel [(match_operand:SI 6 "nds32_imm_0_1_operand" " Iu01")]))))))] --+ "NDS32_EXT_DSP_P () && !reload_completed" --+ "#" --+ "NDS32_EXT_DSP_P () && !reload_completed" --+ [(const_int 1)] --+{ --+ rtx result0 = gen_reg_rtx (SImode); --+ rtx result1 = gen_reg_rtx (SImode); --+ emit_insn (gen_mulhisi3v (result0, operands[1], operands[2], --+ operands[3], operands[4])); --+ emit_insn (gen_mulhisi3v (result1, operands[1], operands[2], --+ operands[6], operands[5])); --+ emit_insn (gen_addsi3 (operands[0], result0, result1)); --+ DONE; --+}) --+ --+;; sms for synthetize smalds --+(define_insn_and_split "sms1" --+ [(set (match_operand:SI 0 "register_operand" "= r") --+ (minus:SI --+ (mult:SI --+ (sign_extend:SI (vec_select:HI --+ (match_operand:V2HI 1 "register_operand" " r") --+ (parallel [(match_operand:SI 3 "nds32_imm_0_1_operand" " Iu01")]))) --+ (sign_extend:SI (vec_select:HI --+ (match_operand:V2HI 2 "register_operand" " r") --+ (parallel [(match_operand:SI 4 "nds32_imm_0_1_operand" " Iu01")])))) --+ (mult:SI --+ (sign_extend:SI (vec_select:HI --+ (match_dup 1) --+ (parallel [(match_operand:SI 5 "nds32_imm_0_1_operand" " Iu01")]))) --+ (sign_extend:SI (vec_select:HI --+ (match_dup 2) --+ (parallel [(match_operand:SI 6 "nds32_imm_0_1_operand" " Iu01")]))))))] --+ "NDS32_EXT_DSP_P () --+ && (!reload_completed --+ || !nds32_need_split_sms_p (operands[3], operands[4], --+ operands[5], operands[6]))" --+ --+{ --+ return nds32_output_sms (operands[3], operands[4], --+ operands[5], operands[6]); --+} --+ "NDS32_EXT_DSP_P () --+ && !reload_completed --+ && nds32_need_split_sms_p (operands[3], operands[4], --+ operands[5], operands[6])" --+ [(const_int 1)] --+{ --+ nds32_split_sms (operands[0], operands[1], operands[2], --+ operands[3], operands[4], --+ operands[5], operands[6]); --+ DONE; --+} --+ [(set_attr "type" "dmac") --+ (set_attr "length" "4")]) --+ --+(define_insn_and_split "sms2" --+ [(set (match_operand:SI 0 "register_operand" "= r") --+ (minus:SI --+ (mult:SI --+ (sign_extend:SI (vec_select:HI --+ (match_operand:V2HI 1 "register_operand" " r") --+ (parallel [(match_operand:SI 3 "nds32_imm_0_1_operand" " Iu01")]))) --+ (sign_extend:SI (vec_select:HI --+ (match_operand:V2HI 2 "register_operand" " r") --+ (parallel [(match_operand:SI 4 "nds32_imm_0_1_operand" " Iu01")])))) --+ (mult:SI --+ (sign_extend:SI (vec_select:HI --+ (match_dup 2) --+ (parallel [(match_operand:SI 5 "nds32_imm_0_1_operand" " Iu01")]))) --+ (sign_extend:SI (vec_select:HI --+ (match_dup 1) --+ (parallel [(match_operand:SI 6 "nds32_imm_0_1_operand" " Iu01")]))))))] --+ "NDS32_EXT_DSP_P () --+ && (!reload_completed --+ || !nds32_need_split_sms_p (operands[3], operands[4], --+ operands[6], operands[5]))" --+{ --+ return nds32_output_sms (operands[3], operands[4], --+ operands[6], operands[5]); --+} --+ "NDS32_EXT_DSP_P () --+ && !reload_completed --+ && nds32_need_split_sms_p (operands[3], operands[4], --+ operands[6], operands[5])" --+ [(const_int 1)] --+{ --+ nds32_split_sms (operands[0], operands[1], operands[2], --+ operands[3], operands[4], --+ operands[6], operands[5]); --+ DONE; --+} --+ [(set_attr "type" "dmac") --+ (set_attr "length" "4")]) --+ --+(define_insn "kmda" --+ [(set (match_operand:SI 0 "register_operand" "=r") --+ (ss_plus:SI --+ (mult:SI --+ (sign_extend:SI (vec_select:HI --+ (match_operand:V2HI 1 "register_operand" "r") --+ (parallel [(const_int 1)]))) --+ (sign_extend:SI (vec_select:HI --+ (match_operand:V2HI 2 "register_operand" "r") --+ (parallel [(const_int 1)])))) --+ (mult:SI --+ (sign_extend:SI (vec_select:HI --+ (match_dup 1) --+ (parallel [(const_int 0)]))) --+ (sign_extend:SI (vec_select:HI --+ (match_dup 2) --+ (parallel [(const_int 0)]))))))] --+ "NDS32_EXT_DSP_P ()" --+ "kmda\t%0, %1, %2" --+ [(set_attr "type" "dmac") --+ (set_attr "length" "4")]) --+ --+(define_insn "kmxda" --+ [(set (match_operand:SI 0 "register_operand" "=r") --+ (ss_plus:SI --+ (mult:SI --+ (sign_extend:SI (vec_select:HI --+ (match_operand:V2HI 1 "register_operand" "r") --+ (parallel [(const_int 1)]))) --+ (sign_extend:SI (vec_select:HI --+ (match_operand:V2HI 2 "register_operand" "r") --+ (parallel [(const_int 0)])))) --+ (mult:SI --+ (sign_extend:SI (vec_select:HI --+ (match_dup 1) --+ (parallel [(const_int 0)]))) --+ (sign_extend:SI (vec_select:HI --+ (match_dup 2) --+ (parallel [(const_int 1)]))))))] --+ "NDS32_EXT_DSP_P ()" --+ "kmxda\t%0, %1, %2" --+ [(set_attr "type" "dmac") --+ (set_attr "length" "4")]) --+ --+(define_insn "kmada" --+ [(set (match_operand:SI 0 "register_operand" "=r") --+ (ss_plus:SI --+ (match_operand:SI 1 "register_operand" " 0") --+ (ss_plus:SI --+ (mult:SI --+ (sign_extend:SI (vec_select:HI --+ (match_operand:V2HI 2 "register_operand" " r") --+ (parallel [(const_int 1)]))) --+ (sign_extend:SI (vec_select:HI --+ (match_operand:V2HI 3 "register_operand" " r") --+ (parallel [(const_int 1)])))) --+ (mult:SI --+ (sign_extend:SI (vec_select:HI --+ (match_dup 2) --+ (parallel [(const_int 0)]))) --+ (sign_extend:SI (vec_select:HI --+ (match_dup 3) --+ (parallel [(const_int 0)])))))))] --+ "NDS32_EXT_DSP_P ()" --+ "kmada\t%0, %2, %3" --+ [(set_attr "type" "dmac") --+ (set_attr "length" "4")]) --+ --+(define_insn "kmada2" --+ [(set (match_operand:SI 0 "register_operand" "=r") --+ (ss_plus:SI --+ (match_operand:SI 1 "register_operand" " 0") --+ (ss_plus:SI --+ (mult:SI --+ (sign_extend:SI (vec_select:HI --+ (match_operand:V2HI 2 "register_operand" " r") --+ (parallel [(const_int 0)]))) --+ (sign_extend:SI (vec_select:HI --+ (match_operand:V2HI 3 "register_operand" " r") --+ (parallel [(const_int 0)])))) --+ (mult:SI --+ (sign_extend:SI (vec_select:HI --+ (match_dup 2) --+ (parallel [(const_int 1)]))) --+ (sign_extend:SI (vec_select:HI --+ (match_dup 3) --+ (parallel [(const_int 1)])))))))] --+ "NDS32_EXT_DSP_P ()" --+ "kmada\t%0, %2, %3" --+ [(set_attr "type" "dmac") --+ (set_attr "length" "4")]) --+ --+(define_insn "kmaxda" --+ [(set (match_operand:SI 0 "register_operand" "=r") --+ (ss_plus:SI --+ (match_operand:SI 1 "register_operand" " 0") --+ (ss_plus:SI --+ (mult:SI --+ (sign_extend:SI (vec_select:HI --+ (match_operand:V2HI 2 "register_operand" " r") --+ (parallel [(const_int 1)]))) --+ (sign_extend:SI (vec_select:HI --+ (match_operand:V2HI 3 "register_operand" " r") --+ (parallel [(const_int 0)])))) --+ (mult:SI --+ (sign_extend:SI (vec_select:HI --+ (match_dup 2) --+ (parallel [(const_int 0)]))) --+ (sign_extend:SI (vec_select:HI --+ (match_dup 3) --+ (parallel [(const_int 1)])))))))] --+ "NDS32_EXT_DSP_P ()" --+ "kmaxda\t%0, %2, %3" --+ [(set_attr "type" "dmac") --+ (set_attr "length" "4")]) --+ --+(define_insn "kmads" --+ [(set (match_operand:SI 0 "register_operand" "=r") --+ (ss_plus:SI --+ (match_operand:SI 1 "register_operand" " 0") --+ (ss_minus:SI --+ (mult:SI --+ (sign_extend:SI (vec_select:HI --+ (match_operand:V2HI 2 "register_operand" " r") --+ (parallel [(const_int 1)]))) --+ (sign_extend:SI (vec_select:HI --+ (match_operand:V2HI 3 "register_operand" " r") --+ (parallel [(const_int 1)])))) --+ (mult:SI --+ (sign_extend:SI (vec_select:HI --+ (match_dup 2) --+ (parallel [(const_int 0)]))) --+ (sign_extend:SI (vec_select:HI --+ (match_dup 3) --+ (parallel [(const_int 0)])))))))] --+ "NDS32_EXT_DSP_P ()" --+ "kmads\t%0, %2, %3" --+ [(set_attr "type" "dmac") --+ (set_attr "length" "4")]) --+ --+(define_insn "kmadrs" --+ [(set (match_operand:SI 0 "register_operand" "=r") --+ (ss_plus:SI --+ (match_operand:SI 1 "register_operand" " 0") --+ (ss_minus:SI --+ (mult:SI --+ (sign_extend:SI (vec_select:HI --+ (match_operand:V2HI 2 "register_operand" " r") --+ (parallel [(const_int 0)]))) --+ (sign_extend:SI (vec_select:HI --+ (match_operand:V2HI 3 "register_operand" " r") --+ (parallel [(const_int 0)])))) --+ (mult:SI --+ (sign_extend:SI (vec_select:HI --+ (match_dup 2) --+ (parallel [(const_int 1)]))) --+ (sign_extend:SI (vec_select:HI --+ (match_dup 3) --+ (parallel [(const_int 1)])))))))] --+ "NDS32_EXT_DSP_P ()" --+ "kmadrs\t%0, %2, %3" --+ [(set_attr "type" "dmac") --+ (set_attr "length" "4")]) --+ --+(define_insn "kmaxds" --+ [(set (match_operand:SI 0 "register_operand" "=r") --+ (ss_plus:SI --+ (match_operand:SI 1 "register_operand" " 0") --+ (ss_minus:SI --+ (mult:SI --+ (sign_extend:SI (vec_select:HI --+ (match_operand:V2HI 2 "register_operand" " r") --+ (parallel [(const_int 1)]))) --+ (sign_extend:SI (vec_select:HI --+ (match_operand:V2HI 3 "register_operand" " r") --+ (parallel [(const_int 0)])))) --+ (mult:SI --+ (sign_extend:SI (vec_select:HI --+ (match_dup 2) --+ (parallel [(const_int 0)]))) --+ (sign_extend:SI (vec_select:HI --+ (match_dup 3) --+ (parallel [(const_int 1)])))))))] --+ "NDS32_EXT_DSP_P ()" --+ "kmaxds\t%0, %2, %3" --+ [(set_attr "type" "dmac") --+ (set_attr "length" "4")]) --+ --+(define_insn "kmsda" --+ [(set (match_operand:SI 0 "register_operand" "=r") --+ (ss_minus:SI --+ (match_operand:SI 1 "register_operand" " 0") --+ (ss_minus:SI --+ (mult:SI --+ (sign_extend:SI (vec_select:HI --+ (match_operand:V2HI 2 "register_operand" " r") --+ (parallel [(const_int 1)]))) --+ (sign_extend:SI (vec_select:HI --+ (match_operand:V2HI 3 "register_operand" " r") --+ (parallel [(const_int 1)])))) --+ (mult:SI --+ (sign_extend:SI (vec_select:HI --+ (match_dup 2) --+ (parallel [(const_int 0)]))) --+ (sign_extend:SI (vec_select:HI --+ (match_dup 3) --+ (parallel [(const_int 0)])))))))] --+ "NDS32_EXT_DSP_P ()" --+ "kmsda\t%0, %2, %3" --+ [(set_attr "type" "dmac") --+ (set_attr "length" "4")]) --+ --+(define_insn "kmsxda" --+ [(set (match_operand:SI 0 "register_operand" "=r") --+ (ss_minus:SI --+ (match_operand:SI 1 "register_operand" " 0") --+ (ss_minus:SI --+ (mult:SI --+ (sign_extend:SI (vec_select:HI --+ (match_operand:V2HI 2 "register_operand" " r") --+ (parallel [(const_int 1)]))) --+ (sign_extend:SI (vec_select:HI --+ (match_operand:V2HI 3 "register_operand" " r") --+ (parallel [(const_int 0)])))) --+ (mult:SI --+ (sign_extend:SI (vec_select:HI --+ (match_dup 2) --+ (parallel [(const_int 0)]))) --+ (sign_extend:SI (vec_select:HI --+ (match_dup 3) --+ (parallel [(const_int 1)])))))))] --+ "NDS32_EXT_DSP_P ()" --+ "kmsxda\t%0, %2, %3" --+ [(set_attr "type" "dmac") --+ (set_attr "length" "4")]) --+ --+;; smax[8|16] and umax[8|16] --+(define_insn "3" --+ [(set (match_operand:VQIHI 0 "register_operand" "=r") --+ (sumax:VQIHI (match_operand:VQIHI 1 "register_operand" " r") --+ (match_operand:VQIHI 2 "register_operand" " r")))] --+ "NDS32_EXT_DSP_P ()" --+ "\t%0, %1, %2" --+ [(set_attr "type" "dalu") --+ (set_attr "length" "4")]) --+ --+;; smin[8|16] and umin[8|16] --+(define_insn "3" --+ [(set (match_operand:VQIHI 0 "register_operand" "=r") --+ (sumin:VQIHI (match_operand:VQIHI 1 "register_operand" " r") --+ (match_operand:VQIHI 2 "register_operand" " r")))] --+ "NDS32_EXT_DSP_P ()" --+ "\t%0, %1, %2" --+ [(set_attr "type" "dalu") --+ (set_attr "length" "4")]) --+ --+(define_insn "3_bb" --+ [(set (match_operand: 0 "register_operand" "=r") --+ (sumin_max: (vec_select: --+ (match_operand:VQIHI 1 "register_operand" " r") --+ (parallel [(const_int 0)])) --+ (vec_select: --+ (match_operand:VQIHI 2 "register_operand" " r") --+ (parallel [(const_int 0)]))))] --+ "NDS32_EXT_DSP_P () && !TARGET_BIG_ENDIAN" --+ "\t%0, %1, %2" --+ [(set_attr "type" "dalu") --+ (set_attr "length" "4")]) --+ --+(define_insn_and_split "3_tt" --+ [(set (match_operand: 0 "register_operand" "=r") --+ (sumin_max: (vec_select: --+ (match_operand:VQIHI 1 "register_operand" " r") --+ (parallel [(const_int 1)])) --+ (vec_select: --+ (match_operand:VQIHI 2 "register_operand" " r") --+ (parallel [(const_int 1)]))))] --+ "NDS32_EXT_DSP_P () && !reload_completed && !TARGET_BIG_ENDIAN" --+ "#" --+ "NDS32_EXT_DSP_P () && !reload_completed" --+ [(const_int 0)] --+{ --+ rtx tmp = gen_reg_rtx (mode); --+ emit_insn (gen_3 (tmp, operands[1], operands[2])); --+ emit_insn (gen_rotr_1 (tmp, tmp)); --+ emit_move_insn (operands[0], simplify_gen_subreg (mode, tmp, mode, 0)); --+ DONE; --+} --+ [(set_attr "type" "dalu") --+ (set_attr "length" "4")]) --+ --+(define_insn_and_split "v4qi3_22" --+ [(set (match_operand:QI 0 "register_operand" "=r") --+ (sumin_max:QI (vec_select:QI --+ (match_operand:V4QI 1 "register_operand" " r") --+ (parallel [(const_int 2)])) --+ (vec_select:QI --+ (match_operand:V4QI 2 "register_operand" " r") --+ (parallel [(const_int 2)]))))] --+ "NDS32_EXT_DSP_P () && !reload_completed && !TARGET_BIG_ENDIAN" --+ "#" --+ "NDS32_EXT_DSP_P () && !reload_completed" --+ [(const_int 0)] --+{ --+ rtx tmp = gen_reg_rtx (V4QImode); --+ emit_insn (gen_v4qi3 (tmp, operands[1], operands[2])); --+ emit_insn (gen_rotrv4qi_2 (tmp, tmp)); --+ emit_move_insn (operands[0], simplify_gen_subreg (QImode, tmp, V4QImode, 0)); --+ DONE; --+} --+ [(set_attr "type" "dalu") --+ (set_attr "length" "4")]) --+ --+(define_insn_and_split "v4qi3_33" --+ [(set (match_operand:QI 0 "register_operand" "=r") --+ (sumin_max:QI (vec_select:QI --+ (match_operand:V4QI 1 "register_operand" " r") --+ (parallel [(const_int 3)])) --+ (vec_select:QI --+ (match_operand:V4QI 2 "register_operand" " r") --+ (parallel [(const_int 3)]))))] --+ "NDS32_EXT_DSP_P () && !reload_completed && !TARGET_BIG_ENDIAN" --+ "#" --+ "NDS32_EXT_DSP_P () && !reload_completed" --+ [(const_int 0)] --+{ --+ rtx tmp = gen_reg_rtx (V4QImode); --+ emit_insn (gen_v4qi3 (tmp, operands[1], operands[2])); --+ emit_insn (gen_rotrv4qi_3 (tmp, tmp)); --+ emit_move_insn (operands[0], simplify_gen_subreg (QImode, tmp, V4QImode, 0)); --+ DONE; --+} --+ [(set_attr "type" "dalu") --+ (set_attr "length" "4")]) --+ --+(define_insn_and_split "v2hi3_bbtt" --+ [(set (match_operand:V2HI 0 "register_operand" "=r") --+ (vec_merge:V2HI --+ (vec_duplicate:V2HI --+ (sumin_max:HI (vec_select:HI --+ (match_operand:V2HI 1 "register_operand" " r") --+ (parallel [(const_int 1)])) --+ (vec_select:HI --+ (match_operand:V2HI 2 "register_operand" " r") --+ (parallel [(const_int 1)])))) --+ (vec_duplicate:V2HI --+ (sumin_max:HI (vec_select:HI --+ (match_dup:V2HI 1) --+ (parallel [(const_int 0)])) --+ (vec_select:HI --+ (match_dup:HI 2) --+ (parallel [(const_int 0)])))) --+ (const_int 2)))] --+ "NDS32_EXT_DSP_P () && !TARGET_BIG_ENDIAN" --+ "#" --+ "NDS32_EXT_DSP_P ()" --+ [(const_int 0)] --+{ --+ emit_insn (gen_v2hi3 (operands[0], operands[1], operands[2])); --+ DONE; --+} --+ [(set_attr "type" "dalu") --+ (set_attr "length" "4")]) --+ --+(define_expand "abs2" --+ [(set (match_operand:VQIHI 0 "register_operand" "=r") --+ (ss_abs:VQIHI (match_operand:VQIHI 1 "register_operand" " r")))] --+ "NDS32_EXT_DSP_P () && TARGET_HW_ABS && !flag_wrapv" --+{ --+}) --+ --+(define_insn "kabs2" --+ [(set (match_operand:VQIHI 0 "register_operand" "=r") --+ (ss_abs:VQIHI (match_operand:VQIHI 1 "register_operand" " r")))] --+ "NDS32_EXT_DSP_P ()" --+ "kabs\t%0, %1" --+ [(set_attr "type" "dalu") --+ (set_attr "length" "4")]) --+ --+(define_insn "mar64_1" --+ [(set (match_operand:DI 0 "register_operand" "=r") --+ (plus:DI --+ (match_operand:DI 1 "register_operand" " 0") --+ (mult:DI --+ (extend:DI --+ (match_operand:SI 2 "register_operand" " r")) --+ (extend:DI --+ (match_operand:SI 3 "register_operand" " r")))))] --+ "NDS32_EXT_DSP_P ()" --+ "mar64\t%0, %2, %3" --+ [(set_attr "type" "dmac") --+ (set_attr "length" "4")]) --+ --+(define_insn "mar64_2" --+ [(set (match_operand:DI 0 "register_operand" "=r") --+ (plus:DI --+ (mult:DI --+ (extend:DI --+ (match_operand:SI 2 "register_operand" " r")) --+ (extend:DI --+ (match_operand:SI 3 "register_operand" " r"))) --+ (match_operand:DI 1 "register_operand" " 0")))] --+ "NDS32_EXT_DSP_P ()" --+ "mar64\t%0, %2, %3" --+ [(set_attr "type" "dmac") --+ (set_attr "length" "4")]) --+ --+(define_insn "mar64_3" --+ [(set (match_operand:DI 0 "register_operand" "=r") --+ (plus:DI --+ (match_operand:DI 1 "register_operand" " 0") --+ (extend:DI --+ (mult:SI --+ (match_operand:SI 2 "register_operand" " r") --+ (match_operand:SI 3 "register_operand" " r")))))] --+ "NDS32_EXT_DSP_P ()" --+ "mar64\t%0, %2, %3" --+ [(set_attr "type" "dmac") --+ (set_attr "length" "4")]) --+ --+(define_insn "mar64_4" --+ [(set (match_operand:DI 0 "register_operand" "=r") --+ (plus:DI --+ (extend:DI --+ (mult:SI --+ (match_operand:SI 2 "register_operand" " r") --+ (match_operand:SI 3 "register_operand" " r"))) --+ (match_operand:DI 1 "register_operand" " 0")))] --+ "NDS32_EXT_DSP_P ()" --+ "mar64\t%0, %2, %3" --+ [(set_attr "type" "dmac") --+ (set_attr "length" "4")]) --+ --+(define_insn "msr64" --+ [(set (match_operand:DI 0 "register_operand" "=r") --+ (minus:DI --+ (match_operand:DI 1 "register_operand" " 0") --+ (mult:DI --+ (extend:DI --+ (match_operand:SI 2 "register_operand" " r")) --+ (extend:DI --+ (match_operand:SI 3 "register_operand" " r")))))] --+ "NDS32_EXT_DSP_P ()" --+ "msr64\t%0, %2, %3" --+ [(set_attr "type" "dmac") --+ (set_attr "length" "4")]) --+ --+(define_insn "msr64_2" --+ [(set (match_operand:DI 0 "register_operand" "=r") --+ (minus:DI --+ (match_operand:DI 1 "register_operand" " 0") --+ (extend:DI --+ (mult:SI --+ (match_operand:SI 2 "register_operand" " r") --+ (match_operand:SI 3 "register_operand" " r")))))] --+ "NDS32_EXT_DSP_P ()" --+ "msr64\t%0, %2, %3" --+ [(set_attr "type" "dmac") --+ (set_attr "length" "4")]) --+ --+;; kmar64, kmsr64, ukmar64 and ukmsr64 --+(define_insn "kmar64_1" --+ [(set (match_operand:DI 0 "register_operand" "=r") --+ (ss_plus:DI --+ (match_operand:DI 1 "register_operand" " 0") --+ (mult:DI --+ (sign_extend:DI --+ (match_operand:SI 2 "register_operand" " r")) --+ (sign_extend:DI --+ (match_operand:SI 3 "register_operand" " r")))))] --+ "NDS32_EXT_DSP_P ()" --+ "kmar64\t%0, %2, %3" --+ [(set_attr "type" "dmac") --+ (set_attr "length" "4")]) --+ --+(define_insn "kmar64_2" --+ [(set (match_operand:DI 0 "register_operand" "=r") --+ (ss_plus:DI --+ (mult:DI --+ (sign_extend:DI --+ (match_operand:SI 2 "register_operand" " r")) --+ (sign_extend:DI --+ (match_operand:SI 3 "register_operand" " r"))) --+ (match_operand:DI 1 "register_operand" " 0")))] --+ "NDS32_EXT_DSP_P ()" --+ "kmar64\t%0, %2, %3" --+ [(set_attr "type" "dmac") --+ (set_attr "length" "4")]) --+ --+(define_insn "kmsr64" --+ [(set (match_operand:DI 0 "register_operand" "=r") --+ (ss_minus:DI --+ (match_operand:DI 1 "register_operand" " 0") --+ (mult:DI --+ (sign_extend:DI --+ (match_operand:SI 2 "register_operand" " r")) --+ (sign_extend:DI --+ (match_operand:SI 3 "register_operand" " r")))))] --+ "NDS32_EXT_DSP_P ()" --+ "kmsr64\t%0, %2, %3" --+ [(set_attr "type" "dmac") --+ (set_attr "length" "4")]) --+ --+(define_insn "ukmar64_1" --+ [(set (match_operand:DI 0 "register_operand" "=r") --+ (us_plus:DI --+ (match_operand:DI 1 "register_operand" " 0") --+ (mult:DI --+ (zero_extend:DI --+ (match_operand:SI 2 "register_operand" " r")) --+ (zero_extend:DI --+ (match_operand:SI 3 "register_operand" " r")))))] --+ "NDS32_EXT_DSP_P ()" --+ "ukmar64\t%0, %2, %3" --+ [(set_attr "type" "dmac") --+ (set_attr "length" "4")]) --+ --+(define_insn "ukmar64_2" --+ [(set (match_operand:DI 0 "register_operand" "=r") --+ (us_plus:DI --+ (mult:DI --+ (zero_extend:DI --+ (match_operand:SI 2 "register_operand" " r")) --+ (zero_extend:DI --+ (match_operand:SI 3 "register_operand" " r"))) --+ (match_operand:DI 1 "register_operand" " 0")))] --+ "NDS32_EXT_DSP_P ()" --+ "ukmar64\t%0, %2, %3" --+ [(set_attr "type" "dmac") --+ (set_attr "length" "4")]) --+ --+(define_insn "ukmsr64" --+ [(set (match_operand:DI 0 "register_operand" "=r") --+ (us_minus:DI --+ (match_operand:DI 1 "register_operand" " 0") --+ (mult:DI --+ (zero_extend:DI --+ (match_operand:SI 2 "register_operand" " r")) --+ (zero_extend:DI --+ (match_operand:SI 3 "register_operand" " r")))))] --+ "NDS32_EXT_DSP_P ()" --+ "ukmsr64\t%0, %2, %3" --+ [(set_attr "type" "dmac") --+ (set_attr "length" "4")]) --+ --+(define_insn "bpick1" --+ [(set (match_operand:SI 0 "register_operand" "=r") --+ (ior:SI --+ (and:SI --+ (match_operand:SI 1 "register_operand" " r") --+ (match_operand:SI 3 "register_operand" " r")) --+ (and:SI --+ (match_operand:SI 2 "register_operand" " r") --+ (not:SI (match_dup 3)))))] --+ "NDS32_EXT_DSP_P ()" --+ "bpick\t%0, %1, %2, %3" --+ [(set_attr "type" "dbpick") --+ (set_attr "length" "4")]) --+ --+(define_insn "bpick2" --+ [(set (match_operand:SI 0 "register_operand" "=r") --+ (ior:SI --+ (and:SI --+ (match_operand:SI 1 "register_operand" " r") --+ (match_operand:SI 2 "register_operand" " r")) --+ (and:SI --+ (not:SI (match_dup 2)) --+ (match_operand:SI 3 "register_operand" " r"))))] --+ "NDS32_EXT_DSP_P ()" --+ "bpick\t%0, %1, %3, %2" --+ [(set_attr "type" "dbpick") --+ (set_attr "length" "4")]) --+ --+(define_insn "bpick3" --+ [(set (match_operand:SI 0 "register_operand" "=r") --+ (ior:SI --+ (and:SI --+ (match_operand:SI 1 "register_operand" " r") --+ (match_operand:SI 2 "register_operand" " r")) --+ (and:SI --+ (match_operand:SI 3 "register_operand" " r") --+ (not:SI (match_dup 1)))))] --+ "NDS32_EXT_DSP_P ()" --+ "bpick\t%0, %2, %3, %1" --+ [(set_attr "type" "dbpick") --+ (set_attr "length" "4")]) --+ --+(define_insn "bpick4" --+ [(set (match_operand:SI 0 "register_operand" "=r") --+ (ior:SI --+ (and:SI --+ (match_operand:SI 1 "register_operand" " r") --+ (match_operand:SI 2 "register_operand" " r")) --+ (and:SI --+ (not:SI (match_dup 1)) --+ (match_operand:SI 3 "register_operand" " r"))))] --+ "NDS32_EXT_DSP_P ()" --+ "bpick\t%0, %2, %3, %1" --+ [(set_attr "type" "dbpick") --+ (set_attr "length" "4")]) --+ --+(define_insn "bpick5" --+ [(set (match_operand:SI 0 "register_operand" "=r") --+ (ior:SI --+ (and:SI --+ (match_operand:SI 1 "register_operand" " r") --+ (not:SI (match_operand:SI 2 "register_operand" " r"))) --+ (and:SI --+ (match_operand:SI 3 "register_operand" " r") --+ (match_dup 2))))] --+ "NDS32_EXT_DSP_P ()" --+ "bpick\t%0, %3, %1, %2" --+ [(set_attr "type" "dbpick") --+ (set_attr "length" "4")]) --+ --+(define_insn "bpick6" --+ [(set (match_operand:SI 0 "register_operand" "=r") --+ (ior:SI --+ (and:SI --+ (not:SI (match_operand:SI 1 "register_operand" " r")) --+ (match_operand:SI 2 "register_operand" " r")) --+ (and:SI --+ (match_operand:SI 3 "register_operand" " r") --+ (match_dup 1))))] --+ "NDS32_EXT_DSP_P ()" --+ "bpick\t%0, %3, %2, %1" --+ [(set_attr "type" "dbpick") --+ (set_attr "length" "4")]) --+ --+(define_insn "bpick7" --+ [(set (match_operand:SI 0 "register_operand" "=r") --+ (ior:SI --+ (and:SI --+ (match_operand:SI 1 "register_operand" " r") --+ (not:SI (match_operand:SI 2 "register_operand" " r"))) --+ (and:SI --+ (match_dup 2) --+ (match_operand:SI 3 "register_operand" " r"))))] --+ "NDS32_EXT_DSP_P ()" --+ "bpick\t%0, %3, %1, %2" --+ [(set_attr "type" "dbpick") --+ (set_attr "length" "4")]) --+ --+(define_insn "bpick8" --+ [(set (match_operand:SI 0 "register_operand" "=r") --+ (ior:SI --+ (and:SI --+ (not:SI (match_operand:SI 1 "register_operand" " r")) --+ (match_operand:SI 2 "register_operand" " r")) --+ (and:SI --+ (match_dup 1) --+ (match_operand:SI 3 "register_operand" " r"))))] --+ "NDS32_EXT_DSP_P ()" --+ "bpick\t%0, %3, %2, %1" --+ [(set_attr "type" "dbpick") --+ (set_attr "length" "4")]) --+ --+(define_insn "sraiu" --+ [(set (match_operand:SI 0 "register_operand" "= r, r") --+ (unspec:SI [(ashiftrt:SI (match_operand:SI 1 "register_operand" " r, r") --+ (match_operand:SI 2 "nds32_rimm5u_operand" " Iu05, r"))] --+ UNSPEC_ROUND))] --+ "NDS32_EXT_DSP_P ()" --+ "@ --+ srai.u\t%0, %1, %2 --+ sra.u\t%0, %1, %2" --+ [(set_attr "type" "daluround") --+ (set_attr "length" "4")]) --+ --+(define_insn "kssl" --+ [(set (match_operand:SI 0 "register_operand" "= r, r") --+ (ss_ashift:SI (match_operand:SI 1 "register_operand" " r, r") --+ (match_operand:SI 2 "nds32_rimm5u_operand" " Iu05, r")))] --+ "NDS32_EXT_DSP_P ()" --+ "@ --+ kslli\t%0, %1, %2 --+ ksll\t%0, %1, %2" --+ [(set_attr "type" "dalu") --+ (set_attr "length" "4")]) --+ --+(define_insn "kslraw_round" --+ [(set (match_operand:SI 0 "register_operand" "=r") --+ (if_then_else:SI --+ (lt:SI (match_operand:SI 2 "register_operand" " r") --+ (const_int 0)) --+ (unspec:SI [(ashiftrt:SI (match_operand:SI 1 "register_operand" " r") --+ (neg:SI (match_dup 2)))] --+ UNSPEC_ROUND) --+ (ss_ashift:SI (match_dup 1) --+ (match_dup 2))))] --+ "NDS32_EXT_DSP_P ()" --+ "kslraw.u\t%0, %1, %2" --+ [(set_attr "type" "daluround") --+ (set_attr "length" "4")]) --+ --+(define_insn_and_split "di3" --+ [(set (match_operand:DI 0 "register_operand" "") --+ (shift_rotate:DI (match_operand:DI 1 "register_operand" "") --+ (match_operand:SI 2 "nds32_rimm6u_operand" "")))] --+ "NDS32_EXT_DSP_P () && !reload_completed" --+ "#" --+ "NDS32_EXT_DSP_P () && !reload_completed" --+ [(const_int 0)] --+{ --+ if (REGNO (operands[0]) == REGNO (operands[1])) --+ { --+ rtx tmp = gen_reg_rtx (DImode); --+ nds32_split_di3 (tmp, operands[1], operands[2]); --+ emit_move_insn (operands[0], tmp); --+ } --+ else --+ nds32_split_di3 (operands[0], operands[1], operands[2]); --+ DONE; --+}) --+ --+(define_insn "sclip32" --+ [(set (match_operand:SI 0 "register_operand" "=r") --+ (unspec:SI [(match_operand:SI 1 "register_operand" "r") --+ (match_operand:SI 2 "immediate_operand" "i")] UNSPEC_CLIPS_OV))] --+ "NDS32_EXT_DSP_P ()" --+ "sclip32\t%0, %1, %2" --+ [(set_attr "type" "dclip") --+ (set_attr "length" "4")] --+) --+ --+(define_insn "uclip32" --+ [(set (match_operand:SI 0 "register_operand" "=r") --+ (unspec:SI [(match_operand:SI 1 "register_operand" "r") --+ (match_operand:SI 2 "immediate_operand" "i")] UNSPEC_CLIP_OV))] --+ "NDS32_EXT_DSP_P ()" --+ "uclip32\t%0, %1, %2" --+ [(set_attr "type" "dclip") --+ (set_attr "length" "4")] --+) --+ --+(define_insn "bitrev" --+ [(set (match_operand:SI 0 "register_operand" "=r, r") --+ (unspec:SI [(match_operand:SI 1 "register_operand" " r, r") --+ (match_operand:SI 2 "nds32_rimm5u_operand" " r, Iu05")] --+ UNSPEC_BITREV))] --+ "" --+ "@ --+ bitrev\t%0, %1, %2 --+ bitrevi\t%0, %1, %2" --+ [(set_attr "type" "dalu") --+ (set_attr "length" "4")] --+) --+ --+;; wext, wexti --+(define_insn "wext" --+ [(set (match_operand:SI 0 "register_operand" "=r, r") --+ (truncate:SI --+ (shiftrt:DI --+ (match_operand:DI 1 "register_operand" " r, r") --+ (match_operand:SI 2 "nds32_rimm5u_operand" " r,Iu05"))))] --+ "NDS32_EXT_DSP_P ()" --+ "@ --+ wext\t%0, %1, %2 --+ wexti\t%0, %1, %2" --+ [(set_attr "type" "dwext") --+ (set_attr "length" "4")]) --+ --+;; 32-bit add/sub instruction: raddw and rsubw. --+(define_insn "rsi3" --+ [(set (match_operand:SI 0 "register_operand" "=r") --+ (truncate:SI --+ (ashiftrt:DI --+ (plus_minus:DI --+ (sign_extend:DI (match_operand:SI 1 "register_operand" " r")) --+ (sign_extend:DI (match_operand:SI 2 "register_operand" " r"))) --+ (const_int 1))))] --+ "NDS32_EXT_DSP_P ()" --+ "rw\t%0, %1, %2" --+ [(set_attr "type" "dalu") --+ (set_attr "length" "4")]) --+ --+;; 32-bit add/sub instruction: uraddw and ursubw. --+(define_insn "ursi3" --+ [(set (match_operand:SI 0 "register_operand" "=r") --+ (truncate:SI --+ (lshiftrt:DI --+ (plus_minus:DI --+ (zero_extend:DI (match_operand:SI 1 "register_operand" " r")) --+ (zero_extend:DI (match_operand:SI 2 "register_operand" " r"))) --+ (const_int 1))))] --+ "NDS32_EXT_DSP_P ()" --+ "urw\t%0, %1, %2" --+ [(set_attr "type" "dalu") --+ (set_attr "length" "4")]) --diff --git a/gcc/config/nds32/nds32-e8.md b/gcc/config/nds32/nds32-e8.md --new file mode 100644 --index 0000000..1f24b5c ----- /dev/null --+++ b/gcc/config/nds32/nds32-e8.md --@@ -0,0 +1,329 @@ --+;; Pipeline descriptions of Andes NDS32 cpu for GNU compiler --+;; Copyright (C) 2012-2016 Free Software Foundation, Inc. --+;; Contributed by Andes Technology Corporation. --+;; --+;; This file is part of GCC. --+;; --+;; GCC is free software; you can redistribute it and/or modify it --+;; under the terms of the GNU General Public License as published --+;; by the Free Software Foundation; either version 3, or (at your --+;; option) any later version. --+;; --+;; GCC is distributed in the hope that it will be useful, but WITHOUT --+;; ANY WARRANTY; without even the implied warranty of MERCHANTABILITY --+;; or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public --+;; License for more details. --+;; --+;; You should have received a copy of the GNU General Public License --+;; along with GCC; see the file COPYING3. If not see --+;; . --+ --+ --+;; ------------------------------------------------------------------------ --+;; Define E8 pipeline settings. --+;; ------------------------------------------------------------------------ --+ --+(define_automaton "nds32_e8_machine") --+ --+;; ------------------------------------------------------------------------ --+;; Pipeline Stages --+;; ------------------------------------------------------------------------ --+;; IF - Instruction Fetch --+;; II - Instruction Issue / Address Generation --+;; EX - Instruction Execution --+;; EXD - Psuedo Stage / Load Data Completion --+ --+(define_cpu_unit "e8_ii" "nds32_e8_machine") --+(define_cpu_unit "e8_ex" "nds32_e8_machine") --+ --+(define_insn_reservation "nds_e8_unknown" 1 --+ (and (eq_attr "type" "unknown") --+ (eq_attr "pipeline_model" "e8")) --+ "e8_ii, e8_ex") --+ --+(define_insn_reservation "nds_e8_misc" 1 --+ (and (eq_attr "type" "misc") --+ (eq_attr "pipeline_model" "e8")) --+ "e8_ii, e8_ex") --+ --+(define_insn_reservation "nds_e8_alu" 1 --+ (and (eq_attr "type" "alu") --+ (eq_attr "pipeline_model" "e8")) --+ "e8_ii, e8_ex") --+ --+(define_insn_reservation "nds_e8_load" 1 --+ (and (match_test "nds32::load_single_p (insn)") --+ (eq_attr "pipeline_model" "e8")) --+ "e8_ii, e8_ex") --+ --+(define_insn_reservation "nds_e8_store" 1 --+ (and (match_test "nds32::store_single_p (insn)") --+ (eq_attr "pipeline_model" "e8")) --+ "e8_ii, e8_ex") --+ --+(define_insn_reservation "nds_e8_load_multiple_1" 1 --+ (and (and (eq_attr "type" "load_multiple") --+ (eq_attr "combo" "1")) --+ (eq_attr "pipeline_model" "e8")) --+ "e8_ii, e8_ex") --+ --+(define_insn_reservation "nds_e8_load_multiple_2" 1 --+ (and (ior (and (eq_attr "type" "load_multiple") --+ (eq_attr "combo" "2")) --+ (match_test "nds32::load_double_p (insn)")) --+ (eq_attr "pipeline_model" "e8")) --+ "e8_ii, e8_ii+e8_ex, e8_ex") --+ --+(define_insn_reservation "nds_e8_load_multiple_3" 1 --+ (and (and (eq_attr "type" "load_multiple") --+ (eq_attr "combo" "3")) --+ (eq_attr "pipeline_model" "e8")) --+ "e8_ii, (e8_ii+e8_ex)*2, e8_ex") --+ --+(define_insn_reservation "nds_e8_load_multiple_4" 1 --+ (and (and (eq_attr "type" "load_multiple") --+ (eq_attr "combo" "4")) --+ (eq_attr "pipeline_model" "e8")) --+ "e8_ii, (e8_ii+e8_ex)*3, e8_ex") --+ --+(define_insn_reservation "nds_e8_load_multiple_5" 1 --+ (and (and (eq_attr "type" "load_multiple") --+ (eq_attr "combo" "5")) --+ (eq_attr "pipeline_model" "e8")) --+ "e8_ii, (e8_ii+e8_ex)*4, e8_ex") --+ --+(define_insn_reservation "nds_e8_load_multiple_6" 1 --+ (and (and (eq_attr "type" "load_multiple") --+ (eq_attr "combo" "6")) --+ (eq_attr "pipeline_model" "e8")) --+ "e8_ii, (e8_ii+e8_ex)*5, e8_ex") --+ --+(define_insn_reservation "nds_e8_load_multiple_7" 1 --+ (and (and (eq_attr "type" "load_multiple") --+ (eq_attr "combo" "7")) --+ (eq_attr "pipeline_model" "e8")) --+ "e8_ii, (e8_ii+e8_ex)*6, e8_ex") --+ --+(define_insn_reservation "nds_e8_load_multiple_8" 1 --+ (and (and (eq_attr "type" "load_multiple") --+ (eq_attr "combo" "8")) --+ (eq_attr "pipeline_model" "e8")) --+ "e8_ii, (e8_ii+e8_ex)*7, e8_ex") --+ --+(define_insn_reservation "nds_e8_load_multiple_12" 1 --+ (and (and (eq_attr "type" "load_multiple") --+ (eq_attr "combo" "12")) --+ (eq_attr "pipeline_model" "e8")) --+ "e8_ii, (e8_ii+e8_ex)*11, e8_ex") --+ --+(define_insn_reservation "nds_e8_store_multiple_1" 1 --+ (and (and (eq_attr "type" "store_multiple") --+ (eq_attr "combo" "1")) --+ (eq_attr "pipeline_model" "e8")) --+ "e8_ii, e8_ex") --+ --+(define_insn_reservation "nds_e8_store_multiple_2" 1 --+ (and (ior (and (eq_attr "type" "store_multiple") --+ (eq_attr "combo" "2")) --+ (match_test "nds32::store_double_p (insn)")) --+ (eq_attr "pipeline_model" "e8")) --+ "e8_ii, e8_ii+e8_ex, e8_ex") --+ --+(define_insn_reservation "nds_e8_store_multiple_3" 1 --+ (and (and (eq_attr "type" "store_multiple") --+ (eq_attr "combo" "3")) --+ (eq_attr "pipeline_model" "e8")) --+ "e8_ii, (e8_ii+e8_ex)*2, e8_ex") --+ --+(define_insn_reservation "nds_e8_store_multiple_4" 1 --+ (and (and (eq_attr "type" "store_multiple") --+ (eq_attr "combo" "4")) --+ (eq_attr "pipeline_model" "e8")) --+ "e8_ii, (e8_ii+e8_ex)*3, e8_ex") --+ --+(define_insn_reservation "nds_e8_store_multiple_5" 1 --+ (and (and (eq_attr "type" "store_multiple") --+ (eq_attr "combo" "5")) --+ (eq_attr "pipeline_model" "e8")) --+ "e8_ii, (e8_ii+e8_ex)*4, e8_ex") --+ --+(define_insn_reservation "nds_e8_store_multiple_6" 1 --+ (and (and (eq_attr "type" "store_multiple") --+ (eq_attr "combo" "6")) --+ (eq_attr "pipeline_model" "e8")) --+ "e8_ii, (e8_ii+e8_ex)*5, e8_ex") --+ --+(define_insn_reservation "nds_e8_store_multiple_7" 1 --+ (and (and (eq_attr "type" "store_multiple") --+ (eq_attr "combo" "7")) --+ (eq_attr "pipeline_model" "e8")) --+ "e8_ii, (e8_ii+e8_ex)*6, e8_ex") --+ --+(define_insn_reservation "nds_e8_store_multiple_8" 1 --+ (and (and (eq_attr "type" "store_multiple") --+ (eq_attr "combo" "8")) --+ (eq_attr "pipeline_model" "e8")) --+ "e8_ii, (e8_ii+e8_ex)*7, e8_ex") --+ --+(define_insn_reservation "nds_e8_store_multiple_12" 1 --+ (and (and (eq_attr "type" "store_multiple") --+ (eq_attr "combo" "12")) --+ (eq_attr "pipeline_model" "e8")) --+ "e8_ii, (e8_ii+e8_ex)*11, e8_ex") --+ --+(define_insn_reservation "nds_e8_mul_fast" 1 --+ (and (match_test "nds32_mul_config != MUL_TYPE_SLOW") --+ (and (eq_attr "type" "mul") --+ (eq_attr "pipeline_model" "e8"))) --+ "e8_ii, e8_ex") --+ --+(define_insn_reservation "nds_e8_mul_slow" 1 --+ (and (match_test "nds32_mul_config == MUL_TYPE_SLOW") --+ (and (eq_attr "type" "mul") --+ (eq_attr "pipeline_model" "e8"))) --+ "e8_ii, e8_ex*16") --+ --+(define_insn_reservation "nds_e8_mac_fast" 1 --+ (and (match_test "nds32_mul_config != MUL_TYPE_SLOW") --+ (and (eq_attr "type" "mac") --+ (eq_attr "pipeline_model" "e8"))) --+ "e8_ii, e8_ii+e8_ex, e8_ex") --+ --+(define_insn_reservation "nds_e8_mac_slow" 1 --+ (and (match_test "nds32_mul_config == MUL_TYPE_SLOW") --+ (and (eq_attr "type" "mac") --+ (eq_attr "pipeline_model" "e8"))) --+ "e8_ii, (e8_ii+e8_ex)*16, e8_ex") --+ --+(define_insn_reservation "nds_e8_div" 1 --+ (and (eq_attr "type" "div") --+ (eq_attr "pipeline_model" "e8")) --+ "e8_ii, (e8_ii+e8_ex)*36, e8_ex") --+ --+(define_insn_reservation "nds_e8_branch" 1 --+ (and (eq_attr "type" "branch") --+ (eq_attr "pipeline_model" "e8")) --+ "e8_ii, e8_ex") --+ --+;; ------------------------------------------------------------------------ --+;; Comment Notations and Bypass Rules --+;; ------------------------------------------------------------------------ --+;; Producers (LHS) --+;; LD --+;; Load data from the memory and produce the loaded data. The result is --+;; ready at EXD. --+;; LMW(N, M) --+;; There are N micro-operations within an instruction that loads multiple --+;; words. The result produced by the M-th micro-operation is sent to --+;; consumers. The result is ready at EXD. --+;; ADDR_OUT --+;; Most load/store instructions can produce an address output if updating --+;; the base register is required. The result is ready at EX, which is --+;; produced by ALU. --+;; ALU, MOVD44, MUL, MAC --+;; The result is ready at EX. --+;; DIV_Rs --+;; A division instruction saves the quotient result to Rt and saves the --+;; remainder result to Rs. The instruction is separated into two micro- --+;; operations. The first micro-operation writes to Rt, and the seconde --+;; one writes to Rs. Each of the results is ready at EX. --+;; --+;; Consumers (RHS) --+;; ALU, MUL, DIV --+;; Require operands at EX. --+;; ADDR_IN_MOP(N) --+;; N denotes the address input is required by the N-th micro-operation. --+;; Such operand is required at II. --+;; ST --+;; A store instruction requires its data at EX. --+;; SMW(N, M) --+;; There are N micro-operations within an instruction that stores multiple --+;; words. Each M-th micro-operation requires its data at EX. --+;; BR_COND --+;; If a branch instruction is conditional, its input data is required at EX. --+ --+;; LD -> ADDR_IN_MOP(1) --+(define_bypass 2 --+ "nds_e8_load" --+ "nds_e8_branch,\ --+ nds_e8_load, nds_e8_store,\ --+ nds_e8_load_multiple_1,nds_e8_load_multiple_2, nds_e8_load_multiple_3,\ --+ nds_e8_load_multiple_4,nds_e8_load_multiple_5, nds_e8_load_multiple_6,\ --+ nds_e8_load_multiple_7,nds_e8_load_multiple_8, nds_e8_load_multiple_12,\ --+ nds_e8_store_multiple_1,nds_e8_store_multiple_2, nds_e8_store_multiple_3,\ --+ nds_e8_store_multiple_4,nds_e8_store_multiple_5, nds_e8_store_multiple_6,\ --+ nds_e8_store_multiple_7,nds_e8_store_multiple_8, nds_e8_store_multiple_12" --+ "nds32_e8_load_to_ii_p" --+) --+ --+;; LD -> ALU, MUL, MAC, DIV, BR_COND, ST, SMW(N, 1) --+(define_bypass 2 --+ "nds_e8_load" --+ "nds_e8_alu, --+ nds_e8_mul_fast, nds_e8_mul_slow,\ --+ nds_e8_mac_fast, nds_e8_mac_slow,\ --+ nds_e8_div,\ --+ nds_e8_branch,\ --+ nds_e8_store,\ --+ nds_e8_store_multiple_1,nds_e8_store_multiple_2, nds_e8_store_multiple_3,\ --+ nds_e8_store_multiple_4,nds_e8_store_multiple_5, nds_e8_store_multiple_6,\ --+ nds_e8_store_multiple_7,nds_e8_store_multiple_8, nds_e8_store_multiple_12" --+ "nds32_e8_load_to_ex_p" --+) --+ --+;; ALU, MOVD44, MUL, MAC, DIV_Rs, LD_bi, ADDR_OUT -> ADDR_IN_MOP(1) --+(define_bypass 2 --+ "nds_e8_alu, --+ nds_e8_mul_fast, nds_e8_mul_slow,\ --+ nds_e8_mac_fast, nds_e8_mac_slow,\ --+ nds_e8_div,\ --+ nds_e8_load, nds_e8_store,\ --+ nds_e8_load_multiple_1,nds_e8_load_multiple_2, nds_e8_load_multiple_3,\ --+ nds_e8_load_multiple_4,nds_e8_load_multiple_5, nds_e8_load_multiple_6,\ --+ nds_e8_load_multiple_7,nds_e8_load_multiple_8, nds_e8_load_multiple_12,\ --+ nds_e8_store_multiple_1,nds_e8_store_multiple_2, nds_e8_store_multiple_3,\ --+ nds_e8_store_multiple_4,nds_e8_store_multiple_5, nds_e8_store_multiple_6,\ --+ nds_e8_store_multiple_7,nds_e8_store_multiple_8, nds_e8_store_multiple_12" --+ "nds_e8_branch,\ --+ nds_e8_load, nds_e8_store,\ --+ nds_e8_load_multiple_1,nds_e8_load_multiple_2, nds_e8_load_multiple_3,\ --+ nds_e8_load_multiple_4,nds_e8_load_multiple_5, nds_e8_load_multiple_6,\ --+ nds_e8_load_multiple_7,nds_e8_load_multiple_8, nds_e8_load_multiple_12,\ --+ nds_e8_store_multiple_1,nds_e8_store_multiple_2, nds_e8_store_multiple_3,\ --+ nds_e8_store_multiple_4,nds_e8_store_multiple_5, nds_e8_store_multiple_6,\ --+ nds_e8_store_multiple_7,nds_e8_store_multiple_8, nds_e8_store_multiple_12" --+ "nds32_e8_ex_to_ii_p" --+) --+ --+;; LMW(N, N) -> ADDR_IN_MOP(1) --+(define_bypass 2 --+ "nds_e8_load_multiple_1,nds_e8_load_multiple_2, nds_e8_load_multiple_3,\ --+ nds_e8_load_multiple_4,nds_e8_load_multiple_5, nds_e8_load_multiple_6,\ --+ nds_e8_load_multiple_7,nds_e8_load_multiple_8, nds_e8_load_multiple_12" --+ "nds_e8_branch,\ --+ nds_e8_load, nds_e8_store,\ --+ nds_e8_load_multiple_1,nds_e8_load_multiple_2, nds_e8_load_multiple_3,\ --+ nds_e8_load_multiple_4,nds_e8_load_multiple_5, nds_e8_load_multiple_6,\ --+ nds_e8_load_multiple_7,nds_e8_load_multiple_8, nds_e8_load_multiple_12,\ --+ nds_e8_store_multiple_1,nds_e8_store_multiple_2, nds_e8_store_multiple_3,\ --+ nds_e8_store_multiple_4,nds_e8_store_multiple_5, nds_e8_store_multiple_6,\ --+ nds_e8_store_multiple_7,nds_e8_store_multiple_8, nds_e8_store_multiple_12" --+ "nds32_e8_last_load_to_ii_p" --+) --+ --+;; LMW(N, N) -> ALU, MUL, MAC, DIV, BR_COND, ST, SMW(N, 1) --+(define_bypass 2 --+ "nds_e8_load_multiple_1,nds_e8_load_multiple_2, nds_e8_load_multiple_3,\ --+ nds_e8_load_multiple_4,nds_e8_load_multiple_5, nds_e8_load_multiple_6,\ --+ nds_e8_load_multiple_7,nds_e8_load_multiple_8, nds_e8_load_multiple_12" --+ "nds_e8_alu, --+ nds_e8_mul_fast, nds_e8_mul_slow,\ --+ nds_e8_mac_fast, nds_e8_mac_slow,\ --+ nds_e8_div,\ --+ nds_e8_branch,\ --+ nds_e8_store,\ --+ nds_e8_store_multiple_1,nds_e8_store_multiple_2, nds_e8_store_multiple_3,\ --+ nds_e8_store_multiple_4,nds_e8_store_multiple_5, nds_e8_store_multiple_6,\ --+ nds_e8_store_multiple_7,nds_e8_store_multiple_8, nds_e8_store_multiple_12" --+ "nds32_e8_last_load_to_ex_p" --+) --diff --git a/gcc/config/nds32/nds32-elf.opt b/gcc/config/nds32/nds32-elf.opt --new file mode 100644 --index 0000000..afe6aad ----- /dev/null --+++ b/gcc/config/nds32/nds32-elf.opt --@@ -0,0 +1,16 @@ --+mcmodel= --+Target RejectNegative Joined Enum(nds32_cmodel_type) Var(nds32_cmodel_option) Init(CMODEL_MEDIUM) --+Specify the address generation strategy for code model. --+ --+Enum --+Name(nds32_cmodel_type) Type(enum nds32_cmodel_type) --+Known cmodel types (for use with the -mcmodel= option): --+ --+EnumValue --+Enum(nds32_cmodel_type) String(small) Value(CMODEL_SMALL) --+ --+EnumValue --+Enum(nds32_cmodel_type) String(medium) Value(CMODEL_MEDIUM) --+ --+EnumValue --+Enum(nds32_cmodel_type) String(large) Value(CMODEL_LARGE) --diff --git a/gcc/config/nds32/nds32-fp-as-gp.c b/gcc/config/nds32/nds32-fp-as-gp.c --index f8b2738..6525915 100644 ----- a/gcc/config/nds32/nds32-fp-as-gp.c --+++ b/gcc/config/nds32/nds32-fp-as-gp.c --@@ -1,4 +1,4 @@ ---/* The fp-as-gp pass of Andes NDS32 cpu for GNU compiler --+/* fp-as-gp pass of Andes NDS32 cpu for GNU compiler -- Copyright (C) 2012-2016 Free Software Foundation, Inc. -- Contributed by Andes Technology Corporation. -- --@@ -24,19 +24,280 @@ -- #include "system.h" -- #include "coretypes.h" -- #include "backend.h" --+#include "tree.h" --+#include "rtl.h" --+#include "df.h" --+#include "alias.h" --+#include "stor-layout.h" --+#include "varasm.h" --+#include "calls.h" --+#include "regs.h" --+#include "insn-config.h" /* Required by recog.h. */ --+#include "conditions.h" --+#include "output.h" --+#include "insn-attr.h" /* For DFA state_t. */ --+#include "insn-codes.h" /* For CODE_FOR_xxx. */ --+#include "reload.h" /* For push_reload(). */ --+#include "flags.h" --+#include "insn-config.h" --+#include "expmed.h" --+#include "dojump.h" --+#include "explow.h" --+#include "emit-rtl.h" --+#include "stmt.h" --+#include "expr.h" --+#include "recog.h" --+#include "diagnostic-core.h" --+#include "cfgrtl.h" --+#include "cfganal.h" --+#include "lcm.h" --+#include "cfgbuild.h" --+#include "cfgcleanup.h" --+#include "tm_p.h" --+#include "tm-constrs.h" --+#include "optabs.h" /* For GEN_FCN. */ --+#include "target.h" --+#include "langhooks.h" /* For add_builtin_function(). */ --+#include "builtins.h" --+#include "ira.h" --+#include "ira-int.h" --+#include "tree-pass.h" -- -- /* ------------------------------------------------------------------------ */ -- --+/* A helper function to check if this function should contain prologue. */ --+static bool --+nds32_have_prologue_p (void) --+{ --+ int i; --+ --+ for (i = 0; i < 28; i++) --+ if (NDS32_REQUIRED_CALLEE_SAVED_P (i)) --+ return true; --+ --+ return (flag_pic --+ || NDS32_REQUIRED_CALLEE_SAVED_P (FP_REGNUM) --+ || NDS32_REQUIRED_CALLEE_SAVED_P (LP_REGNUM)); --+} --+ --+static int --+nds32_get_symbol_count (void) --+{ --+ int symbol_count = 0; --+ rtx_insn *insn; --+ basic_block bb; --+ --+ FOR_EACH_BB_FN (bb, cfun) --+ { --+ FOR_BB_INSNS (bb, insn) --+ { --+ /* Counting the insn number which the addressing mode is symbol. */ --+ if (single_set (insn) && nds32_symbol_load_store_p (insn)) --+ { --+ rtx pattern = PATTERN (insn); --+ rtx mem; --+ gcc_assert (GET_CODE (pattern) == SET); --+ if (GET_CODE (SET_SRC (pattern)) == REG ) --+ mem = SET_DEST (pattern); --+ else --+ mem = SET_SRC (pattern); --+ --+ /* We have only lwi37 and swi37 for fp-as-gp optimization, --+ so don't count any other than SImode. --+ MEM for QImode and HImode will wrap by ZERO_EXTEND --+ or SIGN_EXTEND */ --+ if (GET_CODE (mem) == MEM) --+ symbol_count++; --+ } --+ } --+ } --+ --+ return symbol_count; --+} --+ -- /* Function to determine whether it is worth to do fp_as_gp optimization. --- Return 0: It is NOT worth to do fp_as_gp optimization. --- Return 1: It is APPROXIMATELY worth to do fp_as_gp optimization. --+ Return false: It is NOT worth to do fp_as_gp optimization. --+ Return true: It is APPROXIMATELY worth to do fp_as_gp optimization. -- Note that if it is worth to do fp_as_gp optimization, -- we MUST set FP_REGNUM ever live in this function. */ ---int --+static bool -- nds32_fp_as_gp_check_available (void) -- { --- /* By default we return 0. */ --- return 0; --+ basic_block bb; --+ basic_block exit_bb; --+ edge_iterator ei; --+ edge e; --+ bool first_exit_blocks_p; --+ --+ /* If there exists ANY of following conditions, --+ we DO NOT perform fp_as_gp optimization: --+ 1. TARGET_FORBID_FP_AS_GP is set --+ regardless of the TARGET_FORCE_FP_AS_GP. --+ 2. User explicitly uses 'naked'/'no_prologue' attribute. --+ We use nds32_naked_function_p() to help such checking. --+ 3. Not optimize for size. --+ 4. Need frame pointer. --+ 5. If $fp is already required to be saved, --+ it means $fp is already choosen by register allocator. --+ Thus we better not to use it for fp_as_gp optimization. --+ 6. This function is a vararg function. --+ DO NOT apply fp_as_gp optimization on this function --+ because it may change and break stack frame. --+ 7. The epilogue is empty. --+ This happens when the function uses exit() --+ or its attribute is no_return. --+ In that case, compiler will not expand epilogue --+ so that we have no chance to output .omit_fp_end directive. */ --+ if (TARGET_FORBID_FP_AS_GP --+ || nds32_naked_function_p (current_function_decl) --+ || !optimize_size --+ || frame_pointer_needed --+ || NDS32_REQUIRED_CALLEE_SAVED_P (FP_REGNUM) --+ || (cfun->stdarg == 1) --+ || (find_fallthru_edge (EXIT_BLOCK_PTR_FOR_FN (cfun)->preds) == NULL)) --+ return false; --+ --+ /* Disable fp_as_gp if there is any infinite loop since the fp may --+ reuse in infinite loops by register rename. --+ For check infinite loops we should make sure exit_bb is post dominate --+ all other basic blocks if there is no infinite loops. */ --+ first_exit_blocks_p = true; --+ exit_bb = NULL; --+ --+ FOR_EACH_EDGE (e, ei, EXIT_BLOCK_PTR_FOR_FN (cfun)->preds) --+ { --+ /* More than one exit block also do not perform fp_as_gp optimization. */ --+ if (!first_exit_blocks_p) --+ return false; --+ --+ exit_bb = e->src; --+ first_exit_blocks_p = false; --+ } --+ --+ /* Not found exit_bb? just abort fp_as_gp! */ --+ if (!exit_bb) --+ return false; --+ --+ /* Each bb should post dominate by exit_bb if there is no infinite loop! */ --+ FOR_EACH_BB_FN (bb, cfun) --+ { --+ if (!dominated_by_p (CDI_POST_DOMINATORS, --+ bb, --+ exit_bb)) --+ return false; --+ } --+ --+ /* Now we can check the possibility of using fp_as_gp optimization. */ --+ if (TARGET_FORCE_FP_AS_GP) --+ { --+ /* User explicitly issues -mforce-fp-as-gp option. */ --+ return true; --+ } --+ else --+ { --+ /* In the following we are going to evaluate whether --+ it is worth to do fp_as_gp optimization. */ --+ bool good_gain = false; --+ int symbol_count; --+ --+ int threshold; --+ --+ /* We check if there already requires prologue. --+ Note that $gp will be saved in prologue for PIC code generation. --+ After that, we can set threshold by the existence of prologue. --+ Each fp-implied instruction will gain 2-byte code size --+ from gp-aware instruction, so we have following heuristics. */ --+ if (flag_pic --+ || nds32_have_prologue_p ()) --+ { --+ /* Have-prologue: --+ Compiler already intends to generate prologue content, --+ so the fp_as_gp optimization will only insert --+ 'la $fp,_FP_BASE_' instruction, which will be --+ converted into 4-byte instruction at link time. --+ The threshold is "3" symbol accesses, 2 + 2 + 2 > 4. */ --+ threshold = 3; --+ } --+ else --+ { --+ /* None-prologue: --+ Compiler originally does not generate prologue content, --+ so the fp_as_gp optimization will NOT ONLY insert --+ 'la $fp,_FP_BASE' instruction, but also causes --+ push/pop instructions. --+ If we are using v3push (push25/pop25), --+ the threshold is "5" symbol accesses, 5*2 > 4 + 2 + 2; --+ If we are using normal push (smw/lmw), --+ the threshold is "5+2" symbol accesses 7*2 > 4 + 4 + 4. */ --+ threshold = 5 + (TARGET_V3PUSH ? 0 : 2); --+ } --+ --+ symbol_count = nds32_get_symbol_count (); --+ --+ if (symbol_count >= threshold) --+ good_gain = true; --+ --+ /* Enable fp_as_gp optimization when potential gain is good enough. */ --+ return good_gain; --+ } --+} --+ --+static unsigned int --+nds32_fp_as_gp (void) --+{ --+ bool fp_as_gp_p; --+ calculate_dominance_info (CDI_POST_DOMINATORS); --+ fp_as_gp_p = nds32_fp_as_gp_check_available (); --+ --+ /* Here is a hack to IRA for enable/disable a hard register per function. --+ We *MUST* review this way after migrate gcc 4.9! */ --+ if (fp_as_gp_p) { --+ SET_HARD_REG_BIT(this_target_ira_int->x_no_unit_alloc_regs, FP_REGNUM); --+ df_set_regs_ever_live (FP_REGNUM, 1); --+ } else { --+ CLEAR_HARD_REG_BIT(this_target_ira_int->x_no_unit_alloc_regs, FP_REGNUM); --+ } --+ --+ cfun->machine->fp_as_gp_p = fp_as_gp_p; --+ --+ free_dominance_info (CDI_POST_DOMINATORS); --+ return 1; --+} --+ --+const pass_data pass_data_nds32_fp_as_gp = --+{ --+ RTL_PASS, /* type */ --+ "fp_as_gp", /* name */ --+ OPTGROUP_NONE, /* optinfo_flags */ --+ TV_MACH_DEP, /* tv_id */ --+ 0, /* properties_required */ --+ 0, /* properties_provided */ --+ 0, /* properties_destroyed */ --+ 0, /* todo_flags_start */ --+ 0 /* todo_flags_finish */ --+}; --+ --+class pass_nds32_fp_as_gp : public rtl_opt_pass --+{ --+public: --+ pass_nds32_fp_as_gp (gcc::context *ctxt) --+ : rtl_opt_pass (pass_data_nds32_fp_as_gp, ctxt) --+ {} --+ --+ /* opt_pass methods: */ --+ bool gate (function *) --+ { --+ return !TARGET_LINUX_ABI --+ && TARGET_16_BIT --+ && optimize_size; --+ } --+ unsigned int execute (function *) { return nds32_fp_as_gp (); } --+}; --+ --+rtl_opt_pass * --+make_pass_nds32_fp_as_gp (gcc::context *ctxt) --+{ --+ return new pass_nds32_fp_as_gp (ctxt); -- } -- -- /* ------------------------------------------------------------------------ */ --diff --git a/gcc/config/nds32/nds32-fpu.md b/gcc/config/nds32/nds32-fpu.md --new file mode 100644 --index 0000000..11eabd5 ----- /dev/null --+++ b/gcc/config/nds32/nds32-fpu.md --@@ -0,0 +1,503 @@ --+;; Machine description of Andes NDS32 cpu for GNU compiler --+;; Copyright (C) 2012-2016 Free Software Foundation, Inc. --+;; Contributed by Andes Technology Corporation. --+;; --+;; This file is part of GCC. --+;; --+;; GCC is free software; you can redistribute it and/or modify it --+;; under the terms of the GNU General Public License as published --+;; by the Free Software Foundation; either version 3, or (at your --+;; option) any later version. --+;; --+;; GCC is distributed in the hope that it will be useful, but WITHOUT --+;; ANY WARRANTY; without even the implied warranty of MERCHANTABILITY --+;; or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public --+;; License for more details. --+;; --+;; You should have received a copy of the GNU General Public License --+;; along with GCC; see the file COPYING3. If not see --+;; . --+ --+;;SFmode moves --+ --+(define_expand "movsf" --+ [(set (match_operand:SF 0 "general_operand" "") --+ (match_operand:SF 1 "general_operand" ""))] --+ "" --+{ --+ /* Need to force register if mem <- !reg. */ --+ if (MEM_P (operands[0]) && !REG_P (operands[1])) --+ operands[1] = force_reg (SFmode, operands[1]); --+ if (CONST_DOUBLE_P (operands[1]) --+ && !satisfies_constraint_Cs20 (operands[1])) --+ { --+ const REAL_VALUE_TYPE *r; --+ unsigned long l; --+ --+ r = CONST_DOUBLE_REAL_VALUE (operands[1]); --+ REAL_VALUE_TO_TARGET_SINGLE (*r, l); --+ --+ emit_move_insn (operands[0], gen_rtx_HIGH (SFmode, operands[1])); --+ --+ if ((l & 0xFFF) != 0) --+ emit_insn (gen_movsf_lo (operands[0], operands[0], operands[1])); --+ DONE; --+ } --+}) --+ --+(define_insn "movsf_lo" --+ [(set (match_operand:SF 0 "register_operand" "=r") --+ (lo_sum:SF (match_operand:SF 1 "register_operand" "r") --+ (match_operand:SF 2 "immediate_operand" "i")))] --+ "" --+ "ori\t%0, %1, lo12(%2)" --+ [(set_attr "type" "alu") --+ (set_attr "length" "4")] --+) --+ --+(define_insn "*movsf" --+ [(set (match_operand:SF 0 "nonimmediate_operand" "=r, r, U45, U33, U37, U45, m, l, l, l, d, r, f, *f, *r, f, Q, r, r, r") --+ (match_operand:SF 1 "general_operand" " r, r, l, l, l, d, r, U45, U33, U37, U45, m, f, *r, *f, Q, f,Cs05,Cs20, Chig"))] --+ "(register_operand(operands[0], SFmode) --+ || register_operand(operands[1], SFmode))" --+{ --+ switch (which_alternative) --+ { --+ case 0: --+ return "mov55\t%0, %1"; --+ case 1: --+ return "ori\t%0, %1, 0"; --+ case 2: --+ case 3: --+ case 4: --+ case 5: --+ return nds32_output_16bit_store (operands, 4); --+ case 6: --+ return nds32_output_32bit_store (operands, 4); --+ case 7: --+ case 8: --+ case 9: --+ case 10: --+ return nds32_output_16bit_load (operands, 4); --+ case 11: --+ return nds32_output_32bit_load (operands, 4); --+ case 12: --+ if (TARGET_FPU_SINGLE) --+ return "fcpyss\t%0, %1, %1"; --+ else --+ return "#"; --+ case 13: --+ return "fmtsr\t%1, %0"; --+ case 14: --+ return "fmfsr\t%0, %1"; --+ case 15: --+ return nds32_output_float_load (operands); --+ case 16: --+ return nds32_output_float_store (operands); --+ case 17: --+ return "movi55\t%0, %1"; --+ case 18: --+ return "movi\t%0, %1"; --+ case 19: --+ return "sethi\t%0, %1"; --+ default: --+ gcc_unreachable (); --+ } --+} --+ [(set_attr "type" "alu,alu,store,store,store,store,store,load,load,load,load,load,fcpy,fmtsr,fmfsr,fload,fstore,alu,alu,alu") --+ (set_attr "length" " 2, 4, 2, 2, 2, 2, 4, 2, 2, 2, 2, 4, 4, 4, 4, 4, 4, 2, 4, 4") --+ (set_attr "feature" " v1, v1, v1, v1, v1, v1, v1, v1, v1, v1, v1, v1, fpu, fpu, fpu, fpu, fpu, v1, v1, v1")]) --+ --+;; Conditional Move Instructions --+ --+(define_expand "movcc" --+ [(set (match_operand:ANYF 0 "register_operand" "") --+ (if_then_else:ANYF (match_operand 1 "nds32_float_comparison_operator" "") --+ (match_operand:ANYF 2 "register_operand" "") --+ (match_operand:ANYF 3 "register_operand" "")))] --+ "" --+{ --+ if (nds32_cond_move_p (operands[1])) --+ { --+ /* Operands[1] condition code is UNORDERED or ORDERED, and --+ sub-operands[1] MODE isn't SFmode or SFmode, return FAIL --+ for gcc, because we don't using slt compare instruction --+ to generate UNORDERED and ORDERED condition. */ --+ FAIL; --+ } --+ else --+ nds32_expand_float_movcc (operands); --+}) --+ --+(define_insn "fcmov_eq" --+ [(set (match_operand:ANYF 0 "register_operand" "=f, f") --+ (if_then_else:ANYF (eq (match_operand:SI 1 "register_operand" "f, f") --+ (const_int 0)) --+ (match_operand:ANYF 2 "register_operand" "f, 0") --+ (match_operand:ANYF 3 "register_operand" "0, f")))] --+ "" --+ "@ --+ fcmovz\t%0,%2,%1 --+ fcmovn\t%0,%3,%1" --+ [(set_attr "type" "fcmov") --+ (set_attr "length" "4")] --+) --+ --+(define_insn "fcmov_ne" --+ [(set (match_operand:ANYF 0 "register_operand" "=f, f") --+ (if_then_else:ANYF (ne (match_operand:SI 1 "register_operand" "f, f") --+ (const_int 0)) --+ (match_operand:ANYF 2 "register_operand" "f, 0") --+ (match_operand:ANYF 3 "register_operand" "0, f")))] --+ "" --+ "@ --+ fcmovn\t%0,%2,%1 --+ fcmovz\t%0,%3,%1" --+ [(set_attr "type" "fcmov") --+ (set_attr "length" "4")] --+) --+ --+;; Arithmetic instructions. --+ --+(define_insn "add3" --+ [(set (match_operand:ANYF 0 "register_operand" "=f") --+ (plus:ANYF (match_operand:ANYF 1 "register_operand" "f") --+ (match_operand:ANYF 2 "register_operand" "f")))] --+ "" --+ "fadd\t %0, %1, %2" --+ [(set_attr "type" "falu") --+ (set_attr "length" "4")] --+) --+ --+(define_insn "sub3" --+ [(set (match_operand:ANYF 0 "register_operand" "=f") --+ (minus:ANYF (match_operand:ANYF 1 "register_operand" "f") --+ (match_operand:ANYF 2 "register_operand" "f")))] --+ "" --+ "fsub\t %0, %1, %2" --+ [(set_attr "type" "falu") --+ (set_attr "length" "4")] --+) --+ --+;; Multiplication insns. --+ --+(define_insn "mul3" --+ [(set (match_operand:ANYF 0 "register_operand" "=f") --+ (mult:ANYF (match_operand:ANYF 1 "register_operand" "f") --+ (match_operand:ANYF 2 "register_operand" "f")))] --+ "" --+ "fmul\t %0, %1, %2" --+ [(set_attr "type" "fmul") --+ (set_attr "length" "4")] --+) --+ --+(define_insn "fma4" --+ [(set (match_operand:ANYF 0 "register_operand" "=f") --+ (fma:ANYF (match_operand:ANYF 1 "register_operand" "f") --+ (match_operand:ANYF 2 "register_operand" "f") --+ (match_operand:ANYF 3 "register_operand" "0")))] --+ "TARGET_EXT_FPU_FMA" --+ "fmadd\t%0, %1, %2" --+ [(set_attr "type" "fmac") --+ (set_attr "length" "4")] --+) --+ --+(define_insn "fnma4" --+ [(set (match_operand:ANYF 0 "register_operand" "=f") --+ (fma:ANYF (neg:ANYF (match_operand:ANYF 1 "register_operand" "f")) --+ (match_operand:ANYF 2 "register_operand" "f") --+ (match_operand:ANYF 3 "register_operand" "0")))] --+ "TARGET_EXT_FPU_FMA" --+ "fmsub\t%0, %1, %2" --+ [(set_attr "type" "fmac") --+ (set_attr "length" "4")] --+) --+ --+(define_insn "fms4" --+ [(set (match_operand:ANYF 0 "register_operand" "=f") --+ (fma:ANYF (match_operand:ANYF 1 "register_operand" "f") --+ (match_operand:ANYF 2 "register_operand" "f") --+ (neg:ANYF (match_operand:ANYF 3 "register_operand" "0"))))] --+ "TARGET_EXT_FPU_FMA" --+ "fnmsub\t%0, %1, %2" --+ [(set_attr "type" "fmac") --+ (set_attr "length" "4")] --+) --+ --+(define_insn "fnms4" --+ [(set (match_operand:ANYF 0 "register_operand" "=f") --+ (fma:ANYF (neg:ANYF (match_operand:ANYF 1 "register_operand" "f")) --+ (match_operand:ANYF 2 "register_operand" "f") --+ (neg:ANYF (match_operand:ANYF 3 "register_operand" "0"))))] --+ "TARGET_EXT_FPU_FMA" --+ "fnmadd\t%0, %1, %2" --+ [(set_attr "type" "fmac") --+ (set_attr "length" "4")] --+) --+ --+;; Div Instructions. --+ --+(define_insn "div3" --+ [(set (match_operand:ANYF 0 "register_operand" "=f") --+ (div:ANYF (match_operand:ANYF 1 "register_operand" "f") --+ (match_operand:ANYF 2 "register_operand" "f")))] --+ "" --+ "fdiv\t %0, %1, %2" --+ [(set_attr "type" "fdiv") --+ (set_attr "length" "4")] --+) --+ --+(define_insn "sqrt2" --+ [(set (match_operand:ANYF 0 "register_operand" "=f") --+ (sqrt:ANYF (match_operand:ANYF 1 "register_operand" "f")))] --+ "" --+ "fsqrt\t %0, %1" --+ [(set_attr "type" "fsqrt") --+ (set_attr "length" "4")] --+) --+ --+;; Conditional Branch patterns --+ --+(define_expand "cstore4" --+ [(set (match_operand:SI 0 "register_operand" "") --+ (match_operator:SI 1 "nds32_float_comparison_operator" --+ [(match_operand:ANYF 2 "register_operand" "") --+ (match_operand:ANYF 3 "register_operand" "")]))] --+ "" --+{ --+ nds32_expand_float_cstore (operands); --+ DONE; --+}) --+ --+(define_expand "cbranch4" --+ [(set (pc) --+ (if_then_else (match_operator 0 "nds32_float_comparison_operator" --+ [(match_operand:ANYF 1 "register_operand" "") --+ (match_operand:ANYF 2 "register_operand" "")]) --+ (label_ref (match_operand 3 "" "")) --+ (pc)))] --+ "" --+{ --+ nds32_expand_float_cbranch (operands); --+ DONE; --+}) --+ --+;; Copysign Instructions. --+ --+(define_insn "copysignsf3" --+ [(set (match_operand:SF 0 "register_operand" "=f") --+ (unspec:SF [(match_operand:SF 1 "register_operand" "f") --+ (match_operand:SF 2 "register_operand" "f")] --+ UNSPEC_COPYSIGN))] --+ "TARGET_FPU_SINGLE" --+ "fcpyss\t%0,%1,%2" --+ [(set_attr "type" "fcpy") --+ (set_attr "length" "4")] --+) --+ --+(define_insn "copysigndf3" --+ [(set (match_operand:DF 0 "register_operand" "=f") --+ (unspec:DF [(match_operand:DF 1 "register_operand" "f") --+ (match_operand:DF 2 "register_operand" "f")] --+ UNSPEC_COPYSIGN))] --+ "TARGET_FPU_SINGLE || TARGET_FPU_DOUBLE" --+ "fcpysd\t%0,%1,%2" --+ [(set_attr "type" "fcpy") --+ (set_attr "length" "4")] --+) --+ --+(define_insn "*ncopysign3" --+ [(set (match_operand:ANYF 0 "register_operand" "=f") --+ (neg:ANYF (unspec:ANYF [(match_operand:ANYF 1 "register_operand" "f") --+ (match_operand:ANYF 2 "register_operand" "f")] --+ UNSPEC_COPYSIGN)))] --+ "" --+ "fcpyns\t%0,%1,%2" --+ [(set_attr "type" "fcpy") --+ (set_attr "length" "4")] --+) --+ --+;; Absolute Instructions --+ --+(define_insn "abssf2" --+ [(set (match_operand:SF 0 "register_operand" "=f, r") --+ (abs:SF (match_operand:SF 1 "register_operand" "f, r")))] --+ "TARGET_FPU_SINGLE || TARGET_EXT_PERF" --+ "@ --+ fabss\t%0, %1 --+ bclr\t%0, %1, 31" --+ [(set_attr "type" "fabs,alu") --+ (set_attr "length" "4") --+ (set_attr "feature" "fpu,pe1")] --+) --+ --+(define_insn "absdf2" --+ [(set (match_operand:DF 0 "register_operand" "=f") --+ (abs:DF (match_operand:DF 1 "register_operand" "f")))] --+ "TARGET_FPU_DOUBLE" --+ "fabsd\t%0, %1" --+ [(set_attr "type" "fabs") --+ (set_attr "length" "4")] --+) --+ --+;; Negation Instructions --+ --+(define_insn "*negsf2" --+ [(set (match_operand:SF 0 "register_operand" "=f, r") --+ (neg:SF (match_operand:SF 1 "register_operand" "f, r")))] --+ "TARGET_FPU_SINGLE || TARGET_EXT_PERF" --+ "@ --+ fcpynss\t%0, %1, %1 --+ btgl\t%0, %1, 31" --+ [(set_attr "type" "fcpy,alu") --+ (set_attr "length" "4") --+ (set_attr "feature" "fpu,pe1")] --+) --+ --+(define_insn "*negdf2" --+ [(set (match_operand:DF 0 "register_operand" "=f") --+ (neg:DF (match_operand:DF 1 "register_operand" "f")))] --+ "TARGET_FPU_DOUBLE" --+ "fcpynsd\t%0, %1, %1" --+ [(set_attr "type" "fcpy") --+ (set_attr "length" "4")] --+) --+ --+;; Data Format Conversion Instructions --+ --+(define_insn "floatunssi2" --+ [(set (match_operand:ANYF 0 "register_operand" "=f") --+ (unsigned_float:ANYF (match_operand:SI 1 "register_operand" "f")))] --+ "" --+ "fui2\t %0, %1" --+ [(set_attr "type" "falu") --+ (set_attr "length" "4")] --+) --+ --+(define_insn "floatsi2" --+ [(set (match_operand:ANYF 0 "register_operand" "=f") --+ (float:ANYF (match_operand:SI 1 "register_operand" "f")))] --+ "" --+ "fsi2\t %0, %1" --+ [(set_attr "type" "falu") --+ (set_attr "length" "4")] --+) --+ --+(define_insn "fixuns_truncsi2" --+ [(set (match_operand:SI 0 "register_operand" "=f") --+ (unsigned_fix:SI (fix:ANYF (match_operand:ANYF 1 "register_operand" "f"))))] --+ "" --+ "f2ui.z\t %0, %1" --+ [(set_attr "type" "falu") --+ (set_attr "length" "4")] --+) --+ --+(define_insn "fix_truncsi2" --+ [(set (match_operand:SI 0 "register_operand" "=f") --+ (fix:SI (fix:ANYF (match_operand:ANYF 1 "register_operand" "f"))))] --+ "" --+ "f2si.z\t %0, %1" --+ [(set_attr "type" "falu") --+ (set_attr "length" "4")] --+) --+ --+(define_insn "extendsfdf2" --+ [(set (match_operand:DF 0 "register_operand" "=f") --+ (float_extend:DF (match_operand:SF 1 "register_operand" "f")))] --+ "TARGET_FPU_SINGLE && TARGET_FPU_DOUBLE" --+ "fs2d\t%0, %1" --+ [(set_attr "type" "falu") --+ (set_attr "length" "4")] --+) --+ --+(define_insn "truncdfsf2" --+ [(set (match_operand:SF 0 "register_operand" "=f") --+ (float_truncate:SF (match_operand:DF 1 "register_operand" "f")))] --+ "TARGET_FPU_SINGLE && TARGET_FPU_DOUBLE" --+ "fd2s\t%0, %1" --+ [(set_attr "type" "falu") --+ (set_attr "length" "4")] --+) --+ --+;; Compare Instructions --+ --+(define_insn "cmp_eq" --+ [(set (match_operand:SI 0 "register_operand" "=f") --+ (eq:SI (match_operand:ANYF 1 "register_operand" "f") --+ (match_operand:ANYF 2 "register_operand" "f")))] --+ "" --+ { --+ if (NDS32_EXT_FPU_DOT_E) --+ return "fcmpeq.e %0, %1, %2"; --+ else --+ return "fcmpeq\t%0, %1, %2"; --+ } --+ [(set_attr "type" "fcmp") --+ (set_attr "length" "4")] --+) --+ --+(define_insn "cmp_lt" --+ [(set (match_operand:SI 0 "register_operand" "=f") --+ (lt:SI (match_operand:ANYF 1 "register_operand" "f") --+ (match_operand:ANYF 2 "register_operand" "f")))] --+ "" --+{ --+ if (NDS32_EXT_FPU_DOT_E) --+ return "fcmplt.e %0, %1, %2"; --+ else --+ return "fcmplt\t%0, %1, %2"; --+} --+ [(set_attr "type" "fcmp") --+ (set_attr "length" "4")] --+) --+ --+(define_insn "cmp_le" --+ [(set (match_operand:SI 0 "register_operand" "=f") --+ (le:SI (match_operand:ANYF 1 "register_operand" "f") --+ (match_operand:ANYF 2 "register_operand" "f")))] --+ "" --+{ --+ if (NDS32_EXT_FPU_DOT_E) --+ return "fcmple.e %0, %1, %2"; --+ else --+ return "fcmple\t%0, %1, %2"; --+} --+ [(set_attr "type" "fcmp") --+ (set_attr "length" "4")] --+) --+ --+(define_insn "cmp_un" --+ [(set (match_operand:SI 0 "register_operand" "=f") --+ (unordered:SI (match_operand:ANYF 1 "register_operand" "f") --+ (match_operand:ANYF 2 "register_operand" "f")))] --+ "" --+{ --+ if (NDS32_EXT_FPU_DOT_E) --+ return "fcmpun.e %0, %1, %2"; --+ else --+ return "fcmpun\t%0, %1, %2"; --+} --+ [(set_attr "type" "fcmp") --+ (set_attr "length" "4")] --+) --+ --+(define_split --+ [(set (match_operand:SF 0 "register_operand" "") --+ (match_operand:SF 1 "register_operand" ""))] --+ "!TARGET_FPU_SINGLE --+ && NDS32_IS_FPR_REGNUM (REGNO (operands[0])) --+ && NDS32_IS_FPR_REGNUM (REGNO (operands[1]))" --+ [(set (match_dup 2) (match_dup 1)) --+ (set (match_dup 0) (match_dup 2))] --+{ --+ operands[2] = gen_rtx_REG (SFmode, TA_REGNUM); --+}) --+ --+(define_split --+ [(set (match_operand:SF 0 "register_operand" "") --+ (match_operand:SF 1 "const_double_operand" ""))] --+ "!satisfies_constraint_Cs20 (operands[1]) --+ && !satisfies_constraint_Chig (operands[1])" --+ [(set (match_dup 0) (high:SF (match_dup 1))) --+ (set (match_dup 0) (lo_sum:SF (match_dup 0) (match_dup 1)))]) --+;; ---------------------------------------------------------------------------- --diff --git a/gcc/config/nds32/nds32-gcse.c b/gcc/config/nds32/nds32-gcse.c --new file mode 100644 --index 0000000..301981d ----- /dev/null --+++ b/gcc/config/nds32/nds32-gcse.c --@@ -0,0 +1,670 @@ --+/* Global CSE pass of Andes NDS32 cpu for GNU compiler --+ Copyright (C) 2012-2016 Free Software Foundation, Inc. --+ Contributed by Andes Technology Corporation. --+ --+ This file is part of GCC. --+ --+ GCC is free software; you can redistribute it and/or modify it --+ under the terms of the GNU General Public License as published --+ by the Free Software Foundation; either version 3, or (at your --+ option) any later version. --+ --+ GCC is distributed in the hope that it will be useful, but WITHOUT --+ ANY WARRANTY; without even the implied warranty of MERCHANTABILITY --+ or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public --+ License for more details. --+ --+ You should have received a copy of the GNU General Public License --+ along with GCC; see the file COPYING3. If not see --+ . */ --+ --+/* ------------------------------------------------------------------------ */ --+ --+#include "config.h" --+#include "system.h" --+#include "coretypes.h" --+#include "backend.h" --+#include "tree.h" --+#include "rtl.h" --+#include "df.h" --+#include "alias.h" --+#include "stor-layout.h" --+#include "varasm.h" --+#include "calls.h" --+#include "regs.h" --+#include "insn-config.h" /* Required by recog.h. */ --+#include "conditions.h" --+#include "output.h" --+#include "insn-attr.h" /* For DFA state_t. */ --+#include "insn-codes.h" /* For CODE_FOR_xxx. */ --+#include "reload.h" /* For push_reload(). */ --+#include "flags.h" --+#include "insn-config.h" --+#include "expmed.h" --+#include "dojump.h" --+#include "explow.h" --+#include "emit-rtl.h" --+#include "stmt.h" --+#include "expr.h" --+#include "recog.h" --+#include "diagnostic-core.h" --+#include "cfgrtl.h" --+#include "cfganal.h" --+#include "lcm.h" --+#include "cfgbuild.h" --+#include "cfgcleanup.h" --+#include "tm_p.h" --+#include "tm-constrs.h" --+#include "optabs.h" /* For GEN_FCN. */ --+#include "target.h" --+#include "langhooks.h" /* For add_builtin_function(). */ --+#include "builtins.h" --+#include "cpplib.h" --+#include "params.h" --+#include "tree-pass.h" --+#include "dbgcnt.h" --+#include "df.h" --+#include "reload.h" --+ --+/* ------------------------------------------------------------------------ */ --+ --+struct expr --+{ --+ /* The expression. */ --+ rtx expr; --+ --+ /* The same hash for this entry. */ --+ hashval_t hash; --+ --+ struct occr *antic_occr; --+ /* The number of antic_occr. */ --+ unsigned int count; --+}; --+ --+struct occr --+{ --+ /* Next occurrence of this expression. */ --+ struct occr *next; --+ /* The insn that computes the expression. */ --+ rtx_insn *insn; --+ /* Nonzero if this [anticipatable] occurrence has been deleted. */ --+ char deleted_p; --+}; --+ --+struct reg_avail_info --+{ --+ basic_block last_bb; --+ int first_set; --+ int first_use; --+}; --+ --+/* Hashtable helpers. */ --+ --+struct expr_hasher : nofree_ptr_hash --+{ --+ static inline hashval_t hash (const expr *); --+ static inline bool equal (const expr *, const expr *); --+}; --+ --+/* Callback for hashtab. --+ Return the hash value for expression EXP. We don't actually hash --+ here, we just return the cached hash value. */ --+ --+inline hashval_t --+expr_hasher::hash (const expr *exp) --+{ --+ return exp->hash; --+} --+ --+/* Callback for hashtab. --+ Return nonzero if exp1 is equivalent to exp2. */ --+ --+inline bool --+expr_hasher::equal (const expr *exp1, const expr *exp2) --+{ --+ int equiv_p = exp_equiv_p (exp1->expr, exp2->expr, 0, true); --+ --+ gcc_assert (!equiv_p || exp1->hash == exp2->hash); --+ return equiv_p; --+} --+ --+static hashval_t --+hash_expr (rtx x, int *do_not_record_p) --+{ --+ *do_not_record_p = 0; --+ return hash_rtx (x, GET_MODE (x), do_not_record_p, --+ NULL, /*have_reg_qty=*/false); --+} --+ --+ --+/* Helpers for memory allocation/freeing. */ --+static void alloc_mem (void); --+static void free_mem (void); --+static void compute_hash_table (void); --+/* Scan the pattern of INSN and add an entry to the hash TABLE. --+ After reload we are interested in loads/stores only. */ --+static void hash_scan_set (rtx_insn *); --+static void insert_expr_in_table (rtx, rtx_insn *); --+static void dump_hash_table (FILE *); --+ --+static struct obstack expr_obstack; --+/* The table itself. */ --+static hash_table *expr_table; --+static struct reg_avail_info *reg_avail_info; --+static sbitmap *hoist_vbein; --+static sbitmap *hoist_vbeout; --+ --+/* Allocate memory for the CUID mapping array and register/memory --+ tracking tables. */ --+ --+static void --+alloc_mem (void) --+{ --+ /* Allocate the available expressions hash table. We don't want to --+ make the hash table too small, but unnecessarily making it too large --+ also doesn't help. The i/4 is a gcse.c relic, and seems like a --+ reasonable choice. */ --+ expr_table = new hash_table (MAX (get_max_insn_count () / 4, --+ 13)); --+ --+ /* We allocate everything on obstacks because we often can roll back --+ the whole obstack to some point. Freeing obstacks is very fast. */ --+ gcc_obstack_init (&expr_obstack); --+} --+ --+/* Free memory allocated by alloc_mem. */ --+ --+static void --+free_mem (void) --+{ --+ delete expr_table; --+ expr_table = NULL; --+ --+ obstack_free (&expr_obstack, NULL); --+} --+ --+ --+/* Dump all expressions and occurrences that are currently in the --+ expression hash table to FILE. */ --+ --+/* This helper is called via htab_traverse. */ --+int --+nds32_dump_expr_hash_table_entry (expr **slot, FILE *file) --+{ --+ struct expr *exprs = *slot; --+ struct occr *occr; --+ --+ fprintf (file, "expr: "); --+ print_rtl (file, exprs->expr); --+ fprintf (file,"\nhashcode: %u\n", exprs->hash); --+ fprintf (file,"list of occurrences:\n"); --+ occr = exprs->antic_occr; --+ while (occr) --+ { --+ rtx_insn *insn = occr->insn; --+ print_rtl_single (file, insn); --+ fprintf (file, "\n"); --+ occr = occr->next; --+ } --+ fprintf (file, "\n"); --+ return 1; --+} --+ --+static void --+dump_hash_table (FILE *file) --+{ --+ fprintf (file, "\n\nexpression hash table\n"); --+ fprintf (file, "size %ld, %ld elements, %f collision/search ratio\n", --+ (long) expr_table->size (), --+ (long) expr_table->elements (), --+ expr_table->collisions ()); --+ if (expr_table->elements () > 0) --+ { --+ fprintf (file, "\n\ntable entries:\n"); --+ expr_table->traverse (file); --+ } --+ fprintf (file, "\n"); --+} --+ --+/* Insert expression X in INSN in the hash TABLE. --+ If it is already present, record it as the last occurrence in INSN's --+ basic block. */ --+ --+static void --+insert_expr_in_table (rtx x, rtx_insn *insn) --+{ --+ int do_not_record_p; --+ hashval_t hash; --+ struct expr *cur_expr, **slot; --+ struct occr *antic_occr, *last_occr = NULL; --+ --+ hash = hash_expr (x, &do_not_record_p); --+ --+ /* Do not insert expression in the table if it contains volatile operands, --+ or if hash_expr determines the expression is something we don't want --+ to or can't handle. */ --+ if (do_not_record_p) --+ return; --+ --+ /* We anticipate that redundant expressions are rare, so for convenience --+ allocate a new hash table element here already and set its fields. --+ If we don't do this, we need a hack with a static struct expr. Anyway, --+ obstack_free is really fast and one more obstack_alloc doesn't hurt if --+ we're going to see more expressions later on. */ --+ cur_expr = (struct expr *) obstack_alloc (&expr_obstack, --+ sizeof (struct expr)); --+ cur_expr->expr = x; --+ cur_expr->hash = hash; --+ cur_expr->antic_occr = NULL; --+ --+ slot = expr_table->find_slot_with_hash (cur_expr, hash, INSERT); --+ --+ if (! (*slot)) --+ /* The expression isn't found, so insert it. */ --+ *slot = cur_expr; --+ else --+ { --+ /* The expression is already in the table, so roll back the --+ obstack and use the existing table entry. */ --+ obstack_free (&expr_obstack, cur_expr); --+ cur_expr = *slot; --+ } --+ --+ /* Search for another occurrence in the same basic block. */ --+ antic_occr = cur_expr->antic_occr; --+ cur_expr->count++; --+ while (antic_occr --+ && BLOCK_FOR_INSN (antic_occr->insn) != BLOCK_FOR_INSN (insn)) --+ { --+ /* If an occurrence isn't found, save a pointer to the end of --+ the list. */ --+ last_occr = antic_occr; --+ antic_occr = antic_occr->next; --+ } --+ --+ if (antic_occr) --+ /* Found another instance of the expression in the same basic block. --+ Prefer this occurrence to the currently recorded one. We want --+ the last one in the block and the block is scanned from start --+ to end. */ --+ antic_occr->insn = insn; --+ else --+ { --+ /* First occurrence of this expression in this basic block. */ --+ antic_occr = (struct occr *) obstack_alloc (&expr_obstack, --+ sizeof (struct occr)); --+ --+ /* First occurrence of this expression in any block? */ --+ if (cur_expr->antic_occr == NULL) --+ cur_expr->antic_occr = antic_occr; --+ else --+ last_occr->next = antic_occr; --+ --+ antic_occr->insn = insn; --+ antic_occr->next = NULL; --+ antic_occr->deleted_p = 0; --+ } --+} --+ --+/* Check whether this instruction is supported format. */ --+ --+static void --+hash_scan_set (rtx_insn *insn) --+{ --+ rtx pat = PATTERN (insn); --+ rtx src = SET_SRC (pat); --+ rtx dest = SET_DEST (pat); --+ int regno; --+ struct reg_avail_info *info; --+ --+ /* Don't mess with jumps and nops. */ --+ if (JUMP_P (insn) || set_noop_p (pat)) --+ return; --+ --+ /* TODO: support more format. */ --+ --+ /* Only consider locally anticipatable intructions currently. */ --+ if (REG_P (dest) && REGNO (dest) <= SP_REGNUM) --+ { --+ regno = REGNO (dest); --+ info = ®_avail_info[regno]; --+ --+ if (BLOCK_FOR_INSN (insn) == info->last_bb --+ && info->first_set == DF_INSN_LUID (insn) --+ && info->first_use >= info->first_set) --+ { --+ /* Only support immediate input currently because --+ this is bugzilla case. */ --+ if (CONST_INT_P (src) || CONST_DOUBLE_P (src)) --+ insert_expr_in_table (PATTERN (insn), insn); --+ } --+ } --+} --+ --+/* Record register first use information for REGNO in INSN. --+ --+ first_use records the first place in the block where the register --+ is used and is used to compute "anticipatability". --+ --+ last_bb records the block for which first_use is valid, --+ as a quick test to invalidate them. */ --+ --+static void --+record_first_reg_use_info (rtx_insn *insn, int regno) --+{ --+ struct reg_avail_info *info = ®_avail_info[regno]; --+ int luid = DF_INSN_LUID (insn); --+ --+ if (info->last_bb != BLOCK_FOR_INSN (insn)) --+ { --+ info->last_bb = BLOCK_FOR_INSN (insn); --+ info->first_use = luid; --+ /* Set the value to record the using is former than setting. */ --+ info->first_set = luid + 1; --+ } --+} --+ --+/* Called from compute_hash_table via note_stores to handle one --+ SET or CLOBBER in an insn. DATA is really the instruction in which --+ the SET is taking place. */ --+ --+static void --+record_first_use_info (rtx *dest, void *data) --+{ --+ rtx_insn *last_set_insn = static_cast (data); --+ int i, j; --+ enum rtx_code code; --+ const char *fmt; --+ rtx x = *dest; --+ --+ if (x == 0) --+ return; --+ --+ code = GET_CODE (x); --+ if (REG_P (x) && REGNO (x) <= SP_REGNUM) --+ { --+ record_first_reg_use_info (last_set_insn, REGNO (x)); --+ /* DF and DI mode may use two registers. */ --+ if (GET_MODE_SIZE (GET_MODE (x)) == 8) --+ record_first_reg_use_info (last_set_insn, REGNO (x) + 1); --+ } --+ --+ for (i = GET_RTX_LENGTH (code) - 1, fmt = GET_RTX_FORMAT (code); i >= 0; i--) --+ { --+ if (fmt[i] == 'e') --+ record_first_use_info (&XEXP (x, i), data); --+ else if (fmt[i] == 'E') --+ for (j = 0; j < XVECLEN (x, i); j++) --+ record_first_use_info (&XVECEXP (x, i, j), data); --+ } --+} --+ --+/* Record register first/block set information for REGNO in INSN. --+ --+ first_set records the first place in the block where the register --+ is set and is used to compute "anticipatability". --+ --+ last_bb records the block for which first_set is valid, --+ as a quick test to invalidate them. */ --+ --+static void --+record_first_reg_set_info (rtx_insn *insn, int regno) --+{ --+ struct reg_avail_info *info = ®_avail_info[regno]; --+ int luid = DF_INSN_LUID (insn); --+ --+ if (info->last_bb != BLOCK_FOR_INSN (insn)) --+ { --+ info->last_bb = BLOCK_FOR_INSN (insn); --+ info->first_set = luid; --+ /* Set the value to record the using is later than setting. */ --+ info->first_use = luid + 1; --+ } --+} --+ --+/* Called from compute_hash_table via note_stores to handle one --+ SET or CLOBBER in an insn. DATA is really the instruction in which --+ the SET is taking place. */ --+ --+static void --+record_first_set_info (rtx dest, const_rtx setter ATTRIBUTE_UNUSED, void *data) --+{ --+ rtx_insn *last_set_insn = static_cast (data); --+ --+ if (GET_CODE (dest) == SUBREG) --+ dest = SUBREG_REG (dest); --+ --+ if (REG_P (dest) && REGNO (dest) <= SP_REGNUM) --+ { --+ record_first_reg_set_info (last_set_insn, REGNO (dest)); --+ if (GET_MODE_SIZE (GET_MODE (dest)) == 8) --+ record_first_reg_set_info (last_set_insn, REGNO (dest) + 1); --+ } --+} --+ --+/* Build hash table for supported format instructions. --+ Only consider if the instruction is anticipatable in the basic block here. --+ We postpone the def-use check until hoisting. */ --+ --+static void --+compute_hash_table (void) --+{ --+ basic_block bb; --+ int i; --+ --+ /* We only take care hard registers. */ --+ reg_avail_info = --+ (struct reg_avail_info *) xmalloc (sizeof (struct reg_avail_info) * --+ (SP_REGNUM + 1)); --+ --+ for (i = 0; i < 32; i++) --+ reg_avail_info[i].last_bb = NULL; --+ --+ FOR_EACH_BB_FN (bb, cfun) --+ { --+ rtx_insn *insn; --+ --+ /* Do not hoist instrucion from block which has more --+ than one predecessor. */ --+ if (EDGE_COUNT (bb->preds) > 1) --+ continue; --+ --+ FOR_BB_INSNS (bb, insn) --+ { --+ if (!NONDEBUG_INSN_P (insn)) --+ continue; --+ --+ /* Construct a caller save register barrier. We cannot hoist the --+ instruction over a function call which sets caller save --+ registers. */ --+ if (CALL_P (insn)) --+ { --+ for (i = 0; i <= SP_REGNUM; i++) --+ if (call_used_regs[i]) --+ record_first_reg_use_info (insn, i); --+ } --+ --+ note_uses (&PATTERN (insn), record_first_use_info, insn); --+ note_stores (PATTERN (insn), record_first_set_info, insn); --+ } --+ --+ /* Build the hash table. */ --+ FOR_BB_INSNS (bb, insn) --+ if (INSN_P (insn) && GET_CODE (PATTERN (insn)) == SET) --+ hash_scan_set (insn); --+ } --+} --+ --+/* Hoist instructions in this slot if possible. */ --+int --+nds32_find_gcse_expr_table (expr **slot, void *data ATTRIBUTE_UNUSED) --+{ --+ struct expr *exprs = *slot; --+ struct occr *occr; --+ rtx_insn *insn = NULL; --+ rtx_insn *last_insn; --+ basic_block bb; --+ edge e; --+ unsigned ix; --+ unsigned emit_done; --+ unsigned cover, regno; --+ df_ref use; --+ enum machine_mode mode; --+ --+ if (exprs->count < 2) --+ return 1; --+ --+ bitmap_vector_clear (hoist_vbeout, last_basic_block_for_fn (cfun)); --+ bitmap_vector_clear (hoist_vbein, last_basic_block_for_fn (cfun)); --+ --+ /* Set the bit for this slot. */ --+ occr = exprs->antic_occr; --+ while (occr) --+ { --+ insn = occr->insn; --+ bb = BLOCK_FOR_INSN (insn); --+ if (!occr->deleted_p) --+ bitmap_set_bit (hoist_vbein[bb->index], 0); --+ occr = occr->next; --+ } --+ --+ /* Try to hoist code for each basic block. */ --+ FOR_EACH_BB_REVERSE_FN (bb, cfun) --+ { --+ if (bb->next_bb != EXIT_BLOCK_PTR_FOR_FN (cfun)) --+ bitmap_intersection_of_succs (hoist_vbeout[bb->index], hoist_vbein, bb); --+ --+ if (bitmap_bit_p (hoist_vbeout[bb->index], 0) --+ && EDGE_COUNT (bb->succs) > 1) --+ { --+ emit_done = 0; --+ cover = FALSE; --+ for (e = NULL, ix = 0; ix < EDGE_COUNT (bb->succs); ix++) --+ { --+ e = EDGE_SUCC (bb, ix); --+ if (e->dest == EXIT_BLOCK_PTR_FOR_FN (cfun)) --+ continue; --+ occr = exprs->antic_occr; --+ while (occr) --+ { --+ insn = occr->insn; --+ if (!occr->deleted_p && e->dest == BLOCK_FOR_INSN (insn)) --+ break; --+ occr = occr->next; --+ } --+ --+ gcc_assert (insn != NULL); --+ --+ if (!emit_done) --+ { --+ last_insn = BB_END (bb); --+ /* Check the defined register is not used by the last --+ instruction of the previos block.*/ --+ regno = REGNO (SET_DEST (PATTERN (insn))); --+ mode = GET_MODE (SET_DEST (PATTERN (insn))); --+ FOR_EACH_INSN_USE (use, last_insn) --+ { --+ if (DF_REF_REGNO (use) == regno --+ || regno_clobbered_p (regno, last_insn, mode, 2)) --+ { --+ cover = TRUE; --+ break; --+ } --+ } --+ --+ /* TODO: support more format. */ --+ if (cover) --+ break; --+ else if (JUMP_P (last_insn)) --+ { --+ emit_insn_before_noloc (PATTERN (insn), last_insn, bb); --+ emit_done = TRUE; --+ } --+ else --+ break; --+ } --+ --+ if (emit_done) --+ { --+ delete_insn (insn); --+ occr->deleted_p = TRUE; --+ } --+ } --+ } --+ } --+ return 1; --+} --+ --+static int --+hoist_code (void) --+{ --+ hoist_vbein = sbitmap_vector_alloc (last_basic_block_for_fn (cfun), 1); --+ hoist_vbeout = sbitmap_vector_alloc (last_basic_block_for_fn (cfun), 1); --+ --+ expr_table->traverse (NULL); --+ --+ sbitmap_vector_free (hoist_vbein); --+ sbitmap_vector_free (hoist_vbeout); --+ --+ return 0; --+} --+ --+ --+static unsigned int --+nds32_gcse_opt (void) --+{ --+ --+ if (n_basic_blocks_for_fn (cfun) <= NUM_FIXED_BLOCKS + 1) --+ return 0; --+ /* Allocate memory for this pass. --+ Also computes and initializes the insns' CUIDs. */ --+ alloc_mem (); --+ --+ df_chain_add_problem (DF_DU_CHAIN); --+ df_insn_rescan_all (); --+ df_analyze (); --+ --+ compute_hash_table (); --+ --+ if (dump_file) --+ dump_hash_table (dump_file); --+ --+ hoist_code (); --+ --+ df_insn_rescan_all (); --+ free_mem (); --+ return 0; --+} --+ --+const pass_data pass_data_nds32_gcse_opt = --+{ --+ RTL_PASS, /* type */ --+ "gcse_opt", /* name */ --+ OPTGROUP_NONE, /* optinfo_flags */ --+ TV_MACH_DEP, /* tv_id */ --+ 0, /* properties_required */ --+ 0, /* properties_provided */ --+ 0, /* properties_destroyed */ --+ 0, /* todo_flags_start */ --+ 0, /* todo_flags_finish */ --+}; --+ --+class pass_nds32_gcse_opt : public rtl_opt_pass --+{ --+public: --+ pass_nds32_gcse_opt (gcc::context *ctxt) --+ : rtl_opt_pass (pass_data_nds32_gcse_opt, ctxt) --+ {} --+ --+ /* opt_pass methods: */ --+ bool gate (function *) { return TARGET_GCSE_OPT; } --+ unsigned int execute (function *) { return nds32_gcse_opt (); } --+}; --+ --+rtl_opt_pass * --+make_pass_nds32_gcse_opt (gcc::context *ctxt) --+{ --+ return new pass_nds32_gcse_opt (ctxt); --+} --+ --+/* ------------------------------------------------------------------------ */ --diff --git a/gcc/config/nds32/nds32-graywolf.md b/gcc/config/nds32/nds32-graywolf.md --new file mode 100644 --index 0000000..f9ddbd8 ----- /dev/null --+++ b/gcc/config/nds32/nds32-graywolf.md --@@ -0,0 +1,471 @@ --+;; Pipeline descriptions of Andes NDS32 cpu for GNU compiler --+;; Copyright (C) 2012-2016 Free Software Foundation, Inc. --+;; Contributed by Andes Technology Corporation. --+;; --+;; This file is part of GCC. --+;; --+;; GCC is free software; you can redistribute it and/or modify it --+;; under the terms of the GNU General Public License as published --+;; by the Free Software Foundation; either version 3, or (at your --+;; option) any later version. --+;; --+;; GCC is distributed in the hope that it will be useful, but WITHOUT --+;; ANY WARRANTY; without even the implied warranty of MERCHANTABILITY --+;; or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public --+;; License for more details. --+;; --+;; You should have received a copy of the GNU General Public License --+;; along with GCC; see the file COPYING3. If not see --+;; . --+ --+;; ------------------------------------------------------------------------ --+;; Define Graywolf pipeline settings. --+;; ------------------------------------------------------------------------ --+ --+(define_automaton "nds32_graywolf_machine") --+ --+(define_cpu_unit "gw_ii_0" "nds32_graywolf_machine") --+(define_cpu_unit "gw_ii_1" "nds32_graywolf_machine") --+(define_cpu_unit "gw_ex_p0" "nds32_graywolf_machine") --+(define_cpu_unit "gw_mm_p0" "nds32_graywolf_machine") --+(define_cpu_unit "gw_wb_p0" "nds32_graywolf_machine") --+(define_cpu_unit "gw_ex_p1" "nds32_graywolf_machine") --+(define_cpu_unit "gw_mm_p1" "nds32_graywolf_machine") --+(define_cpu_unit "gw_wb_p1" "nds32_graywolf_machine") --+(define_cpu_unit "gw_iq_p2" "nds32_graywolf_machine") --+(define_cpu_unit "gw_rf_p2" "nds32_graywolf_machine") --+(define_cpu_unit "gw_e1_p2" "nds32_graywolf_machine") --+(define_cpu_unit "gw_e2_p2" "nds32_graywolf_machine") --+(define_cpu_unit "gw_e3_p2" "nds32_graywolf_machine") --+(define_cpu_unit "gw_e4_p2" "nds32_graywolf_machine") --+ --+(define_reservation "gw_ii" "gw_ii_0 | gw_ii_1") --+(define_reservation "gw_ex" "gw_ex_p0 | gw_ex_p1") --+(define_reservation "gw_mm" "gw_mm_p0 | gw_mm_p1") --+(define_reservation "gw_wb" "gw_wb_p0 | gw_wb_p1") --+ --+(define_reservation "gw_ii_all" "gw_ii_0 + gw_ii_1") --+ --+(define_insn_reservation "nds_gw_unknown" 1 --+ (and (eq_attr "type" "unknown") --+ (eq_attr "pipeline_model" "graywolf")) --+ "gw_ii, gw_ex, gw_mm, gw_wb") --+ --+(define_insn_reservation "nds_gw_misc" 1 --+ (and (eq_attr "type" "misc") --+ (eq_attr "pipeline_model" "graywolf")) --+ "gw_ii, gw_ex, gw_mm, gw_wb") --+ --+(define_insn_reservation "nds_gw_mmu" 1 --+ (and (eq_attr "type" "mmu") --+ (eq_attr "pipeline_model" "graywolf")) --+ "gw_ii, gw_ex, gw_mm, gw_wb") --+ --+(define_insn_reservation "nds_gw_alu" 1 --+ (and (and (eq_attr "type" "alu") --+ (match_test "!nds32::movd44_insn_p (insn)")) --+ (eq_attr "pipeline_model" "graywolf")) --+ "gw_ii, gw_ex, gw_mm, gw_wb") --+ --+(define_insn_reservation "nds_gw_movd44" 1 --+ (and (and (eq_attr "type" "alu") --+ (match_test "nds32::movd44_insn_p (insn)")) --+ (eq_attr "pipeline_model" "graywolf")) --+ "gw_ii_1, gw_ex, gw_mm, gw_wb") --+ --+(define_insn_reservation "nds_gw_alu_shift" 1 --+ (and (eq_attr "type" "alu_shift") --+ (eq_attr "pipeline_model" "graywolf")) --+ "gw_ii, gw_ex*2, gw_mm, gw_wb") --+ --+(define_insn_reservation "nds_gw_pbsad" 1 --+ (and (eq_attr "type" "pbsad") --+ (eq_attr "pipeline_model" "graywolf")) --+ "gw_ii, gw_ex*3, gw_mm, gw_wb") --+ --+(define_insn_reservation "nds_gw_pbsada" 1 --+ (and (eq_attr "type" "pbsada") --+ (eq_attr "pipeline_model" "graywolf")) --+ "gw_ii, gw_ex*3, gw_mm, gw_wb") --+ --+(define_insn_reservation "nds_gw_load" 1 --+ (and (and (eq_attr "type" "load") --+ (match_test "!nds32::post_update_insn_p (insn)")) --+ (eq_attr "pipeline_model" "graywolf")) --+ "gw_ii_1, gw_ex_p1, gw_mm_p1, gw_wb_p1") --+ --+(define_insn_reservation "nds_gw_load_2w" 1 --+ (and (and (eq_attr "type" "load") --+ (match_test "nds32::post_update_insn_p (insn)")) --+ (eq_attr "pipeline_model" "graywolf")) --+ "gw_ii_all, gw_ex_p1, gw_mm_p1, gw_wb_p1") --+ --+(define_insn_reservation "nds_gw_store" 1 --+ (and (and (eq_attr "type" "store") --+ (match_test "!nds32::store_offset_reg_p (insn)")) --+ (eq_attr "pipeline_model" "graywolf")) --+ "gw_ii_1, gw_ex_p1, gw_mm_p1, gw_wb_p1") --+ --+(define_insn_reservation "nds_gw_store_3r" 1 --+ (and (and (eq_attr "type" "store") --+ (match_test "nds32::store_offset_reg_p (insn)")) --+ (eq_attr "pipeline_model" "graywolf")) --+ "gw_ii_all, gw_ex_p1, gw_mm_p1, gw_wb_p1") --+ --+(define_insn_reservation "nds_gw_load_multiple_1" 1 --+ (and (and (eq_attr "type" "load_multiple") --+ (eq_attr "combo" "1")) --+ (eq_attr "pipeline_model" "graywolf")) --+ "gw_ii_1, gw_ex_p1, gw_mm_p1, gw_wb_p1") --+ --+(define_insn_reservation "nds_gw_load_multiple_2" 1 --+ (and (and (eq_attr "type" "load_multiple") --+ (eq_attr "combo" "2")) --+ (eq_attr "pipeline_model" "graywolf")) --+ "gw_ii_1, gw_ex_p1*2, gw_mm_p1, gw_wb_p1") --+ --+(define_insn_reservation "nds_gw_load_multiple_3" 1 --+ (and (and (eq_attr "type" "load_multiple") --+ (eq_attr "combo" "3")) --+ (eq_attr "pipeline_model" "graywolf")) --+ "gw_ii_1, gw_ex_p1*3, gw_mm_p1, gw_wb_p1") --+ --+(define_insn_reservation "nds_gw_load_multiple_4" 1 --+ (and (and (eq_attr "type" "load_multiple") --+ (eq_attr "combo" "4")) --+ (eq_attr "pipeline_model" "graywolf")) --+ "gw_ii_1, gw_ex_p1*4, gw_mm_p1, gw_wb_p1") --+ --+(define_insn_reservation "nds_gw_load_multiple_5" 1 --+ (and (and (eq_attr "type" "load_multiple") --+ (eq_attr "combo" "5")) --+ (eq_attr "pipeline_model" "graywolf")) --+ "gw_ii_1, gw_ex_p1*4, gw_mm_p1, gw_wb_p1") --+ --+(define_insn_reservation "nds_gw_load_multiple_6" 1 --+ (and (and (eq_attr "type" "load_multiple") --+ (eq_attr "combo" "6")) --+ (eq_attr "pipeline_model" "graywolf")) --+ "gw_ii_1, gw_ex_p1*4, gw_mm_p1, gw_wb_p1") --+ --+(define_insn_reservation "nds_gw_load_multiple_7" 1 --+ (and (and (eq_attr "type" "load_multiple") --+ (eq_attr "combo" "7")) --+ (eq_attr "pipeline_model" "graywolf")) --+ "gw_ii_1, gw_ex_p1*4, gw_mm_p1, gw_wb_p1") --+ --+(define_insn_reservation "nds_gw_load_multiple_8" 1 --+ (and (and (eq_attr "type" "load_multiple") --+ (eq_attr "combo" "8")) --+ (eq_attr "pipeline_model" "graywolf")) --+ "gw_ii_1, gw_ex_p1*4, gw_mm_p1, gw_wb_p1") --+ --+(define_insn_reservation "nds_gw_load_multiple_12" 1 --+ (and (and (eq_attr "type" "load_multiple") --+ (eq_attr "combo" "12")) --+ (eq_attr "pipeline_model" "graywolf")) --+ "gw_ii_1, gw_ex_p1*4, gw_mm_p1, gw_wb_p1") --+ --+(define_insn_reservation "nds_gw_store_multiple_1" 1 --+ (and (and (eq_attr "type" "store_multiple") --+ (eq_attr "combo" "1")) --+ (eq_attr "pipeline_model" "graywolf")) --+ "gw_ii_1, gw_ex_p1, gw_mm_p1, gw_wb_p1") --+ --+(define_insn_reservation "nds_gw_store_multiple_2" 1 --+ (and (and (eq_attr "type" "store_multiple") --+ (eq_attr "combo" "2")) --+ (eq_attr "pipeline_model" "graywolf")) --+ "gw_ii_1, gw_ex_p1*2, gw_mm_p1, gw_wb_p1") --+ --+(define_insn_reservation "nds_gw_store_multiple_3" 1 --+ (and (and (eq_attr "type" "store_multiple") --+ (eq_attr "combo" "3")) --+ (eq_attr "pipeline_model" "graywolf")) --+ "gw_ii_1, gw_ex_p1*3, gw_mm_p1, gw_wb_p1") --+ --+(define_insn_reservation "nds_gw_store_multiple_4" 1 --+ (and (and (eq_attr "type" "store_multiple") --+ (eq_attr "combo" "4")) --+ (eq_attr "pipeline_model" "graywolf")) --+ "gw_ii_1, gw_ex_p1*4, gw_mm_p1, gw_wb_p1") --+ --+(define_insn_reservation "nds_gw_store_multiple_5" 1 --+ (and (and (eq_attr "type" "store_multiple") --+ (eq_attr "combo" "5")) --+ (eq_attr "pipeline_model" "graywolf")) --+ "gw_ii_1, gw_ex_p1*4, gw_mm_p1, gw_wb_p1") --+ --+(define_insn_reservation "nds_gw_store_multiple_6" 1 --+ (and (and (eq_attr "type" "store_multiple") --+ (eq_attr "combo" "6")) --+ (eq_attr "pipeline_model" "graywolf")) --+ "gw_ii_1, gw_ex_p1*4, gw_mm_p1, gw_wb_p1") --+ --+(define_insn_reservation "nds_gw_store_multiple_7" 1 --+ (and (and (eq_attr "type" "store_multiple") --+ (eq_attr "combo" "7")) --+ (eq_attr "pipeline_model" "graywolf")) --+ "gw_ii_1, gw_ex_p1*4, gw_mm_p1, gw_wb_p1") --+ --+(define_insn_reservation "nds_gw_store_multiple_8" 1 --+ (and (and (eq_attr "type" "store_multiple") --+ (eq_attr "combo" "8")) --+ (eq_attr "pipeline_model" "graywolf")) --+ "gw_ii_1, gw_ex_p1*4, gw_mm_p1, gw_wb_p1") --+ --+(define_insn_reservation "nds_gw_store_multiple_12" 1 --+ (and (and (eq_attr "type" "store_multiple") --+ (eq_attr "combo" "12")) --+ (eq_attr "pipeline_model" "graywolf")) --+ "gw_ii_1, gw_ex_p1*4, gw_mm_p1, gw_wb_p1") --+ --+(define_insn_reservation "nds_gw_mul_fast1" 1 --+ (and (match_test "nds32_mul_config == MUL_TYPE_FAST_1") --+ (and (eq_attr "type" "mul") --+ (eq_attr "pipeline_model" "graywolf"))) --+ "gw_ii_0, gw_ex_p0, gw_mm_p0, gw_wb_p0") --+ --+(define_insn_reservation "nds_gw_mul_fast2" 1 --+ (and (match_test "nds32_mul_config == MUL_TYPE_FAST_2") --+ (and (eq_attr "type" "mul") --+ (eq_attr "pipeline_model" "graywolf"))) --+ "gw_ii_0, gw_ex_p0*2, gw_mm_p0, gw_wb_p0") --+ --+(define_insn_reservation "nds_gw_mul_slow" 1 --+ (and (match_test "nds32_mul_config == MUL_TYPE_SLOW") --+ (and (eq_attr "type" "mul") --+ (eq_attr "pipeline_model" "graywolf"))) --+ "gw_ii_0, gw_ex_p0*4, gw_mm_p0, gw_wb_p0") --+ --+(define_insn_reservation "nds_gw_mac_fast1" 1 --+ (and (match_test "nds32_mul_config == MUL_TYPE_FAST_1") --+ (and (eq_attr "type" "mac") --+ (eq_attr "pipeline_model" "graywolf"))) --+ "gw_ii_all, gw_ex_p0, gw_mm_p0, gw_wb_p0") --+ --+(define_insn_reservation "nds_gw_mac_fast2" 1 --+ (and (match_test "nds32_mul_config == MUL_TYPE_FAST_2") --+ (and (eq_attr "type" "mac") --+ (eq_attr "pipeline_model" "graywolf"))) --+ "gw_ii_all, gw_ex_p0*2, gw_mm_p0, gw_wb_p0") --+ --+(define_insn_reservation "nds_gw_mac_slow" 1 --+ (and (match_test "nds32_mul_config == MUL_TYPE_SLOW") --+ (and (eq_attr "type" "mac") --+ (eq_attr "pipeline_model" "graywolf"))) --+ "gw_ii_all, gw_ex_p0*4, gw_mm_p0, gw_wb_p0") --+ --+(define_insn_reservation "nds_gw_div" 1 --+ (and (and (eq_attr "type" "div") --+ (match_test "!nds32::divmod_p (insn)")) --+ (eq_attr "pipeline_model" "graywolf")) --+ "gw_ii_0, gw_ex_p0*4, gw_mm_p0, gw_wb_p0") --+ --+(define_insn_reservation "nds_gw_div_2w" 1 --+ (and (and (eq_attr "type" "div") --+ (match_test "nds32::divmod_p (insn)")) --+ (eq_attr "pipeline_model" "graywolf")) --+ "gw_ii_all, gw_ex_p0*4, gw_mm_p0, gw_wb_p0") --+ --+(define_insn_reservation "nds_gw_branch" 1 --+ (and (eq_attr "type" "branch") --+ (eq_attr "pipeline_model" "graywolf")) --+ "gw_ii_0, gw_ex_p0, gw_mm_p0, gw_wb_p0") --+ --+(define_insn_reservation "nds_gw_dsp_alu" 1 --+ (and (eq_attr "type" "dalu") --+ (eq_attr "pipeline_model" "graywolf")) --+ "gw_ii, gw_ex, gw_mm, gw_wb") --+ --+(define_insn_reservation "nds_gw_dsp_alu64" 1 --+ (and (eq_attr "type" "dalu64") --+ (eq_attr "pipeline_model" "graywolf")) --+ "gw_ii_all, gw_ex_p0, gw_mm_p0, gw_wb_p0") --+ --+(define_insn_reservation "nds_gw_dsp_alu_round" 1 --+ (and (eq_attr "type" "daluround") --+ (eq_attr "pipeline_model" "graywolf")) --+ "gw_ii_0, gw_ex_p0, gw_mm_p0, gw_wb_p0") --+ --+(define_insn_reservation "nds_gw_dsp_cmp" 1 --+ (and (eq_attr "type" "dcmp") --+ (eq_attr "pipeline_model" "graywolf")) --+ "gw_ii_0, gw_ex_p0, gw_mm_p0, gw_wb_p0") --+ --+(define_insn_reservation "nds_gw_dsp_clip" 1 --+ (and (eq_attr "type" "dclip") --+ (eq_attr "pipeline_model" "graywolf")) --+ "gw_ii_0, gw_ex_p0, gw_mm_p0, gw_wb_p0") --+ --+(define_insn_reservation "nds_gw_dsp_mul" 1 --+ (and (eq_attr "type" "dmul") --+ (eq_attr "pipeline_model" "graywolf")) --+ "gw_ii_0, gw_ex_p0, gw_mm_p0, gw_wb_p0") --+ --+(define_insn_reservation "nds_gw_dsp_mac" 1 --+ (and (eq_attr "type" "dmac") --+ (eq_attr "pipeline_model" "graywolf")) --+ "gw_ii_all, gw_ex_p0, gw_mm_p0, gw_wb_p0") --+ --+(define_insn_reservation "nds_gw_dsp_insb" 1 --+ (and (eq_attr "type" "dinsb") --+ (eq_attr "pipeline_model" "graywolf")) --+ "gw_ii_0, gw_ex_p0, gw_mm_p0, gw_wb_p0") --+ --+(define_insn_reservation "nds_gw_dsp_pack" 1 --+ (and (eq_attr "type" "dpack") --+ (eq_attr "pipeline_model" "graywolf")) --+ "gw_ii_0, gw_ex_p0, gw_mm_p0, gw_wb_p0") --+ --+(define_insn_reservation "nds_gw_dsp_bpick" 1 --+ (and (eq_attr "type" "dbpick") --+ (eq_attr "pipeline_model" "graywolf")) --+ "gw_ii_0, gw_ex_p0, gw_mm_p0, gw_wb_p0") --+ --+(define_insn_reservation "nds_gw_dsp_wext" 1 --+ (and (eq_attr "type" "dwext") --+ (eq_attr "pipeline_model" "graywolf")) --+ "gw_ii_all, gw_ex_p0, gw_mm_p0, gw_wb_p0") --+ --+(define_insn_reservation "nds_gw_fpu_alu" 4 --+ (and (eq_attr "type" "falu") --+ (eq_attr "pipeline_model" "graywolf")) --+ "gw_ii, gw_iq_p2, gw_rf_p2, gw_e1_p2, gw_e2_p2, gw_e3_p2, gw_e4_p2") --+ --+(define_insn_reservation "nds_gw_fpu_muls" 4 --+ (and (eq_attr "type" "fmuls") --+ (eq_attr "pipeline_model" "graywolf")) --+ "gw_ii, gw_iq_p2, gw_rf_p2, gw_e1_p2, gw_e2_p2, gw_e3_p2, gw_e4_p2") --+ --+(define_insn_reservation "nds_gw_fpu_muld" 4 --+ (and (eq_attr "type" "fmuld") --+ (eq_attr "pipeline_model" "graywolf")) --+ "gw_ii, gw_iq_p2, gw_rf_p2, gw_e1_p2, gw_e2_p2*2, gw_e3_p2, gw_e4_p2") --+ --+(define_insn_reservation "nds_gw_fpu_macs" 4 --+ (and (eq_attr "type" "fmacs") --+ (eq_attr "pipeline_model" "graywolf")) --+ "gw_ii, gw_iq_p2, gw_rf_p2, gw_e1_p2, gw_e2_p2*3, gw_e3_p2, gw_e4_p2") --+ --+(define_insn_reservation "nds_gw_fpu_macd" 4 --+ (and (eq_attr "type" "fmacd") --+ (eq_attr "pipeline_model" "graywolf")) --+ "gw_ii, gw_iq_p2, gw_rf_p2, gw_e1_p2, gw_e2_p2*4, gw_e3_p2, gw_e4_p2") --+ --+(define_insn_reservation "nds_gw_fpu_divs" 4 --+ (and (ior (eq_attr "type" "fdivs") --+ (eq_attr "type" "fsqrts")) --+ (eq_attr "pipeline_model" "graywolf")) --+ "gw_ii, gw_iq_p2, gw_rf_p2, gw_e1_p2, gw_e2_p2*14, gw_e3_p2, gw_e4_p2") --+ --+(define_insn_reservation "nds_gw_fpu_divd" 4 --+ (and (ior (eq_attr "type" "fdivd") --+ (eq_attr "type" "fsqrtd")) --+ (eq_attr "pipeline_model" "graywolf")) --+ "gw_ii, gw_iq_p2, gw_rf_p2, gw_e1_p2, gw_e2_p2*28, gw_e3_p2, gw_e4_p2") --+ --+(define_insn_reservation "nds_gw_fpu_fast_alu" 2 --+ (and (ior (eq_attr "type" "fcmp") --+ (ior (eq_attr "type" "fabs") --+ (ior (eq_attr "type" "fcpy") --+ (eq_attr "type" "fcmov")))) --+ (eq_attr "pipeline_model" "graywolf")) --+ "gw_ii, gw_iq_p2, gw_rf_p2, gw_e1_p2, gw_e2_p2, gw_e3_p2, gw_e4_p2") --+ --+(define_insn_reservation "nds_gw_fpu_fmtsr" 1 --+ (and (eq_attr "type" "fmtsr") --+ (eq_attr "pipeline_model" "graywolf")) --+ "gw_ii, gw_iq_p2, gw_rf_p2, gw_e1_p2, gw_e2_p2, gw_e3_p2, gw_e4_p2") --+ --+(define_insn_reservation "nds_gw_fpu_fmtdr" 1 --+ (and (eq_attr "type" "fmtdr") --+ (eq_attr "pipeline_model" "graywolf")) --+ "gw_ii, gw_ii+gw_iq_p2, gw_iq_p2+gw_rf_p2, gw_rf_p2+gw_e1_p2, gw_e1_p2+gw_e2_p2, gw_e2_p2+gw_e3_p2, gw_e3_p2+gw_e4_p2, gw_e4_p2") --+ --+(define_insn_reservation "nds_gw_fpu_fmfsr" 1 --+ (and (eq_attr "type" "fmfsr") --+ (eq_attr "pipeline_model" "graywolf")) --+ "gw_ii, gw_iq_p2, gw_rf_p2, gw_e1_p2, gw_e2_p2, gw_e3_p2, gw_e4_p2") --+ --+(define_insn_reservation "nds_gw_fpu_fmfdr" 1 --+ (and (eq_attr "type" "fmfdr") --+ (eq_attr "pipeline_model" "graywolf")) --+ "gw_ii, gw_ii+gw_iq_p2, gw_iq_p2+gw_rf_p2, gw_rf_p2+gw_e1_p2, gw_e1_p2+gw_e2_p2, gw_e2_p2+gw_e3_p2, gw_e3_p2+gw_e4_p2, gw_e4_p2") --+ --+(define_insn_reservation "nds_gw_fpu_load" 3 --+ (and (eq_attr "type" "fload") --+ (eq_attr "pipeline_model" "graywolf")) --+ "gw_ii, gw_iq_p2, gw_rf_p2, gw_e1_p2, gw_e2_p2, gw_e3_p2, gw_e4_p2") --+ --+(define_insn_reservation "nds_gw_fpu_store" 1 --+ (and (eq_attr "type" "fstore") --+ (eq_attr "pipeline_model" "graywolf")) --+ "gw_ii, gw_iq_p2, gw_rf_p2, gw_e1_p2, gw_e2_p2, gw_e3_p2, gw_e4_p2") --+ --+;; FPU_ADDR_OUT -> FPU_ADDR_IN --+;; Main pipeline rules don't need this because those default latency is 1. --+(define_bypass 1 --+ "nds_gw_fpu_load, nds_gw_fpu_store" --+ "nds_gw_fpu_load, nds_gw_fpu_store" --+ "nds32_gw_ex_to_ex_p" --+) --+ --+;; LD, MUL, MAC, DIV, DALU64, DMUL, DMAC, DALUROUND, DBPICK, DWEXT --+;; -> ALU, ALU_SHIFT_Rb, PBSAD, PBSADA_RaRb, MOVD44, MUL, MAC_RaRb, DIV, ADDR_IN, BR, MMU, --+;; DALU, DALUROUND, DMUL, DMAC_RaRb, DPACK, DINSB, DCMP, DCLIP, WEXT_O, BPICK_RaRb --+(define_bypass 2 --+ "nds_gw_load, nds_gw_load_2w,\ --+ nds_gw_mul_fast1, nds_gw_mul_fast2, nds_gw_mul_slow,\ --+ nds_gw_mac_fast1, nds_gw_mac_fast2, nds_gw_mac_slow,\ --+ nds_gw_div, nds_gw_div_2w,\ --+ nds_gw_dsp_alu64, nds_gw_dsp_mul, nds_gw_dsp_mac,\ --+ nds_gw_dsp_alu_round, nds_gw_dsp_bpick, nds_gw_dsp_wext" --+ "nds_gw_alu, nds_gw_movd44, nds_gw_alu_shift,\ --+ nds_gw_pbsad, nds_gw_pbsada,\ --+ nds_gw_mul_fast1, nds_gw_mul_fast2, nds_gw_mul_slow,\ --+ nds_gw_mac_fast1, nds_gw_mac_fast2, nds_gw_mac_slow,\ --+ nds_gw_branch,\ --+ nds_gw_div, nds_gw_div_2w,\ --+ nds_gw_load, nds_gw_load_2w, nds_gw_store, nds_gw_store_3r,\ --+ nds_gw_load_multiple_1,nds_gw_load_multiple_2, nds_gw_load_multiple_3,\ --+ nds_gw_load_multiple_4,nds_gw_load_multiple_5, nds_gw_load_multiple_6,\ --+ nds_gw_load_multiple_7,nds_gw_load_multiple_8, nds_gw_load_multiple_12,\ --+ nds_gw_store_multiple_1,nds_gw_store_multiple_2, nds_gw_store_multiple_3,\ --+ nds_gw_store_multiple_4,nds_gw_store_multiple_5, nds_gw_store_multiple_6,\ --+ nds_gw_store_multiple_7,nds_gw_store_multiple_8, nds_gw_store_multiple_12,\ --+ nds_gw_mmu,\ --+ nds_gw_dsp_alu, nds_gw_dsp_alu_round,\ --+ nds_gw_dsp_mul, nds_gw_dsp_mac, nds_gw_dsp_pack,\ --+ nds_gw_dsp_insb, nds_gw_dsp_cmp, nds_gw_dsp_clip,\ --+ nds_gw_dsp_wext, nds_gw_dsp_bpick" --+ "nds32_gw_mm_to_ex_p" --+) --+ --+;; LMW(N, N) --+;; -> ALU, ALU_SHIFT_Rb, PBSAD, PBSADA_RaRb, MOVD44, MUL, MAC_RaRb, DIV, ADDR_IN, BR, MMU --+;; DALU, DALUROUND, DMUL, DMAC_RaRb, DPACK, DINSB, DCMP, DCLIP, WEXT_O, BPICK_RaRb --+(define_bypass 2 --+ "nds_gw_load_multiple_1,nds_gw_load_multiple_2, nds_gw_load_multiple_3,\ --+ nds_gw_load_multiple_4,nds_gw_load_multiple_5, nds_gw_load_multiple_6,\ --+ nds_gw_load_multiple_7,nds_gw_load_multiple_8, nds_gw_load_multiple_12" --+ "nds_gw_alu, nds_gw_movd44, nds_gw_alu_shift,\ --+ nds_gw_pbsad, nds_gw_pbsada,\ --+ nds_gw_mul_fast1, nds_gw_mul_fast2, nds_gw_mul_slow,\ --+ nds_gw_mac_fast1, nds_gw_mac_fast2, nds_gw_mac_slow,\ --+ nds_gw_branch,\ --+ nds_gw_div, nds_gw_div_2w,\ --+ nds_gw_load, nds_gw_load_2w, nds_gw_store, nds_gw_store_3r,\ --+ nds_gw_load_multiple_1,nds_gw_load_multiple_2, nds_gw_load_multiple_3,\ --+ nds_gw_load_multiple_4,nds_gw_load_multiple_5, nds_gw_load_multiple_6,\ --+ nds_gw_load_multiple_7,nds_gw_load_multiple_8, nds_gw_load_multiple_12,\ --+ nds_gw_store_multiple_1,nds_gw_store_multiple_2, nds_gw_store_multiple_3,\ --+ nds_gw_store_multiple_4,nds_gw_store_multiple_5, nds_gw_store_multiple_6,\ --+ nds_gw_store_multiple_7,nds_gw_store_multiple_8, nds_gw_store_multiple_12,\ --+ nds_gw_mmu,\ --+ nds_gw_dsp_alu, nds_gw_dsp_alu_round,\ --+ nds_gw_dsp_mul, nds_gw_dsp_mac, nds_gw_dsp_pack,\ --+ nds_gw_dsp_insb, nds_gw_dsp_cmp, nds_gw_dsp_clip,\ --+ nds_gw_dsp_wext, nds_gw_dsp_bpick" --+ "nds32_gw_last_load_to_ex_p" --+) --diff --git a/gcc/config/nds32/nds32-intrinsic.c b/gcc/config/nds32/nds32-intrinsic.c --index fabf262..7547fb1 100644 ----- a/gcc/config/nds32/nds32-intrinsic.c --+++ b/gcc/config/nds32/nds32-intrinsic.c --@@ -24,210 +24,1867 @@ -- #include "system.h" -- #include "coretypes.h" -- #include "backend.h" ---#include "target.h" ---#include "rtl.h" -- #include "tree.h" ---#include "optabs.h" /* For GEN_FCN. */ ---#include "diagnostic-core.h" --+#include "rtl.h" --+#include "df.h" --+#include "alias.h" -- #include "stor-layout.h" --+#include "varasm.h" --+#include "calls.h" --+#include "regs.h" --+#include "insn-config.h" /* Required by recog.h. */ --+#include "conditions.h" --+#include "output.h" --+#include "insn-attr.h" /* For DFA state_t. */ --+#include "insn-codes.h" /* For CODE_FOR_xxx. */ --+#include "reload.h" /* For push_reload(). */ --+#include "flags.h" --+#include "insn-config.h" --+#include "expmed.h" --+#include "dojump.h" --+#include "explow.h" --+#include "emit-rtl.h" --+#include "stmt.h" -- #include "expr.h" --+#include "recog.h" --+#include "diagnostic-core.h" --+#include "cfgrtl.h" --+#include "cfganal.h" --+#include "lcm.h" --+#include "cfgbuild.h" --+#include "cfgcleanup.h" --+#include "tm_p.h" --+#include "tm-constrs.h" --+#include "optabs.h" /* For GEN_FCN. */ --+#include "target.h" -- #include "langhooks.h" /* For add_builtin_function(). */ --+#include "builtins.h" -- -- /* ------------------------------------------------------------------------ */ -- ---/* Function to expand builtin function for --- '[(unspec_volatile [(reg)])]'. */ --+/* Read the requested argument from the EXP given by INDEX. --+ Return the value as an rtx. */ --+static rtx --+nds32_read_argument (tree exp, unsigned int index) --+{ --+ return expand_normal (CALL_EXPR_ARG (exp, index)); --+} --+ --+/* Return a legitimate rtx for instruction ICODE's return value. Use TARGET --+ if it's not null, has the right mode, and satisfies operand 0's --+ predicate. */ --+static rtx --+nds32_legitimize_target (enum insn_code icode, rtx target) --+{ --+ enum machine_mode mode = insn_data[icode].operand[0].mode; --+ --+ if (! target --+ || GET_MODE (target) != mode --+ || ! (*insn_data[icode].operand[0].predicate) (target, mode)) --+ return gen_reg_rtx (mode); --+ else --+ return target; --+} --+ --+/* Given that ARG is being passed as operand OPNUM to instruction ICODE, --+ check whether ARG satisfies the operand's constraints. If it doesn't, --+ copy ARG to a temporary register and return that. Otherwise return ARG --+ itself. */ -- static rtx ---nds32_expand_builtin_null_ftype_reg (enum insn_code icode, --- tree exp, rtx target) --+nds32_legitimize_argument (enum insn_code icode, int opnum, rtx arg) --+{ --+ enum machine_mode mode = insn_data[icode].operand[opnum].mode; --+ --+ if ((*insn_data[icode].operand[opnum].predicate) (arg, mode)) --+ return arg; --+ else if (VECTOR_MODE_P (mode) && CONST_INT_P (arg)) --+ { --+ /* Handle CONST_INT covert to CONST_VECTOR. */ --+ int nunits = GET_MODE_NUNITS (mode); --+ int i, shift = 0; --+ rtvec v = rtvec_alloc (nunits); --+ int val = INTVAL (arg); --+ enum machine_mode val_mode = (mode == V4QImode) ? QImode : HImode; --+ int shift_acc = (val_mode == QImode) ? 8 : 16; --+ int mask = (val_mode == QImode) ? 0xff : 0xffff; --+ int tmp_val = val; --+ --+ if (TARGET_BIG_ENDIAN) --+ for (i = 0; i < nunits; i++) --+ { --+ tmp_val = (val >> shift) & mask; --+ RTVEC_ELT (v, nunits - i - 1) = gen_int_mode (tmp_val, val_mode); --+ shift += shift_acc; --+ } --+ else --+ for (i = 0; i < nunits; i++) --+ { --+ tmp_val = (val >> shift) & mask; --+ RTVEC_ELT (v, i) = gen_int_mode (tmp_val, val_mode); --+ shift += shift_acc; --+ } --+ --+ return copy_to_mode_reg (mode, gen_rtx_CONST_VECTOR (mode, v)); --+ } --+ else --+ { --+ rtx tmp_rtx = gen_reg_rtx (mode); --+ convert_move (tmp_rtx, arg, false); --+ return tmp_rtx; --+ } --+} --+ --+/* Return true if OPVAL can be used for operand OPNUM of instruction ICODE. --+ The instruction should require a constant operand of some sort. The --+ function prints an error if OPVAL is not valid. */ --+static int --+nds32_check_constant_argument (enum insn_code icode, int opnum, rtx opval, --+ const char *name) -- { --- /* Mapping: --- ops[0] <--> value0 <--> arg0 */ --- struct expand_operand ops[1]; --- tree arg0; --- rtx value0; --+ if (GET_CODE (opval) != CONST_INT) --+ { --+ error ("invalid argument to built-in function %s", name); --+ return false; --+ } --+ if (! (*insn_data[icode].operand[opnum].predicate) (opval, VOIDmode)) --+ { --+ error ("constant argument out of range for %s", name); --+ --+ return false; --+ } --+ return true; --+} -- --- /* Grab the incoming arguments and extract its rtx. */ --- arg0 = CALL_EXPR_ARG (exp, 0); --- value0 = expand_normal (arg0); --+/* Expand builtins that return target. */ --+static rtx --+nds32_expand_noarg_builtin (enum insn_code icode, rtx target) --+{ --+ rtx pat; -- --- /* Create operands. */ --- create_input_operand (&ops[0], value0, TYPE_MODE (TREE_TYPE (arg0))); --+ target = nds32_legitimize_target (icode, target); -- --- /* Emit new instruction. */ --- if (!maybe_expand_insn (icode, 1, ops)) --- error ("invalid argument to built-in function"); --+ /* Emit and return the new instruction. */ --+ pat = GEN_FCN (icode) (target); --+ if (! pat) --+ return NULL_RTX; -- --+ emit_insn (pat); -- return target; -- } -- ---/* Function to expand builtin function for --- '[(set (reg) (unspec_volatile [(imm)]))]'. */ --+/* Expand builtins that take one operand. */ -- static rtx ---nds32_expand_builtin_reg_ftype_imm (enum insn_code icode, --- tree exp, rtx target) --+nds32_expand_unop_builtin (enum insn_code icode, tree exp, rtx target, --+ bool return_p) -- { --- /* Mapping: --- ops[0] <--> target <--> exp --- ops[1] <--> value0 <--> arg0 */ --- struct expand_operand ops[2]; --- tree arg0; --- rtx value0; --+ rtx pat; --+ rtx op0 = nds32_read_argument (exp, 0); --+ int op0_num = return_p ? 1 : 0; --+ --+ if (return_p) --+ target = nds32_legitimize_target (icode, target); -- --- /* Grab the incoming arguments and extract its rtx. */ --- arg0 = CALL_EXPR_ARG (exp, 0); --- value0 = expand_normal (arg0); --+ op0 = nds32_legitimize_argument (icode, op0_num, op0); -- --- /* Create operands. */ --- create_output_operand (&ops[0], target, TYPE_MODE (TREE_TYPE (exp))); --- create_input_operand (&ops[1], value0, TYPE_MODE (TREE_TYPE (arg0))); --+ /* Emit and return the new instruction. */ --+ if (return_p) --+ pat = GEN_FCN (icode) (target, op0); --+ else --+ pat = GEN_FCN (icode) (op0); -- --- /* Emit new instruction. */ --- if (!maybe_expand_insn (icode, 2, ops)) --- error ("invalid argument to built-in function"); --+ if (! pat) --+ return NULL_RTX; -- --+ emit_insn (pat); -- return target; -- } -- ---/* Function to expand builtin function for --- '[(unspec_volatile [(reg) (imm)])]' pattern. */ --+/* Expand builtins that take one operands and the first is immediate. */ -- static rtx ---nds32_expand_builtin_null_ftype_reg_imm (enum insn_code icode, --- tree exp, rtx target) ---{ --- /* Mapping: --- ops[0] <--> value0 <--> arg0 --- ops[1] <--> value1 <--> arg1 */ --- struct expand_operand ops[2]; --- tree arg0, arg1; --- rtx value0, value1; --- --- /* Grab the incoming arguments and extract its rtx. */ --- arg0 = CALL_EXPR_ARG (exp, 0); --- arg1 = CALL_EXPR_ARG (exp, 1); --- value0 = expand_normal (arg0); --- value1 = expand_normal (arg1); --- --- /* Create operands. */ --- create_input_operand (&ops[0], value0, TYPE_MODE (TREE_TYPE (arg0))); --- create_input_operand (&ops[1], value1, TYPE_MODE (TREE_TYPE (arg1))); --- --- /* Emit new instruction. */ --- if (!maybe_expand_insn (icode, 2, ops)) --- error ("invalid argument to built-in function"); --+nds32_expand_unopimm_builtin (enum insn_code icode, tree exp, rtx target, --+ bool return_p, const char *name) --+{ --+ rtx pat; --+ rtx op0 = nds32_read_argument (exp, 0); --+ int op0_num = return_p ? 1 : 0; --+ --+ if (return_p) --+ target = nds32_legitimize_target (icode, target); --+ --+ if (!nds32_check_constant_argument (icode, op0_num, op0, name)) --+ return NULL_RTX; --+ --+ op0 = nds32_legitimize_argument (icode, op0_num, op0); -- --+ /* Emit and return the new instruction. */ --+ if (return_p) --+ pat = GEN_FCN (icode) (target, op0); --+ else --+ pat = GEN_FCN (icode) (op0); --+ --+ if (! pat) --+ return NULL_RTX; --+ --+ emit_insn (pat); -- return target; -- } -- ---/* ------------------------------------------------------------------------ */ --+/* Expand builtins that take two operands. */ --+static rtx --+nds32_expand_binop_builtin (enum insn_code icode, tree exp, rtx target, --+ bool return_p) --+{ --+ rtx pat; --+ rtx op0 = nds32_read_argument (exp, 0); --+ rtx op1 = nds32_read_argument (exp, 1); --+ int op0_num = return_p ? 1 : 0; --+ int op1_num = return_p ? 2 : 1; -- ---void ---nds32_init_builtins_impl (void) --+ if (return_p) --+ target = nds32_legitimize_target (icode, target); --+ --+ op0 = nds32_legitimize_argument (icode, op0_num, op0); --+ op1 = nds32_legitimize_argument (icode, op1_num, op1); --+ --+ /* Emit and return the new instruction. */ --+ if (return_p) --+ pat = GEN_FCN (icode) (target, op0, op1); --+ else --+ pat = GEN_FCN (icode) (op0, op1); --+ --+ if (! pat) --+ return NULL_RTX; --+ --+ emit_insn (pat); --+ return target; --+} --+ --+/* Expand builtins that take two operands and the second is immediate. */ --+static rtx --+nds32_expand_binopimm_builtin (enum insn_code icode, tree exp, rtx target, --+ bool return_p, const char *name) -- { --- tree pointer_type_node = build_pointer_type (integer_type_node); --+ rtx pat; --+ rtx op0 = nds32_read_argument (exp, 0); --+ rtx op1 = nds32_read_argument (exp, 1); --+ int op0_num = return_p ? 1 : 0; --+ int op1_num = return_p ? 2 : 1; -- --- tree void_ftype_void = build_function_type (void_type_node, --- void_list_node); --+ if (return_p) --+ target = nds32_legitimize_target (icode, target); -- --- tree void_ftype_pint = build_function_type_list (void_type_node, --- pointer_type_node, --- NULL_TREE); --+ if (!nds32_check_constant_argument (icode, op1_num, op1, name)) --+ return NULL_RTX; -- --- tree int_ftype_int = build_function_type_list (integer_type_node, --- integer_type_node, --- NULL_TREE); --+ op0 = nds32_legitimize_argument (icode, op0_num, op0); --+ op1 = nds32_legitimize_argument (icode, op1_num, op1); -- --- tree void_ftype_int_int = build_function_type_list (void_type_node, --- integer_type_node, --- integer_type_node, --- NULL_TREE); --+ /* Emit and return the new instruction. */ --+ if (return_p) --+ pat = GEN_FCN (icode) (target, op0, op1); --+ else --+ pat = GEN_FCN (icode) (op0, op1); -- --- /* Cache. */ --- add_builtin_function ("__builtin_nds32_isync", void_ftype_pint, --- NDS32_BUILTIN_ISYNC, --- BUILT_IN_MD, NULL, NULL_TREE); --- add_builtin_function ("__builtin_nds32_isb", void_ftype_void, --- NDS32_BUILTIN_ISB, --- BUILT_IN_MD, NULL, NULL_TREE); --+ if (! pat) --+ return NULL_RTX; -- --- /* Register Transfer. */ --- add_builtin_function ("__builtin_nds32_mfsr", int_ftype_int, --- NDS32_BUILTIN_MFSR, --- BUILT_IN_MD, NULL, NULL_TREE); --- add_builtin_function ("__builtin_nds32_mfusr", int_ftype_int, --- NDS32_BUILTIN_MFUSR, --- BUILT_IN_MD, NULL, NULL_TREE); --- add_builtin_function ("__builtin_nds32_mtsr", void_ftype_int_int, --- NDS32_BUILTIN_MTSR, --- BUILT_IN_MD, NULL, NULL_TREE); --- add_builtin_function ("__builtin_nds32_mtusr", void_ftype_int_int, --- NDS32_BUILTIN_MTUSR, --- BUILT_IN_MD, NULL, NULL_TREE); --+ emit_insn (pat); --+ return target; --+} -- --- /* Interrupt. */ --- add_builtin_function ("__builtin_nds32_setgie_en", void_ftype_void, --- NDS32_BUILTIN_SETGIE_EN, --- BUILT_IN_MD, NULL, NULL_TREE); --- add_builtin_function ("__builtin_nds32_setgie_dis", void_ftype_void, --- NDS32_BUILTIN_SETGIE_DIS, --- BUILT_IN_MD, NULL, NULL_TREE); --+/* Expand builtins that take three operands. */ --+static rtx --+nds32_expand_triop_builtin (enum insn_code icode, tree exp, rtx target, --+ bool return_p) --+{ --+ rtx pat; --+ rtx op0 = nds32_read_argument (exp, 0); --+ rtx op1 = nds32_read_argument (exp, 1); --+ rtx op2 = nds32_read_argument (exp, 2); --+ int op0_num = return_p ? 1 : 0; --+ int op1_num = return_p ? 2 : 1; --+ int op2_num = return_p ? 3 : 2; --+ --+ if (return_p) --+ target = nds32_legitimize_target (icode, target); --+ --+ op0 = nds32_legitimize_argument (icode, op0_num, op0); --+ op1 = nds32_legitimize_argument (icode, op1_num, op1); --+ op2 = nds32_legitimize_argument (icode, op2_num, op2); --+ --+ /* Emit and return the new instruction. */ --+ if (return_p) --+ pat = GEN_FCN (icode) (target, op0, op1, op2); --+ else --+ pat = GEN_FCN (icode) (op0, op1, op2); --+ --+ if (! pat) --+ return NULL_RTX; --+ --+ emit_insn (pat); --+ return target; --+} --+ --+/* Expand builtins that take three operands and the third is immediate. */ --+static rtx --+nds32_expand_triopimm_builtin (enum insn_code icode, tree exp, rtx target, --+ bool return_p, const char *name) --+{ --+ rtx pat; --+ rtx op0 = nds32_read_argument (exp, 0); --+ rtx op1 = nds32_read_argument (exp, 1); --+ rtx op2 = nds32_read_argument (exp, 2); --+ int op0_num = return_p ? 1 : 0; --+ int op1_num = return_p ? 2 : 1; --+ int op2_num = return_p ? 3 : 2; --+ --+ if (return_p) --+ target = nds32_legitimize_target (icode, target); --+ --+ if (!nds32_check_constant_argument (icode, op2_num, op2, name)) --+ return NULL_RTX; --+ --+ op0 = nds32_legitimize_argument (icode, op0_num, op0); --+ op1 = nds32_legitimize_argument (icode, op1_num, op1); --+ op2 = nds32_legitimize_argument (icode, op2_num, op2); --+ --+ /* Emit and return the new instruction. */ --+ if (return_p) --+ pat = GEN_FCN (icode) (target, op0, op1, op2); --+ else --+ pat = GEN_FCN (icode) (op0, op1, op2); --+ --+ if (! pat) --+ return NULL_RTX; --+ --+ emit_insn (pat); --+ return target; --+} --+ --+/* Expand builtins for load. */ --+static rtx --+nds32_expand_builtin_load (enum insn_code icode, tree exp, rtx target) --+{ --+ /* Load address format is [$ra + $rb], --+ but input arguments not enough, --+ so we need another temp register as $rb. --+ Generating assembly code: --+ movi $temp, 0 --+ llw $rt, [$ra + $temp] */ --+ rtx pat; --+ rtx op0 = nds32_read_argument (exp, 0); --+ rtx addr_helper = gen_reg_rtx (insn_data[icode].operand[1].mode); --+ --+ target = nds32_legitimize_target (icode, target); --+ op0 = nds32_legitimize_argument (icode, 1, op0); --+ --+ /* Emit and return the new instruction. */ --+ pat = GEN_FCN (icode) (target, op0, addr_helper); --+ if (!pat) --+ return NULL_RTX; --+ --+ emit_move_insn (addr_helper, GEN_INT (0)); --+ emit_insn (pat); --+ return target; --+} --+ --+/* Expand builtins for store. */ --+static rtx --+nds32_expand_builtin_store (enum insn_code icode, tree exp, rtx target) --+{ --+ /* Store address format is [$ra + $rb], --+ but input arguments not enough, --+ so we need another temp register as $rb. --+ Generating assembly code: --+ movi $temp, 0 --+ store $rt, [$ra + $temp] */ --+ rtx pat; --+ rtx op0 = nds32_read_argument (exp, 0); --+ rtx op1 = nds32_read_argument (exp, 1); --+ rtx addr_helper = gen_reg_rtx (insn_data[icode].operand[1].mode); --+ --+ op0 = nds32_legitimize_argument (icode, 0, op0); --+ op1 = nds32_legitimize_argument (icode, 2, op1); --+ --+ /* Emit and return the new instruction. */ --+ pat = GEN_FCN (icode) (op0, addr_helper, op1); --+ if (! pat) --+ return NULL_RTX; --+ --+ emit_move_insn (addr_helper, GEN_INT (0)); --+ emit_insn (pat); --+ return target; --+} --+ --+/* Expand cctl builtins. */ --+static rtx --+nds32_expand_cctl_builtin (enum insn_code icode, tree exp, rtx target, --+ bool return_p, const char *name) --+{ --+ rtx pat; --+ rtx op0 = nds32_read_argument (exp, 0); --+ rtx op1 = nds32_read_argument (exp, 1); --+ int op0_num = return_p ? 1 : 0; --+ int op1_num = return_p ? 2 : 1; --+ --+ if (return_p) --+ target = nds32_legitimize_target (icode, target); --+ --+ if (!nds32_check_constant_argument (icode, op0_num, op0, name)) --+ return NULL_RTX; --+ --+ op0 = nds32_legitimize_argument (icode, op0_num, op0); --+ op1 = nds32_legitimize_argument (icode, op1_num, op1); --+ --+ /* Emit and return the new instruction. */ --+ if (icode == CODE_FOR_cctl_idx_write) --+ { --+ /* cctl_idx_write is three argument, --+ so create operand2 for cctl_idx_write pattern. */ --+ rtx op2 = nds32_read_argument (exp, 2); --+ op2 = nds32_legitimize_argument (icode, 2, op2); --+ pat = GEN_FCN (icode) (op0, op1, op2); --+ } --+ else if (return_p) --+ pat = GEN_FCN (icode) (target, op0, op1); --+ else --+ pat = GEN_FCN (icode) (op0, op1); --+ --+ if (! pat) --+ return NULL_RTX; --+ --+ emit_insn (pat); --+ return target; --+} --+ --+/* Expand scw builtins. */ --+static rtx --+nds32_expand_scw_builtin (enum insn_code icode, tree exp, rtx target) --+{ --+ /* SCW address format is [$ra + $rb], but input arguments not enough, --+ so we need another temp register as $rb. --+ Generating assembly code: --+ movi $temp, 0 --+ scw $rt, [$ra + $temp] */ --+ rtx pat; --+ rtx op0 = nds32_read_argument (exp, 0); --+ rtx op1 = nds32_read_argument (exp, 1); --+ rtx addr_helper = gen_reg_rtx (insn_data[icode].operand[1].mode); --+ --+ target = nds32_legitimize_target (icode, target); --+ op0 = nds32_legitimize_argument (icode, 1, op0); --+ op1 = nds32_legitimize_argument (icode, 2, op1); --+ --+ /* Emit and return the new instruction. */ --+ pat = GEN_FCN (icode) (target, op0, addr_helper, target); --+ --+ if (!pat) --+ return NULL_RTX; --+ --+ emit_move_insn (addr_helper, GEN_INT (0)); --+ emit_move_insn (target, op1); --+ emit_insn (pat); --+ return target; -- } -- --+/* Expand set int priority builtins. */ --+static rtx --+nds32_expand_priority_builtin (enum insn_code icode, tree exp, rtx target, --+ const char *name) --+{ --+ rtx pat; --+ rtx op0 = nds32_read_argument (exp, 0); --+ rtx op1 = nds32_read_argument (exp, 1); --+ --+ /* set_int_priority intrinsic function that two arguments are immediate, --+ so check whether auguments are immedite. */ --+ --+ if (!nds32_check_constant_argument (icode, 0, op0, name)) --+ return NULL_RTX; --+ --+ if (!nds32_check_constant_argument (icode, 1, op1, name)) --+ return NULL_RTX; --+ --+ op0 = nds32_legitimize_argument (icode, 0, op0); --+ op1 = nds32_legitimize_argument (icode, 1, op1); --+ --+ /* Emit and return the new instruction. */ --+ pat = GEN_FCN (icode) (op0, op1); --+ --+ if (! pat) --+ return NULL_RTX; --+ --+ emit_insn (pat); --+ return target; --+} --+ --+struct builtin_description --+{ --+ const enum insn_code icode; --+ const char *name; --+ enum nds32_builtins code; --+ bool return_p; --+}; --+ --+#define NDS32_BUILTIN(code, string, builtin) \ --+ { CODE_FOR_##code, "__nds32__" string, \ --+ NDS32_BUILTIN_##builtin, true }, --+ --+#define NDS32_NO_TARGET_BUILTIN(code, string, builtin) \ --+ { CODE_FOR_##code, "__nds32__" string, \ --+ NDS32_BUILTIN_##builtin, false }, --+ --+/* Intrinsics that no argument, and that return value. */ --+static struct builtin_description bdesc_noarg[] = --+{ --+ NDS32_BUILTIN(unspec_fmfcfg, "fmfcfg", FMFCFG) --+ NDS32_BUILTIN(unspec_fmfcsr, "fmfcsr", FMFCSR) --+ NDS32_BUILTIN(unspec_volatile_rdov, "rdov", RDOV) --+ NDS32_BUILTIN(unspec_get_current_sp, "get_current_sp", GET_CURRENT_SP) --+ NDS32_BUILTIN(unspec_return_address, "return_address", RETURN_ADDRESS) --+ NDS32_BUILTIN(unspec_get_all_pending_int, "get_all_pending_int", --+ GET_ALL_PENDING_INT) --+ NDS32_BUILTIN(unspec_unaligned_feature, "unaligned_feature", --+ UNALIGNED_FEATURE) --+ NDS32_NO_TARGET_BUILTIN(unspec_enable_unaligned, "enable_unaligned", --+ ENABLE_UNALIGNED) --+ NDS32_NO_TARGET_BUILTIN(unspec_disable_unaligned, "disable_unaligned", --+ DISABLE_UNALIGNED) --+}; --+ --+/* Intrinsics that take just one argument. */ --+static struct builtin_description bdesc_1arg[] = --+{ --+ NDS32_BUILTIN(unspec_ssabssi2, "abs", ABS) --+ NDS32_BUILTIN(clzsi2, "clz", CLZ) --+ NDS32_BUILTIN(unspec_clo, "clo", CLO) --+ NDS32_BUILTIN(unspec_wsbh, "wsbh", WSBH) --+ NDS32_BUILTIN(unspec_tlbop_pb, "tlbop_pb",TLBOP_PB) --+ NDS32_BUILTIN(unaligned_load_hw, "unaligned_load_hw", UALOAD_HW) --+ NDS32_BUILTIN(unaligned_loadsi, "unaligned_load_w", UALOAD_W) --+ NDS32_BUILTIN(unaligned_loaddi, "unaligned_load_dw", UALOAD_DW) --+ NDS32_NO_TARGET_BUILTIN(unspec_volatile_isync, "isync", ISYNC) --+ NDS32_NO_TARGET_BUILTIN(unspec_fmtcsr, "fmtcsr", FMTCSR) --+ NDS32_NO_TARGET_BUILTIN(unspec_jr_itoff, "jr_itoff", JR_ITOFF) --+ NDS32_NO_TARGET_BUILTIN(unspec_jr_toff, "jr_toff", JR_TOFF) --+ NDS32_NO_TARGET_BUILTIN(unspec_jral_ton, "jral_ton", JRAL_TON) --+ NDS32_NO_TARGET_BUILTIN(unspec_ret_toff, "ret_toff", RET_TOFF) --+ NDS32_NO_TARGET_BUILTIN(unspec_jral_iton, "jral_iton",JRAL_ITON) --+ NDS32_NO_TARGET_BUILTIN(unspec_tlbop_trd, "tlbop_trd", TLBOP_TRD) --+ NDS32_NO_TARGET_BUILTIN(unspec_tlbop_twr, "tlbop_twr", TLBOP_TWR) --+ NDS32_NO_TARGET_BUILTIN(unspec_tlbop_rwr, "tlbop_rwr", TLBOP_RWR) --+ NDS32_NO_TARGET_BUILTIN(unspec_tlbop_rwlk, "tlbop_rwlk", TLBOP_RWLK) --+ NDS32_NO_TARGET_BUILTIN(unspec_tlbop_unlk, "tlbop_unlk", TLBOP_UNLK) --+ NDS32_NO_TARGET_BUILTIN(unspec_tlbop_inv, "tlbop_inv", TLBOP_INV) --+ NDS32_NO_TARGET_BUILTIN(unspec_ret_itoff, "ret_itoff", RET_ITOFF) --+ NDS32_NO_TARGET_BUILTIN(unspec_set_current_sp, --+ "set_current_sp", SET_CURRENT_SP) --+ NDS32_BUILTIN(kabsv2hi2, "kabs16", KABS16) --+ NDS32_BUILTIN(kabsv2hi2, "v_kabs16", V_KABS16) --+ NDS32_BUILTIN(kabsv4qi2, "kabs8", KABS8) --+ NDS32_BUILTIN(kabsv4qi2, "v_kabs8", V_KABS8) --+ NDS32_BUILTIN(sunpkd810, "sunpkd810", SUNPKD810) --+ NDS32_BUILTIN(sunpkd810, "v_sunpkd810", V_SUNPKD810) --+ NDS32_BUILTIN(sunpkd820, "sunpkd820", SUNPKD820) --+ NDS32_BUILTIN(sunpkd820, "v_sunpkd820", V_SUNPKD820) --+ NDS32_BUILTIN(sunpkd830, "sunpkd830", SUNPKD830) --+ NDS32_BUILTIN(sunpkd830, "v_sunpkd830", V_SUNPKD830) --+ NDS32_BUILTIN(sunpkd831, "sunpkd831", SUNPKD831) --+ NDS32_BUILTIN(sunpkd831, "v_sunpkd831", V_SUNPKD831) --+ NDS32_BUILTIN(zunpkd810, "zunpkd810", ZUNPKD810) --+ NDS32_BUILTIN(zunpkd810, "v_zunpkd810", V_ZUNPKD810) --+ NDS32_BUILTIN(zunpkd820, "zunpkd820", ZUNPKD820) --+ NDS32_BUILTIN(zunpkd820, "v_zunpkd820", V_ZUNPKD820) --+ NDS32_BUILTIN(zunpkd830, "zunpkd830", ZUNPKD830) --+ NDS32_BUILTIN(zunpkd830, "v_zunpkd830", V_ZUNPKD830) --+ NDS32_BUILTIN(zunpkd831, "zunpkd831", ZUNPKD831) --+ NDS32_BUILTIN(zunpkd831, "v_zunpkd831", V_ZUNPKD831) --+ NDS32_BUILTIN(unspec_kabs, "kabs", KABS) --+ NDS32_BUILTIN(unaligned_loadv2hi, "get_unaligned_u16x2", UALOAD_U16) --+ NDS32_BUILTIN(unaligned_loadv2hi, "get_unaligned_s16x2", UALOAD_S16) --+ NDS32_BUILTIN(unaligned_loadv4qi, "get_unaligned_u8x4", UALOAD_U8) --+ NDS32_BUILTIN(unaligned_loadv4qi, "get_unaligned_s8x4", UALOAD_S8) --+}; --+ --+/* Intrinsics that take just one argument. and the argument is immediate. */ --+static struct builtin_description bdesc_1argimm[] = --+{ --+ NDS32_BUILTIN(unspec_volatile_mfsr, "mfsr", MFSR) --+ NDS32_BUILTIN(unspec_volatile_mfusr, "mfsr", MFUSR) --+ NDS32_BUILTIN(unspec_get_pending_int, "get_pending_int", GET_PENDING_INT) --+ NDS32_BUILTIN(unspec_get_int_priority, "get_int_priority", GET_INT_PRIORITY) --+ NDS32_NO_TARGET_BUILTIN(unspec_trap, "trap", TRAP) --+ NDS32_NO_TARGET_BUILTIN(unspec_break, "break", BREAK) --+ NDS32_NO_TARGET_BUILTIN(unspec_syscall, "syscall", SYSCALL) --+ NDS32_NO_TARGET_BUILTIN(unspec_enable_int, "enable_int", ENABLE_INT) --+ NDS32_NO_TARGET_BUILTIN(unspec_disable_int, "disable_int", DISABLE_INT) --+ NDS32_NO_TARGET_BUILTIN(unspec_clr_pending_hwint, "clr_pending_hwint", --+ CLR_PENDING_HWINT) --+ NDS32_NO_TARGET_BUILTIN(unspec_set_trig_level, "set_trig_level", --+ SET_TRIG_LEVEL) --+ NDS32_NO_TARGET_BUILTIN(unspec_set_trig_edge, "set_trig_edge", --+ SET_TRIG_EDGE) --+ NDS32_BUILTIN(unspec_get_trig_type, "get_trig_type", GET_TRIG_TYPE) --+}; --+ --+/* Intrinsics that take two arguments. */ --+static struct builtin_description bdesc_2arg[] = --+{ --+ NDS32_BUILTIN(unspec_fcpynss, "fcpynss", FCPYNSS) --+ NDS32_BUILTIN(unspec_fcpyss, "fcpyss", FCPYSS) --+ NDS32_BUILTIN(unspec_fcpynsd, "fcpynsd", FCPYNSD) --+ NDS32_BUILTIN(unspec_fcpysd, "fcpysd", FCPYSD) --+ NDS32_BUILTIN(unspec_ave, "ave", AVE) --+ NDS32_BUILTIN(unspec_pbsad, "pbsad", PBSAD) --+ NDS32_BUILTIN(unspec_ffb, "ffb", FFB) --+ NDS32_BUILTIN(unspec_ffmism, "ffmsim", FFMISM) --+ NDS32_BUILTIN(unspec_flmism, "flmism", FLMISM) --+ NDS32_BUILTIN(unspec_kaddw, "kaddw", KADDW) --+ NDS32_BUILTIN(unspec_kaddh, "kaddh", KADDH) --+ NDS32_BUILTIN(unspec_ksubw, "ksubw", KSUBW) --+ NDS32_BUILTIN(unspec_ksubh, "ksubh", KSUBH) --+ NDS32_BUILTIN(unspec_kdmbb, "kdmbb", KDMBB) --+ NDS32_BUILTIN(unspec_kdmbb, "v_kdmbb", V_KDMBB) --+ NDS32_BUILTIN(unspec_kdmbt, "kdmbt", KDMBT) --+ NDS32_BUILTIN(unspec_kdmbt, "v_kdmbt", V_KDMBT) --+ NDS32_BUILTIN(unspec_kdmtb, "kdmtb", KDMTB) --+ NDS32_BUILTIN(unspec_kdmtb, "v_kdmtb", V_KDMTB) --+ NDS32_BUILTIN(unspec_kdmtt, "kdmtt", KDMTT) --+ NDS32_BUILTIN(unspec_kdmtt, "v_kdmtt", V_KDMTT) --+ NDS32_BUILTIN(unspec_khmbb, "khmbb", KHMBB) --+ NDS32_BUILTIN(unspec_khmbb, "v_khmbb", V_KHMBB) --+ NDS32_BUILTIN(unspec_khmbt, "khmbt", KHMBT) --+ NDS32_BUILTIN(unspec_khmbt, "v_khmbt", V_KHMBT) --+ NDS32_BUILTIN(unspec_khmtb, "khmtb", KHMTB) --+ NDS32_BUILTIN(unspec_khmtb, "v_khmtb", V_KHMTB) --+ NDS32_BUILTIN(unspec_khmtt, "khmtt", KHMTT) --+ NDS32_BUILTIN(unspec_khmtt, "v_khmtt", V_KHMTT) --+ NDS32_BUILTIN(unspec_kslraw, "kslraw", KSLRAW) --+ NDS32_BUILTIN(unspec_kslrawu, "kslraw_u", KSLRAW_U) --+ NDS32_BUILTIN(rotrsi3, "rotr", ROTR) --+ NDS32_BUILTIN(unspec_sva, "sva", SVA) --+ NDS32_BUILTIN(unspec_svs, "svs", SVS) --+ NDS32_NO_TARGET_BUILTIN(mtsr_isb, "mtsr_isb", MTSR_ISB) --+ NDS32_NO_TARGET_BUILTIN(mtsr_dsb, "mtsr_dsb", MTSR_DSB) --+ NDS32_NO_TARGET_BUILTIN(unspec_volatile_mtsr, "mtsr", MTSR) --+ NDS32_NO_TARGET_BUILTIN(unspec_volatile_mtusr, "mtusr", MTUSR) --+ NDS32_NO_TARGET_BUILTIN(unaligned_store_hw, "unaligned_store_hw", UASTORE_HW) --+ NDS32_NO_TARGET_BUILTIN(unaligned_storesi, "unaligned_store_hw", UASTORE_W) --+ NDS32_NO_TARGET_BUILTIN(unaligned_storedi, "unaligned_store_hw", UASTORE_DW) --+ NDS32_BUILTIN(addv2hi3, "add16", ADD16) --+ NDS32_BUILTIN(addv2hi3, "v_uadd16", V_UADD16) --+ NDS32_BUILTIN(addv2hi3, "v_sadd16", V_SADD16) --+ NDS32_BUILTIN(raddv2hi3, "radd16", RADD16) --+ NDS32_BUILTIN(raddv2hi3, "v_radd16", V_RADD16) --+ NDS32_BUILTIN(uraddv2hi3, "uradd16", URADD16) --+ NDS32_BUILTIN(uraddv2hi3, "v_uradd16", V_URADD16) --+ NDS32_BUILTIN(kaddv2hi3, "kadd16", KADD16) --+ NDS32_BUILTIN(kaddv2hi3, "v_kadd16", V_KADD16) --+ NDS32_BUILTIN(ukaddv2hi3, "ukadd16", UKADD16) --+ NDS32_BUILTIN(ukaddv2hi3, "v_ukadd16", V_UKADD16) --+ NDS32_BUILTIN(subv2hi3, "sub16", SUB16) --+ NDS32_BUILTIN(subv2hi3, "v_usub16", V_USUB16) --+ NDS32_BUILTIN(subv2hi3, "v_ssub16", V_SSUB16) --+ NDS32_BUILTIN(rsubv2hi3, "rsub16", RSUB16) --+ NDS32_BUILTIN(rsubv2hi3, "v_rsub16", V_RSUB16) --+ NDS32_BUILTIN(ursubv2hi3, "ursub16", URSUB16) --+ NDS32_BUILTIN(ursubv2hi3, "v_ursub16", V_URSUB16) --+ NDS32_BUILTIN(ksubv2hi3, "ksub16", KSUB16) --+ NDS32_BUILTIN(ksubv2hi3, "v_ksub16", V_KSUB16) --+ NDS32_BUILTIN(uksubv2hi3, "uksub16", UKSUB16) --+ NDS32_BUILTIN(uksubv2hi3, "v_uksub16", V_UKSUB16) --+ NDS32_BUILTIN(cras16_1, "cras16", CRAS16) --+ NDS32_BUILTIN(cras16_1, "v_ucras16", V_UCRAS16) --+ NDS32_BUILTIN(cras16_1, "v_scras16", V_SCRAS16) --+ NDS32_BUILTIN(rcras16_1, "rcras16", RCRAS16) --+ NDS32_BUILTIN(rcras16_1, "v_rcras16", V_RCRAS16) --+ NDS32_BUILTIN(urcras16_1, "urcras16", URCRAS16) --+ NDS32_BUILTIN(urcras16_1, "v_urcras16", V_URCRAS16) --+ NDS32_BUILTIN(kcras16_1, "kcras16", KCRAS16) --+ NDS32_BUILTIN(kcras16_1, "v_kcras16", V_KCRAS16) --+ NDS32_BUILTIN(ukcras16_1, "ukcras16", UKCRAS16) --+ NDS32_BUILTIN(ukcras16_1, "v_ukcras16", V_UKCRAS16) --+ NDS32_BUILTIN(crsa16_1, "crsa16", CRSA16) --+ NDS32_BUILTIN(crsa16_1, "v_ucrsa16", V_UCRSA16) --+ NDS32_BUILTIN(crsa16_1, "v_scrsa16", V_SCRSA16) --+ NDS32_BUILTIN(rcrsa16_1, "rcrsa16", RCRSA16) --+ NDS32_BUILTIN(rcrsa16_1, "v_rcrsa16", V_RCRSA16) --+ NDS32_BUILTIN(urcrsa16_1, "urcrsa16", URCRSA16) --+ NDS32_BUILTIN(urcrsa16_1, "v_urcrsa16", V_URCRSA16) --+ NDS32_BUILTIN(kcrsa16_1, "kcrsa16", KCRSA16) --+ NDS32_BUILTIN(kcrsa16_1, "v_kcrsa16", V_KCRSA16) --+ NDS32_BUILTIN(ukcrsa16_1, "ukcrsa16", UKCRSA16) --+ NDS32_BUILTIN(ukcrsa16_1, "v_ukcrsa16", V_UKCRSA16) --+ NDS32_BUILTIN(addv4qi3, "add8", ADD8) --+ NDS32_BUILTIN(addv4qi3, "v_uadd8", V_UADD8) --+ NDS32_BUILTIN(addv4qi3, "v_sadd8", V_SADD8) --+ NDS32_BUILTIN(raddv4qi3, "radd8", RADD8) --+ NDS32_BUILTIN(raddv4qi3, "v_radd8", V_RADD8) --+ NDS32_BUILTIN(uraddv4qi3, "uradd8", URADD8) --+ NDS32_BUILTIN(uraddv4qi3, "v_uradd8", V_URADD8) --+ NDS32_BUILTIN(kaddv4qi3, "kadd8", KADD8) --+ NDS32_BUILTIN(kaddv4qi3, "v_kadd8", V_KADD8) --+ NDS32_BUILTIN(ukaddv4qi3, "ukadd8", UKADD8) --+ NDS32_BUILTIN(ukaddv4qi3, "v_ukadd8", V_UKADD8) --+ NDS32_BUILTIN(subv4qi3, "sub8", SUB8) --+ NDS32_BUILTIN(subv4qi3, "v_usub8", V_USUB8) --+ NDS32_BUILTIN(subv4qi3, "v_ssub8", V_SSUB8) --+ NDS32_BUILTIN(rsubv4qi3, "rsub8", RSUB8) --+ NDS32_BUILTIN(rsubv4qi3, "v_rsub8", V_RSUB8) --+ NDS32_BUILTIN(ursubv4qi3, "ursub8", URSUB8) --+ NDS32_BUILTIN(ursubv4qi3, "v_ursub8", V_URSUB8) --+ NDS32_BUILTIN(ksubv4qi3, "ksub8", KSUB8) --+ NDS32_BUILTIN(ksubv4qi3, "v_ksub8", V_KSUB8) --+ NDS32_BUILTIN(uksubv4qi3, "uksub8", UKSUB8) --+ NDS32_BUILTIN(uksubv4qi3, "v_uksub8", V_UKSUB8) --+ NDS32_BUILTIN(ashrv2hi3, "sra16", SRA16) --+ NDS32_BUILTIN(ashrv2hi3, "v_sra16", V_SRA16) --+ NDS32_BUILTIN(sra16_round, "sra16_u", SRA16_U) --+ NDS32_BUILTIN(sra16_round, "v_sra16_u", V_SRA16_U) --+ NDS32_BUILTIN(lshrv2hi3, "srl16", SRL16) --+ NDS32_BUILTIN(lshrv2hi3, "v_srl16", V_SRL16) --+ NDS32_BUILTIN(srl16_round, "srl16_u", SRL16_U) --+ NDS32_BUILTIN(srl16_round, "v_srl16_u", V_SRL16_U) --+ NDS32_BUILTIN(ashlv2hi3, "sll16", SLL16) --+ NDS32_BUILTIN(ashlv2hi3, "v_sll16", V_SLL16) --+ NDS32_BUILTIN(kslli16, "ksll16", KSLL16) --+ NDS32_BUILTIN(kslli16, "v_ksll16", V_KSLL16) --+ NDS32_BUILTIN(kslra16, "kslra16", KSLRA16) --+ NDS32_BUILTIN(kslra16, "v_kslra16", V_KSLRA16) --+ NDS32_BUILTIN(kslra16_round, "kslra16_u", KSLRA16_U) --+ NDS32_BUILTIN(kslra16_round, "v_kslra16_u", V_KSLRA16_U) --+ NDS32_BUILTIN(cmpeq16, "cmpeq16", CMPEQ16) --+ NDS32_BUILTIN(cmpeq16, "v_scmpeq16", V_SCMPEQ16) --+ NDS32_BUILTIN(cmpeq16, "v_ucmpeq16", V_UCMPEQ16) --+ NDS32_BUILTIN(scmplt16, "scmplt16", SCMPLT16) --+ NDS32_BUILTIN(scmplt16, "v_scmplt16", V_SCMPLT16) --+ NDS32_BUILTIN(scmple16, "scmple16", SCMPLE16) --+ NDS32_BUILTIN(scmple16, "v_scmple16", V_SCMPLE16) --+ NDS32_BUILTIN(ucmplt16, "ucmplt16", UCMPLT16) --+ NDS32_BUILTIN(ucmplt16, "v_ucmplt16", V_UCMPLT16) --+ NDS32_BUILTIN(ucmplt16, "ucmple16", UCMPLE16) --+ NDS32_BUILTIN(ucmplt16, "v_ucmple16", V_UCMPLE16) --+ NDS32_BUILTIN(cmpeq8, "cmpeq8", CMPEQ8) --+ NDS32_BUILTIN(cmpeq8, "v_scmpeq8", V_SCMPEQ8) --+ NDS32_BUILTIN(cmpeq8, "v_ucmpeq8", V_UCMPEQ8) --+ NDS32_BUILTIN(scmplt8, "scmplt8", SCMPLT8) --+ NDS32_BUILTIN(scmplt8, "v_scmplt8", V_SCMPLT8) --+ NDS32_BUILTIN(scmple8, "scmple8", SCMPLE8) --+ NDS32_BUILTIN(scmple8, "v_scmple8", V_SCMPLE8) --+ NDS32_BUILTIN(ucmplt8, "ucmplt8", UCMPLT8) --+ NDS32_BUILTIN(ucmplt8, "v_ucmplt8", V_UCMPLT8) --+ NDS32_BUILTIN(ucmplt8, "ucmple8", UCMPLE8) --+ NDS32_BUILTIN(ucmplt8, "v_ucmple8", V_UCMPLE8) --+ NDS32_BUILTIN(sminv2hi3, "smin16", SMIN16) --+ NDS32_BUILTIN(sminv2hi3, "v_smin16", V_SMIN16) --+ NDS32_BUILTIN(uminv2hi3, "umin16", UMIN16) --+ NDS32_BUILTIN(uminv2hi3, "v_umin16", V_UMIN16) --+ NDS32_BUILTIN(smaxv2hi3, "smax16", SMAX16) --+ NDS32_BUILTIN(smaxv2hi3, "v_smax16", V_SMAX16) --+ NDS32_BUILTIN(umaxv2hi3, "umax16", UMAX16) --+ NDS32_BUILTIN(umaxv2hi3, "v_umax16", V_UMAX16) --+ NDS32_BUILTIN(khm16, "khm16", KHM16) --+ NDS32_BUILTIN(khm16, "v_khm16", V_KHM16) --+ NDS32_BUILTIN(khmx16, "khmx16", KHMX16) --+ NDS32_BUILTIN(khmx16, "v_khmx16", V_KHMX16) --+ NDS32_BUILTIN(sminv4qi3, "smin8", SMIN8) --+ NDS32_BUILTIN(sminv4qi3, "v_smin8", V_SMIN8) --+ NDS32_BUILTIN(uminv4qi3, "umin8", UMIN8) --+ NDS32_BUILTIN(uminv4qi3, "v_umin8", V_UMIN8) --+ NDS32_BUILTIN(smaxv4qi3, "smax8", SMAX8) --+ NDS32_BUILTIN(smaxv4qi3, "v_smax8", V_SMAX8) --+ NDS32_BUILTIN(umaxv4qi3, "umax8", UMAX8) --+ NDS32_BUILTIN(umaxv4qi3, "v_umax8", V_UMAX8) --+ NDS32_BUILTIN(raddsi3, "raddw", RADDW) --+ NDS32_BUILTIN(uraddsi3, "uraddw", URADDW) --+ NDS32_BUILTIN(rsubsi3, "rsubw", RSUBW) --+ NDS32_BUILTIN(ursubsi3, "ursubw", URSUBW) --+ NDS32_BUILTIN(sraiu, "sra_u", SRA_U) --+ NDS32_BUILTIN(kssl, "ksll", KSLL) --+ NDS32_BUILTIN(pkbb, "pkbb16", PKBB16) --+ NDS32_BUILTIN(pkbb, "v_pkbb16", V_PKBB16) --+ NDS32_BUILTIN(pkbt, "pkbt16", PKBT16) --+ NDS32_BUILTIN(pkbt, "v_pkbt16", V_PKBT16) --+ NDS32_BUILTIN(pktb, "pktb16", PKTB16) --+ NDS32_BUILTIN(pktb, "v_pktb16", V_PKTB16) --+ NDS32_BUILTIN(pktt, "pktt16", PKTT16) --+ NDS32_BUILTIN(pktt, "v_pktt16", V_PKTT16) --+ NDS32_BUILTIN(smulsi3_highpart, "smmul", SMMUL) --+ NDS32_BUILTIN(smmul_round, "smmul_u", SMMUL_U) --+ NDS32_BUILTIN(smmwb, "smmwb", SMMWB) --+ NDS32_BUILTIN(smmwb, "v_smmwb", V_SMMWB) --+ NDS32_BUILTIN(smmwb_round, "smmwb_u", SMMWB_U) --+ NDS32_BUILTIN(smmwb_round, "v_smmwb_u", V_SMMWB_U) --+ NDS32_BUILTIN(smmwt, "smmwt", SMMWT) --+ NDS32_BUILTIN(smmwt, "v_smmwt", V_SMMWT) --+ NDS32_BUILTIN(smmwt_round, "smmwt_u", SMMWT_U) --+ NDS32_BUILTIN(smmwt_round, "v_smmwt_u", V_SMMWT_U) --+ NDS32_BUILTIN(smbb, "smbb", SMBB) --+ NDS32_BUILTIN(smbb, "v_smbb", V_SMBB) --+ NDS32_BUILTIN(smbt, "smbt", SMBT) --+ NDS32_BUILTIN(smbt, "v_smbt", V_SMBT) --+ NDS32_BUILTIN(smtt, "smtt", SMTT) --+ NDS32_BUILTIN(smtt, "v_smtt", V_SMTT) --+ NDS32_BUILTIN(kmda, "kmda", KMDA) --+ NDS32_BUILTIN(kmda, "v_kmda", V_KMDA) --+ NDS32_BUILTIN(kmxda, "kmxda", KMXDA) --+ NDS32_BUILTIN(kmxda, "v_kmxda", V_KMXDA) --+ NDS32_BUILTIN(smds, "smds", SMDS) --+ NDS32_BUILTIN(smds, "v_smds", V_SMDS) --+ NDS32_BUILTIN(smdrs, "smdrs", SMDRS) --+ NDS32_BUILTIN(smdrs, "v_smdrs", V_SMDRS) --+ NDS32_BUILTIN(smxdsv, "smxds", SMXDS) --+ NDS32_BUILTIN(smxdsv, "v_smxds", V_SMXDS) --+ NDS32_BUILTIN(smal1, "smal", SMAL) --+ NDS32_BUILTIN(smal1, "v_smal", V_SMAL) --+ NDS32_BUILTIN(bitrev, "bitrev", BITREV) --+ NDS32_BUILTIN(wext, "wext", WEXT) --+ NDS32_BUILTIN(adddi3, "sadd64", SADD64) --+ NDS32_BUILTIN(adddi3, "uadd64", UADD64) --+ NDS32_BUILTIN(radddi3, "radd64", RADD64) --+ NDS32_BUILTIN(uradddi3, "uradd64", URADD64) --+ NDS32_BUILTIN(kadddi3, "kadd64", KADD64) --+ NDS32_BUILTIN(ukadddi3, "ukadd64", UKADD64) --+ NDS32_BUILTIN(subdi3, "ssub64", SSUB64) --+ NDS32_BUILTIN(subdi3, "usub64", USUB64) --+ NDS32_BUILTIN(rsubdi3, "rsub64", RSUB64) --+ NDS32_BUILTIN(ursubdi3, "ursub64", URSUB64) --+ NDS32_BUILTIN(ksubdi3, "ksub64", KSUB64) --+ NDS32_BUILTIN(uksubdi3, "uksub64", UKSUB64) --+ NDS32_BUILTIN(smul16, "smul16", SMUL16) --+ NDS32_BUILTIN(smul16, "v_smul16", V_SMUL16) --+ NDS32_BUILTIN(smulx16, "smulx16", SMULX16) --+ NDS32_BUILTIN(smulx16, "v_smulx16", V_SMULX16) --+ NDS32_BUILTIN(umul16, "umul16", UMUL16) --+ NDS32_BUILTIN(umul16, "v_umul16", V_UMUL16) --+ NDS32_BUILTIN(umulx16, "umulx16", UMULX16) --+ NDS32_BUILTIN(umulx16, "v_umulx16", V_UMULX16) --+ NDS32_BUILTIN(kwmmul, "kwmmul", KWMMUL) --+ NDS32_BUILTIN(kwmmul_round, "kwmmul_u", KWMMUL_U) --+ NDS32_NO_TARGET_BUILTIN(unaligned_storev2hi, --+ "put_unaligned_u16x2", UASTORE_U16) --+ NDS32_NO_TARGET_BUILTIN(unaligned_storev2hi, --+ "put_unaligned_s16x2", UASTORE_S16) --+ NDS32_NO_TARGET_BUILTIN(unaligned_storev4qi, "put_unaligned_u8x4", UASTORE_U8) --+ NDS32_NO_TARGET_BUILTIN(unaligned_storev4qi, "put_unaligned_s8x4", UASTORE_S8) --+}; --+ --+/* Two-argument intrinsics with an immediate second argument. */ --+static struct builtin_description bdesc_2argimm[] = --+{ --+ NDS32_BUILTIN(unspec_bclr, "bclr", BCLR) --+ NDS32_BUILTIN(unspec_bset, "bset", BSET) --+ NDS32_BUILTIN(unspec_btgl, "btgl", BTGL) --+ NDS32_BUILTIN(unspec_btst, "btst", BTST) --+ NDS32_BUILTIN(unspec_clip, "clip", CLIP) --+ NDS32_BUILTIN(unspec_clips, "clips", CLIPS) --+ NDS32_NO_TARGET_BUILTIN(unspec_teqz, "teqz", TEQZ) --+ NDS32_NO_TARGET_BUILTIN(unspec_tnez, "tnez", TNEZ) --+ NDS32_BUILTIN(ashrv2hi3, "srl16", SRL16) --+ NDS32_BUILTIN(ashrv2hi3, "v_srl16", V_SRL16) --+ NDS32_BUILTIN(srl16_round, "srl16_u", SRL16_U) --+ NDS32_BUILTIN(srl16_round, "v_srl16_u", V_SRL16_U) --+ NDS32_BUILTIN(kslli16, "ksll16", KSLL16) --+ NDS32_BUILTIN(kslli16, "v_ksll16", V_KSLL16) --+ NDS32_BUILTIN(sclip16, "sclip16", SCLIP16) --+ NDS32_BUILTIN(sclip16, "v_sclip16", V_SCLIP16) --+ NDS32_BUILTIN(uclip16, "uclip16", UCLIP16) --+ NDS32_BUILTIN(uclip16, "v_uclip16", V_UCLIP16) --+ NDS32_BUILTIN(sraiu, "sra_u", SRA_U) --+ NDS32_BUILTIN(kssl, "ksll", KSLL) --+ NDS32_BUILTIN(bitrev, "bitrev", BITREV) --+ NDS32_BUILTIN(wext, "wext", WEXT) --+ NDS32_BUILTIN(uclip32, "uclip32", UCLIP32) --+ NDS32_BUILTIN(sclip32, "sclip32", SCLIP32) --+}; --+ --+/* Intrinsics that take three arguments. */ --+static struct builtin_description bdesc_3arg[] = --+{ --+ NDS32_BUILTIN(unspec_pbsada, "pbsada", PBSADA) --+ NDS32_NO_TARGET_BUILTIN(bse, "bse", BSE) --+ NDS32_NO_TARGET_BUILTIN(bsp, "bsp", BSP) --+ NDS32_BUILTIN(kmabb, "kmabb", KMABB) --+ NDS32_BUILTIN(kmabb, "v_kmabb", V_KMABB) --+ NDS32_BUILTIN(kmabt, "kmabt", KMABT) --+ NDS32_BUILTIN(kmabt, "v_kmabt", V_KMABT) --+ NDS32_BUILTIN(kmatt, "kmatt", KMATT) --+ NDS32_BUILTIN(kmatt, "v_kmatt", V_KMATT) --+ NDS32_BUILTIN(kmada, "kmada", KMADA) --+ NDS32_BUILTIN(kmada, "v_kmada", V_KMADA) --+ NDS32_BUILTIN(kmaxda, "kmaxda", KMAXDA) --+ NDS32_BUILTIN(kmaxda, "v_kmaxda", V_KMAXDA) --+ NDS32_BUILTIN(kmads, "kmads", KMADS) --+ NDS32_BUILTIN(kmads, "v_kmads", V_KMADS) --+ NDS32_BUILTIN(kmadrs, "kmadrs", KMADRS) --+ NDS32_BUILTIN(kmadrs, "v_kmadrs", V_KMADRS) --+ NDS32_BUILTIN(kmaxds, "kmaxds", KMAXDS) --+ NDS32_BUILTIN(kmaxds, "v_kmaxds", V_KMAXDS) --+ NDS32_BUILTIN(kmsda, "kmsda", KMSDA) --+ NDS32_BUILTIN(kmsda, "v_kmsda", V_KMSDA) --+ NDS32_BUILTIN(kmsxda, "kmsxda", KMSXDA) --+ NDS32_BUILTIN(kmsxda, "v_kmsxda", V_KMSXDA) --+ NDS32_BUILTIN(bpick1, "bpick", BPICK) --+ NDS32_BUILTIN(smar64_1, "smar64", SMAR64) --+ NDS32_BUILTIN(smsr64, "smsr64", SMSR64) --+ NDS32_BUILTIN(umar64_1, "umar64", UMAR64) --+ NDS32_BUILTIN(umsr64, "umsr64", UMSR64) --+ NDS32_BUILTIN(kmar64_1, "kmar64", KMAR64) --+ NDS32_BUILTIN(kmsr64, "kmsr64", KMSR64) --+ NDS32_BUILTIN(ukmar64_1, "ukmar64", UKMAR64) --+ NDS32_BUILTIN(ukmsr64, "ukmsr64", UKMSR64) --+ NDS32_BUILTIN(smalbb, "smalbb", SMALBB) --+ NDS32_BUILTIN(smalbb, "v_smalbb", V_SMALBB) --+ NDS32_BUILTIN(smalbt, "smalbt", SMALBT) --+ NDS32_BUILTIN(smalbt, "v_smalbt", V_SMALBT) --+ NDS32_BUILTIN(smaltt, "smaltt", SMALTT) --+ NDS32_BUILTIN(smaltt, "v_smaltt", V_SMALTT) --+ NDS32_BUILTIN(smalda1, "smalda", SMALDA) --+ NDS32_BUILTIN(smalda1, "v_smalda", V_SMALDA) --+ NDS32_BUILTIN(smalxda1, "smalxda", SMALXDA) --+ NDS32_BUILTIN(smalxda1, "v_smalxda", V_SMALXDA) --+ NDS32_BUILTIN(smalds1, "smalds", SMALDS) --+ NDS32_BUILTIN(smalds1, "v_smalds", V_SMALDS) --+ NDS32_BUILTIN(smaldrs3, "smaldrs", SMALDRS) --+ NDS32_BUILTIN(smaldrs3, "v_smaldrs", V_SMALDRS) --+ NDS32_BUILTIN(smalxds1, "smalxds", SMALXDS) --+ NDS32_BUILTIN(smalxds1, "v_smalxds", V_SMALXDS) --+ NDS32_BUILTIN(smslda1, "smslda", SMSLDA) --+ NDS32_BUILTIN(smslda1, "v_smslda", V_SMSLDA) --+ NDS32_BUILTIN(smslxda1, "smslxda", SMSLXDA) --+ NDS32_BUILTIN(smslxda1, "v_smslxda", V_SMSLXDA) --+ NDS32_BUILTIN(kmmawb, "kmmawb", KMMAWB) --+ NDS32_BUILTIN(kmmawb, "v_kmmawb", V_KMMAWB) --+ NDS32_BUILTIN(kmmawb_round, "kmmawb_u", KMMAWB_U) --+ NDS32_BUILTIN(kmmawb_round, "v_kmmawb_u", V_KMMAWB_U) --+ NDS32_BUILTIN(kmmawt, "kmmawt", KMMAWT) --+ NDS32_BUILTIN(kmmawt, "v_kmmawt", V_KMMAWT) --+ NDS32_BUILTIN(kmmawt_round, "kmmawt_u", KMMAWT_U) --+ NDS32_BUILTIN(kmmawt_round, "v_kmmawt_u", V_KMMAWT_U) --+ NDS32_BUILTIN(kmmac, "kmmac", KMMAC) --+ NDS32_BUILTIN(kmmac_round, "kmmac_u", KMMAC_U) --+ NDS32_BUILTIN(kmmsb, "kmmsb", KMMSB) --+ NDS32_BUILTIN(kmmsb_round, "kmmsb_u", KMMSB_U) --+}; --+ --+/* Three-argument intrinsics with an immediate third argument. */ --+static struct builtin_description bdesc_3argimm[] = --+{ --+ NDS32_NO_TARGET_BUILTIN(prefetch_qw, "prefetch_qw", DPREF_QW) --+ NDS32_NO_TARGET_BUILTIN(prefetch_hw, "prefetch_hw", DPREF_HW) --+ NDS32_NO_TARGET_BUILTIN(prefetch_w, "prefetch_w", DPREF_W) --+ NDS32_NO_TARGET_BUILTIN(prefetch_dw, "prefetch_dw", DPREF_DW) --+ NDS32_BUILTIN(insb, "insb", INSB) --+}; --+ --+/* Intrinsics that load a value. */ --+static struct builtin_description bdesc_load[] = --+{ --+ NDS32_BUILTIN(unspec_volatile_llw, "llw", LLW) --+ NDS32_BUILTIN(unspec_lwup, "lwup", LWUP) --+ NDS32_BUILTIN(unspec_lbup, "lbup", LBUP) --+}; --+ --+/* Intrinsics that store a value. */ --+static struct builtin_description bdesc_store[] = --+{ --+ NDS32_BUILTIN(unspec_swup, "swup", SWUP) --+ NDS32_BUILTIN(unspec_sbup, "sbup", SBUP) --+}; --+ --+static struct builtin_description bdesc_cctl[] = --+{ --+ NDS32_BUILTIN(cctl_idx_read, "cctl_idx_read", CCTL_IDX_READ) --+ NDS32_NO_TARGET_BUILTIN(cctl_idx_write, "cctl_idx_write", CCTL_IDX_WRITE) --+ NDS32_NO_TARGET_BUILTIN(cctl_va_lck, "cctl_va_lck", CCTL_VA_LCK) --+ NDS32_NO_TARGET_BUILTIN(cctl_idx_wbinval, --+ "cctl_idx_wbinval", CCTL_IDX_WBINVAL) --+ NDS32_NO_TARGET_BUILTIN(cctl_va_wbinval_l1, --+ "cctl_va_wbinval_l1", CCTL_VA_WBINVAL_L1) --+ NDS32_NO_TARGET_BUILTIN(cctl_va_wbinval_la, --+ "cctl_va_wbinval_la", CCTL_VA_WBINVAL_LA) --+}; -- -- rtx -- nds32_expand_builtin_impl (tree exp, -- rtx target, -- rtx subtarget ATTRIBUTE_UNUSED, --- machine_mode mode ATTRIBUTE_UNUSED, --+ enum machine_mode mode ATTRIBUTE_UNUSED, -- int ignore ATTRIBUTE_UNUSED) -- { -- tree fndecl = TREE_OPERAND (CALL_EXPR_FN (exp), 0); --+ unsigned int fcode = DECL_FUNCTION_CODE (fndecl); --+ unsigned i; --+ struct builtin_description *d; --+ --+ if (!NDS32_EXT_DSP_P () --+ && fcode > NDS32_BUILTIN_DSP_BEGIN --+ && fcode < NDS32_BUILTIN_DSP_END) --+ error ("don't support DSP extension instructions"); --+ --+ switch (fcode) --+ { --+ /* FPU Register Transfer. */ --+ case NDS32_BUILTIN_FMFCFG: --+ case NDS32_BUILTIN_FMFCSR: --+ case NDS32_BUILTIN_FMTCSR: --+ case NDS32_BUILTIN_FCPYNSS: --+ case NDS32_BUILTIN_FCPYSS: --+ /* Both v3s and v3f toolchains define TARGET_FPU_SINGLE. */ --+ if (!TARGET_FPU_SINGLE) --+ { --+ error ("this builtin function is only available " --+ "on the v3s or v3f toolchain"); --+ return NULL_RTX; --+ } --+ break; --+ --+ /* FPU Register Transfer. */ --+ case NDS32_BUILTIN_FCPYNSD: --+ case NDS32_BUILTIN_FCPYSD: --+ /* Only v3f toolchain defines TARGET_FPU_DOUBLE. */ --+ if (!TARGET_FPU_DOUBLE) --+ { --+ error ("this builtin function is only available " --+ "on the v3f toolchain"); --+ return NULL_RTX; --+ } --+ break; --+ --+ /* Load and Store */ --+ case NDS32_BUILTIN_LLW: --+ case NDS32_BUILTIN_LWUP: --+ case NDS32_BUILTIN_LBUP: --+ case NDS32_BUILTIN_SCW: --+ case NDS32_BUILTIN_SWUP: --+ case NDS32_BUILTIN_SBUP: --+ if (TARGET_ISA_V3M) --+ { --+ error ("this builtin function not support " --+ "on the v3m toolchain"); --+ return NULL_RTX; --+ } --+ break; --+ --+ /* Performance Extension */ --+ case NDS32_BUILTIN_ABS: --+ case NDS32_BUILTIN_AVE: --+ case NDS32_BUILTIN_BCLR: --+ case NDS32_BUILTIN_BSET: --+ case NDS32_BUILTIN_BTGL: --+ case NDS32_BUILTIN_BTST: --+ case NDS32_BUILTIN_CLIP: --+ case NDS32_BUILTIN_CLIPS: --+ case NDS32_BUILTIN_CLZ: --+ case NDS32_BUILTIN_CLO: --+ if (!TARGET_EXT_PERF) --+ { --+ error ("don't support performance extension instructions"); --+ return NULL_RTX; --+ } --+ break; --+ --+ /* Performance Extension 2 */ --+ case NDS32_BUILTIN_PBSAD: --+ case NDS32_BUILTIN_PBSADA: --+ case NDS32_BUILTIN_BSE: --+ case NDS32_BUILTIN_BSP: --+ if (!TARGET_EXT_PERF2) --+ { --+ error ("don't support performance extension " --+ "version 2 instructions"); --+ return NULL_RTX; --+ } --+ break; -- --- int fcode = DECL_FUNCTION_CODE (fndecl); --+ /* String Extension */ --+ case NDS32_BUILTIN_FFB: --+ case NDS32_BUILTIN_FFMISM: --+ case NDS32_BUILTIN_FLMISM: --+ if (!TARGET_EXT_STRING) --+ { --+ error ("don't support string extension instructions"); --+ return NULL_RTX; --+ } --+ break; -- --+ default: --+ break; --+ } --+ --+ /* Since there are no result and operands, we can simply emit this rtx. */ -- switch (fcode) -- { --- /* Cache. */ --- case NDS32_BUILTIN_ISYNC: --- return nds32_expand_builtin_null_ftype_reg --- (CODE_FOR_unspec_volatile_isync, exp, target); -- case NDS32_BUILTIN_ISB: --- /* Since there are no result and operands for isb instruciton, --- we can simply emit this rtx. */ -- emit_insn (gen_unspec_volatile_isb ()); -- return target; --- --- /* Register Transfer. */ --- case NDS32_BUILTIN_MFSR: --- return nds32_expand_builtin_reg_ftype_imm --- (CODE_FOR_unspec_volatile_mfsr, exp, target); --- case NDS32_BUILTIN_MFUSR: --- return nds32_expand_builtin_reg_ftype_imm --- (CODE_FOR_unspec_volatile_mfusr, exp, target); --- case NDS32_BUILTIN_MTSR: --- return nds32_expand_builtin_null_ftype_reg_imm --- (CODE_FOR_unspec_volatile_mtsr, exp, target); --- case NDS32_BUILTIN_MTUSR: --- return nds32_expand_builtin_null_ftype_reg_imm --- (CODE_FOR_unspec_volatile_mtusr, exp, target); --- --- /* Interrupt. */ --+ case NDS32_BUILTIN_DSB: --+ emit_insn (gen_unspec_dsb ()); --+ return target; --+ case NDS32_BUILTIN_MSYNC_ALL: --+ emit_insn (gen_unspec_msync_all ()); --+ return target; --+ case NDS32_BUILTIN_MSYNC_STORE: --+ emit_insn (gen_unspec_msync_store ()); --+ return target; -- case NDS32_BUILTIN_SETGIE_EN: --- /* Since there are no result and operands for setgie.e instruciton, --- we can simply emit this rtx. */ -- emit_insn (gen_unspec_volatile_setgie_en ()); --+ emit_insn (gen_unspec_dsb ()); -- return target; -- case NDS32_BUILTIN_SETGIE_DIS: --- /* Since there are no result and operands for setgie.d instruciton, --- we can simply emit this rtx. */ -- emit_insn (gen_unspec_volatile_setgie_dis ()); --+ emit_insn (gen_unspec_dsb ()); --+ return target; --+ case NDS32_BUILTIN_GIE_DIS: --+ emit_insn (gen_unspec_volatile_setgie_dis ()); --+ emit_insn (gen_unspec_dsb ()); --+ return target; --+ case NDS32_BUILTIN_GIE_EN: --+ emit_insn (gen_unspec_volatile_setgie_en ()); --+ emit_insn (gen_unspec_dsb ()); --+ return target; --+ case NDS32_BUILTIN_SET_PENDING_SWINT: --+ emit_insn (gen_unspec_set_pending_swint ()); --+ return target; --+ case NDS32_BUILTIN_CLR_PENDING_SWINT: --+ emit_insn (gen_unspec_clr_pending_swint ()); --+ return target; --+ case NDS32_BUILTIN_CCTL_L1D_INVALALL: --+ emit_insn (gen_cctl_l1d_invalall()); --+ return target; --+ case NDS32_BUILTIN_CCTL_L1D_WBALL_ALVL: --+ emit_insn (gen_cctl_l1d_wball_alvl()); --+ return target; --+ case NDS32_BUILTIN_CCTL_L1D_WBALL_ONE_LVL: --+ emit_insn (gen_cctl_l1d_wball_one_lvl()); --+ return target; --+ case NDS32_BUILTIN_CLROV: --+ emit_insn (gen_unspec_volatile_clrov ()); --+ return target; --+ case NDS32_BUILTIN_STANDBY_NO_WAKE_GRANT: --+ emit_insn (gen_unspec_standby_no_wake_grant ()); --+ return target; --+ case NDS32_BUILTIN_STANDBY_WAKE_GRANT: --+ emit_insn (gen_unspec_standby_wake_grant ()); --+ return target; --+ case NDS32_BUILTIN_STANDBY_WAKE_DONE: --+ emit_insn (gen_unspec_standby_wait_done ()); --+ return target; --+ case NDS32_BUILTIN_SETEND_BIG: --+ emit_insn (gen_unspec_setend_big ()); --+ return target; --+ case NDS32_BUILTIN_SETEND_LITTLE: --+ emit_insn (gen_unspec_setend_little ()); --+ return target; --+ case NDS32_BUILTIN_NOP: --+ emit_insn (gen_unspec_nop ()); --+ return target; --+ case NDS32_BUILTIN_SCHE_BARRIER: --+ emit_insn (gen_blockage ()); --+ return target; --+ case NDS32_BUILTIN_TLBOP_FLUA: --+ emit_insn (gen_unspec_tlbop_flua ()); --+ return target; --+ /* Instruction sequence protection */ --+ case NDS32_BUILTIN_SIGNATURE_BEGIN: --+ emit_insn (gen_unspec_signature_begin ()); --+ return target; --+ case NDS32_BUILTIN_SIGNATURE_END: --+ emit_insn (gen_unspec_signature_end ()); --+ return target; --+ case NDS32_BUILTIN_SCW: --+ return nds32_expand_scw_builtin (CODE_FOR_unspec_volatile_scw, --+ exp, target); --+ case NDS32_BUILTIN_SET_INT_PRIORITY: --+ return nds32_expand_priority_builtin (CODE_FOR_unspec_set_int_priority, --+ exp, target, --+ "__nds32__set_int_priority"); --+ case NDS32_BUILTIN_NO_HWLOOP: --+ emit_insn (gen_no_hwloop ()); -- return target; --- -- default: --- gcc_unreachable (); --+ break; -- } -- --+ /* Expand groups of builtins. */ --+ for (i = 0, d = bdesc_noarg; i < ARRAY_SIZE (bdesc_noarg); i++, d++) --+ if (d->code == fcode) --+ return nds32_expand_noarg_builtin (d->icode, target); --+ --+ for (i = 0, d = bdesc_1arg; i < ARRAY_SIZE (bdesc_1arg); i++, d++) --+ if (d->code == fcode) --+ return nds32_expand_unop_builtin (d->icode, exp, target, d->return_p); --+ --+ for (i = 0, d = bdesc_1argimm; i < ARRAY_SIZE (bdesc_1argimm); i++, d++) --+ if (d->code == fcode) --+ return nds32_expand_unopimm_builtin (d->icode, exp, target, --+ d->return_p, d->name); --+ --+ for (i = 0, d = bdesc_2arg; i < ARRAY_SIZE (bdesc_2arg); i++, d++) --+ if (d->code == fcode) --+ return nds32_expand_binop_builtin (d->icode, exp, target, d->return_p); --+ --+ for (i = 0, d = bdesc_2argimm; i < ARRAY_SIZE (bdesc_2argimm); i++, d++) --+ if (d->code == fcode) --+ return nds32_expand_binopimm_builtin (d->icode, exp, target, --+ d->return_p, d->name); --+ --+ for (i = 0, d = bdesc_3arg; i < ARRAY_SIZE (bdesc_3arg); i++, d++) --+ if (d->code == fcode) --+ return nds32_expand_triop_builtin (d->icode, exp, target, d->return_p); --+ --+ for (i = 0, d = bdesc_3argimm; i < ARRAY_SIZE (bdesc_3argimm); i++, d++) --+ if (d->code == fcode) --+ return nds32_expand_triopimm_builtin (d->icode, exp, target, --+ d->return_p, d->name); --+ --+ for (i = 0, d = bdesc_load; i < ARRAY_SIZE (bdesc_load); i++, d++) --+ if (d->code == fcode) --+ return nds32_expand_builtin_load (d->icode, exp, target); --+ --+ for (i = 0, d = bdesc_store; i < ARRAY_SIZE (bdesc_store); i++, d++) --+ if (d->code == fcode) --+ return nds32_expand_builtin_store (d->icode, exp, target); --+ --+ for (i = 0, d = bdesc_cctl; i < ARRAY_SIZE (bdesc_cctl); i++, d++) --+ if (d->code == fcode) --+ return nds32_expand_cctl_builtin (d->icode, exp, target, --+ d->return_p, d->name); --+ -- return NULL_RTX; -- } -- --+static GTY(()) tree nds32_builtin_decls[NDS32_BUILTIN_COUNT]; --+ --+/* Return the NDS32 builtin for CODE. */ --+tree --+nds32_builtin_decl_impl (unsigned code, bool initialize_p ATTRIBUTE_UNUSED) --+{ --+ if (code >= NDS32_BUILTIN_COUNT) --+ return error_mark_node; --+ --+ return nds32_builtin_decls[code]; --+} --+ --+void --+nds32_init_builtins_impl (void) --+{ --+#define ADD_NDS32_BUILTIN0(NAME, RET_TYPE, CODE) \ --+ nds32_builtin_decls[NDS32_BUILTIN_ ## CODE] = \ --+ add_builtin_function ("__builtin_nds32_" NAME, \ --+ build_function_type_list (RET_TYPE##_type_node, \ --+ NULL_TREE), \ --+ NDS32_BUILTIN_ ## CODE, BUILT_IN_MD, NULL, NULL_TREE) --+ --+#define ADD_NDS32_BUILTIN1(NAME, RET_TYPE, ARG_TYPE, CODE) \ --+ nds32_builtin_decls[NDS32_BUILTIN_ ## CODE] = \ --+ add_builtin_function ("__builtin_nds32_" NAME, \ --+ build_function_type_list (RET_TYPE##_type_node, \ --+ ARG_TYPE##_type_node, \ --+ NULL_TREE), \ --+ NDS32_BUILTIN_ ## CODE, BUILT_IN_MD, NULL, NULL_TREE) --+ --+#define ADD_NDS32_BUILTIN2(NAME, RET_TYPE, ARG_TYPE1, ARG_TYPE2, CODE) \ --+ nds32_builtin_decls[NDS32_BUILTIN_ ## CODE] = \ --+ add_builtin_function ("__builtin_nds32_" NAME, \ --+ build_function_type_list (RET_TYPE##_type_node, \ --+ ARG_TYPE1##_type_node,\ --+ ARG_TYPE2##_type_node,\ --+ NULL_TREE), \ --+ NDS32_BUILTIN_ ## CODE, BUILT_IN_MD, NULL, NULL_TREE) --+ --+#define ADD_NDS32_BUILTIN3(NAME, RET_TYPE, ARG_TYPE1, ARG_TYPE2, ARG_TYPE3, CODE) \ --+ nds32_builtin_decls[NDS32_BUILTIN_ ## CODE] = \ --+ add_builtin_function ("__builtin_nds32_" NAME, \ --+ build_function_type_list (RET_TYPE##_type_node, \ --+ ARG_TYPE1##_type_node,\ --+ ARG_TYPE2##_type_node,\ --+ ARG_TYPE3##_type_node,\ --+ NULL_TREE), \ --+ NDS32_BUILTIN_ ## CODE, BUILT_IN_MD, NULL, NULL_TREE) --+ --+ /* Looking for return type and argument can be found in tree.h file. */ --+ tree ptr_char_type_node = build_pointer_type (char_type_node); --+ tree ptr_uchar_type_node = build_pointer_type (unsigned_char_type_node); --+ tree ptr_ushort_type_node = build_pointer_type (short_unsigned_type_node); --+ tree ptr_short_type_node = build_pointer_type (short_integer_type_node); --+ tree ptr_uint_type_node = build_pointer_type (unsigned_type_node); --+ tree ptr_ulong_type_node = build_pointer_type (long_long_unsigned_type_node); --+ tree v4qi_type_node = build_vector_type (intQI_type_node, 4); --+ tree u_v4qi_type_node = build_vector_type (unsigned_intQI_type_node, 4); --+ tree v2hi_type_node = build_vector_type (intHI_type_node, 2); --+ tree u_v2hi_type_node = build_vector_type (unsigned_intHI_type_node, 2); --+ tree v2si_type_node = build_vector_type (intSI_type_node, 2); --+ tree u_v2si_type_node = build_vector_type (unsigned_intSI_type_node, 2); --+ --+ /* Cache. */ --+ ADD_NDS32_BUILTIN1 ("isync", void, ptr_uint, ISYNC); --+ ADD_NDS32_BUILTIN0 ("isb", void, ISB); --+ ADD_NDS32_BUILTIN0 ("dsb", void, DSB); --+ ADD_NDS32_BUILTIN0 ("msync_all", void, MSYNC_ALL); --+ ADD_NDS32_BUILTIN0 ("msync_store", void, MSYNC_STORE); --+ --+ /* Register Transfer. */ --+ ADD_NDS32_BUILTIN1 ("mfsr", unsigned, integer, MFSR); --+ ADD_NDS32_BUILTIN1 ("mfusr", unsigned, integer, MFUSR); --+ ADD_NDS32_BUILTIN2 ("mtsr", void, unsigned, integer, MTSR); --+ ADD_NDS32_BUILTIN2 ("mtsr_isb", void, unsigned, integer, MTSR_ISB); --+ ADD_NDS32_BUILTIN2 ("mtsr_dsb", void, unsigned, integer, MTSR_DSB); --+ ADD_NDS32_BUILTIN2 ("mtusr", void, unsigned, integer, MTUSR); --+ --+ /* FPU Register Transfer. */ --+ ADD_NDS32_BUILTIN0 ("fmfcsr", unsigned, FMFCSR); --+ ADD_NDS32_BUILTIN1 ("fmtcsr", void, unsigned, FMTCSR); --+ ADD_NDS32_BUILTIN0 ("fmfcfg", unsigned, FMFCFG); --+ ADD_NDS32_BUILTIN2 ("fcpyss", float, float, float, FCPYSS); --+ ADD_NDS32_BUILTIN2 ("fcpynss", float, float, float, FCPYNSS); --+ ADD_NDS32_BUILTIN2 ("fcpysd", double, double, double, FCPYSD); --+ ADD_NDS32_BUILTIN2 ("fcpynsd", double, double, double, FCPYNSD); --+ --+ /* Interrupt. */ --+ ADD_NDS32_BUILTIN0 ("setgie_en", void, SETGIE_EN); --+ ADD_NDS32_BUILTIN0 ("setgie_dis", void, SETGIE_DIS); --+ ADD_NDS32_BUILTIN0 ("gie_en", void, GIE_EN); --+ ADD_NDS32_BUILTIN0 ("gie_dis", void, GIE_DIS); --+ ADD_NDS32_BUILTIN1 ("enable_int", void, integer, ENABLE_INT); --+ ADD_NDS32_BUILTIN1 ("disable_int", void, integer, DISABLE_INT); --+ ADD_NDS32_BUILTIN0 ("set_pending_swint", void, SET_PENDING_SWINT); --+ ADD_NDS32_BUILTIN0 ("clr_pending_swint", void, CLR_PENDING_SWINT); --+ ADD_NDS32_BUILTIN0 ("get_all_pending_int", unsigned, GET_ALL_PENDING_INT); --+ ADD_NDS32_BUILTIN1 ("get_pending_int", unsigned, integer, GET_PENDING_INT); --+ ADD_NDS32_BUILTIN1 ("get_int_priority", unsigned, integer, GET_INT_PRIORITY); --+ ADD_NDS32_BUILTIN2 ("set_int_priority", void, integer, integer, --+ SET_INT_PRIORITY); --+ ADD_NDS32_BUILTIN1 ("clr_pending_hwint", void, integer, CLR_PENDING_HWINT); --+ ADD_NDS32_BUILTIN1 ("set_trig_level", void, integer, SET_TRIG_LEVEL); --+ ADD_NDS32_BUILTIN1 ("set_trig_edge", void, integer, SET_TRIG_EDGE); --+ ADD_NDS32_BUILTIN1 ("get_trig_type", unsigned, integer, GET_TRIG_TYPE); --+ --+ /* Load and Store */ --+ ADD_NDS32_BUILTIN1 ("llw", unsigned, ptr_uint, LLW); --+ ADD_NDS32_BUILTIN1 ("lwup", unsigned, ptr_uint, LWUP); --+ ADD_NDS32_BUILTIN1 ("lbup", char, ptr_uchar, LBUP); --+ ADD_NDS32_BUILTIN2 ("scw", unsigned, ptr_uint, unsigned, SCW); --+ ADD_NDS32_BUILTIN2 ("swup", void, ptr_uint, unsigned, SWUP); --+ ADD_NDS32_BUILTIN2 ("sbup", void, ptr_uchar, char, SBUP); --+ --+ /* CCTL */ --+ ADD_NDS32_BUILTIN0 ("cctl_l1d_invalall", void, CCTL_L1D_INVALALL); --+ ADD_NDS32_BUILTIN0 ("cctl_l1d_wball_alvl", void, CCTL_L1D_WBALL_ALVL); --+ ADD_NDS32_BUILTIN0 ("cctl_l1d_wball_one_lvl", void, CCTL_L1D_WBALL_ONE_LVL); --+ ADD_NDS32_BUILTIN2 ("cctl_va_lck", void, integer, ptr_uint, CCTL_VA_LCK); --+ ADD_NDS32_BUILTIN2 ("cctl_idx_wbinval", void, integer, unsigned, --+ CCTL_IDX_WBINVAL); --+ ADD_NDS32_BUILTIN2 ("cctl_va_wbinval_l1", void, integer, ptr_uint, --+ CCTL_VA_WBINVAL_L1); --+ ADD_NDS32_BUILTIN2 ("cctl_va_wbinval_la", void, integer, ptr_uint, --+ CCTL_VA_WBINVAL_LA); --+ ADD_NDS32_BUILTIN2 ("cctl_idx_read", unsigned, integer, unsigned, --+ CCTL_IDX_READ); --+ ADD_NDS32_BUILTIN3 ("cctl_idx_write", void, integer, unsigned, unsigned, --+ CCTL_IDX_WRITE); --+ --+ /* PREFETCH */ --+ ADD_NDS32_BUILTIN3 ("dpref_qw", void, ptr_uchar, unsigned, integer, DPREF_QW); --+ ADD_NDS32_BUILTIN3 ("dpref_hw", void, ptr_ushort, unsigned, integer, --+ DPREF_HW); --+ ADD_NDS32_BUILTIN3 ("dpref_w", void, ptr_uint, unsigned, integer, DPREF_W); --+ ADD_NDS32_BUILTIN3 ("dpref_dw", void, ptr_ulong, unsigned, integer, DPREF_DW); --+ --+ /* Performance Extension */ --+ ADD_NDS32_BUILTIN1 ("pe_abs", integer, integer, ABS); --+ ADD_NDS32_BUILTIN2 ("pe_ave", integer, integer, integer, AVE); --+ ADD_NDS32_BUILTIN2 ("pe_bclr", unsigned, unsigned, unsigned, BCLR); --+ ADD_NDS32_BUILTIN2 ("pe_bset", unsigned, unsigned, unsigned, BSET); --+ ADD_NDS32_BUILTIN2 ("pe_btgl", unsigned, unsigned, unsigned, BTGL); --+ ADD_NDS32_BUILTIN2 ("pe_btst", unsigned, unsigned, unsigned, BTST); --+ ADD_NDS32_BUILTIN2 ("pe_clip", unsigned, integer, unsigned, CLIP); --+ ADD_NDS32_BUILTIN2 ("pe_clips", integer, integer, unsigned, CLIPS); --+ ADD_NDS32_BUILTIN1 ("pe_clz", unsigned, unsigned, CLZ); --+ ADD_NDS32_BUILTIN1 ("pe_clo", unsigned, unsigned, CLO); --+ --+ /* Performance Extension 2 */ --+ ADD_NDS32_BUILTIN3 ("pe2_bse", void, ptr_uint, unsigned, ptr_uint, BSE); --+ ADD_NDS32_BUILTIN3 ("pe2_bsp", void, ptr_uint, unsigned, ptr_uint, BSP); --+ ADD_NDS32_BUILTIN2 ("pe2_pbsad", unsigned, unsigned, unsigned, PBSAD); --+ ADD_NDS32_BUILTIN3 ("pe2_pbsada", unsigned, unsigned, unsigned, unsigned, --+ PBSADA); --+ --+ /* String Extension */ --+ ADD_NDS32_BUILTIN2 ("se_ffb", integer, unsigned, unsigned, FFB); --+ ADD_NDS32_BUILTIN2 ("se_ffmism", integer, unsigned, unsigned, FFMISM); --+ ADD_NDS32_BUILTIN2 ("se_flmism", integer, unsigned, unsigned, FLMISM); --+ --+ /* SATURATION */ --+ ADD_NDS32_BUILTIN2 ("kaddw", integer, integer, integer, KADDW); --+ ADD_NDS32_BUILTIN2 ("ksubw", integer, integer, integer, KSUBW); --+ ADD_NDS32_BUILTIN2 ("kaddh", integer, integer, integer, KADDH); --+ ADD_NDS32_BUILTIN2 ("ksubh", integer, integer, integer, KSUBH); --+ ADD_NDS32_BUILTIN2 ("kdmbb", integer, unsigned, unsigned, KDMBB); --+ ADD_NDS32_BUILTIN2 ("v_kdmbb", integer, v2hi, v2hi, V_KDMBB); --+ ADD_NDS32_BUILTIN2 ("kdmbt", integer, unsigned, unsigned, KDMBT); --+ ADD_NDS32_BUILTIN2 ("v_kdmbt", integer, v2hi, v2hi, V_KDMBT); --+ ADD_NDS32_BUILTIN2 ("kdmtb", integer, unsigned, unsigned, KDMTB); --+ ADD_NDS32_BUILTIN2 ("v_kdmtb", integer, v2hi, v2hi, V_KDMTB); --+ ADD_NDS32_BUILTIN2 ("kdmtt", integer, unsigned, unsigned, KDMTT); --+ ADD_NDS32_BUILTIN2 ("v_kdmtt", integer, v2hi, v2hi, V_KDMTT); --+ ADD_NDS32_BUILTIN2 ("khmbb", integer, unsigned, unsigned, KHMBB); --+ ADD_NDS32_BUILTIN2 ("v_khmbb", integer, v2hi, v2hi, V_KHMBB); --+ ADD_NDS32_BUILTIN2 ("khmbt", integer, unsigned, unsigned, KHMBT); --+ ADD_NDS32_BUILTIN2 ("v_khmbt", integer, v2hi, v2hi, V_KHMBT); --+ ADD_NDS32_BUILTIN2 ("khmtb", integer, unsigned, unsigned, KHMTB); --+ ADD_NDS32_BUILTIN2 ("v_khmtb", integer, v2hi, v2hi, V_KHMTB); --+ ADD_NDS32_BUILTIN2 ("khmtt", integer, unsigned, unsigned, KHMTT); --+ ADD_NDS32_BUILTIN2 ("v_khmtt", integer, v2hi, v2hi, V_KHMTT); --+ ADD_NDS32_BUILTIN2 ("kslraw", integer, integer, integer, KSLRAW); --+ ADD_NDS32_BUILTIN2 ("kslraw_u", integer, integer, integer, KSLRAW_U); --+ ADD_NDS32_BUILTIN0 ("rdov", unsigned, RDOV); --+ ADD_NDS32_BUILTIN0 ("clrov", void, CLROV); --+ --+ /* ROTR */ --+ ADD_NDS32_BUILTIN2 ("rotr", unsigned, unsigned, unsigned, ROTR); --+ --+ /* Swap */ --+ ADD_NDS32_BUILTIN1 ("wsbh", unsigned, unsigned, WSBH); --+ --+ /* System */ --+ ADD_NDS32_BUILTIN2 ("svs", unsigned, integer, integer, SVS); --+ ADD_NDS32_BUILTIN2 ("sva", unsigned, integer, integer, SVA); --+ ADD_NDS32_BUILTIN1 ("jr_itoff", void, unsigned, JR_ITOFF); --+ ADD_NDS32_BUILTIN1 ("jr_toff", void, unsigned, JR_TOFF); --+ ADD_NDS32_BUILTIN1 ("jral_iton", void, unsigned, JRAL_ITON); --+ ADD_NDS32_BUILTIN1 ("jral_ton", void, unsigned, JRAL_TON); --+ ADD_NDS32_BUILTIN1 ("ret_itoff", void, unsigned, RET_ITOFF); --+ ADD_NDS32_BUILTIN1 ("ret_toff", void, unsigned, RET_TOFF); --+ ADD_NDS32_BUILTIN0 ("standby_no_wake_grant", void, STANDBY_NO_WAKE_GRANT); --+ ADD_NDS32_BUILTIN0 ("standby_wake_grant", void, STANDBY_WAKE_GRANT); --+ ADD_NDS32_BUILTIN0 ("standby_wait_done", void, STANDBY_WAKE_DONE); --+ ADD_NDS32_BUILTIN1 ("break", void, unsigned, BREAK); --+ ADD_NDS32_BUILTIN1 ("syscall", void, unsigned, SYSCALL); --+ ADD_NDS32_BUILTIN0 ("nop", void, NOP); --+ ADD_NDS32_BUILTIN0 ("get_current_sp", unsigned, GET_CURRENT_SP); --+ ADD_NDS32_BUILTIN1 ("set_current_sp", void, unsigned, SET_CURRENT_SP); --+ ADD_NDS32_BUILTIN2 ("teqz", void, unsigned, unsigned, TEQZ); --+ ADD_NDS32_BUILTIN2 ("tnez", void, unsigned, unsigned, TNEZ); --+ ADD_NDS32_BUILTIN1 ("trap", void, unsigned, TRAP); --+ ADD_NDS32_BUILTIN0 ("return_address", unsigned, RETURN_ADDRESS); --+ ADD_NDS32_BUILTIN0 ("setend_big", void, SETEND_BIG); --+ ADD_NDS32_BUILTIN0 ("setend_little", void, SETEND_LITTLE); --+ --+ /* Schedule Barrier */ --+ ADD_NDS32_BUILTIN0 ("schedule_barrier", void, SCHE_BARRIER); --+ --+ /* TLBOP */ --+ ADD_NDS32_BUILTIN1 ("tlbop_trd", void, unsigned, TLBOP_TRD); --+ ADD_NDS32_BUILTIN1 ("tlbop_twr", void, unsigned, TLBOP_TWR); --+ ADD_NDS32_BUILTIN1 ("tlbop_rwr", void, unsigned, TLBOP_RWR); --+ ADD_NDS32_BUILTIN1 ("tlbop_rwlk", void, unsigned, TLBOP_RWLK); --+ ADD_NDS32_BUILTIN1 ("tlbop_unlk", void, unsigned, TLBOP_UNLK); --+ ADD_NDS32_BUILTIN1 ("tlbop_pb", unsigned, unsigned, TLBOP_PB); --+ ADD_NDS32_BUILTIN1 ("tlbop_inv", void, unsigned, TLBOP_INV); --+ ADD_NDS32_BUILTIN0 ("tlbop_flua", void, TLBOP_FLUA); --+ --+ /* Unaligned Load/Store */ --+ ADD_NDS32_BUILTIN1 ("unaligned_load_hw", short_unsigned, ptr_ushort, --+ UALOAD_HW); --+ ADD_NDS32_BUILTIN1 ("unaligned_load_w", unsigned, ptr_uint, UALOAD_W); --+ ADD_NDS32_BUILTIN1 ("unaligned_load_dw", long_long_unsigned, ptr_ulong, --+ UALOAD_DW); --+ ADD_NDS32_BUILTIN2 ("unaligned_store_hw", void, ptr_ushort, short_unsigned, --+ UASTORE_HW); --+ ADD_NDS32_BUILTIN2 ("unaligned_store_w", void, ptr_uint, unsigned, UASTORE_W); --+ ADD_NDS32_BUILTIN2 ("unaligned_store_dw", void, ptr_ulong, long_long_unsigned, --+ UASTORE_DW); --+ ADD_NDS32_BUILTIN0 ("unaligned_feature", unsigned, UNALIGNED_FEATURE); --+ ADD_NDS32_BUILTIN0 ("enable_unaligned", void, ENABLE_UNALIGNED); --+ ADD_NDS32_BUILTIN0 ("disable_unaligned", void, DISABLE_UNALIGNED); --+ --+ /* Instruction sequence protection */ --+ ADD_NDS32_BUILTIN0 ("signature_begin", void, SIGNATURE_BEGIN); --+ ADD_NDS32_BUILTIN0 ("signature_end", void, SIGNATURE_END); --+ --+ /* DSP Extension: SIMD 16bit Add and Subtract. */ --+ ADD_NDS32_BUILTIN2 ("add16", unsigned, unsigned, unsigned, ADD16); --+ ADD_NDS32_BUILTIN2 ("v_uadd16", u_v2hi, u_v2hi, u_v2hi, V_UADD16); --+ ADD_NDS32_BUILTIN2 ("v_sadd16", v2hi, v2hi, v2hi, V_SADD16); --+ ADD_NDS32_BUILTIN2 ("radd16", unsigned, unsigned, unsigned, RADD16); --+ ADD_NDS32_BUILTIN2 ("v_radd16", v2hi, v2hi, v2hi, V_RADD16); --+ ADD_NDS32_BUILTIN2 ("uradd16", unsigned, unsigned, unsigned, URADD16); --+ ADD_NDS32_BUILTIN2 ("v_uradd16", u_v2hi, u_v2hi, u_v2hi, V_URADD16); --+ ADD_NDS32_BUILTIN2 ("kadd16", unsigned, unsigned, unsigned, KADD16); --+ ADD_NDS32_BUILTIN2 ("v_kadd16", v2hi, v2hi, v2hi, V_KADD16); --+ ADD_NDS32_BUILTIN2 ("ukadd16", unsigned, unsigned, unsigned, UKADD16); --+ ADD_NDS32_BUILTIN2 ("v_ukadd16", u_v2hi, u_v2hi, u_v2hi, V_UKADD16); --+ ADD_NDS32_BUILTIN2 ("sub16", unsigned, unsigned, unsigned, SUB16); --+ ADD_NDS32_BUILTIN2 ("v_usub16", u_v2hi, u_v2hi, u_v2hi, V_USUB16); --+ ADD_NDS32_BUILTIN2 ("v_ssub16", v2hi, v2hi, v2hi, V_SSUB16); --+ ADD_NDS32_BUILTIN2 ("rsub16", unsigned, unsigned, unsigned, RSUB16); --+ ADD_NDS32_BUILTIN2 ("v_rsub16", v2hi, v2hi, v2hi, V_RSUB16); --+ ADD_NDS32_BUILTIN2 ("ursub16", unsigned, unsigned, unsigned, URSUB16); --+ ADD_NDS32_BUILTIN2 ("v_ursub16", u_v2hi, u_v2hi, u_v2hi, V_URSUB16); --+ ADD_NDS32_BUILTIN2 ("ksub16", unsigned, unsigned, unsigned, KSUB16); --+ ADD_NDS32_BUILTIN2 ("v_ksub16", v2hi, v2hi, v2hi, V_KSUB16); --+ ADD_NDS32_BUILTIN2 ("uksub16", unsigned, unsigned, unsigned, UKSUB16); --+ ADD_NDS32_BUILTIN2 ("v_uksub16", u_v2hi, u_v2hi, u_v2hi, V_UKSUB16); --+ ADD_NDS32_BUILTIN2 ("cras16", unsigned, unsigned, unsigned, CRAS16); --+ ADD_NDS32_BUILTIN2 ("v_ucras16", u_v2hi, u_v2hi, u_v2hi, V_UCRAS16); --+ ADD_NDS32_BUILTIN2 ("v_scras16", v2hi, v2hi, v2hi, V_SCRAS16); --+ ADD_NDS32_BUILTIN2 ("rcras16", unsigned, unsigned, unsigned, RCRAS16); --+ ADD_NDS32_BUILTIN2 ("v_rcras16", v2hi, v2hi, v2hi, V_RCRAS16); --+ ADD_NDS32_BUILTIN2 ("urcras16", unsigned, unsigned, unsigned, URCRAS16); --+ ADD_NDS32_BUILTIN2 ("v_urcras16", u_v2hi, u_v2hi, u_v2hi, V_URCRAS16); --+ ADD_NDS32_BUILTIN2 ("kcras16", unsigned, unsigned, unsigned, KCRAS16); --+ ADD_NDS32_BUILTIN2 ("v_kcras16", v2hi, v2hi, v2hi, V_KCRAS16); --+ ADD_NDS32_BUILTIN2 ("ukcras16", unsigned, unsigned, unsigned, UKCRAS16); --+ ADD_NDS32_BUILTIN2 ("v_ukcras16", u_v2hi, u_v2hi, u_v2hi, V_UKCRAS16); --+ ADD_NDS32_BUILTIN2 ("crsa16", unsigned, unsigned, unsigned, CRSA16); --+ ADD_NDS32_BUILTIN2 ("v_ucrsa16", u_v2hi, u_v2hi, u_v2hi, V_UCRSA16); --+ ADD_NDS32_BUILTIN2 ("v_scrsa16", v2hi, v2hi, v2hi, V_SCRSA16); --+ ADD_NDS32_BUILTIN2 ("rcrsa16", unsigned, unsigned, unsigned, RCRSA16); --+ ADD_NDS32_BUILTIN2 ("v_rcrsa16", v2hi, v2hi, v2hi, V_RCRSA16); --+ ADD_NDS32_BUILTIN2 ("urcrsa16", unsigned, unsigned, unsigned, URCRSA16); --+ ADD_NDS32_BUILTIN2 ("v_urcrsa16", u_v2hi, u_v2hi, u_v2hi, V_URCRSA16); --+ ADD_NDS32_BUILTIN2 ("kcrsa16", unsigned, unsigned, unsigned, KCRSA16); --+ ADD_NDS32_BUILTIN2 ("v_kcrsa16", v2hi, v2hi, v2hi, V_KCRSA16); --+ ADD_NDS32_BUILTIN2 ("ukcrsa16", unsigned, unsigned, unsigned, UKCRSA16); --+ ADD_NDS32_BUILTIN2 ("v_ukcrsa16", u_v2hi, u_v2hi, u_v2hi, V_UKCRSA16); --+ --+ /* DSP Extension: SIMD 8bit Add and Subtract. */ --+ ADD_NDS32_BUILTIN2 ("add8", integer, integer, integer, ADD8); --+ ADD_NDS32_BUILTIN2 ("v_uadd8", u_v4qi, u_v4qi, u_v4qi, V_UADD8); --+ ADD_NDS32_BUILTIN2 ("v_sadd8", v4qi, v4qi, v4qi, V_SADD8); --+ ADD_NDS32_BUILTIN2 ("radd8", unsigned, unsigned, unsigned, RADD8); --+ ADD_NDS32_BUILTIN2 ("v_radd8", v4qi, v4qi, v4qi, V_RADD8); --+ ADD_NDS32_BUILTIN2 ("uradd8", unsigned, unsigned, unsigned, URADD8); --+ ADD_NDS32_BUILTIN2 ("v_uradd8", u_v4qi, u_v4qi, u_v4qi, V_URADD8); --+ ADD_NDS32_BUILTIN2 ("kadd8", unsigned, unsigned, unsigned, KADD8); --+ ADD_NDS32_BUILTIN2 ("v_kadd8", v4qi, v4qi, v4qi, V_KADD8); --+ ADD_NDS32_BUILTIN2 ("ukadd8", unsigned, unsigned, unsigned, UKADD8); --+ ADD_NDS32_BUILTIN2 ("v_ukadd8", u_v4qi, u_v4qi, u_v4qi, V_UKADD8); --+ ADD_NDS32_BUILTIN2 ("sub8", integer, integer, integer, SUB8); --+ ADD_NDS32_BUILTIN2 ("v_usub8", u_v4qi, u_v4qi, u_v4qi, V_USUB8); --+ ADD_NDS32_BUILTIN2 ("v_ssub8", v4qi, v4qi, v4qi, V_SSUB8); --+ ADD_NDS32_BUILTIN2 ("rsub8", unsigned, unsigned, unsigned, RSUB8); --+ ADD_NDS32_BUILTIN2 ("v_rsub8", v4qi, v4qi, v4qi, V_RSUB8); --+ ADD_NDS32_BUILTIN2 ("ursub8", unsigned, unsigned, unsigned, URSUB8); --+ ADD_NDS32_BUILTIN2 ("v_ursub8", u_v4qi, u_v4qi, u_v4qi, V_URSUB8); --+ ADD_NDS32_BUILTIN2 ("ksub8", unsigned, unsigned, unsigned, KSUB8); --+ ADD_NDS32_BUILTIN2 ("v_ksub8", v4qi, v4qi, v4qi, V_KSUB8); --+ ADD_NDS32_BUILTIN2 ("uksub8", unsigned, unsigned, unsigned, UKSUB8); --+ ADD_NDS32_BUILTIN2 ("v_uksub8", u_v4qi, u_v4qi, u_v4qi, V_UKSUB8); --+ --+ /* DSP Extension: SIMD 16bit Shift. */ --+ ADD_NDS32_BUILTIN2 ("sra16", unsigned, unsigned, unsigned, SRA16); --+ ADD_NDS32_BUILTIN2 ("v_sra16", v2hi, v2hi, unsigned, V_SRA16); --+ ADD_NDS32_BUILTIN2 ("sra16_u", unsigned, unsigned, unsigned, SRA16_U); --+ ADD_NDS32_BUILTIN2 ("v_sra16_u", v2hi, v2hi, unsigned, V_SRA16_U); --+ ADD_NDS32_BUILTIN2 ("srl16", unsigned, unsigned, unsigned, SRL16); --+ ADD_NDS32_BUILTIN2 ("v_srl16", u_v2hi, u_v2hi, unsigned, V_SRL16); --+ ADD_NDS32_BUILTIN2 ("srl16_u", unsigned, unsigned, unsigned, SRL16_U); --+ ADD_NDS32_BUILTIN2 ("v_srl16_u", u_v2hi, u_v2hi, unsigned, V_SRL16_U); --+ ADD_NDS32_BUILTIN2 ("sll16", unsigned, unsigned, unsigned, SLL16); --+ ADD_NDS32_BUILTIN2 ("v_sll16", u_v2hi, u_v2hi, unsigned, V_SLL16); --+ ADD_NDS32_BUILTIN2 ("ksll16", unsigned, unsigned, unsigned, KSLL16); --+ ADD_NDS32_BUILTIN2 ("v_ksll16", v2hi, v2hi, unsigned, V_KSLL16); --+ ADD_NDS32_BUILTIN2 ("kslra16", unsigned, unsigned, unsigned, KSLRA16); --+ ADD_NDS32_BUILTIN2 ("v_kslra16", v2hi, v2hi, unsigned, V_KSLRA16); --+ ADD_NDS32_BUILTIN2 ("kslra16_u", unsigned, unsigned, unsigned, KSLRA16_U); --+ ADD_NDS32_BUILTIN2 ("v_kslra16_u", v2hi, v2hi, unsigned, V_KSLRA16_U); --+ --+ /* DSP Extension: 16bit Compare. */ --+ ADD_NDS32_BUILTIN2 ("cmpeq16", unsigned, unsigned, unsigned, CMPEQ16); --+ ADD_NDS32_BUILTIN2 ("v_scmpeq16", u_v2hi, v2hi, v2hi, V_SCMPEQ16); --+ ADD_NDS32_BUILTIN2 ("v_ucmpeq16", u_v2hi, u_v2hi, u_v2hi, V_UCMPEQ16); --+ ADD_NDS32_BUILTIN2 ("scmplt16", unsigned, unsigned, unsigned, SCMPLT16); --+ ADD_NDS32_BUILTIN2 ("v_scmplt16", u_v2hi, v2hi, v2hi, V_SCMPLT16); --+ ADD_NDS32_BUILTIN2 ("scmple16", unsigned, unsigned, unsigned, SCMPLE16); --+ ADD_NDS32_BUILTIN2 ("v_scmple16", u_v2hi, v2hi, v2hi, V_SCMPLE16); --+ ADD_NDS32_BUILTIN2 ("ucmplt16", unsigned, unsigned, unsigned, UCMPLT16); --+ ADD_NDS32_BUILTIN2 ("v_ucmplt16", u_v2hi, u_v2hi, u_v2hi, V_UCMPLT16); --+ ADD_NDS32_BUILTIN2 ("ucmple16", unsigned, unsigned, unsigned, UCMPLE16); --+ ADD_NDS32_BUILTIN2 ("v_ucmple16", u_v2hi, u_v2hi, u_v2hi, V_UCMPLE16); --+ --+ /* DSP Extension: 8bit Compare. */ --+ ADD_NDS32_BUILTIN2 ("cmpeq8", unsigned, unsigned, unsigned, CMPEQ8); --+ ADD_NDS32_BUILTIN2 ("v_scmpeq8", u_v4qi, v4qi, v4qi, V_SCMPEQ8); --+ ADD_NDS32_BUILTIN2 ("v_ucmpeq8", u_v4qi, u_v4qi, u_v4qi, V_UCMPEQ8); --+ ADD_NDS32_BUILTIN2 ("scmplt8", unsigned, unsigned, unsigned, SCMPLT8); --+ ADD_NDS32_BUILTIN2 ("v_scmplt8", u_v4qi, v4qi, v4qi, V_SCMPLT8); --+ ADD_NDS32_BUILTIN2 ("scmple8", unsigned, unsigned, unsigned, SCMPLE8); --+ ADD_NDS32_BUILTIN2 ("v_scmple8", u_v4qi, v4qi, v4qi, V_SCMPLE8); --+ ADD_NDS32_BUILTIN2 ("ucmplt8", unsigned, unsigned, unsigned, UCMPLT8); --+ ADD_NDS32_BUILTIN2 ("v_ucmplt8", u_v4qi, u_v4qi, u_v4qi, V_UCMPLT8); --+ ADD_NDS32_BUILTIN2 ("ucmple8", unsigned, unsigned, unsigned, UCMPLE8); --+ ADD_NDS32_BUILTIN2 ("v_ucmple8", u_v4qi, u_v4qi, u_v4qi, V_UCMPLE8); --+ --+ /* DSP Extension: SIMD 16bit MISC. */ --+ ADD_NDS32_BUILTIN2 ("smin16", unsigned, unsigned, unsigned, SMIN16); --+ ADD_NDS32_BUILTIN2 ("v_smin16", v2hi, v2hi, v2hi, V_SMIN16); --+ ADD_NDS32_BUILTIN2 ("umin16", unsigned, unsigned, unsigned, UMIN16); --+ ADD_NDS32_BUILTIN2 ("v_umin16", u_v2hi, u_v2hi, u_v2hi, V_UMIN16); --+ ADD_NDS32_BUILTIN2 ("smax16", unsigned, unsigned, unsigned, SMAX16); --+ ADD_NDS32_BUILTIN2 ("v_smax16", v2hi, v2hi, v2hi, V_SMAX16); --+ ADD_NDS32_BUILTIN2 ("umax16", unsigned, unsigned, unsigned, UMAX16); --+ ADD_NDS32_BUILTIN2 ("v_umax16", u_v2hi, u_v2hi, u_v2hi, V_UMAX16); --+ ADD_NDS32_BUILTIN2 ("sclip16", unsigned, unsigned, unsigned, SCLIP16); --+ ADD_NDS32_BUILTIN2 ("v_sclip16", v2hi, v2hi, unsigned, V_SCLIP16); --+ ADD_NDS32_BUILTIN2 ("uclip16", unsigned, unsigned, unsigned, UCLIP16); --+ ADD_NDS32_BUILTIN2 ("v_uclip16", v2hi, v2hi, unsigned, V_UCLIP16); --+ ADD_NDS32_BUILTIN2 ("khm16", unsigned, unsigned, unsigned, KHM16); --+ ADD_NDS32_BUILTIN2 ("v_khm16", v2hi, v2hi, v2hi, V_KHM16); --+ ADD_NDS32_BUILTIN2 ("khmx16", unsigned, unsigned, unsigned, KHMX16); --+ ADD_NDS32_BUILTIN2 ("v_khmx16", v2hi, v2hi, v2hi, V_KHMX16); --+ ADD_NDS32_BUILTIN1 ("kabs16", unsigned, unsigned, KABS16); --+ ADD_NDS32_BUILTIN1 ("v_kabs16", v2hi, v2hi, V_KABS16); --+ ADD_NDS32_BUILTIN2 ("smul16", long_long_unsigned, unsigned, unsigned, SMUL16); --+ ADD_NDS32_BUILTIN2 ("v_smul16", v2si, v2hi, v2hi, V_SMUL16); --+ ADD_NDS32_BUILTIN2 ("smulx16", --+ long_long_unsigned, unsigned, unsigned, SMULX16); --+ ADD_NDS32_BUILTIN2 ("v_smulx16", v2si, v2hi, v2hi, V_SMULX16); --+ ADD_NDS32_BUILTIN2 ("umul16", long_long_unsigned, unsigned, unsigned, UMUL16); --+ ADD_NDS32_BUILTIN2 ("v_umul16", u_v2si, u_v2hi, u_v2hi, V_UMUL16); --+ ADD_NDS32_BUILTIN2 ("umulx16", --+ long_long_unsigned, unsigned, unsigned, UMULX16); --+ ADD_NDS32_BUILTIN2 ("v_umulx16", u_v2si, u_v2hi, u_v2hi, V_UMULX16); --+ --+ /* DSP Extension: SIMD 8bit MISC. */ --+ ADD_NDS32_BUILTIN2 ("smin8", unsigned, unsigned, unsigned, SMIN8); --+ ADD_NDS32_BUILTIN2 ("v_smin8", v4qi, v4qi, v4qi, V_SMIN8); --+ ADD_NDS32_BUILTIN2 ("umin8", unsigned, unsigned, unsigned, UMIN8); --+ ADD_NDS32_BUILTIN2 ("v_umin8", u_v4qi, u_v4qi, u_v4qi, V_UMIN8); --+ ADD_NDS32_BUILTIN2 ("smax8", unsigned, unsigned, unsigned, SMAX8); --+ ADD_NDS32_BUILTIN2 ("v_smax8", v4qi, v4qi, v4qi, V_SMAX8); --+ ADD_NDS32_BUILTIN2 ("umax8", unsigned, unsigned, unsigned, UMAX8); --+ ADD_NDS32_BUILTIN2 ("v_umax8", u_v4qi, u_v4qi, u_v4qi, V_UMAX8); --+ ADD_NDS32_BUILTIN1 ("kabs8", unsigned, unsigned, KABS8); --+ ADD_NDS32_BUILTIN1 ("v_kabs8", v4qi, v4qi, V_KABS8); --+ --+ /* DSP Extension: 8bit Unpacking. */ --+ ADD_NDS32_BUILTIN1 ("sunpkd810", unsigned, unsigned, SUNPKD810); --+ ADD_NDS32_BUILTIN1 ("v_sunpkd810", v2hi, v4qi, V_SUNPKD810); --+ ADD_NDS32_BUILTIN1 ("sunpkd820", unsigned, unsigned, SUNPKD820); --+ ADD_NDS32_BUILTIN1 ("v_sunpkd820", v2hi, v4qi, V_SUNPKD820); --+ ADD_NDS32_BUILTIN1 ("sunpkd830", unsigned, unsigned, SUNPKD830); --+ ADD_NDS32_BUILTIN1 ("v_sunpkd830", v2hi, v4qi, V_SUNPKD830); --+ ADD_NDS32_BUILTIN1 ("sunpkd831", unsigned, unsigned, SUNPKD831); --+ ADD_NDS32_BUILTIN1 ("v_sunpkd831", v2hi, v4qi, V_SUNPKD831); --+ ADD_NDS32_BUILTIN1 ("zunpkd810", unsigned, unsigned, ZUNPKD810); --+ ADD_NDS32_BUILTIN1 ("v_zunpkd810", u_v2hi, u_v4qi, V_ZUNPKD810); --+ ADD_NDS32_BUILTIN1 ("zunpkd820", unsigned, unsigned, ZUNPKD820); --+ ADD_NDS32_BUILTIN1 ("v_zunpkd820", u_v2hi, u_v4qi, V_ZUNPKD820); --+ ADD_NDS32_BUILTIN1 ("zunpkd830", unsigned, unsigned, ZUNPKD830); --+ ADD_NDS32_BUILTIN1 ("v_zunpkd830", u_v2hi, u_v4qi, V_ZUNPKD830); --+ ADD_NDS32_BUILTIN1 ("zunpkd831", unsigned, unsigned, ZUNPKD831); --+ ADD_NDS32_BUILTIN1 ("v_zunpkd831", u_v2hi, u_v4qi, V_ZUNPKD831); --+ --+ /* DSP Extension: 32bit Add and Subtract. */ --+ ADD_NDS32_BUILTIN2 ("raddw", integer, integer, integer, RADDW); --+ ADD_NDS32_BUILTIN2 ("uraddw", unsigned, unsigned, unsigned, URADDW); --+ ADD_NDS32_BUILTIN2 ("rsubw", integer, integer, integer, RSUBW); --+ ADD_NDS32_BUILTIN2 ("ursubw", unsigned, unsigned, unsigned, URSUBW); --+ --+ /* DSP Extension: 32bit Shift. */ --+ ADD_NDS32_BUILTIN2 ("sra_u", integer, integer, unsigned, SRA_U); --+ ADD_NDS32_BUILTIN2 ("ksll", integer, integer, unsigned, KSLL); --+ --+ /* DSP Extension: 16bit Packing. */ --+ ADD_NDS32_BUILTIN2 ("pkbb16", unsigned, unsigned, unsigned, PKBB16); --+ ADD_NDS32_BUILTIN2 ("v_pkbb16", u_v2hi, u_v2hi, u_v2hi, V_PKBB16); --+ ADD_NDS32_BUILTIN2 ("pkbt16", unsigned, unsigned, unsigned, PKBT16); --+ ADD_NDS32_BUILTIN2 ("v_pkbt16", u_v2hi, u_v2hi, u_v2hi, V_PKBT16); --+ ADD_NDS32_BUILTIN2 ("pktb16", unsigned, unsigned, unsigned, PKTB16); --+ ADD_NDS32_BUILTIN2 ("v_pktb16", u_v2hi, u_v2hi, u_v2hi, V_PKTB16); --+ ADD_NDS32_BUILTIN2 ("pktt16", unsigned, unsigned, unsigned, PKTT16); --+ ADD_NDS32_BUILTIN2 ("v_pktt16", u_v2hi, u_v2hi, u_v2hi, V_PKTT16); --+ --+ /* DSP Extension: Signed MSW 32x32 Multiply and ADD. */ --+ ADD_NDS32_BUILTIN2 ("smmul", integer, integer, integer, SMMUL); --+ ADD_NDS32_BUILTIN2 ("smmul_u", integer, integer, integer, SMMUL_U); --+ ADD_NDS32_BUILTIN3 ("kmmac", integer, integer, integer, integer, KMMAC); --+ ADD_NDS32_BUILTIN3 ("kmmac_u", integer, integer, integer, integer, KMMAC_U); --+ ADD_NDS32_BUILTIN3 ("kmmsb", integer, integer, integer, integer, KMMSB); --+ ADD_NDS32_BUILTIN3 ("kmmsb_u", integer, integer, integer, integer, KMMSB_U); --+ ADD_NDS32_BUILTIN2 ("kwmmul", integer, integer, integer, KWMMUL); --+ ADD_NDS32_BUILTIN2 ("kwmmul_u", integer, integer, integer, KWMMUL_U); --+ --+ /* DSP Extension: Most Significant Word 32x16 Multiply and ADD. */ --+ ADD_NDS32_BUILTIN2 ("smmwb", integer, integer, unsigned, SMMWB); --+ ADD_NDS32_BUILTIN2 ("v_smmwb", integer, integer, v2hi, V_SMMWB); --+ ADD_NDS32_BUILTIN2 ("smmwb_u", integer, integer, unsigned, SMMWB_U); --+ ADD_NDS32_BUILTIN2 ("v_smmwb_u", integer, integer, v2hi, V_SMMWB_U); --+ ADD_NDS32_BUILTIN2 ("smmwt", integer, integer, unsigned, SMMWT); --+ ADD_NDS32_BUILTIN2 ("v_smmwt", integer, integer, v2hi, V_SMMWT); --+ ADD_NDS32_BUILTIN2 ("smmwt_u", integer, integer, unsigned, SMMWT_U); --+ ADD_NDS32_BUILTIN2 ("v_smmwt_u", integer, integer, v2hi, V_SMMWT_U); --+ ADD_NDS32_BUILTIN3 ("kmmawb", integer, integer, integer, unsigned, KMMAWB); --+ ADD_NDS32_BUILTIN3 ("v_kmmawb", integer, integer, integer, v2hi, V_KMMAWB); --+ ADD_NDS32_BUILTIN3 ("kmmawb_u", --+ integer, integer, integer, unsigned, KMMAWB_U); --+ ADD_NDS32_BUILTIN3 ("v_kmmawb_u", --+ integer, integer, integer, v2hi, V_KMMAWB_U); --+ ADD_NDS32_BUILTIN3 ("kmmawt", integer, integer, integer, unsigned, KMMAWT); --+ ADD_NDS32_BUILTIN3 ("v_kmmawt", integer, integer, integer, v2hi, V_KMMAWT); --+ ADD_NDS32_BUILTIN3 ("kmmawt_u", --+ integer, integer, integer, unsigned, KMMAWT_U); --+ ADD_NDS32_BUILTIN3 ("v_kmmawt_u", --+ integer, integer, integer, v2hi, V_KMMAWT_U); --+ --+ /* DSP Extension: Signed 16bit Multiply with ADD/Subtract. */ --+ ADD_NDS32_BUILTIN2 ("smbb", integer, unsigned, unsigned, SMBB); --+ ADD_NDS32_BUILTIN2 ("v_smbb", integer, v2hi, v2hi, V_SMBB); --+ ADD_NDS32_BUILTIN2 ("smbt", integer, unsigned, unsigned, SMBT); --+ ADD_NDS32_BUILTIN2 ("v_smbt", integer, v2hi, v2hi, V_SMBT); --+ ADD_NDS32_BUILTIN2 ("smtt", integer, unsigned, unsigned, SMTT); --+ ADD_NDS32_BUILTIN2 ("v_smtt", integer, v2hi, v2hi, V_SMTT); --+ ADD_NDS32_BUILTIN2 ("kmda", integer, unsigned, unsigned, KMDA); --+ ADD_NDS32_BUILTIN2 ("v_kmda", integer, v2hi, v2hi, V_KMDA); --+ ADD_NDS32_BUILTIN2 ("kmxda", integer, unsigned, unsigned, KMXDA); --+ ADD_NDS32_BUILTIN2 ("v_kmxda", integer, v2hi, v2hi, V_KMXDA); --+ ADD_NDS32_BUILTIN2 ("smds", integer, unsigned, unsigned, SMDS); --+ ADD_NDS32_BUILTIN2 ("v_smds", integer, v2hi, v2hi, V_SMDS); --+ ADD_NDS32_BUILTIN2 ("smdrs", integer, unsigned, unsigned, SMDRS); --+ ADD_NDS32_BUILTIN2 ("v_smdrs", integer, v2hi, v2hi, V_SMDRS); --+ ADD_NDS32_BUILTIN2 ("smxds", integer, unsigned, unsigned, SMXDS); --+ ADD_NDS32_BUILTIN2 ("v_smxds", integer, v2hi, v2hi, V_SMXDS); --+ ADD_NDS32_BUILTIN3 ("kmabb", integer, integer, unsigned, unsigned, KMABB); --+ ADD_NDS32_BUILTIN3 ("v_kmabb", integer, integer, v2hi, v2hi, V_KMABB); --+ ADD_NDS32_BUILTIN3 ("kmabt", integer, integer, unsigned, unsigned, KMABT); --+ ADD_NDS32_BUILTIN3 ("v_kmabt", integer, integer, v2hi, v2hi, V_KMABT); --+ ADD_NDS32_BUILTIN3 ("kmatt", integer, integer, unsigned, unsigned, KMATT); --+ ADD_NDS32_BUILTIN3 ("v_kmatt", integer, integer, v2hi, v2hi, V_KMATT); --+ ADD_NDS32_BUILTIN3 ("kmada", integer, integer, unsigned, unsigned, KMADA); --+ ADD_NDS32_BUILTIN3 ("v_kmada", integer, integer, v2hi, v2hi, V_KMADA); --+ ADD_NDS32_BUILTIN3 ("kmaxda", integer, integer, unsigned, unsigned, KMAXDA); --+ ADD_NDS32_BUILTIN3 ("v_kmaxda", integer, integer, v2hi, v2hi, V_KMAXDA); --+ ADD_NDS32_BUILTIN3 ("kmads", integer, integer, unsigned, unsigned, KMADS); --+ ADD_NDS32_BUILTIN3 ("v_kmads", integer, integer, v2hi, v2hi, V_KMADS); --+ ADD_NDS32_BUILTIN3 ("kmadrs", integer, integer, unsigned, unsigned, KMADRS); --+ ADD_NDS32_BUILTIN3 ("v_kmadrs", integer, integer, v2hi, v2hi, V_KMADRS); --+ ADD_NDS32_BUILTIN3 ("kmaxds", integer, integer, unsigned, unsigned, KMAXDS); --+ ADD_NDS32_BUILTIN3 ("v_kmaxds", integer, integer, v2hi, v2hi, V_KMAXDS); --+ ADD_NDS32_BUILTIN3 ("kmsda", integer, integer, unsigned, unsigned, KMSDA); --+ ADD_NDS32_BUILTIN3 ("v_kmsda", integer, integer, v2hi, v2hi, V_KMSDA); --+ ADD_NDS32_BUILTIN3 ("kmsxda", integer, integer, unsigned, unsigned, KMSXDA); --+ ADD_NDS32_BUILTIN3 ("v_kmsxda", integer, integer, v2hi, v2hi, V_KMSXDA); --+ --+ /* DSP Extension: Signed 16bit Multiply with 64bit ADD/Subtract. */ --+ ADD_NDS32_BUILTIN2 ("smal", long_long_integer, --+ long_long_integer, unsigned, SMAL); --+ ADD_NDS32_BUILTIN2 ("v_smal", long_long_integer, --+ long_long_integer, v2hi, V_SMAL); --+ --+ /* DSP Extension: 32bit MISC. */ --+ ADD_NDS32_BUILTIN2 ("bitrev", unsigned, unsigned, unsigned, BITREV); --+ ADD_NDS32_BUILTIN2 ("wext", unsigned, long_long_integer, unsigned, WEXT); --+ ADD_NDS32_BUILTIN3 ("bpick", unsigned, unsigned, unsigned, unsigned, BPICK); --+ ADD_NDS32_BUILTIN3 ("insb", unsigned, unsigned, unsigned, unsigned, INSB); --+ --+ /* DSP Extension: 64bit Add and Subtract. */ --+ ADD_NDS32_BUILTIN2 ("sadd64", long_long_integer, --+ long_long_integer, long_long_integer, SADD64); --+ ADD_NDS32_BUILTIN2 ("uadd64", long_long_unsigned, --+ long_long_unsigned, long_long_unsigned, UADD64); --+ ADD_NDS32_BUILTIN2 ("radd64", long_long_integer, --+ long_long_integer, long_long_integer, RADD64); --+ ADD_NDS32_BUILTIN2 ("uradd64", long_long_unsigned, --+ long_long_unsigned, long_long_unsigned, URADD64); --+ ADD_NDS32_BUILTIN2 ("kadd64", long_long_integer, --+ long_long_integer, long_long_integer, KADD64); --+ ADD_NDS32_BUILTIN2 ("ukadd64", long_long_unsigned, --+ long_long_unsigned, long_long_unsigned, UKADD64); --+ ADD_NDS32_BUILTIN2 ("ssub64", long_long_integer, --+ long_long_integer, long_long_integer, SSUB64); --+ ADD_NDS32_BUILTIN2 ("usub64", long_long_unsigned, --+ long_long_unsigned, long_long_unsigned, USUB64); --+ ADD_NDS32_BUILTIN2 ("rsub64", long_long_integer, --+ long_long_integer, long_long_integer, RSUB64); --+ ADD_NDS32_BUILTIN2 ("ursub64", long_long_unsigned, --+ long_long_unsigned, long_long_unsigned, URSUB64); --+ ADD_NDS32_BUILTIN2 ("ksub64", long_long_integer, --+ long_long_integer, long_long_integer, KSUB64); --+ ADD_NDS32_BUILTIN2 ("uksub64", long_long_unsigned, --+ long_long_unsigned, long_long_unsigned, UKSUB64); --+ --+ /* DSP Extension: 32bit Multiply with 64bit Add/Subtract. */ --+ ADD_NDS32_BUILTIN3 ("smar64", long_long_integer, --+ long_long_integer, integer, integer, SMAR64); --+ ADD_NDS32_BUILTIN3 ("smsr64", long_long_integer, --+ long_long_integer, integer, integer, SMSR64); --+ ADD_NDS32_BUILTIN3 ("umar64", long_long_unsigned, --+ long_long_unsigned, unsigned, unsigned, UMAR64); --+ ADD_NDS32_BUILTIN3 ("umsr64", long_long_unsigned, --+ long_long_unsigned, unsigned, unsigned, UMSR64); --+ ADD_NDS32_BUILTIN3 ("kmar64", long_long_integer, --+ long_long_integer, integer, integer, KMAR64); --+ ADD_NDS32_BUILTIN3 ("kmsr64", long_long_integer, --+ long_long_integer, integer, integer, KMSR64); --+ ADD_NDS32_BUILTIN3 ("ukmar64", long_long_unsigned, --+ long_long_unsigned, unsigned, unsigned, UKMAR64); --+ ADD_NDS32_BUILTIN3 ("ukmsr64", long_long_unsigned, --+ long_long_unsigned, unsigned, unsigned, UKMSR64); --+ --+ /* DSP Extension: Signed 16bit Multiply with 64bit Add/Subtract. */ --+ ADD_NDS32_BUILTIN3 ("smalbb", long_long_integer, --+ long_long_integer, unsigned, unsigned, SMALBB); --+ ADD_NDS32_BUILTIN3 ("v_smalbb", long_long_integer, --+ long_long_integer, v2hi, v2hi, V_SMALBB); --+ ADD_NDS32_BUILTIN3 ("smalbt", long_long_integer, --+ long_long_integer, unsigned, unsigned, SMALBT); --+ ADD_NDS32_BUILTIN3 ("v_smalbt", long_long_integer, --+ long_long_integer, v2hi, v2hi, V_SMALBT); --+ ADD_NDS32_BUILTIN3 ("smaltt", long_long_integer, --+ long_long_integer, unsigned, unsigned, SMALTT); --+ ADD_NDS32_BUILTIN3 ("v_smaltt", long_long_integer, --+ long_long_integer, v2hi, v2hi, V_SMALTT); --+ ADD_NDS32_BUILTIN3 ("smalda", long_long_integer, --+ long_long_integer, unsigned, unsigned, SMALDA); --+ ADD_NDS32_BUILTIN3 ("v_smalda", long_long_integer, --+ long_long_integer, v2hi, v2hi, V_SMALDA); --+ ADD_NDS32_BUILTIN3 ("smalxda", long_long_integer, --+ long_long_integer, unsigned, unsigned, SMALXDA); --+ ADD_NDS32_BUILTIN3 ("v_smalxda", long_long_integer, --+ long_long_integer, v2hi, v2hi, V_SMALXDA); --+ ADD_NDS32_BUILTIN3 ("smalds", long_long_integer, --+ long_long_integer, unsigned, unsigned, SMALDS); --+ ADD_NDS32_BUILTIN3 ("v_smalds", long_long_integer, --+ long_long_integer, v2hi, v2hi, V_SMALDS); --+ ADD_NDS32_BUILTIN3 ("smaldrs", long_long_integer, --+ long_long_integer, unsigned, unsigned, SMALDRS); --+ ADD_NDS32_BUILTIN3 ("v_smaldrs", long_long_integer, --+ long_long_integer, v2hi, v2hi, V_SMALDRS); --+ ADD_NDS32_BUILTIN3 ("smalxds", long_long_integer, --+ long_long_integer, unsigned, unsigned, SMALXDS); --+ ADD_NDS32_BUILTIN3 ("v_smalxds", long_long_integer, --+ long_long_integer, v2hi, v2hi, V_SMALXDS); --+ ADD_NDS32_BUILTIN3 ("smslda", long_long_integer, --+ long_long_integer, unsigned, unsigned, SMSLDA); --+ ADD_NDS32_BUILTIN3 ("v_smslda", long_long_integer, --+ long_long_integer, v2hi, v2hi, V_SMSLDA); --+ ADD_NDS32_BUILTIN3 ("smslxda", long_long_integer, --+ long_long_integer, unsigned, unsigned, SMSLXDA); --+ ADD_NDS32_BUILTIN3 ("v_smslxda", long_long_integer, --+ long_long_integer, v2hi, v2hi, V_SMSLXDA); --+ --+ /* DSP Extension: augmented baseline. */ --+ ADD_NDS32_BUILTIN2 ("uclip32", unsigned, integer, unsigned, UCLIP32); --+ ADD_NDS32_BUILTIN2 ("sclip32", integer, integer, unsigned, SCLIP32); --+ ADD_NDS32_BUILTIN1 ("kabs", integer, integer, KABS); --+ --+ /* The builtin turn off hwloop optimization. */ --+ ADD_NDS32_BUILTIN0 ("no_ext_zol", void, NO_HWLOOP); --+ --+ /* DSP Extension: vector type unaligned Load/Store */ --+ ADD_NDS32_BUILTIN1 ("get_unaligned_u16x2", u_v2hi, ptr_ushort, UALOAD_U16); --+ ADD_NDS32_BUILTIN1 ("get_unaligned_s16x2", v2hi, ptr_short, UALOAD_S16); --+ ADD_NDS32_BUILTIN1 ("get_unaligned_u8x4", u_v4qi, ptr_uchar, UALOAD_U8); --+ ADD_NDS32_BUILTIN1 ("get_unaligned_s8x4", v4qi, ptr_char, UALOAD_S8); --+ ADD_NDS32_BUILTIN2 ("put_unaligned_u16x2", void, ptr_ushort, --+ u_v2hi, UASTORE_U16); --+ ADD_NDS32_BUILTIN2 ("put_unaligned_s16x2", void, ptr_short, --+ v2hi, UASTORE_S16); --+ ADD_NDS32_BUILTIN2 ("put_unaligned_u8x4", void, ptr_uchar, --+ u_v4qi, UASTORE_U8); --+ ADD_NDS32_BUILTIN2 ("put_unaligned_s8x4", void, ptr_char, --+ v4qi, UASTORE_S8); --+} -- /* ------------------------------------------------------------------------ */ --diff --git a/gcc/config/nds32/nds32-intrinsic.md b/gcc/config/nds32/nds32-intrinsic.md --index 53876c5..6f8b3eb 100644 ----- a/gcc/config/nds32/nds32-intrinsic.md --+++ b/gcc/config/nds32/nds32-intrinsic.md --@@ -40,6 +40,26 @@ -- (set_attr "length" "4")] -- ) -- --+(define_expand "mtsr_isb" --+ [(set (match_operand:SI 0 "register_operand" "") --+ (match_operand:SI 1 "immediate_operand" ""))] --+ "" --+{ --+ emit_insn (gen_unspec_volatile_mtsr (operands[0], operands[1])); --+ emit_insn (gen_unspec_volatile_isb()); --+ DONE; --+}) --+ --+(define_expand "mtsr_dsb" --+ [(set (match_operand:SI 0 "register_operand" "") --+ (match_operand:SI 1 "immediate_operand" ""))] --+ "" --+{ --+ emit_insn (gen_unspec_volatile_mtsr (operands[0], operands[1])); --+ emit_insn (gen_unspec_dsb()); --+ DONE; --+}) --+ -- (define_insn "unspec_volatile_mtsr" -- [(unspec_volatile:SI [(match_operand:SI 0 "register_operand" "r") -- (match_operand:SI 1 "immediate_operand" "i")] UNSPEC_VOLATILE_MTSR)] --@@ -58,6 +78,74 @@ -- (set_attr "length" "4")] -- ) -- --+;; FPU Register Transfer. --+ --+(define_insn "unspec_fcpynsd" --+ [(set (match_operand:DF 0 "register_operand" "=f") --+ (unspec:DF [(match_operand:DF 1 "register_operand" "f") --+ (match_operand:DF 2 "register_operand" "f")] UNSPEC_FCPYNSD))] --+ "" --+ "fcpynsd\t%0, %1, %2" --+ [(set_attr "type" "misc") --+ (set_attr "length" "4")] --+) --+ --+(define_insn "unspec_fcpynss" --+ [(set (match_operand:SF 0 "register_operand" "=f") --+ (unspec:SF [(match_operand:SF 1 "register_operand" "f") --+ (match_operand:SF 2 "register_operand" "f")] UNSPEC_FCPYNSS))] --+ "" --+ "fcpynss\t%0, %1, %2" --+ [(set_attr "type" "misc") --+ (set_attr "length" "4")] --+) --+ --+(define_insn "unspec_fcpysd" --+ [(set (match_operand:DF 0 "register_operand" "=f") --+ (unspec:DF [(match_operand:DF 1 "register_operand" "f") --+ (match_operand:DF 2 "register_operand" "f")] UNSPEC_FCPYSD))] --+ "" --+ "fcpysd\t%0, %1, %2" --+ [(set_attr "type" "misc") --+ (set_attr "length" "4")] --+) --+ --+(define_insn "unspec_fcpyss" --+ [(set (match_operand:SF 0 "register_operand" "=f") --+ (unspec:SF [(match_operand:SF 1 "register_operand" "f") --+ (match_operand:SF 2 "register_operand" "f")] UNSPEC_FCPYSS))] --+ "" --+ "fcpyss\t%0, %1, %2" --+ [(set_attr "type" "misc") --+ (set_attr "length" "4")] --+) --+ --+(define_insn "unspec_fmfcsr" --+ [(set (match_operand:SI 0 "register_operand" "=r") --+ (unspec_volatile:SI [(const_int 0)] UNSPEC_VOLATILE_FMFCSR))] --+ "" --+ "fmfcsr\t%0" --+ [(set_attr "type" "misc") --+ (set_attr "length" "4")] --+) --+ --+(define_insn "unspec_fmtcsr" --+ [(unspec_volatile:SI [(match_operand:SI 0 "register_operand" "r")] UNSPEC_VOLATILE_FMTCSR)] --+ "" --+ "fmtcsr\t%0" --+ [(set_attr "type" "misc") --+ (set_attr "length" "4")] --+) --+ --+(define_insn "unspec_fmfcfg" --+ [(set (match_operand:SI 0 "register_operand" "=r") --+ (unspec_volatile:SI [(const_int 0)] UNSPEC_VOLATILE_FMFCFG))] --+ "" --+ "fmfcfg\t%0" --+ [(set_attr "type" "misc") --+ (set_attr "length" "4")] --+) --+ -- ;; ------------------------------------------------------------------------ -- -- ;; Interrupt Instructions. --@@ -76,6 +164,445 @@ -- [(set_attr "type" "misc")] -- ) -- --+(define_expand "unspec_enable_int" --+ [(unspec_volatile:SI [(match_operand:SI 0 "immediate_operand" "")] UNSPEC_VOLATILE_ENABLE_INT)] --+ "" --+{ --+ rtx system_reg; --+ rtx temp_reg = gen_reg_rtx (SImode); --+ --+ /* Set system register form nds32_intrinsic_register_names[]. */ --+ if ((INTVAL (operands[0]) >= NDS32_INT_H16) --+ && (INTVAL (operands[0]) <= NDS32_INT_H31)) --+ { --+ system_reg = GEN_INT (__NDS32_REG_INT_MASK2__); --+ operands[0] = GEN_INT (1 << (INTVAL (operands[0]))); --+ } --+ else if ((INTVAL (operands[0]) >= NDS32_INT_H32) --+ && (INTVAL (operands[0]) <= NDS32_INT_H63)) --+ { --+ system_reg = GEN_INT (__NDS32_REG_INT_MASK3__); --+ operands[0] = GEN_INT (1 << (INTVAL (operands[0]) - 32)); --+ } --+ else --+ { --+ system_reg = GEN_INT (__NDS32_REG_INT_MASK__); --+ --+ if (INTVAL (operands[0]) == NDS32_INT_SWI) --+ operands[0] = GEN_INT (1 << 16); --+ else if ((INTVAL (operands[0]) >= NDS32_INT_ALZ) --+ && (INTVAL (operands[0]) <= NDS32_INT_DSSIM)) --+ operands[0] = GEN_INT (1 << (INTVAL (operands[0]) - 4)); --+ else --+ operands[0] = GEN_INT (1 << (INTVAL (operands[0]))); --+ } --+ --+ emit_insn (gen_unspec_volatile_mfsr (temp_reg, system_reg)); --+ emit_insn (gen_iorsi3 (temp_reg, temp_reg, operands[0])); --+ emit_insn (gen_unspec_volatile_mtsr (temp_reg, system_reg)); --+ emit_insn (gen_unspec_dsb ()); --+ DONE; --+}) --+ --+(define_expand "unspec_disable_int" --+ [(unspec_volatile:SI [(match_operand:SI 0 "immediate_operand" "")] UNSPEC_VOLATILE_DISABLE_INT)] --+ "" --+{ --+ rtx system_reg; --+ rtx temp_reg = gen_reg_rtx (SImode); --+ --+ /* Set system register form nds32_intrinsic_register_names[]. */ --+ if ((INTVAL (operands[0]) >= NDS32_INT_H16) --+ && (INTVAL (operands[0]) <= NDS32_INT_H31)) --+ { --+ system_reg = GEN_INT (__NDS32_REG_INT_MASK2__); --+ operands[0] = GEN_INT (~(1 << INTVAL (operands[0]))); --+ } --+ else if ((INTVAL (operands[0]) >= NDS32_INT_H32) --+ && (INTVAL (operands[0]) <= NDS32_INT_H63)) --+ { --+ system_reg = GEN_INT (__NDS32_REG_INT_MASK3__); --+ operands[0] = GEN_INT (~(1 << (INTVAL (operands[0]) - 32))); --+ } --+ else --+ { --+ system_reg = GEN_INT (__NDS32_REG_INT_MASK__); --+ --+ if (INTVAL (operands[0]) == NDS32_INT_SWI) --+ operands[0] = GEN_INT (~(1 << 16)); --+ else if ((INTVAL (operands[0]) >= NDS32_INT_ALZ) --+ && (INTVAL (operands[0]) <= NDS32_INT_DSSIM)) --+ operands[0] = GEN_INT (~(1 << (INTVAL (operands[0]) - 4))); --+ else --+ operands[0] = GEN_INT (~(1 << INTVAL (operands[0]))); --+ } --+ --+ emit_insn (gen_unspec_volatile_mfsr (temp_reg, system_reg)); --+ emit_insn (gen_andsi3 (temp_reg, temp_reg, operands[0])); --+ emit_insn (gen_unspec_volatile_mtsr (temp_reg, system_reg)); --+ emit_insn (gen_unspec_dsb ()); --+ DONE; --+}) --+ --+(define_expand "unspec_set_pending_swint" --+ [(unspec_volatile:SI [(const_int 0)] UNSPEC_VOLATILE_SET_PENDING_SWINT)] --+ "" --+{ --+ /* Get $INT_PEND system register form nds32_intrinsic_register_names[] */ --+ rtx system_reg = GEN_INT (__NDS32_REG_INT_PEND__); --+ rtx temp_reg = gen_reg_rtx (SImode); --+ --+ emit_insn (gen_unspec_volatile_mfsr (temp_reg, system_reg)); --+ emit_insn (gen_iorsi3 (temp_reg, temp_reg, GEN_INT (65536))); --+ emit_insn (gen_unspec_volatile_mtsr (temp_reg, system_reg)); --+ emit_insn (gen_unspec_dsb ()); --+ DONE; --+}) --+ --+(define_expand "unspec_clr_pending_swint" --+ [(unspec_volatile:SI [(const_int 0)] UNSPEC_VOLATILE_CLR_PENDING_SWINT)] --+ "" --+{ --+ /* Get $INT_PEND system register form nds32_intrinsic_register_names[] */ --+ rtx system_reg = GEN_INT (__NDS32_REG_INT_PEND__); --+ rtx temp_reg = gen_reg_rtx (SImode); --+ --+ emit_insn (gen_unspec_volatile_mfsr (temp_reg, system_reg)); --+ emit_insn (gen_andsi3 (temp_reg, temp_reg, GEN_INT (~(1 << 16)))); --+ emit_insn (gen_unspec_volatile_mtsr (temp_reg, system_reg)); --+ emit_insn (gen_unspec_dsb ()); --+ DONE; --+}) --+ --+(define_expand "unspec_clr_pending_hwint" --+ [(unspec_volatile:SI [(match_operand:SI 0 "immediate_operand" "")] UNSPEC_VOLATILE_CLR_PENDING_HWINT)] --+ "" --+{ --+ rtx system_reg = NULL_RTX; --+ rtx temp_reg = gen_reg_rtx (SImode); --+ rtx clr_hwint; --+ unsigned offset = 0; --+ --+ /* Set system register form nds32_intrinsic_register_names[]. */ --+ if ((INTVAL (operands[0]) >= NDS32_INT_H0) --+ && (INTVAL (operands[0]) <= NDS32_INT_H15)) --+ { --+ system_reg = GEN_INT (__NDS32_REG_INT_PEND__); --+ } --+ else if ((INTVAL (operands[0]) >= NDS32_INT_H16) --+ && (INTVAL (operands[0]) <= NDS32_INT_H31)) --+ { --+ system_reg = GEN_INT (__NDS32_REG_INT_PEND2__); --+ } --+ else if ((INTVAL (operands[0]) >= NDS32_INT_H32) --+ && (INTVAL (operands[0]) <= NDS32_INT_H63)) --+ { --+ system_reg = GEN_INT (__NDS32_REG_INT_PEND3__); --+ offset = 32; --+ } --+ else --+ error ("__nds32__clr_pending_hwint not support NDS32_INT_SWI," --+ " NDS32_INT_ALZ, NDS32_INT_IDIVZE, NDS32_INT_DSSIM"); --+ --+ /* $INT_PEND type is write one clear. */ --+ clr_hwint = GEN_INT (1 << (INTVAL (operands[0]) - offset)); --+ --+ if (system_reg != NULL_RTX) --+ { --+ emit_move_insn (temp_reg, clr_hwint); --+ emit_insn (gen_unspec_volatile_mtsr (temp_reg, system_reg)); --+ emit_insn (gen_unspec_dsb ()); --+ } --+ DONE; --+}) --+ --+(define_expand "unspec_get_all_pending_int" --+ [(set (match_operand:SI 0 "register_operand" "") --+ (unspec_volatile:SI [(const_int 0)] UNSPEC_VOLATILE_GET_ALL_PENDING_INT))] --+ "" --+{ --+ rtx system_reg = GEN_INT (__NDS32_REG_INT_PEND__); --+ emit_insn (gen_unspec_volatile_mfsr (operands[0], system_reg)); --+ emit_insn (gen_unspec_dsb ()); --+ DONE; --+}) --+ --+(define_expand "unspec_get_pending_int" --+ [(set (match_operand:SI 0 "register_operand" "") --+ (unspec_volatile:SI [(match_operand:SI 1 "immediate_operand" "")] UNSPEC_VOLATILE_GET_PENDING_INT))] --+ "" --+{ --+ rtx system_reg = NULL_RTX; --+ --+ /* Set system register form nds32_intrinsic_register_names[]. */ --+ if ((INTVAL (operands[1]) >= NDS32_INT_H0) --+ && (INTVAL (operands[1]) <= NDS32_INT_H15)) --+ { --+ system_reg = GEN_INT (__NDS32_REG_INT_PEND__); --+ operands[2] = GEN_INT (31 - INTVAL (operands[1])); --+ } --+ else if (INTVAL (operands[1]) == NDS32_INT_SWI) --+ { --+ system_reg = GEN_INT (__NDS32_REG_INT_PEND__); --+ operands[2] = GEN_INT (15); --+ } --+ else if ((INTVAL (operands[1]) >= NDS32_INT_H16) --+ && (INTVAL (operands[1]) <= NDS32_INT_H31)) --+ { --+ system_reg = GEN_INT (__NDS32_REG_INT_PEND2__); --+ operands[2] = GEN_INT (31 - INTVAL (operands[1])); --+ } --+ else if ((INTVAL (operands[1]) >= NDS32_INT_H32) --+ && (INTVAL (operands[1]) <= NDS32_INT_H63)) --+ { --+ system_reg = GEN_INT (__NDS32_REG_INT_PEND3__); --+ operands[2] = GEN_INT (31 - (INTVAL (operands[1]) - 32)); --+ } --+ else --+ error ("get_pending_int not support NDS32_INT_ALZ," --+ " NDS32_INT_IDIVZE, NDS32_INT_DSSIM"); --+ --+ /* mfsr op0, sytem_reg */ --+ if (system_reg != NULL_RTX) --+ { --+ emit_insn (gen_unspec_volatile_mfsr (operands[0], system_reg)); --+ emit_insn (gen_ashlsi3 (operands[0], operands[0], operands[2])); --+ emit_insn (gen_lshrsi3 (operands[0], operands[0], GEN_INT (31))); --+ emit_insn (gen_unspec_dsb ()); --+ } --+ DONE; --+}) --+ --+(define_expand "unspec_set_int_priority" --+ [(unspec_volatile:SI [(match_operand:SI 0 "immediate_operand" "") --+ (match_operand:SI 1 "immediate_operand" "")] UNSPEC_VOLATILE_SET_INT_PRIORITY)] --+ "" --+{ --+ rtx system_reg = NULL_RTX; --+ rtx priority = NULL_RTX; --+ rtx mask = NULL_RTX; --+ rtx temp_reg = gen_reg_rtx (SImode); --+ rtx mask_reg = gen_reg_rtx (SImode); --+ rtx set_reg = gen_reg_rtx (SImode); --+ unsigned offset = 0; --+ --+ /* Get system register form nds32_intrinsic_register_names[]. */ --+ if (INTVAL (operands[0]) <= NDS32_INT_H15) --+ { --+ system_reg = GEN_INT (__NDS32_REG_INT_PRI__); --+ offset = 0; --+ } --+ else if (INTVAL (operands[0]) >= NDS32_INT_H16 --+ && INTVAL (operands[0]) <= NDS32_INT_H31) --+ { --+ system_reg = GEN_INT (__NDS32_REG_INT_PRI2__); --+ /* The $INT_PRI2 first bit correspond to H16, so need --+ subtract 16. */ --+ offset = 16; --+ } --+ else if (INTVAL (operands[0]) >= NDS32_INT_H32 --+ && INTVAL (operands[0]) <= NDS32_INT_H47) --+ { --+ system_reg = GEN_INT (__NDS32_REG_INT_PRI3__); --+ /* The $INT_PRI3 first bit correspond to H32, so need --+ subtract 32. */ --+ offset = 32; --+ } --+ else if (INTVAL (operands[0]) >= NDS32_INT_H48 --+ && INTVAL (operands[0]) <= NDS32_INT_H63) --+ { --+ system_reg = GEN_INT (__NDS32_REG_INT_PRI4__); --+ /* The $INT_PRI3 first bit correspond to H48, so need --+ subtract 48. */ --+ offset = 48; --+ } --+ else --+ error ("set_int_priority not support NDS32_INT_SWI," --+ " NDS32_INT_ALZ, NDS32_INT_IDIVZE, NDS32_INT_DSSIM"); --+ --+ mask = GEN_INT (~(3 << 2 * (INTVAL (operands[0]) - offset))); --+ priority = GEN_INT ((int) (INTVAL (operands[1]) --+ << ((INTVAL (operands[0]) - offset) * 2))); --+ --+ if (system_reg != NULL_RTX) --+ { --+ emit_move_insn (mask_reg, mask); --+ emit_move_insn (set_reg, priority); --+ emit_insn (gen_unspec_volatile_mfsr (temp_reg, system_reg)); --+ emit_insn (gen_andsi3 (temp_reg, temp_reg, mask_reg)); --+ emit_insn (gen_iorsi3 (temp_reg, temp_reg, set_reg)); --+ emit_insn (gen_unspec_volatile_mtsr (temp_reg, system_reg)); --+ emit_insn (gen_unspec_dsb ()); --+ } --+ DONE; --+}) --+ --+(define_expand "unspec_get_int_priority" --+ [(set (match_operand:SI 0 "register_operand" "") --+ (unspec_volatile:SI [(match_operand:SI 1 "immediate_operand" "")] UNSPEC_VOLATILE_GET_INT_PRIORITY))] --+ "" --+{ --+ rtx system_reg = NULL_RTX; --+ rtx priority = NULL_RTX; --+ unsigned offset = 0; --+ --+ /* Get system register form nds32_intrinsic_register_names[] */ --+ if (INTVAL (operands[1]) <= NDS32_INT_H15) --+ { --+ system_reg = GEN_INT (__NDS32_REG_INT_PRI__); --+ offset = 0; --+ } --+ else if (INTVAL (operands[1]) >= NDS32_INT_H16 --+ && INTVAL (operands[1]) <= NDS32_INT_H31) --+ { --+ system_reg = GEN_INT (__NDS32_REG_INT_PRI2__); --+ /* The $INT_PRI2 first bit correspond to H16, so need --+ subtract 16. */ --+ offset = 16; --+ } --+ else if (INTVAL (operands[1]) >= NDS32_INT_H32 --+ && INTVAL (operands[1]) <= NDS32_INT_H47) --+ { --+ system_reg = GEN_INT (__NDS32_REG_INT_PRI3__); --+ /* The $INT_PRI3 first bit correspond to H32, so need --+ subtract 32. */ --+ offset = 32; --+ } --+ else if (INTVAL (operands[1]) >= NDS32_INT_H48 --+ && INTVAL (operands[1]) <= NDS32_INT_H63) --+ { --+ system_reg = GEN_INT (__NDS32_REG_INT_PRI4__); --+ /* The $INT_PRI4 first bit correspond to H48, so need --+ subtract 48. */ --+ offset = 48; --+ } --+ else --+ error ("set_int_priority not support NDS32_INT_SWI," --+ " NDS32_INT_ALZ, NDS32_INT_IDIVZE, NDS32_INT_DSSIM"); --+ --+ priority = GEN_INT (31 - 2 * (INTVAL (operands[1]) - offset)); --+ --+ if (system_reg != NULL_RTX) --+ { --+ emit_insn (gen_unspec_volatile_mfsr (operands[0], system_reg)); --+ emit_insn (gen_ashlsi3 (operands[0], operands[0], priority)); --+ emit_insn (gen_lshrsi3 (operands[0], operands[0], GEN_INT (30))); --+ emit_insn (gen_unspec_dsb ()); --+ } --+ DONE; --+}) --+ --+(define_expand "unspec_set_trig_level" --+ [(unspec_volatile:SI [(match_operand:SI 0 "immediate_operand" "")] UNSPEC_VOLATILE_SET_TRIG_LEVEL)] --+ "" --+{ --+ rtx system_reg = NULL_RTX; --+ rtx temp_reg = gen_reg_rtx (SImode); --+ rtx set_level; --+ unsigned offset = 0; --+ --+ if (INTVAL (operands[0]) >= NDS32_INT_H0 --+ && INTVAL (operands[0]) <= NDS32_INT_H31) --+ { --+ system_reg = GEN_INT (__NDS32_REG_INT_TRIGGER__); --+ offset = 0; --+ } --+ else if (INTVAL (operands[0]) >= NDS32_INT_H32 --+ && INTVAL (operands[0]) <= NDS32_INT_H63) --+ { --+ system_reg = GEN_INT (__NDS32_REG_INT_TRIGGER2__); --+ offset = 32; --+ } --+ else --+ error ("__nds32__set_trig_type_level not support NDS32_INT_SWI," --+ " NDS32_INT_ALZ, NDS32_INT_IDIVZE, NDS32_INT_DSSIM"); --+ --+ if (system_reg != NULL_RTX) --+ { --+ /* TRIGGER register, 0 mean level triggered and 1 mean edge triggered. */ --+ set_level = GEN_INT (~(1 << (INTVAL (operands[0]) - offset))); --+ --+ emit_insn (gen_unspec_volatile_mfsr (temp_reg, system_reg)); --+ emit_insn (gen_andsi3 (temp_reg, temp_reg, set_level)); --+ emit_insn (gen_unspec_volatile_mtsr (temp_reg, system_reg)); --+ } --+ DONE; --+}) --+ --+(define_expand "unspec_set_trig_edge" --+ [(unspec_volatile:SI [(match_operand:SI 0 "immediate_operand" "")] UNSPEC_VOLATILE_SET_TRIG_EDGE)] --+ "" --+{ --+ rtx system_reg = NULL_RTX; --+ rtx temp_reg = gen_reg_rtx (SImode); --+ rtx set_level; --+ unsigned offset = 0; --+ --+ if (INTVAL (operands[0]) >= NDS32_INT_H0 --+ && INTVAL (operands[0]) <= NDS32_INT_H31) --+ { --+ system_reg = GEN_INT (__NDS32_REG_INT_TRIGGER__); --+ offset = 0; --+ } --+ else if (INTVAL (operands[0]) >= NDS32_INT_H32 --+ && INTVAL (operands[0]) <= NDS32_INT_H63) --+ { --+ system_reg = GEN_INT (__NDS32_REG_INT_TRIGGER2__); --+ offset = 32; --+ } --+ else --+ error ("__nds32__set_trig_type_edge not support NDS32_INT_SWI," --+ " NDS32_INT_ALZ, NDS32_INT_IDIVZE, NDS32_INT_DSSIM"); --+ --+ if (system_reg != NULL_RTX) --+ { --+ /* TRIGGER register, 0 mean level triggered and 1 mean edge triggered. */ --+ set_level = GEN_INT ((1 << (INTVAL (operands[0]) - offset))); --+ --+ emit_insn (gen_unspec_volatile_mfsr (temp_reg, system_reg)); --+ emit_insn (gen_iorsi3 (temp_reg, temp_reg, set_level)); --+ emit_insn (gen_unspec_volatile_mtsr (temp_reg, system_reg)); --+ } --+ DONE; --+}) --+ --+(define_expand "unspec_get_trig_type" --+ [(set (match_operand:SI 0 "register_operand" "") --+ (unspec_volatile:SI [(match_operand:SI 1 "immediate_operand" "")] UNSPEC_VOLATILE_GET_TRIG_TYPE))] --+ "" --+{ --+ rtx system_reg = NULL_RTX; --+ rtx trig_type; --+ unsigned offset = 0; --+ --+ if (INTVAL (operands[1]) >= NDS32_INT_H0 --+ && INTVAL (operands[1]) <= NDS32_INT_H31) --+ { --+ system_reg = GEN_INT (__NDS32_REG_INT_TRIGGER__); --+ offset = 0; --+ } --+ else if (INTVAL (operands[1]) >= NDS32_INT_H32 --+ && INTVAL (operands[1]) <= NDS32_INT_H63) --+ { --+ system_reg = GEN_INT (__NDS32_REG_INT_TRIGGER2__); --+ offset = 32; --+ } --+ else --+ error ("__nds32__get_trig_type not support NDS32_INT_SWI," --+ " NDS32_INT_ALZ, NDS32_INT_IDIVZE, NDS32_INT_DSSIM"); --+ --+ if (system_reg != NULL_RTX) --+ { --+ trig_type = GEN_INT (31 - (INTVAL (operands[1]) - offset)); --+ --+ emit_insn (gen_unspec_volatile_mfsr (operands[0], system_reg)); --+ emit_insn (gen_ashlsi3 (operands[0], operands[0], trig_type)); --+ emit_insn (gen_lshrsi3 (operands[0], operands[0], GEN_INT (31))); --+ emit_insn (gen_unspec_dsb ()); --+ } --+ DONE; --+}) --+ -- ;; ------------------------------------------------------------------------ -- -- ;; Cache Synchronization Instructions --@@ -84,7 +611,7 @@ -- [(unspec_volatile:SI [(match_operand:SI 0 "register_operand" "r")] UNSPEC_VOLATILE_ISYNC)] -- "" -- "isync\t%0" --- [(set_attr "type" "misc")] --+ [(set_attr "type" "mmu")] -- ) -- -- (define_insn "unspec_volatile_isb" --@@ -94,4 +621,1077 @@ -- [(set_attr "type" "misc")] -- ) -- --+(define_insn "unspec_dsb" --+ [(unspec_volatile [(const_int 0)] UNSPEC_VOLATILE_DSB)] --+ "" --+ "dsb" --+ [(set_attr "type" "misc")] --+) --+ --+(define_insn "unspec_msync" --+ [(unspec_volatile [(match_operand:SI 0 "immediate_operand" "i")] UNSPEC_VOLATILE_MSYNC)] --+ "" --+ "msync\t%0" --+ [(set_attr "type" "misc")] --+) --+ --+(define_insn "unspec_msync_all" --+ [(unspec_volatile [(const_int 0)] UNSPEC_VOLATILE_MSYNC_ALL)] --+ "" --+ "msync\tall" --+ [(set_attr "type" "misc")] --+) --+ --+(define_insn "unspec_msync_store" --+ [(unspec_volatile [(const_int 0)] UNSPEC_VOLATILE_MSYNC_STORE)] --+ "" --+ "msync\tstore" --+ [(set_attr "type" "misc")] --+) --+ --+;; Load and Store --+ --+(define_insn "unspec_volatile_llw" --+ [(set (match_operand:SI 0 "register_operand" "=r") --+ (unspec_volatile:SI [(mem:SI (plus:SI (match_operand:SI 1 "register_operand" "r") --+ (match_operand:SI 2 "register_operand" "r")))] UNSPEC_VOLATILE_LLW))] --+ "" --+ "llw\t%0, [%1 + %2]" --+ [(set_attr "length" "4")] --+) --+ --+(define_insn "unspec_lwup" --+ [(set (match_operand:SI 0 "register_operand" "=r") --+ (unspec_volatile:SI [(mem:SI (plus:SI (match_operand:SI 1 "register_operand" "r") --+ (match_operand:SI 2 "register_operand" "r")))] UNSPEC_LWUP))] --+ "" --+ "lwup\t%0, [%1 + %2]" --+ [(set_attr "length" "4")] --+) --+ --+(define_insn "unspec_lbup" --+ [(set (match_operand:SI 0 "register_operand" "=r") --+ (unspec_volatile:SI [(mem:SI (plus:SI (match_operand:SI 1 "register_operand" "r") --+ (match_operand:SI 2 "register_operand" "r")))] UNSPEC_LBUP))] --+ "" --+ "lbup\t%0, [%1 + %2]" --+ [(set_attr "length" "4")] --+) --+ --+(define_insn "unspec_volatile_scw" --+ [(set (match_operand:SI 0 "register_operand" "=r") --+ (unspec_volatile:SI [(mem:SI (plus:SI (match_operand:SI 1 "register_operand" "r") --+ (match_operand:SI 2 "register_operand" "r"))) --+ (match_operand:SI 3 "register_operand" "0")] UNSPEC_VOLATILE_SCW))] --+ "" --+ "scw\t%0, [%1 + %2]" --+ [(set_attr "length" "4")] --+) --+ --+(define_insn "unspec_swup" --+ [(set (mem:SI (plus:SI (match_operand:SI 0 "register_operand" "r") --+ (match_operand:SI 1 "register_operand" "r"))) --+ (unspec:SI [(match_operand:SI 2 "register_operand" "r")] UNSPEC_SWUP))] --+ "" --+ "swup\t%2, [%0 + %1]" --+ [(set_attr "length" "4")] --+) --+ --+(define_insn "unspec_sbup" --+ [(set (mem:SI (plus:SI (match_operand:SI 0 "register_operand" "r") --+ (match_operand:SI 1 "register_operand" "r"))) --+ (unspec:SI [(match_operand:SI 2 "register_operand" "r")] UNSPEC_SBUP))] --+ "" --+ "sbup\t%2, [%0 + %1]" --+ [(set_attr "length" "4")] --+) --+ --+;; CCTL --+ --+(define_insn "cctl_l1d_invalall" --+ [(unspec_volatile:SI [(const_int 0)] UNSPEC_VOLATILE_CCTL_L1D_INVALALL)] --+ "" --+ "cctl\tL1D_INVALALL" --+ [(set_attr "type" "mmu")] --+) --+ --+(define_insn "cctl_l1d_wball_alvl" --+ [(unspec_volatile:SI [(const_int 0)] UNSPEC_VOLATILE_CCTL_L1D_WBALL_ALVL)] --+ "" --+ "cctl\tL1D_WBALL, alevel" --+ [(set_attr "type" "mmu")] --+) --+ --+(define_insn "cctl_l1d_wball_one_lvl" --+ [(unspec_volatile:SI [(const_int 0)] UNSPEC_VOLATILE_CCTL_L1D_WBALL_ONE_LVL)] --+ "" --+ "cctl\tL1D_WBALL, 1level" --+ [(set_attr "type" "mmu")] --+) --+ --+(define_insn "cctl_idx_read" --+ [(set (match_operand:SI 0 "register_operand" "=r") --+ (unspec_volatile:SI [(match_operand:SI 1 "immediate_operand" "i") --+ (match_operand:SI 2 "register_operand" "r")] UNSPEC_VOLATILE_CCTL_IDX_READ))] --+ "" --+ "cctl\t%0, %2, %X1" --+ [(set_attr "type" "mmu")] --+) --+ --+(define_insn "cctl_idx_write" --+ [(unspec_volatile:SI [(match_operand:SI 0 "immediate_operand" "i") --+ (match_operand:SI 1 "register_operand" "r") --+ (match_operand:SI 2 "register_operand" "r")] UNSPEC_VOLATILE_CCTL_IDX_WRITE)] --+ "" --+ "cctl\t%1, %2, %W0" --+ [(set_attr "type" "mmu")] --+) --+ --+(define_insn "cctl_va_wbinval_l1" --+ [(unspec_volatile:SI [(match_operand:SI 0 "immediate_operand" "i") --+ (match_operand:SI 1 "register_operand" "r")] UNSPEC_VOLATILE_CCTL_VA_WBINVAL_L1)] --+ "" --+ "cctl\t%1, %U0, 1level" --+ [(set_attr "type" "mmu")] --+) --+ --+(define_insn "cctl_va_wbinval_la" --+ [(unspec_volatile:SI [(match_operand:SI 0 "immediate_operand" "i") --+ (match_operand:SI 1 "register_operand" "r")] UNSPEC_VOLATILE_CCTL_VA_WBINVAL_LA)] --+ "" --+ "cctl\t%1, %U0, alevel" --+ [(set_attr "type" "mmu")] --+) --+ --+(define_insn "cctl_idx_wbinval" --+ [(unspec_volatile:SI [(match_operand:SI 0 "immediate_operand" "i") --+ (match_operand:SI 1 "register_operand" "r")] UNSPEC_VOLATILE_CCTL_IDX_WBINVAL)] --+ "" --+ "cctl\t%1, %T0" --+ [(set_attr "type" "mmu")] --+) --+ --+(define_insn "cctl_va_lck" --+ [(unspec_volatile:SI [(match_operand:SI 0 "immediate_operand" "i") --+ (match_operand:SI 1 "register_operand" "r")] UNSPEC_VOLATILE_CCTL_VA_LCK)] --+ "" --+ "cctl\t%1, %R0" --+ [(set_attr "type" "mmu")] --+) --+ --+;;PREFETCH --+ --+(define_insn "prefetch_qw" --+ [(unspec_volatile:QI [(match_operand:SI 0 "register_operand" "r") --+ (match_operand:SI 1 "nonmemory_operand" "r") --+ (match_operand:SI 2 "immediate_operand" "i")] UNSPEC_VOLATILE_DPREF_QW)] --+ "" --+ "dpref\t%Z2, [%0 + %1]" --+ [(set_attr "type" "misc")] --+) --+ --+(define_insn "prefetch_hw" --+ [(unspec_volatile:HI [(match_operand:SI 0 "register_operand" "r") --+ (match_operand:SI 1 "nonmemory_operand" "r") --+ (match_operand:SI 2 "immediate_operand" "i")] UNSPEC_VOLATILE_DPREF_HW)] --+ "" --+ "dpref\t%Z2, [%0 + (%1<<1)]" --+ [(set_attr "type" "misc")] --+) --+ --+(define_insn "prefetch_w" --+ [(unspec_volatile:SI [(match_operand:SI 0 "register_operand" " r, r") --+ (match_operand:SI 1 "nonmemory_operand" "Is15, r") --+ (match_operand:SI 2 "immediate_operand" " i, i")] UNSPEC_VOLATILE_DPREF_W)] --+ "" --+ "@ --+ dprefi.w\t%Z2, [%0 + %1] --+ dpref\t%Z2, [%0 + (%1<<2)]" --+ [(set_attr "type" "misc")] --+) --+ --+(define_insn "prefetch_dw" --+ [(unspec_volatile:DI [(match_operand:SI 0 "register_operand" " r, r") --+ (match_operand:SI 1 "nonmemory_operand" "Is15, r") --+ (match_operand:SI 2 "immediate_operand" " i, i")] UNSPEC_VOLATILE_DPREF_DW)] --+ "" --+ "@ --+ dprefi.d\t%Z2, [%0 + %1] --+ dpref\t%Z2, [%0 + (%1<<3)]" --+ [(set_attr "type" "misc")] --+) --+ --+;; Performance Extension --+ --+(define_expand "unspec_ave" --+ [(match_operand:SI 0 "register_operand" "") --+ (match_operand:SI 1 "register_operand" "") --+ (match_operand:SI 2 "register_operand" "")] --+ "" --+{ --+ emit_insn (gen_ave (operands[0], operands[1], operands[2])); --+ DONE; --+}) --+ --+(define_expand "unspec_bclr" --+ [(match_operand:SI 0 "register_operand" "") --+ (match_operand:SI 1 "register_operand" "") --+ (match_operand:SI 2 "immediate_operand" "")] --+ "" --+{ --+ unsigned HOST_WIDE_INT val = ~(1u << UINTVAL (operands[2])); --+ emit_insn (gen_andsi3 (operands[0], operands[1], gen_int_mode (val, SImode))); --+ DONE; --+}) --+ --+(define_expand "unspec_bset" --+ [(match_operand:SI 0 "register_operand" "") --+ (match_operand:SI 1 "register_operand" "") --+ (match_operand:SI 2 "immediate_operand" "")] --+ "" --+{ --+ unsigned HOST_WIDE_INT val = 1u << UINTVAL (operands[2]); --+ emit_insn (gen_iorsi3 (operands[0], operands[1], gen_int_mode (val, SImode))); --+ DONE; --+}) --+ --+(define_expand "unspec_btgl" --+ [(match_operand:SI 0 "register_operand" "") --+ (match_operand:SI 1 "register_operand" "") --+ (match_operand:SI 2 "immediate_operand" "")] --+ "" --+{ --+ unsigned HOST_WIDE_INT val = 1u << UINTVAL (operands[2]); --+ emit_insn (gen_xorsi3 (operands[0], operands[1], gen_int_mode (val, SImode))); --+ DONE; --+}) --+ --+(define_expand "unspec_btst" --+ [(match_operand:SI 0 "register_operand" "") --+ (match_operand:SI 1 "register_operand" "") --+ (match_operand:SI 2 "immediate_operand" "")] --+ "" --+{ --+ emit_insn (gen_btst (operands[0], operands[1], operands[2])); --+ DONE; --+}) --+ --+(define_insn "unspec_clip" --+ [(set (match_operand:SI 0 "register_operand" "=r") --+ (unspec:SI [(match_operand:SI 1 "register_operand" "r") --+ (match_operand:SI 2 "immediate_operand" "i")] UNSPEC_CLIP))] --+ "" --+ "clip\t%0, %1, %2" --+ [(set_attr "type" "alu") --+ (set_attr "length" "4")] --+) --+ --+(define_insn "unspec_clips" --+ [(set (match_operand:SI 0 "register_operand" "=r") --+ (unspec:SI [(match_operand:SI 1 "register_operand" "r") --+ (match_operand:SI 2 "immediate_operand" "i")] UNSPEC_CLIPS))] --+ "" --+ "clips\t%0, %1, %2" --+ [(set_attr "type" "alu") --+ (set_attr "length" "4")] --+) --+ --+(define_insn "unspec_clo" --+ [(set (match_operand:SI 0 "register_operand" "=r") --+ (unspec:SI [(match_operand:SI 1 "register_operand" "r")] UNSPEC_CLO))] --+ "" --+ "clo\t%0, %1" --+ [(set_attr "type" "alu") --+ (set_attr "length" "4")] --+) --+ --+(define_insn "unspec_ssabssi2" --+ [(set (match_operand:SI 0 "register_operand" "=r") --+ (ss_abs:SI (match_operand:SI 1 "register_operand" "r")))] --+ "" --+ "abs\t%0, %1" --+ [(set_attr "type" "alu") --+ (set_attr "length" "4")] --+) --+ --+;; Performance extension 2 --+ --+(define_insn "unspec_pbsad" --+ [(set (match_operand:SI 0 "register_operand" "=r") --+ (unspec:SI [(match_operand:SI 1 "register_operand" "r") --+ (match_operand:SI 2 "register_operand" "r")] UNSPEC_PBSAD))] --+ "" --+ "pbsad\t%0, %1, %2" --+ [(set_attr "type" "pbsad") --+ (set_attr "length" "4")] --+) --+ --+(define_insn "unspec_pbsada" --+ [(set (match_operand:SI 0 "register_operand" "=r") --+ (unspec:SI [(match_operand:SI 1 "register_operand" "0") --+ (match_operand:SI 2 "register_operand" "r") --+ (match_operand:SI 3 "register_operand" "r")] UNSPEC_PBSADA))] --+ "" --+ "pbsada\t%0, %2, %3" --+ [(set_attr "type" "pbsada") --+ (set_attr "length" "4")] --+) --+ --+(define_expand "bse" --+ [(match_operand:SI 0 "register_operand" "") --+ (match_operand:SI 1 "register_operand" "") --+ (match_operand:SI 2 "register_operand" "")] --+ "" --+ { --+ rtx temp0 = gen_reg_rtx (SImode); --+ rtx temp2 = gen_reg_rtx (SImode); --+ --+ emit_move_insn (temp0, gen_rtx_MEM (Pmode, operands[0])); --+ emit_move_insn (temp2, gen_rtx_MEM (Pmode, operands[2])); --+ emit_insn (gen_unspec_bse (temp0, operands[1], temp2, temp0, temp2)); --+ emit_move_insn (gen_rtx_MEM (Pmode, operands[0]), temp0); --+ emit_move_insn (gen_rtx_MEM (Pmode, operands[2]), temp2); --+ DONE; --+ } --+) --+ --+(define_insn "unspec_bse" --+ [(set (match_operand:SI 0 "register_operand" "=r") --+ (unspec:SI [(match_operand:SI 1 "register_operand" "r") --+ (match_operand:SI 2 "register_operand" "r") --+ (match_operand:SI 3 "register_operand" "0")] UNSPEC_BSE)) --+ (set (match_operand:SI 4 "register_operand" "=2") --+ (unspec:SI [(match_dup 1) --+ (match_dup 2) --+ (match_dup 0)] UNSPEC_BSE_2))] --+ "" --+ "bse\t%0, %1, %2" --+ [(set_attr "type" "alu") --+ (set_attr "length" "4")] --+) --+ --+(define_expand "bsp" --+ [(match_operand:SI 0 "register_operand" "") --+ (match_operand:SI 1 "register_operand" "") --+ (match_operand:SI 2 "register_operand" "")] --+ "" --+ { --+ rtx temp0 = gen_reg_rtx (SImode); --+ rtx temp2 = gen_reg_rtx (SImode); --+ --+ emit_move_insn (temp0, gen_rtx_MEM (Pmode, operands[0])); --+ emit_move_insn (temp2, gen_rtx_MEM (Pmode, operands[2])); --+ emit_insn (gen_unspec_bsp (temp0, operands[1], temp2, temp0, temp2)); --+ emit_move_insn (gen_rtx_MEM (Pmode, operands[0]), temp0); --+ emit_move_insn (gen_rtx_MEM (Pmode, operands[2]), temp2); --+ DONE; --+ } --+) --+ --+(define_insn "unspec_bsp" --+ [(set (match_operand:SI 0 "register_operand" "=r") --+ (unspec:SI [(match_operand:SI 1 "register_operand" "r") --+ (match_operand:SI 2 "register_operand" "r") --+ (match_operand:SI 3 "register_operand" "0")] UNSPEC_BSP)) --+ (set (match_operand:SI 4 "register_operand" "=2") --+ (unspec:SI [(match_dup 1) --+ (match_dup 2) --+ (match_dup 0)] UNSPEC_BSP_2))] --+ "" --+ "bsp\t%0, %1, %2" --+ [(set_attr "type" "alu") --+ (set_attr "length" "4")] --+) --+ --+;; String Extension --+ --+(define_insn "unspec_ffb" --+ [(set (match_operand:SI 0 "register_operand" "=r, r") --+ (unspec:SI [(match_operand:SI 1 "register_operand" "r, r") --+ (match_operand:SI 2 "nonmemory_operand" "Iu08, r")] UNSPEC_FFB))] --+ "" --+ "@ --+ ffbi\t%0, %1, %2 --+ ffb\t%0, %1, %2" --+ [(set_attr "type" "alu") --+ (set_attr "length" "4")] --+) --+ --+(define_insn "unspec_ffmism" --+ [(set (match_operand:SI 0 "register_operand" "=r") --+ (unspec:SI [(match_operand:SI 1 "register_operand" "r") --+ (match_operand:SI 2 "register_operand" "r")] UNSPEC_FFMISM))] --+ "" --+ "ffmism\t%0, %1, %2" --+ [(set_attr "type" "alu") --+ (set_attr "length" "4")] --+) --+ --+(define_insn "unspec_flmism" --+ [(set (match_operand:SI 0 "register_operand" "=r") --+ (unspec:SI [(match_operand:SI 1 "register_operand" "r") --+ (match_operand:SI 2 "register_operand" "r")] UNSPEC_FLMISM))] --+ "" --+ "flmism\t%0, %1, %2" --+ [(set_attr "type" "alu") --+ (set_attr "length" "4")] --+) --+ --+;; SATURATION --+ --+(define_insn "unspec_kaddw" --+ [(set (match_operand:SI 0 "register_operand" "=r") --+ (ss_plus:SI (match_operand:SI 1 "register_operand" "r") --+ (match_operand:SI 2 "register_operand" "r")))] --+ "" --+ "kaddw\t%0, %1, %2" --+ [(set_attr "type" "alu") --+ (set_attr "length" "4")] --+) --+ --+(define_insn "unspec_ksubw" --+ [(set (match_operand:SI 0 "register_operand" "=r") --+ (ss_minus:SI (match_operand:SI 1 "register_operand" "r") --+ (match_operand:SI 2 "register_operand" "r")))] --+ "" --+ "ksubw\t%0, %1, %2" --+ [(set_attr "type" "alu") --+ (set_attr "length" "4")] --+) --+ --+(define_insn "unspec_kaddh" --+ [(set (match_operand:SI 0 "register_operand" "=r") --+ (unspec:SI [(plus:SI (match_operand:SI 1 "register_operand" "r") --+ (match_operand:SI 2 "register_operand" "r")) --+ (const_int 15)] UNSPEC_CLIPS))] --+ "" --+ "kaddh\t%0, %1, %2" --+ [(set_attr "type" "alu") --+ (set_attr "length" "4")] --+) --+ --+(define_insn "unspec_ksubh" --+ [(set (match_operand:SI 0 "register_operand" "=r") --+ (unspec:SI [(minus:SI (match_operand:SI 1 "register_operand" "r") --+ (match_operand:SI 2 "register_operand" "r")) --+ (const_int 15)] UNSPEC_CLIPS))] --+ "" --+ "ksubh\t%0, %1, %2" --+ [(set_attr "type" "alu") --+ (set_attr "length" "4")] --+) --+ --+(define_insn "unspec_kdmbb" --+ [(set (match_operand:V2HI 0 "register_operand" "=r") --+ (unspec:V2HI [(match_operand:V2HI 1 "register_operand" "r") --+ (match_operand:V2HI 2 "register_operand" "r")] UNSPEC_KDMBB))] --+ "" --+ "kdmbb\t%0, %1, %2" --+ [(set_attr "type" "mul") --+ (set_attr "length" "4")] --+) --+ --+(define_insn "unspec_kdmbt" --+ [(set (match_operand:V2HI 0 "register_operand" "=r") --+ (unspec:V2HI [(match_operand:V2HI 1 "register_operand" "r") --+ (match_operand:V2HI 2 "register_operand" "r")] UNSPEC_KDMBT))] --+ "" --+ "kdmbt\t%0, %1, %2" --+ [(set_attr "type" "mul") --+ (set_attr "length" "4")] --+) --+ --+(define_insn "unspec_kdmtb" --+ [(set (match_operand:V2HI 0 "register_operand" "=r") --+ (unspec:V2HI [(match_operand:V2HI 1 "register_operand" "r") --+ (match_operand:V2HI 2 "register_operand" "r")] UNSPEC_KDMTB))] --+ "" --+ "kdmtb\t%0, %1, %2" --+ [(set_attr "type" "mul") --+ (set_attr "length" "4")] --+) --+ --+(define_insn "unspec_kdmtt" --+ [(set (match_operand:V2HI 0 "register_operand" "=r") --+ (unspec:V2HI [(match_operand:V2HI 1 "register_operand" "r") --+ (match_operand:V2HI 2 "register_operand" "r")] UNSPEC_KDMTT))] --+ "" --+ "kdmtt\t%0, %1, %2" --+ [(set_attr "type" "mul") --+ (set_attr "length" "4")] --+) --+ --+(define_insn "unspec_khmbb" --+ [(set (match_operand:V2HI 0 "register_operand" "=r") --+ (unspec:V2HI [(match_operand:V2HI 1 "register_operand" "r") --+ (match_operand:V2HI 2 "register_operand" "r")] UNSPEC_KHMBB))] --+ "" --+ "khmbb\t%0, %1, %2" --+ [(set_attr "type" "mul") --+ (set_attr "length" "4")] --+) --+ --+(define_insn "unspec_khmbt" --+ [(set (match_operand:V2HI 0 "register_operand" "=r") --+ (unspec:V2HI [(match_operand:V2HI 1 "register_operand" "r") --+ (match_operand:V2HI 2 "register_operand" "r")] UNSPEC_KHMBT))] --+ "" --+ "khmbt\t%0, %1, %2" --+ [(set_attr "type" "mul") --+ (set_attr "length" "4")] --+) --+ --+(define_insn "unspec_khmtb" --+ [(set (match_operand:V2HI 0 "register_operand" "=r") --+ (unspec:V2HI [(match_operand:V2HI 1 "register_operand" "r") --+ (match_operand:V2HI 2 "register_operand" "r")] UNSPEC_KHMTB))] --+ "" --+ "khmtb\t%0, %1, %2" --+ [(set_attr "type" "mul") --+ (set_attr "length" "4")] --+) --+ --+(define_insn "unspec_khmtt" --+ [(set (match_operand:V2HI 0 "register_operand" "=r") --+ (unspec:V2HI [(match_operand:V2HI 1 "register_operand" "r") --+ (match_operand:V2HI 2 "register_operand" "r")] UNSPEC_KHMTT))] --+ "" --+ "khmtt\t%0, %1, %2" --+ [(set_attr "type" "mul") --+ (set_attr "length" "4")] --+) --+ --+(define_insn "unspec_kslraw" --+ [(set (match_operand:SI 0 "register_operand" "=r") --+ (unspec:SI [(match_operand:SI 1 "register_operand" "r") --+ (match_operand:SI 2 "register_operand" "r")] UNSPEC_KSLRAW))] --+ "" --+ "kslraw\t%0, %1, %2" --+ [(set_attr "type" "alu") --+ (set_attr "length" "4")] --+) --+ --+(define_insn "unspec_kslrawu" --+ [(set (match_operand:SI 0 "register_operand" "=r") --+ (unspec:SI [(match_operand:SI 1 "register_operand" "r") --+ (match_operand:SI 2 "register_operand" "r")] UNSPEC_KSLRAWU))] --+ "" --+ "kslraw.u\t%0, %1, %2" --+ [(set_attr "type" "alu") --+ (set_attr "length" "4")] --+) --+ --+(define_insn "unspec_volatile_rdov" --+ [(set (match_operand:SI 0 "register_operand" "=r") --+ (unspec_volatile:SI [(const_int 0)] UNSPEC_VOLATILE_RDOV))] --+ "" --+ "rdov\t%0" --+ [(set_attr "type" "misc") --+ (set_attr "length" "4")] --+) --+ --+(define_insn "unspec_volatile_clrov" --+ [(unspec_volatile:SI [(const_int 0)] UNSPEC_VOLATILE_CLROV)] --+ "" --+ "clrov" --+ [(set_attr "type" "misc") --+ (set_attr "length" "4")] --+) --+ --+;; System --+ --+(define_insn "unspec_sva" --+ [(set (match_operand:SI 0 "register_operand" "=r") --+ (unspec:SI [(match_operand:SI 1 "register_operand" "r") --+ (match_operand:SI 2 "register_operand" "r")] UNSPEC_SVA))] --+ "" --+ "sva\t%0, %1, %2" --+ [(set_attr "type" "alu") --+ (set_attr "length" "4")] --+) --+ --+(define_insn "unspec_svs" --+ [(set (match_operand:SI 0 "register_operand" "=r") --+ (unspec:SI [(match_operand:SI 1 "register_operand" "r") --+ (match_operand:SI 2 "register_operand" "r")] UNSPEC_SVS))] --+ "" --+ "svs\t%0, %1, %2" --+ [(set_attr "type" "alu") --+ (set_attr "length" "4")] --+) --+ --+(define_insn "unspec_jr_itoff" --+ [(unspec_volatile:SI [(match_operand:SI 0 "register_operand" "r")] UNSPEC_VOLATILE_JR_ITOFF)] --+ "" --+ "jr.itoff\t%0" --+ [(set_attr "type" "misc")] --+) --+ --+(define_insn "unspec_jr_toff" --+ [(unspec_volatile:SI [(match_operand:SI 0 "register_operand" "r")] UNSPEC_VOLATILE_JR_TOFF)] --+ "" --+ "jr.toff\t%0" --+ [(set_attr "type" "branch")] --+) --+ --+(define_insn "unspec_jral_iton" --+ [(unspec_volatile:SI [(match_operand:SI 0 "register_operand" "r")] UNSPEC_VOLATILE_JRAL_ITON)] --+ "" --+ "jral.iton\t%0" --+ [(set_attr "type" "branch")] --+) --+ --+(define_insn "unspec_jral_ton" --+ [(unspec_volatile:SI [(match_operand:SI 0 "register_operand" "r")] UNSPEC_VOLATILE_JRAL_TON)] --+ "" --+ "jral.ton\t%0" --+ [(set_attr "type" "branch")] --+) --+ --+(define_insn "unspec_ret_itoff" --+ [(unspec_volatile:SI [(match_operand:SI 0 "register_operand" "r")] UNSPEC_VOLATILE_RET_ITOFF)] --+ "" --+ "ret.itoff\t%0" --+ [(set_attr "type" "branch")] --+) --+ --+(define_insn "unspec_ret_toff" --+ [(unspec_volatile:SI [(match_operand:SI 0 "register_operand" "r")] UNSPEC_VOLATILE_RET_TOFF)] --+ "" --+ "ret.toff\t%0" --+ [(set_attr "type" "branch")] --+) --+ --+(define_insn "unspec_standby_no_wake_grant" --+ [(unspec_volatile:SI [(const_int 0)] UNSPEC_VOLATILE_STANDBY_NO_WAKE_GRANT)] --+ "" --+ "standby\tno_wake_grant" --+ [(set_attr "type" "misc")] --+) --+ --+(define_insn "unspec_standby_wake_grant" --+ [(unspec_volatile:SI [(const_int 0)] UNSPEC_VOLATILE_STANDBY_WAKE_GRANT)] --+ "" --+ "standby\twake_grant" --+ [(set_attr "type" "misc")] --+) --+ --+(define_insn "unspec_standby_wait_done" --+ [(unspec_volatile:SI [(const_int 0)] UNSPEC_VOLATILE_STANDBY_WAKE_DONE)] --+ "" --+ "standby\twait_done" --+ [(set_attr "type" "misc")] --+) --+ --+(define_insn "unspec_teqz" --+ [(unspec_volatile:SI [(match_operand:SI 0 "register_operand" "r") --+ (match_operand:SI 1 "immediate_operand" "i")] UNSPEC_VOLATILE_TEQZ)] --+ "" --+ "teqz\t%0, %1" --+ [(set_attr "type" "misc")] --+) --+ --+(define_insn "unspec_tnez" --+ [(unspec_volatile:SI [(match_operand:SI 0 "register_operand" "r") --+ (match_operand:SI 1 "immediate_operand" "i")] UNSPEC_VOLATILE_TNEZ)] --+ "" --+ "tnez\t%0, %1" --+ [(set_attr "type" "misc")] --+) --+ --+(define_insn "unspec_trap" --+ [(unspec_volatile:SI [(match_operand:SI 0 "immediate_operand" "i")] UNSPEC_VOLATILE_TRAP)] --+ "" --+ "trap\t%0" --+ [(set_attr "type" "misc")] --+) --+ --+(define_insn "unspec_setend_big" --+ [(unspec_volatile:SI [(const_int 0)] UNSPEC_VOLATILE_SETEND_BIG)] --+ "" --+ "setend.b" --+ [(set_attr "type" "misc")] --+) --+ --+(define_insn "unspec_setend_little" --+ [(unspec_volatile:SI [(const_int 0)] UNSPEC_VOLATILE_SETEND_LITTLE)] --+ "" --+ "setend.l" --+ [(set_attr "type" "misc")] --+) --+ --+(define_insn "unspec_break" --+ [(unspec_volatile:SI [(match_operand:SI 0 "immediate_operand" "i")] UNSPEC_VOLATILE_BREAK)] --+ "" --+ "break\t%0" --+ [(set_attr "type" "misc")] --+) --+ --+(define_insn "unspec_syscall" --+ [(unspec_volatile:SI [(match_operand:SI 0 "immediate_operand" "i")] UNSPEC_VOLATILE_SYSCALL)] --+ "" --+ "syscall\t%0" --+ [(set_attr "type" "misc")] --+) --+ --+(define_insn "unspec_nop" --+ [(unspec_volatile:SI [(const_int 0)] UNSPEC_VOLATILE_NOP)] --+ "" --+ "nop" --+ [(set_attr "type" "misc")] --+) --+ --+(define_expand "unspec_get_current_sp" --+ [(match_operand:SI 0 "register_operand" "")] --+ "" --+{ --+ emit_move_insn (operands[0], gen_rtx_REG (SImode, SP_REGNUM)); --+ DONE; --+}) --+ --+(define_expand "unspec_set_current_sp" --+ [(match_operand:SI 0 "register_operand" "")] --+ "" --+{ --+ emit_move_insn (gen_rtx_REG (SImode, SP_REGNUM), operands[0]); --+ DONE; --+}) --+ --+(define_expand "unspec_return_address" --+ [(match_operand:SI 0 "register_operand" "")] --+ "" --+{ --+ emit_move_insn (operands[0], gen_rtx_REG (SImode, LP_REGNUM)); --+ DONE; --+}) --+ --+(define_insn "unspec_signature_begin" --+ [(unspec_volatile:SI [(const_int 0)] UNSPEC_VOLATILE_SIGNATURE_BEGIN)] --+ "" --+ "isps" --+ [(set_attr "length" "4")] --+) --+ --+(define_insn "unspec_signature_end" --+ [(unspec_volatile:SI [(const_int 0)] UNSPEC_VOLATILE_SIGNATURE_END)] --+ "" --+ "! -----\;.signature_end\;j8 2\;! -----" --+ [(set_attr "length" "2")] --+) --+ --+;; Swap --+ --+(define_insn "unspec_wsbh" --+ [(set (match_operand:SI 0 "register_operand" "=r") --+ (unspec:SI [(match_operand:SI 1 "register_operand" "r")] UNSPEC_WSBH))] --+ "" --+ "wsbh\t%0, %1" --+ [(set_attr "type" "alu") --+ (set_attr "length" "4")] --+) --+ --+;; TLBOP Intrinsic --+ --+(define_insn "unspec_tlbop_trd" --+ [(unspec_volatile:SI [(match_operand:SI 0 "register_operand" "r")] UNSPEC_VOLATILE_TLBOP_TRD)] --+ "" --+ "tlbop\t%0, TRD" --+ [(set_attr "type" "mmu")] --+) --+ --+(define_insn "unspec_tlbop_twr" --+ [(unspec_volatile:SI [(match_operand:SI 0 "register_operand" "r")] UNSPEC_VOLATILE_TLBOP_TWR)] --+ "" --+ "tlbop\t%0, TWR" --+ [(set_attr "type" "mmu")] --+) --+ --+(define_insn "unspec_tlbop_rwr" --+ [(unspec_volatile:SI [(match_operand:SI 0 "register_operand" "r")] UNSPEC_VOLATILE_TLBOP_RWR)] --+ "" --+ "tlbop\t%0, RWR" --+ [(set_attr "type" "mmu")] --+) --+ --+(define_insn "unspec_tlbop_rwlk" --+ [(unspec_volatile:SI [(match_operand:SI 0 "register_operand" "r")] UNSPEC_VOLATILE_TLBOP_RWLK)] --+ "" --+ "tlbop\t%0, RWLK" --+ [(set_attr "type" "mmu")] --+) --+ --+(define_insn "unspec_tlbop_unlk" --+ [(unspec_volatile:SI [(match_operand:SI 0 "register_operand" "r")] UNSPEC_VOLATILE_TLBOP_UNLK)] --+ "" --+ "tlbop\t%0, UNLK" --+ [(set_attr "type" "mmu")] --+) --+ --+(define_insn "unspec_tlbop_pb" --+ [(set (match_operand:SI 0 "register_operand" "=r") --+ (unspec_volatile:SI [(match_operand:SI 1 "register_operand" "r")] UNSPEC_VOLATILE_TLBOP_PB))] --+ "" --+ "tlbop\t%0, %1, PB" --+ [(set_attr "type" "mmu")] --+) --+ --+(define_insn "unspec_tlbop_inv" --+ [(unspec_volatile:SI [(match_operand:SI 0 "register_operand" "r")] UNSPEC_VOLATILE_TLBOP_INV)] --+ "" --+ "tlbop\t%0, INV" --+ [(set_attr "type" "mmu")] --+) --+ --+(define_insn "unspec_tlbop_flua" --+ [(unspec_volatile:SI [(const_int 0)] UNSPEC_VOLATILE_TLBOP_FLUA)] --+ "" --+ "tlbop\tFLUA" --+ [(set_attr "type" "mmu")] --+) --+ --+;;Unaligned Load/Store --+ --+(define_expand "unaligned_load_hw" --+ [(set (match_operand:HI 0 "register_operand" "") --+ (unspec:HI [(mem:HI (match_operand:SI 1 "register_operand" ""))] UNSPEC_UALOAD_HW))] --+ "" --+{ --+ operands[0] = simplify_gen_subreg (SImode, operands[0], --+ GET_MODE (operands[0]), 0); --+ if (TARGET_ISA_V3M) --+ { --+ nds32_expand_unaligned_load (operands, HImode); --+ } --+ else --+ { --+ emit_insn (gen_unaligned_load_w (operands[0], --+ gen_rtx_MEM (SImode, operands[1]))); --+ --+ if (WORDS_BIG_ENDIAN) --+ emit_insn (gen_lshrsi3 (operands[0], operands[0], GEN_INT(16))); --+ else --+ emit_insn (gen_andsi3 (operands[0], operands[0], GEN_INT (0xffff))); --+ } --+ --+ DONE; --+}) --+ --+(define_expand "unaligned_loadsi" --+ [(set (match_operand:SI 0 "register_operand" "=r") --+ (unspec:SI [(mem:SI (match_operand:SI 1 "register_operand" "r"))] UNSPEC_UALOAD_W))] --+ "" --+{ --+ if (flag_unaligned_access) --+ { --+ rtx mem = gen_rtx_MEM (SImode, operands[1]); --+ emit_move_insn (operands[0], mem); --+ } --+ else --+ { --+ if (TARGET_ISA_V3M) --+ nds32_expand_unaligned_load (operands, SImode); --+ else --+ emit_insn (gen_unaligned_load_w (operands[0], --+ gen_rtx_MEM (SImode, (operands[1])))); --+ } --+ DONE; --+}) --+ --+(define_insn "unaligned_load_w" --+ [(set (match_operand:SI 0 "register_operand" "= r") --+ (unspec:SI [(match_operand:SI 1 "nds32_lmw_smw_base_operand" " Umw")] UNSPEC_UALOAD_W))] --+ "" --+{ --+ return nds32_output_lmw_single_word (operands); --+} --+ [(set_attr "type" "load") --+ (set_attr "length" "4")] --+) --+ --+(define_expand "unaligned_loaddi" --+ [(set (match_operand:DI 0 "register_operand" "=r") --+ (unspec:DI [(mem:DI (match_operand:SI 1 "register_operand" "r"))] UNSPEC_UALOAD_DW))] --+ "" --+{ --+ if (TARGET_ISA_V3M) --+ { --+ nds32_expand_unaligned_load (operands, DImode); --+ } --+ else --+ emit_insn (gen_unaligned_load_dw (operands[0], operands[1])); --+ DONE; --+}) --+ --+(define_insn "unaligned_load_dw" --+ [(set (match_operand:DI 0 "register_operand" "=r") --+ (unspec:DI [(mem:DI (match_operand:SI 1 "register_operand" "r"))] UNSPEC_UALOAD_DW))] --+ "" --+{ --+ rtx otherops[3]; --+ otherops[0] = gen_rtx_REG (SImode, REGNO (operands[0])); --+ otherops[1] = gen_rtx_REG (SImode, REGNO (operands[0]) + 1); --+ otherops[2] = operands[1]; --+ --+ output_asm_insn ("lmw.bi\t%0, [%2], %1, 0", otherops); --+ return ""; --+} --+ [(set_attr "type" "load") --+ (set_attr "length" "4")] --+) --+ --+(define_expand "unaligned_store_hw" --+ [(set (mem:SI (match_operand:SI 0 "register_operand" "")) --+ (unspec:HI [(match_operand:HI 1 "register_operand" "")] UNSPEC_UASTORE_HW))] --+ "" --+{ --+ operands[1] = simplify_gen_subreg (SImode, operands[1], --+ GET_MODE (operands[1]), 0); --+ nds32_expand_unaligned_store (operands, HImode); --+ DONE; --+}) --+ --+(define_expand "unaligned_storesi" --+ [(set (mem:SI (match_operand:SI 0 "register_operand" "r")) --+ (unspec:SI [(match_operand:SI 1 "register_operand" "r")] UNSPEC_UASTORE_W))] --+ "" --+{ --+ if (flag_unaligned_access) --+ { --+ rtx mem = gen_rtx_MEM (SImode, operands[0]); --+ emit_move_insn (mem, operands[1]); --+ } --+ else --+ { --+ if (TARGET_ISA_V3M) --+ nds32_expand_unaligned_store (operands, SImode); --+ else --+ emit_insn (gen_unaligned_store_w (gen_rtx_MEM (SImode, operands[0]), --+ operands[1])); --+ } --+ DONE; --+}) --+ --+(define_insn "unaligned_store_w" --+ [(set (match_operand:SI 0 "nds32_lmw_smw_base_operand" "=Umw") --+ (unspec:SI [(match_operand:SI 1 "register_operand" " r")] UNSPEC_UASTORE_W))] --+ "" --+{ --+ return nds32_output_smw_single_word (operands); --+} --+ [(set_attr "type" "store") --+ (set_attr "length" "4")] --+) --+ --+(define_expand "unaligned_storedi" --+ [(set (mem:DI (match_operand:SI 0 "register_operand" "r")) --+ (unspec:DI [(match_operand:DI 1 "register_operand" "r")] UNSPEC_UASTORE_DW))] --+ "" --+{ --+ if (TARGET_ISA_V3M) --+ nds32_expand_unaligned_store (operands, DImode); --+ else --+ emit_insn (gen_unaligned_store_dw (gen_rtx_MEM (DImode, operands[0]), --+ operands[1])); --+ DONE; --+}) --+ --+(define_insn "unaligned_store_dw" --+ [(set (match_operand:DI 0 "nds32_lmw_smw_base_operand" "=Umw") --+ (unspec:DI [(match_operand:DI 1 "register_operand" " r")] UNSPEC_UASTORE_DW))] --+ "" --+{ --+ return nds32_output_smw_double_word (operands); --+} --+ [(set_attr "type" "store") --+ (set_attr "length" "4")] --+) --+ --+(define_expand "unspec_unaligned_feature" --+ [(set (match_operand:SI 0 "register_operand" "") --+ (unspec_volatile:SI [(const_int 0)] UNSPEC_VOLATILE_UNALIGNED_FEATURE))] --+ "" --+{ --+ /* Get $MMU_CTL system register form nds32_intrinsic_register_names[] */ --+ rtx system_reg = GEN_INT (__NDS32_REG_MMU_CTL__); --+ rtx temp_reg = gen_reg_rtx (SImode); --+ rtx temp2_reg = gen_reg_rtx (SImode); --+ --+ emit_insn (gen_unspec_volatile_mfsr (operands[0], system_reg)); --+ emit_move_insn (temp_reg, operands[0]); --+ emit_move_insn (temp2_reg, GEN_INT (0x800 << 12)); --+ emit_insn (gen_iorsi3 (operands[0], operands[0], temp2_reg)); --+ emit_insn (gen_unspec_volatile_mtsr (operands[0], system_reg)); --+ emit_insn (gen_unspec_dsb ()); --+ --+ emit_insn (gen_unspec_volatile_mfsr (operands[0], system_reg)); --+ emit_insn (gen_unspec_volatile_mtsr (temp_reg, system_reg)); --+ emit_insn (gen_unspec_dsb ()); --+ --+ emit_insn (gen_ashlsi3 (operands[0], operands[0], GEN_INT (8))); --+ emit_insn (gen_lshrsi3 (operands[0], operands[0], GEN_INT (31))); --+ DONE; --+}) --+ --+(define_expand "unspec_enable_unaligned" --+ [(unspec_volatile:SI [(const_int 0)] UNSPEC_VOLATILE_UNALIGNED_FEATURE)] --+ "" --+{ --+ /* Get $MMU_CTL system register form nds32_intrinsic_register_names[] */ --+ rtx system_reg = GEN_INT (__NDS32_REG_MMU_CTL__); --+ rtx temp_reg = gen_reg_rtx (SImode); --+ rtx temp2_reg = gen_reg_rtx (SImode); --+ emit_insn (gen_unspec_volatile_mfsr (temp_reg, system_reg)); --+ emit_move_insn (temp2_reg, GEN_INT (0x800 << 12)); --+ emit_insn (gen_iorsi3 (temp_reg, temp_reg, temp2_reg)); --+ emit_insn (gen_unspec_volatile_mtsr (temp_reg, system_reg)); --+ emit_insn (gen_unspec_dsb ()); --+ DONE; --+}) --+ --+(define_expand "unspec_disable_unaligned" --+ [(unspec_volatile:SI [(const_int 0)] UNSPEC_VOLATILE_UNALIGNED_FEATURE)] --+ "" --+{ --+ /* Get $MMU_CTL system register form nds32_intrinsic_register_names[] */ --+ rtx system_reg = GEN_INT (__NDS32_REG_MMU_CTL__); --+ rtx temp_reg = gen_reg_rtx (SImode); --+ rtx temp2_reg = gen_reg_rtx (SImode); --+ emit_insn (gen_unspec_volatile_mfsr (temp_reg, system_reg)); --+ emit_move_insn (temp2_reg, GEN_INT (0x800 << 12)); --+ emit_insn (gen_one_cmplsi2 (temp2_reg, temp2_reg)); --+ emit_insn (gen_andsi3 (temp_reg, temp_reg, temp2_reg)); --+ emit_insn (gen_unspec_volatile_mtsr (temp_reg, system_reg)); --+ emit_insn (gen_unspec_dsb ()); --+ DONE; --+}) --+ --+;; abs alias kabs --+ --+(define_insn "unspec_kabs" --+ [(set (match_operand:SI 0 "register_operand" "=r") --+ (unspec:SI [(match_operand:SI 1 "register_operand" "r")] UNSPEC_KABS))] --+ "" --+ "kabs\t%0, %1" --+ [(set_attr "type" "alu") --+ (set_attr "length" "4")] --+) --+ --+(define_expand "no_hwloop" --+ [(const_int 0)] --+ "" --+{ --+ if (NDS32_HW_LOOP_P ()) --+ emit_insn (gen_unspec_no_hwloop ()); --+ else --+ emit_insn (gen_nop ()); --+ --+ DONE; --+}) --+ --+(define_insn "unspec_no_hwloop" --+ [(unspec_volatile [(const_int 0)] UNSPEC_VOLATILE_NO_HWLOOP)] --+ "" --+ "" --+ [(set_attr "type" "misc")] --+) -- ;; ------------------------------------------------------------------------ --diff --git a/gcc/config/nds32/nds32-isr.c b/gcc/config/nds32/nds32-isr.c --index 79be27e..be82609 100644 ----- a/gcc/config/nds32/nds32-isr.c --+++ b/gcc/config/nds32/nds32-isr.c --@@ -24,11 +24,41 @@ -- #include "system.h" -- #include "coretypes.h" -- #include "backend.h" ---#include "target.h" ---#include "rtl.h" -- #include "tree.h" ---#include "diagnostic-core.h" --+#include "rtl.h" --+#include "df.h" --+#include "alias.h" --+#include "stor-layout.h" --+#include "varasm.h" --+#include "calls.h" --+#include "regs.h" --+#include "insn-config.h" /* Required by recog.h. */ --+#include "conditions.h" -- #include "output.h" --+#include "insn-attr.h" /* For DFA state_t. */ --+#include "insn-codes.h" /* For CODE_FOR_xxx. */ --+#include "reload.h" /* For push_reload(). */ --+#include "flags.h" --+#include "insn-config.h" --+#include "expmed.h" --+#include "dojump.h" --+#include "explow.h" --+#include "emit-rtl.h" --+#include "stmt.h" --+#include "expr.h" --+#include "recog.h" --+#include "diagnostic-core.h" --+#include "cfgrtl.h" --+#include "cfganal.h" --+#include "lcm.h" --+#include "cfgbuild.h" --+#include "cfgcleanup.h" --+#include "tm_p.h" --+#include "tm-constrs.h" --+#include "optabs.h" /* For GEN_FCN. */ --+#include "target.h" --+#include "langhooks.h" /* For add_builtin_function(). */ --+#include "builtins.h" -- -- /* ------------------------------------------------------------------------ */ -- --@@ -39,7 +69,260 @@ -- We use an array to record essential information for each vector. */ -- static struct nds32_isr_info nds32_isr_vectors[NDS32_N_ISR_VECTORS]; -- ---/* ------------------------------------------------------------------------ */ --+/* ------------------------------------------------------------- */ --+/* FIXME: --+ FOR BACKWARD COMPATIBILITY, we need to support following patterns: --+ --+ __attribute__((interrupt("XXX;YYY;id=ZZZ"))) --+ __attribute__((exception("XXX;YYY;id=ZZZ"))) --+ __attribute__((reset("vectors=XXX;nmi_func=YYY;warm_func=ZZZ"))) --+ --+ We provide several functions to parse the strings. */ --+ --+static void --+nds32_interrupt_attribute_parse_string (const char *original_str, --+ const char *func_name, --+ unsigned int s_level) --+{ --+ char target_str[100]; --+ enum nds32_isr_save_reg save_reg; --+ enum nds32_isr_nested_type nested_type; --+ --+ char *save_all_regs_str, *save_caller_regs_str; --+ char *nested_str, *not_nested_str, *ready_nested_str, *critical_str; --+ char *id_str, *value_str; --+ --+ /* Copy original string into a character array so that --+ the string APIs can handle it. */ --+ strcpy (target_str, original_str); --+ --+ /* 1. Detect 'save_all_regs' : NDS32_SAVE_ALL --+ 'save_caller_regs' : NDS32_PARTIAL_SAVE */ --+ save_all_regs_str = strstr (target_str, "save_all_regs"); --+ save_caller_regs_str = strstr (target_str, "save_caller_regs"); --+ --+ /* Note that if no argument is found, --+ use NDS32_PARTIAL_SAVE by default. */ --+ if (save_all_regs_str) --+ save_reg = NDS32_SAVE_ALL; --+ else if (save_caller_regs_str) --+ save_reg = NDS32_PARTIAL_SAVE; --+ else --+ save_reg = NDS32_PARTIAL_SAVE; --+ --+ /* 2. Detect 'nested' : NDS32_NESTED --+ 'not_nested' : NDS32_NOT_NESTED --+ 'ready_nested' : NDS32_NESTED_READY --+ 'critical' : NDS32_CRITICAL */ --+ nested_str = strstr (target_str, "nested"); --+ not_nested_str = strstr (target_str, "not_nested"); --+ ready_nested_str = strstr (target_str, "ready_nested"); --+ critical_str = strstr (target_str, "critical"); --+ --+ /* Note that if no argument is found, --+ use NDS32_NOT_NESTED by default. --+ Also, since 'not_nested' and 'ready_nested' both contains --+ 'nested' string, we check 'nested' with lowest priority. */ --+ if (not_nested_str) --+ nested_type = NDS32_NOT_NESTED; --+ else if (ready_nested_str) --+ nested_type = NDS32_NESTED_READY; --+ else if (nested_str) --+ nested_type = NDS32_NESTED; --+ else if (critical_str) --+ nested_type = NDS32_CRITICAL; --+ else --+ nested_type = NDS32_NOT_NESTED; --+ --+ /* 3. Traverse each id value and set corresponding information. */ --+ id_str = strstr (target_str, "id="); --+ --+ /* If user forgets to assign 'id', issue an error message. */ --+ if (id_str == NULL) --+ error ("require id argument in the string"); --+ /* Extract the value_str first. */ --+ id_str = strtok (id_str, "="); --+ value_str = strtok (NULL, ";"); --+ --+ /* Pick up the first id value token. */ --+ value_str = strtok (value_str, ","); --+ while (value_str != NULL) --+ { --+ int i; --+ i = atoi (value_str); --+ --+ /* For interrupt(0..63), the actual vector number is (9..72). */ --+ i = i + 9; --+ if (i < 9 || i > 72) --+ error ("invalid id value for interrupt attribute"); --+ --+ /* Setup nds32_isr_vectors[] array. */ --+ nds32_isr_vectors[i].category = NDS32_ISR_INTERRUPT; --+ strcpy (nds32_isr_vectors[i].func_name, func_name); --+ nds32_isr_vectors[i].save_reg = save_reg; --+ nds32_isr_vectors[i].nested_type = nested_type; --+ nds32_isr_vectors[i].security_level = s_level; --+ --+ /* Fetch next token. */ --+ value_str = strtok (NULL, ","); --+ } --+ --+ return; --+} --+ --+static void --+nds32_exception_attribute_parse_string (const char *original_str, --+ const char *func_name, --+ unsigned int s_level) --+{ --+ char target_str[100]; --+ enum nds32_isr_save_reg save_reg; --+ enum nds32_isr_nested_type nested_type; --+ --+ char *save_all_regs_str, *save_caller_regs_str; --+ char *nested_str, *not_nested_str, *ready_nested_str, *critical_str; --+ char *id_str, *value_str; --+ --+ /* Copy original string into a character array so that --+ the string APIs can handle it. */ --+ strcpy (target_str, original_str); --+ --+ /* 1. Detect 'save_all_regs' : NDS32_SAVE_ALL --+ 'save_caller_regs' : NDS32_PARTIAL_SAVE */ --+ save_all_regs_str = strstr (target_str, "save_all_regs"); --+ save_caller_regs_str = strstr (target_str, "save_caller_regs"); --+ --+ /* Note that if no argument is found, --+ use NDS32_PARTIAL_SAVE by default. */ --+ if (save_all_regs_str) --+ save_reg = NDS32_SAVE_ALL; --+ else if (save_caller_regs_str) --+ save_reg = NDS32_PARTIAL_SAVE; --+ else --+ save_reg = NDS32_PARTIAL_SAVE; --+ --+ /* 2. Detect 'nested' : NDS32_NESTED --+ 'not_nested' : NDS32_NOT_NESTED --+ 'ready_nested' : NDS32_NESTED_READY --+ 'critical' : NDS32_CRITICAL */ --+ nested_str = strstr (target_str, "nested"); --+ not_nested_str = strstr (target_str, "not_nested"); --+ ready_nested_str = strstr (target_str, "ready_nested"); --+ critical_str = strstr (target_str, "critical"); --+ --+ /* Note that if no argument is found, --+ use NDS32_NOT_NESTED by default. --+ Also, since 'not_nested' and 'ready_nested' both contains --+ 'nested' string, we check 'nested' with lowest priority. */ --+ if (not_nested_str) --+ nested_type = NDS32_NOT_NESTED; --+ else if (ready_nested_str) --+ nested_type = NDS32_NESTED_READY; --+ else if (nested_str) --+ nested_type = NDS32_NESTED; --+ else if (critical_str) --+ nested_type = NDS32_CRITICAL; --+ else --+ nested_type = NDS32_NOT_NESTED; --+ --+ /* 3. Traverse each id value and set corresponding information. */ --+ id_str = strstr (target_str, "id="); --+ --+ /* If user forgets to assign 'id', issue an error message. */ --+ if (id_str == NULL) --+ error ("require id argument in the string"); --+ /* Extract the value_str first. */ --+ id_str = strtok (id_str, "="); --+ value_str = strtok (NULL, ";"); --+ --+ /* Pick up the first id value token. */ --+ value_str = strtok (value_str, ","); --+ while (value_str != NULL) --+ { --+ int i; --+ i = atoi (value_str); --+ --+ /* For exception(1..8), the actual vector number is (1..8). */ --+ if (i < 1 || i > 8) --+ error ("invalid id value for exception attribute"); --+ --+ /* Setup nds32_isr_vectors[] array. */ --+ nds32_isr_vectors[i].category = NDS32_ISR_EXCEPTION; --+ strcpy (nds32_isr_vectors[i].func_name, func_name); --+ nds32_isr_vectors[i].save_reg = save_reg; --+ nds32_isr_vectors[i].nested_type = nested_type; --+ nds32_isr_vectors[i].security_level = s_level; --+ --+ /* Fetch next token. */ --+ value_str = strtok (NULL, ","); --+ } --+ --+ return; --+} --+ --+static void --+nds32_reset_attribute_parse_string (const char *original_str, --+ const char *func_name) --+{ --+ char target_str[100]; --+ char *vectors_str, *nmi_str, *warm_str, *value_str; --+ --+ /* Deal with reset attribute. Its vector number is always 0. */ --+ nds32_isr_vectors[0].category = NDS32_ISR_RESET; --+ --+ --+ /* 1. Parse 'vectors=XXXX'. */ --+ --+ /* Copy original string into a character array so that --+ the string APIs can handle it. */ --+ strcpy (target_str, original_str); --+ vectors_str = strstr (target_str, "vectors="); --+ /* The total vectors = interrupt + exception numbers + reset. --+ There are 8 exception and 1 reset in nds32 architecture. --+ If user forgets to assign 'vectors', user default 16 interrupts. */ --+ if (vectors_str != NULL) --+ { --+ /* Extract the value_str. */ --+ vectors_str = strtok (vectors_str, "="); --+ value_str = strtok (NULL, ";"); --+ nds32_isr_vectors[0].total_n_vectors = atoi (value_str) + 8 + 1; --+ } --+ else --+ nds32_isr_vectors[0].total_n_vectors = 16 + 8 + 1; --+ strcpy (nds32_isr_vectors[0].func_name, func_name); --+ --+ --+ /* 2. Parse 'nmi_func=YYYY'. */ --+ --+ /* Copy original string into a character array so that --+ the string APIs can handle it. */ --+ strcpy (target_str, original_str); --+ nmi_str = strstr (target_str, "nmi_func="); --+ if (nmi_str != NULL) --+ { --+ /* Extract the value_str. */ --+ nmi_str = strtok (nmi_str, "="); --+ value_str = strtok (NULL, ";"); --+ strcpy (nds32_isr_vectors[0].nmi_name, value_str); --+ } --+ --+ /* 3. Parse 'warm_func=ZZZZ'. */ --+ --+ /* Copy original string into a character array so that --+ the string APIs can handle it. */ --+ strcpy (target_str, original_str); --+ warm_str = strstr (target_str, "warm_func="); --+ if (warm_str != NULL) --+ { --+ /* Extract the value_str. */ --+ warm_str = strtok (warm_str, "="); --+ value_str = strtok (NULL, ";"); --+ strcpy (nds32_isr_vectors[0].warm_name, value_str); --+ } --+ --+ return; --+} --+/* ------------------------------------------------------------- */ -- -- /* A helper function to emit section head template. */ -- static void --@@ -75,6 +358,15 @@ nds32_emit_isr_jmptbl_section (int vector_id) -- char section_name[100]; -- char symbol_name[100]; -- --+ /* A critical isr does not need jump table section because --+ its behavior is not performed by two-level handler. */ --+ if (nds32_isr_vectors[vector_id].nested_type == NDS32_CRITICAL) --+ { --+ fprintf (asm_out_file, "\t! The vector %02d is a critical isr !\n", --+ vector_id); --+ return; --+ } --+ -- /* Prepare jmptbl section and symbol name. */ -- snprintf (section_name, sizeof (section_name), -- ".nds32_jmptbl.%02d", vector_id); --@@ -95,7 +387,6 @@ nds32_emit_isr_vector_section (int vector_id) -- const char *c_str = "CATEGORY"; -- const char *sr_str = "SR"; -- const char *nt_str = "NT"; --- const char *vs_str = "VS"; -- char first_level_handler_name[100]; -- char section_name[100]; -- char symbol_name[100]; --@@ -143,46 +434,63 @@ nds32_emit_isr_vector_section (int vector_id) -- case NDS32_NESTED_READY: -- nt_str = "nr"; -- break; --+ case NDS32_CRITICAL: --+ /* The critical isr is not performed by two-level handler. */ --+ nt_str = ""; --+ break; -- } -- --- /* Currently we have 4-byte or 16-byte size for each vector. --- If it is 4-byte, the first level handler name has suffix string "_4b". */ --- vs_str = (nds32_isr_vector_size == 4) ? "_4b" : ""; --- -- /* Now we can create first level handler name. */ --- snprintf (first_level_handler_name, sizeof (first_level_handler_name), --- "_nds32_%s_%s_%s%s", c_str, sr_str, nt_str, vs_str); --+ if (nds32_isr_vectors[vector_id].security_level == 0) --+ { --+ /* For security level 0, use normal first level handler name. */ --+ snprintf (first_level_handler_name, sizeof (first_level_handler_name), --+ "_nds32_%s_%s_%s", c_str, sr_str, nt_str); --+ } --+ else --+ { --+ /* For security level 1-3, use corresponding spl_1, spl_2, or spl_3. */ --+ snprintf (first_level_handler_name, sizeof (first_level_handler_name), --+ "_nds32_spl_%d", nds32_isr_vectors[vector_id].security_level); --+ } -- -- /* Prepare vector section and symbol name. */ -- snprintf (section_name, sizeof (section_name), -- ".nds32_vector.%02d", vector_id); -- snprintf (symbol_name, sizeof (symbol_name), --- "_nds32_vector_%02d%s", vector_id, vs_str); --+ "_nds32_vector_%02d", vector_id); -- -- -- /* Everything is ready. We can start emit vector section content. */ -- nds32_emit_section_head_template (section_name, symbol_name, -- floor_log2 (nds32_isr_vector_size), false); -- --- /* According to the vector size, the instructions in the --- vector section may be different. */ --- if (nds32_isr_vector_size == 4) --+ /* First we check if it is a critical isr. --+ If so, jump to user handler directly; otherwise, the instructions --+ in the vector section may be different according to the vector size. */ --+ if (nds32_isr_vectors[vector_id].nested_type == NDS32_CRITICAL) --+ { --+ /* This block is for critical isr. Jump to user handler directly. */ --+ fprintf (asm_out_file, "\tj\t%s ! jump to user handler directly\n", --+ nds32_isr_vectors[vector_id].func_name); --+ } --+ else if (nds32_isr_vector_size == 4) -- { -- /* This block is for 4-byte vector size. --- Hardware $VID support is necessary and only one instruction --- is needed in vector section. */ --+ Hardware $VID support is necessary and only one instruction --+ is needed in vector section. */ -- fprintf (asm_out_file, "\tj\t%s ! jump to first level handler\n", -- first_level_handler_name); -- } -- else -- { -- /* This block is for 16-byte vector size. --- There is NO hardware $VID so that we need several instructions --- such as pushing GPRs and preparing software vid at vector section. --- For pushing GPRs, there are four variations for --- 16-byte vector content and we have to handle each combination. --- For preparing software vid, note that the vid need to --- be substracted vector_number_offset. */ --+ There is NO hardware $VID so that we need several instructions --+ such as pushing GPRs and preparing software vid at vector section. --+ For pushing GPRs, there are four variations for --+ 16-byte vector content and we have to handle each combination. --+ For preparing software vid, note that the vid need to --+ be substracted vector_number_offset. */ -- if (TARGET_REDUCED_REGS) -- { -- if (nds32_isr_vectors[vector_id].save_reg == NDS32_SAVE_ALL) --@@ -235,13 +543,11 @@ nds32_emit_isr_reset_content (void) -- { -- unsigned int i; -- unsigned int total_n_vectors; --- const char *vs_str; -- char reset_handler_name[100]; -- char section_name[100]; -- char symbol_name[100]; -- -- total_n_vectors = nds32_isr_vectors[0].total_n_vectors; --- vs_str = (nds32_isr_vector_size == 4) ? "_4b" : ""; -- -- fprintf (asm_out_file, "\t! RESET HANDLER CONTENT - BEGIN !\n"); -- --@@ -257,7 +563,7 @@ nds32_emit_isr_reset_content (void) -- /* Emit vector references. */ -- fprintf (asm_out_file, "\t ! references to vector section entries\n"); -- for (i = 0; i < total_n_vectors; i++) --- fprintf (asm_out_file, "\t.word\t_nds32_vector_%02d%s\n", i, vs_str); --+ fprintf (asm_out_file, "\t.word\t_nds32_vector_%02d\n", i); -- -- /* Emit jmptbl_00 section. */ -- snprintf (section_name, sizeof (section_name), ".nds32_jmptbl.00"); --@@ -271,9 +577,9 @@ nds32_emit_isr_reset_content (void) -- -- /* Emit vector_00 section. */ -- snprintf (section_name, sizeof (section_name), ".nds32_vector.00"); --- snprintf (symbol_name, sizeof (symbol_name), "_nds32_vector_00%s", vs_str); --+ snprintf (symbol_name, sizeof (symbol_name), "_nds32_vector_00"); -- snprintf (reset_handler_name, sizeof (reset_handler_name), --- "_nds32_reset%s", vs_str); --+ "_nds32_reset"); -- -- fprintf (asm_out_file, "\t! ....................................\n"); -- nds32_emit_section_head_template (section_name, symbol_name, --@@ -319,12 +625,12 @@ void -- nds32_check_isr_attrs_conflict (tree func_decl, tree func_attrs) -- { -- int save_all_p, partial_save_p; --- int nested_p, not_nested_p, nested_ready_p; --+ int nested_p, not_nested_p, nested_ready_p, critical_p; -- int intr_p, excp_p, reset_p; -- -- /* Initialize variables. */ -- save_all_p = partial_save_p = 0; --- nested_p = not_nested_p = nested_ready_p = 0; --+ nested_p = not_nested_p = nested_ready_p = critical_p = 0; -- intr_p = excp_p = reset_p = 0; -- -- /* We must check at MOST one attribute to set save-reg. */ --@@ -343,8 +649,10 @@ nds32_check_isr_attrs_conflict (tree func_decl, tree func_attrs) -- not_nested_p = 1; -- if (lookup_attribute ("nested_ready", func_attrs)) -- nested_ready_p = 1; --+ if (lookup_attribute ("critical", func_attrs)) --+ critical_p = 1; -- --- if ((nested_p + not_nested_p + nested_ready_p) > 1) --+ if ((nested_p + not_nested_p + nested_ready_p + critical_p) > 1) -- error ("multiple nested types attributes to function %qD", func_decl); -- -- /* We must check at MOST one attribute to --@@ -358,6 +666,17 @@ nds32_check_isr_attrs_conflict (tree func_decl, tree func_attrs) -- -- if ((intr_p + excp_p + reset_p) > 1) -- error ("multiple interrupt attributes to function %qD", func_decl); --+ --+ /* Do not allow isr attributes under linux toolchain. */ --+ if (TARGET_LINUX_ABI && intr_p) --+ error ("cannot use interrupt attributes to function %qD " --+ "under linux toolchain", func_decl); --+ if (TARGET_LINUX_ABI && excp_p) --+ error ("cannot use exception attributes to function %qD " --+ "under linux toolchain", func_decl); --+ if (TARGET_LINUX_ABI && reset_p) --+ error ("cannot use reset attributes to function %qD " --+ "under linux toolchain", func_decl); -- } -- -- /* Function to construct isr vectors information array. --@@ -369,15 +688,21 @@ nds32_construct_isr_vectors_information (tree func_attrs, -- const char *func_name) -- { -- tree save_all, partial_save; --- tree nested, not_nested, nested_ready; --+ tree nested, not_nested, nested_ready, critical; -- tree intr, excp, reset; -- --+ tree secure; --+ tree security_level_list; --+ tree security_level; --+ unsigned int s_level; --+ -- save_all = lookup_attribute ("save_all", func_attrs); -- partial_save = lookup_attribute ("partial_save", func_attrs); -- -- nested = lookup_attribute ("nested", func_attrs); -- not_nested = lookup_attribute ("not_nested", func_attrs); -- nested_ready = lookup_attribute ("nested_ready", func_attrs); --+ critical = lookup_attribute ("critical", func_attrs); -- -- intr = lookup_attribute ("interrupt", func_attrs); -- excp = lookup_attribute ("exception", func_attrs); --@@ -387,6 +712,63 @@ nds32_construct_isr_vectors_information (tree func_attrs, -- if (!intr && !excp && !reset) -- return; -- --+ /* At first, we need to retrieve security level. */ --+ secure = lookup_attribute ("secure", func_attrs); --+ if (secure != NULL) --+ { --+ security_level_list = TREE_VALUE (secure); --+ security_level = TREE_VALUE (security_level_list); --+ s_level = TREE_INT_CST_LOW (security_level); --+ } --+ else --+ { --+ /* If there is no secure attribute, the security level is set by --+ nds32_isr_secure_level, which is controlled by -misr-secure=X option. --+ By default nds32_isr_secure_level should be 0. */ --+ s_level = nds32_isr_secure_level; --+ } --+ --+ /* ------------------------------------------------------------- */ --+ /* FIXME: --+ FOR BACKWARD COMPATIBILITY, we need to support following patterns: --+ --+ __attribute__((interrupt("XXX;YYY;id=ZZZ"))) --+ __attribute__((exception("XXX;YYY;id=ZZZ"))) --+ __attribute__((reset("vectors=XXX;nmi_func=YYY;warm_func=ZZZ"))) --+ --+ If interrupt/exception/reset appears and its argument is a --+ STRING_CST, we will parse string with some auxiliary functions --+ which set necessary isr information in the nds32_isr_vectors[] array. --+ After that, we can return immediately to avoid new-syntax isr --+ information construction. */ --+ if (intr != NULL_TREE --+ && TREE_CODE (TREE_VALUE (TREE_VALUE (intr))) == STRING_CST) --+ { --+ tree string_arg = TREE_VALUE (TREE_VALUE (intr)); --+ nds32_interrupt_attribute_parse_string (TREE_STRING_POINTER (string_arg), --+ func_name, --+ s_level); --+ return; --+ } --+ if (excp != NULL_TREE --+ && TREE_CODE (TREE_VALUE (TREE_VALUE (excp))) == STRING_CST) --+ { --+ tree string_arg = TREE_VALUE (TREE_VALUE (excp)); --+ nds32_exception_attribute_parse_string (TREE_STRING_POINTER (string_arg), --+ func_name, --+ s_level); --+ return; --+ } --+ if (reset != NULL_TREE --+ && TREE_CODE (TREE_VALUE (TREE_VALUE (reset))) == STRING_CST) --+ { --+ tree string_arg = TREE_VALUE (TREE_VALUE (reset)); --+ nds32_reset_attribute_parse_string (TREE_STRING_POINTER (string_arg), --+ func_name); --+ return; --+ } --+ /* ------------------------------------------------------------- */ --+ -- /* If we are here, either we have interrupt/exception, -- or reset attribute. */ -- if (intr || excp) --@@ -413,6 +795,9 @@ nds32_construct_isr_vectors_information (tree func_attrs, -- /* Add vector_number_offset to get actual vector number. */ -- vector_id = TREE_INT_CST_LOW (id) + vector_number_offset; -- --+ /* Set security level. */ --+ nds32_isr_vectors[vector_id].security_level = s_level; --+ -- /* Enable corresponding vector and set function name. */ -- nds32_isr_vectors[vector_id].category = (intr) -- ? (NDS32_ISR_INTERRUPT) --@@ -432,6 +817,8 @@ nds32_construct_isr_vectors_information (tree func_attrs, -- nds32_isr_vectors[vector_id].nested_type = NDS32_NOT_NESTED; -- else if (nested_ready) -- nds32_isr_vectors[vector_id].nested_type = NDS32_NESTED_READY; --+ else if (critical) --+ nds32_isr_vectors[vector_id].nested_type = NDS32_CRITICAL; -- -- /* Advance to next id. */ -- id_list = TREE_CHAIN (id_list); --@@ -447,12 +834,12 @@ nds32_construct_isr_vectors_information (tree func_attrs, -- nds32_isr_vectors[0].category = NDS32_ISR_RESET; -- -- /* Prepare id_list and identify id value so that --- we can set total number of vectors. */ --+ we can set total number of vectors. */ -- id_list = TREE_VALUE (reset); -- id = TREE_VALUE (id_list); -- -- /* The total vectors = interrupt + exception numbers + reset. --- There are 8 exception and 1 reset in nds32 architecture. */ --+ There are 8 exception and 1 reset in nds32 architecture. */ -- nds32_isr_vectors[0].total_n_vectors = TREE_INT_CST_LOW (id) + 8 + 1; -- strcpy (nds32_isr_vectors[0].func_name, func_name); -- --@@ -488,7 +875,6 @@ nds32_construct_isr_vectors_information (tree func_attrs, -- } -- } -- ---/* A helper function to handle isr stuff at the beginning of asm file. */ -- void -- nds32_asm_file_start_for_isr (void) -- { --@@ -501,15 +887,14 @@ nds32_asm_file_start_for_isr (void) -- strcpy (nds32_isr_vectors[i].func_name, ""); -- nds32_isr_vectors[i].save_reg = NDS32_PARTIAL_SAVE; -- nds32_isr_vectors[i].nested_type = NDS32_NOT_NESTED; --+ nds32_isr_vectors[i].security_level = 0; -- nds32_isr_vectors[i].total_n_vectors = 0; -- strcpy (nds32_isr_vectors[i].nmi_name, ""); -- strcpy (nds32_isr_vectors[i].warm_name, ""); -- } -- } -- ---/* A helper function to handle isr stuff at the end of asm file. */ ---void ---nds32_asm_file_end_for_isr (void) --+void nds32_asm_file_end_for_isr (void) -- { -- int i; -- --@@ -543,6 +928,8 @@ nds32_asm_file_end_for_isr (void) -- /* Found one vector which is interupt or exception. -- Output its jmptbl and vector section content. */ -- fprintf (asm_out_file, "\t! interrupt/exception vector %02d\n", i); --+ fprintf (asm_out_file, "\t! security level: %d\n", --+ nds32_isr_vectors[i].security_level); -- fprintf (asm_out_file, "\t! ------------------------------------\n"); -- nds32_emit_isr_jmptbl_section (i); -- fprintf (asm_out_file, "\t! ....................................\n"); --@@ -576,4 +963,65 @@ nds32_isr_function_p (tree func) -- || (t_reset != NULL_TREE)); -- } -- ---/* ------------------------------------------------------------------------ */ --+/* Return true if FUNC is a isr function with critical attribute. */ --+bool --+nds32_isr_function_critical_p (tree func) --+{ --+ tree t_intr; --+ tree t_excp; --+ tree t_critical; --+ --+ tree attrs; --+ --+ if (TREE_CODE (func) != FUNCTION_DECL) --+ abort (); --+ --+ attrs = DECL_ATTRIBUTES (func); --+ --+ t_intr = lookup_attribute ("interrupt", attrs); --+ t_excp = lookup_attribute ("exception", attrs); --+ --+ t_critical = lookup_attribute ("critical", attrs); --+ --+ /* If both interrupt and exception attribute does not appear, --+ we can return false immediately. */ --+ if ((t_intr == NULL_TREE) && (t_excp == NULL_TREE)) --+ return false; --+ --+ /* Here we can guarantee either interrupt or ecxception attribute --+ does exist, so further check critical attribute. --+ If it also appears, we can return true. */ --+ if (t_critical != NULL_TREE) --+ return true; --+ --+ /* ------------------------------------------------------------- */ --+ /* FIXME: --+ FOR BACKWARD COMPATIBILITY, we need to handle string type. --+ If the string 'critical' appears in the interrupt/exception --+ string argument, we can return true. */ --+ if (t_intr != NULL_TREE || t_excp != NULL_TREE) --+ { --+ char target_str[100]; --+ char *critical_str; --+ tree t_check; --+ tree string_arg; --+ --+ t_check = t_intr ? t_intr : t_excp; --+ if (TREE_CODE (TREE_VALUE (TREE_VALUE (t_check))) == STRING_CST) --+ { --+ string_arg = TREE_VALUE (TREE_VALUE (t_check)); --+ strcpy (target_str, TREE_STRING_POINTER (string_arg)); --+ critical_str = strstr (target_str, "critical"); --+ --+ /* Found 'critical' string, so return true. */ --+ if (critical_str) --+ return true; --+ } --+ } --+ /* ------------------------------------------------------------- */ --+ --+ /* Other cases, this isr function is not critical type. */ --+ return false; --+} --+ --+/* ------------------------------------------------------------- */ --diff --git a/gcc/config/nds32/nds32-linux.opt b/gcc/config/nds32/nds32-linux.opt --new file mode 100644 --index 0000000..75ccd76 ----- /dev/null --+++ b/gcc/config/nds32/nds32-linux.opt --@@ -0,0 +1,16 @@ --+mcmodel= --+Target RejectNegative Joined Enum(nds32_cmodel_type) Var(nds32_cmodel_option) Init(CMODEL_LARGE) --+Specify the address generation strategy for code model. --+ --+Enum --+Name(nds32_cmodel_type) Type(enum nds32_cmodel_type) --+Known cmodel types (for use with the -mcmodel= option): --+ --+EnumValue --+Enum(nds32_cmodel_type) String(small) Value(CMODEL_SMALL) --+ --+EnumValue --+Enum(nds32_cmodel_type) String(medium) Value(CMODEL_MEDIUM) --+ --+EnumValue --+Enum(nds32_cmodel_type) String(large) Value(CMODEL_LARGE) --diff --git a/gcc/config/nds32/nds32-lmwsmw.c b/gcc/config/nds32/nds32-lmwsmw.c --new file mode 100644 --index 0000000..e3b66bf ----- /dev/null --+++ b/gcc/config/nds32/nds32-lmwsmw.c --@@ -0,0 +1,1998 @@ --+ --+/* lmwsmw pass of Andes NDS32 cpu for GNU compiler --+ Copyright (C) 2012-2016 Free Software Foundation, Inc. --+ Contributed by Andes Technology Corporation. --+ --+ This file is part of GCC. --+ --+ GCC is free software; you can redistribute it and/or modify it --+ under the terms of the GNU General Public License as published --+ by the Free Software Foundation; either version 3, or (at your --+ option) any later version. --+ --+ GCC is distributed in the hope that it will be useful, but WITHOUT --+ ANY WARRANTY; without even the implied warranty of MERCHANTABILITY --+ or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public --+ License for more details. --+ --+ You should have received a copy of the GNU General Public License --+ along with GCC; see the file COPYING3. If not see --+ . */ --+ --+/* ------------------------------------------------------------------------ */ --+#include "config.h" --+#include "system.h" --+#include "coretypes.h" --+#include "tm.h" --+#include "hash-set.h" --+#include "machmode.h" --+#include "vec.h" --+#include "double-int.h" --+#include "input.h" --+#include "alias.h" --+#include "symtab.h" --+#include "wide-int.h" --+#include "inchash.h" --+#include "tree.h" --+#include "stor-layout.h" --+#include "varasm.h" --+#include "calls.h" --+#include "rtl.h" --+#include "regs.h" --+#include "hard-reg-set.h" --+#include "insn-config.h" /* Required by recog.h. */ --+#include "conditions.h" --+#include "output.h" --+#include "insn-attr.h" /* For DFA state_t. */ --+#include "insn-codes.h" /* For CODE_FOR_xxx. */ --+#include "reload.h" /* For push_reload(). */ --+#include "flags.h" --+#include "input.h" --+#include "function.h" --+#include "expr.h" --+#include "recog.h" --+#include "diagnostic-core.h" --+#include "dominance.h" --+#include "cfg.h" --+#include "cfgrtl.h" --+#include "cfganal.h" --+#include "lcm.h" --+#include "cfgbuild.h" --+#include "cfgcleanup.h" --+#include "predict.h" --+#include "basic-block.h" --+#include "bitmap.h" --+#include "df.h" --+#include "tm_p.h" --+#include "tm-constrs.h" --+#include "optabs.h" /* For GEN_FCN. */ --+#include "target.h" --+#include "langhooks.h" /* For add_builtin_function(). */ --+#include "ggc.h" --+#include "tree-pass.h" --+#include "target-globals.h" --+#include "ira.h" --+#include "ira-int.h" --+#include "regrename.h" --+#include "nds32-load-store-opt.h" --+#include "nds32-reg-utils.h" --+#include --+#include --+#include --+ --+#define NDS32_GPR_NUM 32 --+ --+static int --+compare_order (const void *a, const void *b) --+{ --+ const load_store_info_t *fp1 = (const load_store_info_t *) a; --+ const load_store_info_t *fp2 = (const load_store_info_t *) b; --+ const load_store_info_t f1 = *fp1; --+ const load_store_info_t f2 = *fp2; --+ --+ return f1.order < f2.order ? -1 : 1; --+} --+ --+static int --+compare_offset (const void *a, const void *b) --+{ --+ const load_store_info_t *fp1 = (const load_store_info_t *) a; --+ const load_store_info_t *fp2 = (const load_store_info_t *) b; --+ const load_store_info_t f1 = *fp1; --+ const load_store_info_t f2 = *fp2; --+ --+ return f1.offset < f2.offset ? -1 : 1; --+} --+ --+static bool --+compare_amount(available_reg_info_t a, available_reg_info_t b) --+{ --+ return a.amount > b.amount; --+} --+ --+static bool --+nds32_load_store_reg_plus_offset (rtx_insn *insn, load_store_info_t *load_store_info) --+{ --+ rtx pattern, mem, reg, base_reg, addr; --+ HOST_WIDE_INT offset; --+ bool load_p; --+ enum nds32_memory_post_type post_type = NDS32_NONE; --+ --+ pattern = PATTERN (insn); --+ mem = NULL_RTX; --+ reg = NULL_RTX; --+ base_reg = NULL_RTX; --+ offset = 0; --+ load_p = false; --+ --+ if (GET_CODE (pattern) != SET) --+ return false; --+ --+ if (MEM_P (SET_SRC (pattern))) --+ { --+ mem = SET_SRC (pattern); --+ reg = SET_DEST (pattern); --+ load_p = true; --+ } --+ --+ if (MEM_P (SET_DEST (pattern))) --+ { --+ mem = SET_DEST (pattern); --+ reg = SET_SRC (pattern); --+ load_p = false; --+ } --+ --+ if (mem == NULL_RTX || reg == NULL_RTX || !REG_P (reg)) --+ return false; --+ --+ /* The FPU ISA has not load-store-multiple instruction. */ --+ if (!NDS32_IS_GPR_REGNUM (REGNO (reg))) --+ return false; --+ --+ if (MEM_VOLATILE_P (mem)) --+ return false; --+ --+ if (GET_MODE (reg) != SImode) --+ return false; --+ --+ gcc_assert (REG_P (reg)); --+ --+ addr = XEXP (mem, 0); --+ --+ /* We only care about [reg] and [reg+const]. */ --+ if (REG_P (addr)) --+ { --+ base_reg = addr; --+ offset = 0; --+ } --+ else if (GET_CODE (addr) == PLUS --+ && CONST_INT_P (XEXP (addr, 1))) --+ { --+ base_reg = XEXP (addr, 0); --+ offset = INTVAL (XEXP (addr, 1)); --+ if (!REG_P (base_reg)) --+ return false; --+ } --+ else if (GET_CODE (addr) == POST_INC) --+ { --+ base_reg = XEXP (addr, 0); --+ offset = 0; --+ post_type = NDS32_POST_INC; --+ } --+ else if (GET_CODE (addr) == POST_DEC) --+ { --+ base_reg = XEXP (addr, 0); --+ offset = 0; --+ post_type = NDS32_POST_DEC; --+ } --+ else --+ return false; --+ --+ if ((REGNO (base_reg) > NDS32_LAST_GPR_REGNUM) --+ && (REGNO (base_reg) < FIRST_PSEUDO_REGISTER)) --+ return false; --+ --+ if (load_store_info) --+ { --+ load_store_info->load_p = load_p; --+ load_store_info->offset = offset; --+ load_store_info->reg = reg; --+ load_store_info->base_reg = base_reg; --+ load_store_info->insn = insn; --+ load_store_info->mem = mem; --+ load_store_info->post_type = post_type; --+ } --+ --+ return true; --+} --+ --+static bool --+nds32_insn_alias_p (rtx memref, rtx x) --+{ --+ rtx mem; --+ --+ if (GET_CODE (x) == PARALLEL) --+ { --+ int i, j; --+ --+ for (i = GET_RTX_LENGTH (GET_CODE (x)) - 1; i >= 0; i--) --+ { --+ for (j = XVECLEN (x, i) - 1; j >= 0; j--) --+ if (nds32_insn_alias_p (memref, XVECEXP (x, i, j))) --+ return true; --+ } --+ --+ return false; --+ } --+ --+ if (GET_CODE (x) != SET) --+ return true; --+ --+ if (MEM_P (SET_SRC (x))) --+ mem = SET_SRC (x); --+ else if (MEM_P (SET_DEST (x))) --+ mem = SET_DEST (x); --+ else --+ return false; --+ --+ if (may_alias_p (memref, mem)) --+ return true; --+ else --+ return false; --+} --+ --+static void --+nds32_emit_multiple_insn (load_store_infos_t *multiple_insn, --+ rtx base_reg, rtx place, bool update_p) --+{ --+ unsigned int i; --+ unsigned int num_use_regs = multiple_insn->length (); --+ int par_index = 0; --+ int offset = 0; --+ bool load_p = (*multiple_insn)[0].load_p; --+ --+ rtx reg; --+ rtx mem; --+ rtx push_rtx; --+ rtx update_offset; --+ rtx parallel_insn; --+ --+ /* In addition to used registers, --+ we need one more space for (set base base-x) rtx. */ --+ if (update_p) --+ num_use_regs++; --+ --+ parallel_insn = gen_rtx_PARALLEL (VOIDmode, --+ rtvec_alloc (num_use_regs)); --+ --+ /* Set update insn. */ --+ if (update_p) --+ { --+ update_offset = GEN_INT (multiple_insn->length () * 4); --+ push_rtx = gen_addsi3 (base_reg, base_reg, update_offset); --+ XVECEXP (parallel_insn, 0, par_index) = push_rtx; --+ par_index++; --+ } --+ --+ /* Create (set mem regX) from start_reg to end_reg. */ --+ for (i = 0; i < multiple_insn->length (); ++i) --+ { --+ reg = (*multiple_insn)[i].reg; --+ mem = gen_frame_mem (SImode, plus_constant (Pmode, --+ base_reg, --+ offset)); --+ MEM_COPY_ATTRIBUTES (mem, (*multiple_insn)[i].mem); --+ --+ if (load_p) --+ push_rtx = gen_rtx_SET (reg, mem); --+ else --+ push_rtx = gen_rtx_SET (mem, reg); --+ --+ XVECEXP (parallel_insn, 0, par_index) = push_rtx; --+ offset = offset + 4; --+ par_index++; --+ } --+ --+ emit_insn_before (parallel_insn, place); --+ --+ if (dump_file) --+ { --+ fprintf (dump_file, "lmw/smw instruction:\n"); --+ print_rtl_single (dump_file, parallel_insn); --+ } --+} --+ --+static void --+nds32_emit_add_insn (load_store_info_t insn, rtx base_reg, --+ rtx place, bool add_p) --+{ --+ rtx add_insn; --+ HOST_WIDE_INT offset = insn.offset; --+ if (!add_p) --+ offset = -offset; --+ --+ add_insn = gen_addsi3 (base_reg, insn.base_reg, GEN_INT (offset)); --+ emit_insn_before (add_insn, place); --+} --+ --+/* Get the instruction of same ID. */ --+static void --+nds32_fetch_group_insn (load_store_infos_t *src, --+ load_store_infos_t *dst, int id) --+{ --+ unsigned int i = 0; --+ --+ while (i < src->length ()) --+ { --+ if (id == (*src)[i].group) --+ { --+ dst->safe_push ((*src)[i]); --+ src->ordered_remove (i); --+ i = 0; --+ } --+ else --+ i++; --+ } --+} --+ --+/* Check registers are not used and defined. */ --+static rtx --+nds32_lmwsmw_insert_place (load_store_infos_t *insn_set) --+{ --+ unsigned int i, position; --+ bool combine_p; --+ rtx_insn *insn; --+ auto_vec temp_set; --+ --+ for (i = 0; i < insn_set->length (); i++) --+ temp_set.safe_push ((*insn_set)[i]); --+ --+ /* Check registers are not used and defined --+ between first instruction and last instruction, --+ and find insert lmw/smw instruction place. --+ example: --+ lwi $r0, [$r2 + 4] --+ lwi $r1, [$r2 + 8] --+ --+ Check $r0 and $r1 are not used and defined. */ --+ temp_set.qsort (compare_order); --+ --+ for (position = 0; position < temp_set.length (); ++position) --+ { --+ combine_p = true; --+ --+ /* Check instruction form first instruction to position. */ --+ for (i = 0; i < position; i++) --+ { --+ for (insn = NEXT_INSN (temp_set[i].insn); --+ insn != temp_set[position].insn; --+ insn = NEXT_INSN (insn)) --+ { --+ if (!NONDEBUG_INSN_P (insn)) --+ continue; --+ if (df_reg_used (insn, temp_set[i].reg) --+ || df_reg_defined (insn, temp_set[i].reg)) --+ { --+ if (dump_file) --+ { --+ fprintf (dump_file, "Fail:register has modify\n"); --+ fprintf (dump_file, "insn uid:%d, reg: r%d,\n", --+ INSN_UID (temp_set[position].insn), --+ REGNO (temp_set[position].reg)); --+ fprintf (dump_file, "Modify instruction:\n"); --+ print_rtl_single (dump_file, insn); --+ } --+ combine_p = false; --+ break; --+ } --+ } --+ } --+ --+ /* Check instruction form position to last instruction. */ --+ for (i = position + 1; i < temp_set.length (); i++) --+ { --+ for (insn = temp_set[position].insn; --+ insn != temp_set[i].insn; --+ insn = NEXT_INSN (insn)) --+ { --+ if (!NONDEBUG_INSN_P (insn)) --+ continue; --+ if (df_reg_used (insn, temp_set[i].reg) --+ || df_reg_defined (insn, temp_set[i].reg)) --+ { --+ if (dump_file) --+ { --+ fprintf (dump_file, "Fail:register has modify\n"); --+ fprintf (dump_file, "insn uid:%d, reg: r%d,\n", --+ INSN_UID (temp_set[position].insn), --+ REGNO (temp_set[position].reg)); --+ fprintf (dump_file, "Modify instruction:\n"); --+ print_rtl_single (dump_file, insn); --+ } --+ combine_p = false; --+ break; --+ } --+ } --+ } --+ --+ if (combine_p) --+ return temp_set[position].insn; --+ } --+ --+ return NULL_RTX; --+} --+ --+/* Check registers are not used and defined. */ --+static bool --+nds32_base_reg_safe_p (load_store_infos_t *insn_set) --+{ --+ unsigned int i; --+ rtx_insn *insn; --+ auto_vec temp_set; --+ --+ /* We will change 'insn_set' element order, --+ to avoid change order using 'temp_set'. */ --+ for (i = 0; i < insn_set->length (); i++) --+ temp_set.safe_push ((*insn_set)[i]); --+ --+ /* We want to combine load and store instructions, --+ need to check base register is not used and defined --+ between first insn and last insn. --+ example: --+ lwi $r0, [$r3 + 4] --+ ... <- check here --+ lwi $r1, [$r3 + 8] --+ ... <- check here --+ lwi $r2, [$r3 + 12] --+ --+ Check $r3 is not used and defined, --+ between first insn and last insn. */ --+ --+ /* Scan instruction from top to bottom, --+ so need to sort by order. */ --+ temp_set.qsort (compare_order); --+ --+ for (i = 0; i < temp_set.length () - 1; ++i) --+ { --+ for (insn = NEXT_INSN (temp_set[i].insn); --+ insn != temp_set[i + 1].insn; --+ insn = NEXT_INSN (insn)) --+ { --+ if (!NONDEBUG_INSN_P (insn)) --+ continue; --+ --+ if (nds32_insn_alias_p (temp_set[0].mem, PATTERN (insn))) --+ { --+ if (dump_file) --+ { --+ fprintf (dump_file, "Memory alias:\n"); --+ print_rtl_single (dump_file, insn); --+ } --+ return false; --+ } --+ --+ if (temp_set[0].load_p) --+ { --+ if (df_reg_defined (insn, temp_set[0].base_reg)) --+ { --+ if (dump_file) --+ { --+ fprintf (dump_file, "Fail: base register has modify\n"); --+ fprintf (dump_file, "insn uid:%d, base reg: r%d,\n", --+ INSN_UID (temp_set[i].insn), --+ REGNO (temp_set[i].reg)); --+ fprintf (dump_file, "Modify instruction:\n"); --+ print_rtl_single (dump_file, insn); --+ } --+ return false; --+ } --+ } --+ else --+ { --+ if (df_reg_used (insn, temp_set[0].base_reg)) --+ { --+ if (dump_file) --+ { --+ fprintf (dump_file, "Fail: base register has modify\n"); --+ fprintf (dump_file, "insn uid:%d, base reg: r%d,\n", --+ INSN_UID (temp_set[i].insn), --+ REGNO (temp_set[i].reg)); --+ fprintf (dump_file, "Modify instruction:\n"); --+ print_rtl_single (dump_file, insn); --+ } --+ return false; --+ } --+ } --+ } --+ } --+ return true; --+} --+ --+static bool --+nds32_gain_size_p (load_store_infos_t *insn, bool new_base_p) --+{ --+ unsigned int i, new_cost = 4, old_cost = 0; --+ rtx reg; --+ rtx base_reg = (*insn)[0].base_reg; --+ HOST_WIDE_INT offset; --+ --+ for (i = 0; i < insn->length (); ++i) --+ { --+ reg = (*insn)[i].reg; --+ offset = (*insn)[i].offset; --+ --+ if (in_reg_class_p (reg, LOW_REGS)) --+ { --+ /* lwi37.sp/swi37.sp/lwi37/swi37 */ --+ if ((REGNO (base_reg) == SP_REGNUM --+ || REGNO (base_reg) == FP_REGNUM) --+ && (offset >= 0 && offset < 512 && (offset % 4 == 0))) --+ old_cost += 2; --+ /* lwi333/swi333 */ --+ else if (in_reg_class_p (base_reg, LOW_REGS) --+ && (offset >= 0 && offset < 32 && (offset % 4 == 0))) --+ old_cost += 2; --+ else --+ old_cost += 4; --+ } --+ else --+ { --+ /* lwi450/swi450 */ --+ if (in_reg_class_p (reg, MIDDLE_REGS) --+ && offset == 0) --+ old_cost += 2; --+ else --+ old_cost += 4; --+ } --+ } --+ --+ offset = (*insn)[0].offset; --+ if (offset != 0) --+ { --+ /* addi333 */ --+ if (in_reg_class_p (base_reg, LOW_REGS) --+ && satisfies_constraint_Iu05 (GEN_INT (offset))) --+ new_cost += 2; --+ /* addi45 */ --+ else if (in_reg_class_p (base_reg, MIDDLE_REGS) --+ && satisfies_constraint_Iu05 (GEN_INT (offset))) --+ new_cost += 2; --+ else --+ new_cost += 4; --+ --+ /* subri */ --+ if (!new_base_p) --+ new_cost += 4; --+ } --+ --+ if (dump_file) --+ fprintf (dump_file, "Code size compare: old code size is %d," --+ " new code size is %d\n", old_cost, new_cost); --+ --+ return new_cost < old_cost; --+} --+ --+static bool --+nds32_gain_speed_p (load_store_infos_t *insn, bool new_base_p) --+{ --+ unsigned int new_cost = 0, old_cost = insn->length (); --+ --+ if (TARGET_PIPELINE_GRAYWOLF) --+ { --+ new_cost = insn->length () / 2 + insn->length () % 2; --+ --+ if ((*insn)[0].offset != 0) --+ { --+ /* Need addi instruction. */ --+ new_cost += 1; --+ --+ /* Need subri instruction. */ --+ if (!new_base_p) --+ new_cost += 1; --+ } --+ } --+ else --+ { --+ if ((*insn)[0].offset != 0) --+ return false; --+ } --+ --+ return new_cost < old_cost; --+} --+ --+/* Check instructions can combine into a mulitple-instruction. */ --+static bool --+nds32_combine_multiple_p (load_store_infos_t *insn_set, bool new_base_p) --+{ --+ unsigned int i; --+ auto_vec temp_set; --+ --+ /* We will change 'insn_set' element order, --+ to avoid change order using 'temp_set'. */ --+ for (i = 0; i < insn_set->length (); i++) --+ temp_set.safe_push ((*insn_set)[i]); --+ --+ /* Check start offset need to sort by offset. */ --+ temp_set.qsort (compare_offset); --+ --+ /* The lmw/smw pattern, need two or more instructions. */ --+ if (temp_set.length () < 2) --+ return false; --+ --+ /* The lmw/smw pattern, only allow combine 25 instruction. */ --+ if (temp_set.length () > 25) --+ return false; --+ --+ if (TARGET_LMWSMW_OPT_SIZE --+ || (TARGET_LMWSMW_OPT_AUTO && optimize_size)) --+ { --+ /* Compare original instructions with multiple instruction, --+ when mupltiple instruction is small than original instructions --+ then combine it. */ --+ if (!nds32_gain_size_p (&temp_set, new_base_p)) --+ return false; --+ } --+ else if (TARGET_LMWSMW_OPT_SPEED --+ || (TARGET_LMWSMW_OPT_AUTO && !optimize_size)) --+ { --+ /* The start offset is not zero, we need add a instrucion --+ to handle offset, it is not worth on -O3, -O2 level. */ --+ if (!nds32_gain_speed_p (&temp_set, new_base_p)) --+ return false; --+ } --+ --+ /* Base register is not equal register, when offset is not zero. */ --+ if (temp_set[0].offset != 0) --+ for (i = 0; i < temp_set.length (); ++i) --+ { --+ if (REGNO (temp_set[i].reg) --+ == REGNO (temp_set[0].base_reg)) --+ return false; --+ } --+ --+ /* Don't combine, when start offset is greater then Is15, --+ because need extra register. */ --+ if (!satisfies_constraint_Is15 (GEN_INT (temp_set[0].offset))) --+ return false; --+ --+ return true; --+} --+ --+static bool --+nds32_use_bim_p (load_store_infos_t *insn_set, --+ load_store_infos_t *ref_set) --+{ --+ rtx_insn *insn; --+ bool combine_p = true; --+ --+ /* Generate .bim form, need offset is continuous. */ --+ if (insn_set->last ().offset != ((*ref_set)[0].offset - 4)) --+ return false; --+ --+ /* Reject 'insn_set' instructions bottom --+ of the 'ref_set' instructions. */ --+ if ((*insn_set)[0].group > (*ref_set)[0].group) --+ return false; --+ --+ /* Scan instruction from top to bottom, --+ so need to sort by order. */ --+ insn_set->qsort (compare_order); --+ ref_set->qsort (compare_order); --+ --+ /* We want to combine .bim form instruction, --+ so need to check base register is not used and defined --+ between multiple-insn and next mulitple-insn. --+ example: --+ lmw.bim $r0, [$r2], $r1 --+ ... <- check here --+ lmw.bi $r3, [$r2], $r4 --+ --+ Use .bim form need to check $r2 is not used and defined, --+ between lmw.bim and lmw.bi. */ --+ for (insn = NEXT_INSN (insn_set->last ().insn); --+ insn != (*ref_set)[0].insn; --+ insn = NEXT_INSN (insn)) --+ { --+ if (!NONDEBUG_INSN_P (insn)) --+ continue; --+ --+ if (nds32_insn_alias_p ((*insn_set)[0].mem, PATTERN (insn))) --+ { --+ if (dump_file) --+ { --+ fprintf (dump_file, "Have memory instruction:\n"); --+ print_rtl_single (dump_file, insn); --+ } --+ combine_p = false; --+ break; --+ } --+ --+ if (df_reg_used (insn, (*insn_set)[0].base_reg) --+ || df_reg_defined (insn, (*insn_set)[0].base_reg)) --+ { --+ if (dump_file) --+ { --+ fprintf (dump_file, "Use .bi form: Base reg is" --+ " used or defined between multiple-insn" --+ " and next multiple-insn\n"); --+ fprintf (dump_file, "Base register: r%d,\n", --+ REGNO ((*insn_set)[0].base_reg)); --+ fprintf (dump_file, "use or def instruction:\n"); --+ print_rtl_single (dump_file, insn); --+ } --+ combine_p = false; --+ break; --+ } --+ } --+ --+ /* Restore element order. */ --+ insn_set->qsort (compare_offset); --+ ref_set->qsort (compare_offset); --+ --+ if (combine_p) --+ return true; --+ else --+ return false; --+} --+ --+static void --+nds32_merge_overlapping_regs (HARD_REG_SET *pset, struct du_head *head) --+{ --+ bitmap_iterator bi; --+ unsigned i; --+ IOR_HARD_REG_SET (*pset, head->hard_conflicts); --+ EXECUTE_IF_SET_IN_BITMAP (&head->conflicts, 0, i, bi) --+ { --+ du_head_p other = regrename_chain_from_id (i); --+ unsigned j = other->nregs; --+ gcc_assert (other != head); --+ while (j-- > 0) --+ SET_HARD_REG_BIT (*pset, other->regno + j); --+ } --+} --+ --+/* Check if NEW_REG can be the candidate register to rename for --+ REG in THIS_HEAD chain. THIS_UNAVAILABLE is a set of unavailable hard --+ registers. */ --+static bool --+nds32_check_new_reg_p (int reg ATTRIBUTE_UNUSED, int new_reg, --+ struct du_head *this_head, HARD_REG_SET this_unavailable) --+{ --+ enum machine_mode mode = GET_MODE (*this_head->first->loc); --+ int nregs = hard_regno_nregs[new_reg][mode]; --+ int i; --+ struct du_chain *tmp; --+ --+ for (i = nregs - 1; i >= 0; --i) --+ if (TEST_HARD_REG_BIT (this_unavailable, new_reg + i) --+ || fixed_regs[new_reg + i] --+ || global_regs[new_reg + i] --+ /* Can't use regs which aren't saved by the prologue. */ --+ || (! df_regs_ever_live_p (new_reg + i) --+ && ! call_used_regs[new_reg + i]) --+#ifdef LEAF_REGISTERS --+ /* We can't use a non-leaf register if we're in a --+ leaf function. */ --+ || (crtl->is_leaf --+ && !LEAF_REGISTERS[new_reg + i]) --+#endif --+#ifdef HARD_REGNO_RENAME_OK --+ || ! HARD_REGNO_RENAME_OK (reg + i, new_reg + i) --+#endif --+ ) --+ return false; --+ --+ /* See whether it accepts all modes that occur in --+ definition and uses. */ --+ for (tmp = this_head->first; tmp; tmp = tmp->next_use) --+ if ((! HARD_REGNO_MODE_OK (new_reg, GET_MODE (*tmp->loc)) --+ && ! DEBUG_INSN_P (tmp->insn)) --+ || (this_head->need_caller_save_reg --+ && ! (HARD_REGNO_CALL_PART_CLOBBERED --+ (reg, GET_MODE (*tmp->loc))) --+ && (HARD_REGNO_CALL_PART_CLOBBERED --+ (new_reg, GET_MODE (*tmp->loc))))) --+ return false; --+ --+ return true; --+} --+ --+static int --+nds32_find_best_rename_reg (du_head_p this_head, int new_reg, int old_reg) --+{ --+ HARD_REG_SET unavailable; --+ int best_new_reg = old_reg; --+ --+ COMPL_HARD_REG_SET (unavailable, reg_class_contents[GENERAL_REGS]); --+ CLEAR_HARD_REG_BIT (unavailable, this_head->regno); --+ --+ /* Further narrow the set of registers we can use for renaming. --+ If the chain needs a call-saved register, mark the call-used --+ registers as unavailable. */ --+ if (this_head->need_caller_save_reg) --+ IOR_HARD_REG_SET (unavailable, call_used_reg_set); --+ --+ /* Mark registers that overlap this chain's lifetime as unavailable. */ --+ nds32_merge_overlapping_regs (&unavailable, this_head); --+ --+ if (nds32_check_new_reg_p (old_reg, new_reg, this_head, unavailable)) --+ best_new_reg = new_reg; --+ --+ return best_new_reg; --+} --+ --+static bool --+nds32_try_rename_reg (rtx_insn *insn, unsigned op_pos, unsigned best_reg) --+{ --+ insn_rr_info *info; --+ du_head_p op_chain; --+ unsigned oldreg, newreg; --+ --+ info = &insn_rr[INSN_UID (insn)]; --+ --+ if (info->op_info == NULL) --+ return false; --+ --+ if (info->op_info[op_pos].n_chains == 0) --+ return false; --+ --+ op_chain = regrename_chain_from_id (info->op_info[op_pos].heads[0]->id); --+ --+ if (op_chain->cannot_rename) --+ return false; --+ --+ oldreg = op_chain->regno; --+ newreg = nds32_find_best_rename_reg (op_chain, best_reg, oldreg); --+ --+ if (newreg == oldreg) --+ return false; --+ --+ return true; --+} --+ --+/* Grouping consecutive registers. */ --+static void --+nds32_group_available_reg (HARD_REG_SET *available_regset, enum reg_class clazz, --+ std::vector *available_group) --+{ --+ hard_reg_set_iterator hrsi; --+ unsigned regno, pre_regno = 0; --+ unsigned count = 0; --+ available_reg_info_t reg_info; --+ std::vector::iterator it; --+ --+ if (!available_group->empty ()) --+ available_group->clear (); --+ --+ /* Find available register form $r16 to $r31. */ --+ EXECUTE_IF_SET_IN_HARD_REG_SET (reg_class_contents[clazz], 2, regno, hrsi) --+ { --+ /* Caller-save register or callee-save register but it's ever live. */ --+ if (TEST_HARD_REG_BIT (*available_regset, regno) --+ && (call_used_regs[regno] || df_regs_ever_live_p (regno))) --+ { --+ if (pre_regno == 0 --+ || (pre_regno + 1) == regno) --+ count++; --+ } --+ else --+ { --+ if (count >= 2) --+ { --+ reg_info.amount = count; --+ reg_info.end = pre_regno; --+ reg_info.start = pre_regno - count + 1; --+ available_group->push_back (reg_info); --+ } --+ count = 0; --+ } --+ pre_regno = regno; --+ } --+ --+ sort (available_group->begin(), available_group->end(), compare_amount); --+ --+ if (dump_file) --+ { --+ for (it = available_group->begin(); --+ it != available_group->end(); ++it) --+ fprintf (dump_file, --+ "available amount = %d start = %d " --+ "end = %d \n", it->amount, it->start, --+ it->end); --+ } --+} --+ --+/* Try to rename insn's register in order. */ --+static void --+nds32_find_reg (load_store_infos_t *insn, load_store_infos_t *rename_insn, --+ HARD_REG_SET *available_regset) --+{ --+ int can_rename_number; --+ unsigned i, regno, amount; --+ unsigned op_pos = (*insn)[0].load_p ? 0 : 1; --+ auto_vec temp_set; --+ std::vector available_group; --+ std::vector::iterator it; --+ auto_vec down_set, up_set; --+ unsigned int down_num = 0, up_num = 0; --+ long offset; --+ int m; --+ --+ /* We will change 'insn' element order, --+ to avoid change order using 'temp_set'. */ --+ for (i = 0; i < insn->length (); i++) --+ temp_set.safe_push ((*insn)[i]); --+ --+ if (temp_set[0].post_type == NDS32_NONE) --+ temp_set.qsort (compare_offset); --+ --+ nds32_group_available_reg (available_regset, GENERAL_REGS, &available_group); --+ --+ /* Check rename register form top insn to bottom insn, --+ and avoid using fp, sp, lp, gp registers. */ --+ regno = REGNO (temp_set[0].reg); --+ can_rename_number = regno + temp_set.length () - 1; --+ offset = temp_set[0].offset; --+ --+ if (can_rename_number < FP_REGNUM) --+ for (i = 1; i < temp_set.length (); ++i) --+ { --+ /* Find this case: --+ lwi $r0, [$r2 + 4] --+ lwi $r3, [$r2 + 8] --+ --+ Rename $r3 to $r1. */ --+ down_num++; --+ if ((regno + i) != REGNO (temp_set[i].reg)) --+ { --+ if (nds32_try_rename_reg (temp_set[i].insn, op_pos, regno + i)) --+ { --+ /* Store in temparary set. */ --+ down_set.safe_push (temp_set[i]); --+ down_set.last ().new_reg = regno + i; --+ } --+ else --+ /* Stop when the register sequence is broken. */ --+ break; --+ } --+ } --+ --+ /* Check rename register form bottom insn to top insn, --+ and avoid using fp, sp, lp, gp registers. */ --+ regno = REGNO (temp_set.last ().reg); --+ can_rename_number = regno - temp_set.length () + 1; --+ --+ if (can_rename_number > 0 && regno < FP_REGNUM) --+ for (i = temp_set.length () - 1; i > 0; --i) --+ { --+ /* Find this case: --+ lwi $r1, [$r2 + 4] --+ lwi $r4, [$r2 + 8] --+ --+ Rename $r1 to $r3. */ --+ up_num++; --+ if ((regno - i) != REGNO (temp_set[i - 1].reg)) --+ { --+ if (nds32_try_rename_reg (temp_set[i - 1].insn, op_pos, regno - i)) --+ { --+ /* Store in rename_insn. */ --+ up_set.safe_push (temp_set[i - 1]); --+ up_set.last ().new_reg = regno - i; --+ } --+ else --+ /* Stop when the register sequence is broken. */ --+ break; --+ } --+ } --+ --+ /* Rename for the longest sequence. */ --+ /* The overhead of zero offset instruction is lowest, so try it first. */ --+ if ((offset == 0 || down_num >= up_num) && !down_set.is_empty ()) --+ { --+ for (m = down_set.length () - 1; m >= 0; --m) --+ { --+ regno = REGNO (down_set[m].reg); --+ CLEAR_HARD_REG_BIT (*available_regset, regno); --+ rename_insn->safe_push (down_set[m]); --+ } --+ nds32_group_available_reg (available_regset, GENERAL_REGS, --+ &available_group); --+ return; --+ } --+ else if (up_num >= down_num && !up_set.is_empty ()) --+ { --+ for (m = up_set.length () - 1; m >= 0; --m) --+ { --+ regno = REGNO (up_set[m].reg); --+ CLEAR_HARD_REG_BIT (*available_regset, regno); --+ rename_insn->safe_push (up_set[m]); --+ } --+ nds32_group_available_reg (available_regset, GENERAL_REGS, --+ &available_group); --+ return; --+ } --+ /* Check whether it is empty, We will use available table. */ --+ else if (available_group.empty ()) --+ return; --+ --+ amount = available_group.begin ()->amount; --+ /* Using the minimum number, as the rename amount. */ --+ if (amount > temp_set.length ()) --+ amount = temp_set.length (); --+ --+ /* Using most available register number to rename. */ --+ regno = available_group.begin ()->start; --+ for (i = 0; i < amount; ++i) --+ { --+ if (nds32_try_rename_reg (temp_set[i].insn, op_pos, regno)) --+ { --+ rename_insn->safe_push (temp_set[i]); --+ rename_insn->last ().new_reg = regno; --+ CLEAR_HARD_REG_BIT (*available_regset, regno); --+ regno++; --+ } --+ else --+ /* Stop when the register sequence is broken. */ --+ break; --+ } --+ --+ /* Check length here because the whole sequence entries --+ have to be renamed. */ --+ if (rename_insn->length () > 1) --+ { --+ /* Update available table. */ --+ nds32_group_available_reg (available_regset, GENERAL_REGS, --+ &available_group); --+ return; --+ } --+ --+ /* Using all available register to rename each insn. */ --+ for (i = 0; i < (temp_set.length () - 1); i += 2) --+ { --+ for (it = available_group.begin(); --+ it != available_group.end(); ++it) --+ { --+ bool change_p = false; --+ unsigned int j; --+ regno = it->start; --+ --+ /* Once replaced two instructions. */ --+ for (j = regno; j < (it->end + 1); j += 2) --+ { --+ if (nds32_try_rename_reg (temp_set[i].insn, op_pos, regno) --+ && nds32_try_rename_reg (temp_set[i + 1].insn, --+ op_pos, regno + 1)) --+ { --+ rename_insn->safe_push (temp_set[i]); --+ rename_insn->last ().new_reg = regno; --+ CLEAR_HARD_REG_BIT (*available_regset, regno); --+ --+ rename_insn->safe_push (temp_set[i + 1]); --+ rename_insn->last ().new_reg = regno + 1; --+ CLEAR_HARD_REG_BIT (*available_regset, regno + 1); --+ change_p = true; --+ break; --+ } --+ } --+ --+ if (change_p) --+ { --+ nds32_group_available_reg (available_regset, GENERAL_REGS, --+ &available_group); --+ break; --+ } --+ } --+ } --+} --+ --+static void --+nds32_rename_reg (rtx_insn *insn, unsigned op_pos, unsigned newreg) --+{ --+ insn_rr_info *info; --+ du_head_p op_chain; --+ --+ info = &insn_rr[INSN_UID (insn)]; --+ op_chain = regrename_chain_from_id (info->op_info[op_pos].heads[0]->id); --+ --+ if (dump_file) --+ { --+ fprintf (dump_file, "Try to rename operand %d to %d:\n", --+ op_pos, newreg); --+ print_rtl_single (dump_file, insn); --+ } --+ --+ regrename_do_replace (op_chain, newreg); --+ --+ if (dump_file) --+ { --+ print_rtl_single (dump_file, insn); --+ } --+} --+ --+/* Combine mutilple load/store insn into a lmw/smw insn. */ --+static void --+nds32_combine_bi_insn (load_store_infos_t *load_store_info) --+{ --+ auto_vec candidate_set, bi_set; --+ unsigned int i, j, regno; --+ --+ bool load_insn_p; --+ enum nds32_memory_post_type post_type; --+ --+ for (i = 0; i < load_store_info->length (); ++i) --+ { --+ /* Recording instruction order of priority and initinal place. */ --+ (*load_store_info)[i].order = i; --+ (*load_store_info)[i].place = false; --+ candidate_set.safe_push ((*load_store_info)[i]); --+ } --+ --+ for (i = 0; i < candidate_set.length (); ++i) --+ { --+ load_insn_p = candidate_set[i].load_p; --+ post_type = candidate_set[i].post_type; --+ regno = REGNO (candidate_set[i].reg); --+ --+ for (j = i + 1; j < candidate_set.length (); ++j) --+ { --+ if ((post_type == candidate_set[j].post_type) --+ && (load_insn_p == candidate_set[j].load_p) --+ && ((regno + 1) == REGNO (candidate_set[j].reg))) --+ { --+ bi_set.safe_push (candidate_set[i]); --+ bi_set.safe_push (candidate_set[j]); --+ --+ if (nds32_combine_multiple_p (&bi_set, false) --+ && nds32_base_reg_safe_p (&bi_set) --+ && nds32_lmwsmw_insert_place (&bi_set) != NULL_RTX) --+ { --+ rtx place = nds32_lmwsmw_insert_place (&bi_set); --+ rtx base_reg = bi_set[0].base_reg; --+ --+ nds32_emit_multiple_insn (&bi_set, base_reg, place, true); --+ delete_insn (bi_set[i].insn); --+ delete_insn (bi_set[j].insn); --+ candidate_set.ordered_remove (j); --+ bi_set.block_remove (0, bi_set.length ()); --+ break; --+ } --+ --+ bi_set.block_remove (0, bi_set.length ()); --+ } --+ } --+ } --+} --+ --+/* Combine mutilple load/store insn into a lmw/smw insn. */ --+static void --+nds32_combine_load_store_insn (load_store_infos_t *load_store_info, --+ HARD_REG_SET *available_regset) --+{ --+ auto_vec candidate_set, main_set, temp_set; --+ auto_vec first_set, second_set; --+ HOST_WIDE_INT current_offset, last_offset = 0, add_offset = 0; --+ unsigned int i, j, regno; --+ int group_num = 0, group_id; --+ bool load_insn_p; --+ bool new_base_p = false; --+ bool prev_bim_p = false; --+ bool inc_p = true, dec_p = true; --+ rtx new_base_reg = NULL_RTX; --+ rtx base_reg = (*load_store_info)[0].base_reg; --+ rtx place; --+ unsigned new_base_regnum; --+ --+ /* Get available register to add offset for first instruction. */ --+ new_base_regnum = find_available_reg (available_regset, GENERAL_REGS); --+ if (new_base_regnum != INVALID_REGNUM) --+ { --+ CLEAR_HARD_REG_BIT (*available_regset, new_base_regnum); --+ new_base_reg = gen_rtx_REG (Pmode, new_base_regnum); --+ /* Copy attribute form base register to new base register. */ --+ ORIGINAL_REGNO (new_base_reg) = --+ ORIGINAL_REGNO ((*load_store_info)[0].base_reg); --+ REG_ATTRS (new_base_reg) = REG_ATTRS ((*load_store_info)[0].base_reg); --+ new_base_p = true; --+ --+ if (dump_file) --+ fprintf (dump_file, "Have new base register: %d\n", new_base_regnum); --+ } --+ --+ /* Recording instruction order of priority and initinal place. */ --+ for (i = 0; i < load_store_info->length (); ++i) --+ { --+ (*load_store_info)[i].order = i; --+ (*load_store_info)[i].place = false; --+ } --+ --+ /* Fetch first instruction information from 'load_store_info', --+ we will use first instruction as base, to search next instruction. */ --+ candidate_set.safe_push ((*load_store_info)[0]); --+ /* Set offset, regno, load_p state from candidate_set. */ --+ current_offset = candidate_set[0].offset; --+ regno = REGNO (candidate_set[0].reg); --+ load_insn_p = candidate_set[0].load_p; --+ /* Set first instruction group ID, --+ the group ID mark instruction for the same group. */ --+ candidate_set[0].group = group_num; --+ --+ /* Search instructions can be combined to a lmw/smw instruction. */ --+ for (i = 1; i < load_store_info->length (); ++i) --+ { --+ /* Collecting register number and offset is increase, --+ for example: --+ --+ lwi $r0, [$r22 + 4] <- base instruction --+ lwi $r1, [$r22 + 8] <- collect object --+ --+ The collect object (regno + 1), (offset + 4) --+ from base instruction. */ --+ if ((current_offset == (*load_store_info)[i].offset - 4) --+ && ((regno + 1) == REGNO ((*load_store_info)[i].reg)) --+ && (load_insn_p == (*load_store_info)[i].load_p) --+ && inc_p) --+ { --+ /* Give instruction group ID. */ --+ (*load_store_info)[i].group = group_num; --+ /* Save instruction. */ --+ candidate_set.safe_push ((*load_store_info)[i]); --+ /* Update state, next register number and offset. */ --+ regno = REGNO ((*load_store_info)[i].reg); --+ current_offset += 4; --+ /* Close decrease type, search increase type. */ --+ dec_p = false; --+ } --+ /* Collecting register number and offset is decrease, --+ for example: --+ --+ lwi $r2, [$r22 + 8] <- base instruction --+ lwi $r1, [$r22 + 4] <- collect object --+ --+ The collect object (regno - 1), (offset - 4) --+ from base instruction. */ --+ else if ((current_offset == (*load_store_info)[i].offset + 4) --+ && ((regno - 1) == REGNO ((*load_store_info)[i].reg)) --+ && (load_insn_p == (*load_store_info)[i].load_p) --+ && dec_p) --+ { --+ /* Give instruction group ID. */ --+ (*load_store_info)[i].group = group_num; --+ /* Save instruction. */ --+ candidate_set.safe_push ((*load_store_info)[i]); --+ --+ /* Update state, next register number and offset. */ --+ regno = REGNO ((*load_store_info)[i].reg); --+ current_offset -= 4; --+ /* Close increase type, search decrease type. */ --+ inc_p = false; --+ } --+ else --+ { --+ inc_p = true; --+ dec_p = true; --+ } --+ --+ /* Instructions collect is complete. */ --+ if ((inc_p && dec_p) --+ || (i + 1) == load_store_info->length ()) --+ { --+ /* Filter candidate instructions. */ --+ if (nds32_combine_multiple_p (&candidate_set, new_base_p) --+ && nds32_base_reg_safe_p (&candidate_set) --+ && nds32_lmwsmw_insert_place (&candidate_set) != NULL_RTX) --+ { --+ /* Store candidate instructions to 'main_set'. */ --+ for (j = 0; j < candidate_set.length (); j++) --+ main_set.safe_push (candidate_set[j]); --+ } --+ --+ /* Scan to the last instruction, it is complete. */ --+ if ((i + 1) == load_store_info->length ()) --+ break; --+ --+ /* Clean candidate_set sequence. */ --+ candidate_set.block_remove (0, candidate_set.length ()); --+ /* Reinitialize first instruction infomation --+ to search next instruction. */ --+ candidate_set.safe_push ((*load_store_info)[i]); --+ /* Update group number for next sequence. */ --+ group_num ++; --+ /* Set offset, regno, load_p state from candidate_set. */ --+ current_offset = candidate_set.last ().offset; --+ regno = REGNO (candidate_set.last ().reg); --+ load_insn_p = candidate_set.last ().load_p; --+ candidate_set.last ().group = group_num; --+ } --+ else if (!nds32_base_reg_safe_p (&candidate_set) --+ || nds32_lmwsmw_insert_place (&candidate_set) == NULL_RTX) --+ { --+ /* Check collect instruction for each instruction, --+ we store (n - 1) instructions in group, and --+ last instruction make next group First instruction. */ --+ for (j = 0; j < (candidate_set.length () - 1); j++) --+ temp_set.safe_push (candidate_set[j]); --+ --+ /* Store candidate instructions to 'main_set'. */ --+ if (nds32_combine_multiple_p (&temp_set, new_base_p)) --+ { --+ for (j = 0; j < (temp_set.length ()); j++) --+ main_set.safe_push (temp_set[j]); --+ } --+ --+ /* Clean temp_set sequence. */ --+ temp_set.block_remove (0, temp_set.length ()); --+ /* Clean candidate_set sequence. */ --+ candidate_set.block_remove (0, (candidate_set.length () - 1)); --+ /* Update group number for next sequence. */ --+ group_num ++; --+ /* Set offset, regno, load_p state from candidate_set. */ --+ current_offset = candidate_set.last ().offset; --+ regno = REGNO (candidate_set.last ().reg); --+ load_insn_p = candidate_set.last ().load_p; --+ candidate_set.last ().group = group_num; --+ /* Reset it for search increase and decrease type. */ --+ inc_p = true; --+ dec_p = true; --+ } --+ } --+ --+ if (dump_file) --+ { --+ if (!main_set.is_empty ()) --+ fprintf (dump_file,"Do lmwsmw instructions:\n"); --+ for (i = 0; i < main_set.length (); ++i) --+ { --+ fprintf (dump_file, --+ "regno = %d base_regno = %d " --+ "offset = " HOST_WIDE_INT_PRINT_DEC " " --+ "load_p = %d UID = %u group = %d," --+ " order = %d, place = %d\n", --+ REGNO (main_set[i].reg), --+ REGNO (main_set[i].base_reg), --+ main_set[i].offset, --+ main_set[i].load_p, --+ INSN_UID (main_set[i].insn), --+ main_set[i].group, --+ main_set[i].order, --+ main_set[i].place); --+ } --+ } --+ --+ /* Fetch first group instruction from main_set. */ --+ if (!main_set.is_empty ()) --+ { --+ /* Sort main_set by offset. */ --+ main_set.qsort (compare_offset); --+ --+ group_id = main_set[0].group; --+ nds32_fetch_group_insn (&main_set, &first_set, group_id); --+ last_offset = first_set.last ().offset; --+ } --+ --+ /* Main loop for emit lmw/smw instrucion. */ --+ while (!main_set.is_empty ()) --+ { --+ /* Get second group ID. */ --+ group_id = main_set[0].group; --+ for (i = 0; i < main_set.length (); ++i) --+ { --+ /* Prefer get consecutive offset form --+ first group to second group */ --+ if ((last_offset + 4) == main_set[i].offset) --+ { --+ group_id = main_set[i].group; --+ break; --+ } --+ } --+ --+ /* Fetch second instrucion group. */ --+ nds32_fetch_group_insn (&main_set, &second_set, group_id); --+ /* Get lmw/smw insert place. */ --+ place = nds32_lmwsmw_insert_place (&first_set); --+ --+ /* Adjust address offset, because lmw/smw instruction --+ only allow offset is zero. --+ example: --+ lwi $r0, [$r3 + 4] --+ lwi $r1, [$r3 + 8] --+ lwi $r2, [$r3 + 12] --+ --+ combine into --+ --+ addi $r3, $r3, 4 --+ lwm.bi(m) $r0, [$r3], $r2 --+ --+ Need addi instrucion to handle offset. */ --+ if (first_set[0].offset != 0 && !prev_bim_p) --+ { --+ if (dump_file) --+ fprintf (dump_file, "Use addi insn handle offset: " --+ "" HOST_WIDE_INT_PRINT_DEC "\n", --+ first_set[0].offset); --+ /* Use available register to process offset, --+ and don't recovey base register value. */ --+ if (new_base_p) --+ { --+ base_reg = new_base_reg; --+ add_offset = 0; --+ CLEAR_HARD_REG_BIT (*available_regset, new_base_regnum); --+ } --+ else --+ add_offset = first_set[0].offset; --+ --+ nds32_emit_add_insn (first_set[0], base_reg, place, true); --+ } --+ --+ if (nds32_use_bim_p (&first_set, &second_set)) --+ { --+ if (dump_file) --+ fprintf (dump_file, "Generate BIM form.\n"); --+ --+ nds32_emit_multiple_insn (&first_set, base_reg, place, true); --+ --+ /* Update status, for next instruction sequence. --+ The add_offset need add 4, because the instruction --+ is post increase. */ --+ add_offset = first_set.last ().offset + 4; --+ prev_bim_p = true; --+ } --+ else --+ { --+ if (dump_file) --+ fprintf (dump_file, "Generate BI form.\n"); --+ --+ nds32_emit_multiple_insn (&first_set, base_reg, place, false); --+ --+ if (add_offset != 0) --+ { --+ if (dump_file) --+ fprintf (dump_file, "Use addi insn handle -offset: " --+ "" HOST_WIDE_INT_PRINT_DEC "\n", --+ add_offset); --+ --+ nds32_emit_add_insn (first_set[0], base_reg, place, false); --+ add_offset = 0; --+ } --+ prev_bim_p = false; --+ --+ /* Recovey base register for next instruction sequence. */ --+ if (REGNO (base_reg) != REGNO (first_set[0].base_reg)) --+ base_reg = first_set[0].base_reg; --+ } --+ --+ /* Delete insn, replace by lmw/smw instruction. */ --+ for (i = 0; i < first_set.length (); ++i) --+ delete_insn (first_set[i].insn); --+ --+ /* Clean first_set for store next instruction group. */ --+ first_set.block_remove (0, first_set.length ()); --+ /* Store next instruction group. */ --+ for (i = 0; i < second_set.length (); ++i) --+ first_set.safe_insert (i, second_set[i]); --+ --+ /* Clean second_set. */ --+ second_set.block_remove (0, second_set.length ()); --+ --+ /* Update last_offset for search next group. */ --+ last_offset = first_set.last ().offset; --+ } --+ --+ /* Processing the last instruction group. */ --+ if (!first_set.is_empty ()) --+ { --+ /* Get lmw/smw insert place. */ --+ place = nds32_lmwsmw_insert_place (&first_set); --+ --+ if (first_set[0].offset != 0 && !prev_bim_p) --+ { --+ if (dump_file) --+ fprintf (dump_file, "Use addi insn handle offset: " --+ "" HOST_WIDE_INT_PRINT_DEC "\n", --+ first_set[0].offset); --+ --+ if (new_base_p) --+ { --+ base_reg = new_base_reg; --+ add_offset = 0; --+ } --+ else --+ add_offset = first_set[0].offset; --+ --+ nds32_emit_add_insn (first_set[0], base_reg, place, true); --+ } --+ --+ if (dump_file) --+ fprintf (dump_file, "Generate BI form.\n"); --+ --+ nds32_emit_multiple_insn (&first_set, base_reg, place, false); --+ --+ if (add_offset != 0) --+ { --+ if (dump_file) --+ fprintf (dump_file, "Use addi insn handle -offset: " --+ "" HOST_WIDE_INT_PRINT_DEC "\n", --+ -add_offset); --+ --+ nds32_emit_add_insn (first_set[0], base_reg, place, false); --+ } --+ --+ /* Delete insn, replace by lmw/smw instruction. */ --+ for (i = 0; i < first_set.length (); ++i) --+ delete_insn (first_set[i].insn); --+ } --+} --+ --+/* Combine mutilple load/store insn into a lmw/smw insn. */ --+static void --+nds32_rename_bi_insn (load_store_infos_t *load_store_info, --+ HARD_REG_SET *available_regset) --+{ --+ auto_vec candidate_set, bi_set, replace_set; --+ unsigned int i, j; --+ --+ bool load_insn_p; --+ enum nds32_memory_post_type post_type; --+ --+ for (i = 0; i < load_store_info->length (); ++i) --+ { --+ /* Recording instruction order of priority and initinal place. */ --+ (*load_store_info)[i].order = i; --+ (*load_store_info)[i].place = false; --+ candidate_set.safe_push ((*load_store_info)[i]); --+ } --+ --+ for (i = 0; i < candidate_set.length (); ++i) --+ { --+ load_insn_p = candidate_set[i].load_p; --+ post_type = candidate_set[i].post_type; --+ --+ for (j = i + 1; j < candidate_set.length (); ++j) --+ { --+ if ((post_type == candidate_set[j].post_type) --+ && (load_insn_p == candidate_set[j].load_p)) --+ { --+ bi_set.safe_push (candidate_set[i]); --+ bi_set.safe_push (candidate_set[j]); --+ --+ if (nds32_combine_multiple_p (&bi_set, false) --+ && nds32_base_reg_safe_p (&bi_set) --+ && nds32_lmwsmw_insert_place (&bi_set) != NULL_RTX) --+ { --+ nds32_find_reg (&bi_set, &replace_set, available_regset); --+ --+ if (!replace_set.is_empty ()) --+ { --+ unsigned k; --+ unsigned op_pos = replace_set[0].load_p ? 0 : 1; --+ --+ /* Do rename register. */ --+ for (k = 0; k < replace_set.length (); ++k) --+ nds32_rename_reg (replace_set[k].insn, op_pos, --+ replace_set[k].new_reg); --+ --+ replace_set.block_remove (0, replace_set.length ()); --+ } --+ --+ candidate_set.ordered_remove (j); --+ bi_set.block_remove (0, bi_set.length ()); --+ break; --+ } --+ --+ bi_set.block_remove (0, bi_set.length ()); --+ } --+ } --+ } --+} --+ --+/* Rename register, can be combined mutilple load/store insn. */ --+static void --+nds32_rename_load_store_reg (load_store_infos_t *load_store_info, --+ HARD_REG_SET *available_regset) --+{ --+ auto_vec rename_set, temp_set, replace_set; --+ HOST_WIDE_INT current_offset; --+ unsigned int i, j; --+ bool load_insn_p; --+ bool inc_p = true, dec_p = true; --+ --+ /* Recording instruction order of priority and initinal place. */ --+ for (i = 0; i < load_store_info->length (); ++i) --+ { --+ (*load_store_info)[i].order = i; --+ (*load_store_info)[i].place = false; --+ } --+ --+ /* Fetch first instruction information from 'load_store_info', --+ we will use first instruction as base, to search next instruction. */ --+ rename_set.safe_push ((*load_store_info)[0]); --+ /* Set offset, load_p state from rename_set. */ --+ current_offset = rename_set[0].offset; --+ load_insn_p = rename_set[0].load_p; --+ --+ /* Search instructions can be combined to a lmw/smw instruction. */ --+ for (i = 1; i < load_store_info->length (); ++i) --+ { --+ /* Collecting offset is increase, for example: --+ --+ lwi pseudo_reg, [$r22 + 4] <- base instruction --+ lwi pseudo_reg, [$r22 + 8] <- collect object --+ --+ The collect object (offset + 4) from base instruction. */ --+ if ((current_offset == (*load_store_info)[i].offset - 4) --+ && (load_insn_p == (*load_store_info)[i].load_p) --+ && inc_p) --+ { --+ /* Save instruction. */ --+ rename_set.safe_push ((*load_store_info)[i]); --+ /* Update offset. */ --+ current_offset += 4; --+ /* Close decrease type, search increase type. */ --+ dec_p = false; --+ } --+ /* Collecting offset is decrease, for example: --+ --+ lwi pseudo_reg, [$r22 + 8] <- base instruction --+ lwi pseudo_reg, [$r22 + 4] <- collect object --+ --+ The collect object (offset - 4) from base instruction. */ --+ else if ((current_offset == (*load_store_info)[i].offset + 4) --+ && (load_insn_p == (*load_store_info)[i].load_p) --+ && dec_p) --+ { --+ /* Save instruction. */ --+ rename_set.safe_push ((*load_store_info)[i]); --+ --+ /* Update offset. */ --+ current_offset -= 4; --+ /* Close increase type, search decrease type. */ --+ inc_p = false; --+ } --+ else --+ { --+ inc_p = true; --+ dec_p = true; --+ } --+ --+ /* Instructions collect is completed. */ --+ if ((inc_p && dec_p) --+ || (i + 1) == load_store_info->length ()) --+ { --+ /* Check whether the rename register. */ --+ if (nds32_combine_multiple_p (&rename_set, false) --+ && nds32_base_reg_safe_p (&rename_set) --+ && nds32_lmwsmw_insert_place (&rename_set) != NULL_RTX) --+ { --+ /* Find can rename instruction, and store in 'replace_set'. */ --+ nds32_find_reg (&rename_set, &replace_set, available_regset); --+ --+ if (!replace_set.is_empty ()) --+ { --+ unsigned op_pos = replace_set[0].load_p ? 0 : 1; --+ --+ /* Do rename register. */ --+ for (j = 0; j < replace_set.length (); ++j) --+ nds32_rename_reg (replace_set[j].insn, op_pos, --+ replace_set[j].new_reg); --+ --+ replace_set.block_remove (0, replace_set.length ()); --+ } --+ } --+ --+ /* Scan to the last instruction, it is complete. */ --+ if ((i + 1) == load_store_info->length ()) --+ break; --+ --+ /* Clean rename_set sequence. */ --+ rename_set.block_remove (0, rename_set.length ()); --+ /* Reinitialize first instruction infomation --+ to search next instruction. */ --+ rename_set.safe_push ((*load_store_info)[i]); --+ /* Set offset, load_p state from rename_set. */ --+ current_offset = rename_set.last ().offset; --+ load_insn_p = rename_set.last ().load_p; --+ } --+ else if (!nds32_base_reg_safe_p (&rename_set) --+ || nds32_lmwsmw_insert_place (&rename_set) == NULL_RTX) --+ { --+ /* Check collect instruction for each instruction, --+ we store (n - 1) instructions in group, and --+ last instruction as the first instruction of the next group. */ --+ for (j = 0; j < (rename_set.length () - 1); j++) --+ temp_set.safe_push (rename_set[j]); --+ --+ if (nds32_combine_multiple_p (&temp_set, false)) --+ { --+ /* Find can rename instruction, and store in 'replace_set'. */ --+ nds32_find_reg (&temp_set, &replace_set, available_regset); --+ --+ if (!replace_set.is_empty ()) --+ { --+ unsigned op_pos = replace_set[0].load_p ? 0 : 1; --+ --+ /* Do rename register. */ --+ for (j = 0; j < replace_set.length (); ++j) --+ nds32_rename_reg (replace_set[j].insn, op_pos, --+ replace_set[j].new_reg); --+ --+ replace_set.block_remove (0, replace_set.length ()); --+ } --+ } --+ --+ /* Clean temp_set sequence. */ --+ temp_set.block_remove (0, temp_set.length ()); --+ /* Clean rename_set sequence. */ --+ rename_set.block_remove (0, (rename_set.length () - 1)); --+ /* Set offset, regno, load_p state from rename_set. */ --+ current_offset = rename_set.last ().offset; --+ load_insn_p = rename_set.last ().load_p; --+ /* Reset it for search increase and decrease type. */ --+ inc_p = true; --+ dec_p = true; --+ } --+ } --+} --+ --+static void --+nds32_do_lmwsmw_opt (basic_block bb, bool rename_p) --+{ --+ rtx_insn *insn; --+ HARD_REG_SET available_regset; --+ load_store_info_t load_store_info; --+ auto_vec load_store_infos[NDS32_GPR_NUM]; --+ auto_vec plus_infos[NDS32_GPR_NUM]; --+ auto_vec post_infos[NDS32_GPR_NUM]; --+ int i; --+ unsigned j; --+ unsigned regno; --+ unsigned polluting; --+ df_ref def; --+ /* Dirty mean a register is define again after --+ first load/store instruction. --+ For example: --+ --+ lwi $r2, [$r3 + #0x100] --+ mov $r3, $r4 ! $r3 is dirty after this instruction. --+ lwi $r1, [$r3 + #0x120] ! so this load can't chain with prev load. --+ */ --+ bool dirty[NDS32_GPR_NUM]; --+ --+ if (dump_file) --+ fprintf (dump_file, "scan bb %d\n", bb->index); --+ --+ for (i = 0; i < NDS32_GPR_NUM; ++i) --+ dirty[i] = false; --+ --+ FOR_BB_INSNS (bb, insn) --+ { --+ if (!INSN_P (insn)) --+ continue; --+ --+ polluting = INVALID_REGNUM; --+ --+ /* Set def reg is dirty if chain is not empty. */ --+ FOR_EACH_INSN_USE (def, insn) --+ { --+ regno = DF_REF_REGNO (def); --+ --+ if (!NDS32_IS_GPR_REGNUM (regno)) --+ continue; --+ --+ if (!load_store_infos[regno].is_empty ()) --+ { --+ /* Set pulluting here because the source register --+ may be the same one. */ --+ if (dirty[regno] == false) --+ polluting = regno; --+ --+ dirty[regno] = true; --+ } --+ } --+ --+ /* Set all caller-save register is dirty if chain is not empty. */ --+ if (CALL_P (insn)) --+ { --+ for (i = 0; i < NDS32_GPR_NUM; ++i) --+ { --+ if (call_used_regs[i] && !load_store_infos[i].is_empty ()) --+ dirty[i] = true; --+ } --+ } --+ --+ if (nds32_load_store_reg_plus_offset (insn, &load_store_info)) --+ { --+ regno = REGNO (load_store_info.base_reg); --+ gcc_assert (NDS32_IS_GPR_REGNUM (regno)); --+ --+ /* Don't add to chain if this reg is dirty. */ --+ if (dirty[regno] && polluting != regno) --+ break; --+ --+ /* If the register is first time to be used and be polluted --+ right away, we don't push it. */ --+ if (regno == REGNO (load_store_info.reg) && load_store_info.load_p --+ && dirty[regno] == false) --+ continue; --+ --+ load_store_infos[regno].safe_push (load_store_info); --+ } --+ } --+ --+ for (i = 0; i < NDS32_GPR_NUM; ++i) --+ { --+ for (j = 0; j < load_store_infos[i].length (); ++j) --+ { --+ if (load_store_infos[i][j].post_type == NDS32_NONE) --+ plus_infos[i].safe_push (load_store_infos[i][j]); --+ else --+ post_infos[i].safe_push (load_store_infos[i][j]); --+ } --+ } --+ --+ for (i = 0; i < NDS32_GPR_NUM; ++i) --+ { --+ if (load_store_infos[i].length () <= 1) --+ { --+ if (dump_file && load_store_infos[i].length () == 1) --+ fprintf (dump_file, --+ "Skip Chain for $r%d since chain size only 1\n", --+ i); --+ continue; --+ } --+ --+ if (dump_file) --+ { --+ fprintf (dump_file, --+ "Chain for $r%d: (size = %u)\n", --+ i, load_store_infos[i].length ()); --+ --+ for (j = 0; j < load_store_infos[i].length (); ++j) --+ { --+ fprintf (dump_file, --+ "regno = %d base_regno = %d " --+ "offset = " HOST_WIDE_INT_PRINT_DEC " " --+ "load_p = %d UID = %u place = %d\n", --+ REGNO (load_store_infos[i][j].reg), --+ REGNO (load_store_infos[i][j].base_reg), --+ load_store_infos[i][j].offset, --+ load_store_infos[i][j].load_p, --+ INSN_UID (load_store_infos[i][j].insn), --+ load_store_infos[i][j].place); --+ } --+ } --+ --+ nds32_get_available_reg_set (bb, --+ load_store_infos[i][0].insn, --+ load_store_infos[i].last ().insn, --+ &available_regset); --+ if (dump_file) --+ print_hard_reg_set (dump_file, "", available_regset); --+ --+ /* If rename_p is true, then do rename register of load/store --+ instruction. Otherwise combination of a multiple load/sotre --+ a multiple load/store instruction. */ --+ if (rename_p) --+ { --+ if (plus_infos[i].length () > 1) --+ nds32_rename_load_store_reg (&plus_infos[i], &available_regset); --+ if (post_infos[i].length () > 1) --+ nds32_rename_bi_insn (&post_infos[i], &available_regset); --+ } --+ else --+ { --+ if (plus_infos[i].length () > 1) --+ nds32_combine_load_store_insn (&plus_infos[i], &available_regset); --+ if (post_infos[i].length () > 1) --+ nds32_combine_bi_insn (&post_infos[i]); --+ } --+ } --+} --+ --+static void --+nds32_lmwsmw_opt (bool rename_p) --+{ --+ basic_block bb; --+ --+ FOR_EACH_BB_FN (bb, cfun) --+ nds32_do_lmwsmw_opt (bb, rename_p); --+} --+ --+/* Implement rename register for load and store instruction. */ --+static unsigned int --+rest_of_handle_rename_lmwsmw_opt (void) --+{ --+ init_alias_analysis (); --+ --+ df_set_flags (DF_LR_RUN_DCE); --+ df_note_add_problem (); --+ df_analyze (); --+ df_set_flags (DF_DEFER_INSN_RESCAN); --+ --+ regrename_init (true); --+ regrename_analyze (NULL); --+ --+ nds32_lmwsmw_opt (true); --+ --+ regrename_finish (); --+ --+ /* We are finished with alias. */ --+ end_alias_analysis (); --+ return 1; --+} --+ --+/* Implement generate lmw and smw instruction. */ --+static unsigned int --+rest_of_handle_gen_lmwsmw_opt (void) --+{ --+ init_alias_analysis (); --+ --+ df_note_add_problem (); --+ df_analyze (); --+ nds32_lmwsmw_opt (false); --+ --+ /* We are finished with alias. */ --+ end_alias_analysis (); --+ return 1; --+} --+ --+ --+const pass_data pass_data_nds32_rename_lmwsmw_opt = --+{ --+ RTL_PASS, /* type */ --+ "rename_lmwsmw_opt", /* name */ --+ OPTGROUP_NONE, /* optinfo_flags */ --+ TV_MACH_DEP, /* tv_id */ --+ 0, /* properties_required */ --+ 0, /* properties_provided */ --+ 0, /* properties_destroyed */ --+ 0, /* todo_flags_start */ --+ TODO_df_finish, /* todo_flags_finish */ --+}; --+ --+class pass_nds32_rename_lmwsmw_opt : public rtl_opt_pass --+{ --+public: --+ pass_nds32_rename_lmwsmw_opt (gcc::context *ctxt) --+ : rtl_opt_pass (pass_data_nds32_rename_lmwsmw_opt, ctxt) --+ {} --+ --+ /* opt_pass methods: */ --+ bool gate (function *) { return flag_nds32_lmwsmw_opt; } --+ unsigned int execute (function *) { return rest_of_handle_rename_lmwsmw_opt (); } --+}; --+ --+rtl_opt_pass * --+make_pass_nds32_rename_lmwsmw_opt (gcc::context *ctxt) --+{ --+ return new pass_nds32_rename_lmwsmw_opt (ctxt); --+} --+ --+const pass_data pass_data_nds32_gen_lmwsmw_opt = --+{ --+ RTL_PASS, /* type */ --+ "gen_lmwsmw_opt", /* name */ --+ OPTGROUP_NONE, /* optinfo_flags */ --+ TV_MACH_DEP, /* tv_id */ --+ 0, /* properties_required */ --+ 0, /* properties_provided */ --+ 0, /* properties_destroyed */ --+ 0, /* todo_flags_start */ --+ TODO_df_finish, /* todo_flags_finish */ --+}; --+ --+class pass_nds32_gen_lmwsmw_opt : public rtl_opt_pass --+{ --+public: --+ pass_nds32_gen_lmwsmw_opt (gcc::context *ctxt) --+ : rtl_opt_pass (pass_data_nds32_gen_lmwsmw_opt, ctxt) --+ {} --+ --+ /* opt_pass methods: */ --+ bool gate (function *) { return flag_nds32_lmwsmw_opt; } --+ unsigned int execute (function *) { return rest_of_handle_gen_lmwsmw_opt (); } --+}; --+ --+rtl_opt_pass * --+make_pass_nds32_gen_lmwsmw_opt (gcc::context *ctxt) --+{ --+ return new pass_nds32_gen_lmwsmw_opt (ctxt); --+} --diff --git a/gcc/config/nds32/nds32-load-store-opt.c b/gcc/config/nds32/nds32-load-store-opt.c --new file mode 100644 --index 0000000..9e5161e ----- /dev/null --+++ b/gcc/config/nds32/nds32-load-store-opt.c --@@ -0,0 +1,721 @@ --+/* load-store-opt pass of Andes NDS32 cpu for GNU compiler --+ Copyright (C) 2012-2016 Free Software Foundation, Inc. --+ Contributed by Andes Technology Corporation. --+ --+ This file is part of GCC. --+ --+ GCC is free software; you can redistribute it and/or modify it --+ under the terms of the GNU General Public License as published --+ by the Free Software Foundation; either version 3, or (at your --+ option) any later version. --+ --+ GCC is distributed in the hope that it will be useful, but WITHOUT --+ ANY WARRANTY; without even the implied warranty of MERCHANTABILITY --+ or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public --+ License for more details. --+ --+ You should have received a copy of the GNU General Public License --+ along with GCC; see the file COPYING3. If not see --+ . */ --+ --+ --+#include "config.h" --+#include "system.h" --+#include "coretypes.h" --+#include "backend.h" --+#include "tree.h" --+#include "rtl.h" --+#include "df.h" --+#include "alias.h" --+#include "stor-layout.h" --+#include "varasm.h" --+#include "calls.h" --+#include "regs.h" --+#include "insn-config.h" /* Required by recog.h. */ --+#include "conditions.h" --+#include "output.h" --+#include "insn-attr.h" /* For DFA state_t. */ --+#include "insn-codes.h" /* For CODE_FOR_xxx. */ --+#include "reload.h" /* For push_reload(). */ --+#include "flags.h" --+#include "insn-config.h" --+#include "expmed.h" --+#include "dojump.h" --+#include "explow.h" --+#include "emit-rtl.h" --+#include "stmt.h" --+#include "expr.h" --+#include "recog.h" --+#include "diagnostic-core.h" --+#include "cfgrtl.h" --+#include "cfganal.h" --+#include "lcm.h" --+#include "cfgbuild.h" --+#include "cfgcleanup.h" --+#include "tm_p.h" --+#include "tm-constrs.h" --+#include "optabs.h" /* For GEN_FCN. */ --+#include "target.h" --+#include "langhooks.h" /* For add_builtin_function(). */ --+#include "builtins.h" --+#include "cpplib.h" --+#include "params.h" --+#include "tree-pass.h" --+#include "target-globals.h" --+#include "nds32-load-store-opt.h" --+#include "nds32-reg-utils.h" --+#include --+ --+#define NDS32_GPR_NUM 32 --+ --+static new_base_reg_info_t gen_new_base (rtx, --+ offset_info_t, --+ unsigned, --+ HOST_WIDE_INT, --+ HOST_WIDE_INT); --+ --+static const load_store_optimize_pass *load_store_optimizes[] = --+{ --+ /* allow_regclass, new_base_regclass, --+ offset_lower_bound, offset_upper_bound, --+ load_only_p, name */ --+ new load_store_optimize_pass ( --+ LOW_REGS, LOW_REGS, --+ 0, (32-4), --+ false, "lswi333"), --+ new load_store_optimize_pass ( --+ LOW_REGS, FRAME_POINTER_REG, --+ 0, (512-4), --+ false, "lswi37"), --+ new load_store_optimize_pass ( --+ MIDDLE_REGS, GENERAL_REGS, --+ 0, 0, --+ false, "lswi450"), --+ new load_store_optimize_pass ( --+ MIDDLE_REGS, R8_REG, --+ -128, -4, --+ true, "lwi45fe") --+}; --+ --+static const int N_LOAD_STORE_OPT_TYPE = sizeof (load_store_optimizes) --+ / sizeof (load_store_optimize_pass*); --+ --+load_store_optimize_pass --+::load_store_optimize_pass (enum reg_class allow_regclass, --+ enum reg_class new_base_regclass, --+ HOST_WIDE_INT offset_lower_bound, --+ HOST_WIDE_INT offset_upper_bound, --+ bool load_only_p, --+ const char *name) --+ : m_allow_regclass (allow_regclass), --+ m_new_base_regclass (new_base_regclass), --+ m_offset_lower_bound (offset_lower_bound), --+ m_offset_upper_bound (offset_upper_bound), --+ m_load_only_p (load_only_p), --+ m_name (name) --+{ --+ gcc_assert (offset_lower_bound <= offset_upper_bound); --+} --+ --+int --+load_store_optimize_pass::calc_gain (HARD_REG_SET *available_regset, --+ offset_info_t offset_info, --+ load_store_infos_t *load_store_info) const --+{ --+ int extra_cost = 0; --+ int gain = 0; --+ unsigned i; --+ unsigned chain_size; --+ unsigned new_base_regnum; --+ HOST_WIDE_INT allow_range = m_offset_upper_bound - m_offset_lower_bound; --+ new_base_regnum = find_available_reg (available_regset, m_new_base_regclass); --+ chain_size = load_store_info->length (); --+ --+ if (new_base_regnum == INVALID_REGNUM) --+ { --+ if (dump_file) --+ fprintf (dump_file, --+ "%s have no avariable register, so give up try %s\n", --+ reg_class_names[m_new_base_regclass], --+ m_name); --+ return 0; --+ } --+ else if (dump_file) --+ fprintf (dump_file, --+ "%s is avariable, get %s, try %s, chain size = %u\n", --+ reg_class_names[m_new_base_regclass], --+ reg_names[new_base_regnum], --+ m_name, --+ chain_size); --+ --+ HOST_WIDE_INT range = offset_info.max_offset - offset_info.min_offset; --+ --+ if (range > allow_range) --+ { --+ /* TODO: We can perform load-store opt for only part of load store. */ --+ if (dump_file) --+ fprintf (dump_file, --+ "range is too large for %s" --+ " (range = " HOST_WIDE_INT_PRINT_DEC ", " --+ "allow_range = " HOST_WIDE_INT_PRINT_DEC ")\n", --+ m_name, range, allow_range); --+ return 0; --+ } --+ --+ if (offset_info.min_offset >= m_offset_lower_bound --+ && offset_info.max_offset <= m_offset_upper_bound) --+ { --+ /* mov55. */ --+ extra_cost = 2; --+ } --+ else --+ { --+ if (satisfies_constraint_Is15 (GEN_INT (offset_info.min_offset --+ - m_offset_lower_bound))) --+ { --+ /* add. */ --+ extra_cost = 4; --+ } --+ else --+ { --+ /* TODO: Try m_offset_upper_bound instead of m_offset_lower_bound --+ again. */ --+ /* add45 + movi. */ --+ if (satisfies_constraint_Is20 (GEN_INT (offset_info.min_offset --+ - m_offset_lower_bound))) --+ extra_cost = 6; --+ else --+ return -1; /* Give up if this constant is too large. */ --+ } --+ } --+ --+ for (i = 0; i < chain_size; ++i) --+ { --+ if (m_load_only_p && !(*load_store_info)[i].load_p) --+ continue; --+ --+ if (in_reg_class_p ((*load_store_info)[i].reg, m_allow_regclass)) --+ gain += 2; --+ } --+ --+ if (dump_file) --+ fprintf (dump_file, --+ "%s: gain = %d extra_cost = %d\n", --+ m_name, gain, extra_cost); --+ --+ return gain - extra_cost; --+} --+ --+ --+void --+load_store_optimize_pass::do_optimize ( --+ HARD_REG_SET *available_regset, --+ offset_info_t offset_info, --+ load_store_infos_t *load_store_info) const --+{ --+ new_base_reg_info_t new_base_reg_info; --+ rtx load_store_insn; --+ unsigned new_base_regnum; --+ --+ new_base_regnum = find_available_reg (available_regset, m_new_base_regclass); --+ gcc_assert (new_base_regnum != INVALID_REGNUM); --+ --+ new_base_reg_info = --+ gen_new_base ((*load_store_info)[0].base_reg, --+ offset_info, --+ new_base_regnum, --+ m_offset_lower_bound, m_offset_upper_bound); --+ unsigned i; --+ rtx insn; --+ insn = emit_insn_before (new_base_reg_info.set_insns[0], --+ (*load_store_info)[0].insn); --+ if (new_base_reg_info.n_set_insns > 1) --+ { --+ gcc_assert (new_base_reg_info.n_set_insns == 2); --+ emit_insn_before (new_base_reg_info.set_insns[1], insn); --+ } --+ --+ for (i = 0; i < load_store_info->length (); ++i) --+ { --+ if (m_load_only_p && !(*load_store_info)[i].load_p) --+ continue; --+ --+ if (!in_reg_class_p ((*load_store_info)[i].reg, m_allow_regclass)) --+ continue; --+ --+ HOST_WIDE_INT offset = (*load_store_info)[i].offset; --+ --+ if (new_base_reg_info.need_adjust_offset_p) --+ offset = offset + new_base_reg_info.adjust_offset; --+ --+ load_store_insn = --+ gen_reg_plus_imm_load_store ((*load_store_info)[i].reg, --+ new_base_reg_info.reg, --+ offset, --+ (*load_store_info)[i].load_p, --+ (*load_store_info)[i].mem); --+ --+ emit_insn_before (load_store_insn, (*load_store_info)[i].insn); --+ --+ delete_insn ((*load_store_info)[i].insn); --+ } --+ --+ /* Recompute it CFG, to update BB_END() instruction. */ --+ compute_bb_for_insn (); --+} --+ --+static new_base_reg_info_t --+gen_new_base (rtx original_base_reg, --+ offset_info_t offset_info, --+ unsigned new_base_regno, --+ HOST_WIDE_INT offset_lower, --+ HOST_WIDE_INT offset_upper) --+{ --+ new_base_reg_info_t new_base_reg_info; --+ --+ /* Use gen_raw_REG instead of gen_rtx_REG to prevent break the reg --+ info for global one. --+ For example, gen_rtx_REG will return frame_pointer_rtx immediate --+ instead of create new rtx for gen_raw_REG (Pmode, FP_REGNUM). */ --+ new_base_reg_info.reg = gen_raw_REG (Pmode, new_base_regno); --+ --+ /* Setup register info. */ --+ ORIGINAL_REGNO (new_base_reg_info.reg) = ORIGINAL_REGNO (original_base_reg); --+ REG_ATTRS (new_base_reg_info.reg) = REG_ATTRS (original_base_reg); --+ --+ if (offset_info.max_offset <= offset_upper --+ && offset_info.min_offset >= offset_lower) --+ { --+ new_base_reg_info.set_insns[0] = gen_movsi (new_base_reg_info.reg, --+ original_base_reg); --+ new_base_reg_info.n_set_insns = 1; --+ new_base_reg_info.need_adjust_offset_p = false; --+ new_base_reg_info.adjust_offset = 0; --+ } --+ else --+ { --+ /* For example: --+ lwi45.fe allow -4 ~ -128 range: --+ offset_lower = #-4 --+ offset_upper = #-128 --+ --+ lwi $r2, [$r12 + #10] --+ -> --+ addi $r8, $r12, #14 ! $r8 = $r12 + #10 - offset_lower --+ ! = $r12 + #10 - #-4 --+ ! = $r12 + #14 --+ lwi45.fe $r2, [$r8 - #4] ! [$r8 - #4] --+ ! = [$r12 + #14 - #4] --+ ! = [$r12 + #10] --+ */ --+ new_base_reg_info.adjust_offset = --+ -(offset_info.min_offset - offset_lower); --+ --+ rtx offset = GEN_INT (-new_base_reg_info.adjust_offset); --+ --+ --+ if (satisfies_constraint_Is15 (offset)) --+ { --+ new_base_reg_info.set_insns[0] = --+ gen_addsi3(new_base_reg_info.reg, --+ original_base_reg, --+ offset); --+ --+ new_base_reg_info.n_set_insns = 1; --+ } --+ else --+ { --+ if (!satisfies_constraint_Is20 (offset)) --+ gcc_unreachable (); --+ --+ new_base_reg_info.set_insns[1] = --+ gen_rtx_SET (new_base_reg_info.reg, --+ GEN_INT (-new_base_reg_info.adjust_offset)); --+ --+ new_base_reg_info.set_insns[0] = --+ gen_addsi3 (new_base_reg_info.reg, --+ new_base_reg_info.reg, --+ original_base_reg); --+ --+ new_base_reg_info.n_set_insns = 2; --+ } --+ --+ new_base_reg_info.need_adjust_offset_p = true; --+ } --+ --+ return new_base_reg_info; --+} --+ --+static bool --+nds32_4byte_load_store_reg_plus_offset ( --+ rtx_insn *insn, --+ load_store_info_t *load_store_info) --+{ --+ if (!INSN_P (insn)) --+ return false; --+ --+ rtx pattern = PATTERN (insn); --+ rtx mem = NULL_RTX; --+ rtx reg = NULL_RTX; --+ rtx base_reg = NULL_RTX; --+ rtx addr; --+ HOST_WIDE_INT offset = 0; --+ bool load_p = false; --+ --+ if (GET_CODE (pattern) != SET) --+ return false; --+ --+ if (MEM_P (SET_SRC (pattern))) --+ { --+ mem = SET_SRC (pattern); --+ reg = SET_DEST (pattern); --+ load_p = true; --+ } --+ --+ if (MEM_P (SET_DEST (pattern))) --+ { --+ mem = SET_DEST (pattern); --+ reg = SET_SRC (pattern); --+ load_p = false; --+ } --+ --+ if (mem == NULL_RTX || reg == NULL_RTX || !REG_P (reg)) --+ return false; --+ --+ gcc_assert (REG_P (reg)); --+ --+ addr = XEXP (mem, 0); --+ --+ /* We only care about [reg] and [reg+const]. */ --+ if (REG_P (addr)) --+ { --+ base_reg = addr; --+ offset = 0; --+ } --+ else if (GET_CODE (addr) == PLUS --+ && CONST_INT_P (XEXP (addr, 1))) --+ { --+ base_reg = XEXP (addr, 0); --+ offset = INTVAL (XEXP (addr, 1)); --+ if (!REG_P (base_reg)) --+ return false; --+ } --+ else --+ return false; --+ --+ /* At least need MIDDLE_REGS. */ --+ if (!in_reg_class_p (reg, MIDDLE_REGS)) --+ return false; --+ --+ /* lwi450/swi450 */ --+ if (offset == 0) --+ return false; --+ --+ if (in_reg_class_p (reg, LOW_REGS)) --+ { --+ /* lwi37.sp/swi37.sp/lwi37/swi37 */ --+ if ((REGNO (base_reg) == SP_REGNUM --+ || REGNO (base_reg) == FP_REGNUM) --+ && (offset >= 0 && offset < 512 && (offset % 4 == 0))) --+ return false; --+ --+ /* lwi333/swi333 */ --+ if (in_reg_class_p (base_reg, LOW_REGS) --+ && (offset >= 0 && offset < 32 && (offset % 4 == 0))) --+ return false; --+ } --+ --+ if (load_store_info) --+ { --+ load_store_info->load_p = load_p; --+ load_store_info->offset = offset; --+ load_store_info->reg = reg; --+ load_store_info->base_reg = base_reg; --+ load_store_info->insn = insn; --+ load_store_info->mem = mem; --+ } --+ --+ if (GET_MODE (reg) != SImode) --+ return false; --+ --+ return true; --+} --+ --+static bool --+nds32_4byte_load_store_reg_plus_offset_p (rtx_insn *insn) --+{ --+ return nds32_4byte_load_store_reg_plus_offset (insn, NULL); --+} --+ --+static bool --+nds32_load_store_opt_profitable_p (basic_block bb) --+{ --+ int candidate = 0; --+ int threshold = 2; --+ rtx_insn *insn; --+ --+ if (dump_file) --+ fprintf (dump_file, "scan bb %d\n", bb->index); --+ --+ FOR_BB_INSNS (bb, insn) --+ { --+ if (nds32_4byte_load_store_reg_plus_offset_p (insn)) --+ candidate++; --+ } --+ --+ if (dump_file) --+ fprintf (dump_file, " candidate = %d\n", candidate); --+ --+ return candidate >= threshold; --+} --+ --+static offset_info_t --+nds32_get_offset_info (auto_vec *load_store_info) --+{ --+ unsigned i; --+ std::set offsets; --+ offset_info_t offset_info; --+ offset_info.max_offset = 0; --+ offset_info.min_offset = 0; --+ offset_info.num_offset = 0; --+ --+ if (load_store_info->length () == 0) --+ return offset_info; --+ --+ offset_info.max_offset = (*load_store_info)[0].offset; --+ offset_info.min_offset = (*load_store_info)[0].offset; --+ offsets.insert ((*load_store_info)[0].offset); --+ --+ for (i = 1; i < load_store_info->length (); i++) --+ { --+ HOST_WIDE_INT offset = (*load_store_info)[i].offset; --+ offset_info.max_offset = MAX (offset_info.max_offset, offset); --+ offset_info.min_offset = MIN (offset_info.min_offset, offset); --+ offsets.insert (offset); --+ } --+ --+ offset_info.num_offset = offsets.size (); --+ --+ return offset_info; --+} --+ --+static void --+nds32_do_load_store_opt (basic_block bb) --+{ --+ rtx_insn *insn; --+ load_store_info_t load_store_info; --+ auto_vec load_store_infos[NDS32_GPR_NUM]; --+ HARD_REG_SET available_regset; --+ int i; --+ unsigned j; --+ unsigned regno; --+ unsigned polluting; --+ df_ref def; --+ /* Dirty mean a register is define again after --+ first load/store instruction. --+ For example: --+ --+ lwi $r2, [$r3 + #0x100] --+ mov $r3, $r4 ! $r3 is dirty after this instruction. --+ lwi $r1, [$r3 + #0x120] ! so this load can't chain with prev load. --+ */ --+ bool dirty[NDS32_GPR_NUM]; --+ --+ if (dump_file) --+ fprintf (dump_file, "try load store opt for bb %d\n", bb->index); --+ --+ for (i = 0; i < NDS32_GPR_NUM; ++i) --+ dirty[i] = false; --+ --+ FOR_BB_INSNS (bb, insn) --+ { --+ if (!INSN_P (insn)) --+ continue; --+ --+ polluting = INVALID_REGNUM; --+ --+ /* Set def reg is dirty if chain is not empty. */ --+ FOR_EACH_INSN_DEF (def, insn) --+ { --+ regno = DF_REF_REGNO (def); --+ --+ if (!NDS32_IS_GPR_REGNUM (regno)) --+ continue; --+ --+ if (!load_store_infos[regno].is_empty ()) --+ { --+ /* Set pulluting here because the source register --+ may be the same one. */ --+ if (dirty[regno] == false) --+ polluting = regno; --+ --+ dirty[regno] = true; --+ } --+ } --+ --+ /* Set all caller-save register is dirty if chain is not empty. */ --+ if (CALL_P (insn)) --+ { --+ for (i = 0; i < NDS32_GPR_NUM; ++i) --+ { --+ if (call_used_regs[i] && !load_store_infos[i].is_empty ()) --+ dirty[i] = true; --+ } --+ } --+ --+ if (nds32_4byte_load_store_reg_plus_offset (insn, &load_store_info)) --+ { --+ regno = REGNO (load_store_info.base_reg); --+ gcc_assert (NDS32_IS_GPR_REGNUM (regno)); --+ --+ /* Don't add to chain if this reg is dirty. */ --+ if (dirty[regno] && polluting != regno) --+ break; --+ --+ /* If the register is first time to be used and be polluted --+ right away, we don't push it. */ --+ if (regno == REGNO (load_store_info.reg) && load_store_info.load_p --+ && dirty[regno] == false) --+ continue; --+ --+ load_store_infos[regno].safe_push (load_store_info); --+ } --+ } --+ for (i = 0; i < NDS32_GPR_NUM; ++i) --+ { --+ if (load_store_infos[i].length () <= 1) --+ { --+ if (dump_file && load_store_infos[i].length () == 1) --+ fprintf (dump_file, --+ "Skip Chain for $r%d since chain size only 1\n", --+ i); --+ continue; --+ } --+ --+ if (dump_file) --+ { --+ fprintf (dump_file, --+ "Chain for $r%d: (size = %u)\n", --+ i, load_store_infos[i].length ()); --+ --+ for (j = 0; j < load_store_infos[i].length (); ++j) --+ { --+ fprintf (dump_file, --+ "regno = %d base_regno = %d " --+ "offset = " HOST_WIDE_INT_PRINT_DEC " " --+ "load_p = %d UID = %u\n", --+ REGNO (load_store_infos[i][j].reg), --+ REGNO (load_store_infos[i][j].base_reg), --+ load_store_infos[i][j].offset, --+ load_store_infos[i][j].load_p, --+ INSN_UID (load_store_infos[i][j].insn)); --+ } --+ } --+ --+ nds32_get_available_reg_set (bb, --+ load_store_infos[i][0].insn, --+ load_store_infos[i].last ().insn, --+ &available_regset); --+ --+ if (dump_file) --+ { --+ print_hard_reg_set (dump_file, "", available_regset); --+ } --+ --+ offset_info_t offset_info = nds32_get_offset_info (&load_store_infos[i]); --+ if (dump_file) --+ { --+ fprintf (dump_file, --+ "max offset = " HOST_WIDE_INT_PRINT_DEC "\n" --+ "min offset = " HOST_WIDE_INT_PRINT_DEC "\n" --+ "num offset = %d\n", --+ offset_info.max_offset, --+ offset_info.min_offset, --+ offset_info.num_offset); --+ } --+ --+ int gain; --+ int best_gain = 0; --+ const load_store_optimize_pass *best_load_store_optimize_pass = NULL; --+ --+ for (j = 0; j < N_LOAD_STORE_OPT_TYPE; ++j) --+ { --+ gain = load_store_optimizes[j]->calc_gain (&available_regset, --+ offset_info, --+ &load_store_infos[i]); --+ --+ if (dump_file) --+ fprintf (dump_file, "%s gain = %d\n", --+ load_store_optimizes[j]->name (), gain); --+ --+ if (gain > best_gain) --+ { --+ best_gain = gain; --+ best_load_store_optimize_pass = load_store_optimizes[j]; --+ } --+ } --+ --+ if (best_load_store_optimize_pass) --+ { --+ if (dump_file) --+ fprintf (dump_file, "%s is most profit, optimize it!\n", --+ best_load_store_optimize_pass->name ()); --+ --+ best_load_store_optimize_pass->do_optimize (&available_regset, --+ offset_info, --+ &load_store_infos[i]); --+ --+ df_insn_rescan_all (); --+ } --+ --+ } --+} --+ --+static unsigned int --+nds32_load_store_opt (void) --+{ --+ basic_block bb; --+ --+ df_set_flags (DF_LR_RUN_DCE); --+ df_note_add_problem (); --+ df_analyze (); --+ --+ FOR_EACH_BB_FN (bb, cfun) --+ { --+ if (nds32_load_store_opt_profitable_p (bb)) --+ nds32_do_load_store_opt (bb); --+ } --+ --+ return 1; --+} --+ --+const pass_data pass_data_nds32_load_store_opt = --+{ --+ RTL_PASS, /* type */ --+ "load_store_opt", /* name */ --+ OPTGROUP_NONE, /* optinfo_flags */ --+ TV_MACH_DEP, /* tv_id */ --+ 0, /* properties_required */ --+ 0, /* properties_provided */ --+ 0, /* properties_destroyed */ --+ 0, /* todo_flags_start */ --+ TODO_df_finish, /* todo_flags_finish */ --+}; --+ --+class pass_nds32_load_store_opt : public rtl_opt_pass --+{ --+public: --+ pass_nds32_load_store_opt (gcc::context *ctxt) --+ : rtl_opt_pass (pass_data_nds32_load_store_opt, ctxt) --+ {} --+ --+ /* opt_pass methods: */ --+ bool gate (function *) { return TARGET_16_BIT && TARGET_LOAD_STORE_OPT; } --+ unsigned int execute (function *) { return nds32_load_store_opt (); } --+}; --+ --+rtl_opt_pass * --+make_pass_nds32_load_store_opt (gcc::context *ctxt) --+{ --+ return new pass_nds32_load_store_opt (ctxt); --+} --diff --git a/gcc/config/nds32/nds32-load-store-opt.h b/gcc/config/nds32/nds32-load-store-opt.h --new file mode 100644 --index 0000000..f94b56a ----- /dev/null --+++ b/gcc/config/nds32/nds32-load-store-opt.h --@@ -0,0 +1,117 @@ --+/* Prototypes for load-store-opt of Andes NDS32 cpu for GNU compiler --+ Copyright (C) 2012-2016 Free Software Foundation, Inc. --+ Contributed by Andes Technology Corporation. --+ --+ This file is part of GCC. --+ --+ GCC is free software; you can redistribute it and/or modify it --+ under the terms of the GNU General Public License as published --+ by the Free Software Foundation; either version 3, or (at your --+ option) any later version. --+ --+ GCC is distributed in the hope that it will be useful, but WITHOUT --+ ANY WARRANTY; without even the implied warranty of MERCHANTABILITY --+ or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public --+ License for more details. --+ --+ You should have received a copy of the GNU General Public License --+ along with GCC; see the file COPYING3. If not see --+ . */ --+ --+#ifndef NDS32_LOAD_STORE_OPT_H --+#define NDS32_LOAD_STORE_OPT_H --+ --+/* Define the type of a set of hard registers. */ --+ --+enum nds32_memory_post_type --+{ --+ NDS32_NONE, --+ NDS32_POST_INC, --+ NDS32_POST_DEC --+}; --+ --+typedef struct { --+ rtx reg; --+ rtx base_reg; --+ rtx offset; --+ HOST_WIDE_INT shift; --+ bool load_p; --+ rtx insn; --+} rr_load_store_info_t; --+ --+typedef struct { --+ rtx reg; --+ rtx base_reg; --+ HOST_WIDE_INT offset; --+ bool load_p; --+ rtx_insn *insn; --+ rtx mem; --+ int new_reg; --+ int order; --+ int group; --+ bool place; --+ enum nds32_memory_post_type post_type; --+} load_store_info_t; --+ --+typedef struct { --+ HOST_WIDE_INT max_offset; --+ HOST_WIDE_INT min_offset; --+ /* How many different offset. */ --+ int num_offset; --+} offset_info_t; --+ --+typedef struct { --+ rtx set_insns[2]; --+ int n_set_insns; --+ rtx reg; --+ bool need_adjust_offset_p; --+ HOST_WIDE_INT adjust_offset; --+} new_base_reg_info_t; --+ --+typedef struct { --+ unsigned int amount; --+ unsigned int start; --+ unsigned int end; --+} available_reg_info_t; --+ --+typedef auto_vec load_store_infos_t; --+ --+class load_store_optimize_pass --+{ --+public: --+ load_store_optimize_pass (enum reg_class, --+ enum reg_class, --+ HOST_WIDE_INT, --+ HOST_WIDE_INT, --+ bool, --+ const char *); --+ const char *name () const { return m_name; }; --+ int calc_gain (HARD_REG_SET *, --+ offset_info_t, --+ load_store_infos_t *) const; --+ void do_optimize (HARD_REG_SET *, --+ offset_info_t, --+ load_store_infos_t *) const; --+private: --+ enum reg_class m_allow_regclass; --+ enum reg_class m_new_base_regclass; --+ HOST_WIDE_INT m_offset_lower_bound; --+ HOST_WIDE_INT m_offset_upper_bound; --+ bool m_load_only_p; --+ const char *m_name; --+}; --+ --+static inline rtx --+gen_reg_plus_imm_load_store (rtx reg, rtx base_reg, --+ HOST_WIDE_INT offset, bool load_p, rtx oldmem) --+{ --+ rtx addr = plus_constant(Pmode, base_reg, offset); --+ rtx mem = gen_rtx_MEM (SImode, addr); --+ MEM_COPY_ATTRIBUTES (mem, oldmem); --+ if (load_p) --+ return gen_movsi (reg, mem); --+ else --+ return gen_movsi (mem, reg); --+} --+ --+#endif /* ! NDS32_LOAD_STORE_OPT_H */ --diff --git a/gcc/config/nds32/nds32-md-auxiliary.c b/gcc/config/nds32/nds32-md-auxiliary.c --index def8eda..3881df7 100644 ----- a/gcc/config/nds32/nds32-md-auxiliary.c --+++ b/gcc/config/nds32/nds32-md-auxiliary.c --@@ -25,17 +25,74 @@ -- #include "system.h" -- #include "coretypes.h" -- #include "backend.h" ---#include "target.h" ---#include "rtl.h" -- #include "tree.h" ---#include "tm_p.h" ---#include "optabs.h" /* For GEN_FCN. */ ---#include "recog.h" --+#include "rtl.h" --+#include "df.h" --+#include "alias.h" --+#include "stor-layout.h" --+#include "varasm.h" --+#include "calls.h" --+#include "regs.h" --+#include "insn-config.h" /* Required by recog.h. */ --+#include "conditions.h" -- #include "output.h" --+#include "insn-attr.h" /* For DFA state_t. */ --+#include "insn-codes.h" /* For CODE_FOR_xxx. */ --+#include "reload.h" /* For push_reload(). */ --+#include "flags.h" --+#include "insn-config.h" --+#include "expmed.h" --+#include "dojump.h" --+#include "explow.h" --+#include "emit-rtl.h" --+#include "stmt.h" --+#include "expr.h" --+#include "recog.h" --+#include "diagnostic-core.h" --+#include "cfgrtl.h" --+#include "cfganal.h" --+#include "lcm.h" --+#include "cfgbuild.h" --+#include "cfgcleanup.h" --+#include "tm_p.h" -- #include "tm-constrs.h" --+#include "optabs.h" /* For GEN_FCN. */ --+#include "target.h" --+#include "langhooks.h" /* For add_builtin_function(). */ --+#include "builtins.h" --+ --+/* ------------------------------------------------------------------------ */ --+ --+/* This file is divided into three parts: --+ --+ PART 1: Auxiliary static function definitions. --+ --+ PART 2: Auxiliary function for expand RTL pattern. --+ --+ PART 3: Auxiliary function for output asm template. */ -- -- /* ------------------------------------------------------------------------ */ -- --+/* PART 1: Auxiliary static function definitions. */ --+ --+static int --+nds32_regno_to_enable4 (unsigned regno) --+{ --+ switch (regno) --+ { --+ case 28: /* $r28/fp */ --+ return 0x8; --+ case 29: /* $r29/gp */ --+ return 0x4; --+ case 30: /* $r30/lp */ --+ return 0x2; --+ case 31: /* $r31/sp */ --+ return 0x1; --+ default: --+ gcc_unreachable (); --+ } --+} --+ -- /* A helper function to return character based on byte size. */ -- static char -- nds32_byte_to_size (int byte) --@@ -54,796 +111,3825 @@ nds32_byte_to_size (int byte) -- } -- } -- ---/* A helper function to return memory format. */ ---enum nds32_16bit_address_type ---nds32_mem_format (rtx op) --+static int --+nds32_inverse_cond_code (int code) -- { --- machine_mode mode_test; --- int val; --- int regno; --- --- if (!TARGET_16_BIT) --- return ADDRESS_NOT_16BIT_FORMAT; --- --- mode_test = GET_MODE (op); --- --- op = XEXP (op, 0); --+ switch (code) --+ { --+ case NE: --+ return EQ; --+ case EQ: --+ return NE; --+ case GT: --+ return LE; --+ case LE: --+ return GT; --+ case GE: --+ return LT; --+ case LT: --+ return GE; --+ default: --+ gcc_unreachable (); --+ } --+} -- --- /* 45 format. */ --- if (GET_CODE (op) == REG && (mode_test == SImode)) --- return ADDRESS_REG; --+static const char * --+nds32_cond_code_str (int code) --+{ --+ switch (code) --+ { --+ case NE: --+ return "ne"; --+ case EQ: --+ return "eq"; --+ case GT: --+ return "gt"; --+ case LE: --+ return "le"; --+ case GE: --+ return "ge"; --+ case LT: --+ return "lt"; --+ default: --+ gcc_unreachable (); --+ } --+} -- --- /* 333 format for QI/HImode. */ --- if (GET_CODE (op) == REG && (REGNO (op) < R8_REGNUM)) --- return ADDRESS_LO_REG_IMM3U; --+static void --+output_cond_branch (int code, const char *suffix, bool r5_p, --+ bool long_jump_p, rtx *operands) --+{ --+ char pattern[256]; --+ const char *cond_code; --+ bool align_p = NDS32_ALIGN_P (); --+ const char *align = align_p ? "\t.align\t2\n" : ""; -- --- /* post_inc 333 format. */ --- if ((GET_CODE (op) == POST_INC) && (mode_test == SImode)) --+ if (r5_p && REGNO (operands[2]) == 5 && TARGET_16_BIT) -- { --- regno = REGNO(XEXP (op, 0)); --- --- if (regno < 8) --- return ADDRESS_POST_INC_LO_REG_IMM3U; --+ /* This is special case for beqs38 and bnes38, --+ second operand 2 can't be $r5 and it's almost meanless, --+ however it may occur after copy propgation. */ --+ if (code == EQ) --+ { --+ /* $r5 == $r5 always taken! */ --+ if (long_jump_p) --+ snprintf (pattern, sizeof (pattern), --+ "j\t%%3"); --+ else --+ snprintf (pattern, sizeof (pattern), --+ "j8\t%%3"); --+ } --+ else --+ /* Don't output anything since $r5 != $r5 never taken! */ --+ pattern[0] = '\0'; -- } --- --- /* post_inc 333 format. */ --- if ((GET_CODE (op) == POST_MODIFY) --- && (mode_test == SImode) --- && (REG_P (XEXP (XEXP (op, 1), 0))) --- && (CONST_INT_P (XEXP (XEXP (op, 1), 1)))) --+ else if (long_jump_p) -- { --- regno = REGNO (XEXP (XEXP (op, 1), 0)); --- val = INTVAL (XEXP (XEXP (op, 1), 1)); --- if (regno < 8 && val < 32) --- return ADDRESS_POST_INC_LO_REG_IMM3U; --+ int inverse_code = nds32_inverse_cond_code (code); --+ cond_code = nds32_cond_code_str (inverse_code); --+ --+ /* b $r0, $r1, .L0 --+ => --+ b $r0, $r1, .LCB0 --+ j .L0 --+ .LCB0: --+ --+ or --+ --+ b $r0, $r1, .L0 --+ => --+ b $r0, $r1, .LCB0 --+ j .L0 --+ .LCB0: --+ */ --+ if (r5_p && TARGET_16_BIT) --+ { --+ snprintf (pattern, sizeof (pattern), --+ "b%ss38\t %%2, .LCB%%=\n\tj\t%%3\n%s.LCB%%=:", --+ cond_code, align); --+ } --+ else --+ { --+ snprintf (pattern, sizeof (pattern), --+ "b%s%s\t%%1, %%2, .LCB%%=\n\tj\t%%3\n%s.LCB%%=:", --+ cond_code, suffix, align); --+ } -- } --- --- if ((GET_CODE (op) == PLUS) --- && (GET_CODE (XEXP (op, 0)) == REG) --- && (GET_CODE (XEXP (op, 1)) == CONST_INT)) --+ else -- { --- val = INTVAL (XEXP (op, 1)); --- --- regno = REGNO(XEXP (op, 0)); --- --- if (regno > 7 --- && regno != SP_REGNUM --- && regno != FP_REGNUM) --- return ADDRESS_NOT_16BIT_FORMAT; --- --- switch (mode_test) --+ cond_code = nds32_cond_code_str (code); --+ if (r5_p && TARGET_16_BIT) -- { --- case QImode: --- /* 333 format. */ --- if (val >= 0 && val < 8 && regno < 8) --- return ADDRESS_LO_REG_IMM3U; --- break; --- --- case HImode: --- /* 333 format. */ --- if (val >= 0 && val < 16 && (val % 2 == 0) && regno < 8) --- return ADDRESS_LO_REG_IMM3U; --- break; --- --- case SImode: --- case SFmode: --- case DFmode: --- /* fp imply 37 format. */ --- if ((regno == FP_REGNUM) && --- (val >= 0 && val < 512 && (val % 4 == 0))) --- return ADDRESS_FP_IMM7U; --- /* sp imply 37 format. */ --- else if ((regno == SP_REGNUM) && --- (val >= 0 && val < 512 && (val % 4 == 0))) --- return ADDRESS_SP_IMM7U; --- /* 333 format. */ --- else if (val >= 0 && val < 32 && (val % 4 == 0) && regno < 8) --- return ADDRESS_LO_REG_IMM3U; --- break; --- --- default: --- break; --+ /* bs38 $r1, .L0 */ --+ snprintf (pattern, sizeof (pattern), --+ "b%ss38\t %%2, %%3", cond_code); --+ } --+ else --+ { --+ /* b $r0, $r1, .L0 */ --+ snprintf (pattern, sizeof (pattern), --+ "b%s%s\t%%1, %%2, %%3", cond_code, suffix); -- } -- } -- --- return ADDRESS_NOT_16BIT_FORMAT; --+ output_asm_insn (pattern, operands); -- } -- ---/* Output 16-bit store. */ ---const char * ---nds32_output_16bit_store (rtx *operands, int byte) --+static void --+output_cond_branch_compare_zero (int code, const char *suffix, --+ bool long_jump_p, rtx *operands, --+ bool ta_implied_p) -- { --- char pattern[100]; --- char size; --- rtx code = XEXP (operands[0], 0); --- --- size = nds32_byte_to_size (byte); --+ char pattern[256]; --+ const char *cond_code; --+ bool align_p = NDS32_ALIGN_P (); --+ const char *align = align_p ? "\t.align\t2\n" : ""; --+ if (long_jump_p) --+ { --+ int inverse_code = nds32_inverse_cond_code (code); --+ cond_code = nds32_cond_code_str (inverse_code); -- --- switch (nds32_mem_format (operands[0])) --+ if (ta_implied_p && TARGET_16_BIT) --+ { --+ /* bz .L0 --+ => --+ bz .LCB0 --+ j .L0 --+ .LCB0: --+ */ --+ snprintf (pattern, sizeof (pattern), --+ "b%sz%s\t.LCB%%=\n\tj\t%%2\n%s.LCB%%=:", --+ cond_code, suffix, align); --+ } --+ else --+ { --+ /* bz $r0, .L0 --+ => --+ bz $r0, .LCB0 --+ j .L0 --+ .LCB0: --+ */ --+ snprintf (pattern, sizeof (pattern), --+ "b%sz%s\t%%1, .LCB%%=\n\tj\t%%2\n%s.LCB%%=:", --+ cond_code, suffix, align); --+ } --+ } --+ else -- { --- case ADDRESS_REG: --- operands[0] = code; --- output_asm_insn ("swi450\t%1, [%0]", operands); --- break; --- case ADDRESS_LO_REG_IMM3U: --- snprintf (pattern, sizeof (pattern), "s%ci333\t%%1, %%0", size); --- output_asm_insn (pattern, operands); --- break; --- case ADDRESS_POST_INC_LO_REG_IMM3U: --- snprintf (pattern, sizeof (pattern), "s%ci333.bi\t%%1, %%0", size); --- output_asm_insn (pattern, operands); --- break; --- case ADDRESS_FP_IMM7U: --- output_asm_insn ("swi37\t%1, %0", operands); --- break; --- case ADDRESS_SP_IMM7U: --- /* Get immediate value and set back to operands[1]. */ --- operands[0] = XEXP (code, 1); --- output_asm_insn ("swi37.sp\t%1, [ + (%0)]", operands); --- break; --- default: --- break; --+ cond_code = nds32_cond_code_str (code); --+ if (ta_implied_p && TARGET_16_BIT) --+ { --+ /* bz .L0 */ --+ snprintf (pattern, sizeof (pattern), --+ "b%sz%s\t%%2", cond_code, suffix); --+ } --+ else --+ { --+ /* bz $r0, .L0 */ --+ snprintf (pattern, sizeof (pattern), --+ "b%sz%s\t%%1, %%2", cond_code, suffix); --+ } -- } -- --- return ""; --+ output_asm_insn (pattern, operands); -- } -- ---/* Output 16-bit load. */ ---const char * ---nds32_output_16bit_load (rtx *operands, int byte) --+static void --+nds32_split_shiftrtdi3 (rtx dst, rtx src, rtx shiftamount, bool logic_shift_p) -- { --- char pattern[100]; --- unsigned char size; --- rtx code = XEXP (operands[1], 0); --+ rtx src_high_part; --+ rtx dst_high_part, dst_low_part; -- --- size = nds32_byte_to_size (byte); --+ dst_high_part = nds32_di_high_part_subreg (dst); --+ src_high_part = nds32_di_high_part_subreg (src); --+ dst_low_part = nds32_di_low_part_subreg (dst); -- --- switch (nds32_mem_format (operands[1])) --+ if (CONST_INT_P (shiftamount)) -- { --- case ADDRESS_REG: --- operands[1] = code; --- output_asm_insn ("lwi450\t%0, [%1]", operands); --- break; --- case ADDRESS_LO_REG_IMM3U: --- snprintf (pattern, sizeof (pattern), "l%ci333\t%%0, %%1", size); --- output_asm_insn (pattern, operands); --- break; --- case ADDRESS_POST_INC_LO_REG_IMM3U: --- snprintf (pattern, sizeof (pattern), "l%ci333.bi\t%%0, %%1", size); --- output_asm_insn (pattern, operands); --- break; --- case ADDRESS_FP_IMM7U: --- output_asm_insn ("lwi37\t%0, %1", operands); --- break; --- case ADDRESS_SP_IMM7U: --- /* Get immediate value and set back to operands[0]. */ --- operands[1] = XEXP (code, 1); --- output_asm_insn ("lwi37.sp\t%0, [ + (%1)]", operands); --- break; --- default: --- break; --+ if (INTVAL (shiftamount) < 32) --+ { --+ if (logic_shift_p) --+ { --+ emit_insn (gen_uwext (dst_low_part, src, --+ shiftamount)); --+ emit_insn (gen_lshrsi3 (dst_high_part, src_high_part, --+ shiftamount)); --+ } --+ else --+ { --+ emit_insn (gen_wext (dst_low_part, src, --+ shiftamount)); --+ emit_insn (gen_ashrsi3 (dst_high_part, src_high_part, --+ shiftamount)); --+ } --+ } --+ else --+ { --+ rtx new_shift_amout = gen_int_mode(INTVAL (shiftamount) - 32, SImode); --+ --+ if (logic_shift_p) --+ { --+ emit_insn (gen_lshrsi3 (dst_low_part, src_high_part, --+ new_shift_amout)); --+ emit_move_insn (dst_high_part, const0_rtx); --+ } --+ else --+ { --+ emit_insn (gen_ashrsi3 (dst_low_part, src_high_part, --+ new_shift_amout)); --+ emit_insn (gen_ashrsi3 (dst_high_part, src_high_part, --+ GEN_INT (31))); --+ } --+ } -- } --+ else --+ { --+ rtx dst_low_part_l32, dst_high_part_l32; --+ rtx dst_low_part_g32, dst_high_part_g32; --+ rtx new_shift_amout, select_reg; --+ dst_low_part_l32 = gen_reg_rtx (SImode); --+ dst_high_part_l32 = gen_reg_rtx (SImode); --+ dst_low_part_g32 = gen_reg_rtx (SImode); --+ dst_high_part_g32 = gen_reg_rtx (SImode); --+ new_shift_amout = gen_reg_rtx (SImode); --+ select_reg = gen_reg_rtx (SImode); --+ --+ emit_insn (gen_andsi3 (shiftamount, shiftamount, GEN_INT (0x3f))); --+ --+ if (logic_shift_p) --+ { --+ /* --+ if (shiftamount < 32) --+ dst_low_part = wext (src, shiftamount) --+ dst_high_part = src_high_part >> shiftamount --+ else --+ dst_low_part = src_high_part >> (shiftamount & 0x1f) --+ dst_high_part = 0 --+ */ --+ emit_insn (gen_uwext (dst_low_part_l32, src, shiftamount)); --+ emit_insn (gen_lshrsi3 (dst_high_part_l32, src_high_part, --+ shiftamount)); --+ --+ emit_insn (gen_andsi3 (new_shift_amout, shiftamount, GEN_INT (0x1f))); --+ emit_insn (gen_lshrsi3 (dst_low_part_g32, src_high_part, --+ new_shift_amout)); --+ emit_move_insn (dst_high_part_g32, const0_rtx); --+ } --+ else --+ { --+ /* --+ if (shiftamount < 32) --+ dst_low_part = wext (src, shiftamount) --+ dst_high_part = src_high_part >> shiftamount --+ else --+ dst_low_part = src_high_part >> (shiftamount & 0x1f) --+ # shift 31 for sign extend --+ dst_high_part = src_high_part >> 31 --+ */ --+ emit_insn (gen_wext (dst_low_part_l32, src, shiftamount)); --+ emit_insn (gen_ashrsi3 (dst_high_part_l32, src_high_part, --+ shiftamount)); --+ --+ emit_insn (gen_andsi3 (new_shift_amout, shiftamount, GEN_INT (0x1f))); --+ emit_insn (gen_ashrsi3 (dst_low_part_g32, src_high_part, --+ new_shift_amout)); --+ emit_insn (gen_ashrsi3 (dst_high_part_g32, src_high_part, --+ GEN_INT (31))); --+ } -- --- return ""; --+ emit_insn (gen_slt_compare (select_reg, shiftamount, GEN_INT (32))); --+ --+ emit_insn (gen_cmovnsi (dst_low_part, select_reg, --+ dst_low_part_l32, dst_low_part_g32)); --+ emit_insn (gen_cmovnsi (dst_high_part, select_reg, --+ dst_high_part_l32, dst_high_part_g32)); --+ } -- } -- ---/* Output 32-bit store. */ ---const char * ---nds32_output_32bit_store (rtx *operands, int byte) ---{ --- char pattern[100]; --- unsigned char size; --- rtx code = XEXP (operands[0], 0); --+/* ------------------------------------------------------------------------ */ -- --- size = nds32_byte_to_size (byte); --+/* PART 2: Auxiliary function for expand RTL pattern. */ -- --- switch (GET_CODE (code)) --+enum nds32_expand_result_type --+nds32_expand_cbranch (rtx *operands) --+{ --+ rtx tmp_reg; --+ enum rtx_code code; --+ --+ code = GET_CODE (operands[0]); --+ --+ /* If operands[2] is (const_int 0), --+ we can use beqz,bnez,bgtz,bgez,bltz,or blez instructions. --+ So we have gcc generate original template rtx. */ --+ if (GET_CODE (operands[2]) == CONST_INT) --+ if (INTVAL (operands[2]) == 0) --+ if ((code != GTU) --+ && (code != GEU) --+ && (code != LTU) --+ && (code != LEU)) --+ return EXPAND_CREATE_TEMPLATE; --+ --+ /* For other comparison, NDS32 ISA only has slt (Set-on-Less-Than) --+ behavior for the comparison, we might need to generate other --+ rtx patterns to achieve same semantic. */ --+ switch (code) -- { --- case REG: --- /* (mem (reg X)) --- => access location by using register, --- use "sbi / shi / swi" */ --- snprintf (pattern, sizeof (pattern), "s%ci\t%%1, %%0", size); --- break; --- --- case SYMBOL_REF: --- case CONST: --- /* (mem (symbol_ref X)) --- (mem (const (...))) --- => access global variables, --- use "sbi.gp / shi.gp / swi.gp" */ --- operands[0] = XEXP (operands[0], 0); --- snprintf (pattern, sizeof (pattern), "s%ci.gp\t%%1, [ + %%0]", size); --- break; --+ case GT: --+ case GTU: --+ if (GET_CODE (operands[2]) == CONST_INT) --+ { --+ /* GT reg_A, const_int => !(LT reg_A, const_int + 1) */ --+ if (optimize_size || optimize == 0) --+ tmp_reg = gen_rtx_REG (SImode, TA_REGNUM); --+ else --+ tmp_reg = gen_reg_rtx (SImode); --+ --+ /* We want to plus 1 into the integer value --+ of operands[2] to create 'slt' instruction. --+ This caculation is performed on the host machine, --+ which may be 64-bit integer. --+ So the meaning of caculation result may be --+ different from the 32-bit nds32 target. --+ --+ For example: --+ 0x7fffffff + 0x1 -> 0x80000000, --+ this value is POSITIVE on 64-bit machine, --+ but the expected value on 32-bit nds32 target --+ should be NEGATIVE value. --+ --+ Hence, instead of using GEN_INT(), we use gen_int_mode() to --+ explicitly create SImode constant rtx. */ --+ enum rtx_code cmp_code; --+ --+ rtx plus1 = gen_int_mode (INTVAL (operands[2]) + 1, SImode); --+ if (satisfies_constraint_Is15 (plus1)) --+ { --+ operands[2] = plus1; --+ cmp_code = EQ; --+ if (code == GT) --+ { --+ /* GT, use slts instruction */ --+ emit_insn ( --+ gen_slts_compare (tmp_reg, operands[1], operands[2])); --+ } --+ else --+ { --+ /* GTU, use slt instruction */ --+ emit_insn ( --+ gen_slt_compare (tmp_reg, operands[1], operands[2])); --+ } --+ } --+ else --+ { --+ cmp_code = NE; --+ if (code == GT) --+ { --+ /* GT, use slts instruction */ --+ emit_insn ( --+ gen_slts_compare (tmp_reg, operands[2], operands[1])); --+ } --+ else --+ { --+ /* GTU, use slt instruction */ --+ emit_insn ( --+ gen_slt_compare (tmp_reg, operands[2], operands[1])); --+ } --+ } --+ --+ PUT_CODE (operands[0], cmp_code); --+ operands[1] = tmp_reg; --+ operands[2] = const0_rtx; --+ emit_insn (gen_cbranchsi4 (operands[0], operands[1], --+ operands[2], operands[3])); --+ --+ return EXPAND_DONE; --+ } --+ else --+ { --+ /* GT reg_A, reg_B => LT reg_B, reg_A */ --+ if (optimize_size || optimize == 0) --+ tmp_reg = gen_rtx_REG (SImode, TA_REGNUM); --+ else --+ tmp_reg = gen_reg_rtx (SImode); --+ --+ if (code == GT) --+ { --+ /* GT, use slts instruction */ --+ emit_insn (gen_slts_compare (tmp_reg, operands[2], operands[1])); --+ } --+ else --+ { --+ /* GTU, use slt instruction */ --+ emit_insn (gen_slt_compare (tmp_reg, operands[2], operands[1])); --+ } --+ --+ PUT_CODE (operands[0], NE); --+ operands[1] = tmp_reg; --+ operands[2] = const0_rtx; --+ emit_insn (gen_cbranchsi4 (operands[0], operands[1], --+ operands[2], operands[3])); --+ --+ return EXPAND_DONE; --+ } -- --- case POST_INC: --- /* (mem (post_inc reg)) --- => access location by using register which will be post increment, --- use "sbi.bi / shi.bi / swi.bi" */ --- snprintf (pattern, sizeof (pattern), --- "s%ci.bi\t%%1, %%0, %d", size, byte); --- break; --+ case GE: --+ case GEU: --+ /* GE reg_A, reg_B => !(LT reg_A, reg_B) */ --+ /* GE reg_A, const_int => !(LT reg_A, const_int) */ --+ if (optimize_size || optimize == 0) --+ tmp_reg = gen_rtx_REG (SImode, TA_REGNUM); --+ else --+ tmp_reg = gen_reg_rtx (SImode); -- --- case POST_DEC: --- /* (mem (post_dec reg)) --- => access location by using register which will be post decrement, --- use "sbi.bi / shi.bi / swi.bi" */ --- snprintf (pattern, sizeof (pattern), --- "s%ci.bi\t%%1, %%0, -%d", size, byte); --- break; --+ if (code == GE) --+ { --+ /* GE, use slts instruction */ --+ emit_insn (gen_slts_compare (tmp_reg, operands[1], operands[2])); --+ } --+ else --+ { --+ /* GEU, use slt instruction */ --+ emit_insn (gen_slt_compare (tmp_reg, operands[1], operands[2])); --+ } -- --- case POST_MODIFY: --- switch (GET_CODE (XEXP (XEXP (code, 1), 1))) --+ PUT_CODE (operands[0], EQ); --+ operands[1] = tmp_reg; --+ operands[2] = const0_rtx; --+ emit_insn (gen_cbranchsi4 (operands[0], operands[1], --+ operands[2], operands[3])); --+ --+ return EXPAND_DONE; --+ --+ case LT: --+ case LTU: --+ /* LT reg_A, reg_B => LT reg_A, reg_B */ --+ /* LT reg_A, const_int => LT reg_A, const_int */ --+ if (optimize_size || optimize == 0) --+ tmp_reg = gen_rtx_REG (SImode, TA_REGNUM); --+ else --+ tmp_reg = gen_reg_rtx (SImode); --+ --+ if (code == LT) -- { --- case REG: --- case SUBREG: --- /* (mem (post_modify (reg) (plus (reg) (reg)))) --- => access location by using register which will be --- post modified with reg, --- use "sb.bi/ sh.bi / sw.bi" */ --- snprintf (pattern, sizeof (pattern), "s%c.bi\t%%1, %%0", size); --- break; --- case CONST_INT: --- /* (mem (post_modify (reg) (plus (reg) (const_int)))) --- => access location by using register which will be --- post modified with const_int, --- use "sbi.bi/ shi.bi / swi.bi" */ --- snprintf (pattern, sizeof (pattern), "s%ci.bi\t%%1, %%0", size); --- break; --- default: --- abort (); --+ /* LT, use slts instruction */ --+ emit_insn (gen_slts_compare (tmp_reg, operands[1], operands[2])); --+ } --+ else --+ { --+ /* LTU, use slt instruction */ --+ emit_insn (gen_slt_compare (tmp_reg, operands[1], operands[2])); -- } --- break; -- --- case PLUS: --- switch (GET_CODE (XEXP (code, 1))) --+ PUT_CODE (operands[0], NE); --+ operands[1] = tmp_reg; --+ operands[2] = const0_rtx; --+ emit_insn (gen_cbranchsi4 (operands[0], operands[1], --+ operands[2], operands[3])); --+ --+ return EXPAND_DONE; --+ --+ case LE: --+ case LEU: --+ if (GET_CODE (operands[2]) == CONST_INT) -- { --- case REG: --- case SUBREG: --- /* (mem (plus reg reg)) or (mem (plus (mult reg const_int) reg)) --- => access location by adding two registers, --- use "sb / sh / sw" */ --- snprintf (pattern, sizeof (pattern), "s%c\t%%1, %%0", size); --- break; --- case CONST_INT: --- /* (mem (plus reg const_int)) --- => access location by adding one register with const_int, --- use "sbi / shi / swi" */ --- snprintf (pattern, sizeof (pattern), "s%ci\t%%1, %%0", size); --- break; --- default: --- abort (); --+ /* LE reg_A, const_int => LT reg_A, const_int + 1 */ --+ if (optimize_size || optimize == 0) --+ tmp_reg = gen_rtx_REG (SImode, TA_REGNUM); --+ else --+ tmp_reg = gen_reg_rtx (SImode); --+ --+ enum rtx_code cmp_code; --+ /* Note that (le:SI X INT_MAX) is not the same as (lt:SI X INT_MIN). --+ We better have an assert here in case GCC does not properly --+ optimize it away. The INT_MAX here is 0x7fffffff for target. */ --+ rtx plus1 = gen_int_mode (INTVAL (operands[2]) + 1, SImode); --+ if (satisfies_constraint_Is15 (plus1)) --+ { --+ operands[2] = plus1; --+ cmp_code = NE; --+ if (code == LE) --+ { --+ /* LE, use slts instruction */ --+ emit_insn ( --+ gen_slts_compare (tmp_reg, operands[1], operands[2])); --+ } --+ else --+ { --+ /* LEU, use slt instruction */ --+ emit_insn ( --+ gen_slt_compare (tmp_reg, operands[1], operands[2])); --+ } --+ } --+ else --+ { --+ cmp_code = EQ; --+ if (code == LE) --+ { --+ /* LE, use slts instruction */ --+ emit_insn ( --+ gen_slts_compare (tmp_reg, operands[2], operands[1])); --+ } --+ else --+ { --+ /* LEU, use slt instruction */ --+ emit_insn ( --+ gen_slt_compare (tmp_reg, operands[2], operands[1])); --+ } --+ } --+ --+ PUT_CODE (operands[0], cmp_code); --+ operands[1] = tmp_reg; --+ operands[2] = const0_rtx; --+ emit_insn (gen_cbranchsi4 (operands[0], operands[1], --+ operands[2], operands[3])); --+ --+ return EXPAND_DONE; --+ } --+ else --+ { --+ /* LE reg_A, reg_B => !(LT reg_B, reg_A) */ --+ if (optimize_size || optimize == 0) --+ tmp_reg = gen_rtx_REG (SImode, TA_REGNUM); --+ else --+ tmp_reg = gen_reg_rtx (SImode); --+ --+ if (code == LE) --+ { --+ /* LE, use slts instruction */ --+ emit_insn (gen_slts_compare (tmp_reg, operands[2], operands[1])); --+ } --+ else --+ { --+ /* LEU, use slt instruction */ --+ emit_insn (gen_slt_compare (tmp_reg, operands[2], operands[1])); --+ } --+ --+ PUT_CODE (operands[0], EQ); --+ operands[1] = tmp_reg; --+ operands[2] = const0_rtx; --+ emit_insn (gen_cbranchsi4 (operands[0], operands[1], --+ operands[2], operands[3])); --+ --+ return EXPAND_DONE; -- } --- break; -- --- case LO_SUM: --- operands[2] = XEXP (code, 1); --- operands[0] = XEXP (code, 0); --- snprintf (pattern, sizeof (pattern), --- "s%ci\t%%1, [%%0 + lo12(%%2)]", size); --- break; --+ case EQ: --+ case NE: --+ /* NDS32 ISA has various form for eq/ne behavior no matter --+ what kind of the operand is. --+ So just generate original template rtx. */ --+ --+ /* Put operands[2] into register if operands[2] is a large --+ const_int or ISAv2. */ --+ if (GET_CODE (operands[2]) == CONST_INT --+ && (!satisfies_constraint_Is11 (operands[2]) --+ || TARGET_ISA_V2)) --+ operands[2] = force_reg (SImode, operands[2]); --+ --+ return EXPAND_CREATE_TEMPLATE; -- -- default: --- abort (); --+ return EXPAND_FAIL; -- } --- --- output_asm_insn (pattern, operands); --- return ""; -- } -- ---/* Output 32-bit load. */ ---const char * ---nds32_output_32bit_load (rtx *operands, int byte) --+enum nds32_expand_result_type --+nds32_expand_cstore (rtx *operands) -- { --- char pattern[100]; --- unsigned char size; --- rtx code; --- --- code = XEXP (operands[1], 0); --+ rtx tmp_reg; --+ enum rtx_code code; -- --- size = nds32_byte_to_size (byte); --+ code = GET_CODE (operands[1]); -- --- switch (GET_CODE (code)) --+ switch (code) -- { --- case REG: --- /* (mem (reg X)) --- => access location by using register, --- use "lbi / lhi / lwi" */ --- snprintf (pattern, sizeof (pattern), "l%ci\t%%0, %%1", size); --- break; --- --- case SYMBOL_REF: --- case CONST: --- /* (mem (symbol_ref X)) --- (mem (const (...))) --- => access global variables, --- use "lbi.gp / lhi.gp / lwi.gp" */ --- operands[1] = XEXP (operands[1], 0); --- snprintf (pattern, sizeof (pattern), "l%ci.gp\t%%0, [ + %%1]", size); --- break; --+ case EQ: --+ case NE: --+ if (GET_CODE (operands[3]) == CONST_INT) --+ { --+ /* reg_R = (reg_A == const_int_B) --+ --> xori reg_C, reg_A, const_int_B --+ slti reg_R, reg_C, const_int_1 --+ reg_R = (reg_A != const_int_B) --+ --> xori reg_C, reg_A, const_int_B --+ slti reg_R, const_int0, reg_C */ --+ tmp_reg = gen_reg_rtx (SImode); --+ --+ /* If the integer value is not in the range of imm15s, --+ we need to force register first because our addsi3 pattern --+ only accept nds32_rimm15s_operand predicate. */ --+ rtx new_imm = gen_int_mode (-INTVAL (operands[3]), SImode); --+ if (satisfies_constraint_Is15 (new_imm)) --+ emit_insn (gen_addsi3 (tmp_reg, operands[2], new_imm)); --+ else --+ { --+ if (!(satisfies_constraint_Iu15 (operands[3]) --+ || (TARGET_EXT_PERF --+ && satisfies_constraint_It15 (operands[3])))) --+ operands[3] = force_reg (SImode, operands[3]); --+ emit_insn (gen_xorsi3 (tmp_reg, operands[2], operands[3])); --+ } --+ --+ if (code == EQ) --+ emit_insn (gen_slt_eq0 (operands[0], tmp_reg)); --+ else --+ emit_insn (gen_slt_compare (operands[0], const0_rtx, tmp_reg)); --+ --+ return EXPAND_DONE; --+ } --+ else --+ { --+ /* reg_R = (reg_A == reg_B) --+ --> xor reg_C, reg_A, reg_B --+ slti reg_R, reg_C, const_int_1 --+ reg_R = (reg_A != reg_B) --+ --> xor reg_C, reg_A, reg_B --+ slti reg_R, const_int0, reg_C */ --+ tmp_reg = gen_reg_rtx (SImode); --+ emit_insn (gen_xorsi3 (tmp_reg, operands[2], operands[3])); --+ if (code == EQ) --+ emit_insn (gen_slt_eq0 (operands[0], tmp_reg)); --+ else --+ emit_insn (gen_slt_compare (operands[0], const0_rtx, tmp_reg)); --+ --+ return EXPAND_DONE; --+ } --+ case GT: --+ case GTU: --+ /* reg_R = (reg_A > reg_B) --> slt reg_R, reg_B, reg_A */ --+ /* reg_R = (reg_A > const_int_B) --> slt reg_R, const_int_B, reg_A */ --+ if (code == GT) --+ { --+ /* GT, use slts instruction */ --+ emit_insn (gen_slts_compare (operands[0], operands[3], operands[2])); --+ } --+ else --+ { --+ /* GTU, use slt instruction */ --+ emit_insn (gen_slt_compare (operands[0], operands[3], operands[2])); --+ } -- --- case POST_INC: --- /* (mem (post_inc reg)) --- => access location by using register which will be post increment, --- use "lbi.bi / lhi.bi / lwi.bi" */ --- snprintf (pattern, sizeof (pattern), --- "l%ci.bi\t%%0, %%1, %d", size, byte); --- break; --+ return EXPAND_DONE; -- --- case POST_DEC: --- /* (mem (post_dec reg)) --- => access location by using register which will be post decrement, --- use "lbi.bi / lhi.bi / lwi.bi" */ --- snprintf (pattern, sizeof (pattern), --- "l%ci.bi\t%%0, %%1, -%d", size, byte); --- break; --+ case GE: --+ case GEU: --+ if (GET_CODE (operands[3]) == CONST_INT) --+ { --+ /* reg_R = (reg_A >= const_int_B) --+ --> movi reg_C, const_int_B - 1 --+ slt reg_R, reg_C, reg_A */ --+ tmp_reg = gen_reg_rtx (SImode); --+ --+ emit_insn (gen_movsi (tmp_reg, --+ gen_int_mode (INTVAL (operands[3]) - 1, --+ SImode))); --+ if (code == GE) --+ { --+ /* GE, use slts instruction */ --+ emit_insn (gen_slts_compare (operands[0], tmp_reg, operands[2])); --+ } --+ else --+ { --+ /* GEU, use slt instruction */ --+ emit_insn (gen_slt_compare (operands[0], tmp_reg, operands[2])); --+ } --+ --+ return EXPAND_DONE; --+ } --+ else --+ { --+ /* reg_R = (reg_A >= reg_B) --+ --> slt reg_R, reg_A, reg_B --+ xori reg_R, reg_R, const_int_1 */ --+ if (code == GE) --+ { --+ /* GE, use slts instruction */ --+ emit_insn (gen_slts_compare (operands[0], --+ operands[2], operands[3])); --+ } --+ else --+ { --+ /* GEU, use slt instruction */ --+ emit_insn (gen_slt_compare (operands[0], --+ operands[2], operands[3])); --+ } --+ --+ /* perform 'not' behavior */ --+ emit_insn (gen_xorsi3 (operands[0], operands[0], const1_rtx)); --+ --+ return EXPAND_DONE; --+ } -- --- case POST_MODIFY: --- switch (GET_CODE (XEXP (XEXP (code, 1), 1))) --+ case LT: --+ case LTU: --+ /* reg_R = (reg_A < reg_B) --> slt reg_R, reg_A, reg_B */ --+ /* reg_R = (reg_A < const_int_B) --> slt reg_R, reg_A, const_int_B */ --+ if (code == LT) -- { --- case REG: --- case SUBREG: --- /* (mem (post_modify (reg) (plus (reg) (reg)))) --- => access location by using register which will be --- post modified with reg, --- use "lb.bi/ lh.bi / lw.bi" */ --- snprintf (pattern, sizeof (pattern), "l%c.bi\t%%0, %%1", size); --- break; --- case CONST_INT: --- /* (mem (post_modify (reg) (plus (reg) (const_int)))) --- => access location by using register which will be --- post modified with const_int, --- use "lbi.bi/ lhi.bi / lwi.bi" */ --- snprintf (pattern, sizeof (pattern), "l%ci.bi\t%%0, %%1", size); --- break; --- default: --- abort (); --+ /* LT, use slts instruction */ --+ emit_insn (gen_slts_compare (operands[0], operands[2], operands[3])); --+ } --+ else --+ { --+ /* LTU, use slt instruction */ --+ emit_insn (gen_slt_compare (operands[0], operands[2], operands[3])); -- } --- break; -- --- case PLUS: --- switch (GET_CODE (XEXP (code, 1))) --+ return EXPAND_DONE; --+ --+ case LE: --+ case LEU: --+ if (GET_CODE (operands[3]) == CONST_INT) -- { --- case REG: --- case SUBREG: --- /* (mem (plus reg reg)) or (mem (plus (mult reg const_int) reg)) --- use "lb / lh / lw" */ --- snprintf (pattern, sizeof (pattern), "l%c\t%%0, %%1", size); --- break; --- case CONST_INT: --- /* (mem (plus reg const_int)) --- => access location by adding one register with const_int, --- use "lbi / lhi / lwi" */ --- snprintf (pattern, sizeof (pattern), "l%ci\t%%0, %%1", size); --- break; --- default: --- abort (); --+ /* reg_R = (reg_A <= const_int_B) --+ --> movi reg_C, const_int_B + 1 --+ slt reg_R, reg_A, reg_C */ --+ tmp_reg = gen_reg_rtx (SImode); --+ --+ emit_insn (gen_movsi (tmp_reg, --+ gen_int_mode (INTVAL (operands[3]) + 1, --+ SImode))); --+ if (code == LE) --+ { --+ /* LE, use slts instruction */ --+ emit_insn (gen_slts_compare (operands[0], operands[2], tmp_reg)); --+ } --+ else --+ { --+ /* LEU, use slt instruction */ --+ emit_insn (gen_slt_compare (operands[0], operands[2], tmp_reg)); --+ } --+ --+ return EXPAND_DONE; --+ } --+ else --+ { --+ /* reg_R = (reg_A <= reg_B) --> slt reg_R, reg_B, reg_A --+ xori reg_R, reg_R, const_int_1 */ --+ if (code == LE) --+ { --+ /* LE, use slts instruction */ --+ emit_insn (gen_slts_compare (operands[0], --+ operands[3], operands[2])); --+ } --+ else --+ { --+ /* LEU, use slt instruction */ --+ emit_insn (gen_slt_compare (operands[0], --+ operands[3], operands[2])); --+ } --+ --+ /* perform 'not' behavior */ --+ emit_insn (gen_xorsi3 (operands[0], operands[0], const1_rtx)); --+ --+ return EXPAND_DONE; -- } --- break; -- --- case LO_SUM: --- operands[2] = XEXP (code, 1); --- operands[1] = XEXP (code, 0); --- snprintf (pattern, sizeof (pattern), --- "l%ci\t%%0, [%%1 + lo12(%%2)]", size); --- break; -- -- default: --- abort (); --+ gcc_unreachable (); -- } --- --- output_asm_insn (pattern, operands); --- return ""; -- } -- ---/* Output 32-bit load with signed extension. */ ---const char * ---nds32_output_32bit_load_s (rtx *operands, int byte) --+void --+nds32_expand_float_cbranch (rtx *operands) -- { --- char pattern[100]; --- unsigned char size; --- rtx code; --+ enum rtx_code code = GET_CODE (operands[0]); --+ enum rtx_code new_code = code; --+ rtx cmp_op0 = operands[1]; --+ rtx cmp_op1 = operands[2]; --+ rtx tmp_reg; --+ rtx tmp; -- --- code = XEXP (operands[1], 0); --+ int reverse = 0; -- --- size = nds32_byte_to_size (byte); --+ /* Main Goal: Use compare instruction + branch instruction. -- --- switch (GET_CODE (code)) --+ For example: --+ GT, GE: swap condition and swap operands and generate --+ compare instruction(LT, LE) + branch not equal instruction. --+ --+ UNORDERED, LT, LE, EQ: no need to change and generate --+ compare instruction(UNORDERED, LT, LE, EQ) + branch not equal instruction. --+ --+ ORDERED, NE: reverse condition and generate --+ compare instruction(EQ) + branch equal instruction. */ --+ --+ switch (code) -- { --- case REG: --- /* (mem (reg X)) --- => access location by using register, --- use "lbsi / lhsi" */ --- snprintf (pattern, sizeof (pattern), "l%csi\t%%0, %%1", size); --+ case GT: --+ case GE: --+ tmp = cmp_op0; --+ cmp_op0 = cmp_op1; --+ cmp_op1 = tmp; --+ new_code = swap_condition (new_code); -- break; --- --- case SYMBOL_REF: --- case CONST: --- /* (mem (symbol_ref X)) --- (mem (const (...))) --- => access global variables, --- use "lbsi.gp / lhsi.gp" */ --- operands[1] = XEXP (operands[1], 0); --- snprintf (pattern, sizeof (pattern), "l%csi.gp\t%%0, [ + %%1]", size); --+ case UNORDERED: --+ case LT: --+ case LE: --+ case EQ: -- break; --- --- case POST_INC: --- /* (mem (post_inc reg)) --- => access location by using register which will be post increment, --- use "lbsi.bi / lhsi.bi" */ --- snprintf (pattern, sizeof (pattern), --- "l%csi.bi\t%%0, %%1, %d", size, byte); --+ case ORDERED: --+ case NE: --+ new_code = reverse_condition (new_code); --+ reverse = 1; --+ break; --+ case UNGT: --+ case UNGE: --+ new_code = reverse_condition_maybe_unordered (new_code); --+ reverse = 1; -- break; --+ case UNLT: --+ case UNLE: --+ new_code = reverse_condition_maybe_unordered (new_code); --+ tmp = cmp_op0; --+ cmp_op0 = cmp_op1; --+ cmp_op1 = tmp; --+ new_code = swap_condition (new_code); --+ reverse = 1; --+ break; --+ default: --+ return; --+ } -- --- case POST_DEC: --- /* (mem (post_dec reg)) --- => access location by using register which will be post decrement, --- use "lbsi.bi / lhsi.bi" */ --- snprintf (pattern, sizeof (pattern), --- "l%csi.bi\t%%0, %%1, -%d", size, byte); --+ tmp_reg = gen_reg_rtx (SImode); --+ emit_insn (gen_rtx_SET (tmp_reg, --+ gen_rtx_fmt_ee (new_code, SImode, --+ cmp_op0, cmp_op1))); --+ --+ PUT_CODE (operands[0], reverse ? EQ : NE); --+ emit_insn (gen_cbranchsi4 (operands[0], tmp_reg, --+ const0_rtx, operands[3])); --+} --+ --+void --+nds32_expand_float_cstore (rtx *operands) --+{ --+ enum rtx_code code = GET_CODE (operands[1]); --+ enum rtx_code new_code = code; --+ enum machine_mode mode = GET_MODE (operands[2]); --+ --+ rtx cmp_op0 = operands[2]; --+ rtx cmp_op1 = operands[3]; --+ rtx tmp; --+ --+ /* Main Goal: Use compare instruction to store value. --+ --+ For example: --+ GT, GE: swap condition and swap operands. --+ reg_R = (reg_A > reg_B) --> fcmplt reg_R, reg_B, reg_A --+ reg_R = (reg_A >= reg_B) --> fcmple reg_R, reg_B, reg_A --+ --+ LT, LE, EQ: no need to change, it is already LT, LE, EQ. --+ reg_R = (reg_A < reg_B) --> fcmplt reg_R, reg_A, reg_B --+ reg_R = (reg_A <= reg_B) --> fcmple reg_R, reg_A, reg_B --+ reg_R = (reg_A == reg_B) --> fcmpeq reg_R, reg_A, reg_B --+ --+ ORDERED: reverse condition and using xor insturction to achieve 'ORDERED'. --+ reg_R = (reg_A != reg_B) --> fcmpun reg_R, reg_A, reg_B --+ xor reg_R, reg_R, const1_rtx --+ --+ NE: reverse condition and using xor insturction to achieve 'NE'. --+ reg_R = (reg_A != reg_B) --> fcmpeq reg_R, reg_A, reg_B --+ xor reg_R, reg_R, const1_rtx */ --+ switch (code) --+ { --+ case GT: --+ case GE: --+ tmp = cmp_op0; --+ cmp_op0 = cmp_op1; --+ cmp_op1 =tmp; --+ new_code = swap_condition (new_code); -- break; --+ case UNORDERED: --+ case LT: --+ case LE: --+ case EQ: --+ break; --+ case ORDERED: --+ if (mode == SFmode) --+ emit_insn (gen_cmpsf_un (operands[0], cmp_op0, cmp_op1)); --+ else --+ emit_insn (gen_cmpdf_un (operands[0], cmp_op0, cmp_op1)); -- --- case POST_MODIFY: --- switch (GET_CODE (XEXP (XEXP (code, 1), 1))) --+ emit_insn (gen_xorsi3 (operands[0], operands[0], const1_rtx)); --+ return; --+ case NE: --+ if (mode == SFmode) --+ emit_insn (gen_cmpsf_eq (operands[0], cmp_op0, cmp_op1)); --+ else --+ emit_insn (gen_cmpdf_eq (operands[0], cmp_op0, cmp_op1)); --+ --+ emit_insn (gen_xorsi3 (operands[0], operands[0], const1_rtx)); --+ return; --+ default: --+ return; --+ } --+ --+ emit_insn (gen_rtx_SET (operands[0], --+ gen_rtx_fmt_ee (new_code, SImode, --+ cmp_op0, cmp_op1))); --+} --+ --+enum nds32_expand_result_type --+nds32_expand_movcc (rtx *operands) --+{ --+ enum rtx_code code = GET_CODE (operands[1]); --+ enum rtx_code new_code = code; --+ enum machine_mode cmp0_mode = GET_MODE (XEXP (operands[1], 0)); --+ rtx cmp_op0 = XEXP (operands[1], 0); --+ rtx cmp_op1 = XEXP (operands[1], 1); --+ rtx tmp; --+ --+ if ((GET_CODE (operands[1]) == EQ || GET_CODE (operands[1]) == NE) --+ && XEXP (operands[1], 1) == const0_rtx) --+ { --+ /* If the operands[1] rtx is already (eq X 0) or (ne X 0), --+ we have gcc generate original template rtx. */ --+ return EXPAND_CREATE_TEMPLATE; --+ } --+ else if ((TARGET_FPU_SINGLE && cmp0_mode == SFmode) --+ || (TARGET_FPU_DOUBLE && cmp0_mode == DFmode)) --+ { --+ nds32_expand_float_movcc (operands); --+ } --+ else --+ { --+ /* Since there is only 'slt'(Set when Less Than) instruction for --+ comparison in Andes ISA, the major strategy we use here is to --+ convert conditional move into 'LT + EQ' or 'LT + NE' rtx combination. --+ We design constraints properly so that the reload phase will assist --+ to make one source operand to use same register as result operand. --+ Then we can use cmovz/cmovn to catch the other source operand --+ which has different register. */ --+ int reverse = 0; --+ --+ /* Main Goal: Use 'LT + EQ' or 'LT + NE' to target "then" part --+ Strategy : Reverse condition and swap comparison operands --+ --+ For example: --+ --+ a <= b ? P : Q (LE or LEU) --+ --> a > b ? Q : P (reverse condition) --+ --> b < a ? Q : P (swap comparison operands to achieve 'LT/LTU') --+ --+ a >= b ? P : Q (GE or GEU) --+ --> a < b ? Q : P (reverse condition to achieve 'LT/LTU') --+ --+ a < b ? P : Q (LT or LTU) --+ --> (NO NEED TO CHANGE, it is already 'LT/LTU') --+ --+ a > b ? P : Q (GT or GTU) --+ --> b < a ? P : Q (swap comparison operands to achieve 'LT/LTU') */ --+ switch (code) -- { --- case REG: --- case SUBREG: --- /* (mem (post_modify (reg) (plus (reg) (reg)))) --- => access location by using register which will be --- post modified with reg, --- use "lbs.bi/ lhs.bi" */ --- snprintf (pattern, sizeof (pattern), "l%cs.bi\t%%0, %%1", size); --+ case GE: case GEU: case LE: case LEU: --+ new_code = reverse_condition (code); --+ reverse = 1; -- break; --- case CONST_INT: --- /* (mem (post_modify (reg) (plus (reg) (const_int)))) --- => access location by using register which will be --- post modified with const_int, --- use "lbsi.bi/ lhsi.bi" */ --- snprintf (pattern, sizeof (pattern), "l%csi.bi\t%%0, %%1", size); --+ case EQ: --+ case NE: --+ /* no need to reverse condition */ -- break; -- default: --- abort (); --+ return EXPAND_FAIL; -- } --- break; -- --- case PLUS: --- switch (GET_CODE (XEXP (code, 1))) --+ /* For '>' comparison operator, we swap operands --+ so that we can have 'LT/LTU' operator. */ --+ if (new_code == GT || new_code == GTU) -- { --- case REG: --- case SUBREG: --- /* (mem (plus reg reg)) or (mem (plus (mult reg const_int) reg)) --- use "lbs / lhs" */ --- snprintf (pattern, sizeof (pattern), "l%cs\t%%0, %%1", size); --+ tmp = cmp_op0; --+ cmp_op0 = cmp_op1; --+ cmp_op1 = tmp; --+ --+ new_code = swap_condition (new_code); --+ } --+ --+ /* Use a temporary register to store slt/slts result. */ --+ tmp = gen_reg_rtx (SImode); --+ --+ if (new_code == EQ || new_code == NE) --+ { --+ emit_insn (gen_xorsi3 (tmp, cmp_op0, cmp_op1)); --+ /* tmp == 0 if cmp_op0 == cmp_op1. */ --+ operands[1] = gen_rtx_fmt_ee (new_code, VOIDmode, tmp, const0_rtx); --+ } --+ else --+ { --+ /* This emit_insn will create corresponding 'slt/slts' --+ insturction. */ --+ if (new_code == LT) --+ emit_insn (gen_slts_compare (tmp, cmp_op0, cmp_op1)); --+ else if (new_code == LTU) --+ emit_insn (gen_slt_compare (tmp, cmp_op0, cmp_op1)); --+ else --+ gcc_unreachable (); --+ --+ /* Change comparison semantic into (eq X 0) or (ne X 0) behavior --+ so that cmovz or cmovn will be matched later. --+ --+ For reverse condition cases, we want to create a semantic that: --+ (eq X 0) --> pick up "else" part --+ For normal cases, we want to create a semantic that: --+ (ne X 0) --> pick up "then" part --+ --+ Later we will have cmovz/cmovn instruction pattern to --+ match corresponding behavior and output instruction. */ --+ operands[1] = gen_rtx_fmt_ee (reverse ? EQ : NE, --+ VOIDmode, tmp, const0_rtx); --+ } --+ } --+ return EXPAND_CREATE_TEMPLATE; --+} --+ --+void --+nds32_expand_float_movcc (rtx *operands) --+{ --+ if ((GET_CODE (operands[1]) == EQ || GET_CODE (operands[1]) == NE) --+ && GET_MODE (XEXP (operands[1], 0)) == SImode --+ && XEXP (operands[1], 1) == const0_rtx) --+ { --+ /* If the operands[1] rtx is already (eq X 0) or (ne X 0), --+ we have gcc generate original template rtx. */ --+ return; --+ } --+ else --+ { --+ enum rtx_code code = GET_CODE (operands[1]); --+ enum rtx_code new_code = code; --+ enum machine_mode cmp0_mode = GET_MODE (XEXP (operands[1], 0)); --+ enum machine_mode cmp1_mode = GET_MODE (XEXP (operands[1], 1)); --+ rtx cmp_op0 = XEXP (operands[1], 0); --+ rtx cmp_op1 = XEXP (operands[1], 1); --+ rtx tmp; --+ --+ /* Compare instruction Operations: (cmp_op0 condition cmp_op1) ? 1 : 0, --+ when result is 1, and 'reverse' be set 1 for fcmovzs instructuin. */ --+ int reverse = 0; --+ --+ /* Main Goal: Use cmpare instruction + conditional move instruction. --+ Strategy : swap condition and swap comparison operands. --+ --+ For example: --+ a > b ? P : Q (GT) --+ --> a < b ? Q : P (swap condition) --+ --> b < a ? Q : P (swap comparison operands to achieve 'GT') --+ --+ a >= b ? P : Q (GE) --+ --> a <= b ? Q : P (swap condition) --+ --> b <= a ? Q : P (swap comparison operands to achieve 'GE') --+ --+ a < b ? P : Q (LT) --+ --> (NO NEED TO CHANGE, it is already 'LT') --+ --+ a >= b ? P : Q (LE) --+ --> (NO NEED TO CHANGE, it is already 'LE') --+ --+ a == b ? P : Q (EQ) --+ --> (NO NEED TO CHANGE, it is already 'EQ') */ --+ --+ switch (code) --+ { --+ case GT: --+ case GE: --+ tmp = cmp_op0; --+ cmp_op0 = cmp_op1; --+ cmp_op1 =tmp; --+ new_code = swap_condition (new_code); -- break; --- case CONST_INT: --- /* (mem (plus reg const_int)) --- => access location by adding one register with const_int, --- use "lbsi / lhsi" */ --- snprintf (pattern, sizeof (pattern), "l%csi\t%%0, %%1", size); --+ case UNORDERED: --+ case LT: --+ case LE: --+ case EQ: --+ break; --+ case ORDERED: --+ case NE: --+ reverse = 1; --+ new_code = reverse_condition (new_code); --+ break; --+ case UNGT: --+ case UNGE: --+ new_code = reverse_condition_maybe_unordered (new_code); --+ reverse = 1; --+ break; --+ case UNLT: --+ case UNLE: --+ new_code = reverse_condition_maybe_unordered (new_code); --+ tmp = cmp_op0; --+ cmp_op0 = cmp_op1; --+ cmp_op1 = tmp; --+ new_code = swap_condition (new_code); --+ reverse = 1; -- break; -- default: --- abort (); --+ return; -- } --- break; -- --- case LO_SUM: --- operands[2] = XEXP (code, 1); --- operands[1] = XEXP (code, 0); --- snprintf (pattern, sizeof (pattern), --- "l%csi\t%%0, [%%1 + lo12(%%2)]", size); --- break; --+ /* Use a temporary register to store fcmpxxs result. */ --+ tmp = gen_reg_rtx (SImode); --+ --+ /* Create float compare instruction for SFmode and DFmode, --+ other MODE using cstoresi create compare instruction. */ --+ if ((cmp0_mode == DFmode || cmp0_mode == SFmode) --+ && (cmp1_mode == DFmode || cmp1_mode == SFmode)) --+ { --+ /* This emit_insn create corresponding float compare instruction */ --+ emit_insn (gen_rtx_SET (tmp, --+ gen_rtx_fmt_ee (new_code, SImode, --+ cmp_op0, cmp_op1))); --+ } --+ else --+ { --+ /* This emit_insn using cstoresi create corresponding --+ compare instruction */ --+ PUT_CODE (operands[1], new_code); --+ emit_insn (gen_cstoresi4 (tmp, operands[1], --+ cmp_op0, cmp_op1)); --+ } --+ /* operands[1] crete corresponding condition move instruction --+ for fcmovzs and fcmovns. */ --+ operands[1] = gen_rtx_fmt_ee (reverse ? EQ : NE, --+ VOIDmode, tmp, const0_rtx); --+ } --+} --+ --+void --+nds32_emit_push_fpr_callee_saved (int base_offset) --+{ --+ rtx fpu_insn; --+ rtx reg, mem; --+ unsigned int regno = cfun->machine->callee_saved_first_fpr_regno; --+ unsigned int last_fpr = cfun->machine->callee_saved_last_fpr_regno; --+ --+ while (regno <= last_fpr) --+ { --+ /* Handling two registers, using fsdi instruction. */ --+ reg = gen_rtx_REG (DFmode, regno); --+ mem = gen_frame_mem (DFmode, plus_constant (Pmode, --+ stack_pointer_rtx, --+ base_offset)); --+ base_offset += 8; --+ regno += 2; --+ fpu_insn = emit_move_insn (mem, reg); --+ RTX_FRAME_RELATED_P (fpu_insn) = 1; --+ } --+} --+ --+void --+nds32_emit_pop_fpr_callee_saved (int gpr_padding_size) --+{ --+ rtx fpu_insn; --+ rtx reg, mem, addr; --+ rtx dwarf, adjust_sp_rtx; --+ unsigned int regno = cfun->machine->callee_saved_first_fpr_regno; --+ unsigned int last_fpr = cfun->machine->callee_saved_last_fpr_regno; --+ int padding = 0; --+ --+ while (regno <= last_fpr) --+ { --+ /* Handling two registers, using fldi.bi instruction. */ --+ if ((regno + 1) >= last_fpr) --+ padding = gpr_padding_size; --+ --+ reg = gen_rtx_REG (DFmode, (regno)); --+ addr = gen_rtx_POST_MODIFY (Pmode, stack_pointer_rtx, --+ gen_rtx_PLUS (Pmode, stack_pointer_rtx, --+ GEN_INT (8 + padding))); --+ mem = gen_frame_mem (DFmode, addr); --+ regno += 2; --+ fpu_insn = emit_move_insn (reg, mem); --+ --+ adjust_sp_rtx = --+ gen_rtx_SET (stack_pointer_rtx, --+ plus_constant (Pmode, stack_pointer_rtx, --+ 8 + padding)); --+ --+ dwarf = alloc_reg_note (REG_CFA_RESTORE, reg, NULL_RTX); --+ /* Tell gcc we adjust SP in this insn. */ --+ dwarf = alloc_reg_note (REG_CFA_ADJUST_CFA, copy_rtx (adjust_sp_rtx), --+ dwarf); --+ RTX_FRAME_RELATED_P (fpu_insn) = 1; --+ REG_NOTES (fpu_insn) = dwarf; --+ } --+} --+ --+void --+nds32_emit_v3pop_fpr_callee_saved (int base) --+{ --+ int fpu_base_addr = base; --+ int regno; --+ rtx fpu_insn; --+ rtx reg, mem; --+ rtx dwarf; --+ --+ regno = cfun->machine->callee_saved_first_fpr_regno; --+ while (regno <= cfun->machine->callee_saved_last_fpr_regno) --+ { --+ /* Handling two registers, using fldi instruction. */ --+ reg = gen_rtx_REG (DFmode, regno); --+ mem = gen_frame_mem (DFmode, plus_constant (Pmode, --+ stack_pointer_rtx, --+ fpu_base_addr)); --+ fpu_base_addr += 8; --+ regno += 2; --+ fpu_insn = emit_move_insn (reg, mem); --+ dwarf = alloc_reg_note (REG_CFA_RESTORE, reg, NULL_RTX); --+ RTX_FRAME_RELATED_P (fpu_insn) = 1; --+ REG_NOTES (fpu_insn) = dwarf; --+ } --+} --+ --+enum nds32_expand_result_type --+nds32_expand_extv (rtx *operands) --+{ --+ gcc_assert (CONST_INT_P (operands[2]) && CONST_INT_P (operands[3])); --+ HOST_WIDE_INT width = INTVAL (operands[2]); --+ HOST_WIDE_INT bitpos = INTVAL (operands[3]); --+ rtx dst = operands[0]; --+ rtx src = operands[1]; --+ --+ if (MEM_P (src) --+ && width == 32 --+ && (bitpos % BITS_PER_UNIT) == 0 --+ && GET_MODE_BITSIZE (GET_MODE (dst)) == width) --+ { --+ rtx newmem = adjust_address (src, GET_MODE (dst), --+ bitpos / BITS_PER_UNIT); --+ --+ rtx base_addr = force_reg (Pmode, XEXP (newmem, 0)); --+ --+ emit_insn (gen_unaligned_loadsi (dst, base_addr)); --+ --+ return EXPAND_DONE; --+ } --+ return EXPAND_FAIL; --+} --+ --+enum nds32_expand_result_type --+nds32_expand_insv (rtx *operands) --+{ --+ gcc_assert (CONST_INT_P (operands[1]) && CONST_INT_P (operands[2])); --+ HOST_WIDE_INT width = INTVAL (operands[1]); --+ HOST_WIDE_INT bitpos = INTVAL (operands[2]); --+ rtx dst = operands[0]; --+ rtx src = operands[3]; --+ --+ if (MEM_P (dst) --+ && width == 32 --+ && (bitpos % BITS_PER_UNIT) == 0 --+ && GET_MODE_BITSIZE (GET_MODE (src)) == width) --+ { --+ rtx newmem = adjust_address (dst, GET_MODE (src), --+ bitpos / BITS_PER_UNIT); --+ --+ rtx base_addr = force_reg (Pmode, XEXP (newmem, 0)); --+ --+ emit_insn (gen_unaligned_storesi (base_addr, src)); --+ --+ return EXPAND_DONE; --+ } --+ return EXPAND_FAIL; --+} --+ --+/* ------------------------------------------------------------------------ */ --+ --+/* PART 3: Auxiliary function for output asm template. */ --+ --+/* Function to generate PC relative jump table. --+ Refer to nds32.md for more details. --+ --+ The following is the sample for the case that diff value --+ can be presented in '.short' size. --+ --+ addi $r1, $r1, -(case_lower_bound) --+ slti $ta, $r1, (case_number) --+ beqz $ta, .L_skip_label --+ --+ la $ta, .L35 ! get jump table address --+ lh $r1, [$ta + $r1 << 1] ! load symbol diff from jump table entry --+ addi $ta, $r1, $ta --+ jr5 $ta --+ --+ ! jump table entry --+ L35: --+ .short .L25-.L35 --+ .short .L26-.L35 --+ .short .L27-.L35 --+ .short .L28-.L35 --+ .short .L29-.L35 --+ .short .L30-.L35 --+ .short .L31-.L35 --+ .short .L32-.L35 --+ .short .L33-.L35 --+ .short .L34-.L35 */ --+const char * --+nds32_output_casesi_pc_relative (rtx *operands) --+{ --+ enum machine_mode mode; --+ rtx diff_vec; --+ --+ diff_vec = PATTERN (NEXT_INSN (as_a (operands[1]))); --+ --+ gcc_assert (GET_CODE (diff_vec) == ADDR_DIFF_VEC); --+ --+ /* Step C: "t <-- operands[1]". */ --+ if (flag_pic) --+ { --+ output_asm_insn ("sethi\t$ta, hi20(%l1@GOTOFF)", operands); --+ output_asm_insn ("ori\t$ta, $ta, lo12(%l1@GOTOFF)", operands); --+ output_asm_insn ("add\t$ta, $ta, $gp", operands); --+ } --+ else --+ output_asm_insn ("la\t$ta, %l1", operands); --+ --+ /* Get the mode of each element in the difference vector. */ --+ mode = GET_MODE (diff_vec); -- --+ /* Step D: "z <-- (mem (plus (operands[0] << m) t))", --+ where m is 0, 1, or 2 to load address-diff value from table. */ --+ switch (mode) --+ { --+ case QImode: --+ output_asm_insn ("lb\t%2, [$ta + %0 << 0]", operands); --+ break; --+ case HImode: --+ output_asm_insn ("lh\t%2, [$ta + %0 << 1]", operands); --+ break; --+ case SImode: --+ output_asm_insn ("lw\t%2, [$ta + %0 << 2]", operands); --+ break; -- default: --- abort (); --+ gcc_unreachable (); -- } -- --- output_asm_insn (pattern, operands); --- return ""; --+ /* Step E: "t <-- z + t". --+ Add table label_ref with address-diff value to --+ obtain target case address. */ --+ output_asm_insn ("add\t$ta, %2, $ta", operands); --+ --+ /* Step F: jump to target with register t. */ --+ if (TARGET_16_BIT) --+ return "jr5\t$ta"; --+ else --+ return "jr\t$ta"; -- } -- ---/* Function to output stack push operation. --- We need to deal with normal stack push multiple or stack v3push. */ --+/* Function to generate normal jump table. */ -- const char * ---nds32_output_stack_push (rtx par_rtx) --+nds32_output_casesi (rtx *operands) -- { --- /* A string pattern for output_asm_insn(). */ --- char pattern[100]; --- /* The operands array which will be used in output_asm_insn(). */ --- rtx operands[3]; --- /* Pick up varargs first regno and last regno for further use. */ --- int rb_va_args = cfun->machine->va_args_first_regno; --- int re_va_args = cfun->machine->va_args_last_regno; --- int last_argument_regno = NDS32_FIRST_GPR_REGNUM --- + NDS32_MAX_GPR_REGS_FOR_ARGS --- - 1; --- /* Pick up callee-saved first regno and last regno for further use. */ --- int rb_callee_saved = cfun->machine->callee_saved_first_gpr_regno; --- int re_callee_saved = cfun->machine->callee_saved_last_gpr_regno; --+ /* Step C: "t <-- operands[1]". */ --+ if (flag_pic) --+ { --+ output_asm_insn ("sethi\t$ta, hi20(%l1@GOTOFF)", operands); --+ output_asm_insn ("ori\t$ta, $ta, lo12(%l1@GOTOFF)", operands); --+ output_asm_insn ("add\t$ta, $ta, $gp", operands); --+ } --+ else --+ output_asm_insn ("la\t$ta, %l1", operands); -- --- /* First we need to check if we are pushing argument registers not used --- for the named arguments. If so, we have to create 'smw.adm' (push.s) --- instruction. */ --- if (reg_mentioned_p (gen_rtx_REG (SImode, last_argument_regno), par_rtx)) --+ /* Step D: "z <-- (mem (plus (operands[0] << 2) t))". */ --+ output_asm_insn ("lw\t%2, [$ta + %0 << 2]", operands); --+ --+ /* No need to perform Step E, which is only used for --+ pc relative jump table. */ --+ --+ /* Step F: jump to target with register z. */ --+ if (TARGET_16_BIT) --+ return "jr5\t%2"; --+ else --+ return "jr\t%2"; --+} --+ --+ --+/* Function to return memory format. */ --+enum nds32_16bit_address_type --+nds32_mem_format (rtx op) --+{ --+ enum machine_mode mode_test; --+ int val; --+ int regno; --+ --+ if (!TARGET_16_BIT) --+ return ADDRESS_NOT_16BIT_FORMAT; --+ --+ mode_test = GET_MODE (op); --+ --+ op = XEXP (op, 0); --+ --+ /* 45 format. */ --+ if (GET_CODE (op) == REG --+ && ((mode_test == SImode) || (mode_test == SFmode))) --+ return ADDRESS_REG; --+ --+ /* 333 format for QI/HImode. */ --+ if (GET_CODE (op) == REG && (REGNO (op) < R8_REGNUM)) --+ return ADDRESS_LO_REG_IMM3U; --+ --+ /* post_inc 333 format. */ --+ if ((GET_CODE (op) == POST_INC) --+ && ((mode_test == SImode) || (mode_test == SFmode))) -- { --- /* Set operands[0] and operands[1]. */ --- operands[0] = gen_rtx_REG (SImode, rb_va_args); --- operands[1] = gen_rtx_REG (SImode, re_va_args); --- /* Create assembly code pattern: "Rb, Re, { }". */ --- snprintf (pattern, sizeof (pattern), "push.s\t%s", "%0, %1, { }"); --- /* We use output_asm_insn() to output assembly code by ourself. */ --- output_asm_insn (pattern, operands); --- return ""; --+ regno = REGNO(XEXP (op, 0)); --+ --+ if (regno < 8) --+ return ADDRESS_POST_INC_LO_REG_IMM3U; --+ } --+ --+ /* post_inc 333 format. */ --+ if ((GET_CODE (op) == POST_MODIFY) --+ && ((mode_test == SImode) || (mode_test == SFmode)) --+ && (REG_P (XEXP (XEXP (op, 1), 0))) --+ && (CONST_INT_P (XEXP (XEXP (op, 1), 1)))) --+ { --+ regno = REGNO (XEXP (XEXP (op, 1), 0)); --+ val = INTVAL (XEXP (XEXP (op, 1), 1)); --+ if (regno < 8 && val > 0 && val < 32) --+ return ADDRESS_POST_MODIFY_LO_REG_IMM3U; -- } -- --- /* If we step here, we are going to do v3push or multiple push operation. */ --+ if ((GET_CODE (op) == PLUS) --+ && (GET_CODE (XEXP (op, 0)) == REG) --+ && (GET_CODE (XEXP (op, 1)) == CONST_INT)) --+ { --+ val = INTVAL (XEXP (op, 1)); --+ --+ regno = REGNO(XEXP (op, 0)); --+ --+ if (regno > 8 --+ && regno != SP_REGNUM --+ && regno != FP_REGNUM) --+ return ADDRESS_NOT_16BIT_FORMAT; --+ --+ switch (mode_test) --+ { --+ case QImode: --+ /* 333 format. */ --+ if (val >= 0 && val < 8 && regno < 8) --+ return ADDRESS_LO_REG_IMM3U; --+ break; --+ --+ case HImode: --+ /* 333 format. */ --+ if (val >= 0 && val < 16 && (val % 2 == 0) && regno < 8) --+ return ADDRESS_LO_REG_IMM3U; --+ break; --+ --+ case SImode: --+ case SFmode: --+ case DFmode: --+ /* r8 imply fe format. */ --+ if ((regno == 8) && --+ (val >= -128 && val <= -4 && (val % 4 == 0))) --+ return ADDRESS_R8_IMM7U; --+ /* fp imply 37 format. */ --+ if ((regno == FP_REGNUM) && --+ (val >= 0 && val < 512 && (val % 4 == 0))) --+ return ADDRESS_FP_IMM7U; --+ /* sp imply 37 format. */ --+ else if ((regno == SP_REGNUM) && --+ (val >= 0 && val < 512 && (val % 4 == 0))) --+ return ADDRESS_SP_IMM7U; --+ /* 333 format. */ --+ else if (val >= 0 && val < 32 && (val % 4 == 0) && regno < 8) --+ return ADDRESS_LO_REG_IMM3U; --+ break; --+ --+ default: --+ break; --+ } --+ } --+ --+ return ADDRESS_NOT_16BIT_FORMAT; --+} --+ --+/* Output 16-bit store. */ --+const char * --+nds32_output_16bit_store (rtx *operands, int byte) --+{ --+ char pattern[100]; --+ char size; --+ rtx code = XEXP (operands[0], 0); --+ --+ size = nds32_byte_to_size (byte); --+ --+ switch (nds32_mem_format (operands[0])) --+ { --+ case ADDRESS_REG: --+ operands[0] = code; --+ output_asm_insn ("swi450\t%1, [%0]", operands); --+ break; --+ case ADDRESS_LO_REG_IMM3U: --+ snprintf (pattern, sizeof (pattern), "s%ci333\t%%1, %%0", size); --+ output_asm_insn (pattern, operands); --+ break; --+ case ADDRESS_POST_INC_LO_REG_IMM3U: --+ snprintf (pattern, sizeof (pattern), "swi333.bi\t%%1, %%0, 4"); --+ output_asm_insn (pattern, operands); --+ break; --+ case ADDRESS_POST_MODIFY_LO_REG_IMM3U: --+ snprintf (pattern, sizeof (pattern), "swi333.bi\t%%1, %%0"); --+ output_asm_insn (pattern, operands); --+ break; --+ case ADDRESS_FP_IMM7U: --+ output_asm_insn ("swi37\t%1, %0", operands); --+ break; --+ case ADDRESS_SP_IMM7U: --+ /* Get immediate value and set back to operands[1]. */ --+ operands[0] = XEXP (code, 1); --+ output_asm_insn ("swi37.sp\t%1, [ + (%0)]", operands); --+ break; --+ default: --+ break; --+ } --+ --+ return ""; --+} --+ --+/* Output 16-bit load. */ --+const char * --+nds32_output_16bit_load (rtx *operands, int byte) --+{ --+ char pattern[100]; --+ unsigned char size; --+ rtx code = XEXP (operands[1], 0); --+ --+ size = nds32_byte_to_size (byte); --+ --+ switch (nds32_mem_format (operands[1])) --+ { --+ case ADDRESS_REG: --+ operands[1] = code; --+ output_asm_insn ("lwi450\t%0, [%1]", operands); --+ break; --+ case ADDRESS_LO_REG_IMM3U: --+ snprintf (pattern, sizeof (pattern), "l%ci333\t%%0, %%1", size); --+ output_asm_insn (pattern, operands); --+ break; --+ case ADDRESS_POST_INC_LO_REG_IMM3U: --+ snprintf (pattern, sizeof (pattern), "lwi333.bi\t%%0, %%1, 4"); --+ output_asm_insn (pattern, operands); --+ break; --+ case ADDRESS_POST_MODIFY_LO_REG_IMM3U: --+ snprintf (pattern, sizeof (pattern), "lwi333.bi\t%%0, %%1"); --+ output_asm_insn (pattern, operands); --+ break; --+ case ADDRESS_R8_IMM7U: --+ output_asm_insn ("lwi45.fe\t%0, %e1", operands); --+ break; --+ case ADDRESS_FP_IMM7U: --+ output_asm_insn ("lwi37\t%0, %1", operands); --+ break; --+ case ADDRESS_SP_IMM7U: --+ /* Get immediate value and set back to operands[0]. */ --+ operands[1] = XEXP (code, 1); --+ output_asm_insn ("lwi37.sp\t%0, [ + (%1)]", operands); --+ break; --+ default: --+ break; --+ } --+ --+ return ""; --+} --+ --+/* Output 32-bit store. */ --+const char * --+nds32_output_32bit_store (rtx *operands, int byte) --+{ --+ char pattern[100]; --+ unsigned char size; --+ rtx code = XEXP (operands[0], 0); --+ --+ size = nds32_byte_to_size (byte); --+ --+ switch (GET_CODE (code)) --+ { --+ case REG: --+ /* (mem (reg X)) --+ => access location by using register, --+ use "sbi / shi / swi" */ --+ snprintf (pattern, sizeof (pattern), "s%ci\t%%1, %%0", size); --+ break; --+ --+ case SYMBOL_REF: --+ case CONST: --+ /* (mem (symbol_ref X)) --+ (mem (const (...))) --+ => access global variables, --+ use "sbi.gp / shi.gp / swi.gp" */ --+ operands[0] = XEXP (operands[0], 0); --+ snprintf (pattern, sizeof (pattern), "s%ci.gp\t%%1, [ + %%0]", size); --+ break; --+ --+ case POST_INC: --+ /* (mem (post_inc reg)) --+ => access location by using register which will be post increment, --+ use "sbi.bi / shi.bi / swi.bi" */ --+ snprintf (pattern, sizeof (pattern), --+ "s%ci.bi\t%%1, %%0, %d", size, byte); --+ break; --+ --+ case POST_DEC: --+ /* (mem (post_dec reg)) --+ => access location by using register which will be post decrement, --+ use "sbi.bi / shi.bi / swi.bi" */ --+ snprintf (pattern, sizeof (pattern), --+ "s%ci.bi\t%%1, %%0, -%d", size, byte); --+ break; --+ --+ case POST_MODIFY: --+ switch (GET_CODE (XEXP (XEXP (code, 1), 1))) --+ { --+ case REG: --+ case SUBREG: --+ /* (mem (post_modify (reg) (plus (reg) (reg)))) --+ => access location by using register which will be --+ post modified with reg, --+ use "sb.bi/ sh.bi / sw.bi" */ --+ snprintf (pattern, sizeof (pattern), "s%c.bi\t%%1, %%0", size); --+ break; --+ case CONST_INT: --+ /* (mem (post_modify (reg) (plus (reg) (const_int)))) --+ => access location by using register which will be --+ post modified with const_int, --+ use "sbi.bi/ shi.bi / swi.bi" */ --+ snprintf (pattern, sizeof (pattern), "s%ci.bi\t%%1, %%0", size); --+ break; --+ default: --+ abort (); --+ } --+ break; --+ --+ case PLUS: --+ switch (GET_CODE (XEXP (code, 1))) --+ { --+ case REG: --+ case SUBREG: --+ /* (mem (plus reg reg)) or (mem (plus (mult reg const_int) reg)) --+ => access location by adding two registers, --+ use "sb / sh / sw" */ --+ snprintf (pattern, sizeof (pattern), "s%c\t%%1, %%0", size); --+ break; --+ case CONST_INT: --+ /* (mem (plus reg const_int)) --+ => access location by adding one register with const_int, --+ use "sbi / shi / swi" */ --+ snprintf (pattern, sizeof (pattern), "s%ci\t%%1, %%0", size); --+ break; --+ default: --+ abort (); --+ } --+ break; --+ --+ case LO_SUM: --+ operands[2] = XEXP (code, 1); --+ operands[0] = XEXP (code, 0); --+ snprintf (pattern, sizeof (pattern), --+ "s%ci\t%%1, [%%0 + lo12(%%2)]", size); --+ break; --+ --+ default: --+ abort (); --+ } --+ --+ output_asm_insn (pattern, operands); --+ return ""; --+} --+ --+/* Output 32-bit load. */ --+const char * --+nds32_output_32bit_load (rtx *operands, int byte) --+{ --+ char pattern[100]; --+ unsigned char size; --+ rtx code; --+ --+ code = XEXP (operands[1], 0); --+ --+ size = nds32_byte_to_size (byte); --+ --+ switch (GET_CODE (code)) --+ { --+ case REG: --+ /* (mem (reg X)) --+ => access location by using register, --+ use "lbi / lhi / lwi" */ --+ snprintf (pattern, sizeof (pattern), "l%ci\t%%0, %%1", size); --+ break; --+ --+ case SYMBOL_REF: --+ case CONST: --+ /* (mem (symbol_ref X)) --+ (mem (const (...))) --+ => access global variables, --+ use "lbi.gp / lhi.gp / lwi.gp" */ --+ operands[1] = XEXP (operands[1], 0); --+ snprintf (pattern, sizeof (pattern), "l%ci.gp\t%%0, [ + %%1]", size); --+ break; --+ --+ case POST_INC: --+ /* (mem (post_inc reg)) --+ => access location by using register which will be post increment, --+ use "lbi.bi / lhi.bi / lwi.bi" */ --+ snprintf (pattern, sizeof (pattern), --+ "l%ci.bi\t%%0, %%1, %d", size, byte); --+ break; --+ --+ case POST_DEC: --+ /* (mem (post_dec reg)) --+ => access location by using register which will be post decrement, --+ use "lbi.bi / lhi.bi / lwi.bi" */ --+ snprintf (pattern, sizeof (pattern), --+ "l%ci.bi\t%%0, %%1, -%d", size, byte); --+ break; --+ --+ case POST_MODIFY: --+ switch (GET_CODE (XEXP (XEXP (code, 1), 1))) --+ { --+ case REG: --+ case SUBREG: --+ /* (mem (post_modify (reg) (plus (reg) (reg)))) --+ => access location by using register which will be --+ post modified with reg, --+ use "lb.bi/ lh.bi / lw.bi" */ --+ snprintf (pattern, sizeof (pattern), "l%c.bi\t%%0, %%1", size); --+ break; --+ case CONST_INT: --+ /* (mem (post_modify (reg) (plus (reg) (const_int)))) --+ => access location by using register which will be --+ post modified with const_int, --+ use "lbi.bi/ lhi.bi / lwi.bi" */ --+ snprintf (pattern, sizeof (pattern), "l%ci.bi\t%%0, %%1", size); --+ break; --+ default: --+ abort (); --+ } --+ break; --+ --+ case PLUS: --+ switch (GET_CODE (XEXP (code, 1))) --+ { --+ case REG: --+ case SUBREG: --+ /* (mem (plus reg reg)) or (mem (plus (mult reg const_int) reg)) --+ use "lb / lh / lw" */ --+ snprintf (pattern, sizeof (pattern), "l%c\t%%0, %%1", size); --+ break; --+ case CONST_INT: --+ /* (mem (plus reg const_int)) --+ => access location by adding one register with const_int, --+ use "lbi / lhi / lwi" */ --+ snprintf (pattern, sizeof (pattern), "l%ci\t%%0, %%1", size); --+ break; --+ default: --+ abort (); --+ } --+ break; --+ --+ case LO_SUM: --+ operands[2] = XEXP (code, 1); --+ operands[1] = XEXP (code, 0); --+ snprintf (pattern, sizeof (pattern), --+ "l%ci\t%%0, [%%1 + lo12(%%2)]", size); --+ break; --+ --+ default: --+ abort (); --+ } --+ --+ output_asm_insn (pattern, operands); --+ return ""; --+} --+ --+/* Output 32-bit load with signed extension. */ --+const char * --+nds32_output_32bit_load_se (rtx *operands, int byte) --+{ --+ char pattern[100]; --+ unsigned char size; --+ rtx code; --+ --+ code = XEXP (operands[1], 0); --+ --+ size = nds32_byte_to_size (byte); --+ --+ switch (GET_CODE (code)) --+ { --+ case REG: --+ /* (mem (reg X)) --+ => access location by using register, --+ use "lbsi / lhsi" */ --+ snprintf (pattern, sizeof (pattern), "l%csi\t%%0, %%1", size); --+ break; --+ --+ case SYMBOL_REF: --+ case CONST: --+ /* (mem (symbol_ref X)) --+ (mem (const (...))) --+ => access global variables, --+ use "lbsi.gp / lhsi.gp" */ --+ operands[1] = XEXP (operands[1], 0); --+ snprintf (pattern, sizeof (pattern), "l%csi.gp\t%%0, [ + %%1]", size); --+ break; --+ --+ case POST_INC: --+ /* (mem (post_inc reg)) --+ => access location by using register which will be post increment, --+ use "lbsi.bi / lhsi.bi" */ --+ snprintf (pattern, sizeof (pattern), --+ "l%csi.bi\t%%0, %%1, %d", size, byte); --+ break; --+ --+ case POST_DEC: --+ /* (mem (post_dec reg)) --+ => access location by using register which will be post decrement, --+ use "lbsi.bi / lhsi.bi" */ --+ snprintf (pattern, sizeof (pattern), --+ "l%csi.bi\t%%0, %%1, -%d", size, byte); --+ break; --+ --+ case POST_MODIFY: --+ switch (GET_CODE (XEXP (XEXP (code, 1), 1))) --+ { --+ case REG: --+ case SUBREG: --+ /* (mem (post_modify (reg) (plus (reg) (reg)))) --+ => access location by using register which will be --+ post modified with reg, --+ use "lbs.bi/ lhs.bi" */ --+ snprintf (pattern, sizeof (pattern), "l%cs.bi\t%%0, %%1", size); --+ break; --+ case CONST_INT: --+ /* (mem (post_modify (reg) (plus (reg) (const_int)))) --+ => access location by using register which will be --+ post modified with const_int, --+ use "lbsi.bi/ lhsi.bi" */ --+ snprintf (pattern, sizeof (pattern), "l%csi.bi\t%%0, %%1", size); --+ break; --+ default: --+ abort (); --+ } --+ break; --+ --+ case PLUS: --+ switch (GET_CODE (XEXP (code, 1))) --+ { --+ case REG: --+ case SUBREG: --+ /* (mem (plus reg reg)) or (mem (plus (mult reg const_int) reg)) --+ use "lbs / lhs" */ --+ snprintf (pattern, sizeof (pattern), "l%cs\t%%0, %%1", size); --+ break; --+ case CONST_INT: --+ /* (mem (plus reg const_int)) --+ => access location by adding one register with const_int, --+ use "lbsi / lhsi" */ --+ snprintf (pattern, sizeof (pattern), "l%csi\t%%0, %%1", size); --+ break; --+ default: --+ abort (); --+ } --+ break; --+ --+ case LO_SUM: --+ operands[2] = XEXP (code, 1); --+ operands[1] = XEXP (code, 0); --+ snprintf (pattern, sizeof (pattern), --+ "l%csi\t%%0, [%%1 + lo12(%%2)]", size); --+ break; --+ --+ default: --+ abort (); --+ } --+ --+ output_asm_insn (pattern, operands); --+ return ""; --+} --+ --+/* Function to output stack push operation. --+ We need to deal with normal stack push multiple or stack v3push. */ --+const char * --+nds32_output_stack_push (rtx par_rtx) --+{ --+ /* A string pattern for output_asm_insn(). */ --+ char pattern[100]; --+ /* The operands array which will be used in output_asm_insn(). */ --+ rtx operands[3]; --+ /* Pick up varargs first regno and last regno for further use. */ --+ int rb_va_args = cfun->machine->va_args_first_regno; --+ int re_va_args = cfun->machine->va_args_last_regno; --+ int last_argument_regno = NDS32_FIRST_GPR_REGNUM --+ + NDS32_MAX_GPR_REGS_FOR_ARGS --+ - 1; --+ /* Pick up first and last eh data regno for further use. */ --+ int rb_eh_data = cfun->machine->eh_return_data_first_regno; --+ int re_eh_data = cfun->machine->eh_return_data_last_regno; --+ int first_eh_data_regno = EH_RETURN_DATA_REGNO (0); --+ /* Pick up callee-saved first regno and last regno for further use. */ --+ int rb_callee_saved = cfun->machine->callee_saved_first_gpr_regno; --+ int re_callee_saved = cfun->machine->callee_saved_last_gpr_regno; --+ --+ /* First we need to check if we are pushing argument registers not used --+ for the named arguments. If so, we have to create 'smw.adm' (push.s) --+ instruction. */ --+ if (reg_mentioned_p (gen_rtx_REG (SImode, last_argument_regno), par_rtx)) --+ { --+ /* Set operands[0] and operands[1]. */ --+ operands[0] = gen_rtx_REG (SImode, rb_va_args); --+ operands[1] = gen_rtx_REG (SImode, re_va_args); --+ /* Create assembly code pattern: "Rb, Re, { }". */ --+ snprintf (pattern, sizeof (pattern), "push.s\t%s", "%0, %1, { }"); --+ /* We use output_asm_insn() to output assembly code by ourself. */ --+ output_asm_insn (pattern, operands); --+ return ""; --+ } --+ --+ /* If last_argument_regno is not mentioned in par_rtx, we can confirm that --+ we do not need to push argument registers for variadic function. --+ But we still need to check if we need to push exception handling --+ data registers. */ --+ if (reg_mentioned_p (gen_rtx_REG (SImode, first_eh_data_regno), par_rtx)) --+ { --+ /* Set operands[0] and operands[1]. */ --+ operands[0] = gen_rtx_REG (SImode, rb_eh_data); --+ operands[1] = gen_rtx_REG (SImode, re_eh_data); --+ /* Create assembly code pattern: "Rb, Re, { }". */ --+ snprintf (pattern, sizeof (pattern), "push.s\t%s", "%0, %1, { }"); --+ /* We use output_asm_insn() to output assembly code by ourself. */ --+ output_asm_insn (pattern, operands); --+ return ""; --+ } --+ --+ /* If we step here, we are going to do v3push or multiple push operation. */ --+ --+ /* Refer to nds32.h, where we comment when push25/pop25 are available. */ --+ if (NDS32_V3PUSH_AVAILABLE_P) --+ { --+ /* For stack v3push: --+ operands[0]: Re --+ operands[1]: imm8u */ --+ --+ /* This variable is to check if 'push25 Re,imm8u' is available. */ --+ int sp_adjust; --+ --+ /* Set operands[0]. */ --+ operands[0] = gen_rtx_REG (SImode, re_callee_saved); --+ --+ /* Check if we can generate 'push25 Re,imm8u', --+ otherwise, generate 'push25 Re,0'. */ --+ sp_adjust = cfun->machine->local_size --+ + cfun->machine->out_args_size --+ + cfun->machine->callee_saved_area_gpr_padding_bytes --+ + cfun->machine->callee_saved_fpr_regs_size; --+ if (satisfies_constraint_Iu08 (GEN_INT (sp_adjust)) --+ && NDS32_DOUBLE_WORD_ALIGN_P (sp_adjust)) --+ operands[1] = GEN_INT (sp_adjust); --+ else --+ { --+ /* Allocate callee saved fpr space. */ --+ if (cfun->machine->callee_saved_first_fpr_regno != SP_REGNUM) --+ { --+ sp_adjust = cfun->machine->callee_saved_area_gpr_padding_bytes --+ + cfun->machine->callee_saved_fpr_regs_size; --+ operands[1] = GEN_INT (sp_adjust); --+ } --+ else --+ { --+ operands[1] = GEN_INT (0); --+ } --+ } --+ --+ /* Create assembly code pattern. */ --+ snprintf (pattern, sizeof (pattern), "push25\t%%0, %%1"); --+ } --+ else --+ { --+ /* For normal stack push multiple: --+ operands[0]: Rb --+ operands[1]: Re --+ operands[2]: En4 */ --+ --+ /* This variable is used to check if we only need to generate En4 field. --+ As long as Rb==Re=SP_REGNUM, we set this variable to 1. */ --+ int push_en4_only_p = 0; --+ --+ /* Set operands[0] and operands[1]. */ --+ operands[0] = gen_rtx_REG (SImode, rb_callee_saved); --+ operands[1] = gen_rtx_REG (SImode, re_callee_saved); --+ --+ /* 'smw.adm $sp,[$sp],$sp,0' means push nothing. */ --+ if (!cfun->machine->fp_size --+ && !cfun->machine->gp_size --+ && !cfun->machine->lp_size --+ && REGNO (operands[0]) == SP_REGNUM --+ && REGNO (operands[1]) == SP_REGNUM) --+ { --+ /* No need to generate instruction. */ --+ return ""; --+ } --+ else --+ { --+ /* If Rb==Re=SP_REGNUM, we only need to generate En4 field. */ --+ if (REGNO (operands[0]) == SP_REGNUM --+ && REGNO (operands[1]) == SP_REGNUM) --+ push_en4_only_p = 1; --+ --+ /* Create assembly code pattern. --+ We need to handle the form: "Rb, Re, { $fp $gp $lp }". */ --+ snprintf (pattern, sizeof (pattern), --+ "push.s\t%s{%s%s%s }", --+ push_en4_only_p ? "" : "%0, %1, ", --+ cfun->machine->fp_size ? " $fp" : "", --+ cfun->machine->gp_size ? " $gp" : "", --+ cfun->machine->lp_size ? " $lp" : ""); --+ } --+ } --+ --+ /* We use output_asm_insn() to output assembly code by ourself. */ --+ output_asm_insn (pattern, operands); --+ return ""; --+} --+ --+/* Function to output stack pop operation. --+ We need to deal with normal stack pop multiple or stack v3pop. */ --+const char * --+nds32_output_stack_pop (rtx par_rtx ATTRIBUTE_UNUSED) --+{ --+ /* A string pattern for output_asm_insn(). */ --+ char pattern[100]; --+ /* The operands array which will be used in output_asm_insn(). */ --+ rtx operands[3]; --+ /* Pick up first and last eh data regno for further use. */ --+ int rb_eh_data = cfun->machine->eh_return_data_first_regno; --+ int re_eh_data = cfun->machine->eh_return_data_last_regno; --+ int first_eh_data_regno = EH_RETURN_DATA_REGNO (0); --+ /* Pick up callee-saved first regno and last regno for further use. */ --+ int rb_callee_saved = cfun->machine->callee_saved_first_gpr_regno; --+ int re_callee_saved = cfun->machine->callee_saved_last_gpr_regno; --+ --+ /* We need to check if we need to push exception handling --+ data registers. */ --+ if (reg_mentioned_p (gen_rtx_REG (SImode, first_eh_data_regno), par_rtx)) --+ { --+ /* Set operands[0] and operands[1]. */ --+ operands[0] = gen_rtx_REG (SImode, rb_eh_data); --+ operands[1] = gen_rtx_REG (SImode, re_eh_data); --+ /* Create assembly code pattern: "Rb, Re, { }". */ --+ snprintf (pattern, sizeof (pattern), "pop.s\t%s", "%0, %1, { }"); --+ /* We use output_asm_insn() to output assembly code by ourself. */ --+ output_asm_insn (pattern, operands); --+ return ""; --+ } --+ --+ /* If we step here, we are going to do v3pop or multiple pop operation. */ --+ --+ /* Refer to nds32.h, where we comment when push25/pop25 are available. */ --+ if (NDS32_V3PUSH_AVAILABLE_P) --+ { --+ /* For stack v3pop: --+ operands[0]: Re --+ operands[1]: imm8u */ --+ --+ /* This variable is to check if 'pop25 Re,imm8u' is available. */ --+ int sp_adjust; --+ --+ /* Set operands[0]. */ --+ operands[0] = gen_rtx_REG (SImode, re_callee_saved); --+ --+ /* Check if we can generate 'pop25 Re,imm8u', --+ otherwise, generate 'pop25 Re,0'. --+ We have to consider alloca issue as well. --+ If the function does call alloca(), the stack pointer is not fixed. --+ In that case, we cannot use 'pop25 Re,imm8u' directly. --+ We have to caculate stack pointer from frame pointer --+ and then use 'pop25 Re,0'. */ --+ sp_adjust = cfun->machine->local_size --+ + cfun->machine->out_args_size --+ + cfun->machine->callee_saved_area_gpr_padding_bytes --+ + cfun->machine->callee_saved_fpr_regs_size; --+ if (satisfies_constraint_Iu08 (GEN_INT (sp_adjust)) --+ && NDS32_DOUBLE_WORD_ALIGN_P (sp_adjust) --+ && !cfun->calls_alloca) --+ operands[1] = GEN_INT (sp_adjust); --+ else --+ { --+ if (cfun->machine->callee_saved_first_fpr_regno != SP_REGNUM) --+ { --+ /* If has fpr need to restore, the $sp on callee saved fpr --+ position, so we need to consider gpr pading bytes and --+ callee saved fpr size. */ --+ sp_adjust = cfun->machine->callee_saved_area_gpr_padding_bytes --+ + cfun->machine->callee_saved_fpr_regs_size; --+ operands[1] = GEN_INT (sp_adjust); --+ } --+ else --+ { --+ operands[1] = GEN_INT (0); --+ } --+ } --+ --+ /* Create assembly code pattern. */ --+ snprintf (pattern, sizeof (pattern), "pop25\t%%0, %%1"); --+ } --+ else --+ { --+ /* For normal stack pop multiple: --+ operands[0]: Rb --+ operands[1]: Re --+ operands[2]: En4 */ --+ --+ /* This variable is used to check if we only need to generate En4 field. --+ As long as Rb==Re=SP_REGNUM, we set this variable to 1. */ --+ int pop_en4_only_p = 0; --+ --+ /* Set operands[0] and operands[1]. */ --+ operands[0] = gen_rtx_REG (SImode, rb_callee_saved); --+ operands[1] = gen_rtx_REG (SImode, re_callee_saved); --+ --+ /* 'lmw.bim $sp,[$sp],$sp,0' means pop nothing. */ --+ if (!cfun->machine->fp_size --+ && !cfun->machine->gp_size --+ && !cfun->machine->lp_size --+ && REGNO (operands[0]) == SP_REGNUM --+ && REGNO (operands[1]) == SP_REGNUM) --+ { --+ /* No need to generate instruction. */ --+ return ""; --+ } --+ else --+ { --+ /* If Rb==Re=SP_REGNUM, we only need to generate En4 field. */ --+ if (REGNO (operands[0]) == SP_REGNUM --+ && REGNO (operands[1]) == SP_REGNUM) --+ pop_en4_only_p = 1; --+ --+ /* Create assembly code pattern. --+ We need to handle the form: "Rb, Re, { $fp $gp $lp }". */ --+ snprintf (pattern, sizeof (pattern), --+ "pop.s\t%s{%s%s%s }", --+ pop_en4_only_p ? "" : "%0, %1, ", --+ cfun->machine->fp_size ? " $fp" : "", --+ cfun->machine->gp_size ? " $gp" : "", --+ cfun->machine->lp_size ? " $lp" : ""); --+ } --+ } --+ --+ /* We use output_asm_insn() to output assembly code by ourself. */ --+ output_asm_insn (pattern, operands); --+ return ""; --+} --+ --+/* Function to output return operation. */ --+const char * --+nds32_output_return (void) --+{ --+ /* A string pattern for output_asm_insn(). */ --+ char pattern[100]; --+ /* The operands array which will be used in output_asm_insn(). */ --+ rtx operands[2]; --+ /* For stack v3pop: --+ operands[0]: Re --+ operands[1]: imm8u */ --+ int re_callee_saved = cfun->machine->callee_saved_last_gpr_regno; --+ int sp_adjust; --+ --+ /* Set operands[0]. */ --+ operands[0] = gen_rtx_REG (SImode, re_callee_saved); --+ --+ /* Check if we can generate 'pop25 Re,imm8u', --+ otherwise, generate 'pop25 Re,0'. --+ We have to consider alloca issue as well. --+ If the function does call alloca(), the stack pointer is not fixed. --+ In that case, we cannot use 'pop25 Re,imm8u' directly. --+ We have to caculate stack pointer from frame pointer --+ and then use 'pop25 Re,0'. */ --+ sp_adjust = cfun->machine->local_size --+ + cfun->machine->out_args_size --+ + cfun->machine->callee_saved_area_gpr_padding_bytes --+ + cfun->machine->callee_saved_fpr_regs_size; --+ if (satisfies_constraint_Iu08 (GEN_INT (sp_adjust)) --+ && NDS32_DOUBLE_WORD_ALIGN_P (sp_adjust) --+ && !cfun->calls_alloca) --+ operands[1] = GEN_INT (sp_adjust); --+ else --+ operands[1] = GEN_INT (0); --+ --+ /* Create assembly code pattern. */ --+ snprintf (pattern, sizeof (pattern), "pop25\t%%0, %%1"); --+ /* We use output_asm_insn() to output assembly code by ourself. */ --+ output_asm_insn (pattern, operands); --+ return ""; --+} --+ --+ --+/* output a float load instruction */ --+const char * --+nds32_output_float_load (rtx *operands) --+{ --+ char buff[100]; --+ const char *pattern; --+ rtx addr, addr_op0, addr_op1; --+ int dp = GET_MODE_SIZE (GET_MODE (operands[0])) == 8; --+ addr = XEXP (operands[1], 0); --+ switch (GET_CODE (addr)) --+ { --+ case REG: --+ pattern = "fl%ci\t%%0, %%1"; --+ break; --+ --+ case PLUS: --+ addr_op0 = XEXP (addr, 0); --+ addr_op1 = XEXP (addr, 1); --+ --+ if (REG_P (addr_op0) && REG_P (addr_op1)) --+ pattern = "fl%c\t%%0, %%1"; --+ else if (REG_P (addr_op0) && CONST_INT_P (addr_op1)) --+ pattern = "fl%ci\t%%0, %%1"; --+ else if (GET_CODE (addr_op0) == MULT && REG_P (addr_op1) --+ && REG_P (XEXP (addr_op0, 0)) --+ && CONST_INT_P (XEXP (addr_op0, 1))) --+ pattern = "fl%c\t%%0, %%1"; --+ else --+ gcc_unreachable (); --+ break; --+ --+ case POST_MODIFY: --+ addr_op0 = XEXP (addr, 0); --+ addr_op1 = XEXP (addr, 1); --+ --+ if (REG_P (addr_op0) && GET_CODE (addr_op1) == PLUS --+ && REG_P (XEXP (addr_op1, 1))) --+ pattern = "fl%c.bi\t%%0, %%1"; --+ else if (REG_P (addr_op0) && GET_CODE (addr_op1) == PLUS --+ && CONST_INT_P (XEXP (addr_op1, 1))) --+ pattern = "fl%ci.bi\t%%0, %%1"; --+ else --+ gcc_unreachable (); --+ break; --+ --+ case POST_INC: --+ if (REG_P (XEXP (addr, 0))) --+ { --+ if (dp) --+ pattern = "fl%ci.bi\t%%0, %%1, 8"; --+ else --+ pattern = "fl%ci.bi\t%%0, %%1, 4"; --+ } --+ else --+ gcc_unreachable (); --+ break; --+ --+ case POST_DEC: --+ if (REG_P (XEXP (addr, 0))) --+ { --+ if (dp) --+ pattern = "fl%ci.bi\t%%0, %%1, -8"; --+ else --+ pattern = "fl%ci.bi\t%%0, %%1, -4"; --+ } --+ else --+ gcc_unreachable (); --+ break; --+ --+ default: --+ gcc_unreachable (); --+ } --+ --+ sprintf (buff, pattern, dp ? 'd' : 's'); --+ output_asm_insn (buff, operands); --+ return ""; --+} --+ --+/* output a float store instruction */ --+const char * --+nds32_output_float_store (rtx *operands) --+{ --+ char buff[100]; --+ const char *pattern; --+ rtx addr, addr_op0, addr_op1; --+ int dp = GET_MODE_SIZE (GET_MODE (operands[0])) == 8; --+ addr = XEXP (operands[0], 0); --+ switch (GET_CODE (addr)) --+ { --+ case REG: --+ pattern = "fs%ci\t%%1, %%0"; --+ break; --+ --+ case PLUS: --+ addr_op0 = XEXP (addr, 0); --+ addr_op1 = XEXP (addr, 1); --+ --+ if (REG_P (addr_op0) && REG_P (addr_op1)) --+ pattern = "fs%c\t%%1, %%0"; --+ else if (REG_P (addr_op0) && CONST_INT_P (addr_op1)) --+ pattern = "fs%ci\t%%1, %%0"; --+ else if (GET_CODE (addr_op0) == MULT && REG_P (addr_op1) --+ && REG_P (XEXP (addr_op0, 0)) --+ && CONST_INT_P (XEXP (addr_op0, 1))) --+ pattern = "fs%c\t%%1, %%0"; --+ else --+ gcc_unreachable (); --+ break; --+ --+ case POST_MODIFY: --+ addr_op0 = XEXP (addr, 0); --+ addr_op1 = XEXP (addr, 1); --+ --+ if (REG_P (addr_op0) && GET_CODE (addr_op1) == PLUS --+ && REG_P (XEXP (addr_op1, 1))) --+ pattern = "fs%c.bi\t%%1, %%0"; --+ else if (REG_P (addr_op0) && GET_CODE (addr_op1) == PLUS --+ && CONST_INT_P (XEXP (addr_op1, 1))) --+ pattern = "fs%ci.bi\t%%1, %%0"; --+ else --+ gcc_unreachable (); --+ break; --+ --+ case POST_INC: --+ if (REG_P (XEXP (addr, 0))) --+ { --+ if (dp) --+ pattern = "fs%ci.bi\t%%1, %%0, 8"; --+ else --+ pattern = "fs%ci.bi\t%%1, %%0, 4"; --+ } --+ else --+ gcc_unreachable (); --+ break; --+ --+ case POST_DEC: --+ if (REG_P (XEXP (addr, 0))) --+ { --+ if (dp) --+ pattern = "fs%ci.bi\t%%1, %%0, -8"; --+ else --+ pattern = "fs%ci.bi\t%%1, %%0, -4"; --+ } --+ else --+ gcc_unreachable (); --+ break; --+ --+ default: --+ gcc_unreachable (); --+ } --+ --+ sprintf (buff, pattern, dp ? 'd' : 's'); --+ output_asm_insn (buff, operands); --+ return ""; --+} --+ --+const char * --+nds32_output_smw_single_word (rtx *operands) --+{ --+ char buff[100]; --+ unsigned regno; --+ int enable4; --+ bool update_base_p; --+ rtx base_addr = operands[0]; --+ rtx base_reg; --+ rtx otherops[2]; --+ --+ if (REG_P (XEXP (base_addr, 0))) --+ { --+ update_base_p = false; --+ base_reg = XEXP (base_addr, 0); --+ } --+ else --+ { --+ update_base_p = true; --+ base_reg = XEXP (XEXP (base_addr, 0), 0); --+ } --+ --+ const char *update_base = update_base_p ? "m" : ""; --+ --+ regno = REGNO (operands[1]); --+ --+ otherops[0] = base_reg; --+ otherops[1] = operands[1]; --+ --+ if (regno >= 28) --+ { --+ enable4 = nds32_regno_to_enable4 (regno); --+ sprintf (buff, "smw.bi%s\t$sp, [%%0], $sp, %x", update_base, enable4); --+ } --+ else --+ { --+ sprintf (buff, "smw.bi%s\t%%1, [%%0], %%1", update_base); --+ } --+ output_asm_insn (buff, otherops); --+ return ""; --+} --+ --+const char * --+nds32_output_smw_double_word (rtx *operands) --+{ --+ char buff[100]; --+ unsigned regno; --+ int enable4; --+ bool update_base_p; --+ rtx base_addr = operands[0]; --+ rtx base_reg; --+ rtx otherops[3]; --+ --+ if (REG_P (XEXP (base_addr, 0))) --+ { --+ update_base_p = false; --+ base_reg = XEXP (base_addr, 0); --+ } --+ else --+ { --+ update_base_p = true; --+ base_reg = XEXP (XEXP (base_addr, 0), 0); --+ } --+ --+ const char *update_base = update_base_p ? "m" : ""; --+ --+ regno = REGNO (operands[1]); --+ --+ otherops[0] = base_reg; --+ otherops[1] = operands[1]; --+ otherops[2] = gen_rtx_REG (SImode, REGNO (operands[1]) + 1);; --+ --+ if (regno >= 28) --+ { --+ enable4 = nds32_regno_to_enable4 (regno) --+ | nds32_regno_to_enable4 (regno + 1); --+ sprintf (buff, "smw.bi%s\t$sp, [%%0], $sp, %x", update_base, enable4); --+ } --+ else if (regno == 27) --+ { --+ enable4 = nds32_regno_to_enable4 (regno + 1); --+ sprintf (buff, "smw.bi%s\t%%1, [%%0], %%1, %x", update_base, enable4); --+ } --+ else --+ { --+ sprintf (buff, "smw.bi%s\t%%1, [%%0], %%2", update_base); --+ } --+ output_asm_insn (buff, otherops); --+ return ""; --+} --+ --+ --+const char * --+nds32_output_lmw_single_word (rtx *operands) --+{ --+ char buff[100]; --+ unsigned regno; --+ bool update_base_p; --+ int enable4; --+ rtx base_addr = operands[1]; --+ rtx base_reg; --+ rtx otherops[2]; --+ --+ if (REG_P (XEXP (base_addr, 0))) --+ { --+ update_base_p = false; --+ base_reg = XEXP (base_addr, 0); --+ } --+ else --+ { --+ update_base_p = true; --+ base_reg = XEXP (XEXP (base_addr, 0), 0); --+ } --+ --+ const char *update_base = update_base_p ? "m" : ""; --+ --+ regno = REGNO (operands[0]); --+ --+ otherops[0] = operands[0]; --+ otherops[1] = base_reg; --+ --+ if (regno >= 28) --+ { --+ enable4 = nds32_regno_to_enable4 (regno); --+ sprintf (buff, "lmw.bi%s\t$sp, [%%1], $sp, %x", update_base, enable4); --+ } --+ else --+ { --+ sprintf (buff, "lmw.bi%s\t%%0, [%%1], %%0", update_base); --+ } --+ output_asm_insn (buff, otherops); --+ return ""; --+} --+ --+void --+nds32_expand_unaligned_load (rtx *operands, enum machine_mode mode) --+{ --+ /* Initial memory offset. */ --+ int offset = WORDS_BIG_ENDIAN ? GET_MODE_SIZE (mode) - 1 : 0; --+ int offset_adj = WORDS_BIG_ENDIAN ? -1 : 1; --+ /* Initial register shift byte. */ --+ int shift = 0; --+ /* The first load byte instruction is not the same. */ --+ int width = GET_MODE_SIZE (mode) - 1; --+ rtx mem[2]; --+ rtx reg[2]; --+ rtx sub_reg; --+ rtx temp_reg, temp_sub_reg; --+ int num_reg; --+ --+ /* Generating a series of load byte instructions. --+ The first load byte instructions and other --+ load byte instructions are not the same. like: --+ First: --+ lbi reg0, [mem] --+ zeh reg0, reg0 --+ Second: --+ lbi temp_reg, [mem + offset] --+ sll temp_reg, (8 * shift) --+ ior reg0, temp_reg --+ --+ lbi temp_reg, [mem + (offset + 1)] --+ sll temp_reg, (8 * (shift + 1)) --+ ior reg0, temp_reg */ --+ --+ temp_reg = gen_reg_rtx (SImode); --+ temp_sub_reg = gen_lowpart (QImode, temp_reg); --+ --+ if (mode == DImode) --+ { --+ /* Load doubleword, we need two registers to access. */ --+ reg[0] = nds32_di_low_part_subreg (operands[0]); --+ reg[1] = nds32_di_high_part_subreg (operands[0]); --+ /* A register only store 4 byte. */ --+ width = GET_MODE_SIZE (SImode) - 1; --+ } --+ else --+ { --+ if (VECTOR_MODE_P (mode)) --+ reg[0] = gen_reg_rtx (SImode); --+ else --+ reg[0] = operands[0]; --+ } --+ --+ for (num_reg = (mode == DImode) ? 2 : 1; num_reg > 0; num_reg--) --+ { --+ sub_reg = gen_lowpart (QImode, reg[0]); --+ mem[0] = gen_rtx_MEM (QImode, plus_constant (Pmode, operands[1], offset)); --+ --+ /* Generating the first part instructions. --+ lbi reg0, [mem] --+ zeh reg0, reg0 */ --+ emit_move_insn (sub_reg, mem[0]); --+ emit_insn (gen_zero_extendqisi2 (reg[0], sub_reg)); --+ --+ while (width > 0) --+ { --+ offset = offset + offset_adj; --+ shift++; --+ width--; --+ --+ mem[1] = gen_rtx_MEM (QImode, plus_constant (Pmode, --+ operands[1], --+ offset)); --+ /* Generating the second part instructions. --+ lbi temp_reg, [mem + offset] --+ sll temp_reg, (8 * shift) --+ ior reg0, temp_reg */ --+ emit_move_insn (temp_sub_reg, mem[1]); --+ emit_insn (gen_ashlsi3 (temp_reg, temp_reg, --+ GEN_INT (shift * 8))); --+ emit_insn (gen_iorsi3 (reg[0], reg[0], temp_reg)); --+ } --+ --+ if (mode == DImode) --+ { --+ /* Using the second register to load memory information. */ --+ reg[0] = reg[1]; --+ shift = 0; --+ width = GET_MODE_SIZE (SImode) - 1; --+ offset = offset + offset_adj; --+ } --+ } --+ if (VECTOR_MODE_P (mode)) --+ convert_move (operands[0], reg[0], false); --+} --+ --+void --+nds32_expand_unaligned_store (rtx *operands, enum machine_mode mode) --+{ --+ /* Initial memory offset. */ --+ int offset = WORDS_BIG_ENDIAN ? GET_MODE_SIZE (mode) - 1 : 0; --+ int offset_adj = WORDS_BIG_ENDIAN ? -1 : 1; --+ /* Initial register shift byte. */ --+ int shift = 0; --+ /* The first load byte instruction is not the same. */ --+ int width = GET_MODE_SIZE (mode) - 1; --+ rtx mem[2]; --+ rtx reg[2]; --+ rtx sub_reg; --+ rtx temp_reg, temp_sub_reg; --+ int num_reg; --+ --+ /* Generating a series of store byte instructions. --+ The first store byte instructions and other --+ load byte instructions are not the same. like: --+ First: --+ sbi reg0, [mem + 0] --+ Second: --+ srli temp_reg, reg0, (8 * shift) --+ sbi temp_reg, [mem + offset] */ --+ --+ temp_reg = gen_reg_rtx (SImode); --+ temp_sub_reg = gen_lowpart (QImode, temp_reg); --+ --+ if (mode == DImode) --+ { --+ /* Load doubleword, we need two registers to access. */ --+ reg[0] = nds32_di_low_part_subreg (operands[1]); --+ reg[1] = nds32_di_high_part_subreg (operands[1]); --+ /* A register only store 4 byte. */ --+ width = GET_MODE_SIZE (SImode) - 1; --+ } --+ else --+ { --+ if (VECTOR_MODE_P (mode)) --+ { --+ reg[0] = gen_reg_rtx (SImode); --+ convert_move (reg[0], operands[1], false); --+ } --+ else --+ reg[0] = operands[1]; --+ } --+ --+ for (num_reg = (mode == DImode) ? 2 : 1; num_reg > 0; num_reg--) --+ { --+ sub_reg = gen_lowpart (QImode, reg[0]); --+ mem[0] = gen_rtx_MEM (QImode, plus_constant (Pmode, operands[0], offset)); --+ --+ /* Generating the first part instructions. --+ sbi reg0, [mem + 0] */ --+ emit_move_insn (mem[0], sub_reg); --+ --+ while (width > 0) --+ { --+ offset = offset + offset_adj; --+ shift++; --+ width--; --+ --+ mem[1] = gen_rtx_MEM (QImode, plus_constant (Pmode, --+ operands[0], --+ offset)); --+ /* Generating the second part instructions. --+ srli temp_reg, reg0, (8 * shift) --+ sbi temp_reg, [mem + offset] */ --+ emit_insn (gen_lshrsi3 (temp_reg, reg[0], --+ GEN_INT (shift * 8))); --+ emit_move_insn (mem[1], temp_sub_reg); --+ } --+ --+ if (mode == DImode) --+ { --+ /* Using the second register to load memory information. */ --+ reg[0] = reg[1]; --+ shift = 0; --+ width = GET_MODE_SIZE (SImode) - 1; --+ offset = offset + offset_adj; --+ } --+ } --+} --+ --+/* Using multiple load/store instruction to output doubleword instruction. */ --+const char * --+nds32_output_double (rtx *operands, bool load_p) --+{ --+ char pattern[100]; --+ int reg = load_p ? 0 : 1; --+ int mem = load_p ? 1 : 0; --+ rtx otherops[3]; --+ rtx addr = XEXP (operands[mem], 0); --+ --+ otherops[0] = gen_rtx_REG (SImode, REGNO (operands[reg])); --+ otherops[1] = gen_rtx_REG (SImode, REGNO (operands[reg]) + 1); --+ --+ if (GET_CODE (addr) == POST_INC) --+ { --+ /* (mem (post_inc (reg))) */ --+ otherops[2] = XEXP (addr, 0); --+ snprintf (pattern, sizeof (pattern), --+ "%cmw.bim\t%%0, [%%2], %%1, 0", load_p ? 'l' : 's'); --+ } --+ else --+ { --+ /* (mem (reg)) */ --+ otherops[2] = addr; --+ snprintf (pattern, sizeof (pattern), --+ "%cmw.bi\t%%0, [%%2], %%1, 0", load_p ? 'l' : 's'); --+ --+ } --+ --+ output_asm_insn (pattern, otherops); --+ return ""; --+} --+ --+const char * --+nds32_output_cbranchsi4_equality_zero (rtx_insn *insn, rtx *operands) --+{ --+ enum rtx_code code; --+ bool long_jump_p = false; --+ --+ code = GET_CODE (operands[0]); --+ --+ /* This zero-comparison conditional branch has two forms: --+ 32-bit instruction => beqz/bnez imm16s << 1 --+ 16-bit instruction => beqzs8/bnezs8/beqz38/bnez38 imm8s << 1 --+ --+ For 32-bit case, --+ we assume it is always reachable. (but check range -65500 ~ 65500) --+ --+ For 16-bit case, --+ it must satisfy { 255 >= (label - pc) >= -256 } condition. --+ However, since the $pc for nds32 is at the beginning of the instruction, --+ we should leave some length space for current insn. --+ So we use range -250 ~ 250. */ --+ --+ switch (get_attr_length (insn)) --+ { --+ case 8: --+ long_jump_p = true; --+ /* fall through */ --+ case 2: --+ if (which_alternative == 0) --+ { --+ /* constraint: t */ --+ /* bzs8 .L0 --+ or --+ bzs8 .LCB0 --+ j .L0 --+ .LCB0: --+ */ --+ output_cond_branch_compare_zero (code, "s8", long_jump_p, --+ operands, true); --+ return ""; --+ } --+ else if (which_alternative == 1) --+ { --+ /* constraint: l */ --+ /* bz38 $r0, .L0 --+ or --+ bz38 $r0, .LCB0 --+ j .L0 --+ .LCB0: --+ */ --+ output_cond_branch_compare_zero (code, "38", long_jump_p, --+ operands, false); --+ return ""; --+ } --+ else --+ { --+ /* constraint: r */ --+ /* For which_alternative==2, it should not be here. */ --+ gcc_unreachable (); --+ } --+ case 10: --+ /* including constraints: t, l, and r */ --+ long_jump_p = true; --+ /* fall through */ --+ case 4: --+ /* including constraints: t, l, and r */ --+ output_cond_branch_compare_zero (code, "", long_jump_p, operands, false); --+ return ""; --+ --+ default: --+ gcc_unreachable (); --+ } --+} --+ --+const char * --+nds32_output_cbranchsi4_equality_reg (rtx_insn *insn, rtx *operands) --+{ --+ enum rtx_code code; --+ bool long_jump_p, r5_p; --+ int insn_length; --+ --+ insn_length = get_attr_length (insn); --+ --+ long_jump_p = (insn_length == 10 || insn_length == 8) ? true : false; --+ r5_p = (insn_length == 2 || insn_length == 8) ? true : false; --+ --+ code = GET_CODE (operands[0]); --+ --+ /* This register-comparison conditional branch has one form: --+ 32-bit instruction => beq/bne imm14s << 1 --+ --+ For 32-bit case, --+ we assume it is always reachable. (but check range -16350 ~ 16350). */ --+ --+ switch (code) --+ { --+ case EQ: --+ case NE: --+ output_cond_branch (code, "", r5_p, long_jump_p, operands); --+ return ""; --+ --+ default: --+ gcc_unreachable (); --+ } --+} --+ --+const char * --+nds32_output_cbranchsi4_equality_reg_or_const_int (rtx_insn *insn, --+ rtx *operands) --+{ --+ enum rtx_code code; --+ bool long_jump_p, r5_p; --+ int insn_length; --+ --+ insn_length = get_attr_length (insn); --+ --+ long_jump_p = (insn_length == 10 || insn_length == 8) ? true : false; --+ r5_p = (insn_length == 2 || insn_length == 8) ? true : false; --+ --+ code = GET_CODE (operands[0]); --+ --+ /* This register-comparison conditional branch has one form: --+ 32-bit instruction => beq/bne imm14s << 1 --+ 32-bit instruction => beqc/bnec imm8s << 1 --+ --+ For 32-bit case, we assume it is always reachable. --+ (but check range -16350 ~ 16350 and -250 ~ 250). */ --+ --+ switch (code) --+ { --+ case EQ: --+ case NE: --+ if (which_alternative == 2) --+ { --+ /* r, Is11 */ --+ /* bc */ --+ output_cond_branch (code, "c", r5_p, long_jump_p, operands); --+ } --+ else --+ { --+ /* r, r */ --+ /* v, r */ --+ output_cond_branch (code, "", r5_p, long_jump_p, operands); --+ } --+ return ""; --+ default: --+ gcc_unreachable (); --+ } --+} --+ --+const char * --+nds32_output_cbranchsi4_greater_less_zero (rtx_insn *insn, rtx *operands) --+{ --+ enum rtx_code code; --+ bool long_jump_p; --+ int insn_length; --+ --+ insn_length = get_attr_length (insn); --+ --+ gcc_assert (insn_length == 4 || insn_length == 10); --+ --+ long_jump_p = (insn_length == 10) ? true : false; --+ --+ code = GET_CODE (operands[0]); --+ --+ /* This zero-greater-less-comparison conditional branch has one form: --+ 32-bit instruction => bgtz/bgez/bltz/blez imm16s << 1 --+ --+ For 32-bit case, we assume it is always reachable. --+ (but check range -65500 ~ 65500). */ --+ --+ switch (code) --+ { --+ case GT: --+ case GE: --+ case LT: --+ case LE: --+ output_cond_branch_compare_zero (code, "", long_jump_p, operands, false); --+ break; --+ default: --+ gcc_unreachable (); --+ } --+ return ""; --+} --+ --+const char * --+nds32_output_unpkd8 (rtx output, rtx input, --+ rtx high_idx_rtx, rtx low_idx_rtx, --+ bool signed_p) --+{ --+ char pattern[100]; --+ rtx output_operands[2]; --+ HOST_WIDE_INT high_idx, low_idx; --+ high_idx = INTVAL (high_idx_rtx); --+ low_idx = INTVAL (low_idx_rtx); --+ --+ gcc_assert (high_idx >= 0 && high_idx <= 3); --+ gcc_assert (low_idx >= 0 && low_idx <= 3); --+ --+ /* We only have 10, 20, 30 and 31. */ --+ if ((low_idx != 0 || high_idx == 0) && --+ !(low_idx == 1 && high_idx == 3)) --+ return "#"; --+ --+ char sign_char = signed_p ? 's' : 'z'; --+ --+ sprintf (pattern, --+ "%cunpkd8" HOST_WIDE_INT_PRINT_DEC HOST_WIDE_INT_PRINT_DEC "\t%%0, %%1", --+ sign_char, high_idx, low_idx); --+ output_operands[0] = output; --+ output_operands[1] = input; --+ output_asm_insn (pattern, output_operands); --+ return ""; --+} --+ --+/* Return true if SYMBOL_REF X binds locally. */ --+ --+static bool --+nds32_symbol_binds_local_p (const_rtx x) --+{ --+ return (SYMBOL_REF_DECL (x) --+ ? targetm.binds_local_p (SYMBOL_REF_DECL (x)) --+ : SYMBOL_REF_LOCAL_P (x)); --+} --+ --+const char * --+nds32_output_call (rtx insn, rtx *operands, rtx symbol, const char *long_call, --+ const char *call, bool align_p) --+{ --+ char pattern[100]; --+ bool noreturn_p; --+ --+ if (nds32_long_call_p (symbol)) --+ strcpy (pattern, long_call); --+ else --+ strcpy (pattern, call); --+ --+ if (flag_pic && CONSTANT_P (symbol) --+ && !nds32_symbol_binds_local_p (symbol)) --+ strcat (pattern, "@PLT"); --+ --+ if (align_p) --+ strcat (pattern, "\n\t.align 2"); --+ --+ noreturn_p = find_reg_note (insn, REG_NORETURN, NULL_RTX) != NULL_RTX; --+ --+ if (noreturn_p) --+ { --+ if (TARGET_16_BIT) --+ strcat (pattern, "\n\tnop16"); --+ else --+ strcat (pattern, "\n\tnop"); --+ } --+ --+ output_asm_insn (pattern, operands); --+ return ""; --+} --+ --+bool --+nds32_need_split_sms_p (rtx in0_idx0, rtx in1_idx0, --+ rtx in0_idx1, rtx in1_idx1) --+{ --+ /* smds or smdrs. */ --+ if (INTVAL (in0_idx0) == INTVAL (in1_idx0) --+ && INTVAL (in0_idx1) == INTVAL (in1_idx1) --+ && INTVAL (in0_idx0) != INTVAL (in0_idx1)) --+ return false; --+ --+ /* smxds. */ --+ if (INTVAL (in0_idx0) != INTVAL (in0_idx1) --+ && INTVAL (in1_idx0) != INTVAL (in1_idx1)) --+ return false; --+ --+ return true; --+} --+ --+const char * --+nds32_output_sms (rtx in0_idx0, rtx in1_idx0, --+ rtx in0_idx1, rtx in1_idx1) --+{ --+ if (nds32_need_split_sms_p (in0_idx0, in1_idx0, --+ in0_idx1, in1_idx1)) --+ return "#"; --+ /* out = in0[in0_idx0] * in1[in1_idx0] - in0[in0_idx1] * in1[in1_idx1] */ --+ --+ /* smds or smdrs. */ --+ if (INTVAL (in0_idx0) == INTVAL (in1_idx0) --+ && INTVAL (in0_idx1) == INTVAL (in1_idx1) --+ && INTVAL (in0_idx0) != INTVAL (in0_idx1)) --+ { --+ if (INTVAL (in0_idx0) == 0) --+ { --+ if (TARGET_BIG_ENDIAN) --+ return "smds\t%0, %1, %2"; --+ else --+ return "smdrs\t%0, %1, %2"; --+ } --+ else --+ { --+ if (TARGET_BIG_ENDIAN) --+ return "smdrs\t%0, %1, %2"; --+ else --+ return "smds\t%0, %1, %2"; --+ } --+ } --+ --+ if (INTVAL (in0_idx0) != INTVAL (in0_idx1) --+ && INTVAL (in1_idx0) != INTVAL (in1_idx1)) --+ { --+ if (INTVAL (in0_idx0) == 1) --+ { --+ if (TARGET_BIG_ENDIAN) --+ return "smxds\t%0, %2, %1"; --+ else --+ return "smxds\t%0, %1, %2"; --+ } --+ else --+ { --+ if (TARGET_BIG_ENDIAN) --+ return "smxds\t%0, %1, %2"; --+ else --+ return "smxds\t%0, %2, %1"; --+ } --+ } --+ --+ gcc_unreachable (); --+ return ""; --+} --+ --+void --+nds32_split_sms (rtx out, rtx in0, rtx in1, --+ rtx in0_idx0, rtx in1_idx0, --+ rtx in0_idx1, rtx in1_idx1) --+{ --+ rtx result0 = gen_reg_rtx (SImode); --+ rtx result1 = gen_reg_rtx (SImode); --+ emit_insn (gen_mulhisi3v (result0, in0, in1, --+ in0_idx0, in1_idx0)); --+ emit_insn (gen_mulhisi3v (result1, in0, in1, --+ in0_idx1, in1_idx1)); --+ emit_insn (gen_subsi3 (out, result0, result1)); --+} --+ --+/* Spilt a doubleword instrucion to two single word instructions. */ --+void --+nds32_spilt_doubleword (rtx *operands, bool load_p) --+{ --+ int reg = load_p ? 0 : 1; --+ int mem = load_p ? 1 : 0; --+ rtx reg_rtx = load_p ? operands[0] : operands[1]; --+ rtx mem_rtx = load_p ? operands[1] : operands[0]; --+ rtx low_part[2], high_part[2]; --+ rtx sub_mem = XEXP (mem_rtx, 0); --+ --+ /* Generate low_part and high_part register pattern. --+ i.e. register pattern like: --+ (reg:DI) -> (subreg:SI (reg:DI)) --+ (subreg:SI (reg:DI)) */ --+ low_part[reg] = simplify_gen_subreg (SImode, reg_rtx, GET_MODE (reg_rtx), 0); --+ high_part[reg] = simplify_gen_subreg (SImode, reg_rtx, GET_MODE (reg_rtx), 4); --+ --+ /* Generate low_part and high_part memory pattern. --+ Memory format is (post_dec) will generate: --+ low_part: lwi.bi reg, [mem], 4 --+ high_part: lwi.bi reg, [mem], -12 */ --+ if (GET_CODE (sub_mem) == POST_DEC) --+ { --+ /* memory format is (post_dec (reg)), --+ so that extract (reg) from the (post_dec (reg)) pattern. */ --+ sub_mem = XEXP (sub_mem, 0); --+ --+ /* generate low_part and high_part memory format: --+ low_part: (post_modify ((reg) (plus (reg) (const 4))) --+ high_part: (post_modify ((reg) (plus (reg) (const -12))) */ --+ low_part[mem] = gen_frame_mem (SImode, --+ gen_rtx_POST_MODIFY (Pmode, sub_mem, --+ gen_rtx_PLUS (Pmode, --+ sub_mem, --+ GEN_INT (4)))); --+ high_part[mem] = gen_frame_mem (SImode, --+ gen_rtx_POST_MODIFY (Pmode, sub_mem, --+ gen_rtx_PLUS (Pmode, --+ sub_mem, --+ GEN_INT (-12)))); --+ } --+ else if (GET_CODE (sub_mem) == POST_MODIFY) --+ { --+ /* Memory format is (post_modify (reg) (plus (reg) (const))), --+ so that extract (reg) from the post_modify pattern. */ --+ rtx post_mem = XEXP (sub_mem, 0); --+ --+ /* Extract (const) from the (post_modify (reg) (plus (reg) (const))) --+ pattern. */ --+ --+ rtx plus_op = XEXP (sub_mem, 1); --+ rtx post_val = XEXP (plus_op, 1); --+ --+ /* Generate low_part and high_part memory format: --+ low_part: (post_modify ((reg) (plus (reg) (const))) --+ high_part: ((plus (reg) (const 4))) */ --+ low_part[mem] = gen_frame_mem (SImode, --+ gen_rtx_POST_MODIFY (Pmode, post_mem, --+ gen_rtx_PLUS (Pmode, --+ post_mem, --+ post_val))); --+ high_part[mem] = gen_frame_mem (SImode, plus_constant (Pmode, --+ post_mem, --+ 4)); --+ } --+ else --+ { --+ /* memory format: (symbol_ref), (const), (reg + const_int). */ --+ low_part[mem] = adjust_address (mem_rtx, SImode, 0); --+ high_part[mem] = adjust_address (mem_rtx, SImode, 4); --+ } --+ --+ /* After reload completed, we have dependent issue by low part register and --+ higt part memory. i.e. we cannot split a sequence --+ like: --+ load $r0, [%r1] --+ spilt to --+ lw $r0, [%r0] --+ lwi $r1, [%r0 + 4] --+ swap position --+ lwi $r1, [%r0 + 4] --+ lw $r0, [%r0] --+ For store instruction we don't have a problem. --+ --+ When memory format is [post_modify], we need to emit high part instruction, --+ before low part instruction. --+ expamle: --+ load $r0, [%r2], post_val --+ spilt to --+ load $r1, [%r2 + 4] --+ load $r0, [$r2], post_val. */ --+ if ((load_p && reg_overlap_mentioned_p (low_part[0], high_part[1])) --+ || GET_CODE (sub_mem) == POST_MODIFY) --+ { --+ operands[2] = high_part[0]; --+ operands[3] = high_part[1]; --+ operands[4] = low_part[0]; --+ operands[5] = low_part[1]; --+ } --+ else --+ { --+ operands[2] = low_part[0]; --+ operands[3] = low_part[1]; --+ operands[4] = high_part[0]; --+ operands[5] = high_part[1]; --+ } --+} --+ --+void --+nds32_split_ashiftdi3 (rtx dst, rtx src, rtx shiftamount) --+{ --+ rtx src_high_part, src_low_part; --+ rtx dst_high_part, dst_low_part; --+ --+ dst_high_part = nds32_di_high_part_subreg (dst); --+ dst_low_part = nds32_di_low_part_subreg (dst); --+ --+ src_high_part = nds32_di_high_part_subreg (src); --+ src_low_part = nds32_di_low_part_subreg (src); --+ --+ /* We need to handle shift more than 32 bit!!!! */ --+ if (CONST_INT_P (shiftamount)) --+ { --+ if (INTVAL (shiftamount) < 32) --+ { --+ rtx ext_start; --+ ext_start = gen_int_mode(32 - INTVAL (shiftamount), SImode); --+ --+ emit_insn (gen_wext (dst_high_part, src, ext_start)); --+ emit_insn (gen_ashlsi3 (dst_low_part, src_low_part, shiftamount)); --+ } --+ else --+ { --+ rtx new_shift_amout = gen_int_mode(INTVAL (shiftamount) - 32, SImode); --+ --+ emit_insn (gen_ashlsi3 (dst_high_part, src_low_part, --+ new_shift_amout)); --+ --+ emit_move_insn (dst_low_part, GEN_INT (0)); --+ } --+ } --+ else --+ { --+ rtx dst_low_part_l32, dst_high_part_l32; --+ rtx dst_low_part_g32, dst_high_part_g32; --+ rtx new_shift_amout, select_reg; --+ dst_low_part_l32 = gen_reg_rtx (SImode); --+ dst_high_part_l32 = gen_reg_rtx (SImode); --+ dst_low_part_g32 = gen_reg_rtx (SImode); --+ dst_high_part_g32 = gen_reg_rtx (SImode); --+ new_shift_amout = gen_reg_rtx (SImode); --+ select_reg = gen_reg_rtx (SImode); --+ --+ rtx ext_start; --+ ext_start = gen_reg_rtx (SImode); --+ --+ /* --+ if (shiftamount < 32) --+ dst_low_part = src_low_part << shiftamout --+ dst_high_part = wext (src, 32 - shiftamount) --+ # wext can't handle wext (src, 32) since it's only take rb[0:4] --+ # for extract. --+ dst_high_part = shiftamount == 0 ? src_high_part : dst_high_part --+ else --+ dst_low_part = 0 --+ dst_high_part = src_low_part << shiftamount & 0x1f --+ */ --+ --+ emit_insn (gen_subsi3 (ext_start, --+ gen_int_mode (32, SImode), --+ shiftamount)); --+ emit_insn (gen_wext (dst_high_part_l32, src, ext_start)); --+ --+ /* Handle for shiftamout == 0. */ --+ emit_insn (gen_cmovzsi (dst_high_part_l32, shiftamount, --+ src_high_part, dst_high_part_l32)); --+ --+ emit_insn (gen_ashlsi3 (dst_low_part_l32, src_low_part, shiftamount)); --+ --+ emit_move_insn (dst_low_part_g32, const0_rtx); --+ emit_insn (gen_andsi3 (new_shift_amout, shiftamount, GEN_INT (0x1f))); --+ emit_insn (gen_ashlsi3 (dst_high_part_g32, src_low_part, --+ new_shift_amout)); --+ --+ emit_insn (gen_slt_compare (select_reg, shiftamount, GEN_INT (32))); --+ --+ emit_insn (gen_cmovnsi (dst_low_part, select_reg, --+ dst_low_part_l32, dst_low_part_g32)); --+ emit_insn (gen_cmovnsi (dst_high_part, select_reg, --+ dst_high_part_l32, dst_high_part_g32)); --+ } --+} --+ --+void --+nds32_split_ashiftrtdi3 (rtx dst, rtx src, rtx shiftamount) --+{ --+ nds32_split_shiftrtdi3 (dst, src, shiftamount, false); --+} --+ --+void --+nds32_split_lshiftrtdi3 (rtx dst, rtx src, rtx shiftamount) --+{ --+ nds32_split_shiftrtdi3 (dst, src, shiftamount, true); --+} --+ --+void --+nds32_split_rotatertdi3 (rtx dst, rtx src, rtx shiftamount) --+{ --+ rtx dst_low_part_l32, dst_high_part_l32; --+ rtx dst_low_part_g32, dst_high_part_g32; --+ rtx select_reg, low5bit, low5bit_inv, minus32sa; --+ rtx dst_low_part_g32_tmph; --+ rtx dst_low_part_g32_tmpl; --+ rtx dst_high_part_l32_tmph; --+ rtx dst_high_part_l32_tmpl; --+ --+ rtx src_low_part, src_high_part; --+ rtx dst_high_part, dst_low_part; --+ --+ shiftamount = force_reg (SImode, shiftamount); --+ --+ emit_insn (gen_andsi3 (shiftamount, --+ shiftamount, --+ gen_int_mode (0x3f, SImode))); --+ --+ dst_high_part = nds32_di_high_part_subreg (dst); --+ dst_low_part = nds32_di_low_part_subreg (dst); --+ --+ src_high_part = nds32_di_high_part_subreg (src); --+ src_low_part = nds32_di_low_part_subreg (src); --+ --+ dst_low_part_l32 = gen_reg_rtx (SImode); --+ dst_high_part_l32 = gen_reg_rtx (SImode); --+ dst_low_part_g32 = gen_reg_rtx (SImode); --+ dst_high_part_g32 = gen_reg_rtx (SImode); --+ low5bit = gen_reg_rtx (SImode); --+ low5bit_inv = gen_reg_rtx (SImode); --+ minus32sa = gen_reg_rtx (SImode); --+ select_reg = gen_reg_rtx (SImode); --+ --+ dst_low_part_g32_tmph = gen_reg_rtx (SImode); --+ dst_low_part_g32_tmpl = gen_reg_rtx (SImode); --+ --+ dst_high_part_l32_tmph = gen_reg_rtx (SImode); --+ dst_high_part_l32_tmpl = gen_reg_rtx (SImode); --+ --+ emit_insn (gen_slt_compare (select_reg, shiftamount, GEN_INT (32))); --+ --+ /* if shiftamount < 32 --+ dst_low_part = wext(src, shiftamount) --+ else --+ dst_low_part = ((src_high_part >> (shiftamount & 0x1f)) --+ | (src_low_part << (32 - (shiftamount & 0x1f)))) --+ */ --+ emit_insn (gen_andsi3 (low5bit, shiftamount, gen_int_mode (0x1f, SImode))); --+ emit_insn (gen_subsi3 (low5bit_inv, gen_int_mode (32, SImode), low5bit)); --+ --+ emit_insn (gen_wext (dst_low_part_l32, src, shiftamount)); --+ --+ emit_insn (gen_lshrsi3 (dst_low_part_g32_tmpl, src_high_part, low5bit)); --+ emit_insn (gen_ashlsi3 (dst_low_part_g32_tmph, src_low_part, low5bit_inv)); --+ --+ emit_insn (gen_iorsi3 (dst_low_part_g32, --+ dst_low_part_g32_tmpl, --+ dst_low_part_g32_tmph)); --+ --+ emit_insn (gen_cmovnsi (dst_low_part, select_reg, --+ dst_low_part_l32, dst_low_part_g32)); --+ --+ /* if shiftamount < 32 --+ dst_high_part = ((src_high_part >> shiftamount) --+ | (src_low_part << (32 - shiftamount))) --+ dst_high_part = shiftamount == 0 ? src_high_part : dst_high_part --+ else --+ dst_high_part = wext(src, shiftamount & 0x1f) --+ */ --+ --+ emit_insn (gen_subsi3 (minus32sa, gen_int_mode (32, SImode), shiftamount)); --+ --+ emit_insn (gen_lshrsi3 (dst_high_part_l32_tmpl, src_high_part, shiftamount)); --+ emit_insn (gen_ashlsi3 (dst_high_part_l32_tmph, src_low_part, minus32sa)); --+ --+ emit_insn (gen_iorsi3 (dst_high_part_l32, --+ dst_high_part_l32_tmpl, --+ dst_high_part_l32_tmph)); --+ --+ emit_insn (gen_cmovzsi (dst_high_part_l32, shiftamount, --+ src_high_part, dst_high_part_l32)); --+ --+ emit_insn (gen_wext (dst_high_part_g32, src, low5bit)); --+ --+ emit_insn (gen_cmovnsi (dst_high_part, select_reg, --+ dst_high_part_l32, dst_high_part_g32)); --+} --+ --+/* Return true if OP contains a symbol reference. */ --+bool --+symbolic_reference_mentioned_p (rtx op) --+{ --+ const char *fmt; --+ int i; -- --- /* The v3push/v3pop instruction should only be applied on --- none-isr and none-variadic function. */ --- if (TARGET_V3PUSH --- && !nds32_isr_function_p (current_function_decl) --- && (cfun->machine->va_args_size == 0)) --+ if (GET_CODE (op) == SYMBOL_REF || GET_CODE (op) == LABEL_REF) --+ return true; --+ --+ fmt = GET_RTX_FORMAT (GET_CODE (op)); --+ for (i = GET_RTX_LENGTH (GET_CODE (op)) - 1; i >= 0; i--) -- { --- /* For stack v3push: --- operands[0]: Re --- operands[1]: imm8u */ --+ if (fmt[i] == 'E') --+ { --+ int j; -- --- /* This variable is to check if 'push25 Re,imm8u' is available. */ --- int sp_adjust; --+ for (j = XVECLEN (op, i) - 1; j >= 0; j--) --+ if (symbolic_reference_mentioned_p (XVECEXP (op, i, j))) --+ return true; --+ } -- --- /* Set operands[0]. */ --- operands[0] = gen_rtx_REG (SImode, re_callee_saved); --+ else if (fmt[i] == 'e' && symbolic_reference_mentioned_p (XEXP (op, i))) --+ return true; --+ } -- --- /* Check if we can generate 'push25 Re,imm8u', --- otherwise, generate 'push25 Re,0'. */ --- sp_adjust = cfun->machine->local_size --- + cfun->machine->out_args_size --- + cfun->machine->callee_saved_area_gpr_padding_bytes; --- if (satisfies_constraint_Iu08 (GEN_INT (sp_adjust)) --- && NDS32_DOUBLE_WORD_ALIGN_P (sp_adjust)) --- operands[1] = GEN_INT (sp_adjust); --- else --- operands[1] = GEN_INT (0); --+ return false; --+} -- --- /* Create assembly code pattern. */ --- snprintf (pattern, sizeof (pattern), "push25\t%%0, %%1"); --- } --- else --- { --- /* For normal stack push multiple: --- operands[0]: Rb --- operands[1]: Re --- operands[2]: En4 */ --+/* Expand PIC code for @GOTOFF and @GOT. -- --- /* This variable is used to check if we only need to generate En4 field. --- As long as Rb==Re=SP_REGNUM, we set this variable to 1. */ --- int push_en4_only_p = 0; --+ Example for @GOTOFF: -- --- /* Set operands[0] and operands[1]. */ --- operands[0] = gen_rtx_REG (SImode, rb_callee_saved); --- operands[1] = gen_rtx_REG (SImode, re_callee_saved); --+ la $r0, symbol@GOTOFF --+ -> sethi $ta, hi20(symbol@GOTOFF) --+ ori $ta, $ta, lo12(symbol@GOTOFF) --+ add $r0, $ta, $gp -- --- /* 'smw.adm $sp,[$sp],$sp,0' means push nothing. */ --- if (!cfun->machine->fp_size --- && !cfun->machine->gp_size --- && !cfun->machine->lp_size --- && REGNO (operands[0]) == SP_REGNUM --- && REGNO (operands[1]) == SP_REGNUM) --+ Example for @GOT: --+ --+ la $r0, symbol@GOT --+ -> sethi $ta, hi20(symbol@GOT) --+ ori $ta, $ta, lo12(symbol@GOT) --+ lw $r0, [$ta + $gp] --+*/ --+rtx --+nds32_legitimize_pic_address (rtx x) --+{ --+ rtx addr = x; --+ rtx reg = gen_reg_rtx (Pmode); --+ rtx pat; --+ --+ if (GET_CODE (x) == LABEL_REF --+ || (GET_CODE (x) == SYMBOL_REF --+ && (CONSTANT_POOL_ADDRESS_P (x) --+ || SYMBOL_REF_LOCAL_P (x)))) --+ { --+ addr = gen_rtx_UNSPEC (SImode, gen_rtvec (1, x), UNSPEC_GOTOFF); --+ addr = gen_rtx_CONST (SImode, addr); --+ emit_insn (gen_sethi (reg, addr)); --+ emit_insn (gen_lo_sum (reg, reg, addr)); --+ x = gen_rtx_PLUS (Pmode, reg, pic_offset_table_rtx); --+ } --+ else if (GET_CODE (x) == SYMBOL_REF) --+ { --+ addr = gen_rtx_UNSPEC (SImode, gen_rtvec (1, x), UNSPEC_GOT); --+ addr = gen_rtx_CONST (SImode, addr); --+ emit_insn (gen_sethi (reg, addr)); --+ emit_insn (gen_lo_sum (reg, reg, addr)); --+ --+ x = gen_const_mem (SImode, gen_rtx_PLUS (Pmode, pic_offset_table_rtx, --+ reg)); --+ } --+ else if (GET_CODE (x) == CONST) --+ { --+ /* We don't split constant in expand_pic_move because GOTOFF can combine --+ the addend with the symbol. */ --+ addr = XEXP (x, 0); --+ gcc_assert (GET_CODE (addr) == PLUS); --+ --+ rtx op0 = XEXP (addr, 0); --+ rtx op1 = XEXP (addr, 1); --+ --+ if ((GET_CODE (op0) == LABEL_REF --+ || (GET_CODE (op0) == SYMBOL_REF --+ && (CONSTANT_POOL_ADDRESS_P (op0) --+ || SYMBOL_REF_LOCAL_P (op0)))) --+ && GET_CODE (op1) == CONST_INT) -- { --- /* No need to generate instruction. */ --- return ""; --+ pat = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, op0), UNSPEC_GOTOFF); --+ pat = gen_rtx_PLUS (Pmode, pat, op1); --+ pat = gen_rtx_CONST (Pmode, pat); --+ emit_insn (gen_sethi (reg, pat)); --+ emit_insn (gen_lo_sum (reg, reg, pat)); --+ x = gen_rtx_PLUS (Pmode, reg, pic_offset_table_rtx); --+ } --+ else if (GET_CODE (op0) == SYMBOL_REF --+ && GET_CODE (op1) == CONST_INT) --+ { --+ /* This is a constant offset from a @GOT symbol reference. */ --+ addr = gen_rtx_UNSPEC (SImode, gen_rtvec (1, op0), UNSPEC_GOT); --+ addr = gen_rtx_CONST (SImode, addr); --+ emit_insn (gen_sethi (reg, addr)); --+ emit_insn (gen_lo_sum (reg, reg, addr)); --+ addr = gen_const_mem (SImode, gen_rtx_PLUS (Pmode, --+ pic_offset_table_rtx, --+ reg)); --+ emit_move_insn (reg, addr); --+ if (satisfies_constraint_Is15 (op1)) --+ x = gen_rtx_PLUS (Pmode, reg, op1); --+ else --+ { --+ rtx tmp_reg = gen_reg_rtx (SImode); --+ emit_insn (gen_movsi (tmp_reg, op1)); --+ x = gen_rtx_PLUS (Pmode, reg, tmp_reg); --+ } -- } -- else -- { --- /* If Rb==Re=SP_REGNUM, we only need to generate En4 field. */ --- if (REGNO (operands[0]) == SP_REGNUM --- && REGNO (operands[1]) == SP_REGNUM) --- push_en4_only_p = 1; --- --- /* Create assembly code pattern. --- We need to handle the form: "Rb, Re, { $fp $gp $lp }". */ --- snprintf (pattern, sizeof (pattern), --- "push.s\t%s{%s%s%s }", --- push_en4_only_p ? "" : "%0, %1, ", --- cfun->machine->fp_size ? " $fp" : "", --- cfun->machine->gp_size ? " $gp" : "", --- cfun->machine->lp_size ? " $lp" : ""); --+ /* Don't handle this pattern. */ --+ debug_rtx (x); --+ gcc_unreachable (); -- } -- } --+ return x; --+} -- --- /* We use output_asm_insn() to output assembly code by ourself. */ --- output_asm_insn (pattern, operands); --- return ""; --+void --+nds32_expand_pic_move (rtx *operands) --+{ --+ rtx src; --+ --+ src = nds32_legitimize_pic_address (operands[1]); --+ emit_move_insn (operands[0], src); -- } -- ---/* Function to output stack pop operation. --- We need to deal with normal stack pop multiple or stack v3pop. */ ---const char * ---nds32_output_stack_pop (rtx par_rtx ATTRIBUTE_UNUSED) --+/* Expand ICT symbol. --+ Example for @ICT and ICT model=large: --+ --+ la $r0, symbol@ICT --+ -> sethi $rt, hi20(symbol@ICT) --+ lwi $r0, [$rt + lo12(symbol@ICT)] --+ --+*/ --+rtx --+nds32_legitimize_ict_address (rtx x) -- { --- /* A string pattern for output_asm_insn(). */ --- char pattern[100]; --- /* The operands array which will be used in output_asm_insn(). */ --- rtx operands[3]; --- /* Pick up callee-saved first regno and last regno for further use. */ --- int rb_callee_saved = cfun->machine->callee_saved_first_gpr_regno; --- int re_callee_saved = cfun->machine->callee_saved_last_gpr_regno; --+ rtx symbol = x; --+ rtx addr = x; --+ rtx reg = gen_reg_rtx (Pmode); --+ gcc_assert (GET_CODE (x) == SYMBOL_REF --+ && nds32_indirect_call_referenced_p (x)); -- --- /* If we step here, we are going to do v3pop or multiple pop operation. */ --+ addr = gen_rtx_UNSPEC (SImode, gen_rtvec (1, symbol), UNSPEC_ICT); --+ addr = gen_rtx_CONST (SImode, addr); --+ emit_insn (gen_sethi (reg, addr)); -- --- /* The v3push/v3pop instruction should only be applied on --- none-isr and none-variadic function. */ --- if (TARGET_V3PUSH --- && !nds32_isr_function_p (current_function_decl) --- && (cfun->machine->va_args_size == 0)) --- { --- /* For stack v3pop: --- operands[0]: Re --- operands[1]: imm8u */ --+ x = gen_const_mem (SImode, gen_rtx_LO_SUM (Pmode, reg, addr)); -- --- /* This variable is to check if 'pop25 Re,imm8u' is available. */ --- int sp_adjust; --+ return x; --+} -- --- /* Set operands[0]. */ --- operands[0] = gen_rtx_REG (SImode, re_callee_saved); --+void --+nds32_expand_ict_move (rtx *operands) --+{ --+ rtx src = operands[1]; -- --- /* Check if we can generate 'pop25 Re,imm8u', --- otherwise, generate 'pop25 Re,0'. --- We have to consider alloca issue as well. --- If the function does call alloca(), the stack pointer is not fixed. --- In that case, we cannot use 'pop25 Re,imm8u' directly. --- We have to caculate stack pointer from frame pointer --- and then use 'pop25 Re,0'. */ --- sp_adjust = cfun->machine->local_size --- + cfun->machine->out_args_size --- + cfun->machine->callee_saved_area_gpr_padding_bytes; --- if (satisfies_constraint_Iu08 (GEN_INT (sp_adjust)) --- && NDS32_DOUBLE_WORD_ALIGN_P (sp_adjust) --- && !cfun->calls_alloca) --- operands[1] = GEN_INT (sp_adjust); --- else --- operands[1] = GEN_INT (0); --+ src = nds32_legitimize_ict_address (src); -- --- /* Create assembly code pattern. */ --- snprintf (pattern, sizeof (pattern), "pop25\t%%0, %%1"); --+ emit_move_insn (operands[0], src); --+} --+ --+/* Return true X is a indirect call symbol. */ --+bool --+nds32_indirect_call_referenced_p (rtx x) --+{ --+ if (GET_CODE (x) == UNSPEC && XINT (x, 1) == UNSPEC_ICT) --+ x = XVECEXP (x, 0, 0); --+ --+ if (GET_CODE (x) == SYMBOL_REF) --+ { --+ tree decl = SYMBOL_REF_DECL (x); --+ --+ return decl --+ && (lookup_attribute("indirect_call", --+ DECL_ATTRIBUTES(decl)) --+ != NULL); -- } --+ --+ return false; --+} --+ --+/* Return true X is need use long call. */ --+bool --+nds32_long_call_p (rtx symbol) --+{ --+ if (nds32_indirect_call_referenced_p (symbol)) --+ return TARGET_ICT_MODEL_LARGE; -- else --- { --- /* For normal stack pop multiple: --- operands[0]: Rb --- operands[1]: Re --- operands[2]: En4 */ --+ return TARGET_CMODEL_LARGE; --+} -- --- /* This variable is used to check if we only need to generate En4 field. --- As long as Rb==Re=SP_REGNUM, we set this variable to 1. */ --- int pop_en4_only_p = 0; --+/* Return true if X contains a thread-local symbol. */ --+bool --+nds32_tls_referenced_p (rtx x) --+{ --+ if (!targetm.have_tls) --+ return false; -- --- /* Set operands[0] and operands[1]. */ --- operands[0] = gen_rtx_REG (SImode, rb_callee_saved); --- operands[1] = gen_rtx_REG (SImode, re_callee_saved); --+ if (GET_CODE (x) == CONST && GET_CODE (XEXP (x, 0)) == PLUS) --+ x = XEXP (XEXP (x, 0), 0); -- --- /* 'lmw.bim $sp,[$sp],$sp,0' means pop nothing. */ --- if (!cfun->machine->fp_size --- && !cfun->machine->gp_size --- && !cfun->machine->lp_size --- && REGNO (operands[0]) == SP_REGNUM --- && REGNO (operands[1]) == SP_REGNUM) --- { --- /* No need to generate instruction. */ --- return ""; --- } --- else --- { --- /* If Rb==Re=SP_REGNUM, we only need to generate En4 field. */ --- if (REGNO (operands[0]) == SP_REGNUM --- && REGNO (operands[1]) == SP_REGNUM) --- pop_en4_only_p = 1; --+ if (GET_CODE (x) == SYMBOL_REF && SYMBOL_REF_TLS_MODEL (x)) --+ return true; -- --- /* Create assembly code pattern. --- We need to handle the form: "Rb, Re, { $fp $gp $lp }". */ --- snprintf (pattern, sizeof (pattern), --- "pop.s\t%s{%s%s%s }", --- pop_en4_only_p ? "" : "%0, %1, ", --- cfun->machine->fp_size ? " $fp" : "", --- cfun->machine->gp_size ? " $gp" : "", --- cfun->machine->lp_size ? " $lp" : ""); --+ return false; --+} --+ --+/* ADDR contains a thread-local SYMBOL_REF. Generate code to compute --+ this (thread-local) address. */ --+rtx --+nds32_legitimize_tls_address (rtx x) --+{ --+ rtx tmp_reg; --+ rtx tp_reg = gen_rtx_REG (Pmode, TP_REGNUM); --+ rtx pat, insns, reg0; --+ --+ if (GET_CODE (x) == SYMBOL_REF) --+ switch (SYMBOL_REF_TLS_MODEL (x)) --+ { --+ case TLS_MODEL_GLOBAL_DYNAMIC: --+ case TLS_MODEL_LOCAL_DYNAMIC: --+ /* Emit UNSPEC_TLS_DESC rather than expand rtl directly because spill --+ may destroy the define-use chain anylysis to insert relax_hint. */ --+ if (SYMBOL_REF_TLS_MODEL (x) == TLS_MODEL_GLOBAL_DYNAMIC) --+ pat = gen_rtx_UNSPEC (SImode, gen_rtvec (1, x), UNSPEC_TLSGD); --+ else --+ pat = gen_rtx_UNSPEC (SImode, gen_rtvec (1, x), UNSPEC_TLSLD); --+ --+ pat = gen_rtx_CONST (SImode, pat); --+ reg0 = gen_rtx_REG (Pmode, 0); --+ /* If we can confirm all clobber reigsters, it doesn't have to use call --+ instruction. */ --+ insns = emit_call_insn (gen_tls_desc (pat, GEN_INT (0))); --+ use_reg (&CALL_INSN_FUNCTION_USAGE (insns), pic_offset_table_rtx); --+ RTL_CONST_CALL_P (insns) = 1; --+ tmp_reg = gen_reg_rtx (SImode); --+ emit_move_insn (tmp_reg, reg0); --+ x = tmp_reg; --+ break; --+ --+ case TLS_MODEL_INITIAL_EXEC: --+ pat = gen_rtx_UNSPEC (SImode, gen_rtvec (1, x), UNSPEC_TLSIE); --+ tmp_reg = gen_reg_rtx (SImode); --+ pat = gen_rtx_CONST (SImode, pat); --+ emit_insn (gen_tls_ie (tmp_reg, pat, GEN_INT (0))); --+ if (flag_pic) --+ emit_use (pic_offset_table_rtx); --+ x = gen_rtx_PLUS (Pmode, tmp_reg, tp_reg); --+ break; --+ --+ case TLS_MODEL_LOCAL_EXEC: --+ /* Expand symbol_ref@TPOFF': --+ sethi $ta, hi20(symbol_ref@TPOFF) --+ ori $ta, $ta, lo12(symbol_ref@TPOFF) --+ add $r0, $ta, $tp */ --+ tmp_reg = gen_reg_rtx (SImode); --+ pat = gen_rtx_UNSPEC (SImode, gen_rtvec (1, x), UNSPEC_TLSLE); --+ pat = gen_rtx_CONST (SImode, pat); --+ emit_insn (gen_sethi (tmp_reg, pat)); --+ emit_insn (gen_lo_sum (tmp_reg, tmp_reg, pat)); --+ x = gen_rtx_PLUS (Pmode, tmp_reg, tp_reg); --+ break; --+ --+ default: --+ gcc_unreachable (); --+ } --+ else if (GET_CODE (x) == CONST) --+ { --+ rtx base, addend; --+ split_const (x, &base, &addend); --+ --+ if (SYMBOL_REF_TLS_MODEL (base) == TLS_MODEL_LOCAL_EXEC) --+ { --+ /* Expand symbol_ref@TPOFF': --+ sethi $ta, hi20(symbol_ref@TPOFF + addend) --+ ori $ta, $ta, lo12(symbol_ref@TPOFF + addend) --+ add $r0, $ta, $tp */ --+ tmp_reg = gen_reg_rtx (SImode); --+ pat = gen_rtx_UNSPEC (SImode, gen_rtvec (1, base), UNSPEC_TLSLE); --+ pat = gen_rtx_PLUS (SImode, pat, addend); --+ pat = gen_rtx_CONST (SImode, pat); --+ emit_insn (gen_sethi (tmp_reg, pat)); --+ emit_insn (gen_lo_sum (tmp_reg, tmp_reg, pat)); --+ x = gen_rtx_PLUS (Pmode, tmp_reg, tp_reg); -- } -- } -- --- /* We use output_asm_insn() to output assembly code by ourself. */ --- output_asm_insn (pattern, operands); --- return ""; --+ return x; -- } -- ---/* Function to generate PC relative jump table. --- Refer to nds32.md for more details. --+void --+nds32_expand_tls_move (rtx *operands) --+{ --+ rtx src = operands[1]; --+ rtx base, addend; -- --- The following is the sample for the case that diff value --- can be presented in '.short' size. --+ if (CONSTANT_P (src)) --+ split_const (src, &base, &addend); -- --- addi $r1, $r1, -(case_lower_bound) --- slti $ta, $r1, (case_number) --- beqz $ta, .L_skip_label --+ if (SYMBOL_REF_TLS_MODEL (base) == TLS_MODEL_LOCAL_EXEC) --+ src = nds32_legitimize_tls_address (src); --+ else --+ { --+ src = nds32_legitimize_tls_address (base); --+ if (addend != const0_rtx) --+ { --+ src = gen_rtx_PLUS (SImode, src, addend); --+ src = force_operand (src, operands[0]); --+ } --+ } -- --- la $ta, .L35 ! get jump table address --- lh $r1, [$ta + $r1 << 1] ! load symbol diff from jump table entry --- addi $ta, $r1, $ta --- jr5 $ta --+ emit_move_insn (operands[0], src); --+} -- --- ! jump table entry --- L35: --- .short .L25-.L35 --- .short .L26-.L35 --- .short .L27-.L35 --- .short .L28-.L35 --- .short .L29-.L35 --- .short .L30-.L35 --- .short .L31-.L35 --- .short .L32-.L35 --- .short .L33-.L35 --- .short .L34-.L35 */ ---const char * ---nds32_output_casesi_pc_relative (rtx *operands) --+void --+nds32_expand_constant (enum machine_mode mode, HOST_WIDE_INT val, --+ rtx target, rtx source) -- { --- machine_mode mode; --- rtx diff_vec; --+ rtx temp = gen_reg_rtx (mode); --+ int clear_sign_bit_copies = 0; --+ int clear_zero_bit_copies = 0; --+ unsigned HOST_WIDE_INT remainder = val & 0xffffffffUL; --+ --+ /* Count number of leading zeros. */ --+ clear_sign_bit_copies = __builtin_clz (remainder); --+ /* Count number of trailing zeros. */ --+ clear_zero_bit_copies = __builtin_ctz (remainder); --+ --+ HOST_WIDE_INT sign_shift_mask = ((0xffffffffUL --+ << (32 - clear_sign_bit_copies)) --+ & 0xffffffffUL); --+ HOST_WIDE_INT zero_shift_mask = (1 << clear_zero_bit_copies) - 1; --+ --+ if (clear_sign_bit_copies > 0 && clear_sign_bit_copies < 17 --+ && (remainder | sign_shift_mask) == 0xffffffffUL) --+ { --+ /* Transfer AND to two shifts, example: --+ a = b & 0x7fffffff => (b << 1) >> 1 */ --+ rtx shift = GEN_INT (clear_sign_bit_copies); -- --- diff_vec = PATTERN (NEXT_INSN (as_a (operands[1]))); --+ emit_insn (gen_ashlsi3 (temp, source, shift)); --+ emit_insn (gen_lshrsi3 (target, temp, shift)); --+ } --+ else if (clear_zero_bit_copies > 0 && clear_sign_bit_copies < 17 --+ && (remainder | zero_shift_mask) == 0xffffffffUL) --+ { --+ /* Transfer AND to two shifts, example: --+ a = b & 0xfff00000 => (b >> 20) << 20 */ --+ rtx shift = GEN_INT (clear_zero_bit_copies); -- --- gcc_assert (GET_CODE (diff_vec) == ADDR_DIFF_VEC); --+ emit_insn (gen_lshrsi3 (temp, source, shift)); --+ emit_insn (gen_ashlsi3 (target, temp, shift)); --+ } --+ else --+ { --+ emit_move_insn (temp, GEN_INT (val)); --+ emit_move_insn (target, gen_rtx_fmt_ee (AND, mode, source, temp)); --+ } --+} -- --- /* Step C: "t <-- operands[1]". */ --- output_asm_insn ("la\t$ta, %l1", operands); --+/* Auxiliary functions for lwm/smw. */ --+bool --+nds32_valid_smw_lwm_base_p (rtx op) --+{ --+ rtx base_addr; -- --- /* Get the mode of each element in the difference vector. */ --- mode = GET_MODE (diff_vec); --+ if (!MEM_P (op)) --+ return false; -- --- /* Step D: "z <-- (mem (plus (operands[0] << m) t))", --- where m is 0, 1, or 2 to load address-diff value from table. */ --- switch (mode) --+ base_addr = XEXP (op, 0); --+ --+ if (REG_P (base_addr)) --+ return true; --+ else -- { --- case QImode: --- output_asm_insn ("lb\t%2, [$ta + %0 << 0]", operands); --- break; --- case HImode: --- output_asm_insn ("lh\t%2, [$ta + %0 << 1]", operands); --- break; --- case SImode: --- output_asm_insn ("lw\t%2, [$ta + %0 << 2]", operands); --- break; --- default: --- gcc_unreachable (); --+ if (GET_CODE (base_addr) == POST_INC --+ && REG_P (XEXP (base_addr, 0))) --+ return true; -- } -- --- /* Step E: "t <-- z + t". --- Add table label_ref with address-diff value to --- obtain target case address. */ --- output_asm_insn ("add\t$ta, %2, $ta", operands); --+ return false; --+} -- --- /* Step F: jump to target with register t. */ --- if (TARGET_16_BIT) --- return "jr5\t$ta"; --- else --- return "jr\t$ta"; --+/* Auxiliary functions for manipulation DI mode. */ --+rtx nds32_di_high_part_subreg(rtx reg) --+{ --+ unsigned high_part_offset = subreg_highpart_offset (SImode, DImode); --+ --+ return simplify_gen_subreg ( --+ SImode, reg, --+ DImode, high_part_offset); -- } -- ---/* Function to generate normal jump table. */ ---const char * ---nds32_output_casesi (rtx *operands) --+rtx nds32_di_low_part_subreg(rtx reg) -- { --- /* Step C: "t <-- operands[1]". */ --- output_asm_insn ("la\t$ta, %l1", operands); --+ unsigned low_part_offset = subreg_lowpart_offset (SImode, DImode); -- --- /* Step D: "z <-- (mem (plus (operands[0] << 2) t))". */ --- output_asm_insn ("lw\t%2, [$ta + %0 << 2]", operands); --+ return simplify_gen_subreg ( --+ SImode, reg, --+ DImode, low_part_offset); --+} -- --- /* No need to perform Step E, which is only used for --- pc relative jump table. */ --+/* ------------------------------------------------------------------------ */ -- --- /* Step F: jump to target with register z. */ --- if (TARGET_16_BIT) --- return "jr5\t%2"; --+/* Auxiliary function for output TLS patterns. */ --+ --+const char * --+nds32_output_tls_desc (rtx *operands) --+{ --+ char pattern[1000]; --+ --+ if (TARGET_RELAX_HINT) --+ snprintf (pattern, sizeof (pattern), --+ ".relax_hint %%1\n\tsethi $r0, hi20(%%0)\n\t" --+ ".relax_hint %%1\n\tori $r0, $r0, lo12(%%0)\n\t" --+ ".relax_hint %%1\n\tlw $r15, [$r0 + $gp]\n\t" --+ ".relax_hint %%1\n\tadd $r0, $r0, $gp\n\t" --+ ".relax_hint %%1\n\tjral $r15"); -- else --- return "jr\t%2"; --+ snprintf (pattern, sizeof (pattern), --+ "sethi $r0, hi20(%%0)\n\t" --+ "ori $r0, $r0, lo12(%%0)\n\t" --+ "lw $r15, [$r0 + $gp]\n\t" --+ "add $r0, $r0, $gp\n\t" --+ "jral $r15"); --+ output_asm_insn (pattern, operands); --+ return ""; -- } -- ---/* ------------------------------------------------------------------------ */ --+const char * --+nds32_output_tls_ie (rtx *operands) --+{ --+ char pattern[1000]; --+ --+ if (flag_pic) --+ { --+ if (TARGET_RELAX_HINT) --+ snprintf (pattern, sizeof (pattern), --+ ".relax_hint %%2\n\tsethi %%0, hi20(%%1)\n\t" --+ ".relax_hint %%2\n\tori %%0, %%0, lo12(%%1)\n\t" --+ ".relax_hint %%2\n\tlw %%0, [%%0 + $gp]"); --+ else --+ snprintf (pattern, sizeof (pattern), --+ "sethi %%0, hi20(%%1)\n\t" --+ "ori %%0, %%0, lo12(%%1)\n\t" --+ "lw %%0, [%%0 + $gp]"); --+ } --+ else --+ { --+ if (TARGET_RELAX_HINT) --+ snprintf (pattern, sizeof (pattern), --+ ".relax_hint %%2\n\tsethi %%0, hi20(%%1)\n\t" --+ ".relax_hint %%2\n\tlwi %%0, [%%0 + lo12(%%1)]"); --+ else --+ snprintf (pattern, sizeof (pattern), --+ "sethi %%0, hi20(%%1)\n\t" --+ "lwi %%0, [%%0 + lo12(%%1)]"); --+ } --+ output_asm_insn (pattern, operands); --+ return ""; --+} --diff --git a/gcc/config/nds32/nds32-memory-manipulation.c b/gcc/config/nds32/nds32-memory-manipulation.c --index 4c26dcc..c46ac8f 100644 ----- a/gcc/config/nds32/nds32-memory-manipulation.c --+++ b/gcc/config/nds32/nds32-memory-manipulation.c --@@ -25,28 +25,1255 @@ -- #include "system.h" -- #include "coretypes.h" -- #include "backend.h" ---#include "target.h" --+#include "tree.h" -- #include "rtl.h" ---#include "emit-rtl.h" --+#include "df.h" --+#include "alias.h" --+#include "stor-layout.h" --+#include "varasm.h" --+#include "calls.h" --+#include "regs.h" --+#include "insn-config.h" /* Required by recog.h. */ --+#include "conditions.h" --+#include "output.h" --+#include "insn-attr.h" /* For DFA state_t. */ --+#include "insn-codes.h" /* For CODE_FOR_xxx. */ --+#include "reload.h" /* For push_reload(). */ --+#include "flags.h" --+#include "insn-config.h" --+#include "expmed.h" --+#include "dojump.h" -- #include "explow.h" --+#include "emit-rtl.h" --+#include "stmt.h" --+#include "expr.h" --+#include "recog.h" --+#include "diagnostic-core.h" --+#include "cfgrtl.h" --+#include "cfganal.h" --+#include "lcm.h" --+#include "cfgbuild.h" --+#include "cfgcleanup.h" --+#include "tm_p.h" --+#include "tm-constrs.h" --+#include "optabs.h" /* For GEN_FCN. */ --+#include "target.h" --+#include "langhooks.h" /* For add_builtin_function(). */ --+#include "builtins.h" --+ --+/* ------------------------------------------------------------------------ */ --+ --+/* This file is divided into six parts: --+ --+ PART 1: Auxiliary static function definitions. --+ --+ PART 2: Auxiliary function for expand movmem pattern. --+ --+ PART 3: Auxiliary function for expand setmem pattern. --+ --+ PART 4: Auxiliary function for expand movstr pattern. --+ --+ PART 5: Auxiliary function for expand strlen pattern. --+ --+ PART 6: Auxiliary function for expand load_multiple/store_multiple --+ pattern. */ --+ --+/* ------------------------------------------------------------------------ */ --+ --+/* PART 1: Auxiliary static function definitions. */ --+ --+static void --+nds32_emit_load_store (rtx reg, rtx mem, --+ enum machine_mode mode, --+ int offset, bool load_p) --+{ --+ rtx new_mem; --+ new_mem = adjust_address (mem, mode, offset); --+ if (load_p) --+ emit_move_insn (reg, new_mem); --+ else --+ emit_move_insn (new_mem, reg); --+} --+ --+static void --+nds32_emit_post_inc_load_store (rtx reg, rtx base_reg, --+ enum machine_mode mode, --+ bool load_p) --+{ --+ gcc_assert (GET_MODE (reg) == mode); --+ gcc_assert (GET_MODE (base_reg) == Pmode); --+ --+ /* Do not gen (set (reg) (mem (post_inc (reg)))) directly here since it may --+ not recognize by gcc, so let gcc combine it at auto_inc_dec pass. */ --+ if (load_p) --+ emit_move_insn (reg, --+ gen_rtx_MEM (mode, --+ base_reg)); --+ else --+ emit_move_insn (gen_rtx_MEM (mode, --+ base_reg), --+ reg); --+ --+ emit_move_insn (base_reg, --+ plus_constant(Pmode, base_reg, GET_MODE_SIZE (mode))); --+} --+ --+static void --+nds32_emit_mem_move (rtx src, rtx dst, --+ enum machine_mode mode, --+ int addr_offset) --+{ --+ gcc_assert (MEM_P (src) && MEM_P (dst)); --+ rtx tmp_reg = gen_reg_rtx (mode); --+ nds32_emit_load_store (tmp_reg, src, mode, --+ addr_offset, /* load_p */ true); --+ nds32_emit_load_store (tmp_reg, dst, mode, --+ addr_offset, /* load_p */ false); --+} --+ --+static void --+nds32_emit_mem_move_block (int base_regno, int count, --+ rtx *dst_base_reg, rtx *dst_mem, --+ rtx *src_base_reg, rtx *src_mem, --+ bool update_base_reg_p) --+{ --+ rtx new_base_reg; --+ --+ emit_insn (nds32_expand_load_multiple (base_regno, count, --+ *src_base_reg, *src_mem, --+ update_base_reg_p, &new_base_reg)); --+ if (update_base_reg_p) --+ { --+ *src_base_reg = new_base_reg; --+ *src_mem = gen_rtx_MEM (SImode, *src_base_reg); --+ } --+ --+ emit_insn (nds32_expand_store_multiple (base_regno, count, --+ *dst_base_reg, *dst_mem, --+ update_base_reg_p, &new_base_reg)); --+ --+ if (update_base_reg_p) --+ { --+ *dst_base_reg = new_base_reg; --+ *dst_mem = gen_rtx_MEM (SImode, *dst_base_reg); --+ } --+} --+ --+/* ------------------------------------------------------------------------ */ --+ --+/* PART 2: Auxiliary function for expand movmem pattern. */ --+ --+static bool --+nds32_expand_movmemsi_loop_unknown_size (rtx dstmem, rtx srcmem, --+ rtx size, --+ rtx alignment, bool use_zol_p) --+{ --+ /* Emit loop version of movmem. --+ --+ andi $size_least_3_bit, $size, #~7 --+ add $dst_end, $dst, $size --+ move $dst_itr, $dst --+ move $src_itr, $src --+ beqz $size_least_3_bit, .Lbyte_mode_entry ! Not large enough. --+ add $double_word_end, $dst, $size_least_3_bit --+ --+ .Ldouble_word_mode_loop: --+ lmw.bim $tmp-begin, [$src_itr], $tmp-end, #0 ! $src_itr' = $src_itr --+ smw.bim $tmp-begin, [$dst_itr], $tmp-end, #0 ! $dst_itr' = $dst_itr --+ ! move will delete after register allocation --+ move $src_itr, $src_itr' --+ move $dst_itr, $dst_itr' --+ ! Not readch upper bound. Loop. --+ bne $double_word_end, $dst_itr, .Ldouble_word_mode_loop --+ --+ .Lbyte_mode_entry: --+ beq $dst_itr, $dst_end, .Lend_label --+ .Lbyte_mode_loop: --+ lbi.bi $tmp, [$src_itr], #1 --+ sbi.bi $tmp, [$dst_itr], #1 --+ ! Not readch upper bound. Loop. --+ bne $dst_itr, $dst_end, .Lbyte_mode_loop --+ .Lend_label: --+ */ --+ rtx dst_base_reg, src_base_reg; --+ rtx dst_itr, src_itr; --+ rtx dstmem_m, srcmem_m, dst_itr_m, src_itr_m; --+ rtx dst_end; --+ rtx size_least_3_bit; --+ rtx double_word_end = NULL; --+ rtx double_word_mode_loop, byte_mode_entry, byte_mode_loop, end_label; --+ rtx tmp; --+ rtx mask_least_3_bit; --+ int start_regno; --+ bool align_to_4_bytes = (INTVAL (alignment) & 3) == 0; --+ int hwloop_id = cfun->machine->hwloop_group_id; --+ --+ if (TARGET_ISA_V3M && !align_to_4_bytes) --+ return 0; --+ --+ if (TARGET_REDUCED_REGS) --+ start_regno = 2; --+ else --+ start_regno = 16; --+ --+ dst_itr = gen_reg_rtx (Pmode); --+ src_itr = gen_reg_rtx (Pmode); --+ dst_end = gen_reg_rtx (Pmode); --+ tmp = gen_reg_rtx (QImode); --+ mask_least_3_bit = GEN_INT (~7); --+ --+ double_word_mode_loop = gen_label_rtx (); --+ byte_mode_entry = gen_label_rtx (); --+ byte_mode_loop = gen_label_rtx (); --+ end_label = gen_label_rtx (); --+ --+ dst_base_reg = copy_to_mode_reg (Pmode, XEXP (dstmem, 0)); --+ src_base_reg = copy_to_mode_reg (Pmode, XEXP (srcmem, 0)); --+ /* andi $size_least_3_bit, $size, #~7 */ --+ size_least_3_bit = expand_binop (SImode, and_optab, size, mask_least_3_bit, --+ NULL_RTX, 0, OPTAB_WIDEN); --+ /* add $dst_end, $dst, $size */ --+ dst_end = expand_binop (Pmode, add_optab, dst_base_reg, size, --+ NULL_RTX, 0, OPTAB_WIDEN); --+ --+ /* move $dst_itr, $dst --+ move $src_itr, $src */ --+ emit_move_insn (dst_itr, dst_base_reg); --+ emit_move_insn (src_itr, src_base_reg); --+ --+ /* beqz $size_least_3_bit, .Lbyte_mode_entry ! Not large enough. */ --+ emit_cmp_and_jump_insns (size_least_3_bit, const0_rtx, EQ, NULL, --+ SImode, 1, byte_mode_entry); --+ if (TARGET_HWLOOP && use_zol_p) --+ { --+ rtx start_label = gen_rtx_LABEL_REF (Pmode, double_word_mode_loop); --+ /* We use multiple-load/store instruction once to process 8-bytes, --+ division 8-bytes for one cycle, generate --+ srli $size_least_3_bit, size_least_3_bit, 3. */ --+ emit_insn (gen_lshrsi3 (size_least_3_bit, size_least_3_bit, GEN_INT (3))); --+ /* mtlbi .Ldouble_word_mode_loop */ --+ emit_insn (gen_mtlbi_hint (start_label, GEN_INT (hwloop_id))); --+ emit_insn (gen_init_lc (size_least_3_bit, GEN_INT (hwloop_id))); --+ emit_insn (gen_no_hwloop ()); --+ } --+ else --+ { --+ /* add $double_word_end, $dst, $size_least_3_bit */ --+ double_word_end = expand_binop (Pmode, add_optab, --+ dst_base_reg, size_least_3_bit, --+ NULL_RTX, 0, OPTAB_WIDEN); --+ } --+ --+ /* .Ldouble_word_mode_loop: */ --+ emit_label (double_word_mode_loop); --+ /* lmw.bim $tmp-begin, [$src_itr], $tmp-end, #0 ! $src_itr' = $src_itr --+ smw.bim $tmp-begin, [$dst_itr], $tmp-end, #0 ! $dst_itr' = $dst_itr */ --+ src_itr_m = src_itr; --+ dst_itr_m = dst_itr; --+ srcmem_m = srcmem; --+ dstmem_m = dstmem; --+ nds32_emit_mem_move_block (start_regno, 2, --+ &dst_itr_m, &dstmem_m, --+ &src_itr_m, &srcmem_m, --+ true); --+ /* move $src_itr, $src_itr' --+ move $dst_itr, $dst_itr' */ --+ emit_move_insn (dst_itr, dst_itr_m); --+ emit_move_insn (src_itr, src_itr_m); --+ --+ if (TARGET_HWLOOP && use_zol_p) --+ { --+ rtx start_label = gen_rtx_LABEL_REF (Pmode, double_word_mode_loop); --+ /* Hwloop pseduo instrtion to handle CFG. */ --+ rtx cfg_insn = emit_jump_insn (gen_hwloop_cfg (GEN_INT (hwloop_id), --+ start_label)); --+ JUMP_LABEL (cfg_insn) = double_word_mode_loop; --+ cfun->machine->hwloop_group_id++; --+ } --+ else --+ { --+ /* ! Not readch upper bound. Loop. --+ bne $double_word_end, $dst_itr, .Ldouble_word_mode_loop */ --+ emit_cmp_and_jump_insns (double_word_end, dst_itr, NE, NULL, --+ Pmode, 1, double_word_mode_loop); --+ } --+ --+ /* .Lbyte_mode_entry: */ --+ emit_label (byte_mode_entry); --+ --+ /* beq $dst_itr, $dst_end, .Lend_label */ --+ emit_cmp_and_jump_insns (dst_itr, dst_end, EQ, NULL, --+ Pmode, 1, end_label); --+ /* .Lbyte_mode_loop: */ --+ emit_label (byte_mode_loop); --+ --+ emit_insn (gen_no_hwloop ()); --+ /* lbi.bi $tmp, [$src_itr], #1 */ --+ nds32_emit_post_inc_load_store (tmp, src_itr, QImode, true); --+ --+ /* sbi.bi $tmp, [$dst_itr], #1 */ --+ nds32_emit_post_inc_load_store (tmp, dst_itr, QImode, false); --+ /* ! Not readch upper bound. Loop. --+ bne $dst_itr, $dst_end, .Lbyte_mode_loop */ --+ emit_cmp_and_jump_insns (dst_itr, dst_end, NE, NULL, --+ SImode, 1, byte_mode_loop); --+ --+ /* .Lend_label: */ --+ emit_label (end_label); --+ --+ return true; --+} --+ --+static bool --+nds32_expand_movmemsi_loop_known_size (rtx dstmem, rtx srcmem, --+ rtx size, rtx alignment) --+{ --+ rtx dst_base_reg, src_base_reg; --+ rtx dst_itr, src_itr; --+ rtx dstmem_m, srcmem_m, dst_itr_m, src_itr_m; --+ rtx dst_end; --+ rtx double_word_mode_loop, byte_mode_loop; --+ rtx tmp; --+ int start_regno; --+ bool align_to_4_bytes = (INTVAL (alignment) & 3) == 0; --+ int hwloop_id = cfun->machine->hwloop_group_id; --+ unsigned HOST_WIDE_INT total_bytes = UINTVAL (size); --+ --+ if (TARGET_ISA_V3M && !align_to_4_bytes) --+ return 0; --+ --+ if (TARGET_REDUCED_REGS) --+ start_regno = 2; --+ else --+ start_regno = 16; --+ --+ dst_itr = gen_reg_rtx (Pmode); --+ src_itr = gen_reg_rtx (Pmode); --+ dst_end = gen_reg_rtx (Pmode); --+ tmp = gen_reg_rtx (QImode); --+ --+ double_word_mode_loop = gen_label_rtx (); --+ byte_mode_loop = gen_label_rtx (); --+ --+ dst_base_reg = copy_to_mode_reg (Pmode, XEXP (dstmem, 0)); --+ src_base_reg = copy_to_mode_reg (Pmode, XEXP (srcmem, 0)); --+ --+ if (total_bytes < 8) --+ { --+ /* Emit total_bytes less than 8 loop version of movmem. --+ add $dst_end, $dst, $size --+ move $dst_itr, $dst --+ .Lbyte_mode_loop: --+ lbi.bi $tmp, [$src_itr], #1 --+ sbi.bi $tmp, [$dst_itr], #1 --+ ! Not readch upper bound. Loop. --+ bne $dst_itr, $dst_end, .Lbyte_mode_loop */ --+ --+ /* add $dst_end, $dst, $size */ --+ dst_end = expand_binop (Pmode, add_optab, dst_base_reg, size, --+ NULL_RTX, 0, OPTAB_WIDEN); --+ /* move $dst_itr, $dst --+ move $src_itr, $src */ --+ emit_move_insn (dst_itr, dst_base_reg); --+ emit_move_insn (src_itr, src_base_reg); --+ --+ /* .Lbyte_mode_loop: */ --+ emit_label (byte_mode_loop); --+ --+ emit_insn (gen_no_hwloop ()); --+ /* lbi.bi $tmp, [$src_itr], #1 */ --+ nds32_emit_post_inc_load_store (tmp, src_itr, QImode, true); --+ --+ /* sbi.bi $tmp, [$dst_itr], #1 */ --+ nds32_emit_post_inc_load_store (tmp, dst_itr, QImode, false); --+ /* ! Not readch upper bound. Loop. --+ bne $dst_itr, $dst_end, .Lbyte_mode_loop */ --+ emit_cmp_and_jump_insns (dst_itr, dst_end, NE, NULL, --+ SImode, 1, byte_mode_loop); --+ return true; --+ } --+ else if (total_bytes % 8 == 0) --+ { --+ /* Emit multiple of 8 loop version of movmem. --+ --+ add $dst_end, $dst, $size --+ move $dst_itr, $dst --+ move $src_itr, $src --+ --+ .Ldouble_word_mode_loop: --+ lmw.bim $tmp-begin, [$src_itr], $tmp-end, #0 ! $src_itr' = $src_itr --+ smw.bim $tmp-begin, [$dst_itr], $tmp-end, #0 ! $dst_itr' = $dst_itr --+ ! move will delete after register allocation --+ move $src_itr, $src_itr' --+ move $dst_itr, $dst_itr' --+ ! Not readch upper bound. Loop. --+ bne $double_word_end, $dst_itr, .Ldouble_word_mode_loop */ --+ --+ if (TARGET_HWLOOP) --+ { --+ rtx start_label = gen_rtx_LABEL_REF (Pmode, double_word_mode_loop); --+ --+ rtx loop_count_reg = gen_reg_rtx (Pmode); --+ /* movi $loop_count_reg, total_bytes / 8 */ --+ emit_move_insn (loop_count_reg, GEN_INT (total_bytes / 8)); --+ /* mtlbi .Ldouble_word_mode_loop */ --+ emit_insn (gen_mtlbi_hint (start_label, GEN_INT (hwloop_id))); --+ /* mtusr $loop_count_reg, LC */ --+ emit_insn (gen_init_lc (loop_count_reg, GEN_INT (hwloop_id))); --+ emit_insn (gen_no_hwloop ()); --+ } --+ else --+ { --+ /* add $dst_end, $dst, $size */ --+ dst_end = expand_binop (Pmode, add_optab, dst_base_reg, size, --+ NULL_RTX, 0, OPTAB_WIDEN); --+ } --+ --+ /* move $dst_itr, $dst --+ move $src_itr, $src */ --+ emit_move_insn (dst_itr, dst_base_reg); --+ emit_move_insn (src_itr, src_base_reg); --+ --+ /* .Ldouble_word_mode_loop: */ --+ emit_label (double_word_mode_loop); --+ /* lmw.bim $tmp-begin, [$src_itr], $tmp-end, #0 ! $src_itr' = $src_itr --+ smw.bim $tmp-begin, [$dst_itr], $tmp-end, #0 ! $dst_itr' = $dst_itr */ --+ src_itr_m = src_itr; --+ dst_itr_m = dst_itr; --+ srcmem_m = srcmem; --+ dstmem_m = dstmem; --+ nds32_emit_mem_move_block (start_regno, 2, --+ &dst_itr_m, &dstmem_m, --+ &src_itr_m, &srcmem_m, --+ true); --+ /* move $src_itr, $src_itr' --+ move $dst_itr, $dst_itr' */ --+ emit_move_insn (dst_itr, dst_itr_m); --+ emit_move_insn (src_itr, src_itr_m); --+ --+ if (TARGET_HWLOOP) --+ { --+ rtx start_label = gen_rtx_LABEL_REF (Pmode, double_word_mode_loop); --+ /* Hwloop pseduo instrtion to handle CFG. */ --+ rtx cfg_insn = emit_jump_insn (gen_hwloop_cfg (GEN_INT (hwloop_id), --+ start_label)); --+ JUMP_LABEL (cfg_insn) = double_word_mode_loop; --+ cfun->machine->hwloop_group_id++; --+ } --+ else --+ { --+ /* ! Not readch upper bound. Loop. --+ bne $double_word_end, $dst_itr, .Ldouble_word_mode_loop */ --+ emit_cmp_and_jump_insns (dst_end, dst_itr, NE, NULL, --+ Pmode, 1, double_word_mode_loop); --+ } --+ } --+ else --+ { --+ /* Handle size greater than 8, and not a multiple of 8. */ --+ return nds32_expand_movmemsi_loop_unknown_size (dstmem, srcmem, --+ size, alignment, --+ true); --+ } --+ --+ return true; --+} --+ --+static bool --+nds32_expand_movmemsi_loop (rtx dstmem, rtx srcmem, --+ rtx size, rtx alignment) --+{ --+ if (CONST_INT_P (size)) --+ return nds32_expand_movmemsi_loop_known_size (dstmem, srcmem, --+ size, alignment); --+ else --+ return nds32_expand_movmemsi_loop_unknown_size (dstmem, srcmem, --+ size, alignment, false); --+} --+ --+static bool --+nds32_expand_movmemsi_unroll (rtx dstmem, rtx srcmem, --+ rtx total_bytes, rtx alignment) --+{ --+ rtx dst_base_reg, src_base_reg; --+ rtx tmp_reg; --+ int maximum_bytes; --+ int maximum_bytes_per_inst; --+ int maximum_regs; --+ int start_regno; --+ int i, inst_num; --+ HOST_WIDE_INT remain_bytes, remain_words; --+ bool align_to_4_bytes = (INTVAL (alignment) & 3) == 0; --+ bool align_to_2_bytes = (INTVAL (alignment) & 1) == 0; --+ --+ /* Because reduced-set regsiters has few registers --+ (r0~r5, r6~10, r15, r28~r31, where 'r15' and 'r28~r31' --+ cannot be used for register allocation), --+ using 8 registers (32 bytes) for moving memory block --+ may easily consume all of them. --+ It makes register allocation/spilling hard to work. --+ So we only allow maximum=4 registers (16 bytes) for --+ moving memory block under reduced-set registers. */ --+ if (TARGET_REDUCED_REGS) --+ { --+ maximum_regs = 4; --+ maximum_bytes = 64; --+ start_regno = 2; --+ } --+ else --+ { --+ if (TARGET_LINUX_ABI) --+ { --+ /* $r25 is $tp so we use up to 8 registers if using Linux ABI. */ --+ maximum_regs = 8; --+ maximum_bytes = 160; --+ start_regno = 16; --+ } --+ else --+ { --+ maximum_regs = 10; --+ maximum_bytes = 160; --+ start_regno = 16; --+ } --+ } --+ maximum_bytes_per_inst = maximum_regs * UNITS_PER_WORD; --+ --+ /* 1. Total_bytes is integer for sure. --+ 2. Alignment is integer for sure. --+ 3. Maximum 4 or 10 registers and up to 4 instructions, --+ 4 * 4 * 4 = 64 bytes, 8 * 4 * 10 = 160 bytes. --+ 4. The dstmem cannot be volatile memory access. --+ 5. The srcmem cannot be volatile memory access. --+ 6. Known shared alignment not align to 4 byte in v3m since lmw/smw *NOT* --+ support unalign access with v3m configure. */ --+ if (GET_CODE (total_bytes) != CONST_INT --+ || GET_CODE (alignment) != CONST_INT --+ || INTVAL (total_bytes) > maximum_bytes --+ || MEM_VOLATILE_P (dstmem) --+ || MEM_VOLATILE_P (srcmem) --+ || (TARGET_ISA_V3M && !align_to_4_bytes)) --+ return false; --+ --+ dst_base_reg = copy_to_mode_reg (SImode, XEXP (dstmem, 0)); --+ src_base_reg = copy_to_mode_reg (SImode, XEXP (srcmem, 0)); --+ remain_bytes = INTVAL (total_bytes); --+ --+ /* Do not update base address for last lmw/smw pair. */ --+ inst_num = ((INTVAL (total_bytes) + (maximum_bytes_per_inst - 1)) --+ / maximum_bytes_per_inst) - 1; --+ --+ for (i = 0; i < inst_num; i++) --+ { --+ nds32_emit_mem_move_block (start_regno, maximum_regs, --+ &dst_base_reg, &dstmem, --+ &src_base_reg, &srcmem, --+ true); --+ } --+ remain_bytes -= maximum_bytes_per_inst * inst_num; --+ --+ remain_words = remain_bytes / UNITS_PER_WORD; --+ remain_bytes = remain_bytes - (remain_words * UNITS_PER_WORD); --+ --+ if (remain_words != 0) --+ { --+ if (remain_bytes != 0) --+ nds32_emit_mem_move_block (start_regno, remain_words, --+ &dst_base_reg, &dstmem, --+ &src_base_reg, &srcmem, --+ true); --+ else --+ { --+ /* Do not update address if no further byte to move. */ --+ if (remain_words == 1) --+ { --+ /* emit move instruction if align to 4 byte and only 1 --+ word to move. */ --+ if (align_to_4_bytes) --+ nds32_emit_mem_move (srcmem, dstmem, SImode, 0); --+ else --+ { --+ tmp_reg = gen_reg_rtx (SImode); --+ emit_insn ( --+ gen_unaligned_load_w (tmp_reg, --+ gen_rtx_MEM (SImode, src_base_reg))); --+ emit_insn ( --+ gen_unaligned_store_w (gen_rtx_MEM (SImode, dst_base_reg), --+ tmp_reg)); --+ } --+ } --+ else --+ nds32_emit_mem_move_block (start_regno, remain_words, --+ &dst_base_reg, &dstmem, --+ &src_base_reg, &srcmem, --+ false); --+ } --+ } --+ --+ switch (remain_bytes) --+ { --+ case 3: --+ case 2: --+ { --+ if (align_to_2_bytes) --+ nds32_emit_mem_move (srcmem, dstmem, HImode, 0); --+ else --+ { --+ nds32_emit_mem_move (srcmem, dstmem, QImode, 0); --+ nds32_emit_mem_move (srcmem, dstmem, QImode, 1); --+ } --+ --+ if (remain_bytes == 3) --+ nds32_emit_mem_move (srcmem, dstmem, QImode, 2); --+ break; --+ } --+ case 1: --+ nds32_emit_mem_move (srcmem, dstmem, QImode, 0); --+ break; --+ case 0: --+ break; --+ default: --+ gcc_unreachable (); --+ } --+ --+ /* Successfully create patterns, return true. */ --+ return true; --+} --+ --+/* Function to move block memory content by --+ using load_multiple and store_multiple. --+ This is auxiliary extern function to help create rtx template. --+ Check nds32-multiple.md file for the patterns. */ --+bool --+nds32_expand_movmemsi (rtx dstmem, rtx srcmem, rtx total_bytes, rtx alignment) --+{ --+ if (nds32_expand_movmemsi_unroll (dstmem, srcmem, total_bytes, alignment)) --+ return true; --+ --+ if (!optimize_size && optimize > 2) --+ return nds32_expand_movmemsi_loop (dstmem, srcmem, total_bytes, alignment); --+ --+ return false; --+} --+ --+/* ------------------------------------------------------------------------ */ --+ --+/* PART 3: Auxiliary function for expand setmem pattern. */ --+ --+static rtx --+nds32_gen_dup_4_byte_to_word_value_aux (rtx value, rtx value4word) --+{ --+ gcc_assert (GET_MODE (value) == QImode || CONST_INT_P (value)); --+ --+ if (CONST_INT_P (value)) --+ { --+ unsigned HOST_WIDE_INT val = UINTVAL (value) & GET_MODE_MASK(QImode); --+ rtx new_val = gen_int_mode (val | (val << 8) --+ | (val << 16) | (val << 24), SImode); --+ /* Just calculate at here if it's constant value. */ --+ emit_move_insn (value4word, new_val); --+ } --+ else --+ { --+ if (NDS32_EXT_DSP_P ()) --+ { --+ /* ! prepare word --+ insb $tmp, $value, 1 ! $tmp <- 0x0000abab --+ pkbb16 $tmp6, $tmp2, $tmp2 ! $value4word <- 0xabababab */ --+ rtx tmp = gen_reg_rtx (SImode); --+ --+ convert_move (tmp, value, true); --+ --+ emit_insn ( --+ gen_insvsi_internal (tmp, gen_int_mode (0x8, SImode), tmp)); --+ --+ emit_insn (gen_pkbbsi_1 (value4word, tmp, tmp)); --+ } --+ else --+ { --+ /* ! prepare word --+ andi $tmp1, $value, 0xff ! $tmp1 <- 0x000000ab --+ slli $tmp2, $tmp1, 8 ! $tmp2 <- 0x0000ab00 --+ or $tmp3, $tmp1, $tmp2 ! $tmp3 <- 0x0000abab --+ slli $tmp4, $tmp3, 16 ! $tmp4 <- 0xabab0000 --+ or $val4word, $tmp3, $tmp4 ! $value4word <- 0xabababab */ --+ --+ rtx tmp1, tmp2, tmp3, tmp4; --+ tmp1 = expand_binop (SImode, and_optab, value, --+ gen_int_mode (0xff, SImode), --+ NULL_RTX, 0, OPTAB_WIDEN); --+ tmp2 = expand_binop (SImode, ashl_optab, tmp1, --+ gen_int_mode (8, SImode), --+ NULL_RTX, 0, OPTAB_WIDEN); --+ tmp3 = expand_binop (SImode, ior_optab, tmp1, tmp2, --+ NULL_RTX, 0, OPTAB_WIDEN); --+ tmp4 = expand_binop (SImode, ashl_optab, tmp3, --+ gen_int_mode (16, SImode), --+ NULL_RTX, 0, OPTAB_WIDEN); --+ --+ emit_insn (gen_iorsi3 (value4word, tmp3, tmp4)); --+ } --+ } --+ --+ return value4word; --+} --+ --+static rtx --+nds32_gen_dup_4_byte_to_word_value (rtx value) --+{ --+ rtx value4word = gen_reg_rtx (SImode); --+ nds32_gen_dup_4_byte_to_word_value_aux (value, value4word); --+ --+ return value4word; --+} --+ --+static rtx --+nds32_gen_dup_8_byte_to_double_word_value (rtx value) --+{ --+ rtx value4doubleword = gen_reg_rtx (DImode); --+ --+ nds32_gen_dup_4_byte_to_word_value_aux ( --+ value, nds32_di_low_part_subreg(value4doubleword)); --+ --+ emit_move_insn (nds32_di_high_part_subreg(value4doubleword), --+ nds32_di_low_part_subreg(value4doubleword)); --+ return value4doubleword; --+} --+ --+ --+static rtx --+emit_setmem_doubleword_loop (rtx itr, rtx size, rtx value) --+{ --+ rtx word_mode_label = gen_label_rtx (); --+ rtx word_mode_end_label = gen_label_rtx (); --+ rtx byte_mode_size = gen_reg_rtx (SImode); --+ rtx byte_mode_size_tmp = gen_reg_rtx (SImode); --+ rtx word_mode_end = gen_reg_rtx (SImode); --+ rtx size_for_word = gen_reg_rtx (SImode); --+ --+ /* and $size_for_word, $size, #~0x7 */ --+ size_for_word = expand_binop (SImode, and_optab, size, --+ gen_int_mode (~0x7, SImode), --+ NULL_RTX, 0, OPTAB_WIDEN); --+ --+ emit_move_insn (byte_mode_size, size); --+ --+ /* beqz $size_for_word, .Lbyte_mode_entry */ --+ emit_cmp_and_jump_insns (size_for_word, const0_rtx, EQ, NULL, --+ SImode, 1, word_mode_end_label); --+ /* add $word_mode_end, $dst, $size_for_word */ --+ word_mode_end = expand_binop (Pmode, add_optab, itr, size_for_word, --+ NULL_RTX, 0, OPTAB_WIDEN); --+ --+ /* andi $byte_mode_size, $size, 0x7 */ --+ byte_mode_size_tmp = expand_binop (SImode, and_optab, size, GEN_INT (0x7), --+ NULL_RTX, 0, OPTAB_WIDEN); --+ --+ emit_move_insn (byte_mode_size, byte_mode_size_tmp); --+ --+ /* .Lword_mode: */ --+ emit_label (word_mode_label); --+ /* ! word-mode set loop --+ smw.bim $value4word, [$dst_itr], $value4word, 0 --+ bne $word_mode_end, $dst_itr, .Lword_mode */ --+ emit_insn (gen_unaligned_store_update_base_dw (itr, --+ itr, --+ value)); --+ emit_cmp_and_jump_insns (word_mode_end, itr, NE, NULL, --+ Pmode, 1, word_mode_label); --+ --+ emit_label (word_mode_end_label); --+ --+ return byte_mode_size; --+} --+ --+static rtx --+emit_setmem_byte_loop (rtx itr, rtx size, rtx value, bool need_end) --+{ --+ rtx end = gen_reg_rtx (Pmode); --+ rtx byte_mode_label = gen_label_rtx (); --+ rtx end_label = gen_label_rtx (); --+ --+ value = force_reg (QImode, value); --+ --+ if (need_end) --+ end = expand_binop (Pmode, add_optab, itr, size, --+ NULL_RTX, 0, OPTAB_WIDEN); --+ /* beqz $byte_mode_size, .Lend --+ add $byte_mode_end, $dst_itr, $byte_mode_size */ --+ emit_cmp_and_jump_insns (size, const0_rtx, EQ, NULL, --+ SImode, 1, end_label); --+ --+ if (!need_end) --+ end = expand_binop (Pmode, add_optab, itr, size, --+ NULL_RTX, 0, OPTAB_WIDEN); --+ --+ /* .Lbyte_mode: */ --+ emit_label (byte_mode_label); --+ --+ emit_insn (gen_no_hwloop ()); --+ /* ! byte-mode set loop --+ sbi.bi $value, [$dst_itr] ,1 --+ bne $byte_mode_end, $dst_itr, .Lbyte_mode */ --+ nds32_emit_post_inc_load_store (value, itr, QImode, false); --+ --+ emit_cmp_and_jump_insns (end, itr, NE, NULL, --+ Pmode, 1, byte_mode_label); --+ /* .Lend: */ --+ emit_label (end_label); --+ --+ if (need_end) --+ return end; --+ else --+ return NULL_RTX; --+} --+ --+static bool --+nds32_expand_setmem_loop (rtx dstmem, rtx size, rtx value) --+{ --+ rtx value4doubleword; --+ rtx value4byte; --+ rtx dst; --+ rtx byte_mode_size; --+ --+ /* Emit loop version of setmem. --+ memset: --+ ! prepare word --+ andi $tmp1, $val, 0xff ! $tmp1 <- 0x000000ab --+ slli $tmp2, $tmp1, 8 ! $tmp2 <- 0x0000ab00 --+ or $tmp3, $val, $tmp2 ! $tmp3 <- 0x0000abab --+ slli $tmp4, $tmp3, 16 ! $tmp4 <- 0xabab0000 --+ or $val4word, $tmp3, $tmp4 ! $value4word <- 0xabababab --+ --+ and $size_for_word, $size, #-4 --+ beqz $size_for_word, .Lword_mode_end --+ --+ add $word_mode_end, $dst, $size_for_word --+ andi $byte_mode_size, $size, 3 --+ --+ .Lword_mode: --+ ! word-mode set loop --+ smw.bim $value4word, [$dst], $value4word, 0 --+ bne $word_mode_end, $dst, .Lword_mode --+ --+ .Lword_mode_end: --+ beqz $byte_mode_size, .Lend --+ add $byte_mode_end, $dst, $byte_mode_size --+ --+ .Lbyte_mode: --+ ! byte-mode set loop --+ sbi.bi $value4word, [$dst] ,1 --+ bne $byte_mode_end, $dst, .Lbyte_mode --+ .Lend: */ --+ --+ dst = copy_to_mode_reg (SImode, XEXP (dstmem, 0)); --+ --+ /* ! prepare word --+ andi $tmp1, $value, 0xff ! $tmp1 <- 0x000000ab --+ slli $tmp2, $tmp1, 8 ! $tmp2 <- 0x0000ab00 --+ or $tmp3, $tmp1, $tmp2 ! $tmp3 <- 0x0000abab --+ slli $tmp4, $tmp3, 16 ! $tmp4 <- 0xabab0000 --+ or $val4word, $tmp3, $tmp4 ! $value4word <- 0xabababab */ --+ value4doubleword = nds32_gen_dup_8_byte_to_double_word_value (value); --+ --+ /* and $size_for_word, $size, #-4 --+ beqz $size_for_word, .Lword_mode_end --+ --+ add $word_mode_end, $dst, $size_for_word --+ andi $byte_mode_size, $size, 3 --+ --+ .Lword_mode: --+ ! word-mode set loop --+ smw.bim $value4word, [$dst], $value4word, 0 --+ bne $word_mode_end, $dst, .Lword_mode --+ .Lword_mode_end: */ --+ byte_mode_size = emit_setmem_doubleword_loop (dst, size, value4doubleword); --+ --+ /* beqz $byte_mode_size, .Lend --+ add $byte_mode_end, $dst, $byte_mode_size --+ --+ .Lbyte_mode: --+ ! byte-mode set loop --+ sbi.bi $value, [$dst] ,1 --+ bne $byte_mode_end, $dst, .Lbyte_mode --+ .Lend: */ --+ --+ value4byte = simplify_gen_subreg (QImode, value4doubleword, DImode, --+ subreg_lowpart_offset (QImode, DImode)); --+ --+ emit_setmem_byte_loop (dst, byte_mode_size, value4byte, false); --+ --+ return true; --+} --+ --+static bool --+nds32_expand_setmem_loop_v3m (rtx dstmem, rtx size, rtx value) --+{ --+ rtx base_reg = copy_to_mode_reg (Pmode, XEXP (dstmem, 0)); --+ rtx need_align_bytes = gen_reg_rtx (SImode); --+ rtx last_2_bit = gen_reg_rtx (SImode); --+ rtx byte_loop_base = gen_reg_rtx (SImode); --+ rtx byte_loop_size = gen_reg_rtx (SImode); --+ rtx remain_size = gen_reg_rtx (SImode); --+ rtx new_base_reg; --+ rtx value4byte, value4doubleword; --+ rtx byte_mode_size; --+ rtx last_byte_loop_label = gen_label_rtx (); --+ --+ size = force_reg (SImode, size); --+ --+ value4doubleword = nds32_gen_dup_8_byte_to_double_word_value (value); --+ value4byte = simplify_gen_subreg (QImode, value4doubleword, DImode, --+ subreg_lowpart_offset (QImode, DImode)); --+ --+ emit_move_insn (byte_loop_size, size); --+ emit_move_insn (byte_loop_base, base_reg); --+ --+ /* Jump to last byte loop if size is less than 16. */ --+ emit_cmp_and_jump_insns (size, gen_int_mode (16, SImode), LE, NULL, --+ SImode, 1, last_byte_loop_label); --+ --+ /* Make sure align to 4 byte first since v3m can't unalign access. */ --+ emit_insn (gen_andsi3 (last_2_bit, --+ base_reg, --+ gen_int_mode (0x3, SImode))); --+ --+ emit_insn (gen_subsi3 (need_align_bytes, --+ gen_int_mode (4, SImode), --+ last_2_bit)); --+ --+ /* Align to 4 byte. */ --+ new_base_reg = emit_setmem_byte_loop (base_reg, --+ need_align_bytes, --+ value4byte, --+ true); --+ --+ /* Calculate remain size. */ --+ emit_insn (gen_subsi3 (remain_size, size, need_align_bytes)); --+ --+ /* Set memory word by word. */ --+ byte_mode_size = emit_setmem_doubleword_loop (new_base_reg, --+ remain_size, --+ value4doubleword); --+ --+ emit_move_insn (byte_loop_base, new_base_reg); --+ emit_move_insn (byte_loop_size, byte_mode_size); --+ --+ emit_label (last_byte_loop_label); --+ --+ /* And set memory for remain bytes. */ --+ emit_setmem_byte_loop (byte_loop_base, byte_loop_size, value4byte, false); --+ return true; --+} --+ --+static bool --+nds32_expand_setmem_unroll (rtx dstmem, rtx size, rtx value, --+ rtx align ATTRIBUTE_UNUSED, --+ rtx expected_align ATTRIBUTE_UNUSED, --+ rtx expected_size ATTRIBUTE_UNUSED) --+{ --+ unsigned maximum_regs, maximum_bytes, start_regno, regno; --+ rtx value4word; --+ rtx dst_base_reg, new_base_reg; --+ unsigned HOST_WIDE_INT remain_bytes, remain_words, prepare_regs, fill_per_smw; --+ unsigned HOST_WIDE_INT real_size; --+ --+ if (TARGET_REDUCED_REGS) --+ { --+ maximum_regs = 4; --+ maximum_bytes = 64; --+ start_regno = 2; --+ } --+ else --+ { --+ maximum_regs = 8; --+ maximum_bytes = 128; --+ start_regno = 16; --+ } --+ --+ real_size = UINTVAL (size) & GET_MODE_MASK(SImode); --+ --+ if (!(CONST_INT_P (size) && real_size <= maximum_bytes)) --+ return false; --+ --+ remain_bytes = real_size; --+ --+ gcc_assert (GET_MODE (value) == QImode || CONST_INT_P (value)); --+ --+ value4word = nds32_gen_dup_4_byte_to_word_value (value); --+ --+ prepare_regs = remain_bytes / UNITS_PER_WORD; --+ --+ dst_base_reg = copy_to_mode_reg (SImode, XEXP (dstmem, 0)); --+ --+ if (prepare_regs > maximum_regs) --+ prepare_regs = maximum_regs; --+ --+ fill_per_smw = prepare_regs * UNITS_PER_WORD; --+ --+ regno = start_regno; --+ switch (prepare_regs) --+ { --+ case 2: --+ default: --+ { --+ rtx reg0 = gen_rtx_REG (SImode, regno); --+ rtx reg1 = gen_rtx_REG (SImode, regno+1); --+ unsigned last_regno = start_regno + prepare_regs - 1; --+ --+ emit_move_insn (reg0, value4word); --+ emit_move_insn (reg1, value4word); --+ rtx regd = gen_rtx_REG (DImode, regno); --+ regno += 2; --+ --+ /* Try to utilize movd44! */ --+ while (regno <= last_regno) --+ { --+ if ((regno + 1) <=last_regno) --+ { --+ rtx reg = gen_rtx_REG (DImode, regno); --+ emit_move_insn (reg, regd); --+ regno += 2; --+ } --+ else --+ { --+ rtx reg = gen_rtx_REG (SImode, regno); --+ emit_move_insn (reg, reg0); --+ regno += 1; --+ } --+ } --+ break; --+ } --+ case 1: --+ { --+ rtx reg = gen_rtx_REG (SImode, regno++); --+ emit_move_insn (reg, value4word); --+ } --+ break; --+ case 0: --+ break; --+ } --+ --+ if (fill_per_smw) --+ for (;remain_bytes >= fill_per_smw;remain_bytes -= fill_per_smw) --+ { --+ emit_insn (nds32_expand_store_multiple (start_regno, prepare_regs, --+ dst_base_reg, dstmem, --+ true, &new_base_reg)); --+ dst_base_reg = new_base_reg; --+ dstmem = gen_rtx_MEM (SImode, dst_base_reg); --+ } --+ --+ remain_words = remain_bytes / UNITS_PER_WORD; --+ --+ if (remain_words) --+ { --+ emit_insn (nds32_expand_store_multiple (start_regno, remain_words, --+ dst_base_reg, dstmem, --+ true, &new_base_reg)); --+ dst_base_reg = new_base_reg; --+ dstmem = gen_rtx_MEM (SImode, dst_base_reg); --+ } --+ --+ remain_bytes = remain_bytes - (remain_words * UNITS_PER_WORD); --+ --+ if (remain_bytes) --+ { --+ value = simplify_gen_subreg (QImode, value4word, SImode, --+ subreg_lowpart_offset(QImode, SImode)); --+ int offset = 0; --+ for (;remain_bytes;--remain_bytes, ++offset) --+ { --+ nds32_emit_load_store (value, dstmem, QImode, offset, false); --+ } --+ } --+ --+ return true; --+} --+ --+bool --+nds32_expand_setmem (rtx dstmem, rtx size, rtx value, rtx align, --+ rtx expected_align, --+ rtx expected_size) --+{ --+ bool align_to_4_bytes = (INTVAL (align) & 3) == 0; --+ --+ /* Only expand at O3 */ --+ if (optimize_size || optimize < 3) --+ return false; --+ --+ if (TARGET_ISA_V3M && !align_to_4_bytes) --+ return nds32_expand_setmem_loop_v3m (dstmem, size, value); --+ --+ if (nds32_expand_setmem_unroll (dstmem, size, value, --+ align, expected_align, expected_size)) --+ return true; --+ --+ return nds32_expand_setmem_loop (dstmem, size, value); --+} --+ --+/* ------------------------------------------------------------------------ */ --+ --+/* PART 4: Auxiliary function for expand movstr pattern. */ --+ --+bool --+nds32_expand_movstr (rtx dst_end_ptr, --+ rtx dstmem, --+ rtx srcmem) --+{ --+ rtx tmp; --+ rtx dst_base_reg, src_base_reg; --+ rtx new_dst_base_reg, new_src_base_reg; --+ rtx last_non_null_char_ptr; --+ rtx ffbi_result; --+ rtx loop_label; --+ --+ if (optimize_size || optimize < 3) --+ return false; --+ --+ tmp = gen_reg_rtx (SImode); --+ ffbi_result = gen_reg_rtx (Pmode); --+ new_dst_base_reg = gen_reg_rtx (Pmode); --+ new_src_base_reg = gen_reg_rtx (Pmode); --+ dst_base_reg = copy_to_mode_reg (SImode, XEXP (dstmem, 0)); --+ src_base_reg = copy_to_mode_reg (SImode, XEXP (srcmem, 0)); --+ loop_label = gen_label_rtx (); --+ --+ emit_label (loop_label); --+ emit_insn (gen_lmwzb (new_src_base_reg, src_base_reg, tmp)); --+ emit_insn (gen_smwzb (new_dst_base_reg, dst_base_reg, tmp)); --+ emit_insn (gen_unspec_ffb (ffbi_result, tmp, const0_rtx)); --+ --+ emit_move_insn (src_base_reg, new_src_base_reg); --+ emit_move_insn (dst_base_reg, new_dst_base_reg); --+ --+ emit_cmp_and_jump_insns (ffbi_result, const0_rtx, EQ, NULL, --+ SImode, 1, loop_label); --+ --+ last_non_null_char_ptr = expand_binop (Pmode, add_optab, dst_base_reg, --+ ffbi_result, NULL_RTX, 0, OPTAB_WIDEN); --+ --+ emit_move_insn (dst_end_ptr, last_non_null_char_ptr); --+ --+ return true; --+} --+ --+/* ------------------------------------------------------------------------ */ --+ --+/* PART 5: Auxiliary function for expand strlen pattern. */ --+ --+bool --+nds32_expand_strlen (rtx result, rtx str, --+ rtx target_char, rtx align ATTRIBUTE_UNUSED) --+{ --+ rtx base_reg, backup_base_reg; --+ rtx ffb_result; --+ rtx target_char_ptr, length; --+ rtx loop_label, tmp; --+ --+ if (optimize_size || optimize < 3) --+ return false; --+ --+ gcc_assert (MEM_P (str)); --+ gcc_assert (CONST_INT_P (target_char) || REG_P (target_char)); --+ --+ base_reg = copy_to_mode_reg (SImode, XEXP (str, 0)); --+ loop_label = gen_label_rtx (); --+ --+ ffb_result = gen_reg_rtx (Pmode); --+ tmp = gen_reg_rtx (SImode); --+ backup_base_reg = gen_reg_rtx (SImode); --+ --+ /* Emit loop version of strlen. --+ move $backup_base, $base --+ .Lloop: --+ lmw.bim $tmp, [$base], $tmp, 0 --+ ffb $ffb_result, $tmp, $target_char ! is there $target_char? --+ beqz $ffb_result, .Lloop --+ add $last_char_ptr, $base, $ffb_result --+ sub $length, $last_char_ptr, $backup_base */ --+ --+ /* move $backup_base, $base */ --+ emit_move_insn (backup_base_reg, base_reg); --+ --+ /* .Lloop: */ --+ emit_label (loop_label); --+ /* lmw.bim $tmp, [$base], $tmp, 0 */ --+ emit_insn (gen_unaligned_load_update_base_w (base_reg, tmp, base_reg)); --+ --+ /* ffb $ffb_result, $tmp, $target_char ! is there $target_char? */ --+ emit_insn (gen_unspec_ffb (ffb_result, tmp, target_char)); --+ --+ /* beqz $ffb_result, .Lloop */ --+ emit_cmp_and_jump_insns (ffb_result, const0_rtx, EQ, NULL, --+ SImode, 1, loop_label); --+ --+ /* add $target_char_ptr, $base, $ffb_result */ --+ target_char_ptr = expand_binop (Pmode, add_optab, base_reg, --+ ffb_result, NULL_RTX, 0, OPTAB_WIDEN); --+ --+ /* sub $length, $target_char_ptr, $backup_base */ --+ length = expand_binop (Pmode, sub_optab, target_char_ptr, --+ backup_base_reg, NULL_RTX, 0, OPTAB_WIDEN); --+ --+ emit_move_insn (result, length); --+ --+ return true; --+} -- -- /* ------------------------------------------------------------------------ */ -- --+/* PART 6: Auxiliary function for expand load_multiple/store_multiple --+ pattern. */ --+ -- /* Functions to expand load_multiple and store_multiple. -- They are auxiliary extern functions to help create rtx template. -- Check nds32-multiple.md file for the patterns. */ -- rtx -- nds32_expand_load_multiple (int base_regno, int count, --- rtx base_addr, rtx basemem) --+ rtx base_addr, rtx basemem, --+ bool update_base_reg_p, --+ rtx *update_base_reg) -- { -- int par_index; -- int offset; --+ int start_idx; -- rtx result; -- rtx new_addr, mem, reg; -- --+ /* Generate a unaligned load to prevent load instruction pull out from --+ parallel, and then it will generate lwi, and lose unaligned acces */ --+ if (count == 1) --+ { --+ reg = gen_rtx_REG (SImode, base_regno); --+ if (update_base_reg_p) --+ { --+ *update_base_reg = gen_reg_rtx (SImode); --+ return gen_unaligned_load_update_base_w (*update_base_reg, reg, base_addr); --+ } --+ else --+ return gen_unaligned_load_w (reg, gen_rtx_MEM (SImode, base_addr)); --+ } --+ -- /* Create the pattern that is presented in nds32-multiple.md. */ --+ if (update_base_reg_p) --+ { --+ result = gen_rtx_PARALLEL (VOIDmode, rtvec_alloc (count + 1)); --+ start_idx = 1; --+ } --+ else --+ { --+ result = gen_rtx_PARALLEL (VOIDmode, rtvec_alloc (count)); --+ start_idx = 0; --+ } --+ --+ if (update_base_reg_p) --+ { --+ offset = count * 4; --+ new_addr = plus_constant (Pmode, base_addr, offset); --+ *update_base_reg = gen_reg_rtx (SImode); -- --- result = gen_rtx_PARALLEL (VOIDmode, rtvec_alloc (count)); --+ XVECEXP (result, 0, 0) = gen_rtx_SET (*update_base_reg, new_addr); --+ } -- -- for (par_index = 0; par_index < count; par_index++) -- { --@@ -57,7 +1284,7 @@ nds32_expand_load_multiple (int base_regno, int count, -- new_addr, offset); -- reg = gen_rtx_REG (SImode, base_regno + par_index); -- --- XVECEXP (result, 0, par_index) = gen_rtx_SET (reg, mem); --+ XVECEXP (result, 0, (par_index + start_idx)) = gen_rtx_SET (reg, mem); -- } -- -- return result; --@@ -65,16 +1292,49 @@ nds32_expand_load_multiple (int base_regno, int count, -- -- rtx -- nds32_expand_store_multiple (int base_regno, int count, --- rtx base_addr, rtx basemem) --+ rtx base_addr, rtx basemem, --+ bool update_base_reg_p, --+ rtx *update_base_reg) -- { -- int par_index; -- int offset; --+ int start_idx; -- rtx result; -- rtx new_addr, mem, reg; -- --+ if (count == 1) --+ { --+ reg = gen_rtx_REG (SImode, base_regno); --+ if (update_base_reg_p) --+ { --+ *update_base_reg = gen_reg_rtx (SImode); --+ return gen_unaligned_store_update_base_w (*update_base_reg, base_addr, reg); --+ } --+ else --+ return gen_unaligned_store_w (gen_rtx_MEM (SImode, base_addr), reg); --+ } --+ -- /* Create the pattern that is presented in nds32-multiple.md. */ -- --- result = gen_rtx_PARALLEL (VOIDmode, rtvec_alloc (count)); --+ if (update_base_reg_p) --+ { --+ result = gen_rtx_PARALLEL (VOIDmode, rtvec_alloc (count + 1)); --+ start_idx = 1; --+ } --+ else --+ { --+ result = gen_rtx_PARALLEL (VOIDmode, rtvec_alloc (count)); --+ start_idx = 0; --+ } --+ --+ if (update_base_reg_p) --+ { --+ offset = count * 4; --+ new_addr = plus_constant (Pmode, base_addr, offset); --+ *update_base_reg = gen_reg_rtx (SImode); --+ --+ XVECEXP (result, 0, 0) = gen_rtx_SET (*update_base_reg, new_addr); --+ } -- -- for (par_index = 0; par_index < count; par_index++) -- { --@@ -85,58 +1345,11 @@ nds32_expand_store_multiple (int base_regno, int count, -- new_addr, offset); -- reg = gen_rtx_REG (SImode, base_regno + par_index); -- --- XVECEXP (result, 0, par_index) = gen_rtx_SET (mem, reg); --+ XVECEXP (result, 0, par_index + start_idx) = gen_rtx_SET (mem, reg); -- } -- --- return result; ---} --- ---/* Function to move block memory content by --- using load_multiple and store_multiple. --- This is auxiliary extern function to help create rtx template. --- Check nds32-multiple.md file for the patterns. */ ---int ---nds32_expand_movmemqi (rtx dstmem, rtx srcmem, rtx total_bytes, rtx alignment) ---{ --- HOST_WIDE_INT in_words, out_words; --- rtx dst_base_reg, src_base_reg; --- int maximum_bytes; --- --- /* Because reduced-set regsiters has few registers --- (r0~r5, r6~10, r15, r28~r31, where 'r15' and 'r28~r31' --- cannot be used for register allocation), --- using 8 registers (32 bytes) for moving memory block --- may easily consume all of them. --- It makes register allocation/spilling hard to work. --- So we only allow maximum=4 registers (16 bytes) for --- moving memory block under reduced-set registers. */ --- if (TARGET_REDUCED_REGS) --- maximum_bytes = 16; --- else --- maximum_bytes = 32; --- --- /* 1. Total_bytes is integer for sure. --- 2. Alignment is integer for sure. --- 3. Maximum 4 or 8 registers, 4 * 4 = 16 bytes, 8 * 4 = 32 bytes. --- 4. Requires (n * 4) block size. --- 5. Requires 4-byte alignment. */ --- if (GET_CODE (total_bytes) != CONST_INT --- || GET_CODE (alignment) != CONST_INT --- || INTVAL (total_bytes) > maximum_bytes --- || INTVAL (total_bytes) & 3 --- || INTVAL (alignment) & 3) --- return 0; -- --- dst_base_reg = copy_to_mode_reg (SImode, XEXP (dstmem, 0)); --- src_base_reg = copy_to_mode_reg (SImode, XEXP (srcmem, 0)); --- --- out_words = in_words = INTVAL (total_bytes) / UNITS_PER_WORD; --- --- emit_insn (nds32_expand_load_multiple (0, in_words, src_base_reg, srcmem)); --- emit_insn (nds32_expand_store_multiple (0, out_words, dst_base_reg, dstmem)); --- --- /* Successfully create patterns, return 1. */ --- return 1; --+ return result; -- } -- -- /* ------------------------------------------------------------------------ */ --diff --git a/gcc/config/nds32/nds32-modes.def b/gcc/config/nds32/nds32-modes.def --index f2d0e6c..7a6f953 100644 ----- a/gcc/config/nds32/nds32-modes.def --+++ b/gcc/config/nds32/nds32-modes.def --@@ -18,4 +18,6 @@ -- along with GCC; see the file COPYING3. If not see -- . */ -- ---/* So far, there is no need to define any modes for nds32 target. */ --+/* Vector modes. */ --+VECTOR_MODES (INT, 4); /* V4QI V2HI */ --+VECTOR_MODES (INT, 8); /* V8QI V4HI V2SI */ --diff --git a/gcc/config/nds32/nds32-multiple.md b/gcc/config/nds32/nds32-multiple.md --index babc7f2..500a1c6 100644 ----- a/gcc/config/nds32/nds32-multiple.md --+++ b/gcc/config/nds32/nds32-multiple.md --@@ -49,17 +49,19 @@ -- otherwise we have to FAIL this rtx generation: -- 1. The number of consecutive registers must be integer. -- 2. Maximum 4 or 8 registers for lmw.bi instruction --- (based on this nds32-multiple.md design). --+ (based on this nds32-multiple.md design). -- 3. Minimum 2 registers for lmw.bi instruction --- (based on this nds32-multiple.md design). --+ (based on this nds32-multiple.md design). -- 4. operands[0] must be register for sure. -- 5. operands[1] must be memory for sure. --- 6. Do not cross $r15 register because it is not allocatable. */ --+ 6. operands[1] is not volatile memory access. --+ 7. Do not cross $r15 register because it is not allocatable. */ -- if (GET_CODE (operands[2]) != CONST_INT -- || INTVAL (operands[2]) > maximum -- || INTVAL (operands[2]) < 2 -- || GET_CODE (operands[0]) != REG -- || GET_CODE (operands[1]) != MEM --+ || MEM_VOLATILE_P (operands[1]) -- || REGNO (operands[0]) + INTVAL (operands[2]) > TA_REGNUM) -- FAIL; -- --@@ -69,12 +71,943 @@ -- INTVAL (operands[2]), -- force_reg (SImode, -- XEXP (operands[1], 0)), --- operands[1]); --+ operands[1], --+ false, NULL); -- }) -- -- ;; Ordinary Load Multiple. --+(define_insn "*lmw_bim_si25" --+ [(match_parallel 0 "nds32_load_multiple_and_update_address_operation" --+ [(set (match_operand:SI 1 "register_operand" "=r") --+ (plus:SI (match_operand:SI 2 "register_operand" "1") (const_int 100))) --+ (set (match_operand:SI 3 "register_operand" "") --+ (mem:SI (match_dup 2))) --+ (set (match_operand:SI 4 "register_operand" "") --+ (mem:SI (plus:SI (match_dup 2) (const_int 4)))) --+ (set (match_operand:SI 5 "register_operand" "") --+ (mem:SI (plus:SI (match_dup 2) (const_int 8)))) --+ (set (match_operand:SI 6 "register_operand" "") --+ (mem:SI (plus:SI (match_dup 2) (const_int 12)))) --+ (set (match_operand:SI 7 "register_operand" "") --+ (mem:SI (plus:SI (match_dup 2) (const_int 16)))) --+ (set (match_operand:SI 8 "register_operand" "") --+ (mem:SI (plus:SI (match_dup 2) (const_int 20)))) --+ (set (match_operand:SI 9 "register_operand" "") --+ (mem:SI (plus:SI (match_dup 2) (const_int 24)))) --+ (set (match_operand:SI 10 "register_operand" "") --+ (mem:SI (plus:SI (match_dup 2) (const_int 28)))) --+ (set (match_operand:SI 11 "register_operand" "") --+ (mem:SI (plus:SI (match_dup 2) (const_int 32)))) --+ (set (match_operand:SI 12 "register_operand" "") --+ (mem:SI (plus:SI (match_dup 2) (const_int 36)))) --+ (set (match_operand:SI 13 "register_operand" "") --+ (mem:SI (plus:SI (match_dup 2) (const_int 40)))) --+ (set (match_operand:SI 14 "register_operand" "") --+ (mem:SI (plus:SI (match_dup 2) (const_int 44)))) --+ (set (match_operand:SI 15 "register_operand" "") --+ (mem:SI (plus:SI (match_dup 2) (const_int 48)))) --+ (set (match_operand:SI 16 "register_operand" "") --+ (mem:SI (plus:SI (match_dup 2) (const_int 52)))) --+ (set (match_operand:SI 17 "register_operand" "") --+ (mem:SI (plus:SI (match_dup 2) (const_int 56)))) --+ (set (match_operand:SI 18 "register_operand" "") --+ (mem:SI (plus:SI (match_dup 2) (const_int 60)))) --+ (set (match_operand:SI 19 "register_operand" "") --+ (mem:SI (plus:SI (match_dup 2) (const_int 64)))) --+ (set (match_operand:SI 20 "register_operand" "") --+ (mem:SI (plus:SI (match_dup 2) (const_int 68)))) --+ (set (match_operand:SI 21 "register_operand" "") --+ (mem:SI (plus:SI (match_dup 2) (const_int 72)))) --+ (set (match_operand:SI 22 "register_operand" "") --+ (mem:SI (plus:SI (match_dup 2) (const_int 76)))) --+ (set (match_operand:SI 23 "register_operand" "") --+ (mem:SI (plus:SI (match_dup 2) (const_int 80)))) --+ (set (match_operand:SI 24 "register_operand" "") --+ (mem:SI (plus:SI (match_dup 2) (const_int 84)))) --+ (set (match_operand:SI 25 "register_operand" "") --+ (mem:SI (plus:SI (match_dup 2) (const_int 88)))) --+ (set (match_operand:SI 26 "register_operand" "") --+ (mem:SI (plus:SI (match_dup 2) (const_int 92)))) --+ (set (match_operand:SI 27 "register_operand" "") --+ (mem:SI (plus:SI (match_dup 2) (const_int 96))))])] --+ "(XVECLEN (operands[0], 0) == 26)" --+ "lmw.bim\t%3, [%1], %27, 0x0" --+ [(set_attr "type" "load_multiple") --+ (set_attr "combo" "25") --+ (set_attr "length" "4")] --+) -- ---(define_insn "*lmwsi8" --+(define_insn "*lmw_bim_si24" --+ [(match_parallel 0 "nds32_load_multiple_and_update_address_operation" --+ [(set (match_operand:SI 1 "register_operand" "=r") --+ (plus:SI (match_operand:SI 2 "register_operand" "1") (const_int 96))) --+ (set (match_operand:SI 3 "register_operand" "") --+ (mem:SI (match_dup 2))) --+ (set (match_operand:SI 4 "register_operand" "") --+ (mem:SI (plus:SI (match_dup 2) (const_int 4)))) --+ (set (match_operand:SI 5 "register_operand" "") --+ (mem:SI (plus:SI (match_dup 2) (const_int 8)))) --+ (set (match_operand:SI 6 "register_operand" "") --+ (mem:SI (plus:SI (match_dup 2) (const_int 12)))) --+ (set (match_operand:SI 7 "register_operand" "") --+ (mem:SI (plus:SI (match_dup 2) (const_int 16)))) --+ (set (match_operand:SI 8 "register_operand" "") --+ (mem:SI (plus:SI (match_dup 2) (const_int 20)))) --+ (set (match_operand:SI 9 "register_operand" "") --+ (mem:SI (plus:SI (match_dup 2) (const_int 24)))) --+ (set (match_operand:SI 10 "register_operand" "") --+ (mem:SI (plus:SI (match_dup 2) (const_int 28)))) --+ (set (match_operand:SI 11 "register_operand" "") --+ (mem:SI (plus:SI (match_dup 2) (const_int 32)))) --+ (set (match_operand:SI 12 "register_operand" "") --+ (mem:SI (plus:SI (match_dup 2) (const_int 36)))) --+ (set (match_operand:SI 13 "register_operand" "") --+ (mem:SI (plus:SI (match_dup 2) (const_int 40)))) --+ (set (match_operand:SI 14 "register_operand" "") --+ (mem:SI (plus:SI (match_dup 2) (const_int 44)))) --+ (set (match_operand:SI 15 "register_operand" "") --+ (mem:SI (plus:SI (match_dup 2) (const_int 48)))) --+ (set (match_operand:SI 16 "register_operand" "") --+ (mem:SI (plus:SI (match_dup 2) (const_int 52)))) --+ (set (match_operand:SI 17 "register_operand" "") --+ (mem:SI (plus:SI (match_dup 2) (const_int 56)))) --+ (set (match_operand:SI 18 "register_operand" "") --+ (mem:SI (plus:SI (match_dup 2) (const_int 60)))) --+ (set (match_operand:SI 19 "register_operand" "") --+ (mem:SI (plus:SI (match_dup 2) (const_int 64)))) --+ (set (match_operand:SI 20 "register_operand" "") --+ (mem:SI (plus:SI (match_dup 2) (const_int 68)))) --+ (set (match_operand:SI 21 "register_operand" "") --+ (mem:SI (plus:SI (match_dup 2) (const_int 72)))) --+ (set (match_operand:SI 22 "register_operand" "") --+ (mem:SI (plus:SI (match_dup 2) (const_int 76)))) --+ (set (match_operand:SI 23 "register_operand" "") --+ (mem:SI (plus:SI (match_dup 2) (const_int 80)))) --+ (set (match_operand:SI 24 "register_operand" "") --+ (mem:SI (plus:SI (match_dup 2) (const_int 84)))) --+ (set (match_operand:SI 25 "register_operand" "") --+ (mem:SI (plus:SI (match_dup 2) (const_int 88)))) --+ (set (match_operand:SI 26 "register_operand" "") --+ (mem:SI (plus:SI (match_dup 2) (const_int 92))))])] --+ "(XVECLEN (operands[0], 0) == 25)" --+ "lmw.bim\t%3, [%1], %26, 0x0" --+ [(set_attr "type" "load_multiple") --+ (set_attr "combo" "24") --+ (set_attr "length" "4")] --+) --+ --+(define_insn "*lmw_bim_si23" --+ [(match_parallel 0 "nds32_load_multiple_and_update_address_operation" --+ [(set (match_operand:SI 1 "register_operand" "=r") --+ (plus:SI (match_operand:SI 2 "register_operand" "1") (const_int 92))) --+ (set (match_operand:SI 3 "register_operand" "") --+ (mem:SI (match_dup 2))) --+ (set (match_operand:SI 4 "register_operand" "") --+ (mem:SI (plus:SI (match_dup 2) (const_int 4)))) --+ (set (match_operand:SI 5 "register_operand" "") --+ (mem:SI (plus:SI (match_dup 2) (const_int 8)))) --+ (set (match_operand:SI 6 "register_operand" "") --+ (mem:SI (plus:SI (match_dup 2) (const_int 12)))) --+ (set (match_operand:SI 7 "register_operand" "") --+ (mem:SI (plus:SI (match_dup 2) (const_int 16)))) --+ (set (match_operand:SI 8 "register_operand" "") --+ (mem:SI (plus:SI (match_dup 2) (const_int 20)))) --+ (set (match_operand:SI 9 "register_operand" "") --+ (mem:SI (plus:SI (match_dup 2) (const_int 24)))) --+ (set (match_operand:SI 10 "register_operand" "") --+ (mem:SI (plus:SI (match_dup 2) (const_int 28)))) --+ (set (match_operand:SI 11 "register_operand" "") --+ (mem:SI (plus:SI (match_dup 2) (const_int 32)))) --+ (set (match_operand:SI 12 "register_operand" "") --+ (mem:SI (plus:SI (match_dup 2) (const_int 36)))) --+ (set (match_operand:SI 13 "register_operand" "") --+ (mem:SI (plus:SI (match_dup 2) (const_int 40)))) --+ (set (match_operand:SI 14 "register_operand" "") --+ (mem:SI (plus:SI (match_dup 2) (const_int 44)))) --+ (set (match_operand:SI 15 "register_operand" "") --+ (mem:SI (plus:SI (match_dup 2) (const_int 48)))) --+ (set (match_operand:SI 16 "register_operand" "") --+ (mem:SI (plus:SI (match_dup 2) (const_int 52)))) --+ (set (match_operand:SI 17 "register_operand" "") --+ (mem:SI (plus:SI (match_dup 2) (const_int 56)))) --+ (set (match_operand:SI 18 "register_operand" "") --+ (mem:SI (plus:SI (match_dup 2) (const_int 60)))) --+ (set (match_operand:SI 19 "register_operand" "") --+ (mem:SI (plus:SI (match_dup 2) (const_int 64)))) --+ (set (match_operand:SI 20 "register_operand" "") --+ (mem:SI (plus:SI (match_dup 2) (const_int 68)))) --+ (set (match_operand:SI 21 "register_operand" "") --+ (mem:SI (plus:SI (match_dup 2) (const_int 72)))) --+ (set (match_operand:SI 22 "register_operand" "") --+ (mem:SI (plus:SI (match_dup 2) (const_int 76)))) --+ (set (match_operand:SI 23 "register_operand" "") --+ (mem:SI (plus:SI (match_dup 2) (const_int 80)))) --+ (set (match_operand:SI 24 "register_operand" "") --+ (mem:SI (plus:SI (match_dup 2) (const_int 84)))) --+ (set (match_operand:SI 25 "register_operand" "") --+ (mem:SI (plus:SI (match_dup 2) (const_int 88))))])] --+ "(XVECLEN (operands[0], 0) == 24)" --+ "lmw.bim\t%3, [%1], %25, 0x0" --+ [(set_attr "type" "load_multiple") --+ (set_attr "combo" "23") --+ (set_attr "length" "4")] --+) --+ --+(define_insn "*lmw_bim_si22" --+ [(match_parallel 0 "nds32_load_multiple_and_update_address_operation" --+ [(set (match_operand:SI 1 "register_operand" "=r") --+ (plus:SI (match_operand:SI 2 "register_operand" "1") (const_int 88))) --+ (set (match_operand:SI 3 "register_operand" "") --+ (mem:SI (match_dup 2))) --+ (set (match_operand:SI 4 "register_operand" "") --+ (mem:SI (plus:SI (match_dup 2) (const_int 4)))) --+ (set (match_operand:SI 5 "register_operand" "") --+ (mem:SI (plus:SI (match_dup 2) (const_int 8)))) --+ (set (match_operand:SI 6 "register_operand" "") --+ (mem:SI (plus:SI (match_dup 2) (const_int 12)))) --+ (set (match_operand:SI 7 "register_operand" "") --+ (mem:SI (plus:SI (match_dup 2) (const_int 16)))) --+ (set (match_operand:SI 8 "register_operand" "") --+ (mem:SI (plus:SI (match_dup 2) (const_int 20)))) --+ (set (match_operand:SI 9 "register_operand" "") --+ (mem:SI (plus:SI (match_dup 2) (const_int 24)))) --+ (set (match_operand:SI 10 "register_operand" "") --+ (mem:SI (plus:SI (match_dup 2) (const_int 28)))) --+ (set (match_operand:SI 11 "register_operand" "") --+ (mem:SI (plus:SI (match_dup 2) (const_int 32)))) --+ (set (match_operand:SI 12 "register_operand" "") --+ (mem:SI (plus:SI (match_dup 2) (const_int 36)))) --+ (set (match_operand:SI 13 "register_operand" "") --+ (mem:SI (plus:SI (match_dup 2) (const_int 40)))) --+ (set (match_operand:SI 14 "register_operand" "") --+ (mem:SI (plus:SI (match_dup 2) (const_int 44)))) --+ (set (match_operand:SI 15 "register_operand" "") --+ (mem:SI (plus:SI (match_dup 2) (const_int 48)))) --+ (set (match_operand:SI 16 "register_operand" "") --+ (mem:SI (plus:SI (match_dup 2) (const_int 52)))) --+ (set (match_operand:SI 17 "register_operand" "") --+ (mem:SI (plus:SI (match_dup 2) (const_int 56)))) --+ (set (match_operand:SI 18 "register_operand" "") --+ (mem:SI (plus:SI (match_dup 2) (const_int 60)))) --+ (set (match_operand:SI 19 "register_operand" "") --+ (mem:SI (plus:SI (match_dup 2) (const_int 64)))) --+ (set (match_operand:SI 20 "register_operand" "") --+ (mem:SI (plus:SI (match_dup 2) (const_int 68)))) --+ (set (match_operand:SI 21 "register_operand" "") --+ (mem:SI (plus:SI (match_dup 2) (const_int 72)))) --+ (set (match_operand:SI 22 "register_operand" "") --+ (mem:SI (plus:SI (match_dup 2) (const_int 76)))) --+ (set (match_operand:SI 23 "register_operand" "") --+ (mem:SI (plus:SI (match_dup 2) (const_int 80)))) --+ (set (match_operand:SI 24 "register_operand" "") --+ (mem:SI (plus:SI (match_dup 2) (const_int 84))))])] --+ "(XVECLEN (operands[0], 0) == 23)" --+ "lmw.bim\t%3, [%1], %24, 0x0" --+ [(set_attr "type" "load_multiple") --+ (set_attr "combo" "22") --+ (set_attr "length" "4")] --+) --+ --+(define_insn "*lmw_bim_si21" --+ [(match_parallel 0 "nds32_load_multiple_and_update_address_operation" --+ [(set (match_operand:SI 1 "register_operand" "=r") --+ (plus:SI (match_operand:SI 2 "register_operand" "1") (const_int 84))) --+ (set (match_operand:SI 3 "register_operand" "") --+ (mem:SI (match_dup 2))) --+ (set (match_operand:SI 4 "register_operand" "") --+ (mem:SI (plus:SI (match_dup 2) (const_int 4)))) --+ (set (match_operand:SI 5 "register_operand" "") --+ (mem:SI (plus:SI (match_dup 2) (const_int 8)))) --+ (set (match_operand:SI 6 "register_operand" "") --+ (mem:SI (plus:SI (match_dup 2) (const_int 12)))) --+ (set (match_operand:SI 7 "register_operand" "") --+ (mem:SI (plus:SI (match_dup 2) (const_int 16)))) --+ (set (match_operand:SI 8 "register_operand" "") --+ (mem:SI (plus:SI (match_dup 2) (const_int 20)))) --+ (set (match_operand:SI 9 "register_operand" "") --+ (mem:SI (plus:SI (match_dup 2) (const_int 24)))) --+ (set (match_operand:SI 10 "register_operand" "") --+ (mem:SI (plus:SI (match_dup 2) (const_int 28)))) --+ (set (match_operand:SI 11 "register_operand" "") --+ (mem:SI (plus:SI (match_dup 2) (const_int 32)))) --+ (set (match_operand:SI 12 "register_operand" "") --+ (mem:SI (plus:SI (match_dup 2) (const_int 36)))) --+ (set (match_operand:SI 13 "register_operand" "") --+ (mem:SI (plus:SI (match_dup 2) (const_int 40)))) --+ (set (match_operand:SI 14 "register_operand" "") --+ (mem:SI (plus:SI (match_dup 2) (const_int 44)))) --+ (set (match_operand:SI 15 "register_operand" "") --+ (mem:SI (plus:SI (match_dup 2) (const_int 48)))) --+ (set (match_operand:SI 16 "register_operand" "") --+ (mem:SI (plus:SI (match_dup 2) (const_int 52)))) --+ (set (match_operand:SI 17 "register_operand" "") --+ (mem:SI (plus:SI (match_dup 2) (const_int 56)))) --+ (set (match_operand:SI 18 "register_operand" "") --+ (mem:SI (plus:SI (match_dup 2) (const_int 60)))) --+ (set (match_operand:SI 19 "register_operand" "") --+ (mem:SI (plus:SI (match_dup 2) (const_int 64)))) --+ (set (match_operand:SI 20 "register_operand" "") --+ (mem:SI (plus:SI (match_dup 2) (const_int 68)))) --+ (set (match_operand:SI 21 "register_operand" "") --+ (mem:SI (plus:SI (match_dup 2) (const_int 72)))) --+ (set (match_operand:SI 22 "register_operand" "") --+ (mem:SI (plus:SI (match_dup 2) (const_int 76)))) --+ (set (match_operand:SI 23 "register_operand" "") --+ (mem:SI (plus:SI (match_dup 2) (const_int 80))))])] --+ "(XVECLEN (operands[0], 0) == 22)" --+ "lmw.bim\t%3, [%1], %23, 0x0" --+ [(set_attr "type" "load_multiple") --+ (set_attr "combo" "21") --+ (set_attr "length" "4")] --+) --+ --+(define_insn "*lmw_bim_si20" --+ [(match_parallel 0 "nds32_load_multiple_and_update_address_operation" --+ [(set (match_operand:SI 1 "register_operand" "=r") --+ (plus:SI (match_operand:SI 2 "register_operand" "1") (const_int 80))) --+ (set (match_operand:SI 3 "register_operand" "") --+ (mem:SI (match_dup 2))) --+ (set (match_operand:SI 4 "register_operand" "") --+ (mem:SI (plus:SI (match_dup 2) (const_int 4)))) --+ (set (match_operand:SI 5 "register_operand" "") --+ (mem:SI (plus:SI (match_dup 2) (const_int 8)))) --+ (set (match_operand:SI 6 "register_operand" "") --+ (mem:SI (plus:SI (match_dup 2) (const_int 12)))) --+ (set (match_operand:SI 7 "register_operand" "") --+ (mem:SI (plus:SI (match_dup 2) (const_int 16)))) --+ (set (match_operand:SI 8 "register_operand" "") --+ (mem:SI (plus:SI (match_dup 2) (const_int 20)))) --+ (set (match_operand:SI 9 "register_operand" "") --+ (mem:SI (plus:SI (match_dup 2) (const_int 24)))) --+ (set (match_operand:SI 10 "register_operand" "") --+ (mem:SI (plus:SI (match_dup 2) (const_int 28)))) --+ (set (match_operand:SI 11 "register_operand" "") --+ (mem:SI (plus:SI (match_dup 2) (const_int 32)))) --+ (set (match_operand:SI 12 "register_operand" "") --+ (mem:SI (plus:SI (match_dup 2) (const_int 36)))) --+ (set (match_operand:SI 13 "register_operand" "") --+ (mem:SI (plus:SI (match_dup 2) (const_int 40)))) --+ (set (match_operand:SI 14 "register_operand" "") --+ (mem:SI (plus:SI (match_dup 2) (const_int 44)))) --+ (set (match_operand:SI 15 "register_operand" "") --+ (mem:SI (plus:SI (match_dup 2) (const_int 48)))) --+ (set (match_operand:SI 16 "register_operand" "") --+ (mem:SI (plus:SI (match_dup 2) (const_int 52)))) --+ (set (match_operand:SI 17 "register_operand" "") --+ (mem:SI (plus:SI (match_dup 2) (const_int 56)))) --+ (set (match_operand:SI 18 "register_operand" "") --+ (mem:SI (plus:SI (match_dup 2) (const_int 60)))) --+ (set (match_operand:SI 19 "register_operand" "") --+ (mem:SI (plus:SI (match_dup 2) (const_int 64)))) --+ (set (match_operand:SI 20 "register_operand" "") --+ (mem:SI (plus:SI (match_dup 2) (const_int 68)))) --+ (set (match_operand:SI 21 "register_operand" "") --+ (mem:SI (plus:SI (match_dup 2) (const_int 72)))) --+ (set (match_operand:SI 22 "register_operand" "") --+ (mem:SI (plus:SI (match_dup 2) (const_int 76))))])] --+ "(XVECLEN (operands[0], 0) == 21)" --+ "lmw.bim\t%3, [%1], %22, 0x0" --+ [(set_attr "type" "load_multiple") --+ (set_attr "combo" "20") --+ (set_attr "length" "4")] --+) --+ --+(define_insn "*lmw_bim_si19" --+ [(match_parallel 0 "nds32_load_multiple_and_update_address_operation" --+ [(set (match_operand:SI 1 "register_operand" "=r") --+ (plus:SI (match_operand:SI 2 "register_operand" "1") (const_int 76))) --+ (set (match_operand:SI 3 "register_operand" "") --+ (mem:SI (match_dup 2))) --+ (set (match_operand:SI 4 "register_operand" "") --+ (mem:SI (plus:SI (match_dup 2) (const_int 4)))) --+ (set (match_operand:SI 5 "register_operand" "") --+ (mem:SI (plus:SI (match_dup 2) (const_int 8)))) --+ (set (match_operand:SI 6 "register_operand" "") --+ (mem:SI (plus:SI (match_dup 2) (const_int 12)))) --+ (set (match_operand:SI 7 "register_operand" "") --+ (mem:SI (plus:SI (match_dup 2) (const_int 16)))) --+ (set (match_operand:SI 8 "register_operand" "") --+ (mem:SI (plus:SI (match_dup 2) (const_int 20)))) --+ (set (match_operand:SI 9 "register_operand" "") --+ (mem:SI (plus:SI (match_dup 2) (const_int 24)))) --+ (set (match_operand:SI 10 "register_operand" "") --+ (mem:SI (plus:SI (match_dup 2) (const_int 28)))) --+ (set (match_operand:SI 11 "register_operand" "") --+ (mem:SI (plus:SI (match_dup 2) (const_int 32)))) --+ (set (match_operand:SI 12 "register_operand" "") --+ (mem:SI (plus:SI (match_dup 2) (const_int 36)))) --+ (set (match_operand:SI 13 "register_operand" "") --+ (mem:SI (plus:SI (match_dup 2) (const_int 40)))) --+ (set (match_operand:SI 14 "register_operand" "") --+ (mem:SI (plus:SI (match_dup 2) (const_int 44)))) --+ (set (match_operand:SI 15 "register_operand" "") --+ (mem:SI (plus:SI (match_dup 2) (const_int 48)))) --+ (set (match_operand:SI 16 "register_operand" "") --+ (mem:SI (plus:SI (match_dup 2) (const_int 52)))) --+ (set (match_operand:SI 17 "register_operand" "") --+ (mem:SI (plus:SI (match_dup 2) (const_int 56)))) --+ (set (match_operand:SI 18 "register_operand" "") --+ (mem:SI (plus:SI (match_dup 2) (const_int 60)))) --+ (set (match_operand:SI 19 "register_operand" "") --+ (mem:SI (plus:SI (match_dup 2) (const_int 64)))) --+ (set (match_operand:SI 20 "register_operand" "") --+ (mem:SI (plus:SI (match_dup 2) (const_int 68)))) --+ (set (match_operand:SI 21 "register_operand" "") --+ (mem:SI (plus:SI (match_dup 2) (const_int 72))))])] --+ "(XVECLEN (operands[0], 0) == 20)" --+ "lmw.bim\t%3, [%1], %21, 0x0" --+ [(set_attr "type" "load_multiple") --+ (set_attr "combo" "19") --+ (set_attr "length" "4")] --+) --+ --+(define_insn "*lmw_bim_si18" --+ [(match_parallel 0 "nds32_load_multiple_and_update_address_operation" --+ [(set (match_operand:SI 1 "register_operand" "=r") --+ (plus:SI (match_operand:SI 2 "register_operand" "1") (const_int 72))) --+ (set (match_operand:SI 3 "register_operand" "") --+ (mem:SI (match_dup 2))) --+ (set (match_operand:SI 4 "register_operand" "") --+ (mem:SI (plus:SI (match_dup 2) (const_int 4)))) --+ (set (match_operand:SI 5 "register_operand" "") --+ (mem:SI (plus:SI (match_dup 2) (const_int 8)))) --+ (set (match_operand:SI 6 "register_operand" "") --+ (mem:SI (plus:SI (match_dup 2) (const_int 12)))) --+ (set (match_operand:SI 7 "register_operand" "") --+ (mem:SI (plus:SI (match_dup 2) (const_int 16)))) --+ (set (match_operand:SI 8 "register_operand" "") --+ (mem:SI (plus:SI (match_dup 2) (const_int 20)))) --+ (set (match_operand:SI 9 "register_operand" "") --+ (mem:SI (plus:SI (match_dup 2) (const_int 24)))) --+ (set (match_operand:SI 10 "register_operand" "") --+ (mem:SI (plus:SI (match_dup 2) (const_int 28)))) --+ (set (match_operand:SI 11 "register_operand" "") --+ (mem:SI (plus:SI (match_dup 2) (const_int 32)))) --+ (set (match_operand:SI 12 "register_operand" "") --+ (mem:SI (plus:SI (match_dup 2) (const_int 36)))) --+ (set (match_operand:SI 13 "register_operand" "") --+ (mem:SI (plus:SI (match_dup 2) (const_int 40)))) --+ (set (match_operand:SI 14 "register_operand" "") --+ (mem:SI (plus:SI (match_dup 2) (const_int 44)))) --+ (set (match_operand:SI 15 "register_operand" "") --+ (mem:SI (plus:SI (match_dup 2) (const_int 48)))) --+ (set (match_operand:SI 16 "register_operand" "") --+ (mem:SI (plus:SI (match_dup 2) (const_int 52)))) --+ (set (match_operand:SI 17 "register_operand" "") --+ (mem:SI (plus:SI (match_dup 2) (const_int 56)))) --+ (set (match_operand:SI 18 "register_operand" "") --+ (mem:SI (plus:SI (match_dup 2) (const_int 60)))) --+ (set (match_operand:SI 19 "register_operand" "") --+ (mem:SI (plus:SI (match_dup 2) (const_int 64)))) --+ (set (match_operand:SI 20 "register_operand" "") --+ (mem:SI (plus:SI (match_dup 2) (const_int 68))))])] --+ "(XVECLEN (operands[0], 0) == 19)" --+ "lmw.bim\t%3, [%1], %20, 0x0" --+ [(set_attr "type" "load_multiple") --+ (set_attr "combo" "18") --+ (set_attr "length" "4")] --+) --+ --+(define_insn "*lmw_bim_si17" --+ [(match_parallel 0 "nds32_load_multiple_and_update_address_operation" --+ [(set (match_operand:SI 1 "register_operand" "=r") --+ (plus:SI (match_operand:SI 2 "register_operand" "1") (const_int 68))) --+ (set (match_operand:SI 3 "register_operand" "") --+ (mem:SI (match_dup 2))) --+ (set (match_operand:SI 4 "register_operand" "") --+ (mem:SI (plus:SI (match_dup 2) (const_int 4)))) --+ (set (match_operand:SI 5 "register_operand" "") --+ (mem:SI (plus:SI (match_dup 2) (const_int 8)))) --+ (set (match_operand:SI 6 "register_operand" "") --+ (mem:SI (plus:SI (match_dup 2) (const_int 12)))) --+ (set (match_operand:SI 7 "register_operand" "") --+ (mem:SI (plus:SI (match_dup 2) (const_int 16)))) --+ (set (match_operand:SI 8 "register_operand" "") --+ (mem:SI (plus:SI (match_dup 2) (const_int 20)))) --+ (set (match_operand:SI 9 "register_operand" "") --+ (mem:SI (plus:SI (match_dup 2) (const_int 24)))) --+ (set (match_operand:SI 10 "register_operand" "") --+ (mem:SI (plus:SI (match_dup 2) (const_int 28)))) --+ (set (match_operand:SI 11 "register_operand" "") --+ (mem:SI (plus:SI (match_dup 2) (const_int 32)))) --+ (set (match_operand:SI 12 "register_operand" "") --+ (mem:SI (plus:SI (match_dup 2) (const_int 36)))) --+ (set (match_operand:SI 13 "register_operand" "") --+ (mem:SI (plus:SI (match_dup 2) (const_int 40)))) --+ (set (match_operand:SI 14 "register_operand" "") --+ (mem:SI (plus:SI (match_dup 2) (const_int 44)))) --+ (set (match_operand:SI 15 "register_operand" "") --+ (mem:SI (plus:SI (match_dup 2) (const_int 48)))) --+ (set (match_operand:SI 16 "register_operand" "") --+ (mem:SI (plus:SI (match_dup 2) (const_int 52)))) --+ (set (match_operand:SI 17 "register_operand" "") --+ (mem:SI (plus:SI (match_dup 2) (const_int 56)))) --+ (set (match_operand:SI 18 "register_operand" "") --+ (mem:SI (plus:SI (match_dup 2) (const_int 60)))) --+ (set (match_operand:SI 19 "register_operand" "") --+ (mem:SI (plus:SI (match_dup 2) (const_int 64))))])] --+ "(XVECLEN (operands[0], 0) == 18)" --+ "lmw.bim\t%3, [%1], %19, 0x0" --+ [(set_attr "type" "load_multiple") --+ (set_attr "combo" "17") --+ (set_attr "length" "4")] --+) --+ --+(define_insn "*lmw_bim_si16" --+ [(match_parallel 0 "nds32_load_multiple_and_update_address_operation" --+ [(set (match_operand:SI 1 "register_operand" "=r") --+ (plus:SI (match_operand:SI 2 "register_operand" "1") (const_int 64))) --+ (set (match_operand:SI 3 "register_operand" "") --+ (mem:SI (match_dup 2))) --+ (set (match_operand:SI 4 "register_operand" "") --+ (mem:SI (plus:SI (match_dup 2) (const_int 4)))) --+ (set (match_operand:SI 5 "register_operand" "") --+ (mem:SI (plus:SI (match_dup 2) (const_int 8)))) --+ (set (match_operand:SI 6 "register_operand" "") --+ (mem:SI (plus:SI (match_dup 2) (const_int 12)))) --+ (set (match_operand:SI 7 "register_operand" "") --+ (mem:SI (plus:SI (match_dup 2) (const_int 16)))) --+ (set (match_operand:SI 8 "register_operand" "") --+ (mem:SI (plus:SI (match_dup 2) (const_int 20)))) --+ (set (match_operand:SI 9 "register_operand" "") --+ (mem:SI (plus:SI (match_dup 2) (const_int 24)))) --+ (set (match_operand:SI 10 "register_operand" "") --+ (mem:SI (plus:SI (match_dup 2) (const_int 28)))) --+ (set (match_operand:SI 11 "register_operand" "") --+ (mem:SI (plus:SI (match_dup 2) (const_int 32)))) --+ (set (match_operand:SI 12 "register_operand" "") --+ (mem:SI (plus:SI (match_dup 2) (const_int 36)))) --+ (set (match_operand:SI 13 "register_operand" "") --+ (mem:SI (plus:SI (match_dup 2) (const_int 40)))) --+ (set (match_operand:SI 14 "register_operand" "") --+ (mem:SI (plus:SI (match_dup 2) (const_int 44)))) --+ (set (match_operand:SI 15 "register_operand" "") --+ (mem:SI (plus:SI (match_dup 2) (const_int 48)))) --+ (set (match_operand:SI 16 "register_operand" "") --+ (mem:SI (plus:SI (match_dup 2) (const_int 52)))) --+ (set (match_operand:SI 17 "register_operand" "") --+ (mem:SI (plus:SI (match_dup 2) (const_int 56)))) --+ (set (match_operand:SI 18 "register_operand" "") --+ (mem:SI (plus:SI (match_dup 2) (const_int 60))))])] --+ "(XVECLEN (operands[0], 0) == 17)" --+ "lmw.bim\t%3, [%1], %18, 0x0" --+ [(set_attr "type" "load_multiple") --+ (set_attr "combo" "16") --+ (set_attr "length" "4")] --+) --+ --+(define_insn "*lmw_bim_si15" --+ [(match_parallel 0 "nds32_load_multiple_and_update_address_operation" --+ [(set (match_operand:SI 1 "register_operand" "=r") --+ (plus:SI (match_operand:SI 2 "register_operand" "1") (const_int 60))) --+ (set (match_operand:SI 3 "register_operand" "") --+ (mem:SI (match_dup 2))) --+ (set (match_operand:SI 4 "register_operand" "") --+ (mem:SI (plus:SI (match_dup 2) (const_int 4)))) --+ (set (match_operand:SI 5 "register_operand" "") --+ (mem:SI (plus:SI (match_dup 2) (const_int 8)))) --+ (set (match_operand:SI 6 "register_operand" "") --+ (mem:SI (plus:SI (match_dup 2) (const_int 12)))) --+ (set (match_operand:SI 7 "register_operand" "") --+ (mem:SI (plus:SI (match_dup 2) (const_int 16)))) --+ (set (match_operand:SI 8 "register_operand" "") --+ (mem:SI (plus:SI (match_dup 2) (const_int 20)))) --+ (set (match_operand:SI 9 "register_operand" "") --+ (mem:SI (plus:SI (match_dup 2) (const_int 24)))) --+ (set (match_operand:SI 10 "register_operand" "") --+ (mem:SI (plus:SI (match_dup 2) (const_int 28)))) --+ (set (match_operand:SI 11 "register_operand" "") --+ (mem:SI (plus:SI (match_dup 2) (const_int 32)))) --+ (set (match_operand:SI 12 "register_operand" "") --+ (mem:SI (plus:SI (match_dup 2) (const_int 36)))) --+ (set (match_operand:SI 13 "register_operand" "") --+ (mem:SI (plus:SI (match_dup 2) (const_int 40)))) --+ (set (match_operand:SI 14 "register_operand" "") --+ (mem:SI (plus:SI (match_dup 2) (const_int 44)))) --+ (set (match_operand:SI 15 "register_operand" "") --+ (mem:SI (plus:SI (match_dup 2) (const_int 48)))) --+ (set (match_operand:SI 16 "register_operand" "") --+ (mem:SI (plus:SI (match_dup 2) (const_int 52)))) --+ (set (match_operand:SI 17 "register_operand" "") --+ (mem:SI (plus:SI (match_dup 2) (const_int 56))))])] --+ "(XVECLEN (operands[0], 0) == 16)" --+ "lmw.bim\t%3, [%1], %17, 0x0" --+ [(set_attr "type" "load_multiple") --+ (set_attr "combo" "15") --+ (set_attr "length" "4")] --+) --+ --+(define_insn "*lmw_bim_si14" --+ [(match_parallel 0 "nds32_load_multiple_and_update_address_operation" --+ [(set (match_operand:SI 1 "register_operand" "=r") --+ (plus:SI (match_operand:SI 2 "register_operand" "1") (const_int 56))) --+ (set (match_operand:SI 3 "register_operand" "") --+ (mem:SI (match_dup 2))) --+ (set (match_operand:SI 4 "register_operand" "") --+ (mem:SI (plus:SI (match_dup 2) (const_int 4)))) --+ (set (match_operand:SI 5 "register_operand" "") --+ (mem:SI (plus:SI (match_dup 2) (const_int 8)))) --+ (set (match_operand:SI 6 "register_operand" "") --+ (mem:SI (plus:SI (match_dup 2) (const_int 12)))) --+ (set (match_operand:SI 7 "register_operand" "") --+ (mem:SI (plus:SI (match_dup 2) (const_int 16)))) --+ (set (match_operand:SI 8 "register_operand" "") --+ (mem:SI (plus:SI (match_dup 2) (const_int 20)))) --+ (set (match_operand:SI 9 "register_operand" "") --+ (mem:SI (plus:SI (match_dup 2) (const_int 24)))) --+ (set (match_operand:SI 10 "register_operand" "") --+ (mem:SI (plus:SI (match_dup 2) (const_int 28)))) --+ (set (match_operand:SI 11 "register_operand" "") --+ (mem:SI (plus:SI (match_dup 2) (const_int 32)))) --+ (set (match_operand:SI 12 "register_operand" "") --+ (mem:SI (plus:SI (match_dup 2) (const_int 36)))) --+ (set (match_operand:SI 13 "register_operand" "") --+ (mem:SI (plus:SI (match_dup 2) (const_int 40)))) --+ (set (match_operand:SI 14 "register_operand" "") --+ (mem:SI (plus:SI (match_dup 2) (const_int 44)))) --+ (set (match_operand:SI 15 "register_operand" "") --+ (mem:SI (plus:SI (match_dup 2) (const_int 48)))) --+ (set (match_operand:SI 16 "register_operand" "") --+ (mem:SI (plus:SI (match_dup 2) (const_int 52))))])] --+ "(XVECLEN (operands[0], 0) == 15)" --+ "lmw.bim\t%3, [%1], %16, 0x0" --+ [(set_attr "type" "load_multiple") --+ (set_attr "combo" "14") --+ (set_attr "length" "4")] --+) --+ --+(define_insn "*lmw_bim_si13" --+ [(match_parallel 0 "nds32_load_multiple_and_update_address_operation" --+ [(set (match_operand:SI 1 "register_operand" "=r") --+ (plus:SI (match_operand:SI 2 "register_operand" "1") (const_int 52))) --+ (set (match_operand:SI 3 "register_operand" "") --+ (mem:SI (match_dup 2))) --+ (set (match_operand:SI 4 "register_operand" "") --+ (mem:SI (plus:SI (match_dup 2) (const_int 4)))) --+ (set (match_operand:SI 5 "register_operand" "") --+ (mem:SI (plus:SI (match_dup 2) (const_int 8)))) --+ (set (match_operand:SI 6 "register_operand" "") --+ (mem:SI (plus:SI (match_dup 2) (const_int 12)))) --+ (set (match_operand:SI 7 "register_operand" "") --+ (mem:SI (plus:SI (match_dup 2) (const_int 16)))) --+ (set (match_operand:SI 8 "register_operand" "") --+ (mem:SI (plus:SI (match_dup 2) (const_int 20)))) --+ (set (match_operand:SI 9 "register_operand" "") --+ (mem:SI (plus:SI (match_dup 2) (const_int 24)))) --+ (set (match_operand:SI 10 "register_operand" "") --+ (mem:SI (plus:SI (match_dup 2) (const_int 28)))) --+ (set (match_operand:SI 11 "register_operand" "") --+ (mem:SI (plus:SI (match_dup 2) (const_int 32)))) --+ (set (match_operand:SI 12 "register_operand" "") --+ (mem:SI (plus:SI (match_dup 2) (const_int 36)))) --+ (set (match_operand:SI 13 "register_operand" "") --+ (mem:SI (plus:SI (match_dup 2) (const_int 40)))) --+ (set (match_operand:SI 14 "register_operand" "") --+ (mem:SI (plus:SI (match_dup 2) (const_int 44)))) --+ (set (match_operand:SI 15 "register_operand" "") --+ (mem:SI (plus:SI (match_dup 2) (const_int 48))))])] --+ "(XVECLEN (operands[0], 0) == 14)" --+ "lmw.bim\t%3, [%1], %15, 0x0" --+ [(set_attr "type" "load_multiple") --+ (set_attr "combo" "13") --+ (set_attr "length" "4")] --+) --+ --+(define_insn "*lmw_bim_si12" --+ [(match_parallel 0 "nds32_load_multiple_and_update_address_operation" --+ [(set (match_operand:SI 1 "register_operand" "=r") --+ (plus:SI (match_operand:SI 2 "register_operand" "1") (const_int 48))) --+ (set (match_operand:SI 3 "register_operand" "") --+ (mem:SI (match_dup 2))) --+ (set (match_operand:SI 4 "register_operand" "") --+ (mem:SI (plus:SI (match_dup 2) (const_int 4)))) --+ (set (match_operand:SI 5 "register_operand" "") --+ (mem:SI (plus:SI (match_dup 2) (const_int 8)))) --+ (set (match_operand:SI 6 "register_operand" "") --+ (mem:SI (plus:SI (match_dup 2) (const_int 12)))) --+ (set (match_operand:SI 7 "register_operand" "") --+ (mem:SI (plus:SI (match_dup 2) (const_int 16)))) --+ (set (match_operand:SI 8 "register_operand" "") --+ (mem:SI (plus:SI (match_dup 2) (const_int 20)))) --+ (set (match_operand:SI 9 "register_operand" "") --+ (mem:SI (plus:SI (match_dup 2) (const_int 24)))) --+ (set (match_operand:SI 10 "register_operand" "") --+ (mem:SI (plus:SI (match_dup 2) (const_int 28)))) --+ (set (match_operand:SI 11 "register_operand" "") --+ (mem:SI (plus:SI (match_dup 2) (const_int 32)))) --+ (set (match_operand:SI 12 "register_operand" "") --+ (mem:SI (plus:SI (match_dup 2) (const_int 36)))) --+ (set (match_operand:SI 13 "register_operand" "") --+ (mem:SI (plus:SI (match_dup 2) (const_int 40)))) --+ (set (match_operand:SI 14 "register_operand" "") --+ (mem:SI (plus:SI (match_dup 2) (const_int 44))))])] --+ "(XVECLEN (operands[0], 0) == 13)" --+ "lmw.bim\t%3, [%1], %14, 0x0" --+ [(set_attr "type" "load_multiple") --+ (set_attr "combo" "12") --+ (set_attr "length" "4")] --+) --+ --+(define_insn "*lmw_bim_si11" --+ [(match_parallel 0 "nds32_load_multiple_and_update_address_operation" --+ [(set (match_operand:SI 1 "register_operand" "=r") --+ (plus:SI (match_operand:SI 2 "register_operand" "1") (const_int 44))) --+ (set (match_operand:SI 3 "register_operand" "") --+ (mem:SI (match_dup 2))) --+ (set (match_operand:SI 4 "register_operand" "") --+ (mem:SI (plus:SI (match_dup 2) (const_int 4)))) --+ (set (match_operand:SI 5 "register_operand" "") --+ (mem:SI (plus:SI (match_dup 2) (const_int 8)))) --+ (set (match_operand:SI 6 "register_operand" "") --+ (mem:SI (plus:SI (match_dup 2) (const_int 12)))) --+ (set (match_operand:SI 7 "register_operand" "") --+ (mem:SI (plus:SI (match_dup 2) (const_int 16)))) --+ (set (match_operand:SI 8 "register_operand" "") --+ (mem:SI (plus:SI (match_dup 2) (const_int 20)))) --+ (set (match_operand:SI 9 "register_operand" "") --+ (mem:SI (plus:SI (match_dup 2) (const_int 24)))) --+ (set (match_operand:SI 10 "register_operand" "") --+ (mem:SI (plus:SI (match_dup 2) (const_int 28)))) --+ (set (match_operand:SI 11 "register_operand" "") --+ (mem:SI (plus:SI (match_dup 2) (const_int 32)))) --+ (set (match_operand:SI 12 "register_operand" "") --+ (mem:SI (plus:SI (match_dup 2) (const_int 36)))) --+ (set (match_operand:SI 13 "register_operand" "") --+ (mem:SI (plus:SI (match_dup 2) (const_int 40))))])] --+ "(XVECLEN (operands[0], 0) == 12)" --+ "lmw.bim\t%3, [%1], %13, 0x0" --+ [(set_attr "type" "load_multiple") --+ (set_attr "combo" "11") --+ (set_attr "length" "4")] --+) --+ --+(define_insn "*lmw_bim_si10" --+ [(match_parallel 0 "nds32_load_multiple_and_update_address_operation" --+ [(set (match_operand:SI 1 "register_operand" "=r") --+ (plus:SI (match_operand:SI 2 "register_operand" "1") (const_int 40))) --+ (set (match_operand:SI 3 "register_operand" "") --+ (mem:SI (match_dup 2))) --+ (set (match_operand:SI 4 "register_operand" "") --+ (mem:SI (plus:SI (match_dup 2) (const_int 4)))) --+ (set (match_operand:SI 5 "register_operand" "") --+ (mem:SI (plus:SI (match_dup 2) (const_int 8)))) --+ (set (match_operand:SI 6 "register_operand" "") --+ (mem:SI (plus:SI (match_dup 2) (const_int 12)))) --+ (set (match_operand:SI 7 "register_operand" "") --+ (mem:SI (plus:SI (match_dup 2) (const_int 16)))) --+ (set (match_operand:SI 8 "register_operand" "") --+ (mem:SI (plus:SI (match_dup 2) (const_int 20)))) --+ (set (match_operand:SI 9 "register_operand" "") --+ (mem:SI (plus:SI (match_dup 2) (const_int 24)))) --+ (set (match_operand:SI 10 "register_operand" "") --+ (mem:SI (plus:SI (match_dup 2) (const_int 28)))) --+ (set (match_operand:SI 11 "register_operand" "") --+ (mem:SI (plus:SI (match_dup 2) (const_int 32)))) --+ (set (match_operand:SI 12 "register_operand" "") --+ (mem:SI (plus:SI (match_dup 2) (const_int 36))))])] --+ "(XVECLEN (operands[0], 0) == 11)" --+ "lmw.bim\t%3, [%1], %12, 0x0" --+ [(set_attr "type" "load_multiple") --+ (set_attr "combo" "10") --+ (set_attr "length" "4")] --+) --+ --+(define_insn "*lmw_bim_si9" --+ [(match_parallel 0 "nds32_load_multiple_and_update_address_operation" --+ [(set (match_operand:SI 1 "register_operand" "=r") --+ (plus:SI (match_operand:SI 2 "register_operand" "1") (const_int 36))) --+ (set (match_operand:SI 3 "register_operand" "") --+ (mem:SI (match_dup 2))) --+ (set (match_operand:SI 4 "register_operand" "") --+ (mem:SI (plus:SI (match_dup 2) (const_int 4)))) --+ (set (match_operand:SI 5 "register_operand" "") --+ (mem:SI (plus:SI (match_dup 2) (const_int 8)))) --+ (set (match_operand:SI 6 "register_operand" "") --+ (mem:SI (plus:SI (match_dup 2) (const_int 12)))) --+ (set (match_operand:SI 7 "register_operand" "") --+ (mem:SI (plus:SI (match_dup 2) (const_int 16)))) --+ (set (match_operand:SI 8 "register_operand" "") --+ (mem:SI (plus:SI (match_dup 2) (const_int 20)))) --+ (set (match_operand:SI 9 "register_operand" "") --+ (mem:SI (plus:SI (match_dup 2) (const_int 24)))) --+ (set (match_operand:SI 10 "register_operand" "") --+ (mem:SI (plus:SI (match_dup 2) (const_int 28)))) --+ (set (match_operand:SI 11 "register_operand" "") --+ (mem:SI (plus:SI (match_dup 2) (const_int 32))))])] --+ "(XVECLEN (operands[0], 0) == 10)" --+ "lmw.bim\t%3, [%1], %11, 0x0" --+ [(set_attr "type" "load_multiple") --+ (set_attr "combo" "9") --+ (set_attr "length" "4")] --+) --+ --+(define_insn "*lmw_bim_si8" --+ [(match_parallel 0 "nds32_load_multiple_and_update_address_operation" --+ [(set (match_operand:SI 1 "register_operand" "=r") --+ (plus:SI (match_operand:SI 2 "register_operand" "1") (const_int 32))) --+ (set (match_operand:SI 3 "register_operand" "") --+ (mem:SI (match_dup 2))) --+ (set (match_operand:SI 4 "register_operand" "") --+ (mem:SI (plus:SI (match_dup 2) (const_int 4)))) --+ (set (match_operand:SI 5 "register_operand" "") --+ (mem:SI (plus:SI (match_dup 2) (const_int 8)))) --+ (set (match_operand:SI 6 "register_operand" "") --+ (mem:SI (plus:SI (match_dup 2) (const_int 12)))) --+ (set (match_operand:SI 7 "register_operand" "") --+ (mem:SI (plus:SI (match_dup 2) (const_int 16)))) --+ (set (match_operand:SI 8 "register_operand" "") --+ (mem:SI (plus:SI (match_dup 2) (const_int 20)))) --+ (set (match_operand:SI 9 "register_operand" "") --+ (mem:SI (plus:SI (match_dup 2) (const_int 24)))) --+ (set (match_operand:SI 10 "register_operand" "") --+ (mem:SI (plus:SI (match_dup 2) (const_int 28))))])] --+ "(XVECLEN (operands[0], 0) == 9)" --+ "lmw.bim\t%3, [%1], %10, 0x0" --+ [(set_attr "type" "load_multiple") --+ (set_attr "combo" "8") --+ (set_attr "length" "4")] --+) --+ --+(define_insn "*lmw_bim_si7" --+ [(match_parallel 0 "nds32_load_multiple_and_update_address_operation" --+ [(set (match_operand:SI 1 "register_operand" "=r") --+ (plus:SI (match_operand:SI 2 "register_operand" "1") (const_int 28))) --+ (set (match_operand:SI 3 "register_operand" "") --+ (mem:SI (match_dup 2))) --+ (set (match_operand:SI 4 "register_operand" "") --+ (mem:SI (plus:SI (match_dup 2) (const_int 4)))) --+ (set (match_operand:SI 5 "register_operand" "") --+ (mem:SI (plus:SI (match_dup 2) (const_int 8)))) --+ (set (match_operand:SI 6 "register_operand" "") --+ (mem:SI (plus:SI (match_dup 2) (const_int 12)))) --+ (set (match_operand:SI 7 "register_operand" "") --+ (mem:SI (plus:SI (match_dup 2) (const_int 16)))) --+ (set (match_operand:SI 8 "register_operand" "") --+ (mem:SI (plus:SI (match_dup 2) (const_int 20)))) --+ (set (match_operand:SI 9 "register_operand" "") --+ (mem:SI (plus:SI (match_dup 2) (const_int 24))))])] --+ "(XVECLEN (operands[0], 0) == 8)" --+ "lmw.bim\t%3, [%1], %9, 0x0" --+ [(set_attr "type" "load_multiple") --+ (set_attr "combo" "7") --+ (set_attr "length" "4")] --+) --+ --+(define_insn "*lmw_bim_si6" --+ [(match_parallel 0 "nds32_load_multiple_and_update_address_operation" --+ [(set (match_operand:SI 1 "register_operand" "=r") --+ (plus:SI (match_operand:SI 2 "register_operand" "1") (const_int 24))) --+ (set (match_operand:SI 3 "register_operand" "") --+ (mem:SI (match_dup 2))) --+ (set (match_operand:SI 4 "register_operand" "") --+ (mem:SI (plus:SI (match_dup 2) (const_int 4)))) --+ (set (match_operand:SI 5 "register_operand" "") --+ (mem:SI (plus:SI (match_dup 2) (const_int 8)))) --+ (set (match_operand:SI 6 "register_operand" "") --+ (mem:SI (plus:SI (match_dup 2) (const_int 12)))) --+ (set (match_operand:SI 7 "register_operand" "") --+ (mem:SI (plus:SI (match_dup 2) (const_int 16)))) --+ (set (match_operand:SI 8 "register_operand" "") --+ (mem:SI (plus:SI (match_dup 2) (const_int 20))))])] --+ "(XVECLEN (operands[0], 0) == 7)" --+ "lmw.bim\t%3, [%1], %8, 0x0" --+ [(set_attr "type" "load_multiple") --+ (set_attr "combo" "6") --+ (set_attr "length" "4")] --+) --+ --+(define_insn "*lmw_bim_si5" --+ [(match_parallel 0 "nds32_load_multiple_and_update_address_operation" --+ [(set (match_operand:SI 1 "register_operand" "=r") --+ (plus:SI (match_operand:SI 2 "register_operand" "1") (const_int 20))) --+ (set (match_operand:SI 3 "register_operand" "") --+ (mem:SI (match_dup 2))) --+ (set (match_operand:SI 4 "register_operand" "") --+ (mem:SI (plus:SI (match_dup 2) (const_int 4)))) --+ (set (match_operand:SI 5 "register_operand" "") --+ (mem:SI (plus:SI (match_dup 2) (const_int 8)))) --+ (set (match_operand:SI 6 "register_operand" "") --+ (mem:SI (plus:SI (match_dup 2) (const_int 12)))) --+ (set (match_operand:SI 7 "register_operand" "") --+ (mem:SI (plus:SI (match_dup 2) (const_int 16))))])] --+ "(XVECLEN (operands[0], 0) == 6)" --+ "lmw.bim\t%3, [%1], %7, 0x0" --+ [(set_attr "type" "load_multiple") --+ (set_attr "combo" "5") --+ (set_attr "length" "4")] --+) --+ --+(define_insn "*lmw_bim_si4" --+ [(match_parallel 0 "nds32_load_multiple_and_update_address_operation" --+ [(set (match_operand:SI 1 "register_operand" "=r") --+ (plus:SI (match_operand:SI 2 "register_operand" "1") (const_int 16))) --+ (set (match_operand:SI 3 "register_operand" "") --+ (mem:SI (match_dup 2))) --+ (set (match_operand:SI 4 "register_operand" "") --+ (mem:SI (plus:SI (match_dup 2) (const_int 4)))) --+ (set (match_operand:SI 5 "register_operand" "") --+ (mem:SI (plus:SI (match_dup 2) (const_int 8)))) --+ (set (match_operand:SI 6 "register_operand" "") --+ (mem:SI (plus:SI (match_dup 2) (const_int 12))))])] --+ "(XVECLEN (operands[0], 0) == 5)" --+ "lmw.bim\t%3, [%1], %6, 0x0" --+ [(set_attr "type" "load_multiple") --+ (set_attr "combo" "4") --+ (set_attr "length" "4")] --+) --+ --+(define_insn "*lmw_bim_si3" --+ [(match_parallel 0 "nds32_load_multiple_and_update_address_operation" --+ [(set (match_operand:SI 1 "register_operand" "=r") --+ (plus:SI (match_operand:SI 2 "register_operand" "1") (const_int 12))) --+ (set (match_operand:SI 3 "register_operand" "") --+ (mem:SI (match_dup 2))) --+ (set (match_operand:SI 4 "register_operand" "") --+ (mem:SI (plus:SI (match_dup 2) (const_int 4)))) --+ (set (match_operand:SI 5 "register_operand" "") --+ (mem:SI (plus:SI (match_dup 2) (const_int 8))))])] --+ "(XVECLEN (operands[0], 0) == 4)" --+ "lmw.bim\t%3, [%1], %5, 0x0" --+ [(set_attr "type" "load_multiple") --+ (set_attr "combo" "3") --+ (set_attr "length" "4")] --+) --+ --+(define_insn "*lmw_bim_si2" --+ [(match_parallel 0 "nds32_load_multiple_and_update_address_operation" --+ [(set (match_operand:SI 1 "register_operand" "=r") --+ (plus:SI (match_operand:SI 2 "register_operand" "1") (const_int 8))) --+ (set (match_operand:SI 3 "register_operand" "") --+ (mem:SI (match_dup 2))) --+ (set (match_operand:SI 4 "register_operand" "") --+ (mem:SI (plus:SI (match_dup 2) (const_int 4))))])] --+ "(XVECLEN (operands[0], 0) == 3)" --+ "lmw.bim\t%3, [%1], %4, 0x0" --+ [(set_attr "type" "load_multiple") --+ (set_attr "combo" "2") --+ (set_attr "length" "4")] --+) --+ --+(define_expand "unaligned_load_update_base_w" --+ [(parallel [(set (match_operand:SI 0 "register_operand" "") --+ (plus:SI (match_operand:SI 2 "register_operand" "") (const_int 4))) --+ (set (match_operand:SI 1 "register_operand" "") --+ (unspec:SI [(mem:SI (match_dup 2))] UNSPEC_UALOAD_W))])] --+ "" --+{ --+ /* DO NOT emit unaligned_load_w_m immediately since web pass don't --+ recognize post_inc, try it again after GCC 5.0. --+ REF: https://gcc.gnu.org/bugzilla/show_bug.cgi?id=63156 */ --+ emit_insn (gen_unaligned_load_w (operands[1], gen_rtx_MEM (SImode, operands[2]))); --+ emit_insn (gen_addsi3 (operands[0], operands[2], gen_int_mode (4, Pmode))); --+ DONE; --+} --+ [(set_attr "type" "load_multiple") --+ (set_attr "combo" "1") --+ (set_attr "length" "4")] --+) --+ --+(define_insn "*lmwsi25" -- [(match_parallel 0 "nds32_load_multiple_operation" -- [(set (match_operand:SI 2 "register_operand" "") -- (mem:SI (match_operand:SI 1 "register_operand" "r"))) --@@ -91,14 +1024,49 @@ -- (set (match_operand:SI 8 "register_operand" "") -- (mem:SI (plus:SI (match_dup 1) (const_int 24)))) -- (set (match_operand:SI 9 "register_operand" "") --- (mem:SI (plus:SI (match_dup 1) (const_int 28))))])] --- "(XVECLEN (operands[0], 0) == 8)" --- "lmw.bi\t%2, [%1], %9, 0x0" --- [(set_attr "type" "load") --- (set_attr "length" "4")] --+ (mem:SI (plus:SI (match_dup 1) (const_int 28)))) --+ (set (match_operand:SI 10 "register_operand" "") --+ (mem:SI (plus:SI (match_dup 1) (const_int 32)))) --+ (set (match_operand:SI 11 "register_operand" "") --+ (mem:SI (plus:SI (match_dup 1) (const_int 36)))) --+ (set (match_operand:SI 12 "register_operand" "") --+ (mem:SI (plus:SI (match_dup 1) (const_int 40)))) --+ (set (match_operand:SI 13 "register_operand" "") --+ (mem:SI (plus:SI (match_dup 1) (const_int 44)))) --+ (set (match_operand:SI 14 "register_operand" "") --+ (mem:SI (plus:SI (match_dup 1) (const_int 48)))) --+ (set (match_operand:SI 15 "register_operand" "") --+ (mem:SI (plus:SI (match_dup 1) (const_int 52)))) --+ (set (match_operand:SI 16 "register_operand" "") --+ (mem:SI (plus:SI (match_dup 1) (const_int 56)))) --+ (set (match_operand:SI 17 "register_operand" "") --+ (mem:SI (plus:SI (match_dup 1) (const_int 60)))) --+ (set (match_operand:SI 18 "register_operand" "") --+ (mem:SI (plus:SI (match_dup 1) (const_int 64)))) --+ (set (match_operand:SI 19 "register_operand" "") --+ (mem:SI (plus:SI (match_dup 1) (const_int 68)))) --+ (set (match_operand:SI 20 "register_operand" "") --+ (mem:SI (plus:SI (match_dup 1) (const_int 72)))) --+ (set (match_operand:SI 21 "register_operand" "") --+ (mem:SI (plus:SI (match_dup 1) (const_int 76)))) --+ (set (match_operand:SI 22 "register_operand" "") --+ (mem:SI (plus:SI (match_dup 1) (const_int 80)))) --+ (set (match_operand:SI 23 "register_operand" "") --+ (mem:SI (plus:SI (match_dup 1) (const_int 84)))) --+ (set (match_operand:SI 24 "register_operand" "") --+ (mem:SI (plus:SI (match_dup 1) (const_int 88)))) --+ (set (match_operand:SI 25 "register_operand" "") --+ (mem:SI (plus:SI (match_dup 1) (const_int 92)))) --+ (set (match_operand:SI 26 "register_operand" "") --+ (mem:SI (plus:SI (match_dup 1) (const_int 96))))])] --+ "(XVECLEN (operands[0], 0) == 25)" --+ "lmw.bi\t%2, [%1], %26, 0x0" --+ [(set_attr "type" "load_multiple") --+ (set_attr "combo" "25") --+ (set_attr "length" "4")] -- ) -- ---(define_insn "*lmwsi7" --+(define_insn "*lmwsi24" -- [(match_parallel 0 "nds32_load_multiple_operation" -- [(set (match_operand:SI 2 "register_operand" "") -- (mem:SI (match_operand:SI 1 "register_operand" "r"))) --@@ -113,14 +1081,49 @@ -- (set (match_operand:SI 7 "register_operand" "") -- (mem:SI (plus:SI (match_dup 1) (const_int 20)))) -- (set (match_operand:SI 8 "register_operand" "") --- (mem:SI (plus:SI (match_dup 1) (const_int 24))))])] --- "(XVECLEN (operands[0], 0) == 7)" --- "lmw.bi\t%2, [%1], %8, 0x0" --- [(set_attr "type" "load") --- (set_attr "length" "4")] --+ (mem:SI (plus:SI (match_dup 1) (const_int 24)))) --+ (set (match_operand:SI 9 "register_operand" "") --+ (mem:SI (plus:SI (match_dup 1) (const_int 28)))) --+ (set (match_operand:SI 10 "register_operand" "") --+ (mem:SI (plus:SI (match_dup 1) (const_int 32)))) --+ (set (match_operand:SI 11 "register_operand" "") --+ (mem:SI (plus:SI (match_dup 1) (const_int 36)))) --+ (set (match_operand:SI 12 "register_operand" "") --+ (mem:SI (plus:SI (match_dup 1) (const_int 40)))) --+ (set (match_operand:SI 13 "register_operand" "") --+ (mem:SI (plus:SI (match_dup 1) (const_int 44)))) --+ (set (match_operand:SI 14 "register_operand" "") --+ (mem:SI (plus:SI (match_dup 1) (const_int 48)))) --+ (set (match_operand:SI 15 "register_operand" "") --+ (mem:SI (plus:SI (match_dup 1) (const_int 52)))) --+ (set (match_operand:SI 16 "register_operand" "") --+ (mem:SI (plus:SI (match_dup 1) (const_int 56)))) --+ (set (match_operand:SI 17 "register_operand" "") --+ (mem:SI (plus:SI (match_dup 1) (const_int 60)))) --+ (set (match_operand:SI 18 "register_operand" "") --+ (mem:SI (plus:SI (match_dup 1) (const_int 64)))) --+ (set (match_operand:SI 19 "register_operand" "") --+ (mem:SI (plus:SI (match_dup 1) (const_int 68)))) --+ (set (match_operand:SI 20 "register_operand" "") --+ (mem:SI (plus:SI (match_dup 1) (const_int 72)))) --+ (set (match_operand:SI 21 "register_operand" "") --+ (mem:SI (plus:SI (match_dup 1) (const_int 76)))) --+ (set (match_operand:SI 22 "register_operand" "") --+ (mem:SI (plus:SI (match_dup 1) (const_int 80)))) --+ (set (match_operand:SI 23 "register_operand" "") --+ (mem:SI (plus:SI (match_dup 1) (const_int 84)))) --+ (set (match_operand:SI 24 "register_operand" "") --+ (mem:SI (plus:SI (match_dup 1) (const_int 88)))) --+ (set (match_operand:SI 25 "register_operand" "") --+ (mem:SI (plus:SI (match_dup 1) (const_int 92))))])] --+ "(XVECLEN (operands[0], 0) == 24)" --+ "lmw.bi\t%2, [%1], %25, 0x0" --+ [(set_attr "type" "load_multiple") --+ (set_attr "combo" "24") --+ (set_attr "length" "4")] -- ) -- ---(define_insn "*lmwsi6" --+(define_insn "*lmwsi23" -- [(match_parallel 0 "nds32_load_multiple_operation" -- [(set (match_operand:SI 2 "register_operand" "") -- (mem:SI (match_operand:SI 1 "register_operand" "r"))) --@@ -133,14 +1136,49 @@ -- (set (match_operand:SI 6 "register_operand" "") -- (mem:SI (plus:SI (match_dup 1) (const_int 16)))) -- (set (match_operand:SI 7 "register_operand" "") --- (mem:SI (plus:SI (match_dup 1) (const_int 20))))])] --- "(XVECLEN (operands[0], 0) == 6)" --- "lmw.bi\t%2, [%1], %7, 0x0" --- [(set_attr "type" "load") --- (set_attr "length" "4")] --+ (mem:SI (plus:SI (match_dup 1) (const_int 20)))) --+ (set (match_operand:SI 8 "register_operand" "") --+ (mem:SI (plus:SI (match_dup 1) (const_int 24)))) --+ (set (match_operand:SI 9 "register_operand" "") --+ (mem:SI (plus:SI (match_dup 1) (const_int 28)))) --+ (set (match_operand:SI 10 "register_operand" "") --+ (mem:SI (plus:SI (match_dup 1) (const_int 32)))) --+ (set (match_operand:SI 11 "register_operand" "") --+ (mem:SI (plus:SI (match_dup 1) (const_int 36)))) --+ (set (match_operand:SI 12 "register_operand" "") --+ (mem:SI (plus:SI (match_dup 1) (const_int 40)))) --+ (set (match_operand:SI 13 "register_operand" "") --+ (mem:SI (plus:SI (match_dup 1) (const_int 44)))) --+ (set (match_operand:SI 14 "register_operand" "") --+ (mem:SI (plus:SI (match_dup 1) (const_int 48)))) --+ (set (match_operand:SI 15 "register_operand" "") --+ (mem:SI (plus:SI (match_dup 1) (const_int 52)))) --+ (set (match_operand:SI 16 "register_operand" "") --+ (mem:SI (plus:SI (match_dup 1) (const_int 56)))) --+ (set (match_operand:SI 17 "register_operand" "") --+ (mem:SI (plus:SI (match_dup 1) (const_int 60)))) --+ (set (match_operand:SI 18 "register_operand" "") --+ (mem:SI (plus:SI (match_dup 1) (const_int 64)))) --+ (set (match_operand:SI 19 "register_operand" "") --+ (mem:SI (plus:SI (match_dup 1) (const_int 68)))) --+ (set (match_operand:SI 20 "register_operand" "") --+ (mem:SI (plus:SI (match_dup 1) (const_int 72)))) --+ (set (match_operand:SI 21 "register_operand" "") --+ (mem:SI (plus:SI (match_dup 1) (const_int 76)))) --+ (set (match_operand:SI 22 "register_operand" "") --+ (mem:SI (plus:SI (match_dup 1) (const_int 80)))) --+ (set (match_operand:SI 23 "register_operand" "") --+ (mem:SI (plus:SI (match_dup 1) (const_int 84)))) --+ (set (match_operand:SI 24 "register_operand" "") --+ (mem:SI (plus:SI (match_dup 1) (const_int 88))))])] --+ "(XVECLEN (operands[0], 0) == 23)" --+ "lmw.bi\t%2, [%1], %24, 0x0" --+ [(set_attr "type" "load_multiple") --+ (set_attr "combo" "23") --+ (set_attr "length" "4")] -- ) -- ---(define_insn "*lmwsi5" --+(define_insn "*lmwsi22" -- [(match_parallel 0 "nds32_load_multiple_operation" -- [(set (match_operand:SI 2 "register_operand" "") -- (mem:SI (match_operand:SI 1 "register_operand" "r"))) --@@ -151,110 +1189,2430 @@ -- (set (match_operand:SI 5 "register_operand" "") -- (mem:SI (plus:SI (match_dup 1) (const_int 12)))) -- (set (match_operand:SI 6 "register_operand" "") --- (mem:SI (plus:SI (match_dup 1) (const_int 16))))])] --- "(XVECLEN (operands[0], 0) == 5)" --- "lmw.bi\t%2, [%1], %6, 0x0" --- [(set_attr "type" "load") --- (set_attr "length" "4")] --+ (mem:SI (plus:SI (match_dup 1) (const_int 16)))) --+ (set (match_operand:SI 7 "register_operand" "") --+ (mem:SI (plus:SI (match_dup 1) (const_int 20)))) --+ (set (match_operand:SI 8 "register_operand" "") --+ (mem:SI (plus:SI (match_dup 1) (const_int 24)))) --+ (set (match_operand:SI 9 "register_operand" "") --+ (mem:SI (plus:SI (match_dup 1) (const_int 28)))) --+ (set (match_operand:SI 10 "register_operand" "") --+ (mem:SI (plus:SI (match_dup 1) (const_int 32)))) --+ (set (match_operand:SI 11 "register_operand" "") --+ (mem:SI (plus:SI (match_dup 1) (const_int 36)))) --+ (set (match_operand:SI 12 "register_operand" "") --+ (mem:SI (plus:SI (match_dup 1) (const_int 40)))) --+ (set (match_operand:SI 13 "register_operand" "") --+ (mem:SI (plus:SI (match_dup 1) (const_int 44)))) --+ (set (match_operand:SI 14 "register_operand" "") --+ (mem:SI (plus:SI (match_dup 1) (const_int 48)))) --+ (set (match_operand:SI 15 "register_operand" "") --+ (mem:SI (plus:SI (match_dup 1) (const_int 52)))) --+ (set (match_operand:SI 16 "register_operand" "") --+ (mem:SI (plus:SI (match_dup 1) (const_int 56)))) --+ (set (match_operand:SI 17 "register_operand" "") --+ (mem:SI (plus:SI (match_dup 1) (const_int 60)))) --+ (set (match_operand:SI 18 "register_operand" "") --+ (mem:SI (plus:SI (match_dup 1) (const_int 64)))) --+ (set (match_operand:SI 19 "register_operand" "") --+ (mem:SI (plus:SI (match_dup 1) (const_int 68)))) --+ (set (match_operand:SI 20 "register_operand" "") --+ (mem:SI (plus:SI (match_dup 1) (const_int 72)))) --+ (set (match_operand:SI 21 "register_operand" "") --+ (mem:SI (plus:SI (match_dup 1) (const_int 76)))) --+ (set (match_operand:SI 22 "register_operand" "") --+ (mem:SI (plus:SI (match_dup 1) (const_int 80)))) --+ (set (match_operand:SI 23 "register_operand" "") --+ (mem:SI (plus:SI (match_dup 1) (const_int 84))))])] --+ "(XVECLEN (operands[0], 0) == 22)" --+ "lmw.bi\t%2, [%1], %23, 0x0" --+ [(set_attr "type" "load_multiple") --+ (set_attr "combo" "22") --+ (set_attr "length" "4")] --+) --+ --+(define_insn "*lmwsi21" --+ [(match_parallel 0 "nds32_load_multiple_operation" --+ [(set (match_operand:SI 2 "register_operand" "") --+ (mem:SI (match_operand:SI 1 "register_operand" "r"))) --+ (set (match_operand:SI 3 "register_operand" "") --+ (mem:SI (plus:SI (match_dup 1) (const_int 4)))) --+ (set (match_operand:SI 4 "register_operand" "") --+ (mem:SI (plus:SI (match_dup 1) (const_int 8)))) --+ (set (match_operand:SI 5 "register_operand" "") --+ (mem:SI (plus:SI (match_dup 1) (const_int 12)))) --+ (set (match_operand:SI 6 "register_operand" "") --+ (mem:SI (plus:SI (match_dup 1) (const_int 16)))) --+ (set (match_operand:SI 7 "register_operand" "") --+ (mem:SI (plus:SI (match_dup 1) (const_int 20)))) --+ (set (match_operand:SI 8 "register_operand" "") --+ (mem:SI (plus:SI (match_dup 1) (const_int 24)))) --+ (set (match_operand:SI 9 "register_operand" "") --+ (mem:SI (plus:SI (match_dup 1) (const_int 28)))) --+ (set (match_operand:SI 10 "register_operand" "") --+ (mem:SI (plus:SI (match_dup 1) (const_int 32)))) --+ (set (match_operand:SI 11 "register_operand" "") --+ (mem:SI (plus:SI (match_dup 1) (const_int 36)))) --+ (set (match_operand:SI 12 "register_operand" "") --+ (mem:SI (plus:SI (match_dup 1) (const_int 40)))) --+ (set (match_operand:SI 13 "register_operand" "") --+ (mem:SI (plus:SI (match_dup 1) (const_int 44)))) --+ (set (match_operand:SI 14 "register_operand" "") --+ (mem:SI (plus:SI (match_dup 1) (const_int 48)))) --+ (set (match_operand:SI 15 "register_operand" "") --+ (mem:SI (plus:SI (match_dup 1) (const_int 52)))) --+ (set (match_operand:SI 16 "register_operand" "") --+ (mem:SI (plus:SI (match_dup 1) (const_int 56)))) --+ (set (match_operand:SI 17 "register_operand" "") --+ (mem:SI (plus:SI (match_dup 1) (const_int 60)))) --+ (set (match_operand:SI 18 "register_operand" "") --+ (mem:SI (plus:SI (match_dup 1) (const_int 64)))) --+ (set (match_operand:SI 19 "register_operand" "") --+ (mem:SI (plus:SI (match_dup 1) (const_int 68)))) --+ (set (match_operand:SI 20 "register_operand" "") --+ (mem:SI (plus:SI (match_dup 1) (const_int 72)))) --+ (set (match_operand:SI 21 "register_operand" "") --+ (mem:SI (plus:SI (match_dup 1) (const_int 76)))) --+ (set (match_operand:SI 22 "register_operand" "") --+ (mem:SI (plus:SI (match_dup 1) (const_int 80))))])] --+ "(XVECLEN (operands[0], 0) == 21)" --+ "lmw.bi\t%2, [%1], %22, 0x0" --+ [(set_attr "type" "load_multiple") --+ (set_attr "combo" "21") --+ (set_attr "length" "4")] --+) --+ --+(define_insn "*lmwsi20" --+ [(match_parallel 0 "nds32_load_multiple_operation" --+ [(set (match_operand:SI 2 "register_operand" "") --+ (mem:SI (match_operand:SI 1 "register_operand" "r"))) --+ (set (match_operand:SI 3 "register_operand" "") --+ (mem:SI (plus:SI (match_dup 1) (const_int 4)))) --+ (set (match_operand:SI 4 "register_operand" "") --+ (mem:SI (plus:SI (match_dup 1) (const_int 8)))) --+ (set (match_operand:SI 5 "register_operand" "") --+ (mem:SI (plus:SI (match_dup 1) (const_int 12)))) --+ (set (match_operand:SI 6 "register_operand" "") --+ (mem:SI (plus:SI (match_dup 1) (const_int 16)))) --+ (set (match_operand:SI 7 "register_operand" "") --+ (mem:SI (plus:SI (match_dup 1) (const_int 20)))) --+ (set (match_operand:SI 8 "register_operand" "") --+ (mem:SI (plus:SI (match_dup 1) (const_int 24)))) --+ (set (match_operand:SI 9 "register_operand" "") --+ (mem:SI (plus:SI (match_dup 1) (const_int 28)))) --+ (set (match_operand:SI 10 "register_operand" "") --+ (mem:SI (plus:SI (match_dup 1) (const_int 32)))) --+ (set (match_operand:SI 11 "register_operand" "") --+ (mem:SI (plus:SI (match_dup 1) (const_int 36)))) --+ (set (match_operand:SI 12 "register_operand" "") --+ (mem:SI (plus:SI (match_dup 1) (const_int 40)))) --+ (set (match_operand:SI 13 "register_operand" "") --+ (mem:SI (plus:SI (match_dup 1) (const_int 44)))) --+ (set (match_operand:SI 14 "register_operand" "") --+ (mem:SI (plus:SI (match_dup 1) (const_int 48)))) --+ (set (match_operand:SI 15 "register_operand" "") --+ (mem:SI (plus:SI (match_dup 1) (const_int 52)))) --+ (set (match_operand:SI 16 "register_operand" "") --+ (mem:SI (plus:SI (match_dup 1) (const_int 56)))) --+ (set (match_operand:SI 17 "register_operand" "") --+ (mem:SI (plus:SI (match_dup 1) (const_int 60)))) --+ (set (match_operand:SI 18 "register_operand" "") --+ (mem:SI (plus:SI (match_dup 1) (const_int 64)))) --+ (set (match_operand:SI 19 "register_operand" "") --+ (mem:SI (plus:SI (match_dup 1) (const_int 68)))) --+ (set (match_operand:SI 20 "register_operand" "") --+ (mem:SI (plus:SI (match_dup 1) (const_int 72)))) --+ (set (match_operand:SI 21 "register_operand" "") --+ (mem:SI (plus:SI (match_dup 1) (const_int 76))))])] --+ "(XVECLEN (operands[0], 0) == 20)" --+ "lmw.bi\t%2, [%1], %21, 0x0" --+ [(set_attr "type" "load_multiple") --+ (set_attr "combo" "20") --+ (set_attr "length" "4")] --+) --+ --+(define_insn "*lmwsi19" --+ [(match_parallel 0 "nds32_load_multiple_operation" --+ [(set (match_operand:SI 2 "register_operand" "") --+ (mem:SI (match_operand:SI 1 "register_operand" "r"))) --+ (set (match_operand:SI 3 "register_operand" "") --+ (mem:SI (plus:SI (match_dup 1) (const_int 4)))) --+ (set (match_operand:SI 4 "register_operand" "") --+ (mem:SI (plus:SI (match_dup 1) (const_int 8)))) --+ (set (match_operand:SI 5 "register_operand" "") --+ (mem:SI (plus:SI (match_dup 1) (const_int 12)))) --+ (set (match_operand:SI 6 "register_operand" "") --+ (mem:SI (plus:SI (match_dup 1) (const_int 16)))) --+ (set (match_operand:SI 7 "register_operand" "") --+ (mem:SI (plus:SI (match_dup 1) (const_int 20)))) --+ (set (match_operand:SI 8 "register_operand" "") --+ (mem:SI (plus:SI (match_dup 1) (const_int 24)))) --+ (set (match_operand:SI 9 "register_operand" "") --+ (mem:SI (plus:SI (match_dup 1) (const_int 28)))) --+ (set (match_operand:SI 10 "register_operand" "") --+ (mem:SI (plus:SI (match_dup 1) (const_int 32)))) --+ (set (match_operand:SI 11 "register_operand" "") --+ (mem:SI (plus:SI (match_dup 1) (const_int 36)))) --+ (set (match_operand:SI 12 "register_operand" "") --+ (mem:SI (plus:SI (match_dup 1) (const_int 40)))) --+ (set (match_operand:SI 13 "register_operand" "") --+ (mem:SI (plus:SI (match_dup 1) (const_int 44)))) --+ (set (match_operand:SI 14 "register_operand" "") --+ (mem:SI (plus:SI (match_dup 1) (const_int 48)))) --+ (set (match_operand:SI 15 "register_operand" "") --+ (mem:SI (plus:SI (match_dup 1) (const_int 52)))) --+ (set (match_operand:SI 16 "register_operand" "") --+ (mem:SI (plus:SI (match_dup 1) (const_int 56)))) --+ (set (match_operand:SI 17 "register_operand" "") --+ (mem:SI (plus:SI (match_dup 1) (const_int 60)))) --+ (set (match_operand:SI 18 "register_operand" "") --+ (mem:SI (plus:SI (match_dup 1) (const_int 64)))) --+ (set (match_operand:SI 19 "register_operand" "") --+ (mem:SI (plus:SI (match_dup 1) (const_int 68)))) --+ (set (match_operand:SI 20 "register_operand" "") --+ (mem:SI (plus:SI (match_dup 1) (const_int 72))))])] --+ "(XVECLEN (operands[0], 0) == 19)" --+ "lmw.bi\t%2, [%1], %20, 0x0" --+ [(set_attr "type" "load_multiple") --+ (set_attr "combo" "19") --+ (set_attr "length" "4")] --+) --+ --+(define_insn "*lmwsi18" --+ [(match_parallel 0 "nds32_load_multiple_operation" --+ [(set (match_operand:SI 2 "register_operand" "") --+ (mem:SI (match_operand:SI 1 "register_operand" "r"))) --+ (set (match_operand:SI 3 "register_operand" "") --+ (mem:SI (plus:SI (match_dup 1) (const_int 4)))) --+ (set (match_operand:SI 4 "register_operand" "") --+ (mem:SI (plus:SI (match_dup 1) (const_int 8)))) --+ (set (match_operand:SI 5 "register_operand" "") --+ (mem:SI (plus:SI (match_dup 1) (const_int 12)))) --+ (set (match_operand:SI 6 "register_operand" "") --+ (mem:SI (plus:SI (match_dup 1) (const_int 16)))) --+ (set (match_operand:SI 7 "register_operand" "") --+ (mem:SI (plus:SI (match_dup 1) (const_int 20)))) --+ (set (match_operand:SI 8 "register_operand" "") --+ (mem:SI (plus:SI (match_dup 1) (const_int 24)))) --+ (set (match_operand:SI 9 "register_operand" "") --+ (mem:SI (plus:SI (match_dup 1) (const_int 28)))) --+ (set (match_operand:SI 10 "register_operand" "") --+ (mem:SI (plus:SI (match_dup 1) (const_int 32)))) --+ (set (match_operand:SI 11 "register_operand" "") --+ (mem:SI (plus:SI (match_dup 1) (const_int 36)))) --+ (set (match_operand:SI 12 "register_operand" "") --+ (mem:SI (plus:SI (match_dup 1) (const_int 40)))) --+ (set (match_operand:SI 13 "register_operand" "") --+ (mem:SI (plus:SI (match_dup 1) (const_int 44)))) --+ (set (match_operand:SI 14 "register_operand" "") --+ (mem:SI (plus:SI (match_dup 1) (const_int 48)))) --+ (set (match_operand:SI 15 "register_operand" "") --+ (mem:SI (plus:SI (match_dup 1) (const_int 52)))) --+ (set (match_operand:SI 16 "register_operand" "") --+ (mem:SI (plus:SI (match_dup 1) (const_int 56)))) --+ (set (match_operand:SI 17 "register_operand" "") --+ (mem:SI (plus:SI (match_dup 1) (const_int 60)))) --+ (set (match_operand:SI 18 "register_operand" "") --+ (mem:SI (plus:SI (match_dup 1) (const_int 64)))) --+ (set (match_operand:SI 19 "register_operand" "") --+ (mem:SI (plus:SI (match_dup 1) (const_int 68))))])] --+ "(XVECLEN (operands[0], 0) == 18)" --+ "lmw.bi\t%2, [%1], %19, 0x0" --+ [(set_attr "type" "load_multiple") --+ (set_attr "combo" "18") --+ (set_attr "length" "4")] --+) --+ --+(define_insn "*lmwsi17" --+ [(match_parallel 0 "nds32_load_multiple_operation" --+ [(set (match_operand:SI 2 "register_operand" "") --+ (mem:SI (match_operand:SI 1 "register_operand" "r"))) --+ (set (match_operand:SI 3 "register_operand" "") --+ (mem:SI (plus:SI (match_dup 1) (const_int 4)))) --+ (set (match_operand:SI 4 "register_operand" "") --+ (mem:SI (plus:SI (match_dup 1) (const_int 8)))) --+ (set (match_operand:SI 5 "register_operand" "") --+ (mem:SI (plus:SI (match_dup 1) (const_int 12)))) --+ (set (match_operand:SI 6 "register_operand" "") --+ (mem:SI (plus:SI (match_dup 1) (const_int 16)))) --+ (set (match_operand:SI 7 "register_operand" "") --+ (mem:SI (plus:SI (match_dup 1) (const_int 20)))) --+ (set (match_operand:SI 8 "register_operand" "") --+ (mem:SI (plus:SI (match_dup 1) (const_int 24)))) --+ (set (match_operand:SI 9 "register_operand" "") --+ (mem:SI (plus:SI (match_dup 1) (const_int 28)))) --+ (set (match_operand:SI 10 "register_operand" "") --+ (mem:SI (plus:SI (match_dup 1) (const_int 32)))) --+ (set (match_operand:SI 11 "register_operand" "") --+ (mem:SI (plus:SI (match_dup 1) (const_int 36)))) --+ (set (match_operand:SI 12 "register_operand" "") --+ (mem:SI (plus:SI (match_dup 1) (const_int 40)))) --+ (set (match_operand:SI 13 "register_operand" "") --+ (mem:SI (plus:SI (match_dup 1) (const_int 44)))) --+ (set (match_operand:SI 14 "register_operand" "") --+ (mem:SI (plus:SI (match_dup 1) (const_int 48)))) --+ (set (match_operand:SI 15 "register_operand" "") --+ (mem:SI (plus:SI (match_dup 1) (const_int 52)))) --+ (set (match_operand:SI 16 "register_operand" "") --+ (mem:SI (plus:SI (match_dup 1) (const_int 56)))) --+ (set (match_operand:SI 17 "register_operand" "") --+ (mem:SI (plus:SI (match_dup 1) (const_int 60)))) --+ (set (match_operand:SI 18 "register_operand" "") --+ (mem:SI (plus:SI (match_dup 1) (const_int 64))))])] --+ "(XVECLEN (operands[0], 0) == 17)" --+ "lmw.bi\t%2, [%1], %18, 0x0" --+ [(set_attr "type" "load_multiple") --+ (set_attr "combo" "17") --+ (set_attr "length" "4")] --+) --+ --+(define_insn "*lmwsi16" --+ [(match_parallel 0 "nds32_load_multiple_operation" --+ [(set (match_operand:SI 2 "register_operand" "") --+ (mem:SI (match_operand:SI 1 "register_operand" "r"))) --+ (set (match_operand:SI 3 "register_operand" "") --+ (mem:SI (plus:SI (match_dup 1) (const_int 4)))) --+ (set (match_operand:SI 4 "register_operand" "") --+ (mem:SI (plus:SI (match_dup 1) (const_int 8)))) --+ (set (match_operand:SI 5 "register_operand" "") --+ (mem:SI (plus:SI (match_dup 1) (const_int 12)))) --+ (set (match_operand:SI 6 "register_operand" "") --+ (mem:SI (plus:SI (match_dup 1) (const_int 16)))) --+ (set (match_operand:SI 7 "register_operand" "") --+ (mem:SI (plus:SI (match_dup 1) (const_int 20)))) --+ (set (match_operand:SI 8 "register_operand" "") --+ (mem:SI (plus:SI (match_dup 1) (const_int 24)))) --+ (set (match_operand:SI 9 "register_operand" "") --+ (mem:SI (plus:SI (match_dup 1) (const_int 28)))) --+ (set (match_operand:SI 10 "register_operand" "") --+ (mem:SI (plus:SI (match_dup 1) (const_int 32)))) --+ (set (match_operand:SI 11 "register_operand" "") --+ (mem:SI (plus:SI (match_dup 1) (const_int 36)))) --+ (set (match_operand:SI 12 "register_operand" "") --+ (mem:SI (plus:SI (match_dup 1) (const_int 40)))) --+ (set (match_operand:SI 13 "register_operand" "") --+ (mem:SI (plus:SI (match_dup 1) (const_int 44)))) --+ (set (match_operand:SI 14 "register_operand" "") --+ (mem:SI (plus:SI (match_dup 1) (const_int 48)))) --+ (set (match_operand:SI 15 "register_operand" "") --+ (mem:SI (plus:SI (match_dup 1) (const_int 52)))) --+ (set (match_operand:SI 16 "register_operand" "") --+ (mem:SI (plus:SI (match_dup 1) (const_int 56)))) --+ (set (match_operand:SI 17 "register_operand" "") --+ (mem:SI (plus:SI (match_dup 1) (const_int 60))))])] --+ "(XVECLEN (operands[0], 0) == 16)" --+ "lmw.bi\t%2, [%1], %17, 0x0" --+ [(set_attr "type" "load_multiple") --+ (set_attr "combo" "16") --+ (set_attr "length" "4")] --+) --+ --+(define_insn "*lmwsi15" --+ [(match_parallel 0 "nds32_load_multiple_operation" --+ [(set (match_operand:SI 2 "register_operand" "") --+ (mem:SI (match_operand:SI 1 "register_operand" "r"))) --+ (set (match_operand:SI 3 "register_operand" "") --+ (mem:SI (plus:SI (match_dup 1) (const_int 4)))) --+ (set (match_operand:SI 4 "register_operand" "") --+ (mem:SI (plus:SI (match_dup 1) (const_int 8)))) --+ (set (match_operand:SI 5 "register_operand" "") --+ (mem:SI (plus:SI (match_dup 1) (const_int 12)))) --+ (set (match_operand:SI 6 "register_operand" "") --+ (mem:SI (plus:SI (match_dup 1) (const_int 16)))) --+ (set (match_operand:SI 7 "register_operand" "") --+ (mem:SI (plus:SI (match_dup 1) (const_int 20)))) --+ (set (match_operand:SI 8 "register_operand" "") --+ (mem:SI (plus:SI (match_dup 1) (const_int 24)))) --+ (set (match_operand:SI 9 "register_operand" "") --+ (mem:SI (plus:SI (match_dup 1) (const_int 28)))) --+ (set (match_operand:SI 10 "register_operand" "") --+ (mem:SI (plus:SI (match_dup 1) (const_int 32)))) --+ (set (match_operand:SI 11 "register_operand" "") --+ (mem:SI (plus:SI (match_dup 1) (const_int 36)))) --+ (set (match_operand:SI 12 "register_operand" "") --+ (mem:SI (plus:SI (match_dup 1) (const_int 40)))) --+ (set (match_operand:SI 13 "register_operand" "") --+ (mem:SI (plus:SI (match_dup 1) (const_int 44)))) --+ (set (match_operand:SI 14 "register_operand" "") --+ (mem:SI (plus:SI (match_dup 1) (const_int 48)))) --+ (set (match_operand:SI 15 "register_operand" "") --+ (mem:SI (plus:SI (match_dup 1) (const_int 52)))) --+ (set (match_operand:SI 16 "register_operand" "") --+ (mem:SI (plus:SI (match_dup 1) (const_int 56))))])] --+ "(XVECLEN (operands[0], 0) == 15)" --+ "lmw.bi\t%2, [%1], %16, 0x0" --+ [(set_attr "type" "load_multiple") --+ (set_attr "combo" "15") --+ (set_attr "length" "4")] --+) --+ --+(define_insn "*lmwsi14" --+ [(match_parallel 0 "nds32_load_multiple_operation" --+ [(set (match_operand:SI 2 "register_operand" "") --+ (mem:SI (match_operand:SI 1 "register_operand" "r"))) --+ (set (match_operand:SI 3 "register_operand" "") --+ (mem:SI (plus:SI (match_dup 1) (const_int 4)))) --+ (set (match_operand:SI 4 "register_operand" "") --+ (mem:SI (plus:SI (match_dup 1) (const_int 8)))) --+ (set (match_operand:SI 5 "register_operand" "") --+ (mem:SI (plus:SI (match_dup 1) (const_int 12)))) --+ (set (match_operand:SI 6 "register_operand" "") --+ (mem:SI (plus:SI (match_dup 1) (const_int 16)))) --+ (set (match_operand:SI 7 "register_operand" "") --+ (mem:SI (plus:SI (match_dup 1) (const_int 20)))) --+ (set (match_operand:SI 8 "register_operand" "") --+ (mem:SI (plus:SI (match_dup 1) (const_int 24)))) --+ (set (match_operand:SI 9 "register_operand" "") --+ (mem:SI (plus:SI (match_dup 1) (const_int 28)))) --+ (set (match_operand:SI 10 "register_operand" "") --+ (mem:SI (plus:SI (match_dup 1) (const_int 32)))) --+ (set (match_operand:SI 11 "register_operand" "") --+ (mem:SI (plus:SI (match_dup 1) (const_int 36)))) --+ (set (match_operand:SI 12 "register_operand" "") --+ (mem:SI (plus:SI (match_dup 1) (const_int 40)))) --+ (set (match_operand:SI 13 "register_operand" "") --+ (mem:SI (plus:SI (match_dup 1) (const_int 44)))) --+ (set (match_operand:SI 14 "register_operand" "") --+ (mem:SI (plus:SI (match_dup 1) (const_int 48)))) --+ (set (match_operand:SI 15 "register_operand" "") --+ (mem:SI (plus:SI (match_dup 1) (const_int 52))))])] --+ "(XVECLEN (operands[0], 0) == 14)" --+ "lmw.bi\t%2, [%1], %15, 0x0" --+ [(set_attr "type" "load_multiple") --+ (set_attr "combo" "14") --+ (set_attr "length" "4")] --+) --+ --+(define_insn "*lmwsi13" --+ [(match_parallel 0 "nds32_load_multiple_operation" --+ [(set (match_operand:SI 2 "register_operand" "") --+ (mem:SI (match_operand:SI 1 "register_operand" "r"))) --+ (set (match_operand:SI 3 "register_operand" "") --+ (mem:SI (plus:SI (match_dup 1) (const_int 4)))) --+ (set (match_operand:SI 4 "register_operand" "") --+ (mem:SI (plus:SI (match_dup 1) (const_int 8)))) --+ (set (match_operand:SI 5 "register_operand" "") --+ (mem:SI (plus:SI (match_dup 1) (const_int 12)))) --+ (set (match_operand:SI 6 "register_operand" "") --+ (mem:SI (plus:SI (match_dup 1) (const_int 16)))) --+ (set (match_operand:SI 7 "register_operand" "") --+ (mem:SI (plus:SI (match_dup 1) (const_int 20)))) --+ (set (match_operand:SI 8 "register_operand" "") --+ (mem:SI (plus:SI (match_dup 1) (const_int 24)))) --+ (set (match_operand:SI 9 "register_operand" "") --+ (mem:SI (plus:SI (match_dup 1) (const_int 28)))) --+ (set (match_operand:SI 10 "register_operand" "") --+ (mem:SI (plus:SI (match_dup 1) (const_int 32)))) --+ (set (match_operand:SI 11 "register_operand" "") --+ (mem:SI (plus:SI (match_dup 1) (const_int 36)))) --+ (set (match_operand:SI 12 "register_operand" "") --+ (mem:SI (plus:SI (match_dup 1) (const_int 40)))) --+ (set (match_operand:SI 13 "register_operand" "") --+ (mem:SI (plus:SI (match_dup 1) (const_int 44)))) --+ (set (match_operand:SI 14 "register_operand" "") --+ (mem:SI (plus:SI (match_dup 1) (const_int 48))))])] --+ "(XVECLEN (operands[0], 0) == 13)" --+ "lmw.bi\t%2, [%1], %14, 0x0" --+ [(set_attr "type" "load_multiple") --+ (set_attr "combo" "13") --+ (set_attr "length" "4")] --+) --+ --+(define_insn "*lmwsi12" --+ [(match_parallel 0 "nds32_load_multiple_operation" --+ [(set (match_operand:SI 2 "register_operand" "") --+ (mem:SI (match_operand:SI 1 "register_operand" "r"))) --+ (set (match_operand:SI 3 "register_operand" "") --+ (mem:SI (plus:SI (match_dup 1) (const_int 4)))) --+ (set (match_operand:SI 4 "register_operand" "") --+ (mem:SI (plus:SI (match_dup 1) (const_int 8)))) --+ (set (match_operand:SI 5 "register_operand" "") --+ (mem:SI (plus:SI (match_dup 1) (const_int 12)))) --+ (set (match_operand:SI 6 "register_operand" "") --+ (mem:SI (plus:SI (match_dup 1) (const_int 16)))) --+ (set (match_operand:SI 7 "register_operand" "") --+ (mem:SI (plus:SI (match_dup 1) (const_int 20)))) --+ (set (match_operand:SI 8 "register_operand" "") --+ (mem:SI (plus:SI (match_dup 1) (const_int 24)))) --+ (set (match_operand:SI 9 "register_operand" "") --+ (mem:SI (plus:SI (match_dup 1) (const_int 28)))) --+ (set (match_operand:SI 10 "register_operand" "") --+ (mem:SI (plus:SI (match_dup 1) (const_int 32)))) --+ (set (match_operand:SI 11 "register_operand" "") --+ (mem:SI (plus:SI (match_dup 1) (const_int 36)))) --+ (set (match_operand:SI 12 "register_operand" "") --+ (mem:SI (plus:SI (match_dup 1) (const_int 40)))) --+ (set (match_operand:SI 13 "register_operand" "") --+ (mem:SI (plus:SI (match_dup 1) (const_int 44))))])] --+ "(XVECLEN (operands[0], 0) == 12)" --+ "lmw.bi\t%2, [%1], %13, 0x0" --+ [(set_attr "type" "load_multiple") --+ (set_attr "combo" "12") --+ (set_attr "length" "4")] --+) --+ --+(define_insn "*lmwsi11" --+ [(match_parallel 0 "nds32_load_multiple_operation" --+ [(set (match_operand:SI 2 "register_operand" "") --+ (mem:SI (match_operand:SI 1 "register_operand" "r"))) --+ (set (match_operand:SI 3 "register_operand" "") --+ (mem:SI (plus:SI (match_dup 1) (const_int 4)))) --+ (set (match_operand:SI 4 "register_operand" "") --+ (mem:SI (plus:SI (match_dup 1) (const_int 8)))) --+ (set (match_operand:SI 5 "register_operand" "") --+ (mem:SI (plus:SI (match_dup 1) (const_int 12)))) --+ (set (match_operand:SI 6 "register_operand" "") --+ (mem:SI (plus:SI (match_dup 1) (const_int 16)))) --+ (set (match_operand:SI 7 "register_operand" "") --+ (mem:SI (plus:SI (match_dup 1) (const_int 20)))) --+ (set (match_operand:SI 8 "register_operand" "") --+ (mem:SI (plus:SI (match_dup 1) (const_int 24)))) --+ (set (match_operand:SI 9 "register_operand" "") --+ (mem:SI (plus:SI (match_dup 1) (const_int 28)))) --+ (set (match_operand:SI 10 "register_operand" "") --+ (mem:SI (plus:SI (match_dup 1) (const_int 32)))) --+ (set (match_operand:SI 11 "register_operand" "") --+ (mem:SI (plus:SI (match_dup 1) (const_int 36)))) --+ (set (match_operand:SI 12 "register_operand" "") --+ (mem:SI (plus:SI (match_dup 1) (const_int 40))))])] --+ "(XVECLEN (operands[0], 0) == 11)" --+ "lmw.bi\t%2, [%1], %12, 0x0" --+ [(set_attr "type" "load_multiple") --+ (set_attr "combo" "11") --+ (set_attr "length" "4")] --+) --+ --+(define_insn "*lmwsi10" --+ [(match_parallel 0 "nds32_load_multiple_operation" --+ [(set (match_operand:SI 2 "register_operand" "") --+ (mem:SI (match_operand:SI 1 "register_operand" "r"))) --+ (set (match_operand:SI 3 "register_operand" "") --+ (mem:SI (plus:SI (match_dup 1) (const_int 4)))) --+ (set (match_operand:SI 4 "register_operand" "") --+ (mem:SI (plus:SI (match_dup 1) (const_int 8)))) --+ (set (match_operand:SI 5 "register_operand" "") --+ (mem:SI (plus:SI (match_dup 1) (const_int 12)))) --+ (set (match_operand:SI 6 "register_operand" "") --+ (mem:SI (plus:SI (match_dup 1) (const_int 16)))) --+ (set (match_operand:SI 7 "register_operand" "") --+ (mem:SI (plus:SI (match_dup 1) (const_int 20)))) --+ (set (match_operand:SI 8 "register_operand" "") --+ (mem:SI (plus:SI (match_dup 1) (const_int 24)))) --+ (set (match_operand:SI 9 "register_operand" "") --+ (mem:SI (plus:SI (match_dup 1) (const_int 28)))) --+ (set (match_operand:SI 10 "register_operand" "") --+ (mem:SI (plus:SI (match_dup 1) (const_int 32)))) --+ (set (match_operand:SI 11 "register_operand" "") --+ (mem:SI (plus:SI (match_dup 1) (const_int 36))))])] --+ "(XVECLEN (operands[0], 0) == 10)" --+ "lmw.bi\t%2, [%1], %11, 0x0" --+ [(set_attr "type" "load_multiple") --+ (set_attr "combo" "10") --+ (set_attr "length" "4")] --+) --+ --+(define_insn "*lmwsi9" --+ [(match_parallel 0 "nds32_load_multiple_operation" --+ [(set (match_operand:SI 2 "register_operand" "") --+ (mem:SI (match_operand:SI 1 "register_operand" "r"))) --+ (set (match_operand:SI 3 "register_operand" "") --+ (mem:SI (plus:SI (match_dup 1) (const_int 4)))) --+ (set (match_operand:SI 4 "register_operand" "") --+ (mem:SI (plus:SI (match_dup 1) (const_int 8)))) --+ (set (match_operand:SI 5 "register_operand" "") --+ (mem:SI (plus:SI (match_dup 1) (const_int 12)))) --+ (set (match_operand:SI 6 "register_operand" "") --+ (mem:SI (plus:SI (match_dup 1) (const_int 16)))) --+ (set (match_operand:SI 7 "register_operand" "") --+ (mem:SI (plus:SI (match_dup 1) (const_int 20)))) --+ (set (match_operand:SI 8 "register_operand" "") --+ (mem:SI (plus:SI (match_dup 1) (const_int 24)))) --+ (set (match_operand:SI 9 "register_operand" "") --+ (mem:SI (plus:SI (match_dup 1) (const_int 28)))) --+ (set (match_operand:SI 10 "register_operand" "") --+ (mem:SI (plus:SI (match_dup 1) (const_int 32))))])] --+ "(XVECLEN (operands[0], 0) == 9)" --+ "lmw.bi\t%2, [%1], %10, 0x0" --+ [(set_attr "type" "load_multiple") --+ (set_attr "combo" "9") --+ (set_attr "length" "4")] --+) --+ --+(define_insn "*lmwsi8" --+ [(match_parallel 0 "nds32_load_multiple_operation" --+ [(set (match_operand:SI 2 "register_operand" "") --+ (mem:SI (match_operand:SI 1 "register_operand" "r"))) --+ (set (match_operand:SI 3 "register_operand" "") --+ (mem:SI (plus:SI (match_dup 1) (const_int 4)))) --+ (set (match_operand:SI 4 "register_operand" "") --+ (mem:SI (plus:SI (match_dup 1) (const_int 8)))) --+ (set (match_operand:SI 5 "register_operand" "") --+ (mem:SI (plus:SI (match_dup 1) (const_int 12)))) --+ (set (match_operand:SI 6 "register_operand" "") --+ (mem:SI (plus:SI (match_dup 1) (const_int 16)))) --+ (set (match_operand:SI 7 "register_operand" "") --+ (mem:SI (plus:SI (match_dup 1) (const_int 20)))) --+ (set (match_operand:SI 8 "register_operand" "") --+ (mem:SI (plus:SI (match_dup 1) (const_int 24)))) --+ (set (match_operand:SI 9 "register_operand" "") --+ (mem:SI (plus:SI (match_dup 1) (const_int 28))))])] --+ "(XVECLEN (operands[0], 0) == 8)" --+ "lmw.bi\t%2, [%1], %9, 0x0" --+ [(set_attr "type" "load_multiple") --+ (set_attr "combo" "8") --+ (set_attr "length" "4")] --+) --+ --+(define_insn "*lmwsi7" --+ [(match_parallel 0 "nds32_load_multiple_operation" --+ [(set (match_operand:SI 2 "register_operand" "") --+ (mem:SI (match_operand:SI 1 "register_operand" "r"))) --+ (set (match_operand:SI 3 "register_operand" "") --+ (mem:SI (plus:SI (match_dup 1) (const_int 4)))) --+ (set (match_operand:SI 4 "register_operand" "") --+ (mem:SI (plus:SI (match_dup 1) (const_int 8)))) --+ (set (match_operand:SI 5 "register_operand" "") --+ (mem:SI (plus:SI (match_dup 1) (const_int 12)))) --+ (set (match_operand:SI 6 "register_operand" "") --+ (mem:SI (plus:SI (match_dup 1) (const_int 16)))) --+ (set (match_operand:SI 7 "register_operand" "") --+ (mem:SI (plus:SI (match_dup 1) (const_int 20)))) --+ (set (match_operand:SI 8 "register_operand" "") --+ (mem:SI (plus:SI (match_dup 1) (const_int 24))))])] --+ "(XVECLEN (operands[0], 0) == 7)" --+ "lmw.bi\t%2, [%1], %8, 0x0" --+ [(set_attr "type" "load_multiple") --+ (set_attr "combo" "7") --+ (set_attr "length" "4")] --+) --+ --+(define_insn "*lmwsi6" --+ [(match_parallel 0 "nds32_load_multiple_operation" --+ [(set (match_operand:SI 2 "register_operand" "") --+ (mem:SI (match_operand:SI 1 "register_operand" "r"))) --+ (set (match_operand:SI 3 "register_operand" "") --+ (mem:SI (plus:SI (match_dup 1) (const_int 4)))) --+ (set (match_operand:SI 4 "register_operand" "") --+ (mem:SI (plus:SI (match_dup 1) (const_int 8)))) --+ (set (match_operand:SI 5 "register_operand" "") --+ (mem:SI (plus:SI (match_dup 1) (const_int 12)))) --+ (set (match_operand:SI 6 "register_operand" "") --+ (mem:SI (plus:SI (match_dup 1) (const_int 16)))) --+ (set (match_operand:SI 7 "register_operand" "") --+ (mem:SI (plus:SI (match_dup 1) (const_int 20))))])] --+ "(XVECLEN (operands[0], 0) == 6)" --+ "lmw.bi\t%2, [%1], %7, 0x0" --+ [(set_attr "type" "load_multiple") --+ (set_attr "combo" "6") --+ (set_attr "length" "4")] --+) --+ --+(define_insn "*lmwsi5" --+ [(match_parallel 0 "nds32_load_multiple_operation" --+ [(set (match_operand:SI 2 "register_operand" "") --+ (mem:SI (match_operand:SI 1 "register_operand" "r"))) --+ (set (match_operand:SI 3 "register_operand" "") --+ (mem:SI (plus:SI (match_dup 1) (const_int 4)))) --+ (set (match_operand:SI 4 "register_operand" "") --+ (mem:SI (plus:SI (match_dup 1) (const_int 8)))) --+ (set (match_operand:SI 5 "register_operand" "") --+ (mem:SI (plus:SI (match_dup 1) (const_int 12)))) --+ (set (match_operand:SI 6 "register_operand" "") --+ (mem:SI (plus:SI (match_dup 1) (const_int 16))))])] --+ "(XVECLEN (operands[0], 0) == 5)" --+ "lmw.bi\t%2, [%1], %6, 0x0" --+ [(set_attr "type" "load_multiple") --+ (set_attr "combo" "5") --+ (set_attr "length" "4")] --+) --+ --+(define_insn "*lmwsi4" --+ [(match_parallel 0 "nds32_load_multiple_operation" --+ [(set (match_operand:SI 2 "register_operand" "") --+ (mem:SI (match_operand:SI 1 "register_operand" "r"))) --+ (set (match_operand:SI 3 "register_operand" "") --+ (mem:SI (plus:SI (match_dup 1) (const_int 4)))) --+ (set (match_operand:SI 4 "register_operand" "") --+ (mem:SI (plus:SI (match_dup 1) (const_int 8)))) --+ (set (match_operand:SI 5 "register_operand" "") --+ (mem:SI (plus:SI (match_dup 1) (const_int 12))))])] --+ "(XVECLEN (operands[0], 0) == 4)" --+ "lmw.bi\t%2, [%1], %5, 0x0" --+ [(set_attr "type" "load_multiple") --+ (set_attr "combo" "4") --+ (set_attr "length" "4")] --+) --+ --+(define_insn "*lmwsi3" --+ [(match_parallel 0 "nds32_load_multiple_operation" --+ [(set (match_operand:SI 2 "register_operand" "") --+ (mem:SI (match_operand:SI 1 "register_operand" "r"))) --+ (set (match_operand:SI 3 "register_operand" "") --+ (mem:SI (plus:SI (match_dup 1) (const_int 4)))) --+ (set (match_operand:SI 4 "register_operand" "") --+ (mem:SI (plus:SI (match_dup 1) (const_int 8))))])] --+ "(XVECLEN (operands[0], 0) == 3)" --+ "lmw.bi\t%2, [%1], %4, 0x0" --+ [(set_attr "type" "load_multiple") --+ (set_attr "combo" "3") --+ (set_attr "length" "4")] --+) --+ --+(define_insn "*lmwsi2" --+ [(match_parallel 0 "nds32_load_multiple_operation" --+ [(set (match_operand:SI 2 "register_operand" "") --+ (mem:SI (match_operand:SI 1 "register_operand" "r"))) --+ (set (match_operand:SI 3 "register_operand" "") --+ (mem:SI (plus:SI (match_dup 1) (const_int 4))))])] --+ "(XVECLEN (operands[0], 0) == 2)" --+ "lmw.bi\t%2, [%1], %3, 0x0" --+ [(set_attr "type" "load_multiple") --+ (set_attr "combo" "2") --+ (set_attr "length" "4")] --+) --+ --+;; Store Multiple Insns. --+;; --+;; operands[0] is the first memory location. --+;; operands[1] is the first of the consecutive registers. --+;; operands[2] is the number of consecutive registers. --+ --+(define_expand "store_multiple" --+ [(match_par_dup 3 [(set (match_operand:SI 0 "" "") --+ (match_operand:SI 1 "" "")) --+ (use (match_operand:SI 2 "" ""))])] --+ "" --+{ --+ int maximum; --+ --+ /* Because reduced-set regsiters has few registers --+ (r0~r5, r6~10, r15, r28~r31, where 'r15' and 'r28~r31' cannot --+ be used for register allocation), --+ using 8 registers for store_multiple may easily consume all of them. --+ It makes register allocation/spilling hard to work. --+ So we only allow maximum=4 registers for store_multiple --+ under reduced-set registers. */ --+ if (TARGET_REDUCED_REGS) --+ maximum = 4; --+ else --+ maximum = 8; --+ --+ /* Here are the conditions that must be all passed, --+ otherwise we have to FAIL this rtx generation: --+ 1. The number of consecutive registers must be integer. --+ 2. Maximum 4 or 8 registers for smw.bi instruction --+ (based on this nds32-multiple.md design). --+ 3. Minimum 2 registers for smw.bi instruction --+ (based on this nds32-multiple.md design). --+ 4. operands[0] must be memory for sure. --+ 5. operands[1] must be register for sure. --+ 6. operands[0] is not volatile memory access. --+ 7. Do not cross $r15 register because it is not allocatable. */ --+ if (GET_CODE (operands[2]) != CONST_INT --+ || INTVAL (operands[2]) > maximum --+ || INTVAL (operands[2]) < 2 --+ || GET_CODE (operands[0]) != MEM --+ || GET_CODE (operands[1]) != REG --+ || MEM_VOLATILE_P (operands[0]) --+ || REGNO (operands[1]) + INTVAL (operands[2]) > TA_REGNUM) --+ FAIL; --+ --+ /* For (mem addr), we force_reg on addr here, --+ so that nds32_expand_store_multiple can easily use it. */ --+ operands[3] = nds32_expand_store_multiple (REGNO (operands[1]), --+ INTVAL (operands[2]), --+ force_reg (SImode, --+ XEXP (operands[0], 0)), --+ operands[0], --+ false, NULL); --+}) --+ --+;; Ordinary Store Multiple. --+(define_insn "*stm_bim_si25" --+ [(match_parallel 0 "nds32_store_multiple_and_update_address_operation" --+ [(set (match_operand:SI 1 "register_operand" "=r") --+ (plus:SI (match_operand:SI 2 "register_operand" "1") (const_int 100))) --+ (set (mem:SI (match_dup 2)) --+ (match_operand:SI 3 "register_operand" "")) --+ (set (mem:SI (plus:SI (match_dup 2) (const_int 4))) --+ (match_operand:SI 4 "register_operand" "")) --+ (set (mem:SI (plus:SI (match_dup 2) (const_int 8))) --+ (match_operand:SI 5 "register_operand" "")) --+ (set (mem:SI (plus:SI (match_dup 2) (const_int 12))) --+ (match_operand:SI 6 "register_operand" "")) --+ (set (mem:SI (plus:SI (match_dup 2) (const_int 16))) --+ (match_operand:SI 7 "register_operand" "")) --+ (set (mem:SI (plus:SI (match_dup 2) (const_int 20))) --+ (match_operand:SI 8 "register_operand" "")) --+ (set (mem:SI (plus:SI (match_dup 2) (const_int 24))) --+ (match_operand:SI 9 "register_operand" "")) --+ (set (mem:SI (plus:SI (match_dup 2) (const_int 28))) --+ (match_operand:SI 10 "register_operand" "")) --+ (set (mem:SI (plus:SI (match_dup 2) (const_int 32))) --+ (match_operand:SI 11 "register_operand" "")) --+ (set (mem:SI (plus:SI (match_dup 2) (const_int 36))) --+ (match_operand:SI 12 "register_operand" "")) --+ (set (mem:SI (plus:SI (match_dup 2) (const_int 40))) --+ (match_operand:SI 13 "register_operand" "")) --+ (set (mem:SI (plus:SI (match_dup 2) (const_int 44))) --+ (match_operand:SI 14 "register_operand" "")) --+ (set (mem:SI (plus:SI (match_dup 2) (const_int 48))) --+ (match_operand:SI 15 "register_operand" "")) --+ (set (mem:SI (plus:SI (match_dup 2) (const_int 52))) --+ (match_operand:SI 16 "register_operand" "")) --+ (set (mem:SI (plus:SI (match_dup 2) (const_int 56))) --+ (match_operand:SI 17 "register_operand" "")) --+ (set (mem:SI (plus:SI (match_dup 2) (const_int 60))) --+ (match_operand:SI 18 "register_operand" "")) --+ (set (mem:SI (plus:SI (match_dup 2) (const_int 64))) --+ (match_operand:SI 19 "register_operand" "")) --+ (set (mem:SI (plus:SI (match_dup 2) (const_int 68))) --+ (match_operand:SI 20 "register_operand" "")) --+ (set (mem:SI (plus:SI (match_dup 2) (const_int 72))) --+ (match_operand:SI 21 "register_operand" "")) --+ (set (mem:SI (plus:SI (match_dup 2) (const_int 76))) --+ (match_operand:SI 22 "register_operand" "")) --+ (set (mem:SI (plus:SI (match_dup 2) (const_int 80))) --+ (match_operand:SI 23 "register_operand" "")) --+ (set (mem:SI (plus:SI (match_dup 2) (const_int 84))) --+ (match_operand:SI 24 "register_operand" "")) --+ (set (mem:SI (plus:SI (match_dup 2) (const_int 88))) --+ (match_operand:SI 25 "register_operand" "")) --+ (set (mem:SI (plus:SI (match_dup 2) (const_int 92))) --+ (match_operand:SI 26 "register_operand" "")) --+ (set (mem:SI (plus:SI (match_dup 2) (const_int 96))) --+ (match_operand:SI 27 "register_operand" ""))])] --+ "(XVECLEN (operands[0], 0) == 26)" --+ "smw.bim\t%3, [%1], %27, 0x0" --+ [(set_attr "type" "store_multiple") --+ (set_attr "combo" "25") --+ (set_attr "length" "4")] --+) --+ --+(define_insn "*stm_bim_si24" --+ [(match_parallel 0 "nds32_store_multiple_and_update_address_operation" --+ [(set (match_operand:SI 1 "register_operand" "=r") --+ (plus:SI (match_operand:SI 2 "register_operand" "1") (const_int 96))) --+ (set (mem:SI (match_dup 2)) --+ (match_operand:SI 3 "register_operand" "")) --+ (set (mem:SI (plus:SI (match_dup 2) (const_int 4))) --+ (match_operand:SI 4 "register_operand" "")) --+ (set (mem:SI (plus:SI (match_dup 2) (const_int 8))) --+ (match_operand:SI 5 "register_operand" "")) --+ (set (mem:SI (plus:SI (match_dup 2) (const_int 12))) --+ (match_operand:SI 6 "register_operand" "")) --+ (set (mem:SI (plus:SI (match_dup 2) (const_int 16))) --+ (match_operand:SI 7 "register_operand" "")) --+ (set (mem:SI (plus:SI (match_dup 2) (const_int 20))) --+ (match_operand:SI 8 "register_operand" "")) --+ (set (mem:SI (plus:SI (match_dup 2) (const_int 24))) --+ (match_operand:SI 9 "register_operand" "")) --+ (set (mem:SI (plus:SI (match_dup 2) (const_int 28))) --+ (match_operand:SI 10 "register_operand" "")) --+ (set (mem:SI (plus:SI (match_dup 2) (const_int 32))) --+ (match_operand:SI 11 "register_operand" "")) --+ (set (mem:SI (plus:SI (match_dup 2) (const_int 36))) --+ (match_operand:SI 12 "register_operand" "")) --+ (set (mem:SI (plus:SI (match_dup 2) (const_int 40))) --+ (match_operand:SI 13 "register_operand" "")) --+ (set (mem:SI (plus:SI (match_dup 2) (const_int 44))) --+ (match_operand:SI 14 "register_operand" "")) --+ (set (mem:SI (plus:SI (match_dup 2) (const_int 48))) --+ (match_operand:SI 15 "register_operand" "")) --+ (set (mem:SI (plus:SI (match_dup 2) (const_int 52))) --+ (match_operand:SI 16 "register_operand" "")) --+ (set (mem:SI (plus:SI (match_dup 2) (const_int 56))) --+ (match_operand:SI 17 "register_operand" "")) --+ (set (mem:SI (plus:SI (match_dup 2) (const_int 60))) --+ (match_operand:SI 18 "register_operand" "")) --+ (set (mem:SI (plus:SI (match_dup 2) (const_int 64))) --+ (match_operand:SI 19 "register_operand" "")) --+ (set (mem:SI (plus:SI (match_dup 2) (const_int 68))) --+ (match_operand:SI 20 "register_operand" "")) --+ (set (mem:SI (plus:SI (match_dup 2) (const_int 72))) --+ (match_operand:SI 21 "register_operand" "")) --+ (set (mem:SI (plus:SI (match_dup 2) (const_int 76))) --+ (match_operand:SI 22 "register_operand" "")) --+ (set (mem:SI (plus:SI (match_dup 2) (const_int 80))) --+ (match_operand:SI 23 "register_operand" "")) --+ (set (mem:SI (plus:SI (match_dup 2) (const_int 84))) --+ (match_operand:SI 24 "register_operand" "")) --+ (set (mem:SI (plus:SI (match_dup 2) (const_int 88))) --+ (match_operand:SI 25 "register_operand" "")) --+ (set (mem:SI (plus:SI (match_dup 2) (const_int 92))) --+ (match_operand:SI 26 "register_operand" ""))])] --+ "(XVECLEN (operands[0], 0) == 25)" --+ "smw.bim\t%3, [%1], %26, 0x0" --+ [(set_attr "type" "store_multiple") --+ (set_attr "combo" "24") --+ (set_attr "length" "4")] --+) --+ --+(define_insn "*stm_bim_si23" --+ [(match_parallel 0 "nds32_store_multiple_and_update_address_operation" --+ [(set (match_operand:SI 1 "register_operand" "=r") --+ (plus:SI (match_operand:SI 2 "register_operand" "1") (const_int 92))) --+ (set (mem:SI (match_dup 2)) --+ (match_operand:SI 3 "register_operand" "")) --+ (set (mem:SI (plus:SI (match_dup 2) (const_int 4))) --+ (match_operand:SI 4 "register_operand" "")) --+ (set (mem:SI (plus:SI (match_dup 2) (const_int 8))) --+ (match_operand:SI 5 "register_operand" "")) --+ (set (mem:SI (plus:SI (match_dup 2) (const_int 12))) --+ (match_operand:SI 6 "register_operand" "")) --+ (set (mem:SI (plus:SI (match_dup 2) (const_int 16))) --+ (match_operand:SI 7 "register_operand" "")) --+ (set (mem:SI (plus:SI (match_dup 2) (const_int 20))) --+ (match_operand:SI 8 "register_operand" "")) --+ (set (mem:SI (plus:SI (match_dup 2) (const_int 24))) --+ (match_operand:SI 9 "register_operand" "")) --+ (set (mem:SI (plus:SI (match_dup 2) (const_int 28))) --+ (match_operand:SI 10 "register_operand" "")) --+ (set (mem:SI (plus:SI (match_dup 2) (const_int 32))) --+ (match_operand:SI 11 "register_operand" "")) --+ (set (mem:SI (plus:SI (match_dup 2) (const_int 36))) --+ (match_operand:SI 12 "register_operand" "")) --+ (set (mem:SI (plus:SI (match_dup 2) (const_int 40))) --+ (match_operand:SI 13 "register_operand" "")) --+ (set (mem:SI (plus:SI (match_dup 2) (const_int 44))) --+ (match_operand:SI 14 "register_operand" "")) --+ (set (mem:SI (plus:SI (match_dup 2) (const_int 48))) --+ (match_operand:SI 15 "register_operand" "")) --+ (set (mem:SI (plus:SI (match_dup 2) (const_int 52))) --+ (match_operand:SI 16 "register_operand" "")) --+ (set (mem:SI (plus:SI (match_dup 2) (const_int 56))) --+ (match_operand:SI 17 "register_operand" "")) --+ (set (mem:SI (plus:SI (match_dup 2) (const_int 60))) --+ (match_operand:SI 18 "register_operand" "")) --+ (set (mem:SI (plus:SI (match_dup 2) (const_int 64))) --+ (match_operand:SI 19 "register_operand" "")) --+ (set (mem:SI (plus:SI (match_dup 2) (const_int 68))) --+ (match_operand:SI 20 "register_operand" "")) --+ (set (mem:SI (plus:SI (match_dup 2) (const_int 72))) --+ (match_operand:SI 21 "register_operand" "")) --+ (set (mem:SI (plus:SI (match_dup 2) (const_int 76))) --+ (match_operand:SI 22 "register_operand" "")) --+ (set (mem:SI (plus:SI (match_dup 2) (const_int 80))) --+ (match_operand:SI 23 "register_operand" "")) --+ (set (mem:SI (plus:SI (match_dup 2) (const_int 84))) --+ (match_operand:SI 24 "register_operand" "")) --+ (set (mem:SI (plus:SI (match_dup 2) (const_int 88))) --+ (match_operand:SI 25 "register_operand" ""))])] --+ "(XVECLEN (operands[0], 0) == 24)" --+ "smw.bim\t%3, [%1], %25, 0x0" --+ [(set_attr "type" "store_multiple") --+ (set_attr "combo" "23") --+ (set_attr "length" "4")] --+) --+ --+(define_insn "*stm_bim_si22" --+ [(match_parallel 0 "nds32_store_multiple_and_update_address_operation" --+ [(set (match_operand:SI 1 "register_operand" "=r") --+ (plus:SI (match_operand:SI 2 "register_operand" "1") (const_int 88))) --+ (set (mem:SI (match_dup 2)) --+ (match_operand:SI 3 "register_operand" "")) --+ (set (mem:SI (plus:SI (match_dup 2) (const_int 4))) --+ (match_operand:SI 4 "register_operand" "")) --+ (set (mem:SI (plus:SI (match_dup 2) (const_int 8))) --+ (match_operand:SI 5 "register_operand" "")) --+ (set (mem:SI (plus:SI (match_dup 2) (const_int 12))) --+ (match_operand:SI 6 "register_operand" "")) --+ (set (mem:SI (plus:SI (match_dup 2) (const_int 16))) --+ (match_operand:SI 7 "register_operand" "")) --+ (set (mem:SI (plus:SI (match_dup 2) (const_int 20))) --+ (match_operand:SI 8 "register_operand" "")) --+ (set (mem:SI (plus:SI (match_dup 2) (const_int 24))) --+ (match_operand:SI 9 "register_operand" "")) --+ (set (mem:SI (plus:SI (match_dup 2) (const_int 28))) --+ (match_operand:SI 10 "register_operand" "")) --+ (set (mem:SI (plus:SI (match_dup 2) (const_int 32))) --+ (match_operand:SI 11 "register_operand" "")) --+ (set (mem:SI (plus:SI (match_dup 2) (const_int 36))) --+ (match_operand:SI 12 "register_operand" "")) --+ (set (mem:SI (plus:SI (match_dup 2) (const_int 40))) --+ (match_operand:SI 13 "register_operand" "")) --+ (set (mem:SI (plus:SI (match_dup 2) (const_int 44))) --+ (match_operand:SI 14 "register_operand" "")) --+ (set (mem:SI (plus:SI (match_dup 2) (const_int 48))) --+ (match_operand:SI 15 "register_operand" "")) --+ (set (mem:SI (plus:SI (match_dup 2) (const_int 52))) --+ (match_operand:SI 16 "register_operand" "")) --+ (set (mem:SI (plus:SI (match_dup 2) (const_int 56))) --+ (match_operand:SI 17 "register_operand" "")) --+ (set (mem:SI (plus:SI (match_dup 2) (const_int 60))) --+ (match_operand:SI 18 "register_operand" "")) --+ (set (mem:SI (plus:SI (match_dup 2) (const_int 64))) --+ (match_operand:SI 19 "register_operand" "")) --+ (set (mem:SI (plus:SI (match_dup 2) (const_int 68))) --+ (match_operand:SI 20 "register_operand" "")) --+ (set (mem:SI (plus:SI (match_dup 2) (const_int 72))) --+ (match_operand:SI 21 "register_operand" "")) --+ (set (mem:SI (plus:SI (match_dup 2) (const_int 76))) --+ (match_operand:SI 22 "register_operand" "")) --+ (set (mem:SI (plus:SI (match_dup 2) (const_int 80))) --+ (match_operand:SI 23 "register_operand" "")) --+ (set (mem:SI (plus:SI (match_dup 2) (const_int 84))) --+ (match_operand:SI 24 "register_operand" ""))])] --+ "(XVECLEN (operands[0], 0) == 23)" --+ "smw.bim\t%3, [%1], %24, 0x0" --+ [(set_attr "type" "store_multiple") --+ (set_attr "combo" "22") --+ (set_attr "length" "4")] --+) --+ --+(define_insn "*stm_bim_si21" --+ [(match_parallel 0 "nds32_store_multiple_and_update_address_operation" --+ [(set (match_operand:SI 1 "register_operand" "=r") --+ (plus:SI (match_operand:SI 2 "register_operand" "1") (const_int 84))) --+ (set (mem:SI (match_dup 2)) --+ (match_operand:SI 3 "register_operand" "")) --+ (set (mem:SI (plus:SI (match_dup 2) (const_int 4))) --+ (match_operand:SI 4 "register_operand" "")) --+ (set (mem:SI (plus:SI (match_dup 2) (const_int 8))) --+ (match_operand:SI 5 "register_operand" "")) --+ (set (mem:SI (plus:SI (match_dup 2) (const_int 12))) --+ (match_operand:SI 6 "register_operand" "")) --+ (set (mem:SI (plus:SI (match_dup 2) (const_int 16))) --+ (match_operand:SI 7 "register_operand" "")) --+ (set (mem:SI (plus:SI (match_dup 2) (const_int 20))) --+ (match_operand:SI 8 "register_operand" "")) --+ (set (mem:SI (plus:SI (match_dup 2) (const_int 24))) --+ (match_operand:SI 9 "register_operand" "")) --+ (set (mem:SI (plus:SI (match_dup 2) (const_int 28))) --+ (match_operand:SI 10 "register_operand" "")) --+ (set (mem:SI (plus:SI (match_dup 2) (const_int 32))) --+ (match_operand:SI 11 "register_operand" "")) --+ (set (mem:SI (plus:SI (match_dup 2) (const_int 36))) --+ (match_operand:SI 12 "register_operand" "")) --+ (set (mem:SI (plus:SI (match_dup 2) (const_int 40))) --+ (match_operand:SI 13 "register_operand" "")) --+ (set (mem:SI (plus:SI (match_dup 2) (const_int 44))) --+ (match_operand:SI 14 "register_operand" "")) --+ (set (mem:SI (plus:SI (match_dup 2) (const_int 48))) --+ (match_operand:SI 15 "register_operand" "")) --+ (set (mem:SI (plus:SI (match_dup 2) (const_int 52))) --+ (match_operand:SI 16 "register_operand" "")) --+ (set (mem:SI (plus:SI (match_dup 2) (const_int 56))) --+ (match_operand:SI 17 "register_operand" "")) --+ (set (mem:SI (plus:SI (match_dup 2) (const_int 60))) --+ (match_operand:SI 18 "register_operand" "")) --+ (set (mem:SI (plus:SI (match_dup 2) (const_int 64))) --+ (match_operand:SI 19 "register_operand" "")) --+ (set (mem:SI (plus:SI (match_dup 2) (const_int 68))) --+ (match_operand:SI 20 "register_operand" "")) --+ (set (mem:SI (plus:SI (match_dup 2) (const_int 72))) --+ (match_operand:SI 21 "register_operand" "")) --+ (set (mem:SI (plus:SI (match_dup 2) (const_int 76))) --+ (match_operand:SI 22 "register_operand" "")) --+ (set (mem:SI (plus:SI (match_dup 2) (const_int 80))) --+ (match_operand:SI 23 "register_operand" ""))])] --+ "(XVECLEN (operands[0], 0) == 22)" --+ "smw.bim\t%3, [%1], %23, 0x0" --+ [(set_attr "type" "store_multiple") --+ (set_attr "combo" "21") --+ (set_attr "length" "4")] --+) --+ --+(define_insn "*stm_bim_si20" --+ [(match_parallel 0 "nds32_store_multiple_and_update_address_operation" --+ [(set (match_operand:SI 1 "register_operand" "=r") --+ (plus:SI (match_operand:SI 2 "register_operand" "1") (const_int 80))) --+ (set (mem:SI (match_dup 2)) --+ (match_operand:SI 3 "register_operand" "")) --+ (set (mem:SI (plus:SI (match_dup 2) (const_int 4))) --+ (match_operand:SI 4 "register_operand" "")) --+ (set (mem:SI (plus:SI (match_dup 2) (const_int 8))) --+ (match_operand:SI 5 "register_operand" "")) --+ (set (mem:SI (plus:SI (match_dup 2) (const_int 12))) --+ (match_operand:SI 6 "register_operand" "")) --+ (set (mem:SI (plus:SI (match_dup 2) (const_int 16))) --+ (match_operand:SI 7 "register_operand" "")) --+ (set (mem:SI (plus:SI (match_dup 2) (const_int 20))) --+ (match_operand:SI 8 "register_operand" "")) --+ (set (mem:SI (plus:SI (match_dup 2) (const_int 24))) --+ (match_operand:SI 9 "register_operand" "")) --+ (set (mem:SI (plus:SI (match_dup 2) (const_int 28))) --+ (match_operand:SI 10 "register_operand" "")) --+ (set (mem:SI (plus:SI (match_dup 2) (const_int 32))) --+ (match_operand:SI 11 "register_operand" "")) --+ (set (mem:SI (plus:SI (match_dup 2) (const_int 36))) --+ (match_operand:SI 12 "register_operand" "")) --+ (set (mem:SI (plus:SI (match_dup 2) (const_int 40))) --+ (match_operand:SI 13 "register_operand" "")) --+ (set (mem:SI (plus:SI (match_dup 2) (const_int 44))) --+ (match_operand:SI 14 "register_operand" "")) --+ (set (mem:SI (plus:SI (match_dup 2) (const_int 48))) --+ (match_operand:SI 15 "register_operand" "")) --+ (set (mem:SI (plus:SI (match_dup 2) (const_int 52))) --+ (match_operand:SI 16 "register_operand" "")) --+ (set (mem:SI (plus:SI (match_dup 2) (const_int 56))) --+ (match_operand:SI 17 "register_operand" "")) --+ (set (mem:SI (plus:SI (match_dup 2) (const_int 60))) --+ (match_operand:SI 18 "register_operand" "")) --+ (set (mem:SI (plus:SI (match_dup 2) (const_int 64))) --+ (match_operand:SI 19 "register_operand" "")) --+ (set (mem:SI (plus:SI (match_dup 2) (const_int 68))) --+ (match_operand:SI 20 "register_operand" "")) --+ (set (mem:SI (plus:SI (match_dup 2) (const_int 72))) --+ (match_operand:SI 21 "register_operand" "")) --+ (set (mem:SI (plus:SI (match_dup 2) (const_int 76))) --+ (match_operand:SI 22 "register_operand" ""))])] --+ "(XVECLEN (operands[0], 0) == 21)" --+ "smw.bim\t%3, [%1], %22, 0x0" --+ [(set_attr "type" "store_multiple") --+ (set_attr "combo" "20") --+ (set_attr "length" "4")] --+) --+ --+(define_insn "*stm_bim_si19" --+ [(match_parallel 0 "nds32_store_multiple_and_update_address_operation" --+ [(set (match_operand:SI 1 "register_operand" "=r") --+ (plus:SI (match_operand:SI 2 "register_operand" "1") (const_int 76))) --+ (set (mem:SI (match_dup 2)) --+ (match_operand:SI 3 "register_operand" "")) --+ (set (mem:SI (plus:SI (match_dup 2) (const_int 4))) --+ (match_operand:SI 4 "register_operand" "")) --+ (set (mem:SI (plus:SI (match_dup 2) (const_int 8))) --+ (match_operand:SI 5 "register_operand" "")) --+ (set (mem:SI (plus:SI (match_dup 2) (const_int 12))) --+ (match_operand:SI 6 "register_operand" "")) --+ (set (mem:SI (plus:SI (match_dup 2) (const_int 16))) --+ (match_operand:SI 7 "register_operand" "")) --+ (set (mem:SI (plus:SI (match_dup 2) (const_int 20))) --+ (match_operand:SI 8 "register_operand" "")) --+ (set (mem:SI (plus:SI (match_dup 2) (const_int 24))) --+ (match_operand:SI 9 "register_operand" "")) --+ (set (mem:SI (plus:SI (match_dup 2) (const_int 28))) --+ (match_operand:SI 10 "register_operand" "")) --+ (set (mem:SI (plus:SI (match_dup 2) (const_int 32))) --+ (match_operand:SI 11 "register_operand" "")) --+ (set (mem:SI (plus:SI (match_dup 2) (const_int 36))) --+ (match_operand:SI 12 "register_operand" "")) --+ (set (mem:SI (plus:SI (match_dup 2) (const_int 40))) --+ (match_operand:SI 13 "register_operand" "")) --+ (set (mem:SI (plus:SI (match_dup 2) (const_int 44))) --+ (match_operand:SI 14 "register_operand" "")) --+ (set (mem:SI (plus:SI (match_dup 2) (const_int 48))) --+ (match_operand:SI 15 "register_operand" "")) --+ (set (mem:SI (plus:SI (match_dup 2) (const_int 52))) --+ (match_operand:SI 16 "register_operand" "")) --+ (set (mem:SI (plus:SI (match_dup 2) (const_int 56))) --+ (match_operand:SI 17 "register_operand" "")) --+ (set (mem:SI (plus:SI (match_dup 2) (const_int 60))) --+ (match_operand:SI 18 "register_operand" "")) --+ (set (mem:SI (plus:SI (match_dup 2) (const_int 64))) --+ (match_operand:SI 19 "register_operand" "")) --+ (set (mem:SI (plus:SI (match_dup 2) (const_int 68))) --+ (match_operand:SI 20 "register_operand" "")) --+ (set (mem:SI (plus:SI (match_dup 2) (const_int 72))) --+ (match_operand:SI 21 "register_operand" ""))])] --+ "(XVECLEN (operands[0], 0) == 20)" --+ "smw.bim\t%3, [%1], %21, 0x0" --+ [(set_attr "type" "store_multiple") --+ (set_attr "combo" "19") --+ (set_attr "length" "4")] --+) --+ --+(define_insn "*stm_bim_si18" --+ [(match_parallel 0 "nds32_store_multiple_and_update_address_operation" --+ [(set (match_operand:SI 1 "register_operand" "=r") --+ (plus:SI (match_operand:SI 2 "register_operand" "1") (const_int 72))) --+ (set (mem:SI (match_dup 2)) --+ (match_operand:SI 3 "register_operand" "")) --+ (set (mem:SI (plus:SI (match_dup 2) (const_int 4))) --+ (match_operand:SI 4 "register_operand" "")) --+ (set (mem:SI (plus:SI (match_dup 2) (const_int 8))) --+ (match_operand:SI 5 "register_operand" "")) --+ (set (mem:SI (plus:SI (match_dup 2) (const_int 12))) --+ (match_operand:SI 6 "register_operand" "")) --+ (set (mem:SI (plus:SI (match_dup 2) (const_int 16))) --+ (match_operand:SI 7 "register_operand" "")) --+ (set (mem:SI (plus:SI (match_dup 2) (const_int 20))) --+ (match_operand:SI 8 "register_operand" "")) --+ (set (mem:SI (plus:SI (match_dup 2) (const_int 24))) --+ (match_operand:SI 9 "register_operand" "")) --+ (set (mem:SI (plus:SI (match_dup 2) (const_int 28))) --+ (match_operand:SI 10 "register_operand" "")) --+ (set (mem:SI (plus:SI (match_dup 2) (const_int 32))) --+ (match_operand:SI 11 "register_operand" "")) --+ (set (mem:SI (plus:SI (match_dup 2) (const_int 36))) --+ (match_operand:SI 12 "register_operand" "")) --+ (set (mem:SI (plus:SI (match_dup 2) (const_int 40))) --+ (match_operand:SI 13 "register_operand" "")) --+ (set (mem:SI (plus:SI (match_dup 2) (const_int 44))) --+ (match_operand:SI 14 "register_operand" "")) --+ (set (mem:SI (plus:SI (match_dup 2) (const_int 48))) --+ (match_operand:SI 15 "register_operand" "")) --+ (set (mem:SI (plus:SI (match_dup 2) (const_int 52))) --+ (match_operand:SI 16 "register_operand" "")) --+ (set (mem:SI (plus:SI (match_dup 2) (const_int 56))) --+ (match_operand:SI 17 "register_operand" "")) --+ (set (mem:SI (plus:SI (match_dup 2) (const_int 60))) --+ (match_operand:SI 18 "register_operand" "")) --+ (set (mem:SI (plus:SI (match_dup 2) (const_int 64))) --+ (match_operand:SI 19 "register_operand" "")) --+ (set (mem:SI (plus:SI (match_dup 2) (const_int 68))) --+ (match_operand:SI 20 "register_operand" ""))])] --+ "(XVECLEN (operands[0], 0) == 19)" --+ "smw.bim\t%3, [%1], %20, 0x0" --+ [(set_attr "type" "store_multiple") --+ (set_attr "combo" "18") --+ (set_attr "length" "4")] --+) --+ --+(define_insn "*stm_bim_si17" --+ [(match_parallel 0 "nds32_store_multiple_and_update_address_operation" --+ [(set (match_operand:SI 1 "register_operand" "=r") --+ (plus:SI (match_operand:SI 2 "register_operand" "1") (const_int 68))) --+ (set (mem:SI (match_dup 2)) --+ (match_operand:SI 3 "register_operand" "")) --+ (set (mem:SI (plus:SI (match_dup 2) (const_int 4))) --+ (match_operand:SI 4 "register_operand" "")) --+ (set (mem:SI (plus:SI (match_dup 2) (const_int 8))) --+ (match_operand:SI 5 "register_operand" "")) --+ (set (mem:SI (plus:SI (match_dup 2) (const_int 12))) --+ (match_operand:SI 6 "register_operand" "")) --+ (set (mem:SI (plus:SI (match_dup 2) (const_int 16))) --+ (match_operand:SI 7 "register_operand" "")) --+ (set (mem:SI (plus:SI (match_dup 2) (const_int 20))) --+ (match_operand:SI 8 "register_operand" "")) --+ (set (mem:SI (plus:SI (match_dup 2) (const_int 24))) --+ (match_operand:SI 9 "register_operand" "")) --+ (set (mem:SI (plus:SI (match_dup 2) (const_int 28))) --+ (match_operand:SI 10 "register_operand" "")) --+ (set (mem:SI (plus:SI (match_dup 2) (const_int 32))) --+ (match_operand:SI 11 "register_operand" "")) --+ (set (mem:SI (plus:SI (match_dup 2) (const_int 36))) --+ (match_operand:SI 12 "register_operand" "")) --+ (set (mem:SI (plus:SI (match_dup 2) (const_int 40))) --+ (match_operand:SI 13 "register_operand" "")) --+ (set (mem:SI (plus:SI (match_dup 2) (const_int 44))) --+ (match_operand:SI 14 "register_operand" "")) --+ (set (mem:SI (plus:SI (match_dup 2) (const_int 48))) --+ (match_operand:SI 15 "register_operand" "")) --+ (set (mem:SI (plus:SI (match_dup 2) (const_int 52))) --+ (match_operand:SI 16 "register_operand" "")) --+ (set (mem:SI (plus:SI (match_dup 2) (const_int 56))) --+ (match_operand:SI 17 "register_operand" "")) --+ (set (mem:SI (plus:SI (match_dup 2) (const_int 60))) --+ (match_operand:SI 18 "register_operand" "")) --+ (set (mem:SI (plus:SI (match_dup 2) (const_int 64))) --+ (match_operand:SI 19 "register_operand" ""))])] --+ "(XVECLEN (operands[0], 0) == 18)" --+ "smw.bim\t%3, [%1], %19, 0x0" --+ [(set_attr "type" "store_multiple") --+ (set_attr "combo" "17") --+ (set_attr "length" "4")] --+) --+ --+(define_insn "*stm_bim_si16" --+ [(match_parallel 0 "nds32_store_multiple_and_update_address_operation" --+ [(set (match_operand:SI 1 "register_operand" "=r") --+ (plus:SI (match_operand:SI 2 "register_operand" "1") (const_int 64))) --+ (set (mem:SI (match_dup 2)) --+ (match_operand:SI 3 "register_operand" "")) --+ (set (mem:SI (plus:SI (match_dup 2) (const_int 4))) --+ (match_operand:SI 4 "register_operand" "")) --+ (set (mem:SI (plus:SI (match_dup 2) (const_int 8))) --+ (match_operand:SI 5 "register_operand" "")) --+ (set (mem:SI (plus:SI (match_dup 2) (const_int 12))) --+ (match_operand:SI 6 "register_operand" "")) --+ (set (mem:SI (plus:SI (match_dup 2) (const_int 16))) --+ (match_operand:SI 7 "register_operand" "")) --+ (set (mem:SI (plus:SI (match_dup 2) (const_int 20))) --+ (match_operand:SI 8 "register_operand" "")) --+ (set (mem:SI (plus:SI (match_dup 2) (const_int 24))) --+ (match_operand:SI 9 "register_operand" "")) --+ (set (mem:SI (plus:SI (match_dup 2) (const_int 28))) --+ (match_operand:SI 10 "register_operand" "")) --+ (set (mem:SI (plus:SI (match_dup 2) (const_int 32))) --+ (match_operand:SI 11 "register_operand" "")) --+ (set (mem:SI (plus:SI (match_dup 2) (const_int 36))) --+ (match_operand:SI 12 "register_operand" "")) --+ (set (mem:SI (plus:SI (match_dup 2) (const_int 40))) --+ (match_operand:SI 13 "register_operand" "")) --+ (set (mem:SI (plus:SI (match_dup 2) (const_int 44))) --+ (match_operand:SI 14 "register_operand" "")) --+ (set (mem:SI (plus:SI (match_dup 2) (const_int 48))) --+ (match_operand:SI 15 "register_operand" "")) --+ (set (mem:SI (plus:SI (match_dup 2) (const_int 52))) --+ (match_operand:SI 16 "register_operand" "")) --+ (set (mem:SI (plus:SI (match_dup 2) (const_int 56))) --+ (match_operand:SI 17 "register_operand" "")) --+ (set (mem:SI (plus:SI (match_dup 2) (const_int 60))) --+ (match_operand:SI 18 "register_operand" ""))])] --+ "(XVECLEN (operands[0], 0) == 17)" --+ "smw.bim\t%3, [%1], %18, 0x0" --+ [(set_attr "type" "store_multiple") --+ (set_attr "combo" "16") --+ (set_attr "length" "4")] --+) --+ --+(define_insn "*stm_bim_si15" --+ [(match_parallel 0 "nds32_store_multiple_and_update_address_operation" --+ [(set (match_operand:SI 1 "register_operand" "=r") --+ (plus:SI (match_operand:SI 2 "register_operand" "1") (const_int 60))) --+ (set (mem:SI (match_dup 2)) --+ (match_operand:SI 3 "register_operand" "")) --+ (set (mem:SI (plus:SI (match_dup 2) (const_int 4))) --+ (match_operand:SI 4 "register_operand" "")) --+ (set (mem:SI (plus:SI (match_dup 2) (const_int 8))) --+ (match_operand:SI 5 "register_operand" "")) --+ (set (mem:SI (plus:SI (match_dup 2) (const_int 12))) --+ (match_operand:SI 6 "register_operand" "")) --+ (set (mem:SI (plus:SI (match_dup 2) (const_int 16))) --+ (match_operand:SI 7 "register_operand" "")) --+ (set (mem:SI (plus:SI (match_dup 2) (const_int 20))) --+ (match_operand:SI 8 "register_operand" "")) --+ (set (mem:SI (plus:SI (match_dup 2) (const_int 24))) --+ (match_operand:SI 9 "register_operand" "")) --+ (set (mem:SI (plus:SI (match_dup 2) (const_int 28))) --+ (match_operand:SI 10 "register_operand" "")) --+ (set (mem:SI (plus:SI (match_dup 2) (const_int 32))) --+ (match_operand:SI 11 "register_operand" "")) --+ (set (mem:SI (plus:SI (match_dup 2) (const_int 36))) --+ (match_operand:SI 12 "register_operand" "")) --+ (set (mem:SI (plus:SI (match_dup 2) (const_int 40))) --+ (match_operand:SI 13 "register_operand" "")) --+ (set (mem:SI (plus:SI (match_dup 2) (const_int 44))) --+ (match_operand:SI 14 "register_operand" "")) --+ (set (mem:SI (plus:SI (match_dup 2) (const_int 48))) --+ (match_operand:SI 15 "register_operand" "")) --+ (set (mem:SI (plus:SI (match_dup 2) (const_int 52))) --+ (match_operand:SI 16 "register_operand" "")) --+ (set (mem:SI (plus:SI (match_dup 2) (const_int 56))) --+ (match_operand:SI 17 "register_operand" ""))])] --+ "(XVECLEN (operands[0], 0) == 16)" --+ "smw.bim\t%3, [%1], %17, 0x0" --+ [(set_attr "type" "store_multiple") --+ (set_attr "combo" "15") --+ (set_attr "length" "4")] --+) --+ --+(define_insn "*stm_bim_si14" --+ [(match_parallel 0 "nds32_store_multiple_and_update_address_operation" --+ [(set (match_operand:SI 1 "register_operand" "=r") --+ (plus:SI (match_operand:SI 2 "register_operand" "1") (const_int 56))) --+ (set (mem:SI (match_dup 2)) --+ (match_operand:SI 3 "register_operand" "")) --+ (set (mem:SI (plus:SI (match_dup 2) (const_int 4))) --+ (match_operand:SI 4 "register_operand" "")) --+ (set (mem:SI (plus:SI (match_dup 2) (const_int 8))) --+ (match_operand:SI 5 "register_operand" "")) --+ (set (mem:SI (plus:SI (match_dup 2) (const_int 12))) --+ (match_operand:SI 6 "register_operand" "")) --+ (set (mem:SI (plus:SI (match_dup 2) (const_int 16))) --+ (match_operand:SI 7 "register_operand" "")) --+ (set (mem:SI (plus:SI (match_dup 2) (const_int 20))) --+ (match_operand:SI 8 "register_operand" "")) --+ (set (mem:SI (plus:SI (match_dup 2) (const_int 24))) --+ (match_operand:SI 9 "register_operand" "")) --+ (set (mem:SI (plus:SI (match_dup 2) (const_int 28))) --+ (match_operand:SI 10 "register_operand" "")) --+ (set (mem:SI (plus:SI (match_dup 2) (const_int 32))) --+ (match_operand:SI 11 "register_operand" "")) --+ (set (mem:SI (plus:SI (match_dup 2) (const_int 36))) --+ (match_operand:SI 12 "register_operand" "")) --+ (set (mem:SI (plus:SI (match_dup 2) (const_int 40))) --+ (match_operand:SI 13 "register_operand" "")) --+ (set (mem:SI (plus:SI (match_dup 2) (const_int 44))) --+ (match_operand:SI 14 "register_operand" "")) --+ (set (mem:SI (plus:SI (match_dup 2) (const_int 48))) --+ (match_operand:SI 15 "register_operand" "")) --+ (set (mem:SI (plus:SI (match_dup 2) (const_int 52))) --+ (match_operand:SI 16 "register_operand" ""))])] --+ "(XVECLEN (operands[0], 0) == 15)" --+ "smw.bim\t%3, [%1], %16, 0x0" --+ [(set_attr "type" "store_multiple") --+ (set_attr "combo" "14") --+ (set_attr "length" "4")] --+) --+ --+(define_insn "*stm_bim_si13" --+ [(match_parallel 0 "nds32_store_multiple_and_update_address_operation" --+ [(set (match_operand:SI 1 "register_operand" "=r") --+ (plus:SI (match_operand:SI 2 "register_operand" "1") (const_int 52))) --+ (set (mem:SI (match_dup 2)) --+ (match_operand:SI 3 "register_operand" "")) --+ (set (mem:SI (plus:SI (match_dup 2) (const_int 4))) --+ (match_operand:SI 4 "register_operand" "")) --+ (set (mem:SI (plus:SI (match_dup 2) (const_int 8))) --+ (match_operand:SI 5 "register_operand" "")) --+ (set (mem:SI (plus:SI (match_dup 2) (const_int 12))) --+ (match_operand:SI 6 "register_operand" "")) --+ (set (mem:SI (plus:SI (match_dup 2) (const_int 16))) --+ (match_operand:SI 7 "register_operand" "")) --+ (set (mem:SI (plus:SI (match_dup 2) (const_int 20))) --+ (match_operand:SI 8 "register_operand" "")) --+ (set (mem:SI (plus:SI (match_dup 2) (const_int 24))) --+ (match_operand:SI 9 "register_operand" "")) --+ (set (mem:SI (plus:SI (match_dup 2) (const_int 28))) --+ (match_operand:SI 10 "register_operand" "")) --+ (set (mem:SI (plus:SI (match_dup 2) (const_int 32))) --+ (match_operand:SI 11 "register_operand" "")) --+ (set (mem:SI (plus:SI (match_dup 2) (const_int 36))) --+ (match_operand:SI 12 "register_operand" "")) --+ (set (mem:SI (plus:SI (match_dup 2) (const_int 40))) --+ (match_operand:SI 13 "register_operand" "")) --+ (set (mem:SI (plus:SI (match_dup 2) (const_int 44))) --+ (match_operand:SI 14 "register_operand" "")) --+ (set (mem:SI (plus:SI (match_dup 2) (const_int 48))) --+ (match_operand:SI 15 "register_operand" ""))])] --+ "(XVECLEN (operands[0], 0) == 14)" --+ "smw.bim\t%3, [%1], %15, 0x0" --+ [(set_attr "type" "store_multiple") --+ (set_attr "combo" "13") --+ (set_attr "length" "4")] --+) --+ --+(define_insn "*stm_bim_si12" --+ [(match_parallel 0 "nds32_store_multiple_and_update_address_operation" --+ [(set (match_operand:SI 1 "register_operand" "=r") --+ (plus:SI (match_operand:SI 2 "register_operand" "1") (const_int 48))) --+ (set (mem:SI (match_dup 2)) --+ (match_operand:SI 3 "register_operand" "")) --+ (set (mem:SI (plus:SI (match_dup 2) (const_int 4))) --+ (match_operand:SI 4 "register_operand" "")) --+ (set (mem:SI (plus:SI (match_dup 2) (const_int 8))) --+ (match_operand:SI 5 "register_operand" "")) --+ (set (mem:SI (plus:SI (match_dup 2) (const_int 12))) --+ (match_operand:SI 6 "register_operand" "")) --+ (set (mem:SI (plus:SI (match_dup 2) (const_int 16))) --+ (match_operand:SI 7 "register_operand" "")) --+ (set (mem:SI (plus:SI (match_dup 2) (const_int 20))) --+ (match_operand:SI 8 "register_operand" "")) --+ (set (mem:SI (plus:SI (match_dup 2) (const_int 24))) --+ (match_operand:SI 9 "register_operand" "")) --+ (set (mem:SI (plus:SI (match_dup 2) (const_int 28))) --+ (match_operand:SI 10 "register_operand" "")) --+ (set (mem:SI (plus:SI (match_dup 2) (const_int 32))) --+ (match_operand:SI 11 "register_operand" "")) --+ (set (mem:SI (plus:SI (match_dup 2) (const_int 36))) --+ (match_operand:SI 12 "register_operand" "")) --+ (set (mem:SI (plus:SI (match_dup 2) (const_int 40))) --+ (match_operand:SI 13 "register_operand" "")) --+ (set (mem:SI (plus:SI (match_dup 2) (const_int 44))) --+ (match_operand:SI 14 "register_operand" ""))])] --+ "(XVECLEN (operands[0], 0) == 13)" --+ "smw.bim\t%3, [%1], %14, 0x0" --+ [(set_attr "type" "store_multiple") --+ (set_attr "combo" "12") --+ (set_attr "length" "4")] --+) --+ --+(define_insn "*stm_bim_si11" --+ [(match_parallel 0 "nds32_store_multiple_and_update_address_operation" --+ [(set (match_operand:SI 1 "register_operand" "=r") --+ (plus:SI (match_operand:SI 2 "register_operand" "1") (const_int 44))) --+ (set (mem:SI (match_dup 2)) --+ (match_operand:SI 3 "register_operand" "")) --+ (set (mem:SI (plus:SI (match_dup 2) (const_int 4))) --+ (match_operand:SI 4 "register_operand" "")) --+ (set (mem:SI (plus:SI (match_dup 2) (const_int 8))) --+ (match_operand:SI 5 "register_operand" "")) --+ (set (mem:SI (plus:SI (match_dup 2) (const_int 12))) --+ (match_operand:SI 6 "register_operand" "")) --+ (set (mem:SI (plus:SI (match_dup 2) (const_int 16))) --+ (match_operand:SI 7 "register_operand" "")) --+ (set (mem:SI (plus:SI (match_dup 2) (const_int 20))) --+ (match_operand:SI 8 "register_operand" "")) --+ (set (mem:SI (plus:SI (match_dup 2) (const_int 24))) --+ (match_operand:SI 9 "register_operand" "")) --+ (set (mem:SI (plus:SI (match_dup 2) (const_int 28))) --+ (match_operand:SI 10 "register_operand" "")) --+ (set (mem:SI (plus:SI (match_dup 2) (const_int 32))) --+ (match_operand:SI 11 "register_operand" "")) --+ (set (mem:SI (plus:SI (match_dup 2) (const_int 36))) --+ (match_operand:SI 12 "register_operand" "")) --+ (set (mem:SI (plus:SI (match_dup 2) (const_int 40))) --+ (match_operand:SI 13 "register_operand" ""))])] --+ "(XVECLEN (operands[0], 0) == 12)" --+ "smw.bim\t%3, [%1], %13, 0x0" --+ [(set_attr "type" "store_multiple") --+ (set_attr "combo" "11") --+ (set_attr "length" "4")] --+) --+ --+(define_insn "*stm_bim_si10" --+ [(match_parallel 0 "nds32_store_multiple_and_update_address_operation" --+ [(set (match_operand:SI 1 "register_operand" "=r") --+ (plus:SI (match_operand:SI 2 "register_operand" "1") (const_int 40))) --+ (set (mem:SI (match_dup 2)) --+ (match_operand:SI 3 "register_operand" "")) --+ (set (mem:SI (plus:SI (match_dup 2) (const_int 4))) --+ (match_operand:SI 4 "register_operand" "")) --+ (set (mem:SI (plus:SI (match_dup 2) (const_int 8))) --+ (match_operand:SI 5 "register_operand" "")) --+ (set (mem:SI (plus:SI (match_dup 2) (const_int 12))) --+ (match_operand:SI 6 "register_operand" "")) --+ (set (mem:SI (plus:SI (match_dup 2) (const_int 16))) --+ (match_operand:SI 7 "register_operand" "")) --+ (set (mem:SI (plus:SI (match_dup 2) (const_int 20))) --+ (match_operand:SI 8 "register_operand" "")) --+ (set (mem:SI (plus:SI (match_dup 2) (const_int 24))) --+ (match_operand:SI 9 "register_operand" "")) --+ (set (mem:SI (plus:SI (match_dup 2) (const_int 28))) --+ (match_operand:SI 10 "register_operand" "")) --+ (set (mem:SI (plus:SI (match_dup 2) (const_int 32))) --+ (match_operand:SI 11 "register_operand" "")) --+ (set (mem:SI (plus:SI (match_dup 2) (const_int 36))) --+ (match_operand:SI 12 "register_operand" ""))])] --+ "(XVECLEN (operands[0], 0) == 11)" --+ "smw.bim\t%3, [%1], %12, 0x0" --+ [(set_attr "type" "store_multiple") --+ (set_attr "combo" "10") --+ (set_attr "length" "4")] --+) --+ --+(define_insn "*stm_bim_si9" --+ [(match_parallel 0 "nds32_store_multiple_and_update_address_operation" --+ [(set (match_operand:SI 1 "register_operand" "=r") --+ (plus:SI (match_operand:SI 2 "register_operand" "1") (const_int 36))) --+ (set (mem:SI (match_dup 2)) --+ (match_operand:SI 3 "register_operand" "")) --+ (set (mem:SI (plus:SI (match_dup 2) (const_int 4))) --+ (match_operand:SI 4 "register_operand" "")) --+ (set (mem:SI (plus:SI (match_dup 2) (const_int 8))) --+ (match_operand:SI 5 "register_operand" "")) --+ (set (mem:SI (plus:SI (match_dup 2) (const_int 12))) --+ (match_operand:SI 6 "register_operand" "")) --+ (set (mem:SI (plus:SI (match_dup 2) (const_int 16))) --+ (match_operand:SI 7 "register_operand" "")) --+ (set (mem:SI (plus:SI (match_dup 2) (const_int 20))) --+ (match_operand:SI 8 "register_operand" "")) --+ (set (mem:SI (plus:SI (match_dup 2) (const_int 24))) --+ (match_operand:SI 9 "register_operand" "")) --+ (set (mem:SI (plus:SI (match_dup 2) (const_int 28))) --+ (match_operand:SI 10 "register_operand" "")) --+ (set (mem:SI (plus:SI (match_dup 2) (const_int 32))) --+ (match_operand:SI 11 "register_operand" ""))])] --+ "(XVECLEN (operands[0], 0) == 10)" --+ "smw.bim\t%3, [%1], %11, 0x0" --+ [(set_attr "type" "store_multiple") --+ (set_attr "combo" "9") --+ (set_attr "length" "4")] --+) --+ --+ --+(define_insn "*stm_bim_si8" --+ [(match_parallel 0 "nds32_store_multiple_and_update_address_operation" --+ [(set (match_operand:SI 1 "register_operand" "=r") --+ (plus:SI (match_operand:SI 2 "register_operand" "1") (const_int 32))) --+ (set (mem:SI (match_dup 2)) --+ (match_operand:SI 3 "register_operand" "")) --+ (set (mem:SI (plus:SI (match_dup 2) (const_int 4))) --+ (match_operand:SI 4 "register_operand" "")) --+ (set (mem:SI (plus:SI (match_dup 2) (const_int 8))) --+ (match_operand:SI 5 "register_operand" "")) --+ (set (mem:SI (plus:SI (match_dup 2) (const_int 12))) --+ (match_operand:SI 6 "register_operand" "")) --+ (set (mem:SI (plus:SI (match_dup 2) (const_int 16))) --+ (match_operand:SI 7 "register_operand" "")) --+ (set (mem:SI (plus:SI (match_dup 2) (const_int 20))) --+ (match_operand:SI 8 "register_operand" "")) --+ (set (mem:SI (plus:SI (match_dup 2) (const_int 24))) --+ (match_operand:SI 9 "register_operand" "")) --+ (set (mem:SI (plus:SI (match_dup 2) (const_int 28))) --+ (match_operand:SI 10 "register_operand" ""))])] --+ "(XVECLEN (operands[0], 0) == 9)" --+ "smw.bim\t%3, [%1], %10, 0x0" --+ [(set_attr "type" "store_multiple") --+ (set_attr "combo" "8") --+ (set_attr "length" "4")] --+) --+ --+(define_insn "*stm_bim_si7" --+ [(match_parallel 0 "nds32_store_multiple_and_update_address_operation" --+ [(set (match_operand:SI 1 "register_operand" "=r") --+ (plus:SI (match_operand:SI 2 "register_operand" "1") (const_int 28))) --+ (set (mem:SI (match_dup 2)) --+ (match_operand:SI 3 "register_operand" "")) --+ (set (mem:SI (plus:SI (match_dup 2) (const_int 4))) --+ (match_operand:SI 4 "register_operand" "")) --+ (set (mem:SI (plus:SI (match_dup 2) (const_int 8))) --+ (match_operand:SI 5 "register_operand" "")) --+ (set (mem:SI (plus:SI (match_dup 2) (const_int 12))) --+ (match_operand:SI 6 "register_operand" "")) --+ (set (mem:SI (plus:SI (match_dup 2) (const_int 16))) --+ (match_operand:SI 7 "register_operand" "")) --+ (set (mem:SI (plus:SI (match_dup 2) (const_int 20))) --+ (match_operand:SI 8 "register_operand" "")) --+ (set (mem:SI (plus:SI (match_dup 2) (const_int 24))) --+ (match_operand:SI 9 "register_operand" ""))])] --+ "(XVECLEN (operands[0], 0) == 8)" --+ "smw.bim\t%3, [%1], %9, 0x0" --+ [(set_attr "type" "store_multiple") --+ (set_attr "combo" "7") --+ (set_attr "length" "4")] --+) --+ --+(define_insn "*stm_bim_si6" --+ [(match_parallel 0 "nds32_store_multiple_and_update_address_operation" --+ [(set (match_operand:SI 1 "register_operand" "=r") --+ (plus:SI (match_operand:SI 2 "register_operand" "1") (const_int 24))) --+ (set (mem:SI (match_dup 2)) --+ (match_operand:SI 3 "register_operand" "")) --+ (set (mem:SI (plus:SI (match_dup 2) (const_int 4))) --+ (match_operand:SI 4 "register_operand" "")) --+ (set (mem:SI (plus:SI (match_dup 2) (const_int 8))) --+ (match_operand:SI 5 "register_operand" "")) --+ (set (mem:SI (plus:SI (match_dup 2) (const_int 12))) --+ (match_operand:SI 6 "register_operand" "")) --+ (set (mem:SI (plus:SI (match_dup 2) (const_int 16))) --+ (match_operand:SI 7 "register_operand" "")) --+ (set (mem:SI (plus:SI (match_dup 2) (const_int 20))) --+ (match_operand:SI 8 "register_operand" ""))])] --+ "(XVECLEN (operands[0], 0) == 7)" --+ "smw.bim\t%3, [%1], %8, 0x0" --+ [(set_attr "type" "store_multiple") --+ (set_attr "combo" "6") --+ (set_attr "length" "4")] --+) --+ --+(define_insn "*stm_bim_si5" --+ [(match_parallel 0 "nds32_store_multiple_and_update_address_operation" --+ [(set (match_operand:SI 1 "register_operand" "=r") --+ (plus:SI (match_operand:SI 2 "register_operand" "1") (const_int 20))) --+ (set (mem:SI (match_dup 2)) --+ (match_operand:SI 3 "register_operand" "")) --+ (set (mem:SI (plus:SI (match_dup 2) (const_int 4))) --+ (match_operand:SI 4 "register_operand" "")) --+ (set (mem:SI (plus:SI (match_dup 2) (const_int 8))) --+ (match_operand:SI 5 "register_operand" "")) --+ (set (mem:SI (plus:SI (match_dup 2) (const_int 12))) --+ (match_operand:SI 6 "register_operand" "")) --+ (set (mem:SI (plus:SI (match_dup 2) (const_int 16))) --+ (match_operand:SI 7 "register_operand" ""))])] --+ "(XVECLEN (operands[0], 0) == 6)" --+ "smw.bim\t%3, [%1], %7, 0x0" --+ [(set_attr "type" "store_multiple") --+ (set_attr "combo" "5") --+ (set_attr "length" "4")] --+) --+ --+(define_insn "*stm_bim_si4" --+ [(match_parallel 0 "nds32_store_multiple_and_update_address_operation" --+ [(set (match_operand:SI 1 "register_operand" "=r") --+ (plus:SI (match_operand:SI 2 "register_operand" "1") (const_int 16))) --+ (set (mem:SI (match_dup 2)) --+ (match_operand:SI 3 "register_operand" "")) --+ (set (mem:SI (plus:SI (match_dup 2) (const_int 4))) --+ (match_operand:SI 4 "register_operand" "")) --+ (set (mem:SI (plus:SI (match_dup 2) (const_int 8))) --+ (match_operand:SI 5 "register_operand" "")) --+ (set (mem:SI (plus:SI (match_dup 2) (const_int 12))) --+ (match_operand:SI 6 "register_operand" ""))])] --+ "(XVECLEN (operands[0], 0) == 5)" --+ "smw.bim\t%3, [%1], %6, 0x0" --+ [(set_attr "type" "store_multiple") --+ (set_attr "combo" "4") --+ (set_attr "length" "4")] --+) --+ --+(define_insn "*stm_bim_si3" --+ [(match_parallel 0 "nds32_store_multiple_and_update_address_operation" --+ [(set (match_operand:SI 1 "register_operand" "=r") --+ (plus:SI (match_operand:SI 2 "register_operand" "1") (const_int 12))) --+ (set (mem:SI (match_dup 2)) --+ (match_operand:SI 3 "register_operand" "")) --+ (set (mem:SI (plus:SI (match_dup 2) (const_int 4))) --+ (match_operand:SI 4 "register_operand" "")) --+ (set (mem:SI (plus:SI (match_dup 2) (const_int 8))) --+ (match_operand:SI 5 "register_operand" ""))])] --+ "(XVECLEN (operands[0], 0) == 4)" --+ "smw.bim\t%3, [%1], %5, 0x0" --+ [(set_attr "type" "store_multiple") --+ (set_attr "combo" "3") --+ (set_attr "length" "4")] --+) --+ --+(define_insn "*stm_bim_si2" --+ [(match_parallel 0 "nds32_store_multiple_and_update_address_operation" --+ [(set (match_operand:SI 1 "register_operand" "=r") --+ (plus:SI (match_operand:SI 2 "register_operand" "1") (const_int 8))) --+ (set (mem:SI (match_dup 2)) --+ (match_operand:SI 3 "register_operand" "")) --+ (set (mem:SI (plus:SI (match_dup 2) (const_int 4))) --+ (match_operand:SI 4 "register_operand" ""))])] --+ "(XVECLEN (operands[0], 0) == 3)" --+ "smw.bim\t%3, [%1], %4, 0x0" --+ [(set_attr "type" "store_multiple") --+ (set_attr "combo" "2") --+ (set_attr "length" "4")] --+) --+ --+(define_expand "unaligned_store_update_base_w" --+ [(parallel [(set (match_operand:SI 0 "register_operand" "=r") --+ (plus:SI (match_operand:SI 1 "register_operand" "0") (const_int 4))) --+ (set (mem:SI (match_dup 1)) --+ (unspec:SI [(match_operand:SI 2 "register_operand" "r")] UNSPEC_UASTORE_W))])] --+ "" --+{ --+ /* DO NOT emit unaligned_store_w_m immediately since web pass don't --+ recognize post_inc, try it again after GCC 5.0. --+ REF: https://gcc.gnu.org/bugzilla/show_bug.cgi?id=63156 */ --+ emit_insn (gen_unaligned_store_w (gen_rtx_MEM (SImode, operands[1]), operands[2])); --+ emit_insn (gen_addsi3 (operands[0], operands[1], gen_int_mode (4, Pmode))); --+ DONE; --+} --+ [(set_attr "type" "store_multiple") --+ (set_attr "combo" "1") --+ (set_attr "length" "4")] --+) --+ --+(define_expand "unaligned_store_update_base_dw" --+ [(parallel [(set (match_operand:SI 0 "register_operand" "=r") --+ (plus:SI (match_operand:SI 1 "register_operand" "0") (const_int 8))) --+ (set (mem:DI (match_dup 1)) --+ (unspec:DI [(match_operand:DI 2 "register_operand" "r")] UNSPEC_UASTORE_DW))])] --+ "" --+{ --+ /* DO NOT emit unaligned_store_w_m immediately since web pass don't --+ recognize post_inc, try it again after GCC 5.0. --+ REF: https://gcc.gnu.org/bugzilla/show_bug.cgi?id=63156 */ --+ emit_insn (gen_unaligned_store_dw (gen_rtx_MEM (DImode, operands[1]), operands[2])); --+ emit_insn (gen_addsi3 (operands[0], operands[1], gen_int_mode (8, Pmode))); --+ DONE; --+} --+ [(set_attr "type" "store_multiple") --+ (set_attr "combo" "2") --+ (set_attr "length" "4")] --+) --+ --+(define_insn "*stmsi25" --+ [(match_parallel 0 "nds32_store_multiple_operation" --+ [(set (mem:SI (match_operand:SI 1 "register_operand" "r")) --+ (match_operand:SI 2 "register_operand" "")) --+ (set (mem:SI (plus:SI (match_dup 1) (const_int 4))) --+ (match_operand:SI 3 "register_operand" "")) --+ (set (mem:SI (plus:SI (match_dup 1) (const_int 8))) --+ (match_operand:SI 4 "register_operand" "")) --+ (set (mem:SI (plus:SI (match_dup 1) (const_int 12))) --+ (match_operand:SI 5 "register_operand" "")) --+ (set (mem:SI (plus:SI (match_dup 1) (const_int 16))) --+ (match_operand:SI 6 "register_operand" "")) --+ (set (mem:SI (plus:SI (match_dup 1) (const_int 20))) --+ (match_operand:SI 7 "register_operand" "")) --+ (set (mem:SI (plus:SI (match_dup 1) (const_int 24))) --+ (match_operand:SI 8 "register_operand" "")) --+ (set (mem:SI (plus:SI (match_dup 1) (const_int 28))) --+ (match_operand:SI 9 "register_operand" "")) --+ (set (mem:SI (plus:SI (match_dup 1) (const_int 32))) --+ (match_operand:SI 10 "register_operand" "")) --+ (set (mem:SI (plus:SI (match_dup 1) (const_int 36))) --+ (match_operand:SI 11 "register_operand" "")) --+ (set (mem:SI (plus:SI (match_dup 1) (const_int 40))) --+ (match_operand:SI 12 "register_operand" "")) --+ (set (mem:SI (plus:SI (match_dup 1) (const_int 44))) --+ (match_operand:SI 13 "register_operand" "")) --+ (set (mem:SI (plus:SI (match_dup 1) (const_int 48))) --+ (match_operand:SI 14 "register_operand" "")) --+ (set (mem:SI (plus:SI (match_dup 1) (const_int 52))) --+ (match_operand:SI 15 "register_operand" "")) --+ (set (mem:SI (plus:SI (match_dup 1) (const_int 56))) --+ (match_operand:SI 16 "register_operand" "")) --+ (set (mem:SI (plus:SI (match_dup 1) (const_int 60))) --+ (match_operand:SI 17 "register_operand" "")) --+ (set (mem:SI (plus:SI (match_dup 1) (const_int 64))) --+ (match_operand:SI 18 "register_operand" "")) --+ (set (mem:SI (plus:SI (match_dup 1) (const_int 68))) --+ (match_operand:SI 19 "register_operand" "")) --+ (set (mem:SI (plus:SI (match_dup 1) (const_int 72))) --+ (match_operand:SI 20 "register_operand" "")) --+ (set (mem:SI (plus:SI (match_dup 1) (const_int 76))) --+ (match_operand:SI 21 "register_operand" "")) --+ (set (mem:SI (plus:SI (match_dup 1) (const_int 80))) --+ (match_operand:SI 22 "register_operand" "")) --+ (set (mem:SI (plus:SI (match_dup 1) (const_int 84))) --+ (match_operand:SI 23 "register_operand" "")) --+ (set (mem:SI (plus:SI (match_dup 1) (const_int 88))) --+ (match_operand:SI 24 "register_operand" "")) --+ (set (mem:SI (plus:SI (match_dup 1) (const_int 92))) --+ (match_operand:SI 25 "register_operand" "")) --+ (set (mem:SI (plus:SI (match_dup 1) (const_int 96))) --+ (match_operand:SI 26 "register_operand" ""))])] --+ "(XVECLEN (operands[0], 0) == 25)" --+ "smw.bi\t%2, [%1], %26, 0x0" --+ [(set_attr "type" "store_multiple") --+ (set_attr "combo" "25") --+ (set_attr "length" "4")] --+) --+ --+(define_insn "*stmsi24" --+ [(match_parallel 0 "nds32_store_multiple_operation" --+ [(set (mem:SI (match_operand:SI 1 "register_operand" "r")) --+ (match_operand:SI 2 "register_operand" "")) --+ (set (mem:SI (plus:SI (match_dup 1) (const_int 4))) --+ (match_operand:SI 3 "register_operand" "")) --+ (set (mem:SI (plus:SI (match_dup 1) (const_int 8))) --+ (match_operand:SI 4 "register_operand" "")) --+ (set (mem:SI (plus:SI (match_dup 1) (const_int 12))) --+ (match_operand:SI 5 "register_operand" "")) --+ (set (mem:SI (plus:SI (match_dup 1) (const_int 16))) --+ (match_operand:SI 6 "register_operand" "")) --+ (set (mem:SI (plus:SI (match_dup 1) (const_int 20))) --+ (match_operand:SI 7 "register_operand" "")) --+ (set (mem:SI (plus:SI (match_dup 1) (const_int 24))) --+ (match_operand:SI 8 "register_operand" "")) --+ (set (mem:SI (plus:SI (match_dup 1) (const_int 28))) --+ (match_operand:SI 9 "register_operand" "")) --+ (set (mem:SI (plus:SI (match_dup 1) (const_int 32))) --+ (match_operand:SI 10 "register_operand" "")) --+ (set (mem:SI (plus:SI (match_dup 1) (const_int 36))) --+ (match_operand:SI 11 "register_operand" "")) --+ (set (mem:SI (plus:SI (match_dup 1) (const_int 40))) --+ (match_operand:SI 12 "register_operand" "")) --+ (set (mem:SI (plus:SI (match_dup 1) (const_int 44))) --+ (match_operand:SI 13 "register_operand" "")) --+ (set (mem:SI (plus:SI (match_dup 1) (const_int 48))) --+ (match_operand:SI 14 "register_operand" "")) --+ (set (mem:SI (plus:SI (match_dup 1) (const_int 52))) --+ (match_operand:SI 15 "register_operand" "")) --+ (set (mem:SI (plus:SI (match_dup 1) (const_int 56))) --+ (match_operand:SI 16 "register_operand" "")) --+ (set (mem:SI (plus:SI (match_dup 1) (const_int 60))) --+ (match_operand:SI 17 "register_operand" "")) --+ (set (mem:SI (plus:SI (match_dup 1) (const_int 64))) --+ (match_operand:SI 18 "register_operand" "")) --+ (set (mem:SI (plus:SI (match_dup 1) (const_int 68))) --+ (match_operand:SI 19 "register_operand" "")) --+ (set (mem:SI (plus:SI (match_dup 1) (const_int 72))) --+ (match_operand:SI 20 "register_operand" "")) --+ (set (mem:SI (plus:SI (match_dup 1) (const_int 76))) --+ (match_operand:SI 21 "register_operand" "")) --+ (set (mem:SI (plus:SI (match_dup 1) (const_int 80))) --+ (match_operand:SI 22 "register_operand" "")) --+ (set (mem:SI (plus:SI (match_dup 1) (const_int 84))) --+ (match_operand:SI 23 "register_operand" "")) --+ (set (mem:SI (plus:SI (match_dup 1) (const_int 88))) --+ (match_operand:SI 24 "register_operand" "")) --+ (set (mem:SI (plus:SI (match_dup 1) (const_int 92))) --+ (match_operand:SI 25 "register_operand" "")) --+])] --+ "(XVECLEN (operands[0], 0) == 24)" --+ "smw.bi\t%2, [%1], %25, 0x0" --+ [(set_attr "type" "store_multiple") --+ (set_attr "combo" "24") --+ (set_attr "length" "4")] --+) --+ --+(define_insn "*stmsi23" --+ [(match_parallel 0 "nds32_store_multiple_operation" --+ [(set (mem:SI (match_operand:SI 1 "register_operand" "r")) --+ (match_operand:SI 2 "register_operand" "")) --+ (set (mem:SI (plus:SI (match_dup 1) (const_int 4))) --+ (match_operand:SI 3 "register_operand" "")) --+ (set (mem:SI (plus:SI (match_dup 1) (const_int 8))) --+ (match_operand:SI 4 "register_operand" "")) --+ (set (mem:SI (plus:SI (match_dup 1) (const_int 12))) --+ (match_operand:SI 5 "register_operand" "")) --+ (set (mem:SI (plus:SI (match_dup 1) (const_int 16))) --+ (match_operand:SI 6 "register_operand" "")) --+ (set (mem:SI (plus:SI (match_dup 1) (const_int 20))) --+ (match_operand:SI 7 "register_operand" "")) --+ (set (mem:SI (plus:SI (match_dup 1) (const_int 24))) --+ (match_operand:SI 8 "register_operand" "")) --+ (set (mem:SI (plus:SI (match_dup 1) (const_int 28))) --+ (match_operand:SI 9 "register_operand" "")) --+ (set (mem:SI (plus:SI (match_dup 1) (const_int 32))) --+ (match_operand:SI 10 "register_operand" "")) --+ (set (mem:SI (plus:SI (match_dup 1) (const_int 36))) --+ (match_operand:SI 11 "register_operand" "")) --+ (set (mem:SI (plus:SI (match_dup 1) (const_int 40))) --+ (match_operand:SI 12 "register_operand" "")) --+ (set (mem:SI (plus:SI (match_dup 1) (const_int 44))) --+ (match_operand:SI 13 "register_operand" "")) --+ (set (mem:SI (plus:SI (match_dup 1) (const_int 48))) --+ (match_operand:SI 14 "register_operand" "")) --+ (set (mem:SI (plus:SI (match_dup 1) (const_int 52))) --+ (match_operand:SI 15 "register_operand" "")) --+ (set (mem:SI (plus:SI (match_dup 1) (const_int 56))) --+ (match_operand:SI 16 "register_operand" "")) --+ (set (mem:SI (plus:SI (match_dup 1) (const_int 60))) --+ (match_operand:SI 17 "register_operand" "")) --+ (set (mem:SI (plus:SI (match_dup 1) (const_int 64))) --+ (match_operand:SI 18 "register_operand" "")) --+ (set (mem:SI (plus:SI (match_dup 1) (const_int 68))) --+ (match_operand:SI 19 "register_operand" "")) --+ (set (mem:SI (plus:SI (match_dup 1) (const_int 72))) --+ (match_operand:SI 20 "register_operand" "")) --+ (set (mem:SI (plus:SI (match_dup 1) (const_int 76))) --+ (match_operand:SI 21 "register_operand" "")) --+ (set (mem:SI (plus:SI (match_dup 1) (const_int 80))) --+ (match_operand:SI 22 "register_operand" "")) --+ (set (mem:SI (plus:SI (match_dup 1) (const_int 84))) --+ (match_operand:SI 23 "register_operand" "")) --+ (set (mem:SI (plus:SI (match_dup 1) (const_int 88))) --+ (match_operand:SI 24 "register_operand" "")) --+])] --+ "(XVECLEN (operands[0], 0) == 23)" --+ "smw.bi\t%2, [%1], %24, 0x0" --+ [(set_attr "type" "store_multiple") --+ (set_attr "combo" "23") --+ (set_attr "length" "4")] --+) --+ --+(define_insn "*stmsi22" --+ [(match_parallel 0 "nds32_store_multiple_operation" --+ [(set (mem:SI (match_operand:SI 1 "register_operand" "r")) --+ (match_operand:SI 2 "register_operand" "")) --+ (set (mem:SI (plus:SI (match_dup 1) (const_int 4))) --+ (match_operand:SI 3 "register_operand" "")) --+ (set (mem:SI (plus:SI (match_dup 1) (const_int 8))) --+ (match_operand:SI 4 "register_operand" "")) --+ (set (mem:SI (plus:SI (match_dup 1) (const_int 12))) --+ (match_operand:SI 5 "register_operand" "")) --+ (set (mem:SI (plus:SI (match_dup 1) (const_int 16))) --+ (match_operand:SI 6 "register_operand" "")) --+ (set (mem:SI (plus:SI (match_dup 1) (const_int 20))) --+ (match_operand:SI 7 "register_operand" "")) --+ (set (mem:SI (plus:SI (match_dup 1) (const_int 24))) --+ (match_operand:SI 8 "register_operand" "")) --+ (set (mem:SI (plus:SI (match_dup 1) (const_int 28))) --+ (match_operand:SI 9 "register_operand" "")) --+ (set (mem:SI (plus:SI (match_dup 1) (const_int 32))) --+ (match_operand:SI 10 "register_operand" "")) --+ (set (mem:SI (plus:SI (match_dup 1) (const_int 36))) --+ (match_operand:SI 11 "register_operand" "")) --+ (set (mem:SI (plus:SI (match_dup 1) (const_int 40))) --+ (match_operand:SI 12 "register_operand" "")) --+ (set (mem:SI (plus:SI (match_dup 1) (const_int 44))) --+ (match_operand:SI 13 "register_operand" "")) --+ (set (mem:SI (plus:SI (match_dup 1) (const_int 48))) --+ (match_operand:SI 14 "register_operand" "")) --+ (set (mem:SI (plus:SI (match_dup 1) (const_int 52))) --+ (match_operand:SI 15 "register_operand" "")) --+ (set (mem:SI (plus:SI (match_dup 1) (const_int 56))) --+ (match_operand:SI 16 "register_operand" "")) --+ (set (mem:SI (plus:SI (match_dup 1) (const_int 60))) --+ (match_operand:SI 17 "register_operand" "")) --+ (set (mem:SI (plus:SI (match_dup 1) (const_int 64))) --+ (match_operand:SI 18 "register_operand" "")) --+ (set (mem:SI (plus:SI (match_dup 1) (const_int 68))) --+ (match_operand:SI 19 "register_operand" "")) --+ (set (mem:SI (plus:SI (match_dup 1) (const_int 72))) --+ (match_operand:SI 20 "register_operand" "")) --+ (set (mem:SI (plus:SI (match_dup 1) (const_int 76))) --+ (match_operand:SI 21 "register_operand" "")) --+ (set (mem:SI (plus:SI (match_dup 1) (const_int 80))) --+ (match_operand:SI 22 "register_operand" "")) --+ (set (mem:SI (plus:SI (match_dup 1) (const_int 84))) --+ (match_operand:SI 23 "register_operand" "")) --+])] --+ "(XVECLEN (operands[0], 0) == 22)" --+ "smw.bi\t%2, [%1], %23, 0x0" --+ [(set_attr "type" "store_multiple") --+ (set_attr "combo" "22") --+ (set_attr "length" "4")] --+) --+ --+(define_insn "*stmsi21" --+ [(match_parallel 0 "nds32_store_multiple_operation" --+ [(set (mem:SI (match_operand:SI 1 "register_operand" "r")) --+ (match_operand:SI 2 "register_operand" "")) --+ (set (mem:SI (plus:SI (match_dup 1) (const_int 4))) --+ (match_operand:SI 3 "register_operand" "")) --+ (set (mem:SI (plus:SI (match_dup 1) (const_int 8))) --+ (match_operand:SI 4 "register_operand" "")) --+ (set (mem:SI (plus:SI (match_dup 1) (const_int 12))) --+ (match_operand:SI 5 "register_operand" "")) --+ (set (mem:SI (plus:SI (match_dup 1) (const_int 16))) --+ (match_operand:SI 6 "register_operand" "")) --+ (set (mem:SI (plus:SI (match_dup 1) (const_int 20))) --+ (match_operand:SI 7 "register_operand" "")) --+ (set (mem:SI (plus:SI (match_dup 1) (const_int 24))) --+ (match_operand:SI 8 "register_operand" "")) --+ (set (mem:SI (plus:SI (match_dup 1) (const_int 28))) --+ (match_operand:SI 9 "register_operand" "")) --+ (set (mem:SI (plus:SI (match_dup 1) (const_int 32))) --+ (match_operand:SI 10 "register_operand" "")) --+ (set (mem:SI (plus:SI (match_dup 1) (const_int 36))) --+ (match_operand:SI 11 "register_operand" "")) --+ (set (mem:SI (plus:SI (match_dup 1) (const_int 40))) --+ (match_operand:SI 12 "register_operand" "")) --+ (set (mem:SI (plus:SI (match_dup 1) (const_int 44))) --+ (match_operand:SI 13 "register_operand" "")) --+ (set (mem:SI (plus:SI (match_dup 1) (const_int 48))) --+ (match_operand:SI 14 "register_operand" "")) --+ (set (mem:SI (plus:SI (match_dup 1) (const_int 52))) --+ (match_operand:SI 15 "register_operand" "")) --+ (set (mem:SI (plus:SI (match_dup 1) (const_int 56))) --+ (match_operand:SI 16 "register_operand" "")) --+ (set (mem:SI (plus:SI (match_dup 1) (const_int 60))) --+ (match_operand:SI 17 "register_operand" "")) --+ (set (mem:SI (plus:SI (match_dup 1) (const_int 64))) --+ (match_operand:SI 18 "register_operand" "")) --+ (set (mem:SI (plus:SI (match_dup 1) (const_int 68))) --+ (match_operand:SI 19 "register_operand" "")) --+ (set (mem:SI (plus:SI (match_dup 1) (const_int 72))) --+ (match_operand:SI 20 "register_operand" "")) --+ (set (mem:SI (plus:SI (match_dup 1) (const_int 76))) --+ (match_operand:SI 21 "register_operand" "")) --+ (set (mem:SI (plus:SI (match_dup 1) (const_int 80))) --+ (match_operand:SI 22 "register_operand" "")) --+])] --+ "(XVECLEN (operands[0], 0) == 21)" --+ "smw.bi\t%2, [%1], %22, 0x0" --+ [(set_attr "type" "store_multiple") --+ (set_attr "combo" "21") --+ (set_attr "length" "4")] --+) --+ --+(define_insn "*stmsi20" --+ [(match_parallel 0 "nds32_store_multiple_operation" --+ [(set (mem:SI (match_operand:SI 1 "register_operand" "r")) --+ (match_operand:SI 2 "register_operand" "")) --+ (set (mem:SI (plus:SI (match_dup 1) (const_int 4))) --+ (match_operand:SI 3 "register_operand" "")) --+ (set (mem:SI (plus:SI (match_dup 1) (const_int 8))) --+ (match_operand:SI 4 "register_operand" "")) --+ (set (mem:SI (plus:SI (match_dup 1) (const_int 12))) --+ (match_operand:SI 5 "register_operand" "")) --+ (set (mem:SI (plus:SI (match_dup 1) (const_int 16))) --+ (match_operand:SI 6 "register_operand" "")) --+ (set (mem:SI (plus:SI (match_dup 1) (const_int 20))) --+ (match_operand:SI 7 "register_operand" "")) --+ (set (mem:SI (plus:SI (match_dup 1) (const_int 24))) --+ (match_operand:SI 8 "register_operand" "")) --+ (set (mem:SI (plus:SI (match_dup 1) (const_int 28))) --+ (match_operand:SI 9 "register_operand" "")) --+ (set (mem:SI (plus:SI (match_dup 1) (const_int 32))) --+ (match_operand:SI 10 "register_operand" "")) --+ (set (mem:SI (plus:SI (match_dup 1) (const_int 36))) --+ (match_operand:SI 11 "register_operand" "")) --+ (set (mem:SI (plus:SI (match_dup 1) (const_int 40))) --+ (match_operand:SI 12 "register_operand" "")) --+ (set (mem:SI (plus:SI (match_dup 1) (const_int 44))) --+ (match_operand:SI 13 "register_operand" "")) --+ (set (mem:SI (plus:SI (match_dup 1) (const_int 48))) --+ (match_operand:SI 14 "register_operand" "")) --+ (set (mem:SI (plus:SI (match_dup 1) (const_int 52))) --+ (match_operand:SI 15 "register_operand" "")) --+ (set (mem:SI (plus:SI (match_dup 1) (const_int 56))) --+ (match_operand:SI 16 "register_operand" "")) --+ (set (mem:SI (plus:SI (match_dup 1) (const_int 60))) --+ (match_operand:SI 17 "register_operand" "")) --+ (set (mem:SI (plus:SI (match_dup 1) (const_int 64))) --+ (match_operand:SI 18 "register_operand" "")) --+ (set (mem:SI (plus:SI (match_dup 1) (const_int 68))) --+ (match_operand:SI 19 "register_operand" "")) --+ (set (mem:SI (plus:SI (match_dup 1) (const_int 72))) --+ (match_operand:SI 20 "register_operand" "")) --+ (set (mem:SI (plus:SI (match_dup 1) (const_int 76))) --+ (match_operand:SI 21 "register_operand" ""))])] --+ "(XVECLEN (operands[0], 0) == 20)" --+ "smw.bi\t%2, [%1], %21, 0x0" --+ [(set_attr "type" "store_multiple") --+ (set_attr "combo" "20") --+ (set_attr "length" "4")] --+) --+ --+(define_insn "*stmsi19" --+ [(match_parallel 0 "nds32_store_multiple_operation" --+ [(set (mem:SI (match_operand:SI 1 "register_operand" "r")) --+ (match_operand:SI 2 "register_operand" "")) --+ (set (mem:SI (plus:SI (match_dup 1) (const_int 4))) --+ (match_operand:SI 3 "register_operand" "")) --+ (set (mem:SI (plus:SI (match_dup 1) (const_int 8))) --+ (match_operand:SI 4 "register_operand" "")) --+ (set (mem:SI (plus:SI (match_dup 1) (const_int 12))) --+ (match_operand:SI 5 "register_operand" "")) --+ (set (mem:SI (plus:SI (match_dup 1) (const_int 16))) --+ (match_operand:SI 6 "register_operand" "")) --+ (set (mem:SI (plus:SI (match_dup 1) (const_int 20))) --+ (match_operand:SI 7 "register_operand" "")) --+ (set (mem:SI (plus:SI (match_dup 1) (const_int 24))) --+ (match_operand:SI 8 "register_operand" "")) --+ (set (mem:SI (plus:SI (match_dup 1) (const_int 28))) --+ (match_operand:SI 9 "register_operand" "")) --+ (set (mem:SI (plus:SI (match_dup 1) (const_int 32))) --+ (match_operand:SI 10 "register_operand" "")) --+ (set (mem:SI (plus:SI (match_dup 1) (const_int 36))) --+ (match_operand:SI 11 "register_operand" "")) --+ (set (mem:SI (plus:SI (match_dup 1) (const_int 40))) --+ (match_operand:SI 12 "register_operand" "")) --+ (set (mem:SI (plus:SI (match_dup 1) (const_int 44))) --+ (match_operand:SI 13 "register_operand" "")) --+ (set (mem:SI (plus:SI (match_dup 1) (const_int 48))) --+ (match_operand:SI 14 "register_operand" "")) --+ (set (mem:SI (plus:SI (match_dup 1) (const_int 52))) --+ (match_operand:SI 15 "register_operand" "")) --+ (set (mem:SI (plus:SI (match_dup 1) (const_int 56))) --+ (match_operand:SI 16 "register_operand" "")) --+ (set (mem:SI (plus:SI (match_dup 1) (const_int 60))) --+ (match_operand:SI 17 "register_operand" "")) --+ (set (mem:SI (plus:SI (match_dup 1) (const_int 64))) --+ (match_operand:SI 18 "register_operand" "")) --+ (set (mem:SI (plus:SI (match_dup 1) (const_int 68))) --+ (match_operand:SI 19 "register_operand" "")) --+ (set (mem:SI (plus:SI (match_dup 1) (const_int 72))) --+ (match_operand:SI 20 "register_operand" ""))])] --+ "(XVECLEN (operands[0], 0) == 19)" --+ "smw.bi\t%2, [%1], %20, 0x0" --+ [(set_attr "type" "store_multiple") --+ (set_attr "combo" "19") --+ (set_attr "length" "4")] --+) --+ --+(define_insn "*stmsi18" --+ [(match_parallel 0 "nds32_store_multiple_operation" --+ [(set (mem:SI (match_operand:SI 1 "register_operand" "r")) --+ (match_operand:SI 2 "register_operand" "")) --+ (set (mem:SI (plus:SI (match_dup 1) (const_int 4))) --+ (match_operand:SI 3 "register_operand" "")) --+ (set (mem:SI (plus:SI (match_dup 1) (const_int 8))) --+ (match_operand:SI 4 "register_operand" "")) --+ (set (mem:SI (plus:SI (match_dup 1) (const_int 12))) --+ (match_operand:SI 5 "register_operand" "")) --+ (set (mem:SI (plus:SI (match_dup 1) (const_int 16))) --+ (match_operand:SI 6 "register_operand" "")) --+ (set (mem:SI (plus:SI (match_dup 1) (const_int 20))) --+ (match_operand:SI 7 "register_operand" "")) --+ (set (mem:SI (plus:SI (match_dup 1) (const_int 24))) --+ (match_operand:SI 8 "register_operand" "")) --+ (set (mem:SI (plus:SI (match_dup 1) (const_int 28))) --+ (match_operand:SI 9 "register_operand" "")) --+ (set (mem:SI (plus:SI (match_dup 1) (const_int 32))) --+ (match_operand:SI 10 "register_operand" "")) --+ (set (mem:SI (plus:SI (match_dup 1) (const_int 36))) --+ (match_operand:SI 11 "register_operand" "")) --+ (set (mem:SI (plus:SI (match_dup 1) (const_int 40))) --+ (match_operand:SI 12 "register_operand" "")) --+ (set (mem:SI (plus:SI (match_dup 1) (const_int 44))) --+ (match_operand:SI 13 "register_operand" "")) --+ (set (mem:SI (plus:SI (match_dup 1) (const_int 48))) --+ (match_operand:SI 14 "register_operand" "")) --+ (set (mem:SI (plus:SI (match_dup 1) (const_int 52))) --+ (match_operand:SI 15 "register_operand" "")) --+ (set (mem:SI (plus:SI (match_dup 1) (const_int 56))) --+ (match_operand:SI 16 "register_operand" "")) --+ (set (mem:SI (plus:SI (match_dup 1) (const_int 60))) --+ (match_operand:SI 17 "register_operand" "")) --+ (set (mem:SI (plus:SI (match_dup 1) (const_int 64))) --+ (match_operand:SI 18 "register_operand" "")) --+ (set (mem:SI (plus:SI (match_dup 1) (const_int 68))) --+ (match_operand:SI 19 "register_operand" ""))])] --+ "(XVECLEN (operands[0], 0) == 18)" --+ "smw.bi\t%2, [%1], %19, 0x0" --+ [(set_attr "type" "store_multiple") --+ (set_attr "combo" "18") --+ (set_attr "length" "4")] -- ) -- ---(define_insn "*lmwsi4" --- [(match_parallel 0 "nds32_load_multiple_operation" --- [(set (match_operand:SI 2 "register_operand" "") --- (mem:SI (match_operand:SI 1 "register_operand" "r"))) --- (set (match_operand:SI 3 "register_operand" "") --- (mem:SI (plus:SI (match_dup 1) (const_int 4)))) --- (set (match_operand:SI 4 "register_operand" "") --- (mem:SI (plus:SI (match_dup 1) (const_int 8)))) --- (set (match_operand:SI 5 "register_operand" "") --- (mem:SI (plus:SI (match_dup 1) (const_int 12))))])] --- "(XVECLEN (operands[0], 0) == 4)" --- "lmw.bi\t%2, [%1], %5, 0x0" --- [(set_attr "type" "load") --- (set_attr "length" "4")] --+(define_insn "*stmsi17" --+ [(match_parallel 0 "nds32_store_multiple_operation" --+ [(set (mem:SI (match_operand:SI 1 "register_operand" "r")) --+ (match_operand:SI 2 "register_operand" "")) --+ (set (mem:SI (plus:SI (match_dup 1) (const_int 4))) --+ (match_operand:SI 3 "register_operand" "")) --+ (set (mem:SI (plus:SI (match_dup 1) (const_int 8))) --+ (match_operand:SI 4 "register_operand" "")) --+ (set (mem:SI (plus:SI (match_dup 1) (const_int 12))) --+ (match_operand:SI 5 "register_operand" "")) --+ (set (mem:SI (plus:SI (match_dup 1) (const_int 16))) --+ (match_operand:SI 6 "register_operand" "")) --+ (set (mem:SI (plus:SI (match_dup 1) (const_int 20))) --+ (match_operand:SI 7 "register_operand" "")) --+ (set (mem:SI (plus:SI (match_dup 1) (const_int 24))) --+ (match_operand:SI 8 "register_operand" "")) --+ (set (mem:SI (plus:SI (match_dup 1) (const_int 28))) --+ (match_operand:SI 9 "register_operand" "")) --+ (set (mem:SI (plus:SI (match_dup 1) (const_int 32))) --+ (match_operand:SI 10 "register_operand" "")) --+ (set (mem:SI (plus:SI (match_dup 1) (const_int 36))) --+ (match_operand:SI 11 "register_operand" "")) --+ (set (mem:SI (plus:SI (match_dup 1) (const_int 40))) --+ (match_operand:SI 12 "register_operand" "")) --+ (set (mem:SI (plus:SI (match_dup 1) (const_int 44))) --+ (match_operand:SI 13 "register_operand" "")) --+ (set (mem:SI (plus:SI (match_dup 1) (const_int 48))) --+ (match_operand:SI 14 "register_operand" "")) --+ (set (mem:SI (plus:SI (match_dup 1) (const_int 52))) --+ (match_operand:SI 15 "register_operand" "")) --+ (set (mem:SI (plus:SI (match_dup 1) (const_int 56))) --+ (match_operand:SI 16 "register_operand" "")) --+ (set (mem:SI (plus:SI (match_dup 1) (const_int 60))) --+ (match_operand:SI 17 "register_operand" "")) --+ (set (mem:SI (plus:SI (match_dup 1) (const_int 64))) --+ (match_operand:SI 18 "register_operand" ""))])] --+ "(XVECLEN (operands[0], 0) == 17)" --+ "smw.bi\t%2, [%1], %18, 0x0" --+ [(set_attr "type" "store_multiple") --+ (set_attr "combo" "17") --+ (set_attr "length" "4")] -- ) -- ---(define_insn "*lmwsi3" --- [(match_parallel 0 "nds32_load_multiple_operation" --- [(set (match_operand:SI 2 "register_operand" "") --- (mem:SI (match_operand:SI 1 "register_operand" "r"))) --- (set (match_operand:SI 3 "register_operand" "") --- (mem:SI (plus:SI (match_dup 1) (const_int 4)))) --- (set (match_operand:SI 4 "register_operand" "") --- (mem:SI (plus:SI (match_dup 1) (const_int 8))))])] --- "(XVECLEN (operands[0], 0) == 3)" --- "lmw.bi\t%2, [%1], %4, 0x0" --- [(set_attr "type" "load") --- (set_attr "length" "4")] --+(define_insn "*stmsi16" --+ [(match_parallel 0 "nds32_store_multiple_operation" --+ [(set (mem:SI (match_operand:SI 1 "register_operand" "r")) --+ (match_operand:SI 2 "register_operand" "")) --+ (set (mem:SI (plus:SI (match_dup 1) (const_int 4))) --+ (match_operand:SI 3 "register_operand" "")) --+ (set (mem:SI (plus:SI (match_dup 1) (const_int 8))) --+ (match_operand:SI 4 "register_operand" "")) --+ (set (mem:SI (plus:SI (match_dup 1) (const_int 12))) --+ (match_operand:SI 5 "register_operand" "")) --+ (set (mem:SI (plus:SI (match_dup 1) (const_int 16))) --+ (match_operand:SI 6 "register_operand" "")) --+ (set (mem:SI (plus:SI (match_dup 1) (const_int 20))) --+ (match_operand:SI 7 "register_operand" "")) --+ (set (mem:SI (plus:SI (match_dup 1) (const_int 24))) --+ (match_operand:SI 8 "register_operand" "")) --+ (set (mem:SI (plus:SI (match_dup 1) (const_int 28))) --+ (match_operand:SI 9 "register_operand" "")) --+ (set (mem:SI (plus:SI (match_dup 1) (const_int 32))) --+ (match_operand:SI 10 "register_operand" "")) --+ (set (mem:SI (plus:SI (match_dup 1) (const_int 36))) --+ (match_operand:SI 11 "register_operand" "")) --+ (set (mem:SI (plus:SI (match_dup 1) (const_int 40))) --+ (match_operand:SI 12 "register_operand" "")) --+ (set (mem:SI (plus:SI (match_dup 1) (const_int 44))) --+ (match_operand:SI 13 "register_operand" "")) --+ (set (mem:SI (plus:SI (match_dup 1) (const_int 48))) --+ (match_operand:SI 14 "register_operand" "")) --+ (set (mem:SI (plus:SI (match_dup 1) (const_int 52))) --+ (match_operand:SI 15 "register_operand" "")) --+ (set (mem:SI (plus:SI (match_dup 1) (const_int 56))) --+ (match_operand:SI 16 "register_operand" "")) --+ (set (mem:SI (plus:SI (match_dup 1) (const_int 60))) --+ (match_operand:SI 17 "register_operand" ""))])] --+ "(XVECLEN (operands[0], 0) == 16)" --+ "smw.bi\t%2, [%1], %17, 0x0" --+ [(set_attr "type" "store_multiple") --+ (set_attr "combo" "16") --+ (set_attr "length" "4")] -- ) -- ---(define_insn "*lmwsi2" --- [(match_parallel 0 "nds32_load_multiple_operation" --- [(set (match_operand:SI 2 "register_operand" "") --- (mem:SI (match_operand:SI 1 "register_operand" "r"))) --- (set (match_operand:SI 3 "register_operand" "") --- (mem:SI (plus:SI (match_dup 1) (const_int 4))))])] --- "(XVECLEN (operands[0], 0) == 2)" --- "lmw.bi\t%2, [%1], %3, 0x0" --- [(set_attr "type" "load") --- (set_attr "length" "4")] --+(define_insn "*stmsi15" --+ [(match_parallel 0 "nds32_store_multiple_operation" --+ [(set (mem:SI (match_operand:SI 1 "register_operand" "r")) --+ (match_operand:SI 2 "register_operand" "")) --+ (set (mem:SI (plus:SI (match_dup 1) (const_int 4))) --+ (match_operand:SI 3 "register_operand" "")) --+ (set (mem:SI (plus:SI (match_dup 1) (const_int 8))) --+ (match_operand:SI 4 "register_operand" "")) --+ (set (mem:SI (plus:SI (match_dup 1) (const_int 12))) --+ (match_operand:SI 5 "register_operand" "")) --+ (set (mem:SI (plus:SI (match_dup 1) (const_int 16))) --+ (match_operand:SI 6 "register_operand" "")) --+ (set (mem:SI (plus:SI (match_dup 1) (const_int 20))) --+ (match_operand:SI 7 "register_operand" "")) --+ (set (mem:SI (plus:SI (match_dup 1) (const_int 24))) --+ (match_operand:SI 8 "register_operand" "")) --+ (set (mem:SI (plus:SI (match_dup 1) (const_int 28))) --+ (match_operand:SI 9 "register_operand" "")) --+ (set (mem:SI (plus:SI (match_dup 1) (const_int 32))) --+ (match_operand:SI 10 "register_operand" "")) --+ (set (mem:SI (plus:SI (match_dup 1) (const_int 36))) --+ (match_operand:SI 11 "register_operand" "")) --+ (set (mem:SI (plus:SI (match_dup 1) (const_int 40))) --+ (match_operand:SI 12 "register_operand" "")) --+ (set (mem:SI (plus:SI (match_dup 1) (const_int 44))) --+ (match_operand:SI 13 "register_operand" "")) --+ (set (mem:SI (plus:SI (match_dup 1) (const_int 48))) --+ (match_operand:SI 14 "register_operand" "")) --+ (set (mem:SI (plus:SI (match_dup 1) (const_int 52))) --+ (match_operand:SI 15 "register_operand" "")) --+ (set (mem:SI (plus:SI (match_dup 1) (const_int 56))) --+ (match_operand:SI 16 "register_operand" ""))])] --+ "(XVECLEN (operands[0], 0) == 15)" --+ "smw.bi\t%2, [%1], %16, 0x0" --+ [(set_attr "type" "store_multiple") --+ (set_attr "combo" "15") --+ (set_attr "length" "4")] -- ) -- --+(define_insn "*stmsi14" --+ [(match_parallel 0 "nds32_store_multiple_operation" --+ [(set (mem:SI (match_operand:SI 1 "register_operand" "r")) --+ (match_operand:SI 2 "register_operand" "")) --+ (set (mem:SI (plus:SI (match_dup 1) (const_int 4))) --+ (match_operand:SI 3 "register_operand" "")) --+ (set (mem:SI (plus:SI (match_dup 1) (const_int 8))) --+ (match_operand:SI 4 "register_operand" "")) --+ (set (mem:SI (plus:SI (match_dup 1) (const_int 12))) --+ (match_operand:SI 5 "register_operand" "")) --+ (set (mem:SI (plus:SI (match_dup 1) (const_int 16))) --+ (match_operand:SI 6 "register_operand" "")) --+ (set (mem:SI (plus:SI (match_dup 1) (const_int 20))) --+ (match_operand:SI 7 "register_operand" "")) --+ (set (mem:SI (plus:SI (match_dup 1) (const_int 24))) --+ (match_operand:SI 8 "register_operand" "")) --+ (set (mem:SI (plus:SI (match_dup 1) (const_int 28))) --+ (match_operand:SI 9 "register_operand" "")) --+ (set (mem:SI (plus:SI (match_dup 1) (const_int 32))) --+ (match_operand:SI 10 "register_operand" "")) --+ (set (mem:SI (plus:SI (match_dup 1) (const_int 36))) --+ (match_operand:SI 11 "register_operand" "")) --+ (set (mem:SI (plus:SI (match_dup 1) (const_int 40))) --+ (match_operand:SI 12 "register_operand" "")) --+ (set (mem:SI (plus:SI (match_dup 1) (const_int 44))) --+ (match_operand:SI 13 "register_operand" "")) --+ (set (mem:SI (plus:SI (match_dup 1) (const_int 48))) --+ (match_operand:SI 14 "register_operand" "")) --+ (set (mem:SI (plus:SI (match_dup 1) (const_int 52))) --+ (match_operand:SI 15 "register_operand" ""))])] --+ "(XVECLEN (operands[0], 0) == 14)" --+ "smw.bi\t%2, [%1], %15, 0x0" --+ [(set_attr "type" "store_multiple") --+ (set_attr "combo" "14") --+ (set_attr "length" "4")] --+) -- ---;; Store Multiple Insns. ---;; ---;; operands[0] is the first memory location. ---;; opernads[1] is the first of the consecutive registers. ---;; operands[2] is the number of consecutive registers. --- ---(define_expand "store_multiple" --- [(match_par_dup 3 [(set (match_operand:SI 0 "" "") --- (match_operand:SI 1 "" "")) --- (use (match_operand:SI 2 "" ""))])] --- "" ---{ --- int maximum; --+(define_insn "*stmsi13" --+ [(match_parallel 0 "nds32_store_multiple_operation" --+ [(set (mem:SI (match_operand:SI 1 "register_operand" "r")) --+ (match_operand:SI 2 "register_operand" "")) --+ (set (mem:SI (plus:SI (match_dup 1) (const_int 4))) --+ (match_operand:SI 3 "register_operand" "")) --+ (set (mem:SI (plus:SI (match_dup 1) (const_int 8))) --+ (match_operand:SI 4 "register_operand" "")) --+ (set (mem:SI (plus:SI (match_dup 1) (const_int 12))) --+ (match_operand:SI 5 "register_operand" "")) --+ (set (mem:SI (plus:SI (match_dup 1) (const_int 16))) --+ (match_operand:SI 6 "register_operand" "")) --+ (set (mem:SI (plus:SI (match_dup 1) (const_int 20))) --+ (match_operand:SI 7 "register_operand" "")) --+ (set (mem:SI (plus:SI (match_dup 1) (const_int 24))) --+ (match_operand:SI 8 "register_operand" "")) --+ (set (mem:SI (plus:SI (match_dup 1) (const_int 28))) --+ (match_operand:SI 9 "register_operand" "")) --+ (set (mem:SI (plus:SI (match_dup 1) (const_int 32))) --+ (match_operand:SI 10 "register_operand" "")) --+ (set (mem:SI (plus:SI (match_dup 1) (const_int 36))) --+ (match_operand:SI 11 "register_operand" "")) --+ (set (mem:SI (plus:SI (match_dup 1) (const_int 40))) --+ (match_operand:SI 12 "register_operand" "")) --+ (set (mem:SI (plus:SI (match_dup 1) (const_int 44))) --+ (match_operand:SI 13 "register_operand" "")) --+ (set (mem:SI (plus:SI (match_dup 1) (const_int 48))) --+ (match_operand:SI 14 "register_operand" ""))])] --+ "(XVECLEN (operands[0], 0) == 13)" --+ "smw.bi\t%2, [%1], %14, 0x0" --+ [(set_attr "type" "store_multiple") --+ (set_attr "combo" "13") --+ (set_attr "length" "4")] --+) -- --- /* Because reduced-set regsiters has few registers --- (r0~r5, r6~10, r15, r28~r31, where 'r15' and 'r28~r31' cannot --- be used for register allocation), --- using 8 registers for store_multiple may easily consume all of them. --- It makes register allocation/spilling hard to work. --- So we only allow maximum=4 registers for store_multiple --- under reduced-set registers. */ --- if (TARGET_REDUCED_REGS) --- maximum = 4; --- else --- maximum = 8; --+(define_insn "*stmsi12" --+ [(match_parallel 0 "nds32_store_multiple_operation" --+ [(set (mem:SI (match_operand:SI 1 "register_operand" "r")) --+ (match_operand:SI 2 "register_operand" "")) --+ (set (mem:SI (plus:SI (match_dup 1) (const_int 4))) --+ (match_operand:SI 3 "register_operand" "")) --+ (set (mem:SI (plus:SI (match_dup 1) (const_int 8))) --+ (match_operand:SI 4 "register_operand" "")) --+ (set (mem:SI (plus:SI (match_dup 1) (const_int 12))) --+ (match_operand:SI 5 "register_operand" "")) --+ (set (mem:SI (plus:SI (match_dup 1) (const_int 16))) --+ (match_operand:SI 6 "register_operand" "")) --+ (set (mem:SI (plus:SI (match_dup 1) (const_int 20))) --+ (match_operand:SI 7 "register_operand" "")) --+ (set (mem:SI (plus:SI (match_dup 1) (const_int 24))) --+ (match_operand:SI 8 "register_operand" "")) --+ (set (mem:SI (plus:SI (match_dup 1) (const_int 28))) --+ (match_operand:SI 9 "register_operand" "")) --+ (set (mem:SI (plus:SI (match_dup 1) (const_int 32))) --+ (match_operand:SI 10 "register_operand" "")) --+ (set (mem:SI (plus:SI (match_dup 1) (const_int 36))) --+ (match_operand:SI 11 "register_operand" "")) --+ (set (mem:SI (plus:SI (match_dup 1) (const_int 40))) --+ (match_operand:SI 12 "register_operand" "")) --+ (set (mem:SI (plus:SI (match_dup 1) (const_int 44))) --+ (match_operand:SI 13 "register_operand" ""))])] --+ "(XVECLEN (operands[0], 0) == 12)" --+ "smw.bi\t%2, [%1], %13, 0x0" --+ [(set_attr "type" "store_multiple") --+ (set_attr "combo" "12") --+ (set_attr "length" "4")] --+) -- --- /* Here are the conditions that must be all passed, --- otherwise we have to FAIL this rtx generation: --- 1. The number of consecutive registers must be integer. --- 2. Maximum 4 or 8 registers for smw.bi instruction --- (based on this nds32-multiple.md design). --- 3. Minimum 2 registers for smw.bi instruction --- (based on this nds32-multiple.md design). --- 4. operands[0] must be memory for sure. --- 5. operands[1] must be register for sure. --- 6. Do not cross $r15 register because it is not allocatable. */ --- if (GET_CODE (operands[2]) != CONST_INT --- || INTVAL (operands[2]) > maximum --- || INTVAL (operands[2]) < 2 --- || GET_CODE (operands[0]) != MEM --- || GET_CODE (operands[1]) != REG --- || REGNO (operands[1]) + INTVAL (operands[2]) > TA_REGNUM) --- FAIL; --+(define_insn "*stmsi11" --+ [(match_parallel 0 "nds32_store_multiple_operation" --+ [(set (mem:SI (match_operand:SI 1 "register_operand" "r")) --+ (match_operand:SI 2 "register_operand" "")) --+ (set (mem:SI (plus:SI (match_dup 1) (const_int 4))) --+ (match_operand:SI 3 "register_operand" "")) --+ (set (mem:SI (plus:SI (match_dup 1) (const_int 8))) --+ (match_operand:SI 4 "register_operand" "")) --+ (set (mem:SI (plus:SI (match_dup 1) (const_int 12))) --+ (match_operand:SI 5 "register_operand" "")) --+ (set (mem:SI (plus:SI (match_dup 1) (const_int 16))) --+ (match_operand:SI 6 "register_operand" "")) --+ (set (mem:SI (plus:SI (match_dup 1) (const_int 20))) --+ (match_operand:SI 7 "register_operand" "")) --+ (set (mem:SI (plus:SI (match_dup 1) (const_int 24))) --+ (match_operand:SI 8 "register_operand" "")) --+ (set (mem:SI (plus:SI (match_dup 1) (const_int 28))) --+ (match_operand:SI 9 "register_operand" "")) --+ (set (mem:SI (plus:SI (match_dup 1) (const_int 32))) --+ (match_operand:SI 10 "register_operand" "")) --+ (set (mem:SI (plus:SI (match_dup 1) (const_int 36))) --+ (match_operand:SI 11 "register_operand" "")) --+ (set (mem:SI (plus:SI (match_dup 1) (const_int 40))) --+ (match_operand:SI 12 "register_operand" ""))])] --+ "(XVECLEN (operands[0], 0) == 11)" --+ "smw.bi\t%2, [%1], %12, 0x0" --+ [(set_attr "type" "store_multiple") --+ (set_attr "combo" "11") --+ (set_attr "length" "4")] --+) -- --- /* For (mem addr), we force_reg on addr here, --- so that nds32_expand_store_multiple can easily use it. */ --- operands[3] = nds32_expand_store_multiple (REGNO (operands[1]), --- INTVAL (operands[2]), --- force_reg (SImode, --- XEXP (operands[0], 0)), --- operands[0]); ---}) --+(define_insn "*stmsi10" --+ [(match_parallel 0 "nds32_store_multiple_operation" --+ [(set (mem:SI (match_operand:SI 1 "register_operand" "r")) --+ (match_operand:SI 2 "register_operand" "")) --+ (set (mem:SI (plus:SI (match_dup 1) (const_int 4))) --+ (match_operand:SI 3 "register_operand" "")) --+ (set (mem:SI (plus:SI (match_dup 1) (const_int 8))) --+ (match_operand:SI 4 "register_operand" "")) --+ (set (mem:SI (plus:SI (match_dup 1) (const_int 12))) --+ (match_operand:SI 5 "register_operand" "")) --+ (set (mem:SI (plus:SI (match_dup 1) (const_int 16))) --+ (match_operand:SI 6 "register_operand" "")) --+ (set (mem:SI (plus:SI (match_dup 1) (const_int 20))) --+ (match_operand:SI 7 "register_operand" "")) --+ (set (mem:SI (plus:SI (match_dup 1) (const_int 24))) --+ (match_operand:SI 8 "register_operand" "")) --+ (set (mem:SI (plus:SI (match_dup 1) (const_int 28))) --+ (match_operand:SI 9 "register_operand" "")) --+ (set (mem:SI (plus:SI (match_dup 1) (const_int 32))) --+ (match_operand:SI 10 "register_operand" "")) --+ (set (mem:SI (plus:SI (match_dup 1) (const_int 36))) --+ (match_operand:SI 11 "register_operand" ""))])] --+ "(XVECLEN (operands[0], 0) == 10)" --+ "smw.bi\t%2, [%1], %11, 0x0" --+ [(set_attr "type" "store_multiple") --+ (set_attr "combo" "10") --+ (set_attr "length" "4")] --+) -- ---;; Ordinary Store Multiple. --+(define_insn "*stmsi9" --+ [(match_parallel 0 "nds32_store_multiple_operation" --+ [(set (mem:SI (match_operand:SI 1 "register_operand" "r")) --+ (match_operand:SI 2 "register_operand" "")) --+ (set (mem:SI (plus:SI (match_dup 1) (const_int 4))) --+ (match_operand:SI 3 "register_operand" "")) --+ (set (mem:SI (plus:SI (match_dup 1) (const_int 8))) --+ (match_operand:SI 4 "register_operand" "")) --+ (set (mem:SI (plus:SI (match_dup 1) (const_int 12))) --+ (match_operand:SI 5 "register_operand" "")) --+ (set (mem:SI (plus:SI (match_dup 1) (const_int 16))) --+ (match_operand:SI 6 "register_operand" "")) --+ (set (mem:SI (plus:SI (match_dup 1) (const_int 20))) --+ (match_operand:SI 7 "register_operand" "")) --+ (set (mem:SI (plus:SI (match_dup 1) (const_int 24))) --+ (match_operand:SI 8 "register_operand" "")) --+ (set (mem:SI (plus:SI (match_dup 1) (const_int 28))) --+ (match_operand:SI 9 "register_operand" "")) --+ (set (mem:SI (plus:SI (match_dup 1) (const_int 32))) --+ (match_operand:SI 10 "register_operand" ""))])] --+ "(XVECLEN (operands[0], 0) == 9)" --+ "smw.bi\t%2, [%1], %10, 0x0" --+ [(set_attr "type" "store_multiple") --+ (set_attr "combo" "9") --+ (set_attr "length" "4")] --+) -- -- (define_insn "*stmsi8" -- [(match_parallel 0 "nds32_store_multiple_operation" --@@ -276,8 +3634,9 @@ -- (match_operand:SI 9 "register_operand" ""))])] -- "(XVECLEN (operands[0], 0) == 8)" -- "smw.bi\t%2, [%1], %9, 0x0" --- [(set_attr "type" "store") --- (set_attr "length" "4")] --+ [(set_attr "type" "store_multiple") --+ (set_attr "combo" "8") --+ (set_attr "length" "4")] -- ) -- -- (define_insn "*stmsi7" --@@ -298,8 +3657,9 @@ -- (match_operand:SI 8 "register_operand" ""))])] -- "(XVECLEN (operands[0], 0) == 7)" -- "smw.bi\t%2, [%1], %8, 0x0" --- [(set_attr "type" "store") --- (set_attr "length" "4")] --+ [(set_attr "type" "store_multiple") --+ (set_attr "combo" "7") --+ (set_attr "length" "4")] -- ) -- -- (define_insn "*stmsi6" --@@ -318,8 +3678,9 @@ -- (match_operand:SI 7 "register_operand" ""))])] -- "(XVECLEN (operands[0], 0) == 6)" -- "smw.bi\t%2, [%1], %7, 0x0" --- [(set_attr "type" "store") --- (set_attr "length" "4")] --+ [(set_attr "type" "store_multiple") --+ (set_attr "combo" "6") --+ (set_attr "length" "4")] -- ) -- -- (define_insn "*stmsi5" --@@ -336,8 +3697,9 @@ -- (match_operand:SI 6 "register_operand" ""))])] -- "(XVECLEN (operands[0], 0) == 5)" -- "smw.bi\t%2, [%1], %6, 0x0" --- [(set_attr "type" "store") --- (set_attr "length" "4")] --+ [(set_attr "type" "store_multiple") --+ (set_attr "combo" "5") --+ (set_attr "length" "4")] -- ) -- -- (define_insn "*stmsi4" --@@ -352,8 +3714,9 @@ -- (match_operand:SI 5 "register_operand" ""))])] -- "(XVECLEN (operands[0], 0) == 4)" -- "smw.bi\t%2, [%1], %5, 0x0" --- [(set_attr "type" "store") --- (set_attr "length" "4")] --+ [(set_attr "type" "store_multiple") --+ (set_attr "combo" "4") --+ (set_attr "length" "4")] -- ) -- -- (define_insn "*stmsi3" --@@ -366,8 +3729,9 @@ -- (match_operand:SI 4 "register_operand" ""))])] -- "(XVECLEN (operands[0], 0) == 3)" -- "smw.bi\t%2, [%1], %4, 0x0" --- [(set_attr "type" "store") --- (set_attr "length" "4")] --+ [(set_attr "type" "store_multiple") --+ (set_attr "combo" "3") --+ (set_attr "length" "4")] -- ) -- -- (define_insn "*stmsi2" --@@ -378,8 +3742,9 @@ -- (match_operand:SI 3 "register_operand" ""))])] -- "(XVECLEN (operands[0], 0) == 2)" -- "smw.bi\t%2, [%1], %3, 0x0" --- [(set_attr "type" "store") --- (set_attr "length" "4")] --+ [(set_attr "type" "store_multiple") --+ (set_attr "combo" "2") --+ (set_attr "length" "4")] -- ) -- -- ;; Move a block of memory if it is word aligned and MORE than 2 words long. --@@ -391,14 +3756,14 @@ -- ;; operands[2] is the number of bytes to move. -- ;; operands[3] is the known shared alignment. -- ---(define_expand "movmemqi" --+(define_expand "movmemsi" -- [(match_operand:BLK 0 "general_operand" "") -- (match_operand:BLK 1 "general_operand" "") --- (match_operand:SI 2 "const_int_operand" "") --+ (match_operand:SI 2 "nds32_reg_constant_operand" "") -- (match_operand:SI 3 "const_int_operand" "")] -- "" -- { --- if (nds32_expand_movmemqi (operands[0], --+ if (nds32_expand_movmemsi (operands[0], -- operands[1], -- operands[2], -- operands[3])) --@@ -408,3 +3773,75 @@ -- }) -- -- ;; ------------------------------------------------------------------------ --+ --+(define_insn "lmwzb" --+ [(set (match_operand:SI 0 "register_operand" "=r") --+ (plus:SI (match_operand:SI 1 "register_operand" "0") (const_int 4))) --+ (set (match_operand:SI 2 "register_operand" "=r") --+ (unspec:SI [(mem:SI (match_dup 1))] UNSPEC_LMWZB))] --+ "" --+ "lmwzb.bm\t%2, [%1], %2, 0x0" --+ [(set_attr "type" "load_multiple") --+ (set_attr "combo" "1") --+ (set_attr "length" "4")] --+) --+ --+(define_insn "smwzb" --+ [(set (match_operand:SI 0 "register_operand" "=r") --+ (plus:SI (match_operand:SI 1 "register_operand" "0") (const_int 4))) --+ (set (mem:SI (match_dup 1)) --+ (unspec:SI [(match_operand:SI 2 "register_operand" "r")] UNSPEC_SMWZB))] --+ "" --+ "smwzb.bm\t%2, [%1], %2, 0x0" --+ [(set_attr "type" "store_multiple") --+ (set_attr "combo" "1") --+ (set_attr "length" "4")] --+) --+ --+(define_expand "movstr" --+ [(match_operand:SI 0 "register_operand" "") --+ (match_operand:BLK 1 "memory_operand" "") --+ (match_operand:BLK 2 "memory_operand" "")] --+ "TARGET_EXT_STRING && TARGET_INLINE_STRCPY" --+{ --+ if (nds32_expand_movstr (operands[0], --+ operands[1], --+ operands[2])) --+ DONE; --+ --+ FAIL; --+}) --+ --+(define_expand "strlensi" --+ [(match_operand:SI 0 "register_operand") --+ (match_operand:BLK 1 "memory_operand") --+ (match_operand:QI 2 "nds32_reg_constant_operand") --+ (match_operand 3 "const_int_operand")] --+ "TARGET_EXT_STRING" --+{ --+ if (nds32_expand_strlen (operands[0], operands[1], operands[2], operands[3])) --+ DONE; --+ --+ FAIL; --+}) --+ --+(define_expand "setmemsi" --+ [(use (match_operand:BLK 0 "memory_operand")) --+ (use (match_operand:SI 1 "nds32_reg_constant_operand")) --+ (use (match_operand:QI 2 "nonmemory_operand")) --+ (use (match_operand 3 "const_int_operand")) --+ (use (match_operand:SI 4 "const_int_operand")) --+ (use (match_operand:SI 5 "const_int_operand"))] --+ "" --+{ --+ if (nds32_expand_setmem (operands[0], operands[1], --+ operands[2], operands[3], --+ operands[4], operands[5])) --+ DONE; --+ --+ FAIL; --+}) --+ --+ --+ --+;; ------------------------------------------------------------------------ --diff --git a/gcc/config/nds32/nds32-n10.md b/gcc/config/nds32/nds32-n10.md --new file mode 100644 --index 0000000..7261608 ----- /dev/null --+++ b/gcc/config/nds32/nds32-n10.md --@@ -0,0 +1,439 @@ --+;; Pipeline descriptions of Andes NDS32 cpu for GNU compiler --+;; Copyright (C) 2012-2016 Free Software Foundation, Inc. --+;; Contributed by Andes Technology Corporation. --+;; --+;; This file is part of GCC. --+;; --+;; GCC is free software; you can redistribute it and/or modify it --+;; under the terms of the GNU General Public License as published --+;; by the Free Software Foundation; either version 3, or (at your --+;; option) any later version. --+;; --+;; GCC is distributed in the hope that it will be useful, but WITHOUT --+;; ANY WARRANTY; without even the implied warranty of MERCHANTABILITY --+;; or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public --+;; License for more details. --+;; --+;; You should have received a copy of the GNU General Public License --+;; along with GCC; see the file COPYING3. If not see --+;; . --+ --+ --+;; ------------------------------------------------------------------------ --+;; Define N10 pipeline settings. --+;; ------------------------------------------------------------------------ --+ --+(define_automaton "nds32_n10_machine") --+ --+;; ------------------------------------------------------------------------ --+;; Pipeline Stages --+;; ------------------------------------------------------------------------ --+;; IF - Instruction Fetch --+;; II - Instruction Issue / Instruction Decode --+;; EX - Instruction Execution --+;; MM - Memory Execution --+;; WB - Instruction Retire / Result Write-Back --+ --+(define_cpu_unit "n10_ii" "nds32_n10_machine") --+(define_cpu_unit "n10_ex" "nds32_n10_machine") --+(define_cpu_unit "n10_mm" "nds32_n10_machine") --+(define_cpu_unit "n10_wb" "nds32_n10_machine") --+(define_cpu_unit "n10f_iq" "nds32_n10_machine") --+(define_cpu_unit "n10f_rf" "nds32_n10_machine") --+(define_cpu_unit "n10f_e1" "nds32_n10_machine") --+(define_cpu_unit "n10f_e2" "nds32_n10_machine") --+(define_cpu_unit "n10f_e3" "nds32_n10_machine") --+(define_cpu_unit "n10f_e4" "nds32_n10_machine") --+ --+(define_insn_reservation "nds_n10_unknown" 1 --+ (and (eq_attr "type" "unknown") --+ (eq_attr "pipeline_model" "n10")) --+ "n10_ii, n10_ex, n10_mm, n10_wb") --+ --+(define_insn_reservation "nds_n10_misc" 1 --+ (and (eq_attr "type" "misc") --+ (eq_attr "pipeline_model" "n10")) --+ "n10_ii, n10_ex, n10_mm, n10_wb") --+ --+(define_insn_reservation "nds_n10_mmu" 1 --+ (and (eq_attr "type" "mmu") --+ (eq_attr "pipeline_model" "n10")) --+ "n10_ii, n10_ex, n10_mm, n10_wb") --+ --+(define_insn_reservation "nds_n10_alu" 1 --+ (and (eq_attr "type" "alu") --+ (eq_attr "pipeline_model" "n10")) --+ "n10_ii, n10_ex, n10_mm, n10_wb") --+ --+(define_insn_reservation "nds_n10_alu_shift" 1 --+ (and (eq_attr "type" "alu_shift") --+ (eq_attr "pipeline_model" "n10")) --+ "n10_ii, n10_ii+n10_ex, n10_ex+n10_mm, n10_mm+n10_wb, n10_wb") --+ --+(define_insn_reservation "nds_n10_pbsad" 1 --+ (and (eq_attr "type" "pbsad") --+ (eq_attr "pipeline_model" "n10")) --+ "n10_ii, n10_ex*3, n10_mm, n10_wb") --+ --+(define_insn_reservation "nds_n10_pbsada" 1 --+ (and (eq_attr "type" "pbsada") --+ (eq_attr "pipeline_model" "n10")) --+ "n10_ii, n10_ex*3, n10_mm, n10_wb") --+ --+(define_insn_reservation "nds_n10_load" 1 --+ (and (match_test "nds32::load_single_p (insn)") --+ (eq_attr "pipeline_model" "n10")) --+ "n10_ii, n10_ex, n10_mm, n10_wb") --+ --+(define_insn_reservation "nds_n10_store" 1 --+ (and (match_test "nds32::store_single_p (insn)") --+ (eq_attr "pipeline_model" "n10")) --+ "n10_ii, n10_ex, n10_mm, n10_wb") --+ --+(define_insn_reservation "nds_n10_load_multiple_1" 1 --+ (and (eq_attr "pipeline_model" "n10") --+ (and (eq_attr "type" "load_multiple") --+ (eq_attr "combo" "1"))) --+ "n10_ii, n10_ex, n10_mm, n10_wb") --+ --+(define_insn_reservation "nds_n10_load_multiple_2" 1 --+ (and (eq_attr "pipeline_model" "n10") --+ (ior (and (eq_attr "type" "load_multiple") --+ (eq_attr "combo" "2")) --+ (match_test "nds32::load_double_p (insn)"))) --+ "n10_ii, n10_ii+n10_ex, n10_ex+n10_mm, n10_mm+n10_wb, n10_wb") --+ --+(define_insn_reservation "nds_n10_load_multiple_3" 1 --+ (and (eq_attr "pipeline_model" "n10") --+ (and (eq_attr "type" "load_multiple") --+ (eq_attr "combo" "3"))) --+ "n10_ii, n10_ii+n10_ex, n10_ii+n10_ex+n10_mm, n10_ex+n10_mm+n10_wb, n10_mm+n10_wb, n10_wb") --+ --+(define_insn_reservation "nds_n10_load_multiple_4" 1 --+ (and (eq_attr "pipeline_model" "n10") --+ (and (eq_attr "type" "load_multiple") --+ (eq_attr "combo" "4"))) --+ "n10_ii, n10_ii+n10_ex, n10_ii+n10_ex+n10_mm, n10_ii+n10_ex+n10_mm+n10_wb, n10_ex+n10_mm+n10_wb, n10_mm+n10_wb, n10_wb") --+ --+(define_insn_reservation "nds_n10_load_multiple_5" 1 --+ (and (eq_attr "pipeline_model" "n10") --+ (and (eq_attr "type" "load_multiple") --+ (eq_attr "combo" "5"))) --+ "n10_ii, n10_ii+n10_ex, n10_ii+n10_ex+n10_mm, (n10_ii+n10_ex+n10_mm+n10_wb)*2, n10_ex+n10_mm+n10_wb, n10_mm+n10_wb, n10_wb") --+ --+(define_insn_reservation "nds_n10_load_multiple_6" 1 --+ (and (eq_attr "pipeline_model" "n10") --+ (and (eq_attr "type" "load_multiple") --+ (eq_attr "combo" "6"))) --+ "n10_ii, n10_ii+n10_ex, n10_ii+n10_ex+n10_mm, (n10_ii+n10_ex+n10_mm+n10_wb)*3, n10_ex+n10_mm+n10_wb, n10_mm+n10_wb, n10_wb") --+ --+(define_insn_reservation "nds_n10_load_multiple_7" 1 --+ (and (eq_attr "pipeline_model" "n10") --+ (and (eq_attr "type" "load_multiple") --+ (eq_attr "combo" "7"))) --+ "n10_ii, n10_ii+n10_ex, n10_ii+n10_ex+n10_mm, (n10_ii+n10_ex+n10_mm+n10_wb)*4, n10_ex+n10_mm+n10_wb, n10_mm+n10_wb, n10_wb") --+ --+(define_insn_reservation "nds_n10_load_multiple_N" 1 --+ (and (eq_attr "pipeline_model" "n10") --+ (and (eq_attr "type" "load_multiple") --+ (match_test "get_attr_combo (insn) >= 8"))) --+ "n10_ii, n10_ii+n10_ex, n10_ii+n10_ex+n10_mm, (n10_ii+n10_ex+n10_mm+n10_wb)*5, n10_ex+n10_mm+n10_wb, n10_mm+n10_wb, n10_wb") --+ --+(define_insn_reservation "nds_n10_store_multiple_1" 1 --+ (and (eq_attr "pipeline_model" "n10") --+ (and (eq_attr "type" "store_multiple") --+ (eq_attr "combo" "1"))) --+ "n10_ii, n10_ex, n10_mm, n10_wb") --+ --+(define_insn_reservation "nds_n10_store_multiple_2" 1 --+ (and (eq_attr "pipeline_model" "n10") --+ (ior (and (eq_attr "type" "store_multiple") --+ (eq_attr "combo" "2")) --+ (match_test "nds32::store_double_p (insn)"))) --+ "n10_ii, n10_ii+n10_ex, n10_ex+n10_mm, n10_mm+n10_wb, n10_wb") --+ --+(define_insn_reservation "nds_n10_store_multiple_3" 1 --+ (and (eq_attr "pipeline_model" "n10") --+ (and (eq_attr "type" "store_multiple") --+ (eq_attr "combo" "3"))) --+ "n10_ii, n10_ii+n10_ex, n10_ii+n10_ex+n10_mm, n10_ex+n10_mm+n10_wb, n10_mm+n10_wb, n10_wb") --+ --+(define_insn_reservation "nds_n10_store_multiple_4" 1 --+ (and (eq_attr "pipeline_model" "n10") --+ (and (eq_attr "type" "store_multiple") --+ (eq_attr "combo" "4"))) --+ "n10_ii, n10_ii+n10_ex, n10_ii+n10_ex+n10_mm, n10_ii+n10_ex+n10_mm+n10_wb, n10_ex+n10_mm+n10_wb, n10_mm+n10_wb, n10_wb") --+ --+(define_insn_reservation "nds_n10_store_multiple_5" 1 --+ (and (eq_attr "pipeline_model" "n10") --+ (and (eq_attr "type" "store_multiple") --+ (eq_attr "combo" "5"))) --+ "n10_ii, n10_ii+n10_ex, n10_ii+n10_ex+n10_mm, (n10_ii+n10_ex+n10_mm+n10_wb)*2, n10_ex+n10_mm+n10_wb, n10_mm+n10_wb, n10_wb") --+ --+(define_insn_reservation "nds_n10_store_multiple_6" 1 --+ (and (eq_attr "pipeline_model" "n10") --+ (and (eq_attr "type" "store_multiple") --+ (eq_attr "combo" "6"))) --+ "n10_ii, n10_ii+n10_ex, n10_ii+n10_ex+n10_mm, (n10_ii+n10_ex+n10_mm+n10_wb)*3, n10_ex+n10_mm+n10_wb, n10_mm+n10_wb, n10_wb") --+ --+(define_insn_reservation "nds_n10_store_multiple_7" 1 --+ (and (eq_attr "pipeline_model" "n10") --+ (and (eq_attr "type" "store_multiple") --+ (eq_attr "combo" "7"))) --+ "n10_ii, n10_ii+n10_ex, n10_ii+n10_ex+n10_mm, (n10_ii+n10_ex+n10_mm+n10_wb)*4, n10_ex+n10_mm+n10_wb, n10_mm+n10_wb, n10_wb") --+ --+(define_insn_reservation "nds_n10_store_multiple_N" 1 --+ (and (eq_attr "pipeline_model" "n10") --+ (and (eq_attr "type" "store_multiple") --+ (match_test "get_attr_combo (insn) >= 8"))) --+ "n10_ii, n10_ii+n10_ex, n10_ii+n10_ex+n10_mm, (n10_ii+n10_ex+n10_mm+n10_wb)*5, n10_ex+n10_mm+n10_wb, n10_mm+n10_wb, n10_wb") --+ --+(define_insn_reservation "nds_n10_mul" 1 --+ (and (eq_attr "type" "mul") --+ (eq_attr "pipeline_model" "n10")) --+ "n10_ii, n10_ex, n10_mm, n10_wb") --+ --+(define_insn_reservation "nds_n10_mac" 1 --+ (and (eq_attr "type" "mac") --+ (eq_attr "pipeline_model" "n10")) --+ "n10_ii, n10_ex, n10_mm, n10_wb") --+ --+(define_insn_reservation "nds_n10_div" 1 --+ (and (eq_attr "type" "div") --+ (eq_attr "pipeline_model" "n10")) --+ "n10_ii, n10_ex*34, n10_mm, n10_wb") --+ --+(define_insn_reservation "nds_n10_branch" 1 --+ (and (eq_attr "type" "branch") --+ (eq_attr "pipeline_model" "n10")) --+ "n10_ii, n10_ex, n10_mm, n10_wb") --+ --+(define_insn_reservation "nds_n10_dsp_alu" 1 --+ (and (eq_attr "type" "dalu") --+ (eq_attr "pipeline_model" "n10")) --+ "n10_ii, n10_ex, n10_mm, n10_wb") --+ --+(define_insn_reservation "nds_n10_dsp_alu64" 1 --+ (and (eq_attr "type" "dalu64") --+ (eq_attr "pipeline_model" "n10")) --+ "n10_ii, n10_ex, n10_mm, n10_wb") --+ --+(define_insn_reservation "nds_n10_dsp_alu_round" 1 --+ (and (eq_attr "type" "daluround") --+ (eq_attr "pipeline_model" "n10")) --+ "n10_ii, n10_ex, n10_mm, n10_wb") --+ --+(define_insn_reservation "nds_n10_dsp_cmp" 1 --+ (and (eq_attr "type" "dcmp") --+ (eq_attr "pipeline_model" "n10")) --+ "n10_ii, n10_ex, n10_mm, n10_wb") --+ --+(define_insn_reservation "nds_n10_dsp_clip" 1 --+ (and (eq_attr "type" "dclip") --+ (eq_attr "pipeline_model" "n10")) --+ "n10_ii, n10_ex, n10_mm, n10_wb") --+ --+(define_insn_reservation "nds_n10_dsp_mul" 1 --+ (and (eq_attr "type" "dmul") --+ (eq_attr "pipeline_model" "n10")) --+ "n10_ii, n10_ex, n10_mm, n10_wb") --+ --+(define_insn_reservation "nds_n10_dsp_mac" 1 --+ (and (eq_attr "type" "dmac") --+ (eq_attr "pipeline_model" "n10")) --+ "n10_ii, n10_ex, n10_mm, n10_wb") --+ --+(define_insn_reservation "nds_n10_dsp_insb" 1 --+ (and (eq_attr "type" "dinsb") --+ (eq_attr "pipeline_model" "n10")) --+ "n10_ii, n10_ex, n10_mm, n10_wb") --+ --+(define_insn_reservation "nds_n10_dsp_pack" 1 --+ (and (eq_attr "type" "dpack") --+ (eq_attr "pipeline_model" "n10")) --+ "n10_ii, n10_ex, n10_mm, n10_wb") --+ --+(define_insn_reservation "nds_n10_dsp_bpick" 1 --+ (and (eq_attr "type" "dbpick") --+ (eq_attr "pipeline_model" "n10")) --+ "n10_ii, n10_ex, n10_mm, n10_wb") --+ --+(define_insn_reservation "nds_n10_dsp_wext" 1 --+ (and (eq_attr "type" "dwext") --+ (eq_attr "pipeline_model" "n10")) --+ "n10_ii, n10_ex, n10_mm, n10_wb") --+ --+(define_insn_reservation "nds_n10_fpu_alu" 4 --+ (and (eq_attr "type" "falu") --+ (eq_attr "pipeline_model" "n10")) --+ "n10_ii, n10f_iq, n10f_rf, n10f_e1, n10f_e2, n10f_e3, n10f_e4") --+ --+(define_insn_reservation "nds_n10_fpu_muls" 4 --+ (and (eq_attr "type" "fmuls") --+ (eq_attr "pipeline_model" "n10")) --+ "n10_ii, n10f_iq, n10f_rf, n10f_e1, n10f_e2, n10f_e3, n10f_e4") --+ --+(define_insn_reservation "nds_n10_fpu_muld" 4 --+ (and (eq_attr "type" "fmuld") --+ (eq_attr "pipeline_model" "n10")) --+ "n10_ii, n10f_iq, n10f_rf, n10f_e1, n10f_e2*2, n10f_e3, n10f_e4") --+ --+(define_insn_reservation "nds_n10_fpu_macs" 4 --+ (and (eq_attr "type" "fmacs") --+ (eq_attr "pipeline_model" "n10")) --+ "n10_ii, n10f_iq, n10f_rf, n10f_e1, n10f_e2*3, n10f_e3, n10f_e4") --+ --+(define_insn_reservation "nds_n10_fpu_macd" 4 --+ (and (eq_attr "type" "fmacd") --+ (eq_attr "pipeline_model" "n10")) --+ "n10_ii, n10f_iq, n10f_rf, n10f_e1, n10f_e2*4, n10f_e3, n10f_e4") --+ --+(define_insn_reservation "nds_n10_fpu_divs" 4 --+ (and (ior (eq_attr "type" "fdivs") --+ (eq_attr "type" "fsqrts")) --+ (eq_attr "pipeline_model" "n10")) --+ "n10_ii, n10f_iq, n10f_rf, n10f_e1, n10f_e2*14, n10f_e3, n10f_e4") --+ --+(define_insn_reservation "nds_n10_fpu_divd" 4 --+ (and (ior (eq_attr "type" "fdivd") --+ (eq_attr "type" "fsqrtd")) --+ (eq_attr "pipeline_model" "n10")) --+ "n10_ii, n10f_iq, n10f_rf, n10f_e1, n10f_e2*28, n10f_e3, n10f_e4") --+ --+(define_insn_reservation "nds_n10_fpu_fast_alu" 2 --+ (and (ior (eq_attr "type" "fcmp") --+ (ior (eq_attr "type" "fabs") --+ (ior (eq_attr "type" "fcpy") --+ (eq_attr "type" "fcmov")))) --+ (eq_attr "pipeline_model" "n10")) --+ "n10_ii, n10f_iq, n10f_rf, n10f_e1, n10f_e2, n10f_e3, n10f_e4") --+ --+(define_insn_reservation "nds_n10_fpu_fmtsr" 4 --+ (and (eq_attr "type" "fmtsr") --+ (eq_attr "pipeline_model" "n10")) --+ "n10_ii, n10f_iq, n10f_rf, n10f_e1, n10f_e2, n10f_e3, n10f_e4") --+ --+(define_insn_reservation "nds_n10_fpu_fmtdr" 4 --+ (and (eq_attr "type" "fmtdr") --+ (eq_attr "pipeline_model" "n10")) --+ "n10_ii, n10_ii+n10f_iq, n10f_iq+n10f_rf, n10f_rf+n10f_e1, n10f_e1+n10f_e2, n10f_e2+n10f_e3, n10f_e3+n10f_e4, n10f_e4") --+ --+(define_insn_reservation "nds_n10_fpu_fmfsr" 2 --+ (and (eq_attr "type" "fmfsr") --+ (eq_attr "pipeline_model" "n10")) --+ "n10_ii, n10f_iq, n10f_rf, n10f_e1, n10f_e2, n10f_e3, n10f_e4") --+ --+(define_insn_reservation "nds_n10_fpu_fmfdr" 2 --+ (and (eq_attr "type" "fmfdr") --+ (eq_attr "pipeline_model" "n10")) --+ "n10_ii, n10_ii+n10f_iq, n10f_iq+n10f_rf, n10f_rf+n10f_e1, n10f_e1+n10f_e2, n10f_e2+n10f_e3, n10f_e3+n10f_e4, n10f_e4") --+ --+(define_insn_reservation "nds_n10_fpu_load" 3 --+ (and (eq_attr "type" "fload") --+ (eq_attr "pipeline_model" "n10")) --+ "n10_ii, n10f_iq, n10f_rf, n10f_e1, n10f_e2, n10f_e3, n10f_e4") --+ --+(define_insn_reservation "nds_n10_fpu_store" 1 --+ (and (eq_attr "type" "fstore") --+ (eq_attr "pipeline_model" "n10")) --+ "n10_ii, n10f_iq, n10f_rf, n10f_e1, n10f_e2, n10f_e3, n10f_e4") --+ --+;; ------------------------------------------------------------------------ --+;; Comment Notations and Bypass Rules --+;; ------------------------------------------------------------------------ --+;; Producers (LHS) --+;; LD --+;; Load data from the memory and produce the loaded data. The result is --+;; ready at MM. --+;; LMW(N, M) --+;; There are N micro-operations within an instruction that loads multiple --+;; words. The result produced by the M-th micro-operation is sent to --+;; consumers. The result is ready at MM. --+;; MUL, MAC --+;; Compute data in the multiply-adder and produce the data. The result --+;; is ready at MM. --+;; DIV --+;; Compute data in the divider and produce the data. The result is ready --+;; at MM. --+;; --+;; Consumers (RHS) --+;; ALU, MOVD44, PBSAD, PBSADA_RaRb, MUL, MAC, DIV, MMU --+;; Require operands at EX. --+;; ALU_SHIFT_Rb --+;; An ALU-SHIFT instruction consists of a shift micro-operation followed --+;; by an arithmetic micro-operation. The operand Rb is used by the first --+;; micro-operation, and there are some latencies if data dependency occurs. --+;; MAC_RaRb --+;; A MAC instruction does multiplication at EX and does accumulation at MM, --+;; so the operand Rt is required at MM, and operands Ra and Rb are required --+;; at EX. --+;; ADDR_IN --+;; If an instruction requires an address as its input operand, the address --+;; is required at EX. --+;; ST --+;; A store instruction requires its data at MM. --+;; SMW(N, M) --+;; There are N micro-operations within an instruction that stores multiple --+;; words. Each M-th micro-operation requires its data at MM. --+;; BR --+;; If a branch instruction is conditional, its input data is required at EX. --+ --+;; FPU_ADDR_OUT -> FPU_ADDR_IN --+;; Main pipeline rules don't need this because those default latency is 1. --+(define_bypass 1 --+ "nds_n10_fpu_load, nds_n10_fpu_store" --+ "nds_n10_fpu_load, nds_n10_fpu_store" --+ "nds32_n10_ex_to_ex_p" --+) --+ --+;; LD, MUL, MAC, DIV, DALU64, DMUL, DMAC, DALUROUND, DBPICK, DWEXT --+;; -> ALU, ALU_SHIFT_Rb, PBSAD, PBSADA_RaRb, MOVD44, MUL, MAC_RaRb, DIV, ADDR_IN, BR, MMU, --+;; DALU, DALUROUND, DMUL, DMAC_RaRb, DPACK, DINSB, DCMP, DCLIP, WEXT_O, BPICK_RaRb --+(define_bypass 2 --+ "nds_n10_load, nds_n10_mul, nds_n10_mac, nds_n10_div,\ --+ nds_n10_dsp_alu64, nds_n10_dsp_mul, nds_n10_dsp_mac,\ --+ nds_n10_dsp_alu_round, nds_n10_dsp_bpick, nds_n10_dsp_wext" --+ "nds_n10_alu, nds_n10_alu_shift,\ --+ nds_n10_pbsad, nds_n10_pbsada,\ --+ nds_n10_mul, nds_n10_mac, nds_n10_div,\ --+ nds_n10_branch,\ --+ nds_n10_load, nds_n10_store,\ --+ nds_n10_load_multiple_1, nds_n10_load_multiple_2, nds_n10_load_multiple_3,\ --+ nds_n10_load_multiple_4, nds_n10_load_multiple_5, nds_n10_load_multiple_6,\ --+ nds_n10_load_multiple_7, nds_n10_load_multiple_N,\ --+ nds_n10_store_multiple_1, nds_n10_store_multiple_2, nds_n10_store_multiple_3,\ --+ nds_n10_store_multiple_4, nds_n10_store_multiple_5, nds_n10_store_multiple_6,\ --+ nds_n10_store_multiple_7, nds_n10_store_multiple_N,\ --+ nds_n10_mmu,\ --+ nds_n10_dsp_alu, nds_n10_dsp_alu_round,\ --+ nds_n10_dsp_mul, nds_n10_dsp_mac, nds_n10_dsp_pack,\ --+ nds_n10_dsp_insb, nds_n10_dsp_cmp, nds_n10_dsp_clip,\ --+ nds_n10_dsp_wext, nds_n10_dsp_bpick" --+ "nds32_n10_mm_to_ex_p" --+) --+ --+;; LMW(N, N) --+;; -> ALU, ALU_SHIFT_Rb, PBSAD, PBSADA_RaRb, MOVD44, MUL, MAC_RaRb, DIV, ADDR_IN, BR, MMU --+;; DALU, DALUROUND, DMUL, DMAC_RaRb, DPACK, DINSB, DCMP, DCLIP, WEXT_O, BPICK_RaRb --+(define_bypass 2 --+ "nds_n10_load_multiple_1, nds_n10_load_multiple_2, nds_n10_load_multiple_3,\ --+ nds_n10_load_multiple_4, nds_n10_load_multiple_5, nds_n10_load_multiple_6,\ --+ nds_n10_load_multiple_7, nds_n10_load_multiple_N" --+ "nds_n10_alu, nds_n10_alu_shift,\ --+ nds_n10_pbsad, nds_n10_pbsada,\ --+ nds_n10_mul, nds_n10_mac, nds_n10_div,\ --+ nds_n10_branch,\ --+ nds_n10_load, nds_n10_store,\ --+ nds_n10_load_multiple_1, nds_n10_load_multiple_2, nds_n10_load_multiple_3,\ --+ nds_n10_load_multiple_4, nds_n10_load_multiple_5, nds_n10_load_multiple_6,\ --+ nds_n10_load_multiple_7, nds_n10_load_multiple_N,\ --+ nds_n10_store_multiple_1, nds_n10_store_multiple_2, nds_n10_store_multiple_3,\ --+ nds_n10_store_multiple_4, nds_n10_store_multiple_5, nds_n10_store_multiple_6,\ --+ nds_n10_store_multiple_7, nds_n10_store_multiple_N,\ --+ nds_n10_mmu,\ --+ nds_n10_dsp_alu, nds_n10_dsp_alu_round,\ --+ nds_n10_dsp_mul, nds_n10_dsp_mac, nds_n10_dsp_pack,\ --+ nds_n10_dsp_insb, nds_n10_dsp_cmp, nds_n10_dsp_clip,\ --+ nds_n10_dsp_wext, nds_n10_dsp_bpick" --+ "nds32_n10_last_load_to_ex_p" --+) --diff --git a/gcc/config/nds32/nds32-n13.md b/gcc/config/nds32/nds32-n13.md --new file mode 100644 --index 0000000..622480d ----- /dev/null --+++ b/gcc/config/nds32/nds32-n13.md --@@ -0,0 +1,401 @@ --+;; Pipeline descriptions of Andes NDS32 cpu for GNU compiler --+;; Copyright (C) 2012-2016 Free Software Foundation, Inc. --+;; Contributed by Andes Technology Corporation. --+;; --+;; This file is part of GCC. --+;; --+;; GCC is free software; you can redistribute it and/or modify it --+;; under the terms of the GNU General Public License as published --+;; by the Free Software Foundation; either version 3, or (at your --+;; option) any later version. --+;; --+;; GCC is distributed in the hope that it will be useful, but WITHOUT --+;; ANY WARRANTY; without even the implied warranty of MERCHANTABILITY --+;; or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public --+;; License for more details. --+;; --+;; You should have received a copy of the GNU General Public License --+;; along with GCC; see the file COPYING3. If not see --+;; . --+ --+ --+;; ------------------------------------------------------------------------ --+;; Define N13 pipeline settings. --+;; ------------------------------------------------------------------------ --+ --+(define_automaton "nds32_n13_machine") --+ --+;; ------------------------------------------------------------------------ --+;; Pipeline Stages --+;; ------------------------------------------------------------------------ --+;; F1 - Instruction Fetch First --+;; Instruction Tag/Data Arrays --+;; ITLB Address Translation --+;; Branch Target Buffer Prediction --+;; F2 - Instruction Fetch Second --+;; Instruction Cache Hit Detection --+;; Cache Way Selection --+;; Inustruction Alignment --+;; I1 - Instruction Issue First / Instruction Decode --+;; Instruction Cache Replay Triggering --+;; 32/16-Bit Instruction Decode --+;; Return Address Stack Prediction --+;; I2 - Instruction Issue Second / Register File Access --+;; Instruction Issue Logic --+;; Register File Access --+;; E1 - Instruction Execute First / Address Generation / MAC First --+;; Data Access Address generation --+;; Multiply Operation --+;; E2 - Instruction Execute Second / Data Access First / MAC Second / --+;; ALU Execute --+;; Skewed ALU --+;; Branch/Jump/Return Resolution --+;; Data Tag/Data arrays --+;; DTLB address translation --+;; Accumulation Operation --+;; E3 - Instruction Execute Third / Data Access Second --+;; Data Cache Hit Detection --+;; Cache Way Selection --+;; Data Alignment --+;; E4 - Instruction Execute Fourth / Write Back --+;; Interruption Resolution --+;; Instruction Retire --+;; Register File Write Back --+ --+(define_cpu_unit "n13_i1" "nds32_n13_machine") --+(define_cpu_unit "n13_i2" "nds32_n13_machine") --+(define_cpu_unit "n13_e1" "nds32_n13_machine") --+(define_cpu_unit "n13_e2" "nds32_n13_machine") --+(define_cpu_unit "n13_e3" "nds32_n13_machine") --+(define_cpu_unit "n13_e4" "nds32_n13_machine") --+ --+(define_insn_reservation "nds_n13_unknown" 1 --+ (and (eq_attr "type" "unknown") --+ (eq_attr "pipeline_model" "n13")) --+ "n13_i1, n13_i2, n13_e1, n13_e2, n13_e3, n13_e4") --+ --+(define_insn_reservation "nds_n13_misc" 1 --+ (and (eq_attr "type" "misc") --+ (eq_attr "pipeline_model" "n13")) --+ "n13_i1, n13_i2, n13_e1, n13_e2, n13_e3, n13_e4") --+ --+(define_insn_reservation "nds_n13_mmu" 1 --+ (and (eq_attr "type" "mmu") --+ (eq_attr "pipeline_model" "n13")) --+ "n13_i1, n13_i2, n13_e1, n13_e2, n13_e3, n13_e4") --+ --+(define_insn_reservation "nds_n13_alu" 1 --+ (and (eq_attr "type" "alu") --+ (eq_attr "pipeline_model" "n13")) --+ "n13_i1, n13_i2, n13_e1, n13_e2, n13_e3, n13_e4") --+ --+(define_insn_reservation "nds_n13_alu_shift" 1 --+ (and (eq_attr "type" "alu_shift") --+ (eq_attr "pipeline_model" "n13")) --+ "n13_i1, n13_i1+n13_i2, n13_i2+n13_e1, n13_e1+n13_e2, n13_e2+n13_e3, n13_e3+n13_e4, n13_e4") --+ --+(define_insn_reservation "nds_n13_pbsad" 1 --+ (and (eq_attr "type" "pbsad") --+ (eq_attr "pipeline_model" "n13")) --+ "n13_i1, n13_i2, n13_e1, n13_e2*2, n13_e3, n13_e4") --+ --+(define_insn_reservation "nds_n13_pbsada" 1 --+ (and (eq_attr "type" "pbsada") --+ (eq_attr "pipeline_model" "n13")) --+ "n13_i1, n13_i2, n13_e1, n13_e2*3, n13_e3, n13_e4") --+ --+(define_insn_reservation "nds_n13_load" 1 --+ (and (match_test "nds32::load_single_p (insn)") --+ (eq_attr "pipeline_model" "n13")) --+ "n13_i1, n13_i2, n13_e1, n13_e2, n13_e3, n13_e4") --+ --+(define_insn_reservation "nds_n13_store" 1 --+ (and (match_test "nds32::store_single_p (insn)") --+ (eq_attr "pipeline_model" "n13")) --+ "n13_i1, n13_i2, n13_e1, n13_e2, n13_e3, n13_e4") --+ --+(define_insn_reservation "nds_n13_load_multiple_1" 1 --+ (and (and (eq_attr "type" "load_multiple") --+ (eq_attr "combo" "1")) --+ (eq_attr "pipeline_model" "n13")) --+ "n13_i1, n13_i2, n13_e1, n13_e2, n13_e3, n13_e4") --+ --+(define_insn_reservation "nds_n13_load_multiple_2" 1 --+ (and (ior (and (eq_attr "type" "load_multiple") --+ (eq_attr "combo" "2")) --+ (match_test "nds32::load_double_p (insn)")) --+ (eq_attr "pipeline_model" "n13")) --+ "n13_i1, n13_i1+n13_i2, n13_i2+n13_e1, n13_e1+n13_e2, n13_e2+n13_e3, n13_e3+n13_e4, n13_e4") --+ --+(define_insn_reservation "nds_n13_load_multiple_3" 1 --+ (and (and (eq_attr "type" "load_multiple") --+ (eq_attr "combo" "3")) --+ (eq_attr "pipeline_model" "n13")) --+ "n13_i1, n13_i2+n13_i2, n13_i1+n13_i2+n13_e1, n13_i2+n13_e1+n13_e2, n13_e1+n13_e2+n13_e3, n13_e2+n13_e3+n13_e4, n13_e3+n13_e4, n13_e4") --+ --+(define_insn_reservation "nds_n13_load_multiple_4" 1 --+ (and (and (eq_attr "type" "load_multiple") --+ (eq_attr "combo" "4")) --+ (eq_attr "pipeline_model" "n13")) --+ "n13_i1, n13_i1+n13_i2, n13_i1+n13_i2+n13_e1, n13_i1+n13_i2+n13_e1+n13_e2, n13_i2+n13_e1+n13_e2+n13_e3, n13_e1+n13_e2+n13_e3+n13_e4, n13_e2+n13_e3+n13_e4, n13_e3+n13_e4, n13_e4") --+ --+(define_insn_reservation "nds_n13_load_multiple_5" 1 --+ (and (and (eq_attr "type" "load_multiple") --+ (eq_attr "combo" "5")) --+ (eq_attr "pipeline_model" "n13")) --+ "n13_i1, n13_i1+n13_i2, n13_i1+n13_i2+n13_e1, n13_i1+n13_i2+n13_e1+n13_e2, n13_i1+n13_i2+n13_e1+n13_e2+n13_e3, n13_i2+n13_e1+n13_e2+n13_e3+n13_e4, n13_e1+n13_e2+n13_e3+n13_e4, n13_e2+n13_e3+n13_e4, n13_e3+n13_e4, n13_e4") --+ --+(define_insn_reservation "nds_n13_load_multiple_6" 1 --+ (and (and (eq_attr "type" "load_multiple") --+ (eq_attr "combo" "6")) --+ (eq_attr "pipeline_model" "n13")) --+ "n13_i1, n13_i1+n13_i2, n13_i1+n13_i2+n13_e1, n13_i1+n13_i2+n13_e1+n13_e2, n13_i1+n13_i2+n13_e1+n13_e2+n13_e3, n13_i1+n13_i2+n13_e1+n13_e2+n13_e3+n13_e4, n13_i2+n13_e1+n13_e2+n13_e3+n13_e4, n13_e1+n13_e2+n13_e3+n13_e4, n13_e2+n13_e3+n13_e4, n13_e3+n13_e4, n13_e4") --+ --+(define_insn_reservation "nds_n13_load_multiple_7" 1 --+ (and (and (eq_attr "type" "load_multiple") --+ (eq_attr "combo" "7")) --+ (eq_attr "pipeline_model" "n13")) --+ "n13_i1, n13_i1+n13_i2, n13_i1+n13_i2+n13_e1, n13_i1+n13_i2+n13_e1+n13_e2, n13_i1+n13_i2+n13_e1+n13_e2+n13_e3, (n13_i1+n13_i2+n13_e1+n13_e2+n13_e3+n13_e4)*2, n13_i2+n13_e1+n13_e2+n13_e3+n13_e4, n13_e1+n13_e2+n13_e3+n13_e4, n13_e2+n13_e3+n13_e4, n13_e3+n13_e4, n13_e4") --+ --+(define_insn_reservation "nds_n13_load_multiple_8" 1 --+ (and (and (eq_attr "type" "load_multiple") --+ (eq_attr "combo" "8")) --+ (eq_attr "pipeline_model" "n13")) --+ "n13_i1, n13_i1+n13_i2, n13_i1+n13_i2+n13_e1, n13_i1+n13_i2+n13_e1+n13_e2, n13_i1+n13_i2+n13_e1+n13_e2+n13_e3, (n13_i1+n13_i2+n13_e1+n13_e2+n13_e3+n13_e4)*3, n13_i2+n13_e1+n13_e2+n13_e3+n13_e4, n13_e1+n13_e2+n13_e3+n13_e4, n13_e2+n13_e3+n13_e4, n13_e3+n13_e4, n13_e4") --+ --+(define_insn_reservation "nds_n13_load_multiple_12" 1 --+ (and (and (eq_attr "type" "load_multiple") --+ (eq_attr "combo" "12")) --+ (eq_attr "pipeline_model" "n13")) --+ "n13_i1, n13_i1+n13_i2, n13_i1+n13_i2+n13_e1, n13_i1+n13_i2+n13_e1+n13_e2, n13_i1+n13_i2+n13_e1+n13_e2+n13_e3, (n13_i1+n13_i2+n13_e1+n13_e2+n13_e3+n13_e4)*7, n13_i2+n13_e1+n13_e2+n13_e3+n13_e4, n13_e1+n13_e2+n13_e3+n13_e4, n13_e2+n13_e3+n13_e4, n13_e3+n13_e4, n13_e4") --+ --+(define_insn_reservation "nds_n13_store_multiple_1" 1 --+ (and (and (eq_attr "type" "store_multiple") --+ (eq_attr "combo" "1")) --+ (eq_attr "pipeline_model" "n13")) --+ "n13_i1, n13_i2, n13_e1, n13_e2, n13_e3, n13_e4") --+ --+(define_insn_reservation "nds_n13_store_multiple_2" 1 --+ (and (ior (and (eq_attr "type" "store_multiple") --+ (eq_attr "combo" "2")) --+ (match_test "nds32::store_double_p (insn)")) --+ (eq_attr "pipeline_model" "n13")) --+ "n13_i1, n13_i1+n13_i2, n13_i2+n13_e1, n13_e1+n13_e2, n13_e2+n13_e3, n13_e3+n13_e4, n13_e4") --+ --+(define_insn_reservation "nds_n13_store_multiple_3" 1 --+ (and (and (eq_attr "type" "store_multiple") --+ (eq_attr "combo" "3")) --+ (eq_attr "pipeline_model" "n13")) --+ "n13_i1, n13_i2+n13_i2, n13_i1+n13_i2+n13_e1, n13_i2+n13_e1+n13_e2, n13_e1+n13_e2+n13_e3, n13_e2+n13_e3+n13_e4, n13_e3+n13_e4, n13_e4") --+ --+(define_insn_reservation "nds_n13_store_multiple_4" 1 --+ (and (and (eq_attr "type" "store_multiple") --+ (eq_attr "combo" "4")) --+ (eq_attr "pipeline_model" "n13")) --+ "n13_i1, n13_i1+n13_i2, n13_i1+n13_i2+n13_e1, n13_i1+n13_i2+n13_e1+n13_e2, n13_i2+n13_e1+n13_e2+n13_e3, n13_e1+n13_e2+n13_e3+n13_e4, n13_e2+n13_e3+n13_e4, n13_e3+n13_e4, n13_e4") --+ --+(define_insn_reservation "nds_n13_store_multiple_5" 1 --+ (and (and (eq_attr "type" "store_multiple") --+ (eq_attr "combo" "5")) --+ (eq_attr "pipeline_model" "n13")) --+ "n13_i1, n13_i1+n13_i2, n13_i1+n13_i2+n13_e1, n13_i1+n13_i2+n13_e1+n13_e2, n13_i1+n13_i2+n13_e1+n13_e2+n13_e3, n13_i2+n13_e1+n13_e2+n13_e3+n13_e4, n13_e1+n13_e2+n13_e3+n13_e4, n13_e2+n13_e3+n13_e4, n13_e3+n13_e4, n13_e4") --+ --+(define_insn_reservation "nds_n13_store_multiple_6" 1 --+ (and (and (eq_attr "type" "store_multiple") --+ (eq_attr "combo" "6")) --+ (eq_attr "pipeline_model" "n13")) --+ "n13_i1, n13_i1+n13_i2, n13_i1+n13_i2+n13_e1, n13_i1+n13_i2+n13_e1+n13_e2, n13_i1+n13_i2+n13_e1+n13_e2+n13_e3, n13_i1+n13_i2+n13_e1+n13_e2+n13_e3+n13_e4, n13_i2+n13_e1+n13_e2+n13_e3+n13_e4, n13_e1+n13_e2+n13_e3+n13_e4, n13_e2+n13_e3+n13_e4, n13_e3+n13_e4, n13_e4") --+ --+(define_insn_reservation "nds_n13_store_multiple_7" 1 --+ (and (and (eq_attr "type" "store_multiple") --+ (eq_attr "combo" "7")) --+ (eq_attr "pipeline_model" "n13")) --+ "n13_i1, n13_i1+n13_i2, n13_i1+n13_i2+n13_e1, n13_i1+n13_i2+n13_e1+n13_e2, n13_i1+n13_i2+n13_e1+n13_e2+n13_e3, (n13_i1+n13_i2+n13_e1+n13_e2+n13_e3+n13_e4)*2, n13_i2+n13_e1+n13_e2+n13_e3+n13_e4, n13_e1+n13_e2+n13_e3+n13_e4, n13_e2+n13_e3+n13_e4, n13_e3+n13_e4, n13_e4") --+ --+(define_insn_reservation "nds_n13_store_multiple_8" 1 --+ (and (and (eq_attr "type" "store_multiple") --+ (eq_attr "combo" "8")) --+ (eq_attr "pipeline_model" "n13")) --+ "n13_i1, n13_i1+n13_i2, n13_i1+n13_i2+n13_e1, n13_i1+n13_i2+n13_e1+n13_e2, n13_i1+n13_i2+n13_e1+n13_e2+n13_e3, (n13_i1+n13_i2+n13_e1+n13_e2+n13_e3+n13_e4)*3, n13_i2+n13_e1+n13_e2+n13_e3+n13_e4, n13_e1+n13_e2+n13_e3+n13_e4, n13_e2+n13_e3+n13_e4, n13_e3+n13_e4, n13_e4") --+ --+(define_insn_reservation "nds_n13_store_multiple_12" 1 --+ (and (and (eq_attr "type" "store_multiple") --+ (eq_attr "combo" "12")) --+ (eq_attr "pipeline_model" "n13")) --+ "n13_i1, n13_i1+n13_i2, n13_i1+n13_i2+n13_e1, n13_i1+n13_i2+n13_e1+n13_e2, n13_i1+n13_i2+n13_e1+n13_e2+n13_e3, (n13_i1+n13_i2+n13_e1+n13_e2+n13_e3+n13_e4)*7, n13_i2+n13_e1+n13_e2+n13_e3+n13_e4, n13_e1+n13_e2+n13_e3+n13_e4, n13_e2+n13_e3+n13_e4, n13_e3+n13_e4, n13_e4") --+ --+;; The multiplier at E1 takes two cycles. --+(define_insn_reservation "nds_n13_mul" 1 --+ (and (eq_attr "type" "mul") --+ (eq_attr "pipeline_model" "n13")) --+ "n13_i1, n13_i2, n13_e1*2, n13_e2, n13_e3, n13_e4") --+ --+(define_insn_reservation "nds_n13_mac" 1 --+ (and (eq_attr "type" "mac") --+ (eq_attr "pipeline_model" "n13")) --+ "n13_i1, n13_i2, n13_e1*2, n13_e2, n13_e3, n13_e4") --+ --+;; The cycles consumed at E2 are 32 - CLZ(abs(Ra)) + 2, --+;; so the worst case is 34. --+(define_insn_reservation "nds_n13_div" 1 --+ (and (eq_attr "type" "div") --+ (eq_attr "pipeline_model" "n13")) --+ "n13_i1, n13_i2, n13_e1, n13_e2*34, n13_e3, n13_e4") --+ --+(define_insn_reservation "nds_n13_branch" 1 --+ (and (eq_attr "type" "branch") --+ (eq_attr "pipeline_model" "n13")) --+ "n13_i1, n13_i2, n13_e1, n13_e2, n13_e3, n13_e4") --+ --+;; ------------------------------------------------------------------------ --+;; Comment Notations and Bypass Rules --+;; ------------------------------------------------------------------------ --+;; Producers (LHS) --+;; LD --+;; Load data from the memory and produce the loaded data. The result is --+;; ready at E3. --+;; LMW(N, M) --+;; There are N micro-operations within an instruction that loads multiple --+;; words. The result produced by the M-th micro-operation is sent to --+;; consumers. The result is ready at E3. --+;; ADDR_OUT --+;; Most load/store instructions can produce an address output if updating --+;; the base register is required. The result is ready at E2, which is --+;; produced by ALU. --+;; ALU, ALU_SHIFT, SIMD --+;; Compute data in ALU and produce the data. The result is ready at E2. --+;; MUL, MAC --+;; Compute data in the multiply-adder and produce the data. The result --+;; is ready at E2. --+;; DIV --+;; Compute data in the divider and produce the data. The result is ready --+;; at E2. --+;; BR --+;; Branch-with-link instructions produces a result containing the return --+;; address. The result is ready at E2. --+;; --+;; Consumers (RHS) --+;; ALU --+;; General ALU instructions require operands at E2. --+;; ALU_E1 --+;; Some special ALU instructions, such as BSE, BSP and MOVD44, require --+;; operand at E1. --+;; MUL, DIV, PBSAD, MMU --+;; Operands are required at E1. --+;; PBSADA_Rt, PBSADA_RaRb --+;; Operands Ra and Rb are required at E1, and the operand Rt is required --+;; at E2. --+;; ALU_SHIFT_Rb --+;; An ALU-SHIFT instruction consists of a shift micro-operation followed --+;; by an arithmetic micro-operation. The operand Rb is used by the first --+;; micro-operation, and there are some latencies if data dependency occurs. --+;; MAC_RaRb --+;; A MAC instruction does multiplication at E1 and does accumulation at E2, --+;; so the operand Rt is required at E2, and operands Ra and Rb are required --+;; at E1. --+;; ADDR_IN --+;; If an instruction requires an address as its input operand, the address --+;; is required at E1. --+;; ST --+;; A store instruction requires its data at E2. --+;; SMW(N, M) --+;; There are N micro-operations within an instruction that stores multiple --+;; words. Each M-th micro-operation requires its data at E2. --+;; BR --+;; If a branch instruction is conditional, its input data is required at E2. --+ --+;; LD -> ALU_E1, PBSAD, PBSADA_RaRb, MUL, MAC_RaRb, DIV, MMU, ADDR_IN --+(define_bypass 3 --+ "nds_n13_load" --+ "nds_n13_alu, nds_n13_pbsad, nds_n13_pbsada,\ --+ nds_n13_mul, nds_n13_mac, nds_n13_div,\ --+ nds_n13_mmu,\ --+ nds_n13_load, nds_n13_store,\ --+ nds_n13_load_multiple_1,nds_n13_load_multiple_2, nds_n13_load_multiple_3,\ --+ nds_n13_load_multiple_4,nds_n13_load_multiple_5, nds_n13_load_multiple_6,\ --+ nds_n13_load_multiple_7,nds_n13_load_multiple_8, nds_n13_load_multiple_12,\ --+ nds_n13_store_multiple_1,nds_n13_store_multiple_2, nds_n13_store_multiple_3,\ --+ nds_n13_store_multiple_4,nds_n13_store_multiple_5, nds_n13_store_multiple_6,\ --+ nds_n13_store_multiple_7,nds_n13_store_multiple_8, nds_n13_store_multiple_12" --+ "nds32_n13_load_to_e1_p" --+) --+ --+;; LD -> ALU, ALU_SHIFT_Rb, PBSADA_Rt, BR, ST, SMW(N, 1) --+(define_bypass 2 --+ "nds_n13_load" --+ "nds_n13_alu, nds_n13_alu_shift, nds_n13_pbsada, nds_n13_branch, nds_n13_store,\ --+ nds_n13_store_multiple_1,nds_n13_store_multiple_2, nds_n13_store_multiple_3,\ --+ nds_n13_store_multiple_4,nds_n13_store_multiple_5, nds_n13_store_multiple_6,\ --+ nds_n13_store_multiple_7,nds_n13_store_multiple_8, nds_n13_store_multiple_12" --+ "nds32_n13_load_to_e2_p" --+) --+ --+;; LMW(N, N) -> ALU_E1, PBSAD, PBSADA_RaRb, MUL, MAC_RaRb, DIV, MMU, ADDR_IN --+(define_bypass 3 --+ "nds_n13_load_multiple_1,nds_n13_load_multiple_2, nds_n13_load_multiple_3,\ --+ nds_n13_load_multiple_4,nds_n13_load_multiple_5, nds_n13_load_multiple_6,\ --+ nds_n13_load_multiple_7,nds_n13_load_multiple_8, nds_n13_load_multiple_12" --+ "nds_n13_alu, nds_n13_pbsad, nds_n13_pbsada,\ --+ nds_n13_mul, nds_n13_mac, nds_n13_div,\ --+ nds_n13_mmu,\ --+ nds_n13_load, nds_n13_store,\ --+ nds_n13_load_multiple_1,nds_n13_load_multiple_2, nds_n13_load_multiple_3,\ --+ nds_n13_load_multiple_4,nds_n13_load_multiple_5, nds_n13_load_multiple_6,\ --+ nds_n13_load_multiple_7,nds_n13_load_multiple_8, nds_n13_load_multiple_12,\ --+ nds_n13_store_multiple_1,nds_n13_store_multiple_2, nds_n13_store_multiple_3,\ --+ nds_n13_store_multiple_4,nds_n13_store_multiple_5, nds_n13_store_multiple_6,\ --+ nds_n13_store_multiple_7,nds_n13_store_multiple_8, nds_n13_store_multiple_12" --+ "nds32_n13_last_load_to_e1_p") --+ --+;; LMW(N, N) -> ALU, ALU_SHIFT_Rb, PBSADA_Rt, BR, ST, SMW(N, 1) --+(define_bypass 2 --+ "nds_n13_load_multiple_1,nds_n13_load_multiple_2, nds_n13_load_multiple_3,\ --+ nds_n13_load_multiple_4,nds_n13_load_multiple_5, nds_n13_load_multiple_6,\ --+ nds_n13_load_multiple_7,nds_n13_load_multiple_8, nds_n13_load_multiple_12" --+ "nds_n13_alu, nds_n13_alu_shift, nds_n13_pbsada, nds_n13_branch, nds_n13_store,\ --+ nds_n13_store_multiple_1,nds_n13_store_multiple_2, nds_n13_store_multiple_3,\ --+ nds_n13_store_multiple_4,nds_n13_store_multiple_5, nds_n13_store_multiple_6,\ --+ nds_n13_store_multiple_7,nds_n13_store_multiple_8, nds_n13_store_multiple_12" --+ "nds32_n13_last_load_to_e2_p" --+) --+ --+;; LMW(N, N - 1) -> ALU_E1, PBSAD, PBSADA_RaRb, MUL, MAC_RaRb, DIV, MMU, ADDR_IN --+(define_bypass 2 --+ "nds_n13_load_multiple_1,nds_n13_load_multiple_2, nds_n13_load_multiple_3,\ --+ nds_n13_load_multiple_4,nds_n13_load_multiple_5, nds_n13_load_multiple_6,\ --+ nds_n13_load_multiple_7,nds_n13_load_multiple_8, nds_n13_load_multiple_12" --+ "nds_n13_alu, nds_n13_pbsad, nds_n13_pbsada,\ --+ nds_n13_mul, nds_n13_mac, nds_n13_div,\ --+ nds_n13_mmu,\ --+ nds_n13_load, nds_n13_store,\ --+ nds_n13_load_multiple_1,nds_n13_load_multiple_2, nds_n13_load_multiple_3,\ --+ nds_n13_load_multiple_4,nds_n13_load_multiple_5, nds_n13_load_multiple_6,\ --+ nds_n13_load_multiple_7,nds_n13_load_multiple_8, nds_n13_load_multiple_12,\ --+ nds_n13_store_multiple_1,nds_n13_store_multiple_2, nds_n13_store_multiple_3,\ --+ nds_n13_store_multiple_4,nds_n13_store_multiple_5, nds_n13_store_multiple_6,\ --+ nds_n13_store_multiple_7,nds_n13_store_multiple_8, nds_n13_store_multiple_12" --+ "nds32_n13_last_two_load_to_e1_p") --+ --+;; ALU, ALU_SHIFT, SIMD, BR, MUL, MAC, DIV, ADDR_OUT --+;; -> ALU_E1, PBSAD, PBSADA_RaRb, MUL, MAC_RaRb, DIV, MMU, ADDR_IN --+(define_bypass 2 --+ "nds_n13_alu, nds_n13_alu_shift, nds_n13_pbsad, nds_n13_pbsada, nds_n13_branch,\ --+ nds_n13_mul, nds_n13_mac, nds_n13_div,\ --+ nds_n13_load, nds_n13_store,\ --+ nds_n13_load_multiple_1,nds_n13_load_multiple_2, nds_n13_load_multiple_3,\ --+ nds_n13_load_multiple_4,nds_n13_load_multiple_5, nds_n13_load_multiple_6,\ --+ nds_n13_load_multiple_7,nds_n13_load_multiple_8, nds_n13_load_multiple_12,\ --+ nds_n13_store_multiple_1,nds_n13_store_multiple_2, nds_n13_store_multiple_3,\ --+ nds_n13_store_multiple_4,nds_n13_store_multiple_5, nds_n13_store_multiple_6,\ --+ nds_n13_store_multiple_7,nds_n13_store_multiple_8, nds_n13_store_multiple_12" --+ "nds_n13_alu, nds_n13_pbsad, nds_n13_pbsada,\ --+ nds_n13_mul, nds_n13_mac, nds_n13_div,\ --+ nds_n13_mmu,\ --+ nds_n13_load, nds_n13_store,\ --+ nds_n13_load_multiple_1,nds_n13_load_multiple_2, nds_n13_load_multiple_3,\ --+ nds_n13_load_multiple_4,nds_n13_load_multiple_5, nds_n13_load_multiple_6,\ --+ nds_n13_load_multiple_7,nds_n13_load_multiple_8, nds_n13_load_multiple_12,\ --+ nds_n13_store_multiple_1,nds_n13_store_multiple_2, nds_n13_store_multiple_3,\ --+ nds_n13_store_multiple_4,nds_n13_store_multiple_5, nds_n13_store_multiple_6,\ --+ nds_n13_store_multiple_7,nds_n13_store_multiple_8, nds_n13_store_multiple_12" --+ "nds32_n13_e2_to_e1_p") --diff --git a/gcc/config/nds32/nds32-n7.md b/gcc/config/nds32/nds32-n7.md --new file mode 100644 --index 0000000..ff788ce ----- /dev/null --+++ b/gcc/config/nds32/nds32-n7.md --@@ -0,0 +1,298 @@ --+;; Pipeline descriptions of Andes NDS32 cpu for GNU compiler --+;; Copyright (C) 2012-2016 Free Software Foundation, Inc. --+;; Contributed by Andes Technology Corporation. --+;; --+;; This file is part of GCC. --+;; --+;; GCC is free software; you can redistribute it and/or modify it --+;; under the terms of the GNU General Public License as published --+;; by the Free Software Foundation; either version 3, or (at your --+;; option) any later version. --+;; --+;; GCC is distributed in the hope that it will be useful, but WITHOUT --+;; ANY WARRANTY; without even the implied warranty of MERCHANTABILITY --+;; or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public --+;; License for more details. --+;; --+;; You should have received a copy of the GNU General Public License --+;; along with GCC; see the file COPYING3. If not see --+;; . --+ --+ --+;; ------------------------------------------------------------------------ --+;; Define N8 pipeline settings. --+;; ------------------------------------------------------------------------ --+ --+(define_automaton "nds32_n7_machine") --+ --+;; ------------------------------------------------------------------------ --+;; Pipeline Stages --+;; ------------------------------------------------------------------------ --+;; IF - Instruction Fetch --+;; Instruction Alignment --+;; Instruction Pre-decode --+;; II - Instruction Issue --+;; Instruction Decode --+;; Register File Access --+;; Instruction Execution --+;; Interrupt Handling --+;; EXD - Psuedo Stage --+;; Load Data Completion --+ --+(define_cpu_unit "n7_ii" "nds32_n7_machine") --+ --+(define_insn_reservation "nds_n7_unknown" 1 --+ (and (eq_attr "type" "unknown") --+ (eq_attr "pipeline_model" "n7")) --+ "n7_ii") --+ --+(define_insn_reservation "nds_n7_misc" 1 --+ (and (eq_attr "type" "misc") --+ (eq_attr "pipeline_model" "n7")) --+ "n7_ii") --+ --+(define_insn_reservation "nds_n7_alu" 1 --+ (and (eq_attr "type" "alu") --+ (eq_attr "pipeline_model" "n7")) --+ "n7_ii") --+ --+(define_insn_reservation "nds_n7_load" 1 --+ (and (match_test "nds32::load_single_p (insn)") --+ (eq_attr "pipeline_model" "n7")) --+ "n7_ii") --+ --+(define_insn_reservation "nds_n7_store" 1 --+ (and (match_test "nds32::store_single_p (insn)") --+ (eq_attr "pipeline_model" "n7")) --+ "n7_ii") --+ --+(define_insn_reservation "nds_n7_load_multiple_1" 1 --+ (and (and (eq_attr "type" "load_multiple") --+ (eq_attr "combo" "1")) --+ (eq_attr "pipeline_model" "n7")) --+ "n7_ii") --+ --+(define_insn_reservation "nds_n7_load_multiple_2" 1 --+ (and (ior (and (eq_attr "type" "load_multiple") --+ (eq_attr "combo" "2")) --+ (match_test "nds32::load_double_p (insn)")) --+ (eq_attr "pipeline_model" "n7")) --+ "n7_ii*2") --+ --+(define_insn_reservation "nds_n7_load_multiple_3" 1 --+ (and (and (eq_attr "type" "load_multiple") --+ (eq_attr "combo" "3")) --+ (eq_attr "pipeline_model" "n7")) --+ "n7_ii*3") --+ --+(define_insn_reservation "nds_n7_load_multiple_4" 1 --+ (and (and (eq_attr "type" "load_multiple") --+ (eq_attr "combo" "4")) --+ (eq_attr "pipeline_model" "n7")) --+ "n7_ii*4") --+ --+(define_insn_reservation "nds_n7_load_multiple_5" 1 --+ (and (and (eq_attr "type" "load_multiple") --+ (eq_attr "combo" "5")) --+ (eq_attr "pipeline_model" "n7")) --+ "n7_ii*5") --+ --+(define_insn_reservation "nds_n7_load_multiple_6" 1 --+ (and (and (eq_attr "type" "load_multiple") --+ (eq_attr "combo" "6")) --+ (eq_attr "pipeline_model" "n7")) --+ "n7_ii*6") --+ --+(define_insn_reservation "nds_n7_load_multiple_7" 1 --+ (and (and (eq_attr "type" "load_multiple") --+ (eq_attr "combo" "7")) --+ (eq_attr "pipeline_model" "n7")) --+ "n7_ii*7") --+ --+(define_insn_reservation "nds_n7_load_multiple_8" 1 --+ (and (and (eq_attr "type" "load_multiple") --+ (eq_attr "combo" "8")) --+ (eq_attr "pipeline_model" "n7")) --+ "n7_ii*8") --+ --+(define_insn_reservation "nds_n7_load_multiple_12" 1 --+ (and (and (eq_attr "type" "load_multiple") --+ (eq_attr "combo" "12")) --+ (eq_attr "pipeline_model" "n7")) --+ "n7_ii*12") --+ --+(define_insn_reservation "nds_n7_store_multiple_1" 1 --+ (and (and (eq_attr "type" "store_multiple") --+ (eq_attr "combo" "1")) --+ (eq_attr "pipeline_model" "n7")) --+ "n7_ii") --+ --+(define_insn_reservation "nds_n7_store_multiple_2" 1 --+ (and (ior (and (eq_attr "type" "store_multiple") --+ (eq_attr "combo" "2")) --+ (match_test "nds32::store_double_p (insn)")) --+ (eq_attr "pipeline_model" "n7")) --+ "n7_ii*2") --+ --+(define_insn_reservation "nds_n7_store_multiple_3" 1 --+ (and (and (eq_attr "type" "store_multiple") --+ (eq_attr "combo" "3")) --+ (eq_attr "pipeline_model" "n7")) --+ "n7_ii*3") --+ --+(define_insn_reservation "nds_n7_store_multiple_4" 1 --+ (and (and (eq_attr "type" "store_multiple") --+ (eq_attr "combo" "4")) --+ (eq_attr "pipeline_model" "n7")) --+ "n7_ii*4") --+ --+(define_insn_reservation "nds_n7_store_multiple_5" 1 --+ (and (and (eq_attr "type" "store_multiple") --+ (eq_attr "combo" "5")) --+ (eq_attr "pipeline_model" "n7")) --+ "n7_ii*5") --+ --+(define_insn_reservation "nds_n7_store_multiple_6" 1 --+ (and (and (eq_attr "type" "store_multiple") --+ (eq_attr "combo" "6")) --+ (eq_attr "pipeline_model" "n7")) --+ "n7_ii*6") --+ --+(define_insn_reservation "nds_n7_store_multiple_7" 1 --+ (and (and (eq_attr "type" "store_multiple") --+ (eq_attr "combo" "7")) --+ (eq_attr "pipeline_model" "n7")) --+ "n7_ii*7") --+ --+(define_insn_reservation "nds_n7_store_multiple_8" 1 --+ (and (and (eq_attr "type" "store_multiple") --+ (eq_attr "combo" "8")) --+ (eq_attr "pipeline_model" "n7")) --+ "n7_ii*8") --+ --+(define_insn_reservation "nds_n7_store_multiple_12" 1 --+ (and (and (eq_attr "type" "store_multiple") --+ (eq_attr "combo" "12")) --+ (eq_attr "pipeline_model" "n7")) --+ "n7_ii*12") --+ --+(define_insn_reservation "nds_n7_mul_fast" 1 --+ (and (match_test "nds32_mul_config != MUL_TYPE_SLOW") --+ (and (eq_attr "type" "mul") --+ (eq_attr "pipeline_model" "n7"))) --+ "n7_ii") --+ --+(define_insn_reservation "nds_n7_mul_slow" 1 --+ (and (match_test "nds32_mul_config == MUL_TYPE_SLOW") --+ (and (eq_attr "type" "mul") --+ (eq_attr "pipeline_model" "n7"))) --+ "n7_ii*17") --+ --+(define_insn_reservation "nds_n7_mac_fast" 1 --+ (and (match_test "nds32_mul_config != MUL_TYPE_SLOW") --+ (and (eq_attr "type" "mac") --+ (eq_attr "pipeline_model" "n7"))) --+ "n7_ii*2") --+ --+(define_insn_reservation "nds_n7_mac_slow" 1 --+ (and (match_test "nds32_mul_config == MUL_TYPE_SLOW") --+ (and (eq_attr "type" "mac") --+ (eq_attr "pipeline_model" "n7"))) --+ "n7_ii*18") --+ --+(define_insn_reservation "nds_n7_div" 1 --+ (and (eq_attr "type" "div") --+ (eq_attr "pipeline_model" "n7")) --+ "n7_ii*37") --+ --+(define_insn_reservation "nds_n7_branch" 1 --+ (and (eq_attr "type" "branch") --+ (eq_attr "pipeline_model" "n7")) --+ "n7_ii") --+ --+;; ------------------------------------------------------------------------ --+;; Comment Notations and Bypass Rules --+;; ------------------------------------------------------------------------ --+;; Producers (LHS) --+;; LD_!bi --+;; Load data from the memory (without updating the base register) and --+;; produce the loaded data. The result is ready at EXD. --+;; LMW(N, M) --+;; There are N micro-operations within an instruction that loads multiple --+;; words. The result produced by the M-th micro-operation is sent to --+;; consumers. The result is ready at EXD. If the base register should be --+;; updated, an extra micro-operation is inserted to the sequence, and the --+;; result is ready at II. --+;; --+;; Consumers (RHS) --+;; ALU, MUL, DIV --+;; Require operands at II. --+;; MOVD44_E --+;; A double-word move instruction needs two micro-operations because the --+;; reigster ports is 2R1W. The first micro-operation writes an even number --+;; register, and the second micro-operation writes an odd number register. --+;; Each input operand is required at II for each micro-operation. The letter --+;; 'E' stands for even. --+;; MAC_RaRb --+;; A MAC instruction is separated into two micro-operations. The first --+;; micro-operation does the multiplication, which requires operands Ra --+;; and Rb at II. The second micro-options does the accumulation, which --+;; requires the operand Rt at II. --+;; ADDR_IN_MOP(N) --+;; Because the reigster port is 2R1W, some load/store instructions are --+;; separated into many micro-operations. N denotes the address input is --+;; required by the N-th micro-operation. Such operand is required at II. --+;; ST_bi --+;; A post-increment store instruction requires its data at II. --+;; ST_!bi_RI --+;; A store instruction with an immediate offset requires its data at II. --+;; If the offset field is a register (ST_!bi_RR), the instruction will be --+;; separated into two micro-operations, and the second one requires the --+;; input operand at II in order to store it to the memory. --+;; SMW(N, M) --+;; There are N micro-operations within an instruction that stores multiple --+;; words. Each M-th micro-operation requires its data at II. If the base --+;; register should be updated, an extra micro-operation is inserted to the --+;; sequence. --+;; BR_COND --+;; If a branch instruction is conditional, its input data is required at II. --+ --+;; LD_!bi --+;; -> ALU, MOVD44_E, MUL, MAC_RaRb, DIV, BR, ADDR_IN_MOP(1), ST_bi, ST_!bi_RI, SMW(N, 1) --+(define_bypass 2 --+ "nds_n7_load" --+ "nds_n7_alu,\ --+ nds_n7_mul_fast, nds_n7_mul_slow,\ --+ nds_n7_mac_fast, nds_n7_mac_slow,\ --+ nds_n7_div,\ --+ nds_n7_branch,\ --+ nds_n7_load, nds_n7_store,\ --+ nds_n7_load_multiple_1,nds_n7_load_multiple_2, nds_n7_load_multiple_3,\ --+ nds_n7_load_multiple_4,nds_n7_load_multiple_5, nds_n7_load_multiple_6,\ --+ nds_n7_load_multiple_7,nds_n7_load_multiple_8, nds_n7_load_multiple_12,\ --+ nds_n7_store_multiple_1,nds_n7_store_multiple_2, nds_n7_store_multiple_3,\ --+ nds_n7_store_multiple_4,nds_n7_store_multiple_5, nds_n7_store_multiple_6,\ --+ nds_n7_store_multiple_7,nds_n7_store_multiple_8, nds_n7_store_multiple_12" --+ "nds32_n7_load_to_ii_p" --+) --+ --+;; LMW(N, N) --+;; -> ALU, MOVD44_E, MUL, MAC_RaRb, DIV, BR, AADR_IN_MOP(1), ST_bi, ST_!bi_RI, SMW(N, 1) --+(define_bypass 2 --+ "nds_n7_load_multiple_1,nds_n7_load_multiple_2, nds_n7_load_multiple_3,\ --+ nds_n7_load_multiple_4,nds_n7_load_multiple_5, nds_n7_load_multiple_6,\ --+ nds_n7_load_multiple_7,nds_n7_load_multiple_8, nds_n7_load_multiple_12" --+ "nds_n7_alu,\ --+ nds_n7_mul_fast, nds_n7_mul_slow,\ --+ nds_n7_mac_fast, nds_n7_mac_slow,\ --+ nds_n7_div,\ --+ nds_n7_branch,\ --+ nds_n7_load, nds_n7_store,\ --+ nds_n7_load_multiple_1,nds_n7_load_multiple_2, nds_n7_load_multiple_3,\ --+ nds_n7_load_multiple_4,nds_n7_load_multiple_5, nds_n7_load_multiple_6,\ --+ nds_n7_load_multiple_7,nds_n7_load_multiple_8, nds_n7_load_multiple_12,\ --+ nds_n7_store_multiple_1,nds_n7_store_multiple_2, nds_n7_store_multiple_3,\ --+ nds_n7_store_multiple_4,nds_n7_store_multiple_5, nds_n7_store_multiple_6,\ --+ nds_n7_store_multiple_7,nds_n7_store_multiple_8, nds_n7_store_multiple_12" --+ "nds32_n7_last_load_to_ii_p" --+) --diff --git a/gcc/config/nds32/nds32-n8.md b/gcc/config/nds32/nds32-n8.md --new file mode 100644 --index 0000000..c3db9cd ----- /dev/null --+++ b/gcc/config/nds32/nds32-n8.md --@@ -0,0 +1,389 @@ --+;; Pipeline descriptions of Andes NDS32 cpu for GNU compiler --+;; Copyright (C) 2012-2016 Free Software Foundation, Inc. --+;; Contributed by Andes Technology Corporation. --+;; --+;; This file is part of GCC. --+;; --+;; GCC is free software; you can redistribute it and/or modify it --+;; under the terms of the GNU General Public License as published --+;; by the Free Software Foundation; either version 3, or (at your --+;; option) any later version. --+;; --+;; GCC is distributed in the hope that it will be useful, but WITHOUT --+;; ANY WARRANTY; without even the implied warranty of MERCHANTABILITY --+;; or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public --+;; License for more details. --+;; --+;; You should have received a copy of the GNU General Public License --+;; along with GCC; see the file COPYING3. If not see --+;; . --+ --+ --+;; ------------------------------------------------------------------------ --+;; Define N8 pipeline settings. --+;; ------------------------------------------------------------------------ --+ --+(define_automaton "nds32_n8_machine") --+ --+;; ------------------------------------------------------------------------ --+;; Pipeline Stages --+;; ------------------------------------------------------------------------ --+;; IF - Instruction Fetch --+;; II - Instruction Issue / Address Generation --+;; EX - Instruction Execution --+;; EXD - Psuedo Stage / Load Data Completion --+ --+(define_cpu_unit "n8_ii" "nds32_n8_machine") --+(define_cpu_unit "n8_ex" "nds32_n8_machine") --+ --+(define_insn_reservation "nds_n8_unknown" 1 --+ (and (eq_attr "type" "unknown") --+ (eq_attr "pipeline_model" "n8")) --+ "n8_ii, n8_ex") --+ --+(define_insn_reservation "nds_n8_misc" 1 --+ (and (eq_attr "type" "misc") --+ (eq_attr "pipeline_model" "n8")) --+ "n8_ii, n8_ex") --+ --+(define_insn_reservation "nds_n8_alu" 1 --+ (and (eq_attr "type" "alu") --+ (eq_attr "pipeline_model" "n8")) --+ "n8_ii, n8_ex") --+ --+(define_insn_reservation "nds_n8_load" 1 --+ (and (match_test "nds32::load_single_p (insn)") --+ (eq_attr "pipeline_model" "n8")) --+ "n8_ii, n8_ex") --+ --+(define_insn_reservation "nds_n8_store" 1 --+ (and (match_test "nds32::store_single_p (insn)") --+ (eq_attr "pipeline_model" "n8")) --+ "n8_ii, n8_ex") --+ --+(define_insn_reservation "nds_n8_load_multiple_1" 1 --+ (and (and (eq_attr "type" "load_multiple") --+ (eq_attr "combo" "1")) --+ (eq_attr "pipeline_model" "n8")) --+ "n8_ii, n8_ex") --+ --+(define_insn_reservation "nds_n8_load_multiple_2" 1 --+ (and (ior (and (eq_attr "type" "load_multiple") --+ (eq_attr "combo" "2")) --+ (match_test "nds32::load_double_p (insn)")) --+ (eq_attr "pipeline_model" "n8")) --+ "n8_ii, n8_ii+n8_ex, n8_ex") --+ --+(define_insn_reservation "nds_n8_load_multiple_3" 1 --+ (and (and (eq_attr "type" "load_multiple") --+ (eq_attr "combo" "3")) --+ (eq_attr "pipeline_model" "n8")) --+ "n8_ii, (n8_ii+n8_ex)*2, n8_ex") --+ --+(define_insn_reservation "nds_n8_load_multiple_4" 1 --+ (and (and (eq_attr "type" "load_multiple") --+ (eq_attr "combo" "4")) --+ (eq_attr "pipeline_model" "n8")) --+ "n8_ii, (n8_ii+n8_ex)*3, n8_ex") --+ --+(define_insn_reservation "nds_n8_load_multiple_5" 1 --+ (and (and (eq_attr "type" "load_multiple") --+ (eq_attr "combo" "5")) --+ (eq_attr "pipeline_model" "n8")) --+ "n8_ii, (n8_ii+n8_ex)*4, n8_ex") --+ --+(define_insn_reservation "nds_n8_load_multiple_6" 1 --+ (and (and (eq_attr "type" "load_multiple") --+ (eq_attr "combo" "6")) --+ (eq_attr "pipeline_model" "n8")) --+ "n8_ii, (n8_ii+n8_ex)*5, n8_ex") --+ --+(define_insn_reservation "nds_n8_load_multiple_7" 1 --+ (and (and (eq_attr "type" "load_multiple") --+ (eq_attr "combo" "7")) --+ (eq_attr "pipeline_model" "n8")) --+ "n8_ii, (n8_ii+n8_ex)*6, n8_ex") --+ --+(define_insn_reservation "nds_n8_load_multiple_8" 1 --+ (and (and (eq_attr "type" "load_multiple") --+ (eq_attr "combo" "8")) --+ (eq_attr "pipeline_model" "n8")) --+ "n8_ii, (n8_ii+n8_ex)*7, n8_ex") --+ --+(define_insn_reservation "nds_n8_load_multiple_12" 1 --+ (and (and (eq_attr "type" "load_multiple") --+ (eq_attr "combo" "12")) --+ (eq_attr "pipeline_model" "n8")) --+ "n8_ii, (n8_ii+n8_ex)*11, n8_ex") --+ --+(define_insn_reservation "nds_n8_store_multiple_1" 1 --+ (and (and (eq_attr "type" "store_multiple") --+ (eq_attr "combo" "1")) --+ (eq_attr "pipeline_model" "n8")) --+ "n8_ii, n8_ex") --+ --+(define_insn_reservation "nds_n8_store_multiple_2" 1 --+ (and (ior (and (eq_attr "type" "store_multiple") --+ (eq_attr "combo" "2")) --+ (match_test "nds32::store_double_p (insn)")) --+ (eq_attr "pipeline_model" "n8")) --+ "n8_ii, n8_ii+n8_ex, n8_ex") --+ --+(define_insn_reservation "nds_n8_store_multiple_3" 1 --+ (and (and (eq_attr "type" "store_multiple") --+ (eq_attr "combo" "3")) --+ (eq_attr "pipeline_model" "n8")) --+ "n8_ii, (n8_ii+n8_ex)*2, n8_ex") --+ --+(define_insn_reservation "nds_n8_store_multiple_4" 1 --+ (and (and (eq_attr "type" "store_multiple") --+ (eq_attr "combo" "4")) --+ (eq_attr "pipeline_model" "n8")) --+ "n8_ii, (n8_ii+n8_ex)*3, n8_ex") --+ --+(define_insn_reservation "nds_n8_store_multiple_5" 1 --+ (and (and (eq_attr "type" "store_multiple") --+ (eq_attr "combo" "5")) --+ (eq_attr "pipeline_model" "n8")) --+ "n8_ii, (n8_ii+n8_ex)*4, n8_ex") --+ --+(define_insn_reservation "nds_n8_store_multiple_6" 1 --+ (and (and (eq_attr "type" "store_multiple") --+ (eq_attr "combo" "6")) --+ (eq_attr "pipeline_model" "n8")) --+ "n8_ii, (n8_ii+n8_ex)*5, n8_ex") --+ --+(define_insn_reservation "nds_n8_store_multiple_7" 1 --+ (and (and (eq_attr "type" "store_multiple") --+ (eq_attr "combo" "7")) --+ (eq_attr "pipeline_model" "n8")) --+ "n8_ii, (n8_ii+n8_ex)*6, n8_ex") --+ --+(define_insn_reservation "nds_n8_store_multiple_8" 1 --+ (and (and (eq_attr "type" "store_multiple") --+ (eq_attr "combo" "8")) --+ (eq_attr "pipeline_model" "n8")) --+ "n8_ii, (n8_ii+n8_ex)*7, n8_ex") --+ --+(define_insn_reservation "nds_n8_store_multiple_12" 1 --+ (and (and (eq_attr "type" "store_multiple") --+ (eq_attr "combo" "12")) --+ (eq_attr "pipeline_model" "n8")) --+ "n8_ii, (n8_ii+n8_ex)*11, n8_ex") --+ --+(define_insn_reservation "nds_n8_mul_fast" 1 --+ (and (match_test "nds32_mul_config != MUL_TYPE_SLOW") --+ (and (eq_attr "type" "mul") --+ (eq_attr "pipeline_model" "n8"))) --+ "n8_ii, n8_ex") --+ --+(define_insn_reservation "nds_n8_mul_slow" 1 --+ (and (match_test "nds32_mul_config == MUL_TYPE_SLOW") --+ (and (eq_attr "type" "mul") --+ (eq_attr "pipeline_model" "n8"))) --+ "n8_ii, n8_ex*16") --+ --+(define_insn_reservation "nds_n8_mac_fast" 1 --+ (and (match_test "nds32_mul_config != MUL_TYPE_SLOW") --+ (and (eq_attr "type" "mac") --+ (eq_attr "pipeline_model" "n8"))) --+ "n8_ii, n8_ii+n8_ex, n8_ex") --+ --+(define_insn_reservation "nds_n8_mac_slow" 1 --+ (and (match_test "nds32_mul_config == MUL_TYPE_SLOW") --+ (and (eq_attr "type" "mac") --+ (eq_attr "pipeline_model" "n8"))) --+ "n8_ii, (n8_ii+n8_ex)*16, n8_ex") --+ --+(define_insn_reservation "nds_n8_div" 1 --+ (and (eq_attr "type" "div") --+ (eq_attr "pipeline_model" "n8")) --+ "n8_ii, (n8_ii+n8_ex)*36, n8_ex") --+ --+(define_insn_reservation "nds_n8_branch" 1 --+ (and (eq_attr "type" "branch") --+ (eq_attr "pipeline_model" "n8")) --+ "n8_ii, n8_ex") --+ --+;; ------------------------------------------------------------------------ --+;; Comment Notations and Bypass Rules --+;; ------------------------------------------------------------------------ --+;; Producers (LHS) --+;; LD_!bi --+;; Load data from the memory (without updating the base register) and --+;; produce the loaded data. The result is ready at EXD. --+;; LD_bi --+;; Load data from the memory (with updating the base register) and --+;; produce the loaded data. The result is ready at EXD. Because the --+;; register port is 2R1W, two micro-operations are required in order --+;; to write two registers. The base register is updated by the second --+;; micro-operation and the result is ready at EX. --+;; LMW(N, M) --+;; There are N micro-operations within an instruction that loads multiple --+;; words. The result produced by the M-th micro-operation is sent to --+;; consumers. The result is ready at EXD. If the base register should be --+;; updated, an extra micro-operation is inserted to the sequence, and the --+;; result is ready at EX. --+;; ADDR_OUT --+;; Most load/store instructions can produce an address output if updating --+;; the base register is required. The result is ready at EX, which is --+;; produced by ALU. --+;; ALU, MUL, MAC --+;; The result is ready at EX. --+;; MOVD44_O --+;; A double-word move instruction needs to write registers twice. Because --+;; the register port is 2R1W, two micro-operations are required. The even --+;; number reigster is updated by the first one, and the odd number register --+;; is updated by the second one. Each of the results is ready at EX. --+;; The letter 'O' stands for odd. --+;; DIV_Rs --+;; A division instruction saves the quotient result to Rt and saves the --+;; remainder result to Rs. It requires two micro-operations because the --+;; register port is 2R1W. The first micro-operation writes to Rt, and --+;; the seconde one writes to Rs. Each of the results is ready at EX. --+;; --+;; Consumers (RHS) --+;; ALU, MUL, DIV --+;; Require operands at EX. --+;; MOVD44_E --+;; The letter 'E' stands for even, which is accessed by the first micro- --+;; operation and a movd44 instruction. The operand is required at EX. --+;; MAC_RaRb --+;; A MAC instruction is separated into two micro-operations. The first --+;; micro-operation does the multiplication, which requires operands Ra --+;; and Rb at EX. The second micro-options does the accumulation, which --+;; requires the operand Rt at EX. --+;; ADDR_IN_MOP(N) --+;; Because the reigster port is 2R1W, some load/store instructions are --+;; separated into many micro-operations. N denotes the address input is --+;; required by the N-th micro-operation. Such operand is required at II. --+;; ST_bi --+;; A post-increment store instruction requires its data at EX. --+;; ST_!bi_RI --+;; A store instruction with an immediate offset requires its data at EX. --+;; If the offset field is a register (ST_!bi_RR), the instruction will be --+;; separated into two micro-operations, and the second one requires the --+;; input operand at EX in order to store it to the memory. --+;; SMW(N, M) --+;; There are N micro-operations within an instruction that stores multiple --+;; words. Each M-th micro-operation requires its data at EX. If the base --+;; register should be updated, an extra micro-operation is inserted to the --+;; sequence. --+;; BR_COND --+;; If a branch instruction is conditional, its input data is required at EX. --+ --+;; LD_!bi -> ADDR_IN_MOP(1) --+(define_bypass 3 --+ "nds_n8_load" --+ "nds_n8_branch,\ --+ nds_n8_load, nds_n8_store,\ --+ nds_n8_load_multiple_1,nds_n8_load_multiple_2, nds_n8_load_multiple_3,\ --+ nds_n8_load_multiple_4,nds_n8_load_multiple_5, nds_n8_load_multiple_6,\ --+ nds_n8_load_multiple_7,nds_n8_load_multiple_8, nds_n8_load_multiple_12,\ --+ nds_n8_store_multiple_1,nds_n8_store_multiple_2, nds_n8_store_multiple_3,\ --+ nds_n8_store_multiple_4,nds_n8_store_multiple_5, nds_n8_store_multiple_6,\ --+ nds_n8_store_multiple_7,nds_n8_store_multiple_8, nds_n8_store_multiple_12" --+ "nds32_n8_load_to_ii_p" --+) --+ --+;; LMW(N, N) -> ADDR_IN_MOP(1) --+(define_bypass 3 --+ "nds_n8_load_multiple_1,nds_n8_load_multiple_2, nds_n8_load_multiple_3,\ --+ nds_n8_load_multiple_4,nds_n8_load_multiple_5, nds_n8_load_multiple_6,\ --+ nds_n8_load_multiple_7,nds_n8_load_multiple_8, nds_n8_load_multiple_12" --+ "nds_n8_branch,\ --+ nds_n8_load, nds_n8_store,\ --+ nds_n8_load_multiple_1,nds_n8_load_multiple_2, nds_n8_load_multiple_3,\ --+ nds_n8_load_multiple_4,nds_n8_load_multiple_5, nds_n8_load_multiple_6,\ --+ nds_n8_load_multiple_7,nds_n8_load_multiple_8, nds_n8_load_multiple_12,\ --+ nds_n8_store_multiple_1,nds_n8_store_multiple_2, nds_n8_store_multiple_3,\ --+ nds_n8_store_multiple_4,nds_n8_store_multiple_5, nds_n8_store_multiple_6,\ --+ nds_n8_store_multiple_7,nds_n8_store_multiple_8, nds_n8_store_multiple_12" --+ "nds32_n8_last_load_to_ii_p" --+) --+ --+;; LMW(N, N - 1) -> ADDR_IN_MOP(1) --+(define_bypass 2 --+ "nds_n8_load_multiple_1,nds_n8_load_multiple_2, nds_n8_load_multiple_3,\ --+ nds_n8_load_multiple_4,nds_n8_load_multiple_5, nds_n8_load_multiple_6,\ --+ nds_n8_load_multiple_7,nds_n8_load_multiple_8, nds_n8_load_multiple_12" --+ "nds_n8_branch,\ --+ nds_n8_load, nds_n8_store,\ --+ nds_n8_load_multiple_1,nds_n8_load_multiple_2, nds_n8_load_multiple_3,\ --+ nds_n8_load_multiple_4,nds_n8_load_multiple_5, nds_n8_load_multiple_6,\ --+ nds_n8_load_multiple_7,nds_n8_load_multiple_8, nds_n8_load_multiple_12,\ --+ nds_n8_store_multiple_1,nds_n8_store_multiple_2, nds_n8_store_multiple_3,\ --+ nds_n8_store_multiple_4,nds_n8_store_multiple_5, nds_n8_store_multiple_6,\ --+ nds_n8_store_multiple_7,nds_n8_store_multiple_8, nds_n8_store_multiple_12" --+ "nds32_n8_last_load_two_to_ii_p" --+) --+ --+;; LD_bi -> ADDR_IN_MOP(1) --+(define_bypass 2 --+ "nds_n8_load" --+ "nds_n8_branch,\ --+ nds_n8_load, nds_n8_store,\ --+ nds_n8_load_multiple_1,nds_n8_load_multiple_2, nds_n8_load_multiple_3,\ --+ nds_n8_load_multiple_4,nds_n8_load_multiple_5, nds_n8_load_multiple_6,\ --+ nds_n8_load_multiple_7,nds_n8_load_multiple_8, nds_n8_load_multiple_12,\ --+ nds_n8_store_multiple_1,nds_n8_store_multiple_2, nds_n8_store_multiple_3,\ --+ nds_n8_store_multiple_4,nds_n8_store_multiple_5, nds_n8_store_multiple_6,\ --+ nds_n8_store_multiple_7,nds_n8_store_multiple_8, nds_n8_store_multiple_12" --+ "nds32_n8_load_bi_to_ii_p" --+) --+ --+;; LD_!bi -> ALU, MOVD44_E, MUL, MAC_RaRb, DIV, BR_COND, ST_bi, ST_!bi_RI, SMW(N, 1) --+(define_bypass 2 --+ "nds_n8_load" --+ "nds_n8_alu, --+ nds_n8_mul_fast, nds_n8_mul_slow,\ --+ nds_n8_mac_fast, nds_n8_mac_slow,\ --+ nds_n8_div,\ --+ nds_n8_branch,\ --+ nds_n8_store,\ --+ nds_n8_store_multiple_1,nds_n8_store_multiple_2, nds_n8_store_multiple_3,\ --+ nds_n8_store_multiple_4,nds_n8_store_multiple_5, nds_n8_store_multiple_6,\ --+ nds_n8_store_multiple_7,nds_n8_store_multiple_8, nds_n8_store_multiple_12" --+ "nds32_n8_load_to_ex_p" --+) --+ --+;; ALU, MOVD44_O, MUL, MAC, DIV_Rs, LD_bi, ADDR_OUT -> ADDR_IN_MOP(1) --+(define_bypass 2 --+ "nds_n8_alu, --+ nds_n8_mul_fast, nds_n8_mul_slow,\ --+ nds_n8_mac_fast, nds_n8_mac_slow,\ --+ nds_n8_div,\ --+ nds_n8_load, nds_n8_store,\ --+ nds_n8_load_multiple_1,nds_n8_load_multiple_2, nds_n8_load_multiple_3,\ --+ nds_n8_load_multiple_4,nds_n8_load_multiple_5, nds_n8_load_multiple_6,\ --+ nds_n8_load_multiple_7,nds_n8_load_multiple_8, nds_n8_load_multiple_12,\ --+ nds_n8_store_multiple_1,nds_n8_store_multiple_2, nds_n8_store_multiple_3,\ --+ nds_n8_store_multiple_4,nds_n8_store_multiple_5, nds_n8_store_multiple_6,\ --+ nds_n8_store_multiple_7,nds_n8_store_multiple_8, nds_n8_store_multiple_12" --+ "nds_n8_branch,\ --+ nds_n8_load, nds_n8_store,\ --+ nds_n8_load_multiple_1,nds_n8_load_multiple_2, nds_n8_load_multiple_3,\ --+ nds_n8_load_multiple_4,nds_n8_load_multiple_5, nds_n8_load_multiple_6,\ --+ nds_n8_load_multiple_7,nds_n8_load_multiple_8, nds_n8_load_multiple_12,\ --+ nds_n8_store_multiple_1,nds_n8_store_multiple_2, nds_n8_store_multiple_3,\ --+ nds_n8_store_multiple_4,nds_n8_store_multiple_5, nds_n8_store_multiple_6,\ --+ nds_n8_store_multiple_7,nds_n8_store_multiple_8, nds_n8_store_multiple_12" --+ "nds32_n8_ex_to_ii_p" --+) --+ --+;; LMW(N, N) -> ALU, MOVD44_E, MUL, MAC_RaRb, DIV, BR_COND, ST_bi, ST_!bi_RI, SMW(N, 1) --+(define_bypass 2 --+ "nds_n8_load_multiple_1,nds_n8_load_multiple_2, nds_n8_load_multiple_3,\ --+ nds_n8_load_multiple_4,nds_n8_load_multiple_5, nds_n8_load_multiple_6,\ --+ nds_n8_load_multiple_7,nds_n8_load_multiple_8, nds_n8_load_multiple_12" --+ "nds_n8_alu, --+ nds_n8_mul_fast, nds_n8_mul_slow,\ --+ nds_n8_mac_fast, nds_n8_mac_slow,\ --+ nds_n8_div,\ --+ nds_n8_branch,\ --+ nds_n8_store,\ --+ nds_n8_store_multiple_1,nds_n8_store_multiple_2, nds_n8_store_multiple_3,\ --+ nds_n8_store_multiple_4,nds_n8_store_multiple_5, nds_n8_store_multiple_6,\ --+ nds_n8_store_multiple_7,nds_n8_store_multiple_8, nds_n8_store_multiple_12" --+ "nds32_n8_last_load_to_ex_p" --+) --diff --git a/gcc/config/nds32/nds32-n9-2r1w.md b/gcc/config/nds32/nds32-n9-2r1w.md --new file mode 100644 --index 0000000..d0db953 ----- /dev/null --+++ b/gcc/config/nds32/nds32-n9-2r1w.md --@@ -0,0 +1,362 @@ --+;; Pipeline descriptions of Andes NDS32 cpu for GNU compiler --+;; Copyright (C) 2012-2016 Free Software Foundation, Inc. --+;; Contributed by Andes Technology Corporation. --+;; --+;; This file is part of GCC. --+;; --+;; GCC is free software; you can redistribute it and/or modify it --+;; under the terms of the GNU General Public License as published --+;; by the Free Software Foundation; either version 3, or (at your --+;; option) any later version. --+;; --+;; GCC is distributed in the hope that it will be useful, but WITHOUT --+;; ANY WARRANTY; without even the implied warranty of MERCHANTABILITY --+;; or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public --+;; License for more details. --+;; --+;; You should have received a copy of the GNU General Public License --+;; along with GCC; see the file COPYING3. If not see --+;; . --+ --+ --+;; ------------------------------------------------------------------------ --+;; Define N9 2R1W pipeline settings. --+;; ------------------------------------------------------------------------ --+ --+(define_automaton "nds32_n9_2r1w_machine") --+ --+;; ------------------------------------------------------------------------ --+;; Pipeline Stages --+;; ------------------------------------------------------------------------ --+;; IF - Instruction Fetch --+;; II - Instruction Issue / Instruction Decode --+;; EX - Instruction Execution --+;; MM - Memory Execution --+;; WB - Instruction Retire / Result Write-Back --+ --+(define_cpu_unit "n9_2r1w_ii" "nds32_n9_2r1w_machine") --+(define_cpu_unit "n9_2r1w_ex" "nds32_n9_2r1w_machine") --+(define_cpu_unit "n9_2r1w_mm" "nds32_n9_2r1w_machine") --+(define_cpu_unit "n9_2r1w_wb" "nds32_n9_2r1w_machine") --+ --+(define_insn_reservation "nds_n9_2r1w_unknown" 1 --+ (and (match_test "nds32_register_ports_config == REG_PORT_2R1W") --+ (and (eq_attr "type" "unknown") --+ (eq_attr "pipeline_model" "n9"))) --+ "n9_2r1w_ii, n9_2r1w_ex, n9_2r1w_mm, n9_2r1w_wb") --+ --+(define_insn_reservation "nds_n9_2r1w_misc" 1 --+ (and (match_test "nds32_register_ports_config == REG_PORT_2R1W") --+ (and (eq_attr "type" "misc") --+ (eq_attr "pipeline_model" "n9"))) --+ "n9_2r1w_ii, n9_2r1w_ex, n9_2r1w_mm, n9_2r1w_wb") --+ --+(define_insn_reservation "nds_n9_2r1w_mmu" 1 --+ (and (match_test "nds32_register_ports_config == REG_PORT_2R1W") --+ (and (eq_attr "type" "mmu") --+ (eq_attr "pipeline_model" "n9"))) --+ "n9_2r1w_ii, n9_2r1w_ex, n9_2r1w_mm, n9_2r1w_wb") --+ --+(define_insn_reservation "nds_n9_2r1w_alu" 1 --+ (and (match_test "nds32_register_ports_config == REG_PORT_2R1W") --+ (and (eq_attr "type" "alu") --+ (eq_attr "pipeline_model" "n9"))) --+ "n9_2r1w_ii, n9_2r1w_ex, n9_2r1w_mm, n9_2r1w_wb") --+ --+(define_insn_reservation "nds_n9_2r1w_alu_shift" 1 --+ (and (match_test "nds32_register_ports_config == REG_PORT_2R1W") --+ (and (eq_attr "type" "alu_shift") --+ (eq_attr "pipeline_model" "n9"))) --+ "n9_2r1w_ii, n9_2r1w_ii+n9_2r1w_ex, n9_2r1w_ex+n9_2r1w_mm, n9_2r1w_mm+n9_2r1w_wb, n9_2r1w_wb") --+ --+(define_insn_reservation "nds_n9_2r1w_pbsad" 1 --+ (and (match_test "nds32_register_ports_config == REG_PORT_2R1W") --+ (and (eq_attr "type" "pbsad") --+ (eq_attr "pipeline_model" "n9"))) --+ "n9_2r1w_ii, n9_2r1w_ex*3, n9_2r1w_mm, n9_2r1w_wb") --+ --+(define_insn_reservation "nds_n9_2r1w_pbsada" 1 --+ (and (match_test "nds32_register_ports_config == REG_PORT_2R1W") --+ (and (eq_attr "type" "pbsada") --+ (eq_attr "pipeline_model" "n9"))) --+ "n9_2r1w_ii, n9_2r1w_ex*3, n9_2r1w_mm, n9_2r1w_wb") --+ --+(define_insn_reservation "nds_n9_2r1w_load" 1 --+ (and (match_test "nds32_register_ports_config == REG_PORT_2R1W") --+ (and (match_test "nds32::load_single_p (insn)") --+ (eq_attr "pipeline_model" "n9"))) --+ "n9_2r1w_ii, n9_2r1w_ex, n9_2r1w_mm, n9_2r1w_wb") --+ --+(define_insn_reservation "nds_n9_2r1w_store" 1 --+ (and (match_test "nds32_register_ports_config == REG_PORT_2R1W") --+ (and (match_test "nds32::store_single_p (insn)") --+ (eq_attr "pipeline_model" "n9"))) --+ "n9_2r1w_ii, n9_2r1w_ex, n9_2r1w_mm, n9_2r1w_wb") --+ --+(define_insn_reservation "nds_n9_2r1w_load_multiple_1" 1 --+ (and (match_test "nds32_register_ports_config == REG_PORT_2R1W") --+ (and (eq_attr "pipeline_model" "n9") --+ (and (eq_attr "type" "load_multiple") --+ (eq_attr "combo" "1")))) --+ "n9_2r1w_ii, n9_2r1w_ex, n9_2r1w_mm, n9_2r1w_wb") --+ --+(define_insn_reservation "nds_n9_2r1w_load_multiple_2" 1 --+ (and (match_test "nds32_register_ports_config == REG_PORT_2R1W") --+ (and (eq_attr "pipeline_model" "n9") --+ (ior (and (eq_attr "type" "load_multiple") --+ (eq_attr "combo" "2")) --+ (match_test "nds32::load_double_p (insn)")))) --+ "n9_2r1w_ii, n9_2r1w_ii+n9_2r1w_ex, n9_2r1w_ex+n9_2r1w_mm, n9_2r1w_mm+n9_2r1w_wb, n9_2r1w_wb") --+ --+(define_insn_reservation "nds_n9_2r1w_load_multiple_3" 1 --+ (and (match_test "nds32_register_ports_config == REG_PORT_2R1W") --+ (and (eq_attr "pipeline_model" "n9") --+ (and (eq_attr "type" "load_multiple") --+ (eq_attr "combo" "3")))) --+ "n9_2r1w_ii, n9_2r1w_ii+n9_2r1w_ex, n9_2r1w_ii+n9_2r1w_ex+n9_2r1w_mm, n9_2r1w_ex+n9_2r1w_mm+n9_2r1w_wb, n9_2r1w_mm+n9_2r1w_wb, n9_2r1w_wb") --+ --+(define_insn_reservation "nds_n9_2r1w_load_multiple_4" 1 --+ (and (match_test "nds32_register_ports_config == REG_PORT_2R1W") --+ (and (eq_attr "pipeline_model" "n9") --+ (and (eq_attr "type" "load_multiple") --+ (eq_attr "combo" "4")))) --+ "n9_2r1w_ii, n9_2r1w_ii+n9_2r1w_ex, n9_2r1w_ii+n9_2r1w_ex+n9_2r1w_mm, n9_2r1w_ii+n9_2r1w_ex+n9_2r1w_mm+n9_2r1w_wb, n9_2r1w_ex+n9_2r1w_mm+n9_2r1w_wb, n9_2r1w_mm+n9_2r1w_wb, n9_2r1w_wb") --+ --+(define_insn_reservation "nds_n9_2r1w_load_multiple_5" 1 --+ (and (match_test "nds32_register_ports_config == REG_PORT_2R1W") --+ (and (eq_attr "pipeline_model" "n9") --+ (and (eq_attr "type" "load_multiple") --+ (eq_attr "combo" "5")))) --+ "n9_2r1w_ii, n9_2r1w_ii+n9_2r1w_ex, n9_2r1w_ii+n9_2r1w_ex+n9_2r1w_mm, (n9_2r1w_ii+n9_2r1w_ex+n9_2r1w_mm+n9_2r1w_wb)*2, n9_2r1w_ex+n9_2r1w_mm+n9_2r1w_wb, n9_2r1w_mm+n9_2r1w_wb, n9_2r1w_wb") --+ --+(define_insn_reservation "nds_n9_2r1w_load_multiple_6" 1 --+ (and (match_test "nds32_register_ports_config == REG_PORT_2R1W") --+ (and (eq_attr "pipeline_model" "n9") --+ (and (eq_attr "type" "load_multiple") --+ (eq_attr "combo" "6")))) --+ "n9_2r1w_ii, n9_2r1w_ii+n9_2r1w_ex, n9_2r1w_ii+n9_2r1w_ex+n9_2r1w_mm, (n9_2r1w_ii+n9_2r1w_ex+n9_2r1w_mm+n9_2r1w_wb)*3, n9_2r1w_ex+n9_2r1w_mm+n9_2r1w_wb, n9_2r1w_mm+n9_2r1w_wb, n9_2r1w_wb") --+ --+(define_insn_reservation "nds_n9_2r1w_load_multiple_7" 1 --+ (and (match_test "nds32_register_ports_config == REG_PORT_2R1W") --+ (and (eq_attr "pipeline_model" "n9") --+ (and (eq_attr "type" "load_multiple") --+ (eq_attr "combo" "7")))) --+ "n9_2r1w_ii, n9_2r1w_ii+n9_2r1w_ex, n9_2r1w_ii+n9_2r1w_ex+n9_2r1w_mm, (n9_2r1w_ii+n9_2r1w_ex+n9_2r1w_mm+n9_2r1w_wb)*4, n9_2r1w_ex+n9_2r1w_mm+n9_2r1w_wb, n9_2r1w_mm+n9_2r1w_wb, n9_2r1w_wb") --+ --+(define_insn_reservation "nds_n9_2r1w_load_multiple_8" 1 --+ (and (match_test "nds32_register_ports_config == REG_PORT_2R1W") --+ (and (eq_attr "pipeline_model" "n9") --+ (and (eq_attr "type" "load_multiple") --+ (eq_attr "combo" "8")))) --+ "n9_2r1w_ii, n9_2r1w_ii+n9_2r1w_ex, n9_2r1w_ii+n9_2r1w_ex+n9_2r1w_mm, (n9_2r1w_ii+n9_2r1w_ex+n9_2r1w_mm+n9_2r1w_wb)*5, n9_2r1w_ex+n9_2r1w_mm+n9_2r1w_wb, n9_2r1w_mm+n9_2r1w_wb, n9_2r1w_wb") --+ --+(define_insn_reservation "nds_n9_2r1w_load_multiple_12" 1 --+ (and (match_test "nds32_register_ports_config == REG_PORT_2R1W") --+ (and (eq_attr "pipeline_model" "n9") --+ (and (eq_attr "type" "load_multiple") --+ (eq_attr "combo" "12")))) --+ "n9_2r1w_ii, n9_2r1w_ii+n9_2r1w_ex, n9_2r1w_ii+n9_2r1w_ex+n9_2r1w_mm, (n9_2r1w_ii+n9_2r1w_ex+n9_2r1w_mm+n9_2r1w_wb)*9, n9_2r1w_ex+n9_2r1w_mm+n9_2r1w_wb, n9_2r1w_mm+n9_2r1w_wb, n9_2r1w_wb") --+ --+(define_insn_reservation "nds_n9_2r1w_store_multiple_1" 1 --+ (and (match_test "nds32_register_ports_config == REG_PORT_2R1W") --+ (and (eq_attr "pipeline_model" "n9") --+ (and (eq_attr "type" "store_multiple") --+ (eq_attr "combo" "1")))) --+ "n9_2r1w_ii, n9_2r1w_ex, n9_2r1w_mm, n9_2r1w_wb") --+ --+(define_insn_reservation "nds_n9_2r1w_store_multiple_2" 1 --+ (and (match_test "nds32_register_ports_config == REG_PORT_2R1W") --+ (and (eq_attr "pipeline_model" "n9") --+ (ior (and (eq_attr "type" "store_multiple") --+ (eq_attr "combo" "2")) --+ (match_test "nds32::store_double_p (insn)")))) --+ "n9_2r1w_ii, n9_2r1w_ii+n9_2r1w_ex, n9_2r1w_ex+n9_2r1w_mm, n9_2r1w_mm+n9_2r1w_wb, n9_2r1w_wb") --+ --+(define_insn_reservation "nds_n9_2r1w_store_multiple_3" 1 --+ (and (match_test "nds32_register_ports_config == REG_PORT_2R1W") --+ (and (eq_attr "pipeline_model" "n9") --+ (and (eq_attr "type" "store_multiple") --+ (eq_attr "combo" "3")))) --+ "n9_2r1w_ii, n9_2r1w_ii+n9_2r1w_ex, n9_2r1w_ii+n9_2r1w_ex+n9_2r1w_mm, n9_2r1w_ex+n9_2r1w_mm+n9_2r1w_wb, n9_2r1w_mm+n9_2r1w_wb, n9_2r1w_wb") --+ --+(define_insn_reservation "nds_n9_2r1w_store_multiple_4" 1 --+ (and (match_test "nds32_register_ports_config == REG_PORT_2R1W") --+ (and (eq_attr "pipeline_model" "n9") --+ (and (eq_attr "type" "store_multiple") --+ (eq_attr "combo" "4")))) --+ "n9_2r1w_ii, n9_2r1w_ii+n9_2r1w_ex, n9_2r1w_ii+n9_2r1w_ex+n9_2r1w_mm, n9_2r1w_ii+n9_2r1w_ex+n9_2r1w_mm+n9_2r1w_wb, n9_2r1w_ex+n9_2r1w_mm+n9_2r1w_wb, n9_2r1w_mm+n9_2r1w_wb, n9_2r1w_wb") --+ --+(define_insn_reservation "nds_n9_2r1w_store_multiple_5" 1 --+ (and (match_test "nds32_register_ports_config == REG_PORT_2R1W") --+ (and (eq_attr "pipeline_model" "n9") --+ (and (eq_attr "type" "store_multiple") --+ (eq_attr "combo" "5")))) --+ "n9_2r1w_ii, n9_2r1w_ii+n9_2r1w_ex, n9_2r1w_ii+n9_2r1w_ex+n9_2r1w_mm, (n9_2r1w_ii+n9_2r1w_ex+n9_2r1w_mm+n9_2r1w_wb)*2, n9_2r1w_ex+n9_2r1w_mm+n9_2r1w_wb, n9_2r1w_mm+n9_2r1w_wb, n9_2r1w_wb") --+ --+(define_insn_reservation "nds_n9_2r1w_store_multiple_6" 1 --+ (and (match_test "nds32_register_ports_config == REG_PORT_2R1W") --+ (and (eq_attr "pipeline_model" "n9") --+ (and (eq_attr "type" "store_multiple") --+ (eq_attr "combo" "6")))) --+ "n9_2r1w_ii, n9_2r1w_ii+n9_2r1w_ex, n9_2r1w_ii+n9_2r1w_ex+n9_2r1w_mm, (n9_2r1w_ii+n9_2r1w_ex+n9_2r1w_mm+n9_2r1w_wb)*3, n9_2r1w_ex+n9_2r1w_mm+n9_2r1w_wb, n9_2r1w_mm+n9_2r1w_wb, n9_2r1w_wb") --+ --+(define_insn_reservation "nds_n9_2r1w_store_multiple_7" 1 --+ (and (match_test "nds32_register_ports_config == REG_PORT_2R1W") --+ (and (eq_attr "pipeline_model" "n9") --+ (and (eq_attr "type" "store_multiple") --+ (eq_attr "combo" "7")))) --+ "n9_2r1w_ii, n9_2r1w_ii+n9_2r1w_ex, n9_2r1w_ii+n9_2r1w_ex+n9_2r1w_mm, (n9_2r1w_ii+n9_2r1w_ex+n9_2r1w_mm+n9_2r1w_wb)*4, n9_2r1w_ex+n9_2r1w_mm+n9_2r1w_wb, n9_2r1w_mm+n9_2r1w_wb, n9_2r1w_wb") --+ --+(define_insn_reservation "nds_n9_2r1w_store_multiple_8" 1 --+ (and (match_test "nds32_register_ports_config == REG_PORT_2R1W") --+ (and (eq_attr "pipeline_model" "n9") --+ (and (eq_attr "type" "store_multiple") --+ (eq_attr "combo" "8")))) --+ "n9_2r1w_ii, n9_2r1w_ii+n9_2r1w_ex, n9_2r1w_ii+n9_2r1w_ex+n9_2r1w_mm, (n9_2r1w_ii+n9_2r1w_ex+n9_2r1w_mm+n9_2r1w_wb)*5, n9_2r1w_ex+n9_2r1w_mm+n9_2r1w_wb, n9_2r1w_mm+n9_2r1w_wb, n9_2r1w_wb") --+ --+(define_insn_reservation "nds_n9_2r1w_store_multiple_12" 1 --+ (and (match_test "nds32_register_ports_config == REG_PORT_2R1W") --+ (and (eq_attr "pipeline_model" "n9") --+ (and (eq_attr "type" "store_multiple") --+ (eq_attr "combo" "12")))) --+ "n9_2r1w_ii, n9_2r1w_ii+n9_2r1w_ex, n9_2r1w_ii+n9_2r1w_ex+n9_2r1w_mm, (n9_2r1w_ii+n9_2r1w_ex+n9_2r1w_mm+n9_2r1w_wb)*9, n9_2r1w_ex+n9_2r1w_mm+n9_2r1w_wb, n9_2r1w_mm+n9_2r1w_wb, n9_2r1w_wb") --+ --+(define_insn_reservation "nds_n9_2r1w_mul_fast" 1 --+ (and (match_test "nds32_register_ports_config == REG_PORT_2R1W && nds32_mul_config != MUL_TYPE_SLOW") --+ (and (eq_attr "type" "mul") --+ (eq_attr "pipeline_model" "n9"))) --+ "n9_2r1w_ii, n9_2r1w_ex, n9_2r1w_mm, n9_2r1w_wb") --+ --+(define_insn_reservation "nds_n9_2r1w_mul_slow" 1 --+ (and (match_test "nds32_register_ports_config == REG_PORT_2R1W && nds32_mul_config == MUL_TYPE_SLOW") --+ (and (eq_attr "type" "mul") --+ (eq_attr "pipeline_model" "n9"))) --+ "n9_2r1w_ii, n9_2r1w_ex*17, n9_2r1w_mm, n9_2r1w_wb") --+ --+(define_insn_reservation "nds_n9_2r1w_mac_fast" 1 --+ (and (match_test "nds32_register_ports_config == REG_PORT_2R1W && nds32_mul_config != MUL_TYPE_SLOW") --+ (and (eq_attr "type" "mac") --+ (eq_attr "pipeline_model" "n9"))) --+ "n9_2r1w_ii, n9_2r1w_ii+n9_2r1w_ex, n9_2r1w_ex+n9_2r1w_mm, n9_2r1w_mm+n9_2r1w_wb, n9_2r1w_wb") --+ --+(define_insn_reservation "nds_n9_2r1w_mac_slow" 1 --+ (and (match_test "nds32_register_ports_config == REG_PORT_2R1W && nds32_mul_config == MUL_TYPE_SLOW") --+ (and (eq_attr "type" "mac") --+ (eq_attr "pipeline_model" "n9"))) --+ "n9_2r1w_ii, (n9_2r1w_ii+n9_2r1w_ex)*17, n9_2r1w_ex+n9_2r1w_mm, n9_2r1w_ex+n9_2r1w_mm+n9_2r1w_wb, n9_2r1w_wb") --+ --+(define_insn_reservation "nds_n9_2r1w_div" 1 --+ (and (match_test "nds32_register_ports_config == REG_PORT_2R1W") --+ (and (eq_attr "type" "div") --+ (eq_attr "pipeline_model" "n9"))) --+ "n9_2r1w_ii, (n9_2r1w_ii+n9_2r1w_ex)*34, n9_2r1w_ex+n9_2r1w_mm, n9_2r1w_mm+n9_2r1w_wb, n9_2r1w_wb") --+ --+(define_insn_reservation "nds_n9_2r1w_branch" 1 --+ (and (match_test "nds32_register_ports_config == REG_PORT_2R1W") --+ (and (eq_attr "type" "branch") --+ (eq_attr "pipeline_model" "n9"))) --+ "n9_2r1w_ii, n9_2r1w_ex, n9_2r1w_mm, n9_2r1w_wb") --+ --+;; ------------------------------------------------------------------------ --+;; Comment Notations and Bypass Rules --+;; ------------------------------------------------------------------------ --+;; Producers (LHS) --+;; LD_!bi --+;; Load data from the memory (without updating the base register) and --+;; produce the loaded data. The result is ready at MM. Because the register --+;; port is 2R1W, two micro-operations are required if the base register --+;; should be updated. In this case, the base register is updated by the --+;; second micro-operation, and the updated result is ready at EX. --+;; LMW(N, M) --+;; There are N micro-operations within an instruction that loads multiple --+;; words. The result produced by the M-th micro-operation is sent to --+;; consumers. The result is ready at MM. If the base register should be --+;; updated, an extra micro-operation is apppended to the end of the --+;; sequence, and the result is ready at EX. --+;; MUL, MAC --+;; Compute data in the multiply-adder and produce the data. The result --+;; is ready at MM. --+;; DIV --+;; Compute data in the divider and produce the data. The result is ready --+;; at MM. --+;; --+;; Consumers (RHS) --+;; ALU, PBSAD, PBSADA_RaRb, MUL, MAC, DIV, MMU --+;; Require operands at EX. --+;; ALU_SHIFT_Rb --+;; An ALU-SHIFT instruction consists of a shift micro-operation followed --+;; by an arithmetic micro-operation. The operand Rb is used by the first --+;; micro-operation, and there are some latencies if data dependency occurs. --+;; MOVD44_E --+;; A double-word move instruction needs two micro-operations because the --+;; reigster ports is 2R1W. The first micro-operation writes an even number --+;; register, and the second micro-operation writes an odd number register. --+;; Each input operand is required at EX for each micro-operation. MOVD44_E --+;; stands for the first micro-operation. --+;; MAC_RaRb, M2R --+;; MAC instructions do multiplication at EX and do accumulation at MM, but --+;; MAC instructions which operate on general purpose registers always --+;; require operands at EX because MM stage cannot be forwarded in 2R1W mode. --+;; ADDR_IN --+;; If an instruction requires an address as its input operand, the address --+;; is required at EX. --+;; ST_bi --+;; A post-increment store instruction requires its data at EX because MM --+;; cannot be forwarded in 2R1W mode. --+;; ST_!bi_RI --+;; A store instruction with an immediate offset requires its data at EX --+;; because MM cannot be forwarded in 2R1W mode. If the offset field is a --+;; register (ST_!bi_RR), the instruction will be separated into two micro- --+;; operations, and the second one requires the input operand at EX in order --+;; to store it to the memory. --+;; SMW(N, M) --+;; There are N micro-operations within an instruction that stores multiple --+;; words. Each M-th micro-operation requires its data at MM. --+;; BR --+;; If a branch instruction is conditional, its input data is required at EX. --+ --+;; LD_!bi, MUL, MAC --+;; -> ALU, ALU_SHIFT_Rb, PBSAD, PBSADA_RaRb, MOVD44_E, MUL, MAC_RaRb, M2R, DIV, ADDR_IN_!bi, ADDR_IN_bi_Ra, ST_bi, ST_!bi_RI, BR, MMU --+(define_bypass 2 --+ "nds_n9_2r1w_load,\ --+ nds_n9_2r1w_mul_fast, nds_n9_2r1w_mul_slow,\ --+ nds_n9_2r1w_mac_fast, nds_n9_2r1w_mac_slow" --+ "nds_n9_2r1w_alu, nds_n9_2r1w_alu_shift,\ --+ nds_n9_2r1w_pbsad, nds_n9_2r1w_pbsada,\ --+ nds_n9_2r1w_mul_fast, nds_n9_2r1w_mul_slow,\ --+ nds_n9_2r1w_mac_fast, nds_n9_2r1w_mac_slow,\ --+ nds_n9_2r1w_branch,\ --+ nds_n9_2r1w_div,\ --+ nds_n9_2r1w_load,nds_n9_2r1w_store,\ --+ nds_n9_2r1w_load_multiple_1,nds_n9_2r1w_load_multiple_2, nds_n9_2r1w_load_multiple_3,\ --+ nds_n9_2r1w_load_multiple_4,nds_n9_2r1w_load_multiple_5, nds_n9_2r1w_load_multiple_6,\ --+ nds_n9_2r1w_load_multiple_7,nds_n9_2r1w_load_multiple_8, nds_n9_2r1w_load_multiple_12,\ --+ nds_n9_2r1w_store_multiple_1,nds_n9_2r1w_store_multiple_2, nds_n9_2r1w_store_multiple_3,\ --+ nds_n9_2r1w_store_multiple_4,nds_n9_2r1w_store_multiple_5, nds_n9_2r1w_store_multiple_6,\ --+ nds_n9_2r1w_store_multiple_7,nds_n9_2r1w_store_multiple_8, nds_n9_2r1w_store_multiple_12,\ --+ nds_n9_2r1w_mmu" --+ "nds32_n9_2r1w_mm_to_ex_p" --+) --+ --+;; LMW(N, N) --+;; -> ALU, ALU_SHIFT_Rb, PBSAD, PBSADA_RaRb, MOVD44_E, MUL, MAC_RaRb, M2R, DIV, ADDR_IN_!bi, ADDR_IN_bi_Ra, ST_bi, ST_!bi_RI, BR, MMU --+(define_bypass 2 --+ "nds_n9_2r1w_load_multiple_1,nds_n9_2r1w_load_multiple_2, nds_n9_2r1w_load_multiple_3,\ --+ nds_n9_2r1w_load_multiple_4,nds_n9_2r1w_load_multiple_5, nds_n9_2r1w_load_multiple_6,\ --+ nds_n9_2r1w_load_multiple_7,nds_n9_2r1w_load_multiple_8, nds_n9_2r1w_load_multiple_12" --+ "nds_n9_2r1w_alu, nds_n9_2r1w_alu_shift,\ --+ nds_n9_2r1w_pbsad, nds_n9_2r1w_pbsada,\ --+ nds_n9_2r1w_mul_fast, nds_n9_2r1w_mul_slow,\ --+ nds_n9_2r1w_mac_fast, nds_n9_2r1w_mac_slow,\ --+ nds_n9_2r1w_branch,\ --+ nds_n9_2r1w_div,\ --+ nds_n9_2r1w_load,nds_n9_2r1w_store,\ --+ nds_n9_2r1w_load_multiple_1,nds_n9_2r1w_load_multiple_2, nds_n9_2r1w_load_multiple_3,\ --+ nds_n9_2r1w_load_multiple_4,nds_n9_2r1w_load_multiple_5, nds_n9_2r1w_load_multiple_6,\ --+ nds_n9_2r1w_load_multiple_7,nds_n9_2r1w_load_multiple_8, nds_n9_2r1w_load_multiple_12,\ --+ nds_n9_2r1w_store_multiple_1,nds_n9_2r1w_store_multiple_2, nds_n9_2r1w_store_multiple_3,\ --+ nds_n9_2r1w_store_multiple_4,nds_n9_2r1w_store_multiple_5, nds_n9_2r1w_store_multiple_6,\ --+ nds_n9_2r1w_store_multiple_7,nds_n9_2r1w_store_multiple_8, nds_n9_2r1w_store_multiple_12,\ --+ nds_n9_2r1w_mmu" --+ "nds32_n9_last_load_to_ex_p" --+) --diff --git a/gcc/config/nds32/nds32-n9-3r2w.md b/gcc/config/nds32/nds32-n9-3r2w.md --new file mode 100644 --index 0000000..7849c72 ----- /dev/null --+++ b/gcc/config/nds32/nds32-n9-3r2w.md --@@ -0,0 +1,357 @@ --+;; Pipeline descriptions of Andes NDS32 cpu for GNU compiler --+;; Copyright (C) 2012-2016 Free Software Foundation, Inc. --+;; Contributed by Andes Technology Corporation. --+;; --+;; This file is part of GCC. --+;; --+;; GCC is free software; you can redistribute it and/or modify it --+;; under the terms of the GNU General Public License as published --+;; by the Free Software Foundation; either version 3, or (at your --+;; option) any later version. --+;; --+;; GCC is distributed in the hope that it will be useful, but WITHOUT --+;; ANY WARRANTY; without even the implied warranty of MERCHANTABILITY --+;; or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public --+;; License for more details. --+;; --+;; You should have received a copy of the GNU General Public License --+;; along with GCC; see the file COPYING3. If not see --+;; . --+ --+ --+;; ------------------------------------------------------------------------ --+;; Define N9 3R2W pipeline settings. --+;; ------------------------------------------------------------------------ --+ --+(define_automaton "nds32_n9_3r2w_machine") --+ --+;; ------------------------------------------------------------------------ --+;; Pipeline Stages --+;; ------------------------------------------------------------------------ --+;; IF - Instruction Fetch --+;; II - Instruction Issue / Instruction Decode --+;; EX - Instruction Execution --+;; MM - Memory Execution --+;; WB - Instruction Retire / Result Write-Back --+ --+(define_cpu_unit "n9_3r2w_ii" "nds32_n9_3r2w_machine") --+(define_cpu_unit "n9_3r2w_ex" "nds32_n9_3r2w_machine") --+(define_cpu_unit "n9_3r2w_mm" "nds32_n9_3r2w_machine") --+(define_cpu_unit "n9_3r2w_wb" "nds32_n9_3r2w_machine") --+ --+(define_insn_reservation "nds_n9_3r2w_unknown" 1 --+ (and (match_test "nds32_register_ports_config == REG_PORT_3R2W") --+ (and (eq_attr "type" "unknown") --+ (eq_attr "pipeline_model" "n9"))) --+ "n9_3r2w_ii, n9_3r2w_ex, n9_3r2w_mm, n9_3r2w_wb") --+ --+(define_insn_reservation "nds_n9_3r2w_misc" 1 --+ (and (match_test "nds32_register_ports_config == REG_PORT_3R2W") --+ (and (eq_attr "type" "misc") --+ (eq_attr "pipeline_model" "n9"))) --+ "n9_3r2w_ii, n9_3r2w_ex, n9_3r2w_mm, n9_3r2w_wb") --+ --+(define_insn_reservation "nds_n9_3r2w_mmu" 1 --+ (and (match_test "nds32_register_ports_config == REG_PORT_3R2W") --+ (and (eq_attr "type" "mmu") --+ (eq_attr "pipeline_model" "n9"))) --+ "n9_3r2w_ii, n9_3r2w_ex, n9_3r2w_mm, n9_3r2w_wb") --+ --+(define_insn_reservation "nds_n9_3r2w_alu" 1 --+ (and (match_test "nds32_register_ports_config == REG_PORT_3R2W") --+ (and (eq_attr "type" "alu") --+ (eq_attr "pipeline_model" "n9"))) --+ "n9_3r2w_ii, n9_3r2w_ex, n9_3r2w_mm, n9_3r2w_wb") --+ --+(define_insn_reservation "nds_n9_3r2w_alu_shift" 1 --+ (and (match_test "nds32_register_ports_config == REG_PORT_3R2W") --+ (and (eq_attr "type" "alu_shift") --+ (eq_attr "pipeline_model" "n9"))) --+ "n9_3r2w_ii, n9_3r2w_ii+n9_3r2w_ex, n9_3r2w_ex+n9_3r2w_mm, n9_3r2w_mm+n9_3r2w_wb, n9_3r2w_wb") --+ --+(define_insn_reservation "nds_n9_3r2w_pbsad" 1 --+ (and (match_test "nds32_register_ports_config == REG_PORT_3R2W") --+ (and (eq_attr "type" "pbsad") --+ (eq_attr "pipeline_model" "n9"))) --+ "n9_3r2w_ii, n9_3r2w_ex*3, n9_3r2w_mm, n9_3r2w_wb") --+ --+(define_insn_reservation "nds_n9_3r2w_pbsada" 1 --+ (and (match_test "nds32_register_ports_config == REG_PORT_3R2W") --+ (and (eq_attr "type" "pbsada") --+ (eq_attr "pipeline_model" "n9"))) --+ "n9_3r2w_ii, n9_3r2w_ex*3, n9_3r2w_mm, n9_3r2w_wb") --+ --+(define_insn_reservation "nds_n9_3r2w_load" 1 --+ (and (match_test "nds32_register_ports_config == REG_PORT_3R2W") --+ (and (match_test "nds32::load_single_p (insn)") --+ (eq_attr "pipeline_model" "n9"))) --+ "n9_3r2w_ii, n9_3r2w_ex, n9_3r2w_mm, n9_3r2w_wb") --+ --+(define_insn_reservation "nds_n9_3r2w_store" 1 --+ (and (match_test "nds32_register_ports_config == REG_PORT_3R2W") --+ (and (match_test "nds32::store_single_p (insn)") --+ (eq_attr "pipeline_model" "n9"))) --+ "n9_3r2w_ii, n9_3r2w_ex, n9_3r2w_mm, n9_3r2w_wb") --+ --+(define_insn_reservation "nds_n9_3r2w_load_multiple_1" 1 --+ (and (match_test "nds32_register_ports_config == REG_PORT_3R2W") --+ (and (eq_attr "pipeline_model" "n9") --+ (and (eq_attr "type" "load_multiple") --+ (eq_attr "combo" "1")))) --+ "n9_3r2w_ii, n9_3r2w_ex, n9_3r2w_mm, n9_3r2w_wb") --+ --+(define_insn_reservation "nds_n9_3r2w_load_multiple_2" 1 --+ (and (match_test "nds32_register_ports_config == REG_PORT_3R2W") --+ (and (eq_attr "pipeline_model" "n9") --+ (ior (and (eq_attr "type" "load_multiple") --+ (eq_attr "combo" "2")) --+ (match_test "nds32::load_double_p (insn)")))) --+ "n9_3r2w_ii, n9_3r2w_ii+n9_3r2w_ex, n9_3r2w_ex+n9_3r2w_mm, n9_3r2w_mm+n9_3r2w_wb, n9_3r2w_wb") --+ --+(define_insn_reservation "nds_n9_3r2w_load_multiple_3" 1 --+ (and (match_test "nds32_register_ports_config == REG_PORT_3R2W") --+ (and (eq_attr "pipeline_model" "n9") --+ (and (eq_attr "type" "load_multiple") --+ (eq_attr "combo" "3")))) --+ "n9_3r2w_ii, n9_3r2w_ii+n9_3r2w_ex, n9_3r2w_ii+n9_3r2w_ex+n9_3r2w_mm, n9_3r2w_ex+n9_3r2w_mm+n9_3r2w_wb, n9_3r2w_mm+n9_3r2w_wb, n9_3r2w_wb") --+ --+(define_insn_reservation "nds_n9_3r2w_load_multiple_4" 1 --+ (and (match_test "nds32_register_ports_config == REG_PORT_3R2W") --+ (and (eq_attr "pipeline_model" "n9") --+ (and (eq_attr "type" "load_multiple") --+ (eq_attr "combo" "4")))) --+ "n9_3r2w_ii, n9_3r2w_ii+n9_3r2w_ex, n9_3r2w_ii+n9_3r2w_ex+n9_3r2w_mm, n9_3r2w_ii+n9_3r2w_ex+n9_3r2w_mm+n9_3r2w_wb, n9_3r2w_ex+n9_3r2w_mm+n9_3r2w_wb, n9_3r2w_mm+n9_3r2w_wb, n9_3r2w_wb") --+ --+(define_insn_reservation "nds_n9_3r2w_load_multiple_5" 1 --+ (and (match_test "nds32_register_ports_config == REG_PORT_3R2W") --+ (and (eq_attr "pipeline_model" "n9") --+ (and (eq_attr "type" "load_multiple") --+ (eq_attr "combo" "5")))) --+ "n9_3r2w_ii, n9_3r2w_ii+n9_3r2w_ex, n9_3r2w_ii+n9_3r2w_ex+n9_3r2w_mm, (n9_3r2w_ii+n9_3r2w_ex+n9_3r2w_mm+n9_3r2w_wb)*2, n9_3r2w_ex+n9_3r2w_mm+n9_3r2w_wb, n9_3r2w_mm+n9_3r2w_wb, n9_3r2w_wb") --+ --+(define_insn_reservation "nds_n9_3r2w_load_multiple_6" 1 --+ (and (match_test "nds32_register_ports_config == REG_PORT_3R2W") --+ (and (eq_attr "pipeline_model" "n9") --+ (and (eq_attr "type" "load_multiple") --+ (eq_attr "combo" "6")))) --+ "n9_3r2w_ii, n9_3r2w_ii+n9_3r2w_ex, n9_3r2w_ii+n9_3r2w_ex+n9_3r2w_mm, (n9_3r2w_ii+n9_3r2w_ex+n9_3r2w_mm+n9_3r2w_wb)*3, n9_3r2w_ex+n9_3r2w_mm+n9_3r2w_wb, n9_3r2w_mm+n9_3r2w_wb, n9_3r2w_wb") --+ --+(define_insn_reservation "nds_n9_3r2w_load_multiple_7" 1 --+ (and (match_test "nds32_register_ports_config == REG_PORT_3R2W") --+ (and (eq_attr "pipeline_model" "n9") --+ (and (eq_attr "type" "load_multiple") --+ (eq_attr "combo" "7")))) --+ "n9_3r2w_ii, n9_3r2w_ii+n9_3r2w_ex, n9_3r2w_ii+n9_3r2w_ex+n9_3r2w_mm, (n9_3r2w_ii+n9_3r2w_ex+n9_3r2w_mm+n9_3r2w_wb)*4, n9_3r2w_ex+n9_3r2w_mm+n9_3r2w_wb, n9_3r2w_mm+n9_3r2w_wb, n9_3r2w_wb") --+ --+(define_insn_reservation "nds_n9_3r2w_load_multiple_8" 1 --+ (and (match_test "nds32_register_ports_config == REG_PORT_3R2W") --+ (and (eq_attr "pipeline_model" "n9") --+ (and (eq_attr "type" "load_multiple") --+ (eq_attr "combo" "8")))) --+ "n9_3r2w_ii, n9_3r2w_ii+n9_3r2w_ex, n9_3r2w_ii+n9_3r2w_ex+n9_3r2w_mm, (n9_3r2w_ii+n9_3r2w_ex+n9_3r2w_mm+n9_3r2w_wb)*5, n9_3r2w_ex+n9_3r2w_mm+n9_3r2w_wb, n9_3r2w_mm+n9_3r2w_wb, n9_3r2w_wb") --+ --+(define_insn_reservation "nds_n9_3r2w_load_multiple_12" 1 --+ (and (match_test "nds32_register_ports_config == REG_PORT_3R2W") --+ (and (eq_attr "pipeline_model" "n9") --+ (and (eq_attr "type" "load_multiple") --+ (eq_attr "combo" "12")))) --+ "n9_3r2w_ii, n9_3r2w_ii+n9_3r2w_ex, n9_3r2w_ii+n9_3r2w_ex+n9_3r2w_mm, (n9_3r2w_ii+n9_3r2w_ex+n9_3r2w_mm+n9_3r2w_wb)*9, n9_3r2w_ex+n9_3r2w_mm+n9_3r2w_wb, n9_3r2w_mm+n9_3r2w_wb, n9_3r2w_wb") --+ --+(define_insn_reservation "nds_n9_3r2w_store_multiple_1" 1 --+ (and (match_test "nds32_register_ports_config == REG_PORT_3R2W") --+ (and (eq_attr "pipeline_model" "n9") --+ (and (eq_attr "type" "store_multiple") --+ (eq_attr "combo" "1")))) --+ "n9_3r2w_ii, n9_3r2w_ex, n9_3r2w_mm, n9_3r2w_wb") --+ --+(define_insn_reservation "nds_n9_3r2w_store_multiple_2" 1 --+ (and (match_test "nds32_register_ports_config == REG_PORT_3R2W") --+ (and (eq_attr "pipeline_model" "n9") --+ (ior (and (eq_attr "type" "store_multiple") --+ (eq_attr "combo" "2")) --+ (match_test "nds32::store_double_p (insn)")))) --+ "n9_3r2w_ii, n9_3r2w_ii+n9_3r2w_ex, n9_3r2w_ex+n9_3r2w_mm, n9_3r2w_mm+n9_3r2w_wb, n9_3r2w_wb") --+ --+(define_insn_reservation "nds_n9_3r2w_store_multiple_3" 1 --+ (and (match_test "nds32_register_ports_config == REG_PORT_3R2W") --+ (and (eq_attr "pipeline_model" "n9") --+ (and (eq_attr "type" "store_multiple") --+ (eq_attr "combo" "3")))) --+ "n9_3r2w_ii, n9_3r2w_ii+n9_3r2w_ex, n9_3r2w_ii+n9_3r2w_ex+n9_3r2w_mm, n9_3r2w_ex+n9_3r2w_mm+n9_3r2w_wb, n9_3r2w_mm+n9_3r2w_wb, n9_3r2w_wb") --+ --+(define_insn_reservation "nds_n9_3r2w_store_multiple_4" 1 --+ (and (match_test "nds32_register_ports_config == REG_PORT_3R2W") --+ (and (eq_attr "pipeline_model" "n9") --+ (and (eq_attr "type" "store_multiple") --+ (eq_attr "combo" "4")))) --+ "n9_3r2w_ii, n9_3r2w_ii+n9_3r2w_ex, n9_3r2w_ii+n9_3r2w_ex+n9_3r2w_mm, n9_3r2w_ii+n9_3r2w_ex+n9_3r2w_mm+n9_3r2w_wb, n9_3r2w_ex+n9_3r2w_mm+n9_3r2w_wb, n9_3r2w_mm+n9_3r2w_wb, n9_3r2w_wb") --+ --+(define_insn_reservation "nds_n9_3r2w_store_multiple_5" 1 --+ (and (match_test "nds32_register_ports_config == REG_PORT_3R2W") --+ (and (eq_attr "pipeline_model" "n9") --+ (and (eq_attr "type" "store_multiple") --+ (eq_attr "combo" "5")))) --+ "n9_3r2w_ii, n9_3r2w_ii+n9_3r2w_ex, n9_3r2w_ii+n9_3r2w_ex+n9_3r2w_mm, (n9_3r2w_ii+n9_3r2w_ex+n9_3r2w_mm+n9_3r2w_wb)*2, n9_3r2w_ex+n9_3r2w_mm+n9_3r2w_wb, n9_3r2w_mm+n9_3r2w_wb, n9_3r2w_wb") --+ --+(define_insn_reservation "nds_n9_3r2w_store_multiple_6" 1 --+ (and (match_test "nds32_register_ports_config == REG_PORT_3R2W") --+ (and (eq_attr "pipeline_model" "n9") --+ (and (eq_attr "type" "store_multiple") --+ (eq_attr "combo" "6")))) --+ "n9_3r2w_ii, n9_3r2w_ii+n9_3r2w_ex, n9_3r2w_ii+n9_3r2w_ex+n9_3r2w_mm, (n9_3r2w_ii+n9_3r2w_ex+n9_3r2w_mm+n9_3r2w_wb)*3, n9_3r2w_ex+n9_3r2w_mm+n9_3r2w_wb, n9_3r2w_mm+n9_3r2w_wb, n9_3r2w_wb") --+ --+(define_insn_reservation "nds_n9_3r2w_store_multiple_7" 1 --+ (and (match_test "nds32_register_ports_config == REG_PORT_3R2W") --+ (and (eq_attr "pipeline_model" "n9") --+ (and (eq_attr "type" "store_multiple") --+ (eq_attr "combo" "7")))) --+ "n9_3r2w_ii, n9_3r2w_ii+n9_3r2w_ex, n9_3r2w_ii+n9_3r2w_ex+n9_3r2w_mm, (n9_3r2w_ii+n9_3r2w_ex+n9_3r2w_mm+n9_3r2w_wb)*4, n9_3r2w_ex+n9_3r2w_mm+n9_3r2w_wb, n9_3r2w_mm+n9_3r2w_wb, n9_3r2w_wb") --+ --+(define_insn_reservation "nds_n9_3r2w_store_multiple_8" 1 --+ (and (match_test "nds32_register_ports_config == REG_PORT_3R2W") --+ (and (eq_attr "pipeline_model" "n9") --+ (and (eq_attr "type" "store_multiple") --+ (eq_attr "combo" "8")))) --+ "n9_3r2w_ii, n9_3r2w_ii+n9_3r2w_ex, n9_3r2w_ii+n9_3r2w_ex+n9_3r2w_mm, (n9_3r2w_ii+n9_3r2w_ex+n9_3r2w_mm+n9_3r2w_wb)*5, n9_3r2w_ex+n9_3r2w_mm+n9_3r2w_wb, n9_3r2w_mm+n9_3r2w_wb, n9_3r2w_wb") --+ --+(define_insn_reservation "nds_n9_3r2w_store_multiple_12" 1 --+ (and (match_test "nds32_register_ports_config == REG_PORT_3R2W") --+ (and (eq_attr "pipeline_model" "n9") --+ (and (eq_attr "type" "store_multiple") --+ (eq_attr "combo" "12")))) --+ "n9_3r2w_ii, n9_3r2w_ii+n9_3r2w_ex, n9_3r2w_ii+n9_3r2w_ex+n9_3r2w_mm, (n9_3r2w_ii+n9_3r2w_ex+n9_3r2w_mm+n9_3r2w_wb)*9, n9_3r2w_ex+n9_3r2w_mm+n9_3r2w_wb, n9_3r2w_mm+n9_3r2w_wb, n9_3r2w_wb") --+ --+(define_insn_reservation "nds_n9_3r2w_mul_fast1" 1 --+ (and (match_test "nds32_register_ports_config == REG_PORT_3R2W && nds32_mul_config == MUL_TYPE_FAST_1") --+ (and (eq_attr "type" "mul") --+ (eq_attr "pipeline_model" "n9"))) --+ "n9_3r2w_ii, n9_3r2w_ex, n9_3r2w_mm, n9_3r2w_wb") --+ --+(define_insn_reservation "nds_n9_3r2w_mul_fast2" 1 --+ (and (match_test "nds32_register_ports_config == REG_PORT_3R2W && nds32_mul_config == MUL_TYPE_FAST_2") --+ (and (eq_attr "type" "mul") --+ (eq_attr "pipeline_model" "n9"))) --+ "n9_3r2w_ii, n9_3r2w_ex*2, n9_3r2w_mm, n9_3r2w_wb") --+ --+(define_insn_reservation "nds_n9_3r2w_mul_slow" 1 --+ (and (match_test "nds32_register_ports_config == REG_PORT_3R2W && nds32_mul_config == MUL_TYPE_SLOW") --+ (and (eq_attr "type" "mul") --+ (eq_attr "pipeline_model" "n9"))) --+ "n9_3r2w_ii, n9_3r2w_ex*17, n9_3r2w_mm, n9_3r2w_wb") --+ --+(define_insn_reservation "nds_n9_3r2w_mac_fast1" 1 --+ (and (match_test "nds32_register_ports_config == REG_PORT_3R2W && nds32_mul_config == MUL_TYPE_FAST_1") --+ (and (eq_attr "type" "mac") --+ (eq_attr "pipeline_model" "n9"))) --+ "n9_3r2w_ii, n9_3r2w_ex, n9_3r2w_mm, n9_3r2w_wb") --+ --+(define_insn_reservation "nds_n9_3r2w_mac_fast2" 1 --+ (and (match_test "nds32_register_ports_config == REG_PORT_3R2W && nds32_mul_config == MUL_TYPE_FAST_2") --+ (and (eq_attr "type" "mac") --+ (eq_attr "pipeline_model" "n9"))) --+ "n9_3r2w_ii, n9_3r2w_ex*2, n9_3r2w_mm, n9_3r2w_wb") --+ --+(define_insn_reservation "nds_n9_3r2w_mac_slow" 1 --+ (and (match_test "nds32_register_ports_config == REG_PORT_3R2W && nds32_mul_config == MUL_TYPE_SLOW") --+ (and (eq_attr "type" "mac") --+ (eq_attr "pipeline_model" "n9"))) --+ "n9_3r2w_ii, n9_3r2w_ex*17, n9_3r2w_ex+n9_3r2w_mm, n9_3r2w_ex+n9_3r2w_mm+n9_3r2w_wb") --+ --+(define_insn_reservation "nds_n9_3r2w_div" 1 --+ (and (match_test "nds32_register_ports_config == REG_PORT_3R2W") --+ (and (eq_attr "type" "div") --+ (eq_attr "pipeline_model" "n9"))) --+ "n9_3r2w_ii, n9_3r2w_ex*34, n9_3r2w_mm, n9_3r2w_wb") --+ --+(define_insn_reservation "nds_n9_3r2w_branch" 1 --+ (and (match_test "nds32_register_ports_config == REG_PORT_3R2W") --+ (and (eq_attr "type" "branch") --+ (eq_attr "pipeline_model" "n9"))) --+ "n9_3r2w_ii, n9_3r2w_ex, n9_3r2w_mm, n9_3r2w_wb") --+ --+;; ------------------------------------------------------------------------ --+;; Comment Notations and Bypass Rules --+;; ------------------------------------------------------------------------ --+;; Producers (LHS) --+;; LD --+;; Load data from the memory and produce the loaded data. The result is --+;; ready at MM. --+;; LMW(N, M) --+;; There are N micro-operations within an instruction that loads multiple --+;; words. The result produced by the M-th micro-operation is sent to --+;; consumers. The result is ready at MM. --+;; MUL, MAC --+;; Compute data in the multiply-adder and produce the data. The result --+;; is ready at MM. --+;; DIV --+;; Compute data in the divider and produce the data. The result is ready --+;; at MM. --+;; --+;; Consumers (RHS) --+;; ALU, MOVD44, PBSAD, PBSADA_RaRb, MUL, MAC, DIV, MMU --+;; Require operands at EX. --+;; ALU_SHIFT_Rb --+;; An ALU-SHIFT instruction consists of a shift micro-operation followed --+;; by an arithmetic micro-operation. The operand Rb is used by the first --+;; micro-operation, and there are some latencies if data dependency occurs. --+;; MAC_RaRb --+;; A MAC instruction does multiplication at EX and does accumulation at MM, --+;; so the operand Rt is required at MM, and operands Ra and Rb are required --+;; at EX. --+;; ADDR_IN --+;; If an instruction requires an address as its input operand, the address --+;; is required at EX. --+;; ST --+;; A store instruction requires its data at MM. --+;; SMW(N, M) --+;; There are N micro-operations within an instruction that stores multiple --+;; words. Each M-th micro-operation requires its data at MM. --+;; BR --+;; If a branch instruction is conditional, its input data is required at EX. --+ --+;; LD, MUL, MAC, DIV --+;; -> ALU, ALU_SHIFT_Rb, PBSAD, PBSADA_RaRb, MOVD44, MUL, MAC_RaRb, DIV, ADDR_IN, BR, MMU --+(define_bypass 2 --+ "nds_n9_3r2w_load,\ --+ nds_n9_3r2w_mul_fast1, nds_n9_3r2w_mul_fast2, nds_n9_3r2w_mul_slow,\ --+ nds_n9_3r2w_mac_fast1, nds_n9_3r2w_mac_fast2, nds_n9_3r2w_mac_slow,\ --+ nds_n9_3r2w_div" --+ "nds_n9_3r2w_alu, nds_n9_3r2w_alu_shift,\ --+ nds_n9_3r2w_pbsad, nds_n9_3r2w_pbsada,\ --+ nds_n9_3r2w_mul_fast1, nds_n9_3r2w_mul_fast2, nds_n9_3r2w_mul_slow,\ --+ nds_n9_3r2w_mac_fast1, nds_n9_3r2w_mac_fast2, nds_n9_3r2w_mac_slow,\ --+ nds_n9_3r2w_branch,\ --+ nds_n9_3r2w_div,\ --+ nds_n9_3r2w_load,nds_n9_3r2w_store,\ --+ nds_n9_3r2w_load_multiple_1,nds_n9_3r2w_load_multiple_2, nds_n9_3r2w_load_multiple_3,\ --+ nds_n9_3r2w_load_multiple_4,nds_n9_3r2w_load_multiple_5, nds_n9_3r2w_load_multiple_6,\ --+ nds_n9_3r2w_load_multiple_7,nds_n9_3r2w_load_multiple_8, nds_n9_3r2w_load_multiple_12,\ --+ nds_n9_3r2w_store_multiple_1,nds_n9_3r2w_store_multiple_2, nds_n9_3r2w_store_multiple_3,\ --+ nds_n9_3r2w_store_multiple_4,nds_n9_3r2w_store_multiple_5, nds_n9_3r2w_store_multiple_6,\ --+ nds_n9_3r2w_store_multiple_7,nds_n9_3r2w_store_multiple_8, nds_n9_3r2w_store_multiple_12,\ --+ nds_n9_3r2w_mmu" --+ "nds32_n9_3r2w_mm_to_ex_p" --+) --+ --+;; LMW(N, N) --+;; -> ALU, ALU_SHIFT_Rb, PBSAD, PBSADA_RaRb, MOVD44, MUL, MAC_RaRb, DIV, ADDR_IN, BR, MMU --+(define_bypass 2 --+ "nds_n9_3r2w_load_multiple_1,nds_n9_3r2w_load_multiple_2, nds_n9_3r2w_load_multiple_3,\ --+ nds_n9_3r2w_load_multiple_4,nds_n9_3r2w_load_multiple_5, nds_n9_3r2w_load_multiple_6,\ --+ nds_n9_3r2w_load_multiple_7,nds_n9_3r2w_load_multiple_8, nds_n9_3r2w_load_multiple_12" --+ "nds_n9_3r2w_alu, nds_n9_3r2w_alu_shift,\ --+ nds_n9_3r2w_pbsad, nds_n9_3r2w_pbsada,\ --+ nds_n9_3r2w_mul_fast1, nds_n9_3r2w_mul_fast2, nds_n9_3r2w_mul_slow,\ --+ nds_n9_3r2w_mac_fast1, nds_n9_3r2w_mac_fast2, nds_n9_3r2w_mac_slow,\ --+ nds_n9_3r2w_branch,\ --+ nds_n9_3r2w_div,\ --+ nds_n9_3r2w_load,nds_n9_3r2w_store,\ --+ nds_n9_3r2w_load_multiple_1,nds_n9_3r2w_load_multiple_2, nds_n9_3r2w_load_multiple_3,\ --+ nds_n9_3r2w_load_multiple_4,nds_n9_3r2w_load_multiple_5, nds_n9_3r2w_load_multiple_6,\ --+ nds_n9_3r2w_load_multiple_7,nds_n9_3r2w_load_multiple_8, nds_n9_3r2w_load_multiple_12,\ --+ nds_n9_3r2w_store_multiple_1,nds_n9_3r2w_store_multiple_2, nds_n9_3r2w_store_multiple_3,\ --+ nds_n9_3r2w_store_multiple_4,nds_n9_3r2w_store_multiple_5, nds_n9_3r2w_store_multiple_6,\ --+ nds_n9_3r2w_store_multiple_7,nds_n9_3r2w_store_multiple_8, nds_n9_3r2w_store_multiple_12,\ --+ nds_n9_3r2w_mmu" --+ "nds32_n9_last_load_to_ex_p" --+) --diff --git a/gcc/config/nds32/nds32-opts.h b/gcc/config/nds32/nds32-opts.h --index 25c4081..e4017bb 100644 ----- a/gcc/config/nds32/nds32-opts.h --+++ b/gcc/config/nds32/nds32-opts.h --@@ -22,14 +22,42 @@ -- #define NDS32_OPTS_H -- -- #define NDS32_DEFAULT_CACHE_BLOCK_SIZE 16 ---#define NDS32_DEFAULT_ISR_VECTOR_SIZE (TARGET_ISA_V3 ? 4 : 16) --+#define NDS32_DEFAULT_ISR_VECTOR_SIZE TARGET_DEFAULT_ISR_VECTOR_SIZE -- -- /* The various ANDES ISA. */ -- enum nds32_arch_type -- { -- ARCH_V2, --+ ARCH_V2J, -- ARCH_V3, --- ARCH_V3M --+ ARCH_V3J, --+ ARCH_V3M, --+ ARCH_V3M_PLUS, --+ ARCH_V3F, --+ ARCH_V3S --+}; --+ --+/* The various ANDES CPU. */ --+enum nds32_cpu_type --+{ --+ CPU_N6, --+ CPU_N7, --+ CPU_N8, --+ CPU_E8, --+ CPU_N9, --+ CPU_N10, --+ CPU_GRAYWOLF, --+ CPU_N12, --+ CPU_N13, --+ CPU_PANTHER, --+ CPU_SIMPLE --+}; --+ --+/* The code model defines the address generation strategy. */ --+enum nds32_memory_model_type --+{ --+ MEMORY_MODEL_SLOW, --+ MEMORY_MODEL_FAST -- }; -- -- /* The code model defines the address generation strategy. */ --@@ -40,4 +68,56 @@ enum nds32_cmodel_type -- CMODEL_LARGE -- }; -- --+/* The code model defines the address generation strategy. */ --+enum nds32_ict_model_type --+{ --+ ICT_MODEL_SMALL, --+ ICT_MODEL_LARGE --+}; --+ --+ --+/* Multiply instruction configuration. */ --+enum nds32_mul_type --+{ --+ MUL_TYPE_FAST_1, --+ MUL_TYPE_FAST_2, --+ MUL_TYPE_SLOW --+}; --+ --+/* Register ports configuration. */ --+enum nds32_register_ports --+{ --+ REG_PORT_3R2W, --+ REG_PORT_2R1W --+}; --+ --+/* Which ABI to use. */ --+enum abi_type --+{ --+ NDS32_ABI_V2, --+ NDS32_ABI_V2_FP_PLUS --+}; --+ --+/* The various FPU number of registers. */ --+enum float_reg_number --+{ --+ NDS32_CONFIG_FPU_0, --+ NDS32_CONFIG_FPU_1, --+ NDS32_CONFIG_FPU_2, --+ NDS32_CONFIG_FPU_3, --+ NDS32_CONFIG_FPU_4, --+ NDS32_CONFIG_FPU_5, --+ NDS32_CONFIG_FPU_6, --+ NDS32_CONFIG_FPU_7 --+}; --+ --+/* Do lmwsmw opt model. */ --+enum lmwsmw_cost_type --+{ --+ LMWSMW_OPT_SIZE, --+ LMWSMW_OPT_SPEED, --+ LMWSMW_OPT_ALL, --+ LMWSMW_OPT_AUTO --+}; --+ -- #endif --diff --git a/gcc/config/nds32/nds32-panther.md b/gcc/config/nds32/nds32-panther.md --new file mode 100644 --index 0000000..d45de1c ----- /dev/null --+++ b/gcc/config/nds32/nds32-panther.md --@@ -0,0 +1,446 @@ --+;; Pipeline descriptions of Andes NDS32 cpu for GNU compiler --+;; Copyright (C) 2012-2016 Free Software Foundation, Inc. --+;; Contributed by Andes Technology Corporation. --+;; --+;; This file is part of GCC. --+;; --+;; GCC is free software; you can redistribute it and/or modify it --+;; under the terms of the GNU General Public License as published --+;; by the Free Software Foundation; either version 3, or (at your --+;; option) any later version. --+;; --+;; GCC is distributed in the hope that it will be useful, but WITHOUT --+;; ANY WARRANTY; without even the implied warranty of MERCHANTABILITY --+;; or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public --+;; License for more details. --+;; --+;; You should have received a copy of the GNU General Public License --+;; along with GCC; see the file COPYING3. If not see --+;; . --+ --+;; ------------------------------------------------------------------------ --+;; Define Panther pipeline settings. --+;; ------------------------------------------------------------------------ --+ --+(define_automaton "nds32_pn_machine") --+ --+(define_cpu_unit "pn_i3_0" "nds32_pn_machine") --+(define_cpu_unit "pn_i3_1" "nds32_pn_machine") --+(define_cpu_unit "pn_e1_p0" "nds32_pn_machine") --+(define_cpu_unit "pn_e2_p0" "nds32_pn_machine") --+(define_cpu_unit "pn_e3_p0" "nds32_pn_machine") --+(define_cpu_unit "pn_e4_p0" "nds32_pn_machine") --+(define_cpu_unit "pn_wb_p0" "nds32_pn_machine") --+(define_cpu_unit "pn_e1_p1" "nds32_pn_machine") --+(define_cpu_unit "pn_e2_p1" "nds32_pn_machine") --+(define_cpu_unit "pn_e3_p1" "nds32_pn_machine") --+(define_cpu_unit "pn_e4_p1" "nds32_pn_machine") --+(define_cpu_unit "pn_wb_p1" "nds32_pn_machine") --+(define_cpu_unit "pn_e1_p2" "nds32_pn_machine") --+(define_cpu_unit "pn_e2_p2" "nds32_pn_machine") --+(define_cpu_unit "pn_e3_p2" "nds32_pn_machine") --+(define_cpu_unit "pn_e4_p2" "nds32_pn_machine") --+(define_cpu_unit "pn_wb_p2" "nds32_pn_machine") --+ --+(define_reservation "pn_i3" "pn_i3_0 | pn_i3_1") --+(define_reservation "pn_e1" "pn_e1_p0 | pn_e1_p1") --+(define_reservation "pn_e2" "pn_e2_p0 | pn_e2_p1") --+(define_reservation "pn_e3" "pn_e3_p0 | pn_e3_p1") --+(define_reservation "pn_e4" "pn_e4_p0 | pn_e4_p1") --+(define_reservation "pn_wb" "pn_wb_p0 | pn_wb_p1") --+ --+(define_insn_reservation "nds_pn_unknown" 1 --+ (and (eq_attr "type" "unknown") --+ (eq_attr "pipeline_model" "panther")) --+ "pn_i3, pn_e1, pn_e2, pn_e3, pn_e4, pn_wb") --+ --+(define_insn_reservation "nds_pn_misc" 1 --+ (and (eq_attr "type" "misc") --+ (eq_attr "pipeline_model" "panther")) --+ "pn_i3, pn_e1, pn_e2, pn_e3, pn_e4, pn_wb") --+ --+(define_insn_reservation "nds_pn_mmu" 1 --+ (and (eq_attr "type" "mmu") --+ (eq_attr "pipeline_model" "panther")) --+ "pn_i3, pn_e1, pn_e2, pn_e3, pn_e4, pn_wb") --+ --+(define_insn_reservation "nds_pn_movd44" 1 --+ (and (and (and (eq_attr "type" "alu") --+ (eq_attr "subtype" "simple")) --+ (match_test "nds32::movd44_insn_p (insn)")) --+ (eq_attr "pipeline_model" "panther")) --+ "pn_i3, pn_e1_p1, pn_e2_p1, pn_e3_p1, pn_e4_p1, pn_wb_p1") --+ --+(define_insn_reservation "nds_pn_alu" 1 --+ (and (and (and (eq_attr "type" "alu") --+ (eq_attr "subtype" "simple")) --+ (match_test "!nds32::movd44_insn_p (insn)")) --+ (eq_attr "pipeline_model" "panther")) --+ "pn_i3, pn_e1, pn_e2, pn_e3, pn_e4, pn_wb") --+ --+(define_insn_reservation "nds_pn_shift" 1 --+ (and (and (eq_attr "type" "alu") --+ (eq_attr "subtype" "shift")) --+ (eq_attr "pipeline_model" "panther")) --+ "pn_i3, pn_e1, pn_e2, pn_e3, pn_e4, pn_wb") --+ --+(define_insn_reservation "nds_pn_alu_shift" 1 --+ (and (eq_attr "type" "alu_shift") --+ (eq_attr "pipeline_model" "panther")) --+ "pn_i3, pn_e1, pn_e2, pn_e3, pn_e4, pn_wb") --+ --+(define_insn_reservation "nds_pn_pbsad" 1 --+ (and (eq_attr "type" "pbsad") --+ (eq_attr "pipeline_model" "panther")) --+ "pn_i3, pn_e1, pn_e2, pn_e3*2, pn_e4, pn_wb") --+ --+(define_insn_reservation "nds_pn_pbsada" 1 --+ (and (eq_attr "type" "pbsada") --+ (eq_attr "pipeline_model" "panther")) --+ "pn_i3, pn_e1, pn_e2, pn_e3*3, pn_e4, pn_wb") --+ --+(define_insn_reservation "nds_pn_load_full_word" 1 --+ (and (match_test "nds32::load_full_word_p (insn)") --+ (eq_attr "pipeline_model" "panther")) --+ "pn_i3, pn_e1_p2, pn_e2_p2, pn_e3_p2, pn_e4_p2, pn_wb_p2") --+ --+(define_insn_reservation "nds_pn_load_partial_word" 1 --+ (and (match_test "nds32::load_partial_word_p (insn)") --+ (eq_attr "pipeline_model" "panther")) --+ "pn_i3, pn_e1_p2, pn_e2_p2, pn_e3_p2, pn_e4_p2, pn_wb_p2") --+ --+(define_insn_reservation "nds_pn_store" 1 --+ (and (match_test "nds32::store_single_p (insn)") --+ (eq_attr "pipeline_model" "panther")) --+ "pn_i3, pn_e1_p2, pn_e2_p2, pn_e3_p2, pn_e4_p2, pn_wb_p2") --+ --+(define_insn_reservation "nds_pn_load_multiple_1" 1 --+ (and (and (eq_attr "type" "load_multiple") --+ (eq_attr "combo" "1")) --+ (eq_attr "pipeline_model" "panther")) --+ "pn_i3, pn_e1_p2, pn_e2_p2, pn_e3_p2, pn_e4_p2, pn_wb_p2") --+ --+(define_insn_reservation "nds_pn_load_multiple_2" 1 --+ (and (ior (and (eq_attr "type" "load_multiple") --+ (eq_attr "combo" "2")) --+ (match_test "nds32::load_double_p (insn)")) --+ (eq_attr "pipeline_model" "panther")) --+ "pn_i3, pn_e1_p2*2, pn_e2_p2, pn_e3_p2, pn_e4_p2, pn_wb_p2") --+ --+(define_insn_reservation "nds_pn_load_multiple_3" 1 --+ (and (and (eq_attr "type" "load_multiple") --+ (eq_attr "combo" "3")) --+ (eq_attr "pipeline_model" "panther")) --+ "pn_i3, pn_e1_p2*3, pn_e2_p2, pn_e3_p2, pn_e4_p2, pn_wb_p2") --+ --+(define_insn_reservation "nds_pn_load_multiple_4" 1 --+ (and (and (eq_attr "type" "load_multiple") --+ (eq_attr "combo" "4")) --+ (eq_attr "pipeline_model" "panther")) --+ "pn_i3, pn_e1_p2*4, pn_e2_p2, pn_e3_p2, pn_e4_p2, pn_wb_p2") --+ --+(define_insn_reservation "nds_pn_load_multiple_5" 1 --+ (and (and (eq_attr "type" "load_multiple") --+ (eq_attr "combo" "5")) --+ (eq_attr "pipeline_model" "panther")) --+ "pn_i3, pn_e1_p2*5, pn_e2_p2, pn_e3_p2, pn_e4_p2, pn_wb_p2") --+ --+(define_insn_reservation "nds_pn_load_multiple_6" 1 --+ (and (and (eq_attr "type" "load_multiple") --+ (eq_attr "combo" "5")) --+ (eq_attr "pipeline_model" "panther")) --+ "pn_i3, pn_e1_p2*6, pn_e2_p2, pn_e3_p2, pn_e4_p2, pn_wb_p2") --+ --+(define_insn_reservation "nds_pn_load_multiple_7" 1 --+ (and (and (eq_attr "type" "load_multiple") --+ (eq_attr "combo" "7")) --+ (eq_attr "pipeline_model" "panther")) --+ "pn_i3, pn_e1_p2*7, pn_e2_p2, pn_e3_p2, pn_e4_p2, pn_wb_p2") --+ --+(define_insn_reservation "nds_pn_load_multiple_8" 1 --+ (and (and (eq_attr "type" "load_multiple") --+ (eq_attr "combo" "8")) --+ (eq_attr "pipeline_model" "panther")) --+ "pn_i3, pn_e1_p2*8, pn_e2_p2, pn_e3_p2, pn_e4_p2, pn_wb_p2") --+ --+(define_insn_reservation "nds_pn_load_multiple_12" 1 --+ (and (and (eq_attr "type" "load_multiple") --+ (eq_attr "combo" "12")) --+ (eq_attr "pipeline_model" "panther")) --+ "pn_i3, pn_e1_p2*12, pn_e2_p2, pn_e3_p2, pn_e4_p2, pn_wb_p2") --+ --+(define_insn_reservation "nds_pn_store_multiple_1" 1 --+ (and (and (eq_attr "type" "store_multiple") --+ (eq_attr "combo" "1")) --+ (eq_attr "pipeline_model" "panther")) --+ "pn_i3, pn_e1_p2, pn_e2_p2, pn_e3_p2, pn_e4_p2, pn_wb_p2") --+ --+(define_insn_reservation "nds_pn_store_multiple_2" 1 --+ (and (ior (and (eq_attr "type" "store_multiple") --+ (eq_attr "combo" "2")) --+ (match_test "nds32::store_double_p (insn)")) --+ (eq_attr "pipeline_model" "panther")) --+ "pn_i3, pn_e1_p2*2, pn_e2_p2, pn_e3_p2, pn_e4_p2, pn_wb_p2") --+ --+(define_insn_reservation "nds_pn_store_multiple_3" 1 --+ (and (and (eq_attr "type" "store_multiple") --+ (eq_attr "combo" "3")) --+ (eq_attr "pipeline_model" "panther")) --+ "pn_i3, pn_e1_p2*3, pn_e2_p2, pn_e3_p2, pn_e4_p2, pn_wb_p2") --+ --+(define_insn_reservation "nds_pn_store_multiple_4" 1 --+ (and (and (eq_attr "type" "store_multiple") --+ (eq_attr "combo" "4")) --+ (eq_attr "pipeline_model" "panther")) --+ "pn_i3, pn_e1_p2*4, pn_e2_p2, pn_e3_p2, pn_e4_p2, pn_wb_p2") --+ --+(define_insn_reservation "nds_pn_store_multiple_5" 1 --+ (and (and (eq_attr "type" "store_multiple") --+ (eq_attr "combo" "5")) --+ (eq_attr "pipeline_model" "panther")) --+ "pn_i3, pn_e1_p2*5, pn_e2_p2, pn_e3_p2, pn_e4_p2, pn_wb_p2") --+ --+(define_insn_reservation "nds_pn_store_multiple_6" 1 --+ (and (and (eq_attr "type" "store_multiple") --+ (eq_attr "combo" "5")) --+ (eq_attr "pipeline_model" "panther")) --+ "pn_i3, pn_e1_p2*6, pn_e2_p2, pn_e3_p2, pn_e4_p2, pn_wb_p2") --+ --+(define_insn_reservation "nds_pn_store_multiple_7" 1 --+ (and (and (eq_attr "type" "store_multiple") --+ (eq_attr "combo" "7")) --+ (eq_attr "pipeline_model" "panther")) --+ "pn_i3, pn_e1_p2*7, pn_e2_p2, pn_e3_p2, pn_e4_p2, pn_wb_p2") --+ --+(define_insn_reservation "nds_pn_store_multiple_8" 1 --+ (and (and (eq_attr "type" "store_multiple") --+ (eq_attr "combo" "8")) --+ (eq_attr "pipeline_model" "panther")) --+ "pn_i3, pn_e1_p2*8, pn_e2_p2, pn_e3_p2, pn_e4_p2, pn_wb_p2") --+ --+(define_insn_reservation "nds_pn_store_multiple_12" 1 --+ (and (and (eq_attr "type" "store_multiple") --+ (eq_attr "combo" "12")) --+ (eq_attr "pipeline_model" "panther")) --+ "pn_i3, pn_e1_p2*12, pn_e2_p2, pn_e3_p2, pn_e4_p2, pn_wb_p2") --+ --+(define_insn_reservation "nds_pn_mul" 1 --+ (and (eq_attr "type" "mul") --+ (eq_attr "pipeline_model" "panther")) --+ "pn_i3, pn_e1_p1, pn_e2_p1, pn_e3_p1, pn_e4_p1, pn_wb_p1") --+ --+(define_insn_reservation "nds_pn_mac" 1 --+ (and (eq_attr "type" "mac") --+ (eq_attr "pipeline_model" "panther")) --+ "pn_i3, pn_e1_p1, pn_e2_p1, pn_e3_p1, pn_e4_p1, pn_wb_p1") --+ --+;; The cycles consumed in E4 stage is 32 - CLZ(abs(Ra)) + 2, --+;; so the worst case is 34. --+(define_insn_reservation "nds_pn_div" 1 --+ (and (eq_attr "type" "div") --+ (eq_attr "pipeline_model" "panther")) --+ "pn_i3, pn_e1_p1, pn_e2_p1, pn_e3_p1, pn_e4_p1*34, pn_wb_p1") --+ --+(define_insn_reservation "nds_pn_branch" 1 --+ (and (eq_attr "type" "branch") --+ (eq_attr "pipeline_model" "panther")) --+ "pn_i3, pn_e1_p0, pn_e2_p0, pn_e3_p0, pn_e4_p0, pn_wb_p0") --+ --+;; SHIFT -> ADDR_IN --+(define_bypass 2 --+ "nds_pn_shift" --+ "nds_pn_load_full_word, nds_pn_load_partial_word, nds_pn_store,\ --+ nds_pn_load_multiple_1, nds_pn_load_multiple_2, nds_pn_load_multiple_3,\ --+ nds_pn_load_multiple_4, nds_pn_load_multiple_5, nds_pn_load_multiple_6,\ --+ nds_pn_load_multiple_7, nds_pn_load_multiple_8, nds_pn_load_multiple_12,\ --+ nds_pn_store_multiple_1, nds_pn_store_multiple_2, nds_pn_store_multiple_3,\ --+ nds_pn_store_multiple_4, nds_pn_store_multiple_5, nds_pn_store_multiple_6,\ --+ nds_pn_store_multiple_7, nds_pn_store_multiple_8, nds_pn_store_multiple_12" --+ "nds32_pn_e2_to_e1_p" --+) --+ --+;; ALU, MOVD44 -> ADDR_IN --+(define_bypass 3 --+ "nds_pn_alu, nds_pn_movd44" --+ "nds_pn_load_full_word, nds_pn_load_partial_word, nds_pn_store,\ --+ nds_pn_load_multiple_1, nds_pn_load_multiple_2, nds_pn_load_multiple_3,\ --+ nds_pn_load_multiple_4, nds_pn_load_multiple_5, nds_pn_load_multiple_6,\ --+ nds_pn_load_multiple_7, nds_pn_load_multiple_8, nds_pn_load_multiple_12,\ --+ nds_pn_store_multiple_1, nds_pn_store_multiple_2, nds_pn_store_multiple_3,\ --+ nds_pn_store_multiple_4, nds_pn_store_multiple_5, nds_pn_store_multiple_6,\ --+ nds_pn_store_multiple_7, nds_pn_store_multiple_8, nds_pn_store_multiple_12" --+ "nds32_pn_e3_to_e1_p" --+) --+ --+;; ALU, MOVD44 -> SHIFT, MUL, MAC_RaRb --+(define_bypass 2 --+ "nds_pn_alu, nds_pn_movd44" --+ "nds_pn_shift, nds_pn_mul, nds_pn_mac" --+ "nds32_pn_e3_to_e2_p" --+) --+ --+;; MUL, MAC, DIV, LW, ADDR_OUT -> ADDR_IN --+(define_bypass 4 --+ "nds_pn_mul, nds_pn_mac, nds_pn_div,\ --+ nds_pn_load_full_word, nds_pn_load_partial_word, nds_pn_store,\ --+ nds_pn_load_multiple_1, nds_pn_load_multiple_2, nds_pn_load_multiple_3,\ --+ nds_pn_load_multiple_4, nds_pn_load_multiple_5, nds_pn_load_multiple_6,\ --+ nds_pn_load_multiple_7, nds_pn_load_multiple_8, nds_pn_load_multiple_12,\ --+ nds_pn_store_multiple_1, nds_pn_store_multiple_2, nds_pn_store_multiple_3,\ --+ nds_pn_store_multiple_4, nds_pn_store_multiple_5, nds_pn_store_multiple_6,\ --+ nds_pn_store_multiple_7, nds_pn_store_multiple_8, nds_pn_store_multiple_12" --+ "nds_pn_load_full_word, nds_pn_load_partial_word, nds_pn_store,\ --+ nds_pn_load_multiple_1, nds_pn_load_multiple_2, nds_pn_load_multiple_3,\ --+ nds_pn_load_multiple_4, nds_pn_load_multiple_5, nds_pn_load_multiple_6,\ --+ nds_pn_load_multiple_7, nds_pn_load_multiple_8, nds_pn_load_multiple_12,\ --+ nds_pn_store_multiple_1, nds_pn_store_multiple_2, nds_pn_store_multiple_3,\ --+ nds_pn_store_multiple_4, nds_pn_store_multiple_5, nds_pn_store_multiple_6,\ --+ nds_pn_store_multiple_7, nds_pn_store_multiple_8, nds_pn_store_multiple_12" --+ "nds32_pn_e4_to_e1_p" --+) --+ --+;; MUL, MAC, DIV, LW, ADDR_OUT -> SHIFT, MUL, MAC_RaRb --+(define_bypass 3 --+ "nds_pn_mul, nds_pn_mac, nds_pn_div,\ --+ nds_pn_load_full_word, nds_pn_load_partial_word, nds_pn_store,\ --+ nds_pn_load_multiple_1, nds_pn_load_multiple_2, nds_pn_load_multiple_3,\ --+ nds_pn_load_multiple_4, nds_pn_load_multiple_5, nds_pn_load_multiple_6,\ --+ nds_pn_load_multiple_7, nds_pn_load_multiple_8, nds_pn_load_multiple_12,\ --+ nds_pn_store_multiple_1, nds_pn_store_multiple_2, nds_pn_store_multiple_3,\ --+ nds_pn_store_multiple_4, nds_pn_store_multiple_5, nds_pn_store_multiple_6,\ --+ nds_pn_store_multiple_7, nds_pn_store_multiple_8, nds_pn_store_multiple_12" --+ "nds_pn_shift, nds_pn_mul, nds_pn_mac" --+ "nds32_pn_e4_to_e2_p" --+) --+ --+;; MUL, MAC, DIV, LW, ADDR_OUT -> ALU, MOVD44, BR_COND, ST, SMW(N, 1) --+(define_bypass 2 --+ "nds_pn_mul, nds_pn_mac, nds_pn_div,\ --+ nds_pn_load_full_word, nds_pn_load_partial_word, nds_pn_store,\ --+ nds_pn_load_multiple_1, nds_pn_load_multiple_2, nds_pn_load_multiple_3,\ --+ nds_pn_load_multiple_4, nds_pn_load_multiple_5, nds_pn_load_multiple_6,\ --+ nds_pn_load_multiple_7, nds_pn_load_multiple_8, nds_pn_load_multiple_12,\ --+ nds_pn_store_multiple_1, nds_pn_store_multiple_2, nds_pn_store_multiple_3,\ --+ nds_pn_store_multiple_4, nds_pn_store_multiple_5, nds_pn_store_multiple_6,\ --+ nds_pn_store_multiple_7, nds_pn_store_multiple_8, nds_pn_store_multiple_12" --+ "nds_pn_alu, nds_pn_movd44, nds_pn_branch,\ --+ nds_pn_store,\ --+ nds_pn_store_multiple_1, nds_pn_store_multiple_2, nds_pn_store_multiple_3,\ --+ nds_pn_store_multiple_4, nds_pn_store_multiple_5, nds_pn_store_multiple_6,\ --+ nds_pn_store_multiple_7, nds_pn_store_multiple_8, nds_pn_store_multiple_12" --+ "nds32_pn_e4_to_e3_p" --+) --+ --+;; LH, LB -> ADDR_IN --+(define_bypass 5 --+ "nds_pn_load_partial_word" --+ "nds_pn_load_full_word, nds_pn_load_partial_word, nds_pn_store,\ --+ nds_pn_load_multiple_1, nds_pn_load_multiple_2, nds_pn_load_multiple_3,\ --+ nds_pn_load_multiple_4, nds_pn_load_multiple_5, nds_pn_load_multiple_6,\ --+ nds_pn_load_multiple_7, nds_pn_load_multiple_8, nds_pn_load_multiple_12,\ --+ nds_pn_store_multiple_1, nds_pn_store_multiple_2, nds_pn_store_multiple_3,\ --+ nds_pn_store_multiple_4, nds_pn_store_multiple_5, nds_pn_store_multiple_6,\ --+ nds_pn_store_multiple_7, nds_pn_store_multiple_8, nds_pn_store_multiple_12" --+ "nds32_pn_wb_to_e1_p" --+) --+ --+;; LH, LB -> SHIFT, MUL, MAC_RaRb --+(define_bypass 4 --+ "nds_pn_load_partial_word" --+ "nds_pn_shift, nds_pn_mul, nds_pn_mac" --+ "nds32_pn_wb_to_e2_p" --+) --+ --+;; LH, LB -> ALU, MOVD44, BR_COND, ST, SMW(N, 1) --+(define_bypass 3 --+ "nds_pn_load_partial_word" --+ "nds_pn_alu, nds_pn_movd44, nds_pn_branch,\ --+ nds_pn_store,\ --+ nds_pn_store_multiple_1, nds_pn_store_multiple_2, nds_pn_store_multiple_3,\ --+ nds_pn_store_multiple_4, nds_pn_store_multiple_5, nds_pn_store_multiple_6,\ --+ nds_pn_store_multiple_7, nds_pn_store_multiple_8, nds_pn_store_multiple_12" --+ "nds32_pn_wb_to_e3_p" --+) --+ --+;; LH, LB -> DIV --+(define_bypass 2 --+ "nds_pn_load_partial_word" --+ "nds_pn_div" --+ "nds32_pn_wb_to_e4_p" --+) --+ --+;; LMW(N, N) -> ADDR_IN --+(define_bypass 4 --+ "nds_pn_load_multiple_1, nds_pn_load_multiple_2, nds_pn_load_multiple_3,\ --+ nds_pn_load_multiple_4, nds_pn_load_multiple_5, nds_pn_load_multiple_6,\ --+ nds_pn_load_multiple_7, nds_pn_load_multiple_8, nds_pn_load_multiple_12" --+ "nds_pn_load_full_word, nds_pn_load_partial_word, nds_pn_store,\ --+ nds_pn_load_multiple_1, nds_pn_load_multiple_2, nds_pn_load_multiple_3,\ --+ nds_pn_load_multiple_4, nds_pn_load_multiple_5, nds_pn_load_multiple_6,\ --+ nds_pn_load_multiple_7, nds_pn_load_multiple_8, nds_pn_load_multiple_12,\ --+ nds_pn_store_multiple_1, nds_pn_store_multiple_2, nds_pn_store_multiple_3,\ --+ nds_pn_store_multiple_4, nds_pn_store_multiple_5, nds_pn_store_multiple_6,\ --+ nds_pn_store_multiple_7, nds_pn_store_multiple_8, nds_pn_store_multiple_12" --+ "nds32_pn_last_load_to_e1_p" --+) --+ --+;; LMW(N, N) -> SHIFT, MUL, MAC_RaRb --+(define_bypass 3 --+ "nds_pn_load_multiple_1, nds_pn_load_multiple_2, nds_pn_load_multiple_3,\ --+ nds_pn_load_multiple_4, nds_pn_load_multiple_5, nds_pn_load_multiple_6,\ --+ nds_pn_load_multiple_7, nds_pn_load_multiple_8, nds_pn_load_multiple_12" --+ "nds_pn_shift, nds_pn_mul, nds_pn_mac" --+ "nds32_pn_last_load_to_e2_p" --+) --+ --+;; LMW(N, N - 1) -> ADDR_IN --+(define_bypass 3 --+ "nds_pn_load_multiple_1, nds_pn_load_multiple_2, nds_pn_load_multiple_3,\ --+ nds_pn_load_multiple_4, nds_pn_load_multiple_5, nds_pn_load_multiple_6,\ --+ nds_pn_load_multiple_7, nds_pn_load_multiple_8, nds_pn_load_multiple_12" --+ "nds_pn_load_full_word, nds_pn_load_partial_word, nds_pn_store,\ --+ nds_pn_load_multiple_1, nds_pn_load_multiple_2, nds_pn_load_multiple_3,\ --+ nds_pn_load_multiple_4, nds_pn_load_multiple_5, nds_pn_load_multiple_6,\ --+ nds_pn_load_multiple_7, nds_pn_load_multiple_8, nds_pn_load_multiple_12,\ --+ nds_pn_store_multiple_1, nds_pn_store_multiple_2, nds_pn_store_multiple_3,\ --+ nds_pn_store_multiple_4, nds_pn_store_multiple_5, nds_pn_store_multiple_6,\ --+ nds_pn_store_multiple_7, nds_pn_store_multiple_8, nds_pn_store_multiple_12" --+ "nds32_pn_last_two_load_to_e1_p" --+) --+ --+;; LMW(N, N - 2) -> ADDR_IN --+(define_bypass 2 --+ "nds_pn_load_multiple_1, nds_pn_load_multiple_2, nds_pn_load_multiple_3,\ --+ nds_pn_load_multiple_4, nds_pn_load_multiple_5, nds_pn_load_multiple_6,\ --+ nds_pn_load_multiple_7, nds_pn_load_multiple_8, nds_pn_load_multiple_12" --+ "nds_pn_load_full_word, nds_pn_load_partial_word, nds_pn_store,\ --+ nds_pn_load_multiple_1, nds_pn_load_multiple_2, nds_pn_load_multiple_3,\ --+ nds_pn_load_multiple_4, nds_pn_load_multiple_5, nds_pn_load_multiple_6,\ --+ nds_pn_load_multiple_7, nds_pn_load_multiple_8, nds_pn_load_multiple_12,\ --+ nds_pn_store_multiple_1, nds_pn_store_multiple_2, nds_pn_store_multiple_3,\ --+ nds_pn_store_multiple_4, nds_pn_store_multiple_5, nds_pn_store_multiple_6,\ --+ nds_pn_store_multiple_7, nds_pn_store_multiple_8, nds_pn_store_multiple_12" --+ "nds32_pn_last_three_load_to_e1_p" --+) --+ --+;; LMW(N, N - 1) -> SHIFT, MUL, MAC_RaRb --+(define_bypass 2 --+ "nds_pn_load_multiple_1, nds_pn_load_multiple_2, nds_pn_load_multiple_3,\ --+ nds_pn_load_multiple_4, nds_pn_load_multiple_5, nds_pn_load_multiple_6,\ --+ nds_pn_load_multiple_7, nds_pn_load_multiple_8, nds_pn_load_multiple_12" --+ "nds_pn_shift, nds_pn_mul, nds_pn_mac" --+ "nds32_pn_last_two_load_to_e2_p" --+) --+ --+;; LMW(N, N) -> ALU, MOVD44, BR_COND --+(define_bypass 2 --+ "nds_pn_load_multiple_1, nds_pn_load_multiple_2, nds_pn_load_multiple_3,\ --+ nds_pn_load_multiple_4, nds_pn_load_multiple_5, nds_pn_load_multiple_6,\ --+ nds_pn_load_multiple_7, nds_pn_load_multiple_8, nds_pn_load_multiple_12" --+ "nds_pn_alu, nds_pn_movd44, nds_pn_branch,\ --+ nds_pn_store,\ --+ nds_pn_store_multiple_1, nds_pn_store_multiple_2, nds_pn_store_multiple_3,\ --+ nds_pn_store_multiple_4, nds_pn_store_multiple_5, nds_pn_store_multiple_6,\ --+ nds_pn_store_multiple_7, nds_pn_store_multiple_8, nds_pn_store_multiple_12" --+ "nds32_pn_last_load_to_e3_p" --+) --diff --git a/gcc/config/nds32/nds32-peephole2.md b/gcc/config/nds32/nds32-peephole2.md --index 07e3a2b..bb47385 100644 ----- a/gcc/config/nds32/nds32-peephole2.md --+++ b/gcc/config/nds32/nds32-peephole2.md --@@ -19,6 +19,197 @@ -- ;; . -- -- ---;; Use define_peephole2 to handle possible target-specific optimization. --+;; Use define_split, define_peephole, and define_peephole2 to --+;; handle possible target-specific optimization in this file. -- -- ;; ------------------------------------------------------------------------ --+;; Try to utilize 16-bit instruction by swap operand if possible. --+;; ------------------------------------------------------------------------ --+ --+;; Try to make add as add45. --+(define_peephole2 --+ [(set (match_operand:QIHISI 0 "register_operand" "") --+ (plus:QIHISI (match_operand:QIHISI 1 "register_operand" "") --+ (match_operand:QIHISI 2 "register_operand" "")))] --+ "reload_completed --+ && TARGET_16_BIT --+ && REGNO (operands[0]) == REGNO (operands[2]) --+ && REGNO (operands[0]) != REGNO (operands[1]) --+ && TEST_HARD_REG_BIT (reg_class_contents[MIDDLE_REGS], REGNO (operands[0]))" --+ [(set (match_dup 0) (plus:QIHISI (match_dup 2) (match_dup 1)))]) --+ --+;; Try to make xor/ior/and/mult as xor33/ior33/and33/mult33. --+(define_peephole2 --+ [(set (match_operand:SI 0 "register_operand" "") --+ (match_operator:SI 1 "nds32_have_33_inst_operator" --+ [(match_operand:SI 2 "register_operand" "") --+ (match_operand:SI 3 "register_operand" "")]))] --+ "reload_completed --+ && TARGET_16_BIT --+ && REGNO (operands[0]) == REGNO (operands[3]) --+ && REGNO (operands[0]) != REGNO (operands[2]) --+ && TEST_HARD_REG_BIT (reg_class_contents[LOW_REGS], REGNO (operands[0])) --+ && TEST_HARD_REG_BIT (reg_class_contents[LOW_REGS], REGNO (operands[2]))" --+ [(set (match_dup 0) (match_op_dup 1 [(match_dup 3) (match_dup 2)]))]) --+ --+(define_peephole --+ [(set (match_operand:SI 0 "register_operand" "") --+ (match_operand:SI 1 "register_operand" "")) --+ (set (match_operand:SI 2 "register_operand" "") --+ (match_operand:SI 3 "register_operand" ""))] --+ "TARGET_16_BIT --+ && !TARGET_ISA_V2 --+ && NDS32_IS_GPR_REGNUM (REGNO (operands[0])) --+ && NDS32_IS_GPR_REGNUM (REGNO (operands[1])) --+ && ((REGNO (operands[0]) & 0x1) == 0) --+ && ((REGNO (operands[1]) & 0x1) == 0) --+ && (REGNO (operands[0]) + 1) == REGNO (operands[2]) --+ && (REGNO (operands[1]) + 1) == REGNO (operands[3])" --+ "movd44\t%0, %1" --+ [(set_attr "type" "alu") --+ (set_attr "length" "2")]) --+ --+;; Merge two fcpyss to fcpysd. --+(define_peephole2 --+ [(set (match_operand:SF 0 "float_even_register_operand" "") --+ (match_operand:SF 1 "float_even_register_operand" "")) --+ (set (match_operand:SF 2 "float_odd_register_operand" "") --+ (match_operand:SF 3 "float_odd_register_operand" ""))] --+ "(TARGET_FPU_SINGLE || TARGET_FPU_DOUBLE) --+ && REGNO (operands[0]) == REGNO (operands[2]) - 1 --+ && REGNO (operands[1]) == REGNO (operands[3]) - 1" --+ [(set (match_dup 4) (match_dup 5))] --+ { --+ operands[4] = gen_rtx_REG (DFmode, REGNO (operands[0])); --+ operands[5] = gen_rtx_REG (DFmode, REGNO (operands[1])); --+ }) --+ --+(define_peephole2 --+ [(set (match_operand:SF 0 "float_odd_register_operand" "") --+ (match_operand:SF 1 "float_odd_register_operand" "")) --+ (set (match_operand:SF 2 "float_even_register_operand" "") --+ (match_operand:SF 3 "float_even_register_operand" ""))] --+ "(TARGET_FPU_SINGLE || TARGET_FPU_DOUBLE) --+ && REGNO (operands[2]) == REGNO (operands[0]) - 1 --+ && REGNO (operands[3]) == REGNO (operands[1]) - 1" --+ [(set (match_dup 4) (match_dup 5))] --+ { --+ operands[4] = gen_rtx_REG (DFmode, REGNO (operands[2])); --+ operands[5] = gen_rtx_REG (DFmode, REGNO (operands[3])); --+ }) --+ --+;; Merge two flsi to fldi. --+(define_peephole2 --+ [(set (match_operand:SF 0 "float_even_register_operand" "") --+ (match_operand:SF 1 "memory_operand" "")) --+ (set (match_operand:SF 2 "float_odd_register_operand" "") --+ (match_operand:SF 3 "memory_operand" ""))] --+ "REGNO (operands[0]) == REGNO (operands[2]) - 1 --+ && nds32_memory_merge_peep_p (operands[3], operands[1])" --+ [(set (match_dup 0) (match_dup 1))] --+{ --+ operands[1] = widen_memory_access (operands[3], DFmode, 0); --+ operands[0] = gen_rtx_REG (DFmode, REGNO (operands[0])); --+}) --+ --+(define_peephole2 --+ [(set (match_operand:SF 0 "float_odd_register_operand" "") --+ (match_operand:SF 1 "memory_operand" "")) --+ (set (match_operand:SF 2 "float_even_register_operand" "") --+ (match_operand:SF 3 "memory_operand" ""))] --+ "REGNO (operands[2]) == REGNO (operands[0]) - 1 --+ && nds32_memory_merge_peep_p (operands[1], operands[3])" --+ [(set (match_dup 0) (match_dup 1))] --+{ --+ operands[1] = widen_memory_access (operands[1], DFmode, 0); --+ operands[0] = gen_rtx_REG (DFmode, REGNO (operands[2])); --+}) --+ --+;; Merge two fssi to fsdi. --+(define_peephole2 --+ [(set (match_operand:SF 0 "memory_operand" "") --+ (match_operand:SF 1 "float_even_register_operand" "")) --+ (set (match_operand:SF 2 "memory_operand" "") --+ (match_operand:SF 3 "float_odd_register_operand" ""))] --+ "REGNO (operands[1]) == REGNO (operands[3]) - 1 --+ && nds32_memory_merge_peep_p (operands[2], operands[0])" --+ [(set (match_dup 0) (match_dup 1))] --+{ --+ operands[0] = widen_memory_access (operands[2], DFmode, 0); --+ operands[1] = gen_rtx_REG (DFmode, REGNO (operands[1])); --+}) --+ --+(define_peephole2 --+ [(set (match_operand:SF 0 "memory_operand" "") --+ (match_operand:SF 1 "float_odd_register_operand" "")) --+ (set (match_operand:SF 2 "memory_operand" "") --+ (match_operand:SF 3 "float_even_register_operand" ""))] --+ "REGNO (operands[3]) == REGNO (operands[1]) - 1 --+ && nds32_memory_merge_peep_p (operands[0], operands[2])" --+ [(set (match_dup 0) (match_dup 1))] --+{ --+ operands[0] = widen_memory_access (operands[0], DFmode, 0); --+ operands[1] = gen_rtx_REG (DFmode, REGNO (operands[3])); --+}) --+ --+;; ------------------------------------------------------------------------ --+;; GCC will prefer [u]divmodsi3 rather than [u]divsi3 even remainder is --+;; unused, so we use split to drop mod operation for lower register pressure. --+ --+(define_split --+ [(set (match_operand:SI 0 "register_operand") --+ (div:SI (match_operand:SI 1 "register_operand") --+ (match_operand:SI 2 "register_operand"))) --+ (set (match_operand:SI 3 "register_operand") --+ (mod:SI (match_dup 1) (match_dup 2)))] --+ "find_regno_note (insn, REG_UNUSED, REGNO (operands[3])) != NULL --+ && can_create_pseudo_p ()" --+ [(set (match_dup 0) --+ (div:SI (match_dup 1) --+ (match_dup 2)))]) --+ --+(define_split --+ [(set (match_operand:SI 0 "register_operand") --+ (udiv:SI (match_operand:SI 1 "register_operand") --+ (match_operand:SI 2 "register_operand"))) --+ (set (match_operand:SI 3 "register_operand") --+ (umod:SI (match_dup 1) (match_dup 2)))] --+ "find_regno_note (insn, REG_UNUSED, REGNO (operands[3])) != NULL --+ && can_create_pseudo_p ()" --+ [(set (match_dup 0) --+ (udiv:SI (match_dup 1) --+ (match_dup 2)))]) --+ --+(define_peephole2 --+ [(set (match_operand:DI 0 "register_operand") --+ (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand")) --+ (sign_extend:DI (match_operand:SI 2 "register_operand"))))] --+ "NDS32_EXT_DSP_P () --+ && peep2_regno_dead_p (1, WORDS_BIG_ENDIAN ? REGNO (operands[0]) + 1 : REGNO (operands[0]))" --+ [(const_int 1)] --+{ --+ rtx highpart = nds32_di_high_part_subreg (operands[0]); --+ emit_insn (gen_smulsi3_highpart (highpart, operands[1], operands[2])); --+ DONE; --+}) --+ --+(define_split --+ [(set (match_operand:DI 0 "nds32_general_register_operand" "") --+ (match_operand:DI 1 "nds32_general_register_operand" ""))] --+ "find_regno_note (insn, REG_UNUSED, REGNO (operands[0])) != NULL --+ || find_regno_note (insn, REG_UNUSED, REGNO (operands[0]) + 1) != NULL" --+ [(set (match_dup 0) (match_dup 1))] --+{ --+ rtx dead_note = find_regno_note (curr_insn, REG_UNUSED, REGNO (operands[0])); --+ HOST_WIDE_INT offset; --+ if (dead_note == NULL_RTX) --+ offset = 0; --+ else --+ offset = 4; --+ operands[0] = simplify_gen_subreg ( --+ SImode, operands[0], --+ DImode, offset); --+ operands[1] = simplify_gen_subreg ( --+ SImode, operands[1], --+ DImode, offset); --+}) --diff --git a/gcc/config/nds32/nds32-pipelines-auxiliary.c b/gcc/config/nds32/nds32-pipelines-auxiliary.c --index a396fff..903a2ed 100644 ----- a/gcc/config/nds32/nds32-pipelines-auxiliary.c --+++ b/gcc/config/nds32/nds32-pipelines-auxiliary.c --@@ -21,14 +21,2638 @@ -- -- /* ------------------------------------------------------------------------ */ -- --+#include -- #include "config.h" -- #include "system.h" -- #include "coretypes.h" -- #include "backend.h" --+#include "tree.h" --+#include "rtl.h" --+#include "df.h" --+#include "alias.h" --+#include "stor-layout.h" --+#include "varasm.h" --+#include "calls.h" --+#include "regs.h" --+#include "insn-config.h" /* Required by recog.h. */ --+#include "conditions.h" --+#include "output.h" --+#include "insn-attr.h" /* For DFA state_t. */ --+#include "insn-codes.h" /* For CODE_FOR_xxx. */ --+#include "reload.h" /* For push_reload(). */ --+#include "flags.h" --+#include "insn-config.h" --+#include "expmed.h" --+#include "dojump.h" --+#include "explow.h" --+#include "emit-rtl.h" --+#include "stmt.h" --+#include "expr.h" --+#include "recog.h" --+#include "diagnostic-core.h" --+#include "cfgrtl.h" --+#include "cfganal.h" --+#include "lcm.h" --+#include "cfgbuild.h" --+#include "cfgcleanup.h" --+#include "tm_p.h" --+#include "tm-constrs.h" --+#include "optabs.h" /* For GEN_FCN. */ --+#include "target.h" --+#include "langhooks.h" /* For add_builtin_function(). */ --+#include "builtins.h" --+#include "tree-pass.h" -- -- /* ------------------------------------------------------------------------ */ -- ---/* This file is prepared for future implementation of precise --- pipeline description for nds32 target. */ --+namespace nds32 { --+namespace scheduling { --+ --+/* Classify the memory access direction. It's unknown if the offset register --+ is not a constant value. */ --+enum memory_access_direction --+{ --+ MEM_ACCESS_DIR_POS, --+ MEM_ACCESS_DIR_NEG, --+ MEM_ACCESS_DIR_UNKNOWN --+}; --+ --+/* This class provides some wrappers of the DFA scheduler. Due to the design --+ drawback of the DFA scheduler, creating two instances at the same time is --+ now allowed. Use the loosest relationship such as 'dependency' instead of --+ 'aggregation' or 'composition' can minimize this issue. */ --+class pipeline_simulator --+{ --+public: --+ pipeline_simulator (); --+ ~pipeline_simulator (); --+ --+ void advance_cycle (int cycles = 1); --+ int query_latency (rtx_insn *producer, rtx_insn *consumer) const; --+ int issue_insn (rtx_insn *insn); --+ int force_issue_insn (rtx_insn *insn); --+ --+private: --+ static int gcc_dfa_initialized_; --+ state_t state_; --+}; --+ --+/* Insert pseudo NOPs so that we can see stall cycles caused by structural or --+ data hazards in the assembly code. The design of this class is similar to --+ the 'template method' pattern, but we don't need to maintain multiple --+ customized algorithms at the same time. Hence this class has no virtual --+ functions providing further customizations. */ --+class stall_inserter --+{ --+private: --+ enum dep_type { RES_DEP, DATA_DEP }; --+ --+public: --+ void insert_stalls (); --+ --+private: --+ static rtx emit_pseudo_nop_before (rtx_insn *insn, int cycles, enum dep_type type); --+ --+ void insert_structural_hazard_stalls (); --+ void insert_data_hazard_stalls (); --+ void emit_pseudo_nops_for_data_hazards (rtx_insn *insn, --+ pipeline_simulator &simulator); --+}; --+ --+class pass_nds32_print_stalls : public rtl_opt_pass --+{ --+public: --+ pass_nds32_print_stalls (gcc::context *ctxt); --+ --+ bool gate (function *); --+ unsigned int execute (function *); --+}; --+ --+int pipeline_simulator::gcc_dfa_initialized_ = 0; --+ --+const pass_data pass_data_nds32_print_stalls = --+{ --+ RTL_PASS, /* type */ --+ "print_stalls", /* name */ --+ OPTGROUP_NONE, /* optinfo_flags */ --+ TV_MACH_DEP, /* tv_id */ --+ 0, /* properties_required */ --+ 0, /* properties_provided */ --+ 0, /* properties_destroyed */ --+ 0, /* todo_flags_start */ --+ 0 /* todo_flags_finish */ --+}; --+ --+rtl_opt_pass * --+make_pass_nds32_print_stalls (gcc::context *ctxt) --+{ --+ return new pass_nds32_print_stalls (ctxt); --+} --+ --+/* A safe wrapper to the function reg_overlap_mentioned_p (). */ --+bool --+reg_overlap_p (rtx x, rtx in) --+{ --+ if (x == NULL_RTX || in == NULL_RTX) --+ return false; --+ --+ return static_cast (reg_overlap_mentioned_p (x, in)); --+} --+ --+/* Calculate the cycle distance between two insns in pipeline view. --+ Hence each insn can be treated as one cycle. --+ TODO: multi-cycle insns should be handled --+ specially, but we haven't done it here. */ --+int --+cycle_distance (rtx_insn *from, rtx_insn *to) --+{ --+ int count = 1; --+ --+ for (from = NEXT_INSN (from); from && from != to; from = NEXT_INSN (from)) --+ { --+ if (!insn_executable_p (from)) --+ continue; --+ --+ if (insn_pseudo_nop_p (from)) --+ count += INTVAL (XVECEXP (PATTERN (from), 0, 0)); --+ else --+ ++count; --+ } --+ --+ return count; --+} --+ --+/* Determine the memory access direction of a load/store insn. */ --+memory_access_direction --+determine_access_direction (rtx_insn *insn) --+{ --+ int post_update_rtx_index; --+ rtx plus_rtx; --+ rtx mem_rtx; --+ rtx offset_rtx; --+ --+ switch (get_attr_type (insn)) --+ { --+ case TYPE_LOAD_MULTIPLE: --+ gcc_assert (parallel_elements (insn) >= 2); --+ --+ post_update_rtx_index = find_post_update_rtx (insn); --+ if (post_update_rtx_index != -1) --+ plus_rtx = SET_SRC (parallel_element (insn, post_update_rtx_index)); --+ else --+ { --+ /* (parallel --+ [(set (reg) (mem (reg))) : index 0 --+ (set (reg) (mem (plus (reg) (...)))) : index 1 --+ ...]) */ --+ mem_rtx = SET_SRC (parallel_element (insn, 1)); --+ if (GET_CODE (mem_rtx) == UNSPEC) --+ mem_rtx = XVECEXP (mem_rtx, 0, 0); --+ gcc_assert (MEM_P (mem_rtx)); --+ plus_rtx = XEXP (mem_rtx, 0); --+ } --+ break; --+ --+ case TYPE_STORE_MULTIPLE: --+ gcc_assert (parallel_elements (insn) >= 2); --+ --+ post_update_rtx_index = find_post_update_rtx (insn); --+ if (post_update_rtx_index != -1) --+ plus_rtx = SET_SRC (parallel_element (insn, post_update_rtx_index)); --+ else --+ { --+ /* (parallel --+ [(set (mem (reg)) (reg)) : index 0 --+ (set (mem (plus (reg) (...))) (reg)) : index 1 --+ ...]) */ --+ mem_rtx = SET_DEST (parallel_element (insn, 1)); --+ if (GET_CODE (mem_rtx) == UNSPEC) --+ mem_rtx = XVECEXP (mem_rtx, 0, 0); --+ gcc_assert (MEM_P (mem_rtx)); --+ plus_rtx = XEXP (mem_rtx, 0); --+ } --+ break; --+ --+ case TYPE_LOAD: --+ case TYPE_STORE: --+ mem_rtx = extract_mem_rtx (insn); --+ --+ switch (GET_CODE (XEXP (mem_rtx, 0))) --+ { --+ case POST_INC: --+ /* (mem (post_inc (...))) */ --+ return MEM_ACCESS_DIR_POS; --+ --+ case POST_DEC: --+ /* (mem (post_dec (...))) */ --+ return MEM_ACCESS_DIR_NEG; --+ --+ case PLUS: --+ /* (mem (plus (reg) (...))) */ --+ plus_rtx = XEXP (mem_rtx, 0); --+ break; --+ --+ case POST_MODIFY: --+ /* (mem (post_modify (reg) (plus (reg) (...)))) */ --+ plus_rtx = XEXP (XEXP (mem_rtx, 0), 1); --+ break; --+ --+ default: --+ gcc_unreachable (); --+ } --+ break; --+ --+ default: --+ gcc_unreachable (); --+ } --+ --+ gcc_assert (GET_CODE (plus_rtx) == PLUS); --+ --+ offset_rtx = XEXP (plus_rtx, 1); --+ if (GET_CODE (offset_rtx) == CONST_INT) --+ { --+ if (INTVAL (offset_rtx) < 0) --+ return MEM_ACCESS_DIR_NEG; --+ else --+ return MEM_ACCESS_DIR_POS; --+ } --+ --+ return MEM_ACCESS_DIR_UNKNOWN; --+} --+ --+/* Return the nth load/store operation in the real micro-operation --+ accessing order. */ --+rtx --+extract_nth_access_rtx (rtx_insn *insn, int n) --+{ --+ int n_elems = parallel_elements (insn); --+ int post_update_rtx_index = find_post_update_rtx (insn); --+ memory_access_direction direction = determine_access_direction (insn); --+ --+ gcc_assert (direction != MEM_ACCESS_DIR_UNKNOWN); --+ --+ /* Reverse the order if the direction negative. */ --+ if (direction == MEM_ACCESS_DIR_NEG) --+ n = -1 * n - 1; --+ --+ if (post_update_rtx_index != -1) --+ { --+ if (n >= 0 && post_update_rtx_index <= n) --+ ++n; --+ else if (n < 0 && post_update_rtx_index >= n + n_elems) --+ --n; --+ } --+ --+ return parallel_element (insn, n); --+} --+ --+/* Returns the register operated by the nth load/store operation in the real --+ micro-operation accessing order. This function assumes INSN must be a --+ multiple-word load/store insn. */ --+rtx --+extract_nth_lmsw_access_reg (rtx_insn *insn, int n) --+{ --+ rtx nth_rtx = extract_nth_access_rtx (insn, n); --+ --+ if (nth_rtx == NULL_RTX) --+ return NULL_RTX; --+ --+ switch (get_attr_type (insn)) --+ { --+ case TYPE_LOAD_MULTIPLE: --+ return SET_DEST (nth_rtx); --+ --+ case TYPE_STORE_MULTIPLE: --+ return SET_SRC (nth_rtx); --+ --+ default: --+ gcc_unreachable (); --+ } --+} --+ --+/* Returns the register operated by the nth load/store operation in the real --+ micro-operation accessing order. This function assumes INSN must be a --+ double-word load/store insn. */ --+rtx --+extract_nth_ls2_access_reg (rtx_insn *insn, int n) --+{ --+ rtx reg; --+ enum machine_mode mode; --+ --+ if (post_update_insn_p (insn)) --+ { --+ memory_access_direction direction = determine_access_direction (insn); --+ gcc_assert (direction != MEM_ACCESS_DIR_UNKNOWN); --+ --+ /* Reverse the order if the direction negative. */ --+ if (direction == MEM_ACCESS_DIR_NEG) --+ n = -1 * n - 1; --+ } --+ --+ /* Handle the out-of-range case. */ --+ if (n < -2 || n > 1) --+ return NULL_RTX; --+ --+ /* Convert the index to a positive one. */ --+ if (n < 0) --+ n = 2 + n; --+ --+ switch (get_attr_type (insn)) --+ { --+ case TYPE_LOAD: --+ reg = SET_DEST (PATTERN (insn)); --+ break; --+ --+ case TYPE_STORE: --+ reg = SET_SRC (PATTERN (insn)); --+ break; --+ --+ default: --+ gcc_unreachable (); --+ } --+ --+ gcc_assert (REG_P (reg) || GET_CODE (reg) == SUBREG); --+ --+ switch (GET_MODE (reg)) --+ { --+ case DImode: --+ mode = SImode; --+ break; --+ --+ case DFmode: --+ mode = SFmode; --+ break; --+ --+ default: --+ gcc_unreachable (); --+ } --+ --+ if (n == 0) --+ return gen_lowpart (mode, reg); --+ else --+ return gen_highpart (mode, reg); --+} --+ --+/* Returns the register operated by the nth load/store operation in the real --+ micro-operation accessing order. */ --+rtx --+extract_nth_access_reg (rtx_insn *insn, int index) --+{ --+ switch (GET_CODE (PATTERN (insn))) --+ { --+ case PARALLEL: --+ return extract_nth_lmsw_access_reg (insn, index); --+ --+ case SET: --+ return extract_nth_ls2_access_reg (insn, index); --+ --+ default: --+ gcc_unreachable (); --+ } --+} --+ --+/* Determine if the latency is occured when the consumer PBSADA_INSN uses the --+ value of DEF_REG in its Ra or Rb fields. */ --+bool --+pbsada_insn_ra_rb_dep_reg_p (rtx pbsada_insn, rtx def_reg) --+{ --+ rtx unspec_rtx = SET_SRC (PATTERN (pbsada_insn)); --+ gcc_assert (GET_CODE (unspec_rtx) == UNSPEC); --+ --+ rtx pbsada_ra = XVECEXP (unspec_rtx, 0, 0); --+ rtx pbsada_rb = XVECEXP (unspec_rtx, 0, 1); --+ --+ if (rtx_equal_p (def_reg, pbsada_ra) --+ || rtx_equal_p (def_reg, pbsada_rb)) --+ return true; --+ --+ return false; --+} --+ --+/* Determine if the latency is occured when the consumer PBSADA_INSN uses the --+ value of DEF_REG in its Rt field. */ --+bool --+pbsada_insn_rt_dep_reg_p (rtx pbsada_insn, rtx def_reg) --+{ --+ rtx pbsada_rt = SET_DEST (PATTERN (pbsada_insn)); --+ --+ if (rtx_equal_p (def_reg, pbsada_rt)) --+ return true; --+ --+ return false; --+} --+ --+/* Check if INSN is a movd44 insn consuming DEF_REG. */ --+bool --+movd44_even_dep_p (rtx_insn *insn, rtx def_reg) --+{ --+ if (!movd44_insn_p (insn)) --+ return false; --+ --+ rtx use_rtx = SET_SRC (PATTERN (insn)); --+ --+ if (REG_P (def_reg)) --+ { --+ return rtx_equal_p (def_reg, use_rtx); --+ } --+ else if (GET_CODE (def_reg) == SUBREG --+ && GET_MODE (def_reg) == SImode --+ && rtx_equal_p (SUBREG_REG (def_reg), use_rtx)) --+ { --+ if (TARGET_BIG_ENDIAN && SUBREG_BYTE (def_reg) == 4) --+ return true; --+ --+ if (!TARGET_BIG_ENDIAN && SUBREG_BYTE (def_reg) == 0) --+ return true; --+ --+ return false; --+ } --+ --+ return false; --+} --+ --+/* Check if INSN is a wext insn consuming DEF_REG. */ --+bool --+wext_odd_dep_p (rtx insn, rtx def_reg) --+{ --+ rtx shift_rtx = XEXP (SET_SRC (PATTERN (insn)), 0); --+ rtx use_reg = XEXP (shift_rtx, 0); --+ rtx pos_rtx = XEXP (shift_rtx, 1); --+ --+ if (REG_P (pos_rtx) && reg_overlap_p (def_reg, pos_rtx)) --+ return true; --+ --+ if (GET_MODE (def_reg) == DImode) --+ return reg_overlap_p (def_reg, use_reg); --+ --+ gcc_assert (REG_P (def_reg) || GET_CODE (def_reg) == SUBREG); --+ gcc_assert (REG_P (use_reg)); --+ --+ if (REG_P (def_reg)) --+ { --+ if (!TARGET_BIG_ENDIAN) --+ return REGNO (def_reg) == REGNO (use_reg) + 1; --+ else --+ return REGNO (def_reg) == REGNO (use_reg); --+ } --+ --+ if (GET_CODE (def_reg) == SUBREG) --+ { --+ if (!reg_overlap_p (def_reg, use_reg)) --+ return false; --+ --+ if (!TARGET_BIG_ENDIAN) --+ return SUBREG_BYTE (def_reg) == 4; --+ else --+ return SUBREG_BYTE (def_reg) == 0; --+ } --+ --+ return false; --+} --+ --+/* Check if INSN is a bpick insn consuming DEF_REG. */ --+bool --+bpick_ra_rb_dep_p (rtx insn, rtx def_reg) --+{ --+ rtx ior_rtx = SET_SRC (PATTERN (insn)); --+ rtx and1_rtx = XEXP (ior_rtx, 0); --+ rtx and2_rtx = XEXP (ior_rtx, 1); --+ rtx reg1_0 = XEXP (and1_rtx, 0); --+ rtx reg1_1 = XEXP (and1_rtx, 1); --+ rtx reg2_0 = XEXP (and2_rtx, 0); --+ rtx reg2_1 = XEXP (and2_rtx, 1); --+ --+ if (GET_CODE (reg1_0) == NOT) --+ { --+ if (rtx_equal_p (reg1_0, reg2_0)) --+ return reg_overlap_p (def_reg, reg1_1) --+ || reg_overlap_p (def_reg, reg2_1); --+ --+ if (rtx_equal_p (reg1_0, reg2_1)) --+ return reg_overlap_p (def_reg, reg1_1) --+ || reg_overlap_p (def_reg, reg2_0); --+ } --+ --+ if (GET_CODE (reg1_1) == NOT) --+ { --+ if (rtx_equal_p (reg1_1, reg2_0)) --+ return reg_overlap_p (def_reg, reg1_0) --+ || reg_overlap_p (def_reg, reg2_1); --+ --+ if (rtx_equal_p (reg1_1, reg2_1)) --+ return reg_overlap_p (def_reg, reg1_0) --+ || reg_overlap_p (def_reg, reg2_0); --+ } --+ --+ if (GET_CODE (reg2_0) == NOT) --+ { --+ if (rtx_equal_p (reg2_0, reg1_0)) --+ return reg_overlap_p (def_reg, reg2_1) --+ || reg_overlap_p (def_reg, reg1_1); --+ --+ if (rtx_equal_p (reg2_0, reg1_1)) --+ return reg_overlap_p (def_reg, reg2_1) --+ || reg_overlap_p (def_reg, reg1_0); --+ } --+ --+ if (GET_CODE (reg2_1) == NOT) --+ { --+ if (rtx_equal_p (reg2_1, reg1_0)) --+ return reg_overlap_p (def_reg, reg2_0) --+ || reg_overlap_p (def_reg, reg1_1); --+ --+ if (rtx_equal_p (reg2_1, reg1_1)) --+ return reg_overlap_p (def_reg, reg2_0) --+ || reg_overlap_p (def_reg, reg1_0); --+ } --+ --+ gcc_unreachable (); --+} --+ --+pipeline_simulator::pipeline_simulator () --+{ --+ /* The design of dfa_start () operates on static global variables and --+ allocates memory space without checking whether the function is called --+ twice or not. We add some guards in order to protect it from abusing. */ --+ if (!gcc_dfa_initialized_++) --+ dfa_start (); --+ --+ state_ = xmalloc (state_size()); --+ state_reset (state_); --+} --+ --+pipeline_simulator::~pipeline_simulator () --+{ --+ /* The design of dfa_finish () operates on a static global variable and --+ deallocates memory space without checking whether the function is called --+ twice or not. We add some guards in order to protect it from abusing. */ --+ free (state_); --+ --+ gcc_assert(gcc_dfa_initialized_ > 0); --+ if (!--gcc_dfa_initialized_) --+ dfa_finish (); --+} --+ --+void --+pipeline_simulator::advance_cycle (int cycles) --+{ --+ gcc_assert (cycles > 0); --+ --+ /* The second argument was 'NULL', but we found the expression is directly --+ written in insn-automata.c: --+ if (insn == 0) --+ insn_code = DFA__ADVANCE_CYCLE; --+ Hence we change it to '0' in order to make it consistent. */ --+ while (cycles--) --+ state_transition (state_, 0); --+} --+ --+/* A wrapper of insn_latency () provided by the insn-attr.h in the object tree. --+ See that file for more information. */ --+int --+pipeline_simulator::query_latency (rtx_insn *producer, rtx_insn *consumer) const --+{ --+ return insn_latency (producer, consumer); --+} --+ --+/* Return 0 or negative if we can issue INSN at the current cycle. Otherwise, --+ return a postive value indicates how many cycles we have to wait. The --+ interface is consistent with state_transition () provided by insn-attr.h --+ in the object directory. See that file for more information. */ --+int --+pipeline_simulator::issue_insn (rtx_insn *insn) --+{ --+ int stalls; --+ --+ /* Skip cycles specified by pseudo NOPs. */ --+ if (insn_pseudo_nop_p (insn)) --+ { --+ int nop_stalls = INTVAL (XVECEXP (PATTERN (insn), 0, 0)); --+ --+ gcc_assert (nop_stalls > 0); --+ advance_cycle (nop_stalls); --+ stalls = -1; --+ } --+ else --+ { --+ stalls = state_transition (state_, insn); --+ --+ /* All targets are single-issue, so we advance one cycle once after --+ an insn has been issued successfully. */ --+ if (stalls <= 0) --+ advance_cycle (); --+ } --+ --+ return stalls; --+} --+ --+/* This function is similar to issue_insn (), but it advances cycles until INSN --+ can be issued successfully. If INSN can be issued at the current cycle, the --+ return value will be 0 or negaitive. Otherwise, the function will return --+ the cycles it has been skipped. */ --+int --+pipeline_simulator::force_issue_insn (rtx_insn *insn) --+{ --+ int stalls; --+ --+ stalls = issue_insn (insn); --+ --+ /* Skip cycles until we can issue the insn. */ --+ if (stalls > 0) --+ { --+ advance_cycle (stalls); --+ issue_insn (insn); --+ } --+ --+ return stalls; --+} --+ --+/* The main flow of the class STALL_INSERTER. We insert NOPs for structural --+ hazards because self-stalled instructions also consume the delay cycles --+ caused by data hazards. */ --+void --+stall_inserter::insert_stalls () --+{ --+ compute_bb_for_insn_safe (); --+ --+ insert_structural_hazard_stalls (); --+ insert_data_hazard_stalls (); --+ --+ /* We have to call the following two functions again after we inserting --+ some insns after it has been invoked. Otherwise, an assert expression --+ in final () will be triggered and cause to an internal compiler error. */ --+ init_insn_lengths (); --+ shorten_branches (get_insns ()); --+ --+ free_bb_for_insn (); --+} --+ --+/* A helper function inserting NOPs. CYCLES indicates how many cycles the NOP --+ insn consumes. TYPE indicates what type of the NOP insn we want to insert; --+ now there are two types available: RES_DEP and DATA_DEP. */ --+rtx --+stall_inserter::emit_pseudo_nop_before ( --+ rtx_insn *insn, int cycles, enum dep_type type) --+{ --+ rtx nop_pattern; --+ rtx_insn *nop_insn; --+ int recog; --+ --+ switch (type) --+ { --+ case RES_DEP: --+ nop_pattern = gen_nop_res_dep (GEN_INT (cycles)); --+ break; --+ case DATA_DEP: --+ nop_pattern = gen_nop_data_dep (GEN_INT (cycles)); --+ break; --+ default: --+ gcc_unreachable (); --+ } --+ --+ nop_insn = emit_insn_before (nop_pattern, insn); --+ recog = recog_memoized (nop_insn); --+ gcc_assert(recog != -1); --+ --+ return nop_insn; --+} --+ --+void --+stall_inserter::insert_structural_hazard_stalls () --+{ --+ pipeline_simulator simulator; --+ rtx_insn *insn; --+ --+ for (insn = get_insns (); insn; insn = NEXT_INSN (insn)) --+ { --+ if (!insn_executable_p (insn)) continue; --+ --+ int stalls = simulator.force_issue_insn (insn); --+ --+ if (stalls > 0) --+ emit_pseudo_nop_before (insn, stalls, RES_DEP); --+ } --+} --+ --+void --+stall_inserter::insert_data_hazard_stalls () --+{ --+ pipeline_simulator simulator; --+ rtx_insn *insn; --+ --+ /* Calling to df_insn_rescan_all here is required in order to avoid crash --+ when some special options are specified by users, such as --+ -O0 -fschedule-insns2. */ --+ df_chain_add_problem (DF_DU_CHAIN); --+ df_insn_rescan_all (); --+ df_analyze (); --+ --+ for (insn = get_insns (); insn; insn = NEXT_INSN (insn)) --+ { --+ if (!insn_executable_p (insn)) continue; --+ --+ simulator.force_issue_insn (insn); --+ emit_pseudo_nops_for_data_hazards (insn, simulator); --+ } --+ --+ /* We must call df_finish_pass manually because it should be invoked before --+ BB information is destroyed. Hence we cannot set the TODO_df_finish flag --+ to the pass manager. */ --+ df_insn_rescan_all (); --+ df_finish_pass (false); --+} --+ --+/* Traverse all insns using the results produced by INSN and ask SIMULATOR --+ how many delay cycles between them. If there are some delay cycles, insert --+ corresponding NOP insns there. */ --+void --+stall_inserter::emit_pseudo_nops_for_data_hazards ( --+ rtx_insn *insn, pipeline_simulator &simulator) --+{ --+ df_ref def; --+ df_link *link; --+ std::set processed_insns; --+ --+ FOR_EACH_INSN_DEF (def, insn) --+ { --+ for (link = DF_REF_CHAIN (def); link; link = link->next) --+ { --+ if (!DF_REF_INSN_INFO (link->ref)) --+ continue; --+ --+ rtx_insn *use_insn = DF_REF_INSN (link->ref); --+ --+ if (!insn_executable_p (use_insn) --+ || processed_insns.count (use_insn)) --+ continue; --+ --+ int stalls = simulator.query_latency (insn, use_insn); --+ int distance = cycle_distance (insn, use_insn); --+ --+ if (stalls > distance) --+ { --+ stalls -= distance; --+ emit_pseudo_nop_before (use_insn, stalls, DATA_DEP); --+ processed_insns.insert (use_insn); --+ } --+ } --+ } --+} --+ --+pass_nds32_print_stalls::pass_nds32_print_stalls (gcc::context *ctxt) --+ : rtl_opt_pass (pass_data_nds32_print_stalls, ctxt) --+{ --+} --+ --+bool pass_nds32_print_stalls::gate (function *) --+{ --+ return TARGET_PRINT_STALLS; --+} --+ --+unsigned int --+pass_nds32_print_stalls::execute (function *) --+{ --+ stall_inserter inserter; --+ --+ inserter.insert_stalls (); --+ return 0; --+} --+ --+} // namespace scheduling --+} // namespace nds32 --+ --+/* ------------------------------------------------------------------------ */ --+ --+using namespace nds32; --+using namespace nds32::scheduling; --+ --+namespace { // anonymous namespace --+ --+/* Check the dependency between the producer defining DEF_REG and CONSUMER --+ requiring input operand at II. */ --+bool --+n7_consumed_by_ii_dep_p (rtx_insn *consumer, rtx def_reg) --+{ --+ rtx use_rtx; --+ --+ switch (get_attr_type (consumer)) --+ { --+ /* MOVD44_E */ --+ case TYPE_ALU: --+ if (movd44_even_dep_p (consumer, def_reg)) --+ return true; --+ --+ use_rtx = SET_SRC (PATTERN (consumer)); --+ break; --+ --+ case TYPE_MUL: --+ use_rtx = SET_SRC (PATTERN (consumer)); --+ break; --+ --+ case TYPE_MAC: --+ use_rtx = extract_mac_non_acc_rtx (consumer); --+ break; --+ --+ /* Some special instructions, divmodsi4 and udivmodsi4, produce two --+ results, the quotient and the remainder. It requires two micro- --+ operations in order to write two registers. We have to check the --+ dependency from the producer to the first micro-operation. */ --+ case TYPE_DIV: --+ if (divmod_p (consumer)) --+ use_rtx = SET_SRC (parallel_element (consumer, 0)); --+ else --+ use_rtx = SET_SRC (PATTERN (consumer)); --+ break; --+ --+ case TYPE_LOAD: --+ /* ADDR_IN_bi_Ra, ADDR_IN_!bi */ --+ if (post_update_insn_p (consumer)) --+ use_rtx = extract_base_reg (consumer); --+ else --+ use_rtx = extract_mem_rtx (consumer); --+ break; --+ --+ case TYPE_STORE: --+ /* ADDR_IN_bi_Ra, ADDR_IN_!bi */ --+ if (post_update_insn_p (consumer)) --+ use_rtx = extract_base_reg (consumer); --+ else --+ use_rtx = extract_mem_rtx (consumer); --+ --+ if (reg_overlap_p (def_reg, use_rtx)) --+ return true; --+ --+ /* ST_bi, ST_!bi_RI */ --+ if (!post_update_insn_p (consumer) --+ && !immed_offset_p (extract_mem_rtx (consumer))) --+ return false; --+ --+ use_rtx = SET_SRC (PATTERN (consumer)); --+ break; --+ --+ case TYPE_LOAD_MULTIPLE: --+ use_rtx = extract_base_reg (consumer); --+ break; --+ --+ case TYPE_STORE_MULTIPLE: --+ /* ADDR_IN */ --+ use_rtx = extract_base_reg (consumer); --+ if (reg_overlap_p (def_reg, use_rtx)) --+ return true; --+ --+ /* SMW (N, 1) */ --+ use_rtx = extract_nth_access_rtx (consumer, 0); --+ break; --+ --+ case TYPE_BRANCH: --+ use_rtx = PATTERN (consumer); --+ break; --+ --+ default: --+ gcc_unreachable (); --+ } --+ --+ if (reg_overlap_p (def_reg, use_rtx)) --+ return true; --+ --+ return false; --+} --+ --+/* Check the dependency between the producer defining DEF_REG and CONSUMER --+ requiring input operand at AG (II). */ --+bool --+n8_consumed_by_addr_in_p (rtx_insn *consumer, rtx def_reg) --+{ --+ rtx use_rtx; --+ --+ switch (get_attr_type (consumer)) --+ { --+ case TYPE_BRANCH: --+ use_rtx = extract_branch_target_rtx (consumer); --+ break; --+ --+ case TYPE_LOAD: --+ if (load_single_p (consumer)) --+ use_rtx = extract_mem_rtx (consumer); --+ else --+ use_rtx = extract_base_reg (consumer); --+ break; --+ --+ case TYPE_STORE: --+ if (store_single_p (consumer) --+ && (!post_update_insn_p (consumer) --+ || immed_offset_p (extract_mem_rtx (consumer)))) --+ use_rtx = extract_mem_rtx (consumer); --+ else --+ use_rtx = extract_base_reg (consumer); --+ break; --+ --+ case TYPE_LOAD_MULTIPLE: --+ case TYPE_STORE_MULTIPLE: --+ use_rtx = extract_base_reg (consumer); --+ break; --+ --+ default: --+ gcc_unreachable (); --+ } --+ --+ return reg_overlap_p (def_reg, use_rtx); --+} --+ --+/* Check the dependency between the producer defining DEF_REG and CONSUMER --+ requiring input operand at EX. */ --+bool --+n8_consumed_by_ex_p (rtx_insn *consumer, rtx def_reg) --+{ --+ rtx use_rtx; --+ --+ switch (get_attr_type (consumer)) --+ { --+ case TYPE_ALU: --+ if (movd44_even_dep_p (consumer, def_reg)) --+ return true; --+ --+ use_rtx = SET_SRC (PATTERN (consumer)); --+ break; --+ --+ case TYPE_MUL: --+ use_rtx = SET_SRC (PATTERN (consumer)); --+ break; --+ --+ case TYPE_MAC: --+ use_rtx = extract_mac_non_acc_rtx (consumer); --+ break; --+ --+ /* Some special instructions, divmodsi4 and udivmodsi4, produce two --+ results, the quotient and the remainder. It requires two micro- --+ operations in order to write two registers. We have to check the --+ dependency from the producer to the first micro-operation. */ --+ case TYPE_DIV: --+ if (divmod_p (consumer)) --+ use_rtx = SET_SRC (parallel_element (consumer, 0)); --+ else --+ use_rtx = SET_SRC (PATTERN (consumer)); --+ break; --+ --+ case TYPE_BRANCH: --+ use_rtx = extract_branch_condition_rtx (consumer); --+ break; --+ --+ case TYPE_STORE: --+ /* exclude ST_!bi_RR */ --+ if (!post_update_insn_p (consumer) --+ && !immed_offset_p (extract_mem_rtx (consumer))) --+ return false; --+ --+ use_rtx = SET_SRC (PATTERN (consumer)); --+ break; --+ --+ case TYPE_STORE_MULTIPLE: --+ use_rtx = extract_nth_access_rtx (consumer, 0); --+ break; --+ --+ default: --+ gcc_unreachable (); --+ } --+ --+ return reg_overlap_p (def_reg, use_rtx); --+} --+ --+/* Check the dependency between the producer defining DEF_REG and CONSUMER --+ requiring input operand at AG (II). */ --+bool --+e8_consumed_by_addr_in_p (rtx_insn *consumer, rtx def_reg) --+{ --+ return n8_consumed_by_addr_in_p (consumer, def_reg); --+} --+ --+/* Check the dependency between the producer defining DEF_REG and CONSUMER --+ requiring input operand at EX. */ --+bool --+e8_consumed_by_ex_p (rtx_insn *consumer, rtx def_reg) --+{ --+ rtx use_rtx; --+ --+ switch (get_attr_type (consumer)) --+ { --+ case TYPE_ALU: --+ case TYPE_STORE: --+ use_rtx = SET_SRC (PATTERN (consumer)); --+ break; --+ --+ case TYPE_MUL: --+ case TYPE_MAC: --+ case TYPE_DIV: --+ case TYPE_BRANCH: --+ case TYPE_STORE_MULTIPLE: --+ return n8_consumed_by_ex_p (consumer, def_reg); --+ --+ default: --+ gcc_unreachable (); --+ } --+ --+ return reg_overlap_p (def_reg, use_rtx); --+} --+ --+/* Check the dependency between the producer defining DEF_REG and CONSUMER --+ requiring input operand at EX. */ --+bool --+n9_2r1w_consumed_by_ex_dep_p (rtx_insn *consumer, rtx def_reg) --+{ --+ rtx use_rtx; --+ --+ switch (get_attr_type (consumer)) --+ { --+ case TYPE_ALU: --+ if (movd44_even_dep_p (consumer, def_reg)) --+ return true; --+ --+ use_rtx = SET_SRC (PATTERN (consumer)); --+ break; --+ --+ case TYPE_PBSAD: --+ case TYPE_MUL: --+ use_rtx = SET_SRC (PATTERN (consumer)); --+ break; --+ --+ case TYPE_ALU_SHIFT: --+ use_rtx = extract_shift_reg (consumer); --+ break; --+ --+ case TYPE_PBSADA: --+ return pbsada_insn_ra_rb_dep_reg_p (consumer, def_reg); --+ --+ case TYPE_MAC: --+ use_rtx = PATTERN (consumer); --+ break; --+ --+ case TYPE_DIV: --+ if (divmod_p (consumer)) --+ use_rtx = SET_SRC (parallel_element (consumer, 0)); --+ else --+ use_rtx = SET_SRC (PATTERN (consumer)); --+ break; --+ --+ case TYPE_MMU: --+ if (GET_CODE (PATTERN (consumer)) == SET) --+ use_rtx = SET_SRC (PATTERN (consumer)); --+ else --+ return true; --+ break; --+ --+ case TYPE_LOAD: --+ /* ADDR_IN_bi_Ra, ADDR_IN_!bi */ --+ if (post_update_insn_p (consumer)) --+ use_rtx = extract_base_reg (consumer); --+ else --+ use_rtx = extract_mem_rtx (consumer); --+ break; --+ --+ case TYPE_STORE: --+ /* ADDR_IN_bi_Ra, ADDR_IN_!bi */ --+ if (post_update_insn_p (consumer)) --+ use_rtx = extract_base_reg (consumer); --+ else --+ use_rtx = extract_mem_rtx (consumer); --+ --+ if (reg_overlap_p (def_reg, use_rtx)) --+ return true; --+ --+ /* exclude ST_!bi_RR */ --+ if (!post_update_insn_p (consumer) --+ && !immed_offset_p (extract_mem_rtx (consumer))) --+ return false; --+ --+ use_rtx = SET_SRC (PATTERN (consumer)); --+ break; --+ --+ case TYPE_LOAD_MULTIPLE: --+ use_rtx = extract_base_reg (consumer); --+ break; --+ --+ case TYPE_STORE_MULTIPLE: --+ /* ADDR_IN */ --+ use_rtx = extract_base_reg (consumer); --+ if (reg_overlap_p (def_reg, use_rtx)) --+ return true; --+ --+ /* SMW (N, 1) */ --+ use_rtx = extract_nth_access_rtx (consumer, 0); --+ break; --+ --+ case TYPE_BRANCH: --+ use_rtx = PATTERN (consumer); --+ break; --+ --+ default: --+ gcc_unreachable (); --+ } --+ --+ if (reg_overlap_p (def_reg, use_rtx)) --+ return true; --+ --+ return false; --+} --+ --+/* Check the dependency between the producer defining DEF_REG and CONSUMER --+ requiring input operand at EX. */ --+bool --+n9_3r2w_consumed_by_ex_dep_p (rtx_insn *consumer, rtx def_reg) --+{ --+ rtx use_rtx; --+ --+ switch (get_attr_type (consumer)) --+ { --+ case TYPE_ALU: --+ case TYPE_PBSAD: --+ case TYPE_MUL: --+ use_rtx = SET_SRC (PATTERN (consumer)); --+ break; --+ --+ case TYPE_ALU_SHIFT: --+ use_rtx = extract_shift_reg (consumer); --+ break; --+ --+ case TYPE_PBSADA: --+ return pbsada_insn_ra_rb_dep_reg_p (consumer, def_reg); --+ --+ case TYPE_MAC: --+ use_rtx = extract_mac_non_acc_rtx (consumer); --+ break; --+ --+ /* Some special instructions, divmodsi4 and udivmodsi4, produce two --+ results, the quotient and the remainder. In 2R1W configuration, --+ it requires two micro-operations in order to write two registers. --+ We have to check the dependency from the producer to the first --+ micro-operation. */ --+ case TYPE_DIV: --+ if (divmod_p (consumer)) --+ use_rtx = SET_SRC (parallel_element (consumer, 0)); --+ else --+ use_rtx = SET_SRC (PATTERN (consumer)); --+ break; --+ --+ case TYPE_MMU: --+ if (GET_CODE (PATTERN (consumer)) == SET) --+ use_rtx = SET_SRC (PATTERN (consumer)); --+ else --+ return true; --+ break; --+ --+ case TYPE_LOAD: --+ case TYPE_STORE: --+ use_rtx = extract_mem_rtx (consumer); --+ break; --+ --+ case TYPE_LOAD_MULTIPLE: --+ case TYPE_STORE_MULTIPLE: --+ use_rtx = extract_base_reg (consumer); --+ break; --+ --+ case TYPE_BRANCH: --+ use_rtx = PATTERN (consumer); --+ break; --+ --+ default: --+ gcc_unreachable (); --+ } --+ --+ if (reg_overlap_p (def_reg, use_rtx)) --+ return true; --+ --+ return false; --+} --+ --+/* Check the dependency between the producer defining DEF_REG and CONSUMER --+ requiring input operand at EX. */ --+bool --+n10_consumed_by_ex_dep_p (rtx_insn *consumer, rtx def_reg) --+{ --+ rtx use_rtx; --+ --+ switch (get_attr_type (consumer)) --+ { --+ case TYPE_ALU: --+ case TYPE_PBSAD: --+ case TYPE_MUL: --+ case TYPE_DALU: --+ case TYPE_DALU64: --+ case TYPE_DMUL: --+ case TYPE_DPACK: --+ case TYPE_DINSB: --+ case TYPE_DCMP: --+ case TYPE_DCLIP: --+ case TYPE_DALUROUND: --+ use_rtx = SET_SRC (PATTERN (consumer)); --+ break; --+ --+ case TYPE_ALU_SHIFT: --+ use_rtx = extract_shift_reg (consumer); --+ break; --+ --+ case TYPE_PBSADA: --+ return pbsada_insn_ra_rb_dep_reg_p (consumer, def_reg); --+ --+ case TYPE_MAC: --+ case TYPE_DMAC: --+ use_rtx = extract_mac_non_acc_rtx (consumer); --+ break; --+ --+ /* Some special instructions, divmodsi4 and udivmodsi4, produce two --+ results, the quotient and the remainder. */ --+ case TYPE_DIV: --+ if (divmod_p (consumer)) --+ use_rtx = SET_SRC (parallel_element (consumer, 0)); --+ else --+ use_rtx = SET_SRC (PATTERN (consumer)); --+ break; --+ --+ case TYPE_DWEXT: --+ return wext_odd_dep_p (consumer, def_reg); --+ --+ case TYPE_DBPICK: --+ return bpick_ra_rb_dep_p (consumer, def_reg); --+ --+ case TYPE_MMU: --+ if (GET_CODE (PATTERN (consumer)) == SET) --+ use_rtx = SET_SRC (PATTERN (consumer)); --+ else --+ return true; --+ break; --+ --+ case TYPE_LOAD: --+ case TYPE_STORE: --+ use_rtx = extract_mem_rtx (consumer); --+ break; --+ --+ case TYPE_LOAD_MULTIPLE: --+ case TYPE_STORE_MULTIPLE: --+ use_rtx = extract_base_reg (consumer); --+ break; --+ --+ case TYPE_BRANCH: --+ use_rtx = PATTERN (consumer); --+ break; --+ --+ default: --+ gcc_unreachable (); --+ } --+ --+ if (reg_overlap_p (def_reg, use_rtx)) --+ return true; --+ --+ return false; --+} --+ --+/* Check the dependency between the producer defining DEF_REG and CONSUMER --+ requiring input operand at EX. */ --+bool --+gw_consumed_by_ex_dep_p (rtx_insn *consumer, rtx def_reg) --+{ --+ rtx use_rtx; --+ --+ switch (get_attr_type (consumer)) --+ { --+ case TYPE_ALU: --+ case TYPE_PBSAD: --+ case TYPE_MUL: --+ case TYPE_DALU: --+ case TYPE_DALU64: --+ case TYPE_DMUL: --+ case TYPE_DPACK: --+ case TYPE_DINSB: --+ case TYPE_DCMP: --+ case TYPE_DCLIP: --+ case TYPE_DALUROUND: --+ use_rtx = SET_SRC (PATTERN (consumer)); --+ break; --+ --+ case TYPE_ALU_SHIFT: --+ use_rtx = extract_shift_reg (consumer); --+ break; --+ --+ case TYPE_PBSADA: --+ return pbsada_insn_ra_rb_dep_reg_p (consumer, def_reg); --+ --+ case TYPE_MAC: --+ case TYPE_DMAC: --+ use_rtx = extract_mac_non_acc_rtx (consumer); --+ break; --+ --+ /* Some special instructions, divmodsi4 and udivmodsi4, produce two --+ results, the quotient and the remainder. We have to check the --+ dependency from the producer to the first micro-operation. */ --+ case TYPE_DIV: --+ if (divmod_p (consumer)) --+ use_rtx = SET_SRC (parallel_element (consumer, 0)); --+ else --+ use_rtx = SET_SRC (PATTERN (consumer)); --+ break; --+ --+ case TYPE_DWEXT: --+ return wext_odd_dep_p (consumer, def_reg); --+ --+ case TYPE_DBPICK: --+ return bpick_ra_rb_dep_p (consumer, def_reg); --+ --+ case TYPE_MMU: --+ if (GET_CODE (PATTERN (consumer)) == SET) --+ use_rtx = SET_SRC (PATTERN (consumer)); --+ else --+ return true; --+ break; --+ --+ case TYPE_LOAD: --+ case TYPE_STORE: --+ use_rtx = extract_mem_rtx (consumer); --+ break; --+ --+ case TYPE_LOAD_MULTIPLE: --+ case TYPE_STORE_MULTIPLE: --+ use_rtx = extract_base_reg (consumer); --+ break; --+ --+ case TYPE_BRANCH: --+ use_rtx = PATTERN (consumer); --+ break; --+ --+ default: --+ gcc_unreachable (); --+ } --+ --+ if (reg_overlap_p (def_reg, use_rtx)) --+ return true; --+ --+ return false; --+} --+ --+/* Check dependencies from any stages to ALU_E1 (E1). This is a helper --+ function of n13_consumed_by_e1_dep_p (). */ --+bool --+n13_alu_e1_insn_dep_reg_p (rtx_insn *alu_e1_insn, rtx def_reg) --+{ --+ rtx unspec_rtx, operand_ra, operand_rb; --+ rtx src_rtx, dst_rtx; --+ --+ switch (INSN_CODE (alu_e1_insn)) --+ { --+ /* BSP and BSE are supported by built-in functions, the corresponding --+ patterns are formed by UNSPEC RTXs. We have to handle them --+ individually. */ --+ case CODE_FOR_unspec_bsp: --+ case CODE_FOR_unspec_bse: --+ unspec_rtx = SET_SRC (parallel_element (alu_e1_insn, 0)); --+ gcc_assert (GET_CODE (unspec_rtx) == UNSPEC); --+ --+ operand_ra = XVECEXP (unspec_rtx, 0, 0); --+ operand_rb = XVECEXP (unspec_rtx, 0, 1); --+ --+ if (rtx_equal_p (def_reg, operand_ra) --+ || rtx_equal_p (def_reg, operand_rb)) --+ return true; --+ --+ return false; --+ --+ /* Unlink general ALU instructions, MOVD44 requires operands at E1. */ --+ case CODE_FOR_move_di: --+ case CODE_FOR_move_df: --+ src_rtx = SET_SRC (PATTERN (alu_e1_insn)); --+ dst_rtx = SET_DEST (PATTERN (alu_e1_insn)); --+ --+ if (REG_P (dst_rtx) && REG_P (src_rtx) --+ && rtx_equal_p (src_rtx, def_reg)) --+ return true; --+ --+ return false; --+ --+ default: --+ return false; --+ } --+} --+ --+/* Check the dependency between the producer defining DEF_REG and CONSUMER --+ requiring input operand at E1. Because the address generation unti is --+ at E1, the address input should be ready at E1. Note that the branch --+ target is also a kind of addresses, so we have to check it. */ --+bool --+n13_consumed_by_e1_dep_p (rtx_insn *consumer, rtx def_reg) --+{ --+ rtx use_rtx; --+ --+ switch (get_attr_type (consumer)) --+ { --+ /* ALU_E1 */ --+ case TYPE_ALU: --+ return n13_alu_e1_insn_dep_reg_p (consumer, def_reg); --+ --+ case TYPE_PBSADA: --+ return pbsada_insn_ra_rb_dep_reg_p (consumer, def_reg); --+ --+ case TYPE_PBSAD: --+ case TYPE_MUL: --+ use_rtx = SET_SRC (PATTERN (consumer)); --+ break; --+ --+ case TYPE_MAC: --+ use_rtx = extract_mac_non_acc_rtx (consumer); --+ break; --+ --+ case TYPE_DIV: --+ if (divmod_p (consumer)) --+ use_rtx = SET_SRC (parallel_element (consumer, 0)); --+ else --+ use_rtx = SET_SRC (PATTERN (consumer)); --+ break; --+ --+ case TYPE_MMU: --+ if (GET_CODE (PATTERN (consumer)) == SET) --+ use_rtx = SET_SRC (PATTERN (consumer)); --+ else --+ return true; --+ break; --+ --+ case TYPE_BRANCH: --+ use_rtx = extract_branch_target_rtx (consumer); --+ break; --+ --+ case TYPE_LOAD: --+ case TYPE_STORE: --+ use_rtx = extract_mem_rtx (consumer); --+ break; --+ --+ case TYPE_LOAD_MULTIPLE: --+ case TYPE_STORE_MULTIPLE: --+ use_rtx = extract_base_reg (consumer); --+ break; --+ --+ default: --+ return false; --+ } --+ --+ if (reg_overlap_p (def_reg, use_rtx)) --+ return true; --+ --+ return false; --+} --+ --+/* Check the dependency between the producer defining DEF_REG and CONSUMER --+ requiring input operand at E2. */ --+bool --+n13_consumed_by_e2_dep_p (rtx_insn *consumer, rtx def_reg) --+{ --+ rtx use_rtx; --+ --+ switch (get_attr_type (consumer)) --+ { --+ case TYPE_ALU: --+ case TYPE_STORE: --+ use_rtx = SET_SRC (PATTERN (consumer)); --+ break; --+ --+ case TYPE_ALU_SHIFT: --+ use_rtx = extract_shift_reg (consumer); --+ break; --+ --+ case TYPE_PBSADA: --+ return pbsada_insn_rt_dep_reg_p (consumer, def_reg); --+ --+ case TYPE_STORE_MULTIPLE: --+ use_rtx = extract_nth_access_rtx (consumer, 0); --+ break; --+ --+ case TYPE_BRANCH: --+ use_rtx = extract_branch_condition_rtx (consumer); --+ break; --+ --+ default: --+ gcc_unreachable(); --+ } --+ --+ if (reg_overlap_p (def_reg, use_rtx)) --+ return true; --+ --+ return false; --+} --+ --+/* Check the dependency between the producer defining DEF_REG and CONSUMER --+ requiring input operand at AG (E1). */ --+bool --+pn_consumed_by_e1_dep_p (rtx_insn *consumer, rtx def_reg) --+{ --+ rtx use_rtx; --+ --+ switch (get_attr_type (consumer)) --+ { --+ case TYPE_LOAD: --+ if (load_single_p (consumer)) --+ use_rtx = extract_mem_rtx (consumer); --+ else --+ use_rtx = extract_base_reg (consumer); --+ break; --+ --+ case TYPE_STORE: --+ if (store_single_p (consumer) --+ && (!post_update_insn_p (consumer) --+ || immed_offset_p (extract_mem_rtx (consumer)))) --+ use_rtx = extract_mem_rtx (consumer); --+ else --+ use_rtx = extract_base_reg (consumer); --+ break; --+ --+ case TYPE_LOAD_MULTIPLE: --+ case TYPE_STORE_MULTIPLE: --+ use_rtx = extract_base_reg (consumer); --+ break; --+ --+ default: --+ gcc_unreachable (); --+ } --+ --+ return reg_overlap_p (def_reg, use_rtx); --+} --+ --+bool --+pn_consumed_by_e2_dep_p (rtx_insn *consumer, rtx def_reg) --+{ --+ rtx use_rtx; --+ --+ switch (get_attr_type (consumer)) --+ { --+ case TYPE_ALU: --+ if (get_attr_subtype (consumer) != SUBTYPE_SHIFT) --+ return false; --+ case TYPE_PBSAD: --+ case TYPE_PBSADA: --+ case TYPE_MUL: --+ use_rtx = SET_SRC (PATTERN (consumer)); --+ break; --+ --+ case TYPE_MAC: --+ use_rtx = extract_mac_non_acc_rtx (consumer); --+ break; --+ --+ default: --+ gcc_unreachable (); --+ } --+ --+ return reg_overlap_p (def_reg, use_rtx); --+} --+ --+bool --+pn_consumed_by_e3_dep_p (rtx_insn *consumer, rtx def_reg) --+{ --+ rtx use_rtx; --+ --+ switch (get_attr_type (consumer)) --+ { --+ case TYPE_ALU: --+ if (get_attr_subtype (consumer) == SUBTYPE_SHIFT) --+ return false; --+ case TYPE_PBSAD: --+ case TYPE_PBSADA: --+ use_rtx = SET_SRC (PATTERN (consumer)); --+ break; --+ --+ case TYPE_BRANCH: --+ return (reg_overlap_p (def_reg, extract_branch_target_rtx (consumer)) --+ || reg_overlap_p (def_reg, --+ extract_branch_condition_rtx (consumer))); --+ break; --+ --+ case TYPE_STORE: --+ use_rtx = SET_SRC (PATTERN (consumer)); --+ break; --+ --+ case TYPE_STORE_MULTIPLE: --+ use_rtx = extract_nth_access_rtx (consumer, 0); --+ break; --+ --+ default: --+ gcc_unreachable (); --+ } --+ --+ return reg_overlap_p (def_reg, use_rtx); --+} --+ --+bool --+pn_consumed_by_e4_dep_p (rtx_insn *consumer, rtx def_reg) --+{ --+ rtx use_rtx; --+ --+ switch (get_attr_type (consumer)) --+ { --+ case TYPE_MAC: --+ use_rtx = SET_DEST (PATTERN (consumer)); --+ break; --+ --+ case TYPE_DIV: --+ if (divmod_p (consumer)) --+ use_rtx = SET_SRC (parallel_element (consumer, 0)); --+ else --+ use_rtx = SET_SRC (PATTERN (consumer)); --+ break; --+ --+ default: --+ gcc_unreachable (); --+ } --+ --+ return reg_overlap_p (def_reg, use_rtx); --+} --+ --+} // anonymous namespace --+ --+/* ------------------------------------------------------------------------ */ --+ --+/* Guard functions for N7 core. */ --+ --+bool --+nds32_n7_load_to_ii_p (rtx_insn *producer, rtx_insn *consumer) --+{ --+ if (post_update_insn_p (producer)) --+ return false; --+ --+ rtx def_reg = SET_DEST (PATTERN (producer)); --+ --+ return n7_consumed_by_ii_dep_p (consumer, def_reg); --+} --+ --+bool --+nds32_n7_last_load_to_ii_p (rtx_insn *producer, rtx_insn *consumer) --+{ --+ /* If PRODUCER is a post-update LMW insn, the last micro-operation updates --+ the base register and the result is ready in II stage, so we don't need --+ to handle that case in this guard function and the corresponding bypass --+ rule. */ --+ if (post_update_insn_p (producer)) --+ return false; --+ --+ rtx last_def_reg = extract_nth_access_reg (producer, -1); --+ --+ if (last_def_reg == NULL_RTX) --+ return false; --+ --+ gcc_assert (REG_P (last_def_reg) || GET_CODE (last_def_reg) == SUBREG); --+ --+ return n7_consumed_by_ii_dep_p (consumer, last_def_reg); --+} --+ --+/* Guard functions for N8 core. */ --+ --+bool --+nds32_n8_load_to_ii_p (rtx_insn *producer, rtx_insn *consumer) --+{ --+ if (post_update_insn_p (producer)) --+ return false; --+ --+ rtx def_reg = SET_DEST (PATTERN (producer)); --+ --+ return n8_consumed_by_addr_in_p (consumer, def_reg); --+} --+ --+bool --+nds32_n8_load_bi_to_ii_p (rtx_insn *producer, rtx_insn *consumer) --+{ --+ if (!post_update_insn_p (producer)) --+ return false; --+ --+ rtx def_reg = SET_DEST (PATTERN (producer)); --+ --+ return n8_consumed_by_addr_in_p (consumer, def_reg); --+} --+ --+bool --+nds32_n8_load_to_ex_p (rtx_insn *producer, rtx_insn *consumer) --+{ --+ if (post_update_insn_p (producer)) --+ return false; --+ --+ rtx def_reg = SET_DEST (PATTERN (producer)); --+ --+ return n8_consumed_by_ex_p (consumer, def_reg); --+} --+ --+bool --+nds32_n8_ex_to_ii_p (rtx_insn *producer, rtx_insn *consumer) --+{ --+ rtx def_reg; --+ --+ switch (get_attr_type (producer)) --+ { --+ case TYPE_ALU: --+ if (movd44_insn_p (producer)) --+ def_reg = extract_movd44_odd_reg (producer); --+ else --+ def_reg = SET_DEST (PATTERN (producer)); --+ break; --+ --+ case TYPE_MUL: --+ case TYPE_MAC: --+ def_reg = SET_DEST (PATTERN (producer)); --+ break; --+ --+ case TYPE_DIV: --+ if (divmod_p (producer)) --+ def_reg = SET_DEST (parallel_element (producer, 1)); --+ else --+ def_reg = SET_DEST (PATTERN (producer)); --+ break; --+ --+ case TYPE_LOAD: --+ case TYPE_STORE: --+ case TYPE_LOAD_MULTIPLE: --+ case TYPE_STORE_MULTIPLE: --+ if (!post_update_insn_p (producer)) --+ return false; --+ --+ def_reg = extract_base_reg (producer); --+ break; --+ --+ default: --+ gcc_unreachable (); --+ } --+ --+ return n8_consumed_by_addr_in_p (consumer, def_reg); --+} --+ --+bool --+nds32_n8_last_load_to_ii_p (rtx_insn *producer, rtx_insn *consumer) --+{ --+ /* If PRODUCER is a post-update LMW insn, the last micro-operation updates --+ the base register and the result is ready in EX stage, so we don't need --+ to handle that case in this guard function and the corresponding bypass --+ rule. */ --+ if (post_update_insn_p (producer)) --+ return false; --+ --+ rtx last_def_reg = extract_nth_access_reg (producer, -1); --+ --+ if (last_def_reg == NULL_RTX) --+ return false; --+ --+ gcc_assert (REG_P (last_def_reg) || GET_CODE (last_def_reg) == SUBREG); --+ --+ return n8_consumed_by_addr_in_p (consumer, last_def_reg); --+} --+ --+bool --+nds32_n8_last_load_two_to_ii_p (rtx_insn *producer, rtx_insn *consumer) --+{ --+ int index = -2; --+ --+ /* If PRODUCER is a post-update insn, there is an additional one micro- --+ operation inserted in the end, so the last memory access operation should --+ be handled by this guard function and the corresponding bypass rule. */ --+ if (post_update_insn_p (producer)) --+ index = -1; --+ --+ rtx last_two_def_reg = extract_nth_access_reg (producer, index); --+ --+ if (last_two_def_reg == NULL_RTX) --+ return false; --+ --+ gcc_assert (REG_P (last_two_def_reg) --+ || GET_CODE (last_two_def_reg) == SUBREG); --+ --+ return n8_consumed_by_addr_in_p (consumer, last_two_def_reg); --+} --+ --+bool --+nds32_n8_last_load_to_ex_p (rtx_insn *producer, rtx_insn *consumer) --+{ --+ /* If PRODUCER is a post-update LMW insn, the last micro-operation updates --+ the base register and the result is ready in EX stage, so we don't need --+ to handle that case in this guard function and the corresponding bypass --+ rule. */ --+ if (post_update_insn_p (producer)) --+ return false; --+ --+ rtx last_def_reg = extract_nth_access_reg (producer, -1); --+ --+ if (last_def_reg == NULL_RTX) --+ return false; --+ --+ gcc_assert (REG_P (last_def_reg) || GET_CODE (last_def_reg) == SUBREG); --+ --+ return n8_consumed_by_ex_p (consumer, last_def_reg); --+} --+ --+/* Guard functions for E8 cores. */ --+ --+bool --+nds32_e8_load_to_ii_p (rtx_insn *producer, rtx_insn *consumer) --+{ --+ rtx def_reg = SET_DEST (PATTERN (producer)); --+ --+ return e8_consumed_by_addr_in_p (consumer, def_reg); --+} --+ --+bool --+nds32_e8_load_to_ex_p (rtx_insn *producer, rtx_insn *consumer) --+{ --+ rtx def_reg = SET_DEST (PATTERN (producer)); --+ --+ return e8_consumed_by_ex_p (consumer, def_reg); --+} --+ --+bool --+nds32_e8_ex_to_ii_p (rtx_insn *producer, rtx_insn *consumer) --+{ --+ rtx def_reg; --+ --+ switch (get_attr_type (producer)) --+ { --+ case TYPE_ALU: --+ /* No data hazards if AGEN's input is produced by MOVI or SETHI. */ --+ if (GET_CODE (PATTERN (producer)) == SET) --+ { --+ rtx dest = SET_DEST (PATTERN (producer)); --+ rtx src = SET_SRC (PATTERN (producer)); --+ --+ if ((REG_P (dest) || GET_CODE (dest) == SUBREG) --+ && (GET_CODE (src) == CONST_INT || GET_CODE (src) == HIGH)) --+ return false; --+ } --+ --+ def_reg = SET_DEST (PATTERN (producer)); --+ break; --+ --+ case TYPE_MUL: --+ case TYPE_MAC: --+ def_reg = SET_DEST (PATTERN (producer)); --+ break; --+ --+ case TYPE_DIV: --+ if (divmod_p (producer)) --+ { --+ rtx def_reg1 = SET_DEST (parallel_element (producer, 0)); --+ rtx def_reg2 = SET_DEST (parallel_element (producer, 1)); --+ --+ return (e8_consumed_by_addr_in_p (consumer, def_reg1) --+ || e8_consumed_by_addr_in_p (consumer, def_reg2)); --+ } --+ --+ def_reg = SET_DEST (PATTERN (producer)); --+ break; --+ --+ case TYPE_LOAD: --+ case TYPE_STORE: --+ case TYPE_LOAD_MULTIPLE: --+ case TYPE_STORE_MULTIPLE: --+ if (!post_update_insn_p (producer)) --+ return false; --+ --+ def_reg = extract_base_reg (producer); --+ break; --+ --+ default: --+ gcc_unreachable (); --+ } --+ --+ return e8_consumed_by_addr_in_p (consumer, def_reg); --+} --+ --+bool --+nds32_e8_last_load_to_ii_p (rtx_insn *producer, rtx_insn *consumer) --+{ --+ rtx last_def_reg = extract_nth_access_reg (producer, -1); --+ --+ if (last_def_reg == NULL_RTX) --+ return false; --+ --+ gcc_assert (REG_P (last_def_reg) || GET_CODE (last_def_reg) == SUBREG); --+ --+ return e8_consumed_by_addr_in_p (consumer, last_def_reg); --+} --+ --+bool --+nds32_e8_last_load_to_ex_p (rtx_insn *producer, rtx_insn *consumer) --+{ --+ rtx last_def_reg = extract_nth_access_reg (producer, -1); --+ --+ if (last_def_reg == NULL_RTX) --+ return false; --+ --+ gcc_assert (REG_P (last_def_reg) || GET_CODE (last_def_reg) == SUBREG); --+ --+ return e8_consumed_by_ex_p (consumer, last_def_reg); --+} --+ --+/* Guard functions for N9 cores. */ --+ --+/* Check dependencies from MM to EX. */ --+bool --+nds32_n9_2r1w_mm_to_ex_p (rtx_insn *producer, rtx_insn *consumer) --+{ --+ rtx def_reg; --+ --+ switch (get_attr_type (producer)) --+ { --+ /* LD_!bi */ --+ case TYPE_LOAD: --+ if (post_update_insn_p (producer)) --+ return false; --+ --+ def_reg = SET_DEST (PATTERN (producer)); --+ break; --+ --+ case TYPE_MUL: --+ case TYPE_MAC: --+ def_reg = SET_DEST (PATTERN (producer)); --+ break; --+ --+ default: --+ gcc_unreachable (); --+ } --+ --+ return n9_2r1w_consumed_by_ex_dep_p (consumer, def_reg); --+} --+ --+/* Check dependencies from MM to EX. */ --+bool --+nds32_n9_3r2w_mm_to_ex_p (rtx_insn *producer, rtx_insn *consumer) --+{ --+ rtx def_reg; --+ --+ switch (get_attr_type (producer)) --+ { --+ case TYPE_LOAD: --+ case TYPE_MUL: --+ case TYPE_MAC: --+ def_reg = SET_DEST (PATTERN (producer)); --+ break; --+ --+ /* Some special instructions, divmodsi4 and udivmodsi4, produce two --+ results, the quotient and the remainder. We have to handle them --+ individually. */ --+ case TYPE_DIV: --+ if (divmod_p (producer)) --+ { --+ rtx def_reg1 = SET_DEST (parallel_element (producer, 0)); --+ rtx def_reg2 = SET_DEST (parallel_element (producer, 1)); --+ --+ return (n9_3r2w_consumed_by_ex_dep_p (consumer, def_reg1) --+ || n9_3r2w_consumed_by_ex_dep_p (consumer, def_reg2)); --+ } --+ --+ def_reg = SET_DEST (PATTERN (producer)); --+ break; --+ --+ default: --+ gcc_unreachable (); --+ } --+ --+ return n9_3r2w_consumed_by_ex_dep_p (consumer, def_reg); --+} --+ --+/* Check dependencies from LMW(N, N) to EX. */ --+bool --+nds32_n9_last_load_to_ex_p (rtx_insn *producer, rtx_insn *consumer) --+{ --+ rtx last_def_reg = extract_nth_access_reg (producer, -1); --+ --+ if (nds32_register_ports_config == REG_PORT_2R1W) --+ { --+ /* The base-update micro operation occupies the last cycle. */ --+ if (post_update_insn_p (producer)) --+ return false; --+ --+ /* When the base register is in the list of a load multiple insn and the --+ access order of the base register is not the last one, we need an --+ additional micro operation to commit the load result to the base --+ register -- we can treat the base register as the last defined --+ register. */ --+ size_t i; --+ size_t n_elems = parallel_elements (producer); --+ rtx base_reg = extract_base_reg (producer); --+ --+ for (i = 0; i < n_elems; ++i) --+ { --+ rtx load_rtx = extract_nth_access_rtx (producer, i); --+ rtx list_element = SET_DEST (load_rtx); --+ --+ if (rtx_equal_p (base_reg, list_element) && i != n_elems - 1) --+ { --+ last_def_reg = base_reg; --+ break; --+ } --+ } --+ --+ return n9_2r1w_consumed_by_ex_dep_p (consumer, last_def_reg); --+ } --+ else --+ return n9_3r2w_consumed_by_ex_dep_p (consumer, last_def_reg); --+} --+ --+/* Guard functions for N10 cores. */ --+ --+/* Check dependencies from EX to EX (ADDR_OUT -> ADDR_IN). */ --+bool --+nds32_n10_ex_to_ex_p (rtx_insn *producer, rtx_insn *consumer) --+{ --+ gcc_assert (get_attr_type (producer) == TYPE_FLOAD --+ || get_attr_type (producer) == TYPE_FSTORE); --+ gcc_assert (get_attr_type (consumer) == TYPE_FLOAD --+ || get_attr_type (consumer) == TYPE_FSTORE); --+ --+ if (!post_update_insn_p (producer)) --+ return false; --+ --+ return reg_overlap_p (extract_base_reg (producer), --+ extract_mem_rtx (consumer)); --+} --+ --+/* Check dependencies from MM to EX. */ --+bool --+nds32_n10_mm_to_ex_p (rtx_insn *producer, rtx_insn *consumer) --+{ --+ rtx def_reg; --+ --+ switch (get_attr_type (producer)) --+ { --+ case TYPE_LOAD: --+ case TYPE_MUL: --+ case TYPE_MAC: --+ case TYPE_DALU64: --+ case TYPE_DMUL: --+ case TYPE_DMAC: --+ case TYPE_DALUROUND: --+ case TYPE_DBPICK: --+ case TYPE_DWEXT: --+ def_reg = SET_DEST (PATTERN (producer)); --+ break; --+ --+ /* Some special instructions, divmodsi4 and udivmodsi4, produce two --+ results, the quotient and the remainder. We have to handle them --+ individually. */ --+ case TYPE_DIV: --+ if (divmod_p (producer)) --+ { --+ rtx def_reg1 = SET_DEST (parallel_element (producer, 0)); --+ rtx def_reg2 = SET_DEST (parallel_element (producer, 1)); --+ --+ return (n10_consumed_by_ex_dep_p (consumer, def_reg1) --+ || n10_consumed_by_ex_dep_p (consumer, def_reg2)); --+ } --+ --+ def_reg = SET_DEST (PATTERN (producer)); --+ break; --+ --+ default: --+ gcc_unreachable (); --+ } --+ --+ return n10_consumed_by_ex_dep_p (consumer, def_reg); --+} --+ --+/* Check dependencies from LMW(N, N) to EX. */ --+bool --+nds32_n10_last_load_to_ex_p (rtx_insn *producer, rtx_insn *consumer) --+{ --+ rtx last_def_reg = extract_nth_access_reg (producer, -1); --+ --+ return n10_consumed_by_ex_dep_p (consumer, last_def_reg); --+} --+ --+/* Guard functions for Graywolf cores. */ --+ --+/* Check dependencies from EX to EX (ADDR_OUT -> ADDR_IN). */ --+bool --+nds32_gw_ex_to_ex_p (rtx_insn *producer, rtx_insn *consumer) --+{ --+ return nds32_n10_ex_to_ex_p (producer, consumer); --+} --+ --+/* Check dependencies from MM to EX. */ --+bool --+nds32_gw_mm_to_ex_p (rtx_insn *producer, rtx_insn *consumer) --+{ --+ rtx def_reg; --+ --+ switch (get_attr_type (producer)) --+ { --+ case TYPE_LOAD: --+ case TYPE_MUL: --+ case TYPE_MAC: --+ case TYPE_DALU64: --+ case TYPE_DMUL: --+ case TYPE_DMAC: --+ case TYPE_DALUROUND: --+ case TYPE_DBPICK: --+ case TYPE_DWEXT: --+ def_reg = SET_DEST (PATTERN (producer)); --+ break; --+ --+ /* Some special instructions, divmodsi4 and udivmodsi4, produce two --+ results, the quotient and the remainder. We have to handle them --+ individually. */ --+ case TYPE_DIV: --+ if (divmod_p (producer)) --+ { --+ rtx def_reg1 = SET_DEST (parallel_element (producer, 0)); --+ rtx def_reg2 = SET_DEST (parallel_element (producer, 1)); --+ --+ return (gw_consumed_by_ex_dep_p (consumer, def_reg1) --+ || gw_consumed_by_ex_dep_p (consumer, def_reg2)); --+ } --+ --+ def_reg = SET_DEST (PATTERN (producer)); --+ break; --+ --+ default: --+ gcc_unreachable (); --+ } --+ --+ return gw_consumed_by_ex_dep_p (consumer, def_reg); --+} --+ --+/* Check dependencies from LMW(N, N) to EX. */ --+bool --+nds32_gw_last_load_to_ex_p (rtx_insn *producer, rtx_insn *consumer) --+{ --+ rtx last_def_reg = extract_nth_access_reg (producer, -1); --+ --+ return gw_consumed_by_ex_dep_p (consumer, last_def_reg); --+} --+ --+/* Guard functions for N12/N13 cores. */ --+ --+/* Check dependencies from E2 to E1. */ --+bool --+nds32_n13_e2_to_e1_p (rtx_insn *producer, rtx_insn *consumer) --+{ --+ rtx def_reg; --+ --+ switch (get_attr_type (producer)) --+ { --+ /* Only post-update load/store instructions are considered. These --+ instructions produces address output at E2. */ --+ case TYPE_LOAD: --+ case TYPE_STORE: --+ case TYPE_LOAD_MULTIPLE: --+ case TYPE_STORE_MULTIPLE: --+ if (!post_update_insn_p (producer)) --+ return false; --+ --+ def_reg = extract_base_reg (producer); --+ break; --+ --+ case TYPE_ALU: --+ case TYPE_ALU_SHIFT: --+ case TYPE_PBSAD: --+ case TYPE_PBSADA: --+ case TYPE_MUL: --+ case TYPE_MAC: --+ def_reg = SET_DEST (PATTERN (producer)); --+ break; --+ --+ case TYPE_BRANCH: --+ return true; --+ --+ case TYPE_DIV: --+ /* Some special instructions, divmodsi4 and udivmodsi4, produce two --+ results, the quotient and the remainder. We have to handle them --+ individually. */ --+ if (divmod_p (producer)) --+ { --+ rtx def_reg1 = SET_DEST (parallel_element (producer, 0)); --+ rtx def_reg2 = SET_DEST (parallel_element (producer, 1)); --+ --+ return (n13_consumed_by_e1_dep_p (consumer, def_reg1) --+ || n13_consumed_by_e1_dep_p (consumer, def_reg2)); --+ } --+ --+ def_reg = SET_DEST (PATTERN (producer)); --+ break; --+ --+ default: --+ gcc_unreachable (); --+ } --+ --+ return n13_consumed_by_e1_dep_p (consumer, def_reg); --+} --+ --+/* Check dependencies from Load-Store Unit (E3) to E1. */ --+bool --+nds32_n13_load_to_e1_p (rtx_insn *producer, rtx_insn *consumer) --+{ --+ rtx def_reg = SET_DEST (PATTERN (producer)); --+ --+ gcc_assert (get_attr_type (producer) == TYPE_LOAD); --+ gcc_assert (REG_P (def_reg) || GET_CODE (def_reg) == SUBREG); --+ --+ return n13_consumed_by_e1_dep_p (consumer, def_reg); --+} --+ --+/* Check dependencies from Load-Store Unit (E3) to E2. */ --+bool --+nds32_n13_load_to_e2_p (rtx_insn *producer, rtx_insn *consumer) --+{ --+ rtx def_reg = SET_DEST (PATTERN (producer)); --+ --+ gcc_assert (get_attr_type (producer) == TYPE_LOAD); --+ gcc_assert (REG_P (def_reg) || GET_CODE (def_reg) == SUBREG); --+ --+ return n13_consumed_by_e2_dep_p (consumer, def_reg); --+} --+ --+/* Check dependencies from LMW(N, N) to E1. */ --+bool --+nds32_n13_last_load_to_e1_p (rtx_insn *producer, rtx_insn *consumer) --+{ --+ rtx last_def_reg = extract_nth_access_reg (producer, -1); --+ --+ return n13_consumed_by_e1_dep_p (consumer, last_def_reg); --+} --+ --+/* Check dependencies from LMW(N, N) to E2. */ --+bool --+nds32_n13_last_load_to_e2_p (rtx_insn *producer, rtx_insn *consumer) --+{ --+ rtx last_def_reg = extract_nth_access_reg (producer, -1); --+ --+ return n13_consumed_by_e2_dep_p (consumer, last_def_reg); --+} --+ --+/* Check dependencies from LMW(N, N-1) to E2. */ --+bool --+nds32_n13_last_two_load_to_e1_p (rtx_insn *producer, rtx_insn *consumer) --+{ --+ rtx last_two_def_reg = extract_nth_access_reg (producer, -2); --+ --+ if (last_two_def_reg == NULL_RTX) --+ return false; --+ --+ return n13_consumed_by_e1_dep_p (consumer, last_two_def_reg); --+} --+ --+/* Guard functions for Panther cores. */ --+ --+/* Check dependencies from E2 to E1. */ --+bool --+nds32_pn_e2_to_e1_p (rtx_insn *producer, rtx_insn *consumer) --+{ --+ rtx def_reg; --+ --+ switch (get_attr_type (producer)) --+ { --+ case TYPE_ALU: --+ gcc_assert (get_attr_subtype (producer) == SUBTYPE_SHIFT); --+ def_reg = SET_DEST (PATTERN (producer)); --+ break; --+ --+ default: --+ gcc_unreachable (); --+ } --+ --+ return pn_consumed_by_e1_dep_p (consumer, def_reg); --+} --+ --+/* Check dependencies from E3 to E1. */ --+bool --+nds32_pn_e3_to_e1_p (rtx_insn *producer, rtx_insn *consumer) --+{ --+ rtx def_reg; --+ --+ switch (get_attr_type (producer)) --+ { --+ case TYPE_ALU: --+ def_reg = SET_DEST (PATTERN (producer)); --+ break; --+ --+ default: --+ gcc_unreachable (); --+ } --+ --+ return pn_consumed_by_e1_dep_p (consumer, def_reg); --+} --+ --+/* Check dependencies from E3 to E2. */ --+bool --+nds32_pn_e3_to_e2_p (rtx_insn *producer, rtx_insn *consumer) --+{ --+ rtx def_reg; --+ --+ switch (get_attr_type (producer)) --+ { --+ case TYPE_ALU: --+ def_reg = SET_DEST (PATTERN (producer)); --+ break; --+ --+ default: --+ gcc_unreachable (); --+ } --+ --+ return pn_consumed_by_e2_dep_p (consumer, def_reg); --+} --+ --+/* Check dependencies from E4 to E1. */ --+bool --+nds32_pn_e4_to_e1_p (rtx_insn *producer, rtx_insn *consumer) --+{ --+ rtx def_reg; --+ --+ switch (get_attr_type (producer)) --+ { --+ case TYPE_MUL: --+ case TYPE_MAC: --+ def_reg = SET_DEST (PATTERN (producer)); --+ break; --+ --+ case TYPE_DIV: --+ if (divmod_p (producer)) --+ { --+ rtx def_reg1 = SET_DEST (parallel_element (producer, 0)); --+ rtx def_reg2 = SET_DEST (parallel_element (producer, 1)); --+ --+ return (pn_consumed_by_e1_dep_p (consumer, def_reg1) --+ || pn_consumed_by_e1_dep_p (consumer, def_reg2)); --+ } --+ --+ def_reg = SET_DEST (PATTERN (producer)); --+ break; --+ --+ case TYPE_LOAD: --+ if (post_update_insn_p (producer) --+ && pn_consumed_by_e1_dep_p (consumer, extract_base_reg (producer))) --+ return true; --+ --+ if (!load_full_word_p (producer)) --+ return false; --+ --+ def_reg = SET_DEST (PATTERN (producer)); --+ break; --+ --+ case TYPE_STORE: --+ case TYPE_LOAD_MULTIPLE: --+ case TYPE_STORE_MULTIPLE: --+ if (!post_update_insn_p (producer)) --+ return false; --+ --+ def_reg = extract_base_reg (producer); --+ break; --+ --+ default: --+ gcc_unreachable (); --+ } --+ --+ return pn_consumed_by_e1_dep_p (consumer, def_reg); --+} --+ --+/* Check dependencies from E4 to E2. */ --+bool --+nds32_pn_e4_to_e2_p (rtx_insn *producer, rtx_insn *consumer) --+{ --+ rtx def_reg; --+ --+ switch (get_attr_type (producer)) --+ { --+ case TYPE_MUL: --+ case TYPE_MAC: --+ def_reg = SET_DEST (PATTERN (producer)); --+ break; --+ --+ case TYPE_DIV: --+ if (divmod_p (producer)) --+ { --+ rtx def_reg1 = SET_DEST (parallel_element (producer, 0)); --+ rtx def_reg2 = SET_DEST (parallel_element (producer, 1)); --+ --+ return (pn_consumed_by_e2_dep_p (consumer, def_reg1) --+ || pn_consumed_by_e2_dep_p (consumer, def_reg2)); --+ } --+ --+ def_reg = SET_DEST (PATTERN (producer)); --+ break; --+ --+ case TYPE_LOAD: --+ if (post_update_insn_p (producer) --+ && pn_consumed_by_e2_dep_p (consumer, extract_base_reg (producer))) --+ return true; --+ --+ if (!load_full_word_p (producer)) --+ return false; --+ --+ def_reg = SET_DEST (PATTERN (producer)); --+ break; --+ --+ case TYPE_STORE: --+ case TYPE_LOAD_MULTIPLE: --+ case TYPE_STORE_MULTIPLE: --+ if (!post_update_insn_p (producer)) --+ return false; --+ --+ def_reg = extract_base_reg (producer); --+ break; --+ --+ default: --+ gcc_unreachable (); --+ } --+ --+ return pn_consumed_by_e2_dep_p (consumer, def_reg); --+} --+ --+/* Check dependencies from E4 to E3. */ --+bool --+nds32_pn_e4_to_e3_p (rtx_insn *producer, rtx_insn *consumer) --+{ --+ rtx def_reg; --+ --+ switch (get_attr_type (producer)) --+ { --+ case TYPE_MUL: --+ case TYPE_MAC: --+ def_reg = SET_DEST (PATTERN (producer)); --+ break; --+ --+ case TYPE_DIV: --+ if (divmod_p (producer)) --+ { --+ rtx def_reg1 = SET_DEST (parallel_element (producer, 0)); --+ rtx def_reg2 = SET_DEST (parallel_element (producer, 1)); --+ --+ return (pn_consumed_by_e3_dep_p (consumer, def_reg1) --+ || pn_consumed_by_e3_dep_p (consumer, def_reg2)); --+ } --+ --+ def_reg = SET_DEST (PATTERN (producer)); --+ break; --+ --+ case TYPE_LOAD: --+ if (post_update_insn_p (producer) --+ && pn_consumed_by_e3_dep_p (consumer, extract_base_reg (producer))) --+ return true; --+ --+ if (load_partial_word_p (producer)) --+ return false; --+ --+ def_reg = SET_DEST (PATTERN (producer)); --+ break; --+ --+ case TYPE_STORE: --+ case TYPE_LOAD_MULTIPLE: --+ case TYPE_STORE_MULTIPLE: --+ if (!post_update_insn_p (producer)) --+ return false; --+ --+ def_reg = extract_base_reg (producer); --+ break; --+ --+ default: --+ gcc_unreachable (); --+ } --+ --+ return pn_consumed_by_e3_dep_p (consumer, def_reg); --+} --+ --+/* Check dependencies from WB to E1. */ --+bool --+nds32_pn_wb_to_e1_p (rtx_insn *producer, rtx_insn *consumer) --+{ --+ rtx def_reg; --+ --+ switch (get_attr_type (producer)) --+ { --+ case TYPE_LOAD: --+ if (!load_partial_word_p (producer)) --+ return false; --+ --+ def_reg = SET_DEST (PATTERN (producer)); --+ break; --+ --+ default: --+ gcc_unreachable (); --+ } --+ --+ return pn_consumed_by_e1_dep_p (consumer, def_reg); --+} --+ --+/* Check dependencies from WB to E2. */ --+bool --+nds32_pn_wb_to_e2_p (rtx_insn *producer, rtx_insn *consumer) --+{ --+ rtx def_reg; --+ --+ switch (get_attr_type (producer)) --+ { --+ case TYPE_LOAD: --+ if (!load_partial_word_p (producer)) --+ return false; --+ --+ def_reg = SET_DEST (PATTERN (producer)); --+ break; --+ --+ default: --+ gcc_unreachable (); --+ } --+ --+ return pn_consumed_by_e2_dep_p (consumer, def_reg); --+} --+ --+/* Check dependencies from WB to E3. */ --+bool --+nds32_pn_wb_to_e3_p (rtx_insn *producer, rtx_insn *consumer) --+{ --+ rtx def_reg; --+ --+ switch (get_attr_type (producer)) --+ { --+ case TYPE_LOAD: --+ if (!load_partial_word_p (producer)) --+ return false; --+ --+ def_reg = SET_DEST (PATTERN (producer)); --+ break; --+ --+ default: --+ gcc_unreachable (); --+ } --+ --+ return pn_consumed_by_e3_dep_p (consumer, def_reg); --+} --+ --+/* Check dependencies from WB to E4. */ --+bool --+nds32_pn_wb_to_e4_p (rtx_insn *producer, rtx_insn *consumer) --+{ --+ rtx def_reg; --+ --+ switch (get_attr_type (producer)) --+ { --+ case TYPE_LOAD: --+ if (!load_partial_word_p (producer)) --+ return false; --+ --+ def_reg = SET_DEST (PATTERN (producer)); --+ break; --+ --+ default: --+ gcc_unreachable (); --+ } --+ --+ return pn_consumed_by_e4_dep_p (consumer, def_reg); --+} --+ --+/* Check dependencies from LMW(N, N) to E1. */ --+bool --+nds32_pn_last_load_to_e1_p (rtx_insn *producer, rtx_insn *consumer) --+{ --+ rtx last_def_reg = extract_nth_access_reg (producer, -1); --+ --+ return pn_consumed_by_e1_dep_p (consumer, last_def_reg); --+} --+ --+/* Check dependencies from LMW(N, N) to E2. */ --+bool --+nds32_pn_last_load_to_e2_p (rtx_insn *producer, rtx_insn *consumer) --+{ --+ rtx last_def_reg = extract_nth_access_reg (producer, -1); --+ --+ return pn_consumed_by_e2_dep_p (consumer, last_def_reg); --+} --+ --+/* Check dependencies from LMW(N, N) to E3. */ --+bool --+nds32_pn_last_load_to_e3_p (rtx_insn *producer, rtx_insn *consumer) --+{ --+ rtx last_def_reg = extract_nth_access_reg (producer, -1); --+ --+ return pn_consumed_by_e3_dep_p (consumer, last_def_reg); --+} --+ --+/* Check dependencies from LMW(N, N - 1) to E1. */ --+bool --+nds32_pn_last_two_load_to_e1_p (rtx_insn *producer, rtx_insn *consumer) --+{ --+ rtx last_two_def_reg = extract_nth_access_reg (producer, -2); --+ --+ if (last_two_def_reg == NULL_RTX) --+ return false; --+ --+ return pn_consumed_by_e1_dep_p (consumer, last_two_def_reg); --+} --+ --+/* Check dependencies from LMW(N, N - 1) to E2. */ --+bool --+nds32_pn_last_two_load_to_e2_p (rtx_insn *producer, rtx_insn *consumer) --+{ --+ rtx last_two_def_reg = extract_nth_access_reg (producer, -2); --+ --+ if (last_two_def_reg == NULL_RTX) --+ return false; --+ --+ return pn_consumed_by_e2_dep_p (consumer, last_two_def_reg); --+} --+ --+/* Check dependencies from LMW(N, N - 2) to E1. */ --+bool --+nds32_pn_last_three_load_to_e1_p (rtx_insn *producer, rtx_insn *consumer) --+{ --+ rtx last_three_def_reg = extract_nth_access_reg (producer, -3); --+ --+ if (last_three_def_reg == NULL_RTX) --+ return false; --+ --+ return pn_consumed_by_e1_dep_p (consumer, last_three_def_reg); --+} -- -- /* ------------------------------------------------------------------------ */ --diff --git a/gcc/config/nds32/nds32-predicates.c b/gcc/config/nds32/nds32-predicates.c --index 361d001..b45d3e6 100644 ----- a/gcc/config/nds32/nds32-predicates.c --+++ b/gcc/config/nds32/nds32-predicates.c --@@ -24,14 +24,41 @@ -- #include "system.h" -- #include "coretypes.h" -- #include "backend.h" ---#include "target.h" ---#include "rtl.h" -- #include "tree.h" ---#include "tm_p.h" ---#include "optabs.h" /* For GEN_FCN. */ --+#include "rtl.h" --+#include "df.h" --+#include "alias.h" --+#include "stor-layout.h" --+#include "varasm.h" --+#include "calls.h" --+#include "regs.h" --+#include "insn-config.h" /* Required by recog.h. */ --+#include "conditions.h" --+#include "output.h" --+#include "insn-attr.h" /* For DFA state_t. */ --+#include "insn-codes.h" /* For CODE_FOR_xxx. */ --+#include "reload.h" /* For push_reload(). */ --+#include "flags.h" --+#include "insn-config.h" --+#include "expmed.h" --+#include "dojump.h" --+#include "explow.h" -- #include "emit-rtl.h" --+#include "stmt.h" --+#include "expr.h" -- #include "recog.h" --+#include "diagnostic-core.h" --+#include "cfgrtl.h" --+#include "cfganal.h" --+#include "lcm.h" --+#include "cfgbuild.h" --+#include "cfgcleanup.h" --+#include "tm_p.h" -- #include "tm-constrs.h" --+#include "optabs.h" /* For GEN_FCN. */ --+#include "target.h" --+#include "langhooks.h" /* For add_builtin_function(). */ --+#include "builtins.h" -- -- /* ------------------------------------------------------------------------ */ -- --@@ -98,21 +125,33 @@ nds32_consecutive_registers_load_store_p (rtx op, -- We have to extract reg and mem of every element and -- check if the information is valid for multiple load/store operation. */ -- bool ---nds32_valid_multiple_load_store (rtx op, bool load_p) --+nds32_valid_multiple_load_store_p (rtx op, bool load_p, bool bim_p) -- { -- int count; -- int first_elt_regno; --+ int update_base_elt_idx; --+ int offset; -- rtx elt; --+ rtx update_base; -- --- /* Get the counts of elements in the parallel rtx. */ --- count = XVECLEN (op, 0); --- /* Pick up the first element. */ --- elt = XVECEXP (op, 0, 0); --+ /* Get the counts of elements in the parallel rtx. --+ Last one is update base register if bim_p. --+ and pick up the first element. */ --+ if (bim_p) --+ { --+ count = XVECLEN (op, 0) - 1; --+ elt = XVECEXP (op, 0, 1); --+ } --+ else --+ { --+ count = XVECLEN (op, 0); --+ elt = XVECEXP (op, 0, 0); --+ } -- -- /* Perform some quick check for the first element in the parallel rtx. */ -- if (GET_CODE (elt) != SET -- || count <= 1 --- || count > 8) --+ || count > 25) -- return false; -- -- /* Pick up regno of first element for further detail checking. --@@ -138,11 +177,29 @@ nds32_valid_multiple_load_store (rtx op, bool load_p) -- Refer to nds32-multiple.md for more information -- about following checking. -- The starting element of parallel rtx is index 0. */ --- if (!nds32_consecutive_registers_load_store_p (op, load_p, 0, --+ if (!nds32_consecutive_registers_load_store_p (op, load_p, bim_p ? 1 : 0, -- first_elt_regno, -- count)) -- return false; -- --+ if (bim_p) --+ { --+ update_base_elt_idx = 0; --+ update_base = XVECEXP (op, 0, update_base_elt_idx); --+ if (!REG_P (SET_DEST (update_base))) --+ return false; --+ if (GET_CODE (SET_SRC (update_base)) != PLUS) --+ return false; --+ else --+ { --+ offset = count * UNITS_PER_WORD; --+ elt = XEXP (SET_SRC (update_base), 1); --+ if (GET_CODE (elt) != CONST_INT --+ || (INTVAL (elt) != offset)) --+ return false; --+ } --+ } --+ -- /* Pass all test, this is a valid rtx. */ -- return true; -- } --@@ -174,47 +231,47 @@ nds32_valid_stack_push_pop_p (rtx op, bool push_p) -- { -- elt = XVECEXP (op, 0, index); -- if (GET_CODE (elt) != SET) --- return false; --+ return false; -- } -- -- /* For push operation, the parallel rtx looks like: -- (parallel [(set (mem (plus (reg:SI SP_REGNUM) (const_int -32))) --- (reg:SI Rb)) --- (set (mem (plus (reg:SI SP_REGNUM) (const_int -28))) --- (reg:SI Rb+1)) --- ... --- (set (mem (plus (reg:SI SP_REGNUM) (const_int -16))) --- (reg:SI Re)) --- (set (mem (plus (reg:SI SP_REGNUM) (const_int -12))) --- (reg:SI FP_REGNUM)) --- (set (mem (plus (reg:SI SP_REGNUM) (const_int -8))) --- (reg:SI GP_REGNUM)) --- (set (mem (plus (reg:SI SP_REGNUM) (const_int -4))) --- (reg:SI LP_REGNUM)) --- (set (reg:SI SP_REGNUM) --- (plus (reg:SI SP_REGNUM) (const_int -32)))]) --+ (reg:SI Rb)) --+ (set (mem (plus (reg:SI SP_REGNUM) (const_int -28))) --+ (reg:SI Rb+1)) --+ ... --+ (set (mem (plus (reg:SI SP_REGNUM) (const_int -16))) --+ (reg:SI Re)) --+ (set (mem (plus (reg:SI SP_REGNUM) (const_int -12))) --+ (reg:SI FP_REGNUM)) --+ (set (mem (plus (reg:SI SP_REGNUM) (const_int -8))) --+ (reg:SI GP_REGNUM)) --+ (set (mem (plus (reg:SI SP_REGNUM) (const_int -4))) --+ (reg:SI LP_REGNUM)) --+ (set (reg:SI SP_REGNUM) --+ (plus (reg:SI SP_REGNUM) (const_int -32)))]) -- -- For pop operation, the parallel rtx looks like: -- (parallel [(set (reg:SI Rb) --- (mem (reg:SI SP_REGNUM))) --- (set (reg:SI Rb+1) --- (mem (plus (reg:SI SP_REGNUM) (const_int 4)))) --- ... --- (set (reg:SI Re) --- (mem (plus (reg:SI SP_REGNUM) (const_int 16)))) --- (set (reg:SI FP_REGNUM) --- (mem (plus (reg:SI SP_REGNUM) (const_int 20)))) --- (set (reg:SI GP_REGNUM) --- (mem (plus (reg:SI SP_REGNUM) (const_int 24)))) --- (set (reg:SI LP_REGNUM) --- (mem (plus (reg:SI SP_REGNUM) (const_int 28)))) --- (set (reg:SI SP_REGNUM) --- (plus (reg:SI SP_REGNUM) (const_int 32)))]) */ --+ (mem (reg:SI SP_REGNUM))) --+ (set (reg:SI Rb+1) --+ (mem (plus (reg:SI SP_REGNUM) (const_int 4)))) --+ ... --+ (set (reg:SI Re) --+ (mem (plus (reg:SI SP_REGNUM) (const_int 16)))) --+ (set (reg:SI FP_REGNUM) --+ (mem (plus (reg:SI SP_REGNUM) (const_int 20)))) --+ (set (reg:SI GP_REGNUM) --+ (mem (plus (reg:SI SP_REGNUM) (const_int 24)))) --+ (set (reg:SI LP_REGNUM) --+ (mem (plus (reg:SI SP_REGNUM) (const_int 28)))) --+ (set (reg:SI SP_REGNUM) --+ (plus (reg:SI SP_REGNUM) (const_int 32)))]) */ -- -- /* 1. Consecutive registers push/pop operations. --- We need to calculate how many registers should be consecutive. --- The $sp adjustment rtx, $fp push rtx, $gp push rtx, --- and $lp push rtx are excluded. */ --+ We need to calculate how many registers should be consecutive. --+ The $sp adjustment rtx, $fp push rtx, $gp push rtx, --+ and $lp push rtx are excluded. */ -- -- /* Detect whether we have $fp, $gp, or $lp in the parallel rtx. */ -- save_fp = reg_mentioned_p (gen_rtx_REG (SImode, FP_REGNUM), op); --@@ -238,19 +295,19 @@ nds32_valid_stack_push_pop_p (rtx op, bool push_p) -- first_regno = REGNO (elt_reg); -- -- /* The 'push' operation is a kind of store operation. --- The 'pop' operation is a kind of load operation. --- Pass corresponding false/true as second argument (bool load_p). --- The par_index is supposed to start with index 0. */ --+ The 'pop' operation is a kind of load operation. --+ Pass corresponding false/true as second argument (bool load_p). --+ The par_index is supposed to start with index 0. */ -- if (!nds32_consecutive_registers_load_store_p (op, -- !push_p ? true : false, -- 0, -- first_regno, -- rest_count)) --- return false; --+ return false; -- } -- -- /* 2. Valid $fp/$gp/$lp push/pop operations. --- Remember to set start index for checking them. */ --+ Remember to set start index for checking them. */ -- -- /* The rest_count is the start index for checking $fp/$gp/$lp. */ -- index = rest_count; --@@ -269,9 +326,9 @@ nds32_valid_stack_push_pop_p (rtx op, bool push_p) -- index++; -- -- if (GET_CODE (elt_mem) != MEM --- || GET_CODE (elt_reg) != REG --- || REGNO (elt_reg) != FP_REGNUM) --- return false; --+ || GET_CODE (elt_reg) != REG --+ || REGNO (elt_reg) != FP_REGNUM) --+ return false; -- } -- if (save_gp) -- { --@@ -281,9 +338,9 @@ nds32_valid_stack_push_pop_p (rtx op, bool push_p) -- index++; -- -- if (GET_CODE (elt_mem) != MEM --- || GET_CODE (elt_reg) != REG --- || REGNO (elt_reg) != GP_REGNUM) --- return false; --+ || GET_CODE (elt_reg) != REG --+ || REGNO (elt_reg) != GP_REGNUM) --+ return false; -- } -- if (save_lp) -- { --@@ -293,16 +350,16 @@ nds32_valid_stack_push_pop_p (rtx op, bool push_p) -- index++; -- -- if (GET_CODE (elt_mem) != MEM --- || GET_CODE (elt_reg) != REG --- || REGNO (elt_reg) != LP_REGNUM) --- return false; --+ || GET_CODE (elt_reg) != REG --+ || REGNO (elt_reg) != LP_REGNUM) --+ return false; -- } -- -- /* 3. The last element must be stack adjustment rtx. --- Its form of rtx should be: --- (set (reg:SI SP_REGNUM) --- (plus (reg:SI SP_REGNUM) (const_int X))) --- The X could be positive or negative value. */ --+ Its form of rtx should be: --+ (set (reg:SI SP_REGNUM) --+ (plus (reg:SI SP_REGNUM) (const_int X))) --+ The X could be positive or negative value. */ -- -- /* Pick up the last element. */ -- elt = XVECEXP (op, 0, total_count - 1); --@@ -322,54 +379,57 @@ nds32_valid_stack_push_pop_p (rtx op, bool push_p) -- } -- -- /* Function to check if 'bclr' instruction can be used with IVAL. */ ---int ---nds32_can_use_bclr_p (int ival) --+bool --+nds32_can_use_bclr_p (HOST_WIDE_INT ival) -- { -- int one_bit_count; --+ unsigned HOST_WIDE_INT mask = GET_MODE_MASK (SImode); -- -- /* Calculate the number of 1-bit of (~ival), if there is only one 1-bit, -- it means the original ival has only one 0-bit, -- So it is ok to perform 'bclr' operation. */ -- --- one_bit_count = popcount_hwi ((unsigned HOST_WIDE_INT) (~ival)); --+ one_bit_count = popcount_hwi ((unsigned HOST_WIDE_INT) (~ival) & mask); -- -- /* 'bclr' is a performance extension instruction. */ --- return (TARGET_PERF_EXT && (one_bit_count == 1)); --+ return (TARGET_EXT_PERF && (one_bit_count == 1)); -- } -- -- /* Function to check if 'bset' instruction can be used with IVAL. */ ---int ---nds32_can_use_bset_p (int ival) --+bool --+nds32_can_use_bset_p (HOST_WIDE_INT ival) -- { -- int one_bit_count; --+ unsigned HOST_WIDE_INT mask = GET_MODE_MASK (SImode); -- -- /* Caculate the number of 1-bit of ival, if there is only one 1-bit, -- it is ok to perform 'bset' operation. */ -- --- one_bit_count = popcount_hwi ((unsigned HOST_WIDE_INT) (ival)); --+ one_bit_count = popcount_hwi ((unsigned HOST_WIDE_INT) (ival) & mask); -- -- /* 'bset' is a performance extension instruction. */ --- return (TARGET_PERF_EXT && (one_bit_count == 1)); --+ return (TARGET_EXT_PERF && (one_bit_count == 1)); -- } -- -- /* Function to check if 'btgl' instruction can be used with IVAL. */ ---int ---nds32_can_use_btgl_p (int ival) --+bool --+nds32_can_use_btgl_p (HOST_WIDE_INT ival) -- { -- int one_bit_count; --+ unsigned HOST_WIDE_INT mask = GET_MODE_MASK (SImode); -- -- /* Caculate the number of 1-bit of ival, if there is only one 1-bit, -- it is ok to perform 'btgl' operation. */ -- --- one_bit_count = popcount_hwi ((unsigned HOST_WIDE_INT) (ival)); --+ one_bit_count = popcount_hwi ((unsigned HOST_WIDE_INT) (ival) & mask); -- -- /* 'btgl' is a performance extension instruction. */ --- return (TARGET_PERF_EXT && (one_bit_count == 1)); --+ return (TARGET_EXT_PERF && (one_bit_count == 1)); -- } -- -- /* Function to check if 'bitci' instruction can be used with IVAL. */ ---int ---nds32_can_use_bitci_p (int ival) --+bool --+nds32_can_use_bitci_p (HOST_WIDE_INT ival) -- { -- /* If we are using V3 ISA, we have 'bitci' instruction. -- Try to see if we can present 'andi' semantic with --@@ -381,4 +441,286 @@ nds32_can_use_bitci_p (int ival) -- && satisfies_constraint_Iu15 (gen_int_mode (~ival, SImode))); -- } -- --+/* Return true if is load/store with SYMBOL_REF addressing mode --+ and memory mode is SImode. */ --+bool --+nds32_symbol_load_store_p (rtx_insn *insn) --+{ --+ rtx mem_src = NULL_RTX; --+ --+ switch (get_attr_type (insn)) --+ { --+ case TYPE_LOAD: --+ mem_src = SET_SRC (PATTERN (insn)); --+ break; --+ case TYPE_STORE: --+ mem_src = SET_DEST (PATTERN (insn)); --+ break; --+ default: --+ break; --+ } --+ --+ /* Find load/store insn with addressing mode is SYMBOL_REF. */ --+ if (mem_src != NULL_RTX) --+ { --+ if ((GET_CODE (mem_src) == ZERO_EXTEND) --+ || (GET_CODE (mem_src) == SIGN_EXTEND)) --+ mem_src = XEXP (mem_src, 0); --+ --+ if ((GET_CODE (XEXP (mem_src, 0)) == SYMBOL_REF) --+ || (GET_CODE (XEXP (mem_src, 0)) == LO_SUM)) --+ return true; --+ } --+ --+ return false; --+} --+ --+/* Vaild memory operand for floating-point loads and stores */ --+bool --+nds32_float_mem_operand_p (rtx op) --+{ --+ enum machine_mode mode = GET_MODE (op); --+ rtx addr = XEXP (op, 0); --+ --+ /* Not support [symbol] [const] memory */ --+ if (GET_CODE (addr) == SYMBOL_REF --+ || GET_CODE (addr) == CONST --+ || GET_CODE (addr) == LO_SUM) --+ return false; --+ --+ if (GET_CODE (addr) == PLUS) --+ { --+ if (GET_CODE (XEXP (addr, 0)) == SYMBOL_REF) --+ return false; --+ --+ /* Restrict const range: (imm12s << 2) */ --+ if (GET_CODE (XEXP (addr, 1)) == CONST_INT) --+ { --+ if ((mode == SImode || mode == SFmode) --+ && NDS32_SINGLE_WORD_ALIGN_P (INTVAL (XEXP (addr, 1))) --+ && !satisfies_constraint_Is14 ( XEXP(addr, 1))) --+ return false; --+ --+ if ((mode == DImode || mode == DFmode) --+ && NDS32_DOUBLE_WORD_ALIGN_P (INTVAL (XEXP (addr, 1))) --+ && !satisfies_constraint_Is14 (XEXP (addr, 1))) --+ return false; --+ } --+ } --+ --+ return true; --+} --+ --+int --+nds32_cond_move_p (rtx cmp_rtx) --+{ --+ enum machine_mode cmp0_mode = GET_MODE (XEXP (cmp_rtx, 0)); --+ enum machine_mode cmp1_mode = GET_MODE (XEXP (cmp_rtx, 1)); --+ enum rtx_code cond = GET_CODE (cmp_rtx); --+ --+ if ((cmp0_mode == DFmode || cmp0_mode == SFmode) --+ && (cmp1_mode == DFmode || cmp1_mode == SFmode) --+ && (cond == ORDERED || cond == UNORDERED)) --+ return true; --+ return false; --+} --+ --+/* Return true if the addresses in mem1 and mem2 are suitable for use in --+ an fldi or fsdi instruction. --+ --+ This can only happen when addr1 and addr2, the addresses in mem1 --+ and mem2, are consecutive memory locations (addr1 + 4 == addr2). --+ addr1 must also be aligned on a 64-bit boundary. */ --+bool --+nds32_memory_merge_peep_p (rtx mem1, rtx mem2) --+{ --+ rtx addr1, addr2; --+ unsigned int reg1; --+ HOST_WIDE_INT offset1; --+ --+ /* The mems cannot be volatile. */ --+ if (MEM_VOLATILE_P (mem1) || MEM_VOLATILE_P (mem2)) --+ return false; --+ --+ /* MEM1 should be aligned on a 64-bit boundary. */ --+ if (MEM_ALIGN (mem1) < 64) --+ return false; --+ --+ addr1 = XEXP (mem1, 0); --+ addr2 = XEXP (mem2, 0); --+ --+ /* Extract a register number and offset (if used) from the first addr. */ --+ if (GET_CODE (addr1) == PLUS) --+ { --+ if (GET_CODE (XEXP (addr1, 0)) != REG) --+ return false; --+ else --+ { --+ reg1 = REGNO (XEXP (addr1, 0)); --+ if (GET_CODE (XEXP (addr1, 1)) != CONST_INT) --+ return false; --+ --+ offset1 = INTVAL (XEXP (addr1, 1)); --+ } --+ } --+ else if (GET_CODE (addr1) != REG) --+ return false; --+ else --+ { --+ reg1 = REGNO (addr1); --+ /* This was a simple (mem (reg)) expression. Offset is 0. */ --+ offset1 = 0; --+ } --+ /* Make sure the second address is a (mem (plus (reg) (const_int). */ --+ if (GET_CODE (addr2) != PLUS) --+ return false; --+ --+ if (GET_CODE (XEXP (addr2, 0)) != REG --+ || GET_CODE (XEXP (addr2, 1)) != CONST_INT) --+ return false; --+ --+ if (reg1 != REGNO (XEXP (addr2, 0))) --+ return false; --+ --+ /* The first offset must be evenly divisible by 8 to ensure the --+ address is 64 bit aligned. */ --+ if (offset1 % 8 != 0) --+ return false; --+ --+ /* The offset for the second addr must be 4 more than the first addr. */ --+ if (INTVAL (XEXP (addr2, 1)) != offset1 + 4) --+ return false; --+ --+ return true; --+} --+ --+bool --+nds32_const_double_range_ok_p (rtx op, enum machine_mode mode, --+ HOST_WIDE_INT lower, HOST_WIDE_INT upper) --+{ --+ if (GET_CODE (op) != CONST_DOUBLE --+ || GET_MODE (op) != mode) --+ return false; --+ --+ const REAL_VALUE_TYPE *rv; --+ long val; --+ --+ rv = CONST_DOUBLE_REAL_VALUE (op); --+ REAL_VALUE_TO_TARGET_SINGLE (*rv, val); --+ --+ return val >= lower && val < upper; --+} --+ --+bool --+nds32_const_unspec_p (rtx x) --+{ --+ if (GET_CODE (x) == CONST) --+ { --+ x = XEXP (x, 0); --+ --+ if (GET_CODE (x) == PLUS) --+ x = XEXP (x, 0); --+ --+ if (GET_CODE (x) == UNSPEC) --+ { --+ switch (XINT (x, 1)) --+ { --+ case UNSPEC_GOTINIT: --+ case UNSPEC_GOT: --+ case UNSPEC_GOTOFF: --+ case UNSPEC_PLT: --+ case UNSPEC_TLSGD: --+ case UNSPEC_TLSLD: --+ case UNSPEC_TLSIE: --+ case UNSPEC_TLSLE: --+ return false; --+ default: --+ return true; --+ } --+ } --+ } --+ --+ if (GET_CODE (x) == SYMBOL_REF --+ && SYMBOL_REF_TLS_MODEL (x)) --+ return false; --+ --+ return true; --+} --+ --+HOST_WIDE_INT --+const_vector_to_hwint (rtx op) --+{ --+ HOST_WIDE_INT hwint = 0; --+ HOST_WIDE_INT mask; --+ int i; --+ int shift_adv; --+ int shift = 0; --+ int nelem; --+ --+ switch (GET_MODE (op)) --+ { --+ case V2HImode: --+ mask = 0xffff; --+ shift_adv = 16; --+ nelem = 2; --+ break; --+ case V4QImode: --+ mask = 0xff; --+ shift_adv = 8; --+ nelem = 4; --+ break; --+ default: --+ gcc_unreachable (); --+ } --+ --+ if (TARGET_BIG_ENDIAN) --+ { --+ for (i = 0; i < nelem; ++i) --+ { --+ HOST_WIDE_INT val = XINT (XVECEXP (op, 0, nelem - i - 1), 0); --+ hwint |= (val & mask) << shift; --+ shift = shift + shift_adv; --+ } --+ } --+ else --+ { --+ for (i = 0; i < nelem; ++i) --+ { --+ HOST_WIDE_INT val = XINT (XVECEXP (op, 0, i), 0); --+ hwint |= (val & mask) << shift; --+ shift = shift + shift_adv; --+ } --+ } --+ --+ return hwint; --+} --+ --+bool --+nds32_valid_CVp5_p (rtx op) --+{ --+ HOST_WIDE_INT ival = const_vector_to_hwint (op); --+ return (ival < ((1 << 5) + 16)) && (ival >= (0 + 16)); --+} --+ --+bool --+nds32_valid_CVs5_p (rtx op) --+{ --+ HOST_WIDE_INT ival = const_vector_to_hwint (op); --+ return (ival < (1 << 4)) && (ival >= -(1 << 4)); --+} --+ --+bool --+nds32_valid_CVs2_p (rtx op) --+{ --+ HOST_WIDE_INT ival = const_vector_to_hwint (op); --+ return (ival < (1 << 19)) && (ival >= -(1 << 19)); --+} --+ --+bool --+nds32_valid_CVhi_p (rtx op) --+{ --+ HOST_WIDE_INT ival = const_vector_to_hwint (op); --+ return (ival != 0) && ((ival & 0xfff) == 0); --+} --+ -- /* ------------------------------------------------------------------------ */ --diff --git a/gcc/config/nds32/nds32-protos.h b/gcc/config/nds32/nds32-protos.h --index d66749d..19e69e3 100644 ----- a/gcc/config/nds32/nds32-protos.h --+++ b/gcc/config/nds32/nds32-protos.h --@@ -28,10 +28,14 @@ extern void nds32_init_expanders (void); -- -- /* Register Usage. */ -- --+/* -- Order of Allocation of Registers. */ --+extern void nds32_adjust_reg_alloc_order (void); --+ -- /* -- How Values Fit in Registers. */ -- ---extern int nds32_hard_regno_nregs (int, machine_mode); ---extern int nds32_hard_regno_mode_ok (int, machine_mode); --+extern int nds32_hard_regno_nregs (int, enum machine_mode); --+extern int nds32_hard_regno_mode_ok (int, enum machine_mode); --+extern int nds32_modes_tieable_p (enum machine_mode, enum machine_mode); -- -- -- /* Register Classes. */ --@@ -43,6 +47,7 @@ extern enum reg_class nds32_regno_reg_class (int); -- -- /* -- Basic Stack Layout. */ -- --+extern rtx nds32_dynamic_chain_address (rtx); -- extern rtx nds32_return_addr_rtx (int, rtx); -- -- /* -- Eliminating Frame Pointer and Arg Pointer. */ --@@ -61,22 +66,88 @@ extern void nds32_expand_prologue (void); -- extern void nds32_expand_epilogue (bool); -- extern void nds32_expand_prologue_v3push (void); -- extern void nds32_expand_epilogue_v3pop (bool); --+extern void nds32_emit_push_fpr_callee_saved (int); --+extern void nds32_emit_pop_fpr_callee_saved (int); --+extern void nds32_emit_v3pop_fpr_callee_saved (int); --+ --+/* Controlling Debugging Information Format. */ --+ --+extern unsigned int nds32_dbx_register_number (unsigned int); -- -- /* ------------------------------------------------------------------------ */ -- ---/* Auxiliary functions for auxiliary macros in nds32.h. */ --+/* Auxiliary functions for manipulation DI mode. */ -- ---extern bool nds32_ls_333_p (rtx, rtx, rtx, machine_mode); --+extern rtx nds32_di_high_part_subreg(rtx); --+extern rtx nds32_di_low_part_subreg(rtx); -- -- /* Auxiliary functions for expanding rtl used in nds32-multiple.md. */ -- ---extern rtx nds32_expand_load_multiple (int, int, rtx, rtx); ---extern rtx nds32_expand_store_multiple (int, int, rtx, rtx); ---extern int nds32_expand_movmemqi (rtx, rtx, rtx, rtx); --+extern rtx nds32_expand_load_multiple (int, int, rtx, rtx, bool, rtx *); --+extern rtx nds32_expand_store_multiple (int, int, rtx, rtx, bool, rtx *); --+extern bool nds32_expand_movmemsi (rtx, rtx, rtx, rtx); --+extern bool nds32_expand_setmem (rtx, rtx, rtx, rtx, rtx, rtx); --+extern bool nds32_expand_movstr (rtx, rtx, rtx); --+extern bool nds32_expand_strlen (rtx, rtx, rtx, rtx); -- -- /* Auxiliary functions for multiple load/store predicate checking. */ -- ---extern bool nds32_valid_multiple_load_store (rtx, bool); --+extern bool nds32_valid_multiple_load_store_p (rtx, bool, bool); --+ --+/* Auxiliary functions for guard function checking in pipelines.md. */ --+ --+extern bool nds32_n7_load_to_ii_p (rtx_insn *, rtx_insn *); --+extern bool nds32_n7_last_load_to_ii_p (rtx_insn *, rtx_insn *); --+ --+extern bool nds32_n8_load_to_ii_p (rtx_insn *, rtx_insn *); --+extern bool nds32_n8_load_bi_to_ii_p (rtx_insn *, rtx_insn *); --+extern bool nds32_n8_load_to_ex_p (rtx_insn *, rtx_insn *); --+extern bool nds32_n8_ex_to_ii_p (rtx_insn *, rtx_insn *); --+extern bool nds32_n8_last_load_to_ii_p (rtx_insn *, rtx_insn *); --+extern bool nds32_n8_last_load_two_to_ii_p (rtx_insn *, rtx_insn *); --+extern bool nds32_n8_last_load_to_ex_p (rtx_insn *, rtx_insn *); --+ --+extern bool nds32_e8_load_to_ii_p (rtx_insn *, rtx_insn *); --+extern bool nds32_e8_load_to_ex_p (rtx_insn *, rtx_insn *); --+extern bool nds32_e8_ex_to_ii_p (rtx_insn *, rtx_insn *); --+extern bool nds32_e8_last_load_to_ii_p (rtx_insn *, rtx_insn *); --+extern bool nds32_e8_last_load_to_ex_p (rtx_insn *, rtx_insn *); --+ --+extern bool nds32_n9_2r1w_mm_to_ex_p (rtx_insn *, rtx_insn *); --+extern bool nds32_n9_3r2w_mm_to_ex_p (rtx_insn *, rtx_insn *); --+extern bool nds32_n9_last_load_to_ex_p (rtx_insn *, rtx_insn *); --+ --+extern bool nds32_n10_ex_to_ex_p (rtx_insn *, rtx_insn *); --+extern bool nds32_n10_mm_to_ex_p (rtx_insn *, rtx_insn *); --+extern bool nds32_n10_last_load_to_ex_p (rtx_insn *, rtx_insn *); --+ --+extern bool nds32_gw_ex_to_ex_p (rtx_insn *, rtx_insn *); --+extern bool nds32_gw_mm_to_ex_p (rtx_insn *, rtx_insn *); --+extern bool nds32_gw_last_load_to_ex_p (rtx_insn *, rtx_insn *); --+ --+extern bool nds32_n13_e2_to_e1_p (rtx_insn *, rtx_insn *); --+extern bool nds32_n13_load_to_e1_p (rtx_insn *, rtx_insn *); --+extern bool nds32_n13_load_to_e2_p (rtx_insn *, rtx_insn *); --+extern bool nds32_n13_last_load_to_e1_p (rtx_insn *, rtx_insn *); --+extern bool nds32_n13_last_load_to_e2_p (rtx_insn *, rtx_insn *); --+extern bool nds32_n13_last_two_load_to_e1_p (rtx_insn *, rtx_insn *); --+ --+extern bool nds32_pn_e2_to_e1_p (rtx_insn *, rtx_insn *); --+extern bool nds32_pn_e3_to_e1_p (rtx_insn *, rtx_insn *); --+extern bool nds32_pn_e3_to_e2_p (rtx_insn *, rtx_insn *); --+extern bool nds32_pn_e4_to_e1_p (rtx_insn *, rtx_insn *); --+extern bool nds32_pn_e4_to_e2_p (rtx_insn *, rtx_insn *); --+extern bool nds32_pn_e4_to_e3_p (rtx_insn *, rtx_insn *); --+extern bool nds32_pn_wb_to_e1_p (rtx_insn *, rtx_insn *); --+extern bool nds32_pn_wb_to_e2_p (rtx_insn *, rtx_insn *); --+extern bool nds32_pn_wb_to_e3_p (rtx_insn *, rtx_insn *); --+extern bool nds32_pn_wb_to_e4_p (rtx_insn *, rtx_insn *); --+extern bool nds32_pn_last_load_to_e1_p (rtx_insn *, rtx_insn *); --+extern bool nds32_pn_last_load_to_e2_p (rtx_insn *, rtx_insn *); --+extern bool nds32_pn_last_load_to_e3_p (rtx_insn *, rtx_insn *); --+extern bool nds32_pn_last_two_load_to_e1_p (rtx_insn *, rtx_insn *); --+extern bool nds32_pn_last_two_load_to_e2_p (rtx_insn *, rtx_insn *); --+extern bool nds32_pn_last_three_load_to_e1_p (rtx_insn *, rtx_insn *); -- -- /* Auxiliary functions for stack operation predicate checking. */ -- --@@ -84,55 +155,176 @@ extern bool nds32_valid_stack_push_pop_p (rtx, bool); -- -- /* Auxiliary functions for bit operation detection. */ -- ---extern int nds32_can_use_bclr_p (int); ---extern int nds32_can_use_bset_p (int); ---extern int nds32_can_use_btgl_p (int); --+extern bool nds32_can_use_bclr_p (HOST_WIDE_INT); --+extern bool nds32_can_use_bset_p (HOST_WIDE_INT); --+extern bool nds32_can_use_btgl_p (HOST_WIDE_INT); -- ---extern int nds32_can_use_bitci_p (int); --+extern bool nds32_can_use_bitci_p (HOST_WIDE_INT); -- ---/* Auxiliary function for 'Computing the Length of an Insn'. */ --+extern bool nds32_const_double_range_ok_p (rtx, enum machine_mode, --+ HOST_WIDE_INT, HOST_WIDE_INT); -- ---extern int nds32_adjust_insn_length (rtx_insn *, int); --+extern bool nds32_const_unspec_p (rtx x); -- -- /* Auxiliary functions for FP_AS_GP detection. */ -- ---extern int nds32_fp_as_gp_check_available (void); --+extern bool nds32_symbol_load_store_p (rtx_insn *); --+extern bool nds32_naked_function_p (tree); -- -- /* Auxiliary functions for jump table generation. */ -- -- extern const char *nds32_output_casesi_pc_relative (rtx *); -- extern const char *nds32_output_casesi (rtx *); -- --+/* Auxiliary functions for conditional branch generation. */ --+ --+extern enum nds32_expand_result_type nds32_expand_cbranch (rtx *); --+extern enum nds32_expand_result_type nds32_expand_cstore (rtx *); --+extern void nds32_expand_float_cbranch (rtx *); --+extern void nds32_expand_float_cstore (rtx *); --+ --+/* Auxiliary functions for conditional move generation. */ --+ --+extern enum nds32_expand_result_type nds32_expand_movcc (rtx *); --+extern void nds32_expand_float_movcc (rtx *); --+ --+/* Auxiliary functions for expand unalign load instruction. */ --+ --+extern void nds32_expand_unaligned_load (rtx *, enum machine_mode); --+ --+/* Auxiliary functions for expand extv/insv instruction. */ --+ --+extern enum nds32_expand_result_type nds32_expand_extv (rtx *); --+extern enum nds32_expand_result_type nds32_expand_insv (rtx *); --+ --+/* Auxiliary functions for expand unalign store instruction. */ --+ --+extern void nds32_expand_unaligned_store (rtx *, enum machine_mode); --+ --+/* Auxiliary functions for expand PIC instruction. */ --+ --+extern void nds32_expand_pic_move (rtx *); --+ --+/* Auxiliary functions to legitimize PIC address. */ --+ --+extern rtx nds32_legitimize_pic_address (rtx); --+ --+/* Auxiliary functions for expand TLS instruction. */ --+ --+extern void nds32_expand_tls_move (rtx *); --+ --+/* Auxiliary functions to legitimize TLS address. */ --+ --+extern rtx nds32_legitimize_tls_address (rtx); --+ --+/* Auxiliary functions to identify thread-local symbol. */ --+ --+extern bool nds32_tls_referenced_p (rtx); --+ --+/* Auxiliary functions for expand ICT instruction. */ --+ --+extern void nds32_expand_ict_move (rtx *); --+ --+/* Auxiliary functions to legitimize address for indirect-call symbol. */ --+ --+extern rtx nds32_legitimize_ict_address (rtx); --+ --+/* Auxiliary functions to identify indirect-call symbol. */ --+ --+extern bool nds32_indirect_call_referenced_p (rtx); --+ --+/* Auxiliary functions to identify long-call symbol. */ --+extern bool nds32_long_call_p (rtx); --+ --+/* Auxiliary functions to identify SYMBOL_REF and LABEL_REF pattern. */ --+ --+extern bool symbolic_reference_mentioned_p (rtx); --+ --+/* Auxiliary functions to identify conditional move comparison operand. */ --+ --+extern int nds32_cond_move_p (rtx); --+ --+/* Auxiliary functions to identify address for peephole2 merge instruction. */ --+ --+extern bool nds32_memory_merge_peep_p (rtx, rtx); --+ -- /* Auxiliary functions to identify 16 bit addresing mode. */ -- -- extern enum nds32_16bit_address_type nds32_mem_format (rtx); -- --+/* Auxiliary functions to identify floating-point addresing mode. */ --+ --+extern bool nds32_float_mem_operand_p (rtx); --+ -- /* Auxiliary functions to output assembly code. */ -- -- extern const char *nds32_output_16bit_store (rtx *, int); -- extern const char *nds32_output_16bit_load (rtx *, int); -- extern const char *nds32_output_32bit_store (rtx *, int); -- extern const char *nds32_output_32bit_load (rtx *, int); ---extern const char *nds32_output_32bit_load_s (rtx *, int); --+extern const char *nds32_output_32bit_load_se (rtx *, int); --+extern const char *nds32_output_float_load(rtx *); --+extern const char *nds32_output_float_store(rtx *); --+extern const char *nds32_output_smw_single_word (rtx *); --+extern const char *nds32_output_smw_double_word (rtx *); --+extern const char *nds32_output_lmw_single_word (rtx *); --+extern const char *nds32_output_double (rtx *, bool); --+extern const char *nds32_output_cbranchsi4_equality_zero (rtx_insn *, rtx *); --+extern const char *nds32_output_cbranchsi4_equality_reg (rtx_insn *, rtx *); --+extern const char *nds32_output_cbranchsi4_equality_reg_or_const_int (rtx_insn *, --+ rtx *); --+extern const char *nds32_output_cbranchsi4_greater_less_zero (rtx_insn *, rtx *); --+ --+extern const char *nds32_output_unpkd8 (rtx, rtx, rtx, rtx, bool); --+ --+extern const char *nds32_output_call (rtx, rtx *, rtx, --+ const char *, const char *, bool); --+extern const char *nds32_output_tls_desc (rtx *); --+extern const char *nds32_output_tls_ie (rtx *); -- -- /* Auxiliary functions to output stack push/pop instruction. */ -- -- extern const char *nds32_output_stack_push (rtx); -- extern const char *nds32_output_stack_pop (rtx); --+extern const char *nds32_output_return (void); --+ --+ --+/* Auxiliary functions to split/output sms pattern. */ --+extern bool nds32_need_split_sms_p (rtx, rtx, rtx, rtx); --+extern const char *nds32_output_sms (rtx, rtx, rtx, rtx); --+extern void nds32_split_sms (rtx, rtx, rtx, rtx, rtx, rtx, rtx); --+ --+/* Auxiliary functions to split double word RTX pattern. */ --+ --+extern void nds32_spilt_doubleword (rtx *, bool); --+extern void nds32_split_ashiftdi3 (rtx, rtx, rtx); --+extern void nds32_split_ashiftrtdi3 (rtx, rtx, rtx); --+extern void nds32_split_lshiftrtdi3 (rtx, rtx, rtx); --+extern void nds32_split_rotatertdi3 (rtx, rtx, rtx); --+ --+/* Auxiliary functions to split large constant RTX pattern. */ --+ --+extern void nds32_expand_constant (enum machine_mode, --+ HOST_WIDE_INT, rtx, rtx); -- -- /* Auxiliary functions to check using return with null epilogue. */ -- -- extern int nds32_can_use_return_insn (void); --+extern enum machine_mode nds32_case_vector_shorten_mode (int, int, rtx); -- -- /* Auxiliary functions to decide output alignment or not. */ -- -- extern int nds32_target_alignment (rtx); --+extern unsigned int nds32_data_alignment (tree, unsigned int); --+extern unsigned int nds32_constant_alignment (tree, unsigned int); --+extern unsigned int nds32_local_alignment (tree, unsigned int); -- -- /* Auxiliary functions to expand builtin functions. */ -- -- extern void nds32_init_builtins_impl (void); -- extern rtx nds32_expand_builtin_impl (tree, rtx, rtx, --- machine_mode, int); --+ enum machine_mode, int); --+extern tree nds32_builtin_decl_impl (unsigned, bool); -- -- /* Auxiliary functions for ISR implementation. */ -- --@@ -141,10 +333,86 @@ extern void nds32_construct_isr_vectors_information (tree, const char *); -- extern void nds32_asm_file_start_for_isr (void); -- extern void nds32_asm_file_end_for_isr (void); -- extern bool nds32_isr_function_p (tree); --+extern bool nds32_isr_function_critical_p (tree); -- -- /* Auxiliary functions for cost calculation. */ -- --+extern void nds32_init_rtx_costs (void); -- extern bool nds32_rtx_costs_impl (rtx, machine_mode, int, int, int *, bool); ---extern int nds32_address_cost_impl (rtx, machine_mode, addr_space_t, bool); --+extern int nds32_address_cost_impl (rtx, enum machine_mode, addr_space_t, bool); --+extern struct register_pass_info insert_pass_fp_as_gp; --+ --+extern int nds32_adjust_insn_length (rtx_insn *, int); --+ --+/* Auxiliary functions for pre-define marco. */ --+extern void nds32_cpu_cpp_builtins(struct cpp_reader *); --+ --+/* Auxiliary functions for const_vector's constraints. */ --+ --+extern HOST_WIDE_INT const_vector_to_hwint (rtx); --+extern bool nds32_valid_CVp5_p (rtx); --+extern bool nds32_valid_CVs5_p (rtx); --+extern bool nds32_valid_CVs2_p (rtx); --+extern bool nds32_valid_CVhi_p (rtx); --+ --+/* Auxiliary functions for lwm/smw. */ --+ --+extern bool nds32_valid_smw_lwm_base_p (rtx); --+ --+/* Auxiliary functions for register rename pass. */ --+extern reg_class_t nds32_preferred_rename_class_impl (reg_class_t); --+ --+extern bool nds32_split_double_word_load_store_p (rtx *,bool); --+ --+namespace nds32 { --+ --+extern rtx extract_pattern_from_insn (rtx); --+ --+size_t parallel_elements (rtx); --+rtx parallel_element (rtx, int); --+ --+bool insn_pseudo_nop_p (rtx_insn *); --+bool insn_executable_p (rtx_insn *); --+rtx_insn *prev_executable_insn (rtx_insn *); --+rtx_insn *next_executable_insn (rtx_insn *); --+rtx_insn *prev_executable_insn_local (rtx_insn *); --+rtx_insn *next_executable_insn_local (rtx_insn *); --+bool insn_deleted_p (rtx_insn *); --+ --+bool load_single_p (rtx_insn *); --+bool store_single_p (rtx_insn *); --+bool load_double_p (rtx_insn *); --+bool store_double_p (rtx_insn *); --+bool store_offset_reg_p (rtx_insn *); --+bool load_full_word_p (rtx_insn *); --+bool load_partial_word_p (rtx_insn *); --+bool post_update_insn_p (rtx_insn *); --+bool immed_offset_p (rtx); --+int find_post_update_rtx (rtx_insn *); --+rtx extract_mem_rtx (rtx_insn *); --+rtx extract_base_reg (rtx_insn *); --+rtx extract_offset_rtx (rtx_insn *); --+ --+rtx extract_shift_reg (rtx_insn *); --+ --+bool movd44_insn_p (rtx_insn *); --+rtx extract_movd44_even_reg (rtx_insn *); --+rtx extract_movd44_odd_reg (rtx_insn *); --+ --+rtx extract_mac_acc_rtx (rtx_insn *); --+rtx extract_mac_non_acc_rtx (rtx_insn *); --+ --+bool divmod_p (rtx_insn *); --+ --+rtx extract_branch_target_rtx (rtx_insn *); --+rtx extract_branch_condition_rtx (rtx_insn *); --+ --+void compute_bb_for_insn_safe (); --+ --+void exchange_insns (rtx_insn *, rtx_insn *); --+ --+} // namespace nds32 --+ --+extern bool nds32_include_fp_arith; -- -- /* ------------------------------------------------------------------------ */ --diff --git a/gcc/config/nds32/nds32-reg-utils.c b/gcc/config/nds32/nds32-reg-utils.c --new file mode 100644 --index 0000000..1fd8a83 ----- /dev/null --+++ b/gcc/config/nds32/nds32-reg-utils.c --@@ -0,0 +1,190 @@ --+ --+/* lmwsmw pass of Andes NDS32 cpu for GNU compiler --+ Copyright (C) 2012-2016 Free Software Foundation, Inc. --+ Contributed by Andes Technology Corporation. --+ --+ This file is part of GCC. --+ --+ GCC is free software; you can redistribute it and/or modify it --+ under the terms of the GNU General Public License as published --+ by the Free Software Foundation; either version 3, or (at your --+ option) any later version. --+ --+ GCC is distributed in the hope that it will be useful, but WITHOUT --+ ANY WARRANTY; without even the implied warranty of MERCHANTABILITY --+ or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public --+ License for more details. --+ --+ You should have received a copy of the GNU General Public License --+ along with GCC; see the file COPYING3. If not see --+ . */ --+ --+/* ------------------------------------------------------------------------ */ --+#include "config.h" --+#include "system.h" --+#include "coretypes.h" --+#include "tm.h" --+#include "hash-set.h" --+#include "machmode.h" --+#include "vec.h" --+#include "double-int.h" --+#include "input.h" --+#include "alias.h" --+#include "symtab.h" --+#include "wide-int.h" --+#include "inchash.h" --+#include "tree.h" --+#include "stor-layout.h" --+#include "varasm.h" --+#include "calls.h" --+#include "rtl.h" --+#include "regs.h" --+#include "hard-reg-set.h" --+#include "insn-config.h" /* Required by recog.h. */ --+#include "conditions.h" --+#include "output.h" --+#include "insn-attr.h" /* For DFA state_t. */ --+#include "insn-codes.h" /* For CODE_FOR_xxx. */ --+#include "reload.h" /* For push_reload(). */ --+#include "flags.h" --+#include "input.h" --+#include "function.h" --+#include "expr.h" --+#include "recog.h" --+#include "diagnostic-core.h" --+#include "dominance.h" --+#include "cfg.h" --+#include "cfgrtl.h" --+#include "cfganal.h" --+#include "lcm.h" --+#include "cfgbuild.h" --+#include "cfgcleanup.h" --+#include "predict.h" --+#include "basic-block.h" --+#include "bitmap.h" --+#include "df.h" --+#include "tm_p.h" --+#include "tm-constrs.h" --+#include "optabs.h" /* For GEN_FCN. */ --+#include "target.h" --+#include "langhooks.h" /* For add_builtin_function(). */ --+#include "ggc.h" --+#include "tree-pass.h" --+#include "target-globals.h" --+#include "ira.h" --+#include "ira-int.h" --+#include "nds32-reg-utils.h" --+ --+#define NDS32_GPR_NUM 32 --+ --+static bool debug_live_reg = false; --+ --+void --+nds32_live_regs (basic_block bb, rtx_insn *first, rtx_insn *last, bitmap *live) --+{ --+ df_ref def; --+ rtx_insn *insn; --+ bitmap_copy (*live, DF_LR_IN (bb)); --+ df_simulate_initialize_forwards (bb, *live); --+ rtx_insn *first_insn = BB_HEAD (bb); --+ --+ for (insn = first_insn; insn != first; insn = NEXT_INSN (insn)) --+ df_simulate_one_insn_forwards (bb, insn, *live); --+ --+ if (dump_file && debug_live_reg) --+ { --+ fprintf (dump_file, "scan live regs:\nfrom:\n"); --+ print_rtl_single (dump_file, first); --+ --+ fprintf (dump_file, "to:\n"); --+ print_rtl_single (dump_file, last); --+ --+ fprintf (dump_file, "bb lr in:\n"); --+ dump_bitmap (dump_file, DF_LR_IN (bb)); --+ --+ fprintf (dump_file, "init:\n"); --+ dump_bitmap (dump_file, *live); --+ } --+ --+ for (insn = first; insn != last; insn = NEXT_INSN (insn)) --+ { --+ if (!INSN_P (insn)) --+ continue; --+ --+ FOR_EACH_INSN_DEF (def, insn) --+ bitmap_set_bit (*live, DF_REF_REGNO (def)); --+ --+ if (dump_file && debug_live_reg) --+ { --+ fprintf (dump_file, "scaning:\n"); --+ print_rtl_single (dump_file, insn); --+ dump_bitmap (dump_file, *live); --+ } --+ } --+ --+ gcc_assert (INSN_P (insn)); --+ --+ FOR_EACH_INSN_DEF (def, insn) --+ bitmap_set_bit (*live, DF_REF_REGNO (def)); --+ --+ if (dump_file && debug_live_reg) --+ { --+ fprintf (dump_file, "scaning:\n"); --+ print_rtl_single (dump_file, last); --+ dump_bitmap (dump_file, *live); --+ } --+} --+ --+void --+print_hard_reg_set (FILE *file, const char *prefix, HARD_REG_SET set) --+{ --+ int i; --+ bool first = true; --+ fprintf (file, "%s{ ", prefix); --+ --+ for (i = 0; i < FIRST_PSEUDO_REGISTER; i++) --+ { --+ if (TEST_HARD_REG_BIT (set, i)) --+ { --+ if (first) --+ { --+ fprintf (file, "%s", reg_names[i]); --+ first = false; --+ } --+ else --+ fprintf (file, ", %s", reg_names[i]); --+ } --+ } --+ fprintf (file, "}\n"); --+} --+ --+void --+nds32_get_available_reg_set (basic_block bb, --+ rtx_insn *first, --+ rtx_insn *last, --+ HARD_REG_SET *available_regset) --+{ --+ bitmap live; --+ HARD_REG_SET live_regset; --+ unsigned i; --+ live = BITMAP_ALLOC (®_obstack); --+ --+ nds32_live_regs (bb, first, last, &live); --+ --+ REG_SET_TO_HARD_REG_SET (live_regset, live); --+ --+ /* Reverse available_regset. */ --+ COMPL_HARD_REG_SET (*available_regset, live_regset); --+ --+ /* We only care $r0-$r31, so mask $r0-$r31. */ --+ AND_HARD_REG_SET (*available_regset, reg_class_contents[GENERAL_REGS]); --+ --+ /* Fixed register also not available. */ --+ for (i = NDS32_FIRST_GPR_REGNUM; i <= NDS32_LAST_GPR_REGNUM; ++i) --+ { --+ if (fixed_regs[i]) --+ CLEAR_HARD_REG_BIT (*available_regset, i); --+ } --+ --+ BITMAP_FREE (live); --+} --diff --git a/gcc/config/nds32/nds32-reg-utils.h b/gcc/config/nds32/nds32-reg-utils.h --new file mode 100644 --index 0000000..16c23a3 ----- /dev/null --+++ b/gcc/config/nds32/nds32-reg-utils.h --@@ -0,0 +1,61 @@ --+/* Prototypes for load-store-opt of Andes NDS32 cpu for GNU compiler --+ Copyright (C) 2012-2016 Free Software Foundation, Inc. --+ Contributed by Andes Technology Corporation. --+ --+ This file is part of GCC. --+ --+ GCC is free software; you can redistribute it and/or modify it --+ under the terms of the GNU General Public License as published --+ by the Free Software Foundation; either version 3, or (at your --+ option) any later version. --+ --+ GCC is distributed in the hope that it will be useful, but WITHOUT --+ ANY WARRANTY; without even the implied warranty of MERCHANTABILITY --+ or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public --+ License for more details. --+ --+ You should have received a copy of the GNU General Public License --+ along with GCC; see the file COPYING3. If not see --+ . */ --+ --+#ifndef NDS32_REG_UTILS_OPT_H --+#define NDS32_REG_UTILS_OPT_H --+ --+/* Auxiliary functions for register usage analysis. */ --+extern void nds32_live_regs (basic_block, rtx_insn *, rtx_insn *, bitmap *); --+extern void print_hard_reg_set (FILE *, const char *, HARD_REG_SET); --+extern void nds32_get_available_reg_set (basic_block, rtx_insn *, --+ rtx_insn *, HARD_REG_SET *); --+ --+static inline bool --+in_reg_class_p (unsigned regno, enum reg_class clazz) --+{ --+ return TEST_HARD_REG_BIT (reg_class_contents[clazz], regno); --+} --+ --+static inline bool --+in_reg_class_p (rtx reg, enum reg_class clazz) --+{ --+ gcc_assert (REG_P (reg)); --+ return in_reg_class_p (REGNO (reg), clazz); --+} --+ --+static inline unsigned --+find_available_reg (HARD_REG_SET *available_regset, enum reg_class clazz) --+{ --+ hard_reg_set_iterator hrsi; --+ unsigned regno; --+ EXECUTE_IF_SET_IN_HARD_REG_SET (reg_class_contents[clazz], 0, regno, hrsi) --+ { --+ /* Caller-save register or callee-save register but it's ever live. */ --+ if (TEST_HARD_REG_BIT (*available_regset, regno) --+ && (call_used_regs[regno] || df_regs_ever_live_p (regno))) --+ return regno; --+ } --+ --+ return INVALID_REGNUM; --+} --+ --+ --+ --+#endif --diff --git a/gcc/config/nds32/nds32-regrename.c b/gcc/config/nds32/nds32-regrename.c --new file mode 100644 --index 0000000..0875722 ----- /dev/null --+++ b/gcc/config/nds32/nds32-regrename.c --@@ -0,0 +1,389 @@ --+/* Register rename pass of Andes NDS32 cpu for GNU compiler --+ Copyright (C) 2012-2016 Free Software Foundation, Inc. --+ Contributed by Andes Technology Corporation. --+ --+ This file is part of GCC. --+ --+ GCC is free software; you can redistribute it and/or modify it --+ under the terms of the GNU General Public License as published --+ by the Free Software Foundation; either version 3, or (at your --+ option) any later version. --+ --+ GCC is distributed in the hope that it will be useful, but WITHOUT --+ ANY WARRANTY; without even the implied warranty of MERCHANTABILITY --+ or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public --+ License for more details. --+ --+ You should have received a copy of the GNU General Public License --+ along with GCC; see the file COPYING3. If not see --+ . */ --+ --+ --+#include "config.h" --+#include "system.h" --+#include "coretypes.h" --+#include "backend.h" --+#include "tree.h" --+#include "rtl.h" --+#include "df.h" --+#include "alias.h" --+#include "stor-layout.h" --+#include "varasm.h" --+#include "calls.h" --+#include "regs.h" --+#include "insn-config.h" /* Required by recog.h. */ --+#include "conditions.h" --+#include "output.h" --+#include "insn-attr.h" /* For DFA state_t. */ --+#include "insn-codes.h" /* For CODE_FOR_xxx. */ --+#include "reload.h" /* For push_reload(). */ --+#include "flags.h" --+#include "insn-config.h" --+#include "expmed.h" --+#include "dojump.h" --+#include "explow.h" --+#include "emit-rtl.h" --+#include "stmt.h" --+#include "expr.h" --+#include "recog.h" --+#include "diagnostic-core.h" --+#include "cfgrtl.h" --+#include "cfganal.h" --+#include "lcm.h" --+#include "cfgbuild.h" --+#include "cfgcleanup.h" --+#include "tm_p.h" --+#include "tm-constrs.h" --+#include "optabs.h" /* For GEN_FCN. */ --+#include "target.h" --+#include "langhooks.h" /* For add_builtin_function(). */ --+#include "builtins.h" --+#include "cpplib.h" --+#include "params.h" --+#include "tree-pass.h" --+#include "regrename.h" --+ --+static reg_class_t current_preferred_rename_class = NO_REGS; --+ --+reg_class_t --+nds32_preferred_rename_class_impl (reg_class_t rclass) --+{ --+ if (rclass == GENERAL_REGS) --+ return current_preferred_rename_class; --+ else --+ return NO_REGS; --+} --+ --+static void --+print_hard_reg_set (FILE *file, HARD_REG_SET set) --+{ --+ int i; --+ --+ fprintf (file, "{ "); --+ for (i = 0; i < FIRST_PSEUDO_REGISTER; i++) --+ { --+ if (TEST_HARD_REG_BIT (set, i)) --+ fprintf (file, "%d ", i); --+ } --+ fprintf (file, "}\n"); --+} --+ --+void --+dump_hard_reg_set (FILE *file, HARD_REG_SET set) --+{ --+ print_hard_reg_set (file, set); --+} --+ --+static bool --+in_reg_class_p (unsigned regno, enum reg_class clazz) --+{ --+ return TEST_HARD_REG_BIT (reg_class_contents[clazz], regno); --+} --+ --+static unsigned --+try_find_best_rename_reg (du_head_p op_chain, reg_class_t preferred_class) --+{ --+ HARD_REG_SET unavailable; --+ unsigned new_reg; --+ current_preferred_rename_class = preferred_class; --+ --+ COMPL_HARD_REG_SET (unavailable, reg_class_contents[preferred_class]); --+ CLEAR_HARD_REG_BIT (unavailable, op_chain->regno); --+ --+ new_reg = find_rename_reg (op_chain, GENERAL_REGS, --+ &unavailable, op_chain->regno, false); --+ --+ current_preferred_rename_class = NO_REGS; --+ return new_reg; --+} --+ --+static bool --+try_rename_operand_to (rtx insn, unsigned op_pos, --+ reg_class_t preferred_rename_class) --+{ --+ insn_rr_info *info; --+ du_head_p op_chain; --+ unsigned newreg; --+ unsigned oldreg; --+ --+ info = &insn_rr[INSN_UID (insn)]; --+ --+ if (info->op_info == NULL) --+ return false; --+ --+ if (info->op_info[op_pos].n_chains == 0) --+ return false; --+ --+ op_chain = regrename_chain_from_id (info->op_info[op_pos].heads[0]->id); --+ --+ if (op_chain->cannot_rename) --+ return false; --+ --+ /* Already use preferred class, so do nothing. */ --+ if (TEST_HARD_REG_BIT (reg_class_contents[preferred_rename_class], --+ op_chain->regno)) --+ return false; --+ --+ if (dump_file) --+ { --+ fprintf (dump_file, "Try to rename operand %d to %s:\n", --+ op_pos, reg_class_names[preferred_rename_class]); --+ print_rtl_single (dump_file, insn); --+ } --+ --+ oldreg = op_chain->regno; --+ newreg = try_find_best_rename_reg (op_chain, preferred_rename_class); --+ --+ if (newreg == oldreg) --+ return false; --+ --+ regrename_do_replace (op_chain, newreg); --+ --+ if (dump_file) --+ { --+ fprintf (dump_file, "Rename operand %d to %s is Done:\n", --+ op_pos, reg_class_names[preferred_rename_class]); --+ print_rtl_single (dump_file, insn); --+ } --+ return true; --+} --+ --+static bool --+rename_slt_profitlable (rtx insn) --+{ --+ rtx pattern; --+ pattern = PATTERN (insn); --+ rtx src = SET_SRC (pattern); --+ rtx op0 = XEXP (src, 0); --+ rtx op1 = XEXP (src, 0); --+ --+ insn_rr_info *info; --+ du_head_p op_chain; --+ int op_pos = 0; --+ --+ info = &insn_rr[INSN_UID (insn)]; --+ --+ if (info->op_info == NULL) --+ return false; --+ --+ if (info->op_info[op_pos].n_chains == 0) --+ return false; --+ --+ op_chain = regrename_chain_from_id (info->op_info[op_pos].heads[0]->id); --+ --+ if (in_reg_class_p (op_chain->regno, R15_TA_REG)) --+ return false; --+ --+ /* slt[s]45 need second operand in MIDDLE_REGS class. */ --+ if (!REG_P (op0) || !in_reg_class_p (REGNO (op0), MIDDLE_REGS)) --+ return false; --+ --+ /* slt[s]i45 only allow 5 bit unsigned integer. */ --+ if (REG_P (op1) --+ || (CONST_INT_P (op1) && satisfies_constraint_Iu05 (op1))) --+ return true; --+ --+ return false; --+} --+ --+static bool --+rename_cbranch_eq0_low_reg_profitlable (rtx insn) --+{ --+ insn_rr_info *info; --+ du_head_p op_chain; --+ int op_pos = 1; --+ --+ info = &insn_rr[INSN_UID (insn)]; --+ --+ if (info->op_info == NULL) --+ return false; --+ --+ if (info->op_info[op_pos].n_chains == 0) --+ return false; --+ --+ op_chain = regrename_chain_from_id (info->op_info[op_pos].heads[0]->id); --+ --+ if (in_reg_class_p (op_chain->regno, LOW_REGS)) --+ return false; --+ --+ return true; --+} --+ --+ --+static bool --+rename_cbranch_eq0_r15_profitlable (rtx insn) --+{ --+ rtx pattern; --+ pattern = PATTERN (insn); --+ rtx if_then_else = SET_SRC (pattern); --+ rtx cond = XEXP (if_then_else, 0); --+ rtx op0 = XEXP (cond, 0); --+ --+ insn_rr_info *info; --+ du_head_p op_chain; --+ int op_pos = 1; --+ --+ info = &insn_rr[INSN_UID (insn)]; --+ --+ if (info->op_info == NULL) --+ return false; --+ --+ if (info->op_info[op_pos].n_chains == 0) --+ return false; --+ --+ op_chain = regrename_chain_from_id (info->op_info[op_pos].heads[0]->id); --+ --+ if (in_reg_class_p (op_chain->regno, R15_TA_REG)) --+ return false; --+ --+ /* LOW_REGS or R15_TA_REG both are 2-byte instruction. */ --+ if (REG_P (op0) && in_reg_class_p (REGNO (op0), LOW_REGS)) --+ return false; --+ --+ return true; --+} --+ --+static bool --+rename_cbranch_eq_reg_profitlable (rtx insn) --+{ --+ rtx pattern; --+ pattern = PATTERN (insn); --+ rtx if_then_else = SET_SRC (pattern); --+ rtx cond = XEXP (if_then_else, 0); --+ rtx op1 = XEXP (cond, 1); --+ --+ insn_rr_info *info; --+ du_head_p op_chain; --+ int op_pos = 1; --+ --+ info = &insn_rr[INSN_UID (insn)]; --+ --+ if (info->op_info == NULL) --+ return false; --+ --+ if (info->op_info[op_pos].n_chains == 0) --+ return false; --+ --+ op_chain = regrename_chain_from_id (info->op_info[op_pos].heads[0]->id); --+ --+ if (in_reg_class_p (op_chain->regno, R5_REG)) --+ return false; --+ --+ if (REG_P (op1) && in_reg_class_p (REGNO (op1), LOW_REGS)) --+ return true; --+ else --+ return false; --+} --+ --+static void --+do_regrename () --+{ --+ basic_block bb; --+ rtx_insn *insn; --+ --+ FOR_EACH_BB_FN (bb, cfun) --+ { --+ FOR_BB_INSNS (bb, insn) --+ { --+ if (!INSN_P (insn)) --+ continue; --+ --+ switch (recog_memoized (insn)) --+ { --+ case CODE_FOR_slts_compare_impl: --+ case CODE_FOR_slt_compare_impl: --+ /* Try to rename operand 0 to $r15 if profitable. */ --+ if (rename_slt_profitlable (insn)) --+ try_rename_operand_to (insn, 0, R15_TA_REG); --+ break; --+ case CODE_FOR_slt_eq0: --+ /* Try to rename operand 0 to $r15. */ --+ if (rename_slt_profitlable (insn)) --+ try_rename_operand_to (insn, 0, R15_TA_REG); --+ break; --+ case CODE_FOR_cbranchsi4_equality_zero: --+ /* Try to rename operand 1 to $r15. */ --+ if (rename_cbranch_eq0_r15_profitlable (insn)) --+ if (!try_rename_operand_to (insn, 1, R15_TA_REG)) --+ if (rename_cbranch_eq0_low_reg_profitlable (insn)) --+ try_rename_operand_to (insn, 1, LOW_REGS); --+ break; --+ case CODE_FOR_cbranchsi4_equality_reg: --+ case CODE_FOR_cbranchsi4_equality_reg_or_const_int: --+ /* Try to rename operand 1 to $r5. */ --+ if (rename_cbranch_eq_reg_profitlable (insn)) --+ try_rename_operand_to (insn, 1, R5_REG); --+ break; --+ } --+ } --+ } --+} --+ --+static unsigned int --+nds32_regrename (void) --+{ --+ df_set_flags (DF_LR_RUN_DCE); --+ df_note_add_problem (); --+ df_analyze (); --+ df_set_flags (DF_DEFER_INSN_RESCAN); --+ --+ regrename_init (true); --+ --+ regrename_analyze (NULL); --+ --+ do_regrename (); --+ --+ regrename_finish (); --+ return 1; --+} --+ --+const pass_data pass_data_nds32_regrename = --+{ --+ RTL_PASS, /* type */ --+ "nds32-regrename", /* name */ --+ OPTGROUP_NONE, /* optinfo_flags */ --+ TV_MACH_DEP, /* tv_id */ --+ 0, /* properties_required */ --+ 0, /* properties_provided */ --+ 0, /* properties_destroyed */ --+ 0, /* todo_flags_start */ --+ TODO_df_finish, /* todo_flags_finish */ --+}; --+ --+class pass_nds32_regrename_opt : public rtl_opt_pass --+{ --+public: --+ pass_nds32_regrename_opt (gcc::context *ctxt) --+ : rtl_opt_pass (pass_data_nds32_regrename, ctxt) --+ {} --+ --+ /* opt_pass methods: */ --+ bool gate (function *) { return TARGET_16_BIT && TARGET_REGRENAME_OPT; } --+ unsigned int execute (function *) { return nds32_regrename (); } --+}; --+ --+rtl_opt_pass * --+make_pass_nds32_regrename_opt (gcc::context *ctxt) --+{ --+ return new pass_nds32_regrename_opt (ctxt); --+} --diff --git a/gcc/config/nds32/nds32-relax-opt.c b/gcc/config/nds32/nds32-relax-opt.c --new file mode 100644 --index 0000000..0919af6 ----- /dev/null --+++ b/gcc/config/nds32/nds32-relax-opt.c --@@ -0,0 +1,612 @@ --+/* relax-opt pass of Andes NDS32 cpu for GNU compiler --+ Copyright (C) 2012-2016 Free Software Foundation, Inc. --+ Contributed by Andes Technology Corporation. --+ --+ This file is part of GCC. --+ --+ GCC is free software; you can redistribute it and/or modify it --+ under the terms of the GNU General Public License as published --+ by the Free Software Foundation; either version 3, or (at your --+ option) any later version. --+ --+ GCC is distributed in the hope that it will be useful, but WITHOUT --+ ANY WARRANTY; without even the implied warranty of MERCHANTABILITY --+ or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public --+ License for more details. --+ --+ You should have received a copy of the GNU General Public License --+ along with GCC; see the file COPYING3. If not see --+ . */ --+ --+#include "config.h" --+#include "system.h" --+#include "coretypes.h" --+#include "tm.h" --+#include "hash-set.h" --+#include "machmode.h" --+#include "vec.h" --+#include "double-int.h" --+#include "input.h" --+#include "alias.h" --+#include "symtab.h" --+#include "wide-int.h" --+#include "inchash.h" --+#include "tree.h" --+#include "stor-layout.h" --+#include "varasm.h" --+#include "calls.h" --+#include "rtl.h" --+#include "regs.h" --+#include "hard-reg-set.h" --+#include "insn-config.h" /* Required by recog.h. */ --+#include "conditions.h" --+#include "output.h" --+#include "insn-attr.h" /* For DFA state_t. */ --+#include "insn-codes.h" /* For CODE_FOR_xxx. */ --+#include "reload.h" /* For push_reload (). */ --+#include "flags.h" --+#include "input.h" --+#include "function.h" --+#include "emit-rtl.h" --+#include "expr.h" --+#include "recog.h" --+#include "diagnostic-core.h" --+#include "dominance.h" --+#include "cfg.h" --+#include "cfgrtl.h" --+#include "cfganal.h" --+#include "lcm.h" --+#include "cfgbuild.h" --+#include "cfgcleanup.h" --+#include "predict.h" --+#include "basic-block.h" --+#include "bitmap.h" --+#include "df.h" --+#include "tm_p.h" --+#include "tm-constrs.h" --+#include "optabs.h" /* For GEN_FCN. */ --+#include "target.h" --+#include "langhooks.h" /* For add_builtin_function (). */ --+#include "ggc.h" --+#include "tree-pass.h" --+#include "target-globals.h" --+using namespace nds32; --+ --+/* This is used to create unique relax hint id value. --+ The initial value is 0. */ --+static int relax_group_id = 0; --+ --+/* Group the following pattern as relax candidates: --+ --+ 1. sethi $ra, hi20(sym) --+ ori $ra, $ra, lo12(sym) --+ ==> --+ addi.gp $ra, sym --+ --+ 2. sethi $ra, hi20(sym) --+ lwi $rb, [$ra + lo12(sym)] --+ ==> --+ lwi.gp $rb, [(sym)] --+ --+ 3. sethi $ra, hi20(sym) --+ ori $ra, $ra, lo12(sym) --+ lwi $rb, [$ra] --+ swi $rc, [$ra] --+ ==> --+ lwi37 $rb, [(sym)] --+ swi37 $rc, [(sym)] */ --+ --+/* Return true if is load/store with REG addressing mode --+ and memory mode is SImode. */ --+static bool --+nds32_reg_base_load_store_p (rtx_insn *insn) --+{ --+ rtx mem_src = NULL_RTX; --+ --+ switch (get_attr_type (insn)) --+ { --+ case TYPE_LOAD: --+ mem_src = SET_SRC (PATTERN (insn)); --+ break; --+ case TYPE_STORE: --+ mem_src = SET_DEST (PATTERN (insn)); --+ break; --+ default: --+ break; --+ } --+ --+ /* Find load/store insn with addressing mode is REG. */ --+ if (mem_src != NULL_RTX) --+ { --+ if ((GET_CODE (mem_src) == ZERO_EXTEND) --+ || (GET_CODE (mem_src) == SIGN_EXTEND)) --+ mem_src = XEXP (mem_src, 0); --+ --+ if (GET_CODE (XEXP (mem_src, 0)) == REG) --+ return true; --+ } --+ --+ return false; --+} --+ --+/* Return true if insn is a sp/fp base or sp/fp plus load-store instruction. */ --+ --+static bool --+nds32_sp_base_or_plus_load_store_p (rtx_insn *insn) --+{ --+ rtx mem_src = NULL_RTX; --+ --+ switch (get_attr_type (insn)) --+ { --+ case TYPE_LOAD: --+ mem_src = SET_SRC (PATTERN (insn)); --+ break; --+ case TYPE_STORE: --+ mem_src = SET_DEST (PATTERN (insn)); --+ break; --+ default: --+ break; --+ } --+ /* Find load/store insn with addressing mode is REG. */ --+ if (mem_src != NULL_RTX) --+ { --+ if ((GET_CODE (mem_src) == ZERO_EXTEND) --+ || (GET_CODE (mem_src) == SIGN_EXTEND)) --+ mem_src = XEXP (mem_src, 0); --+ --+ if ((GET_CODE (XEXP (mem_src, 0)) == PLUS)) --+ mem_src = XEXP (mem_src, 0); --+ --+ if (REG_P (XEXP (mem_src, 0)) --+ && ((frame_pointer_needed --+ && REGNO (XEXP (mem_src, 0)) == FP_REGNUM) --+ || REGNO (XEXP (mem_src, 0)) == SP_REGNUM)) --+ return true; --+ } --+ --+ return false; --+} --+ --+/* Return true if is load with [REG + REG/CONST_INT] addressing mode. */ --+static bool --+nds32_plus_reg_load_store_p (rtx_insn *insn) --+{ --+ rtx mem_src = NULL_RTX; --+ --+ switch (get_attr_type (insn)) --+ { --+ case TYPE_LOAD: --+ mem_src = SET_SRC (PATTERN (insn)); --+ break; --+ case TYPE_STORE: --+ mem_src = SET_DEST (PATTERN (insn)); --+ break; --+ default: --+ break; --+ } --+ --+ /* Find load/store insn with addressing mode is [REG + REG/CONST]. */ --+ if (mem_src != NULL_RTX) --+ { --+ if ((GET_CODE (mem_src) == ZERO_EXTEND) --+ || (GET_CODE (mem_src) == SIGN_EXTEND)) --+ mem_src = XEXP (mem_src, 0); --+ --+ if ((GET_CODE (XEXP (mem_src, 0)) == PLUS)) --+ mem_src = XEXP (mem_src, 0); --+ else --+ return false; --+ --+ if (GET_CODE (XEXP (mem_src, 0)) == REG) --+ return true; --+ --+ } --+ --+ return false; --+} --+ --+/* Return true if ins is hwloop last instruction. */ --+static bool --+nds32_hwloop_last_insn_p (rtx_insn *insn) --+{ --+ if (recog_memoized (insn) == CODE_FOR_hwloop_last_insn) --+ return true; --+ --+ return false; --+} --+ --+/* Return true if x is const and the referance is ict symbol. */ --+static bool --+nds32_ict_const_p (rtx x) --+{ --+ if (GET_CODE (x) == CONST) --+ { --+ x = XEXP (x, 0); --+ return nds32_indirect_call_referenced_p (x); --+ } --+ return FALSE; --+} --+ --+/* Group the following pattern as relax candidates: --+ --+ GOT: --+ sethi $ra, hi20(sym) --+ ori $ra, $ra, lo12(sym) --+ lw $rb, [$ra + $gp] --+ --+ GOTOFF, TLSLE: --+ sethi $ra, hi20(sym) --+ ori $ra, $ra, lo12(sym) --+ LS $rb, [$ra + $gp] --+ --+ GOTOFF, TLSLE: --+ sethi $ra, hi20(sym) --+ ori $ra, $ra, lo12(sym) --+ add $rb, $ra, $gp($tp) --+ --+ Initial GOT table: --+ sethi $gp,hi20(sym) --+ ori $gp, $gp, lo12(sym) --+ add5.pc $gp */ --+ --+static auto_vec nds32_group_infos; --+/* Group the PIC and TLS relax candidate instructions for linker. */ --+static bool --+nds32_pic_tls_group (rtx_insn *def_insn, --+ enum nds32_relax_insn_type relax_type, --+ int sym_type) --+{ --+ df_ref def_record; --+ df_link *link; --+ rtx_insn *use_insn = NULL; --+ rtx pat, new_pat; --+ def_record = DF_INSN_DEFS (def_insn); --+ for (link = DF_REF_CHAIN (def_record); link; link = link->next) --+ { --+ if (!DF_REF_INSN_INFO (link->ref)) --+ continue; --+ --+ use_insn = DF_REF_INSN (link->ref); --+ --+ /* Skip if define insn and use insn not in the same basic block. */ --+ if (!dominated_by_p (CDI_DOMINATORS, --+ BLOCK_FOR_INSN (use_insn), --+ BLOCK_FOR_INSN (def_insn))) --+ return FALSE; --+ --+ /* Skip if use_insn not active insn. */ --+ if (!active_insn_p (use_insn)) --+ return FALSE; --+ --+ switch (relax_type) --+ { --+ case RELAX_ORI: --+ --+ /* GOTOFF, TLSLE: --+ sethi $ra, hi20(sym) --+ ori $ra, $ra, lo12(sym) --+ add $rb, $ra, $gp($tp) */ --+ if ((sym_type == UNSPEC_TLSLE --+ || sym_type == UNSPEC_GOTOFF) --+ && (recog_memoized (use_insn) == CODE_FOR_addsi3)) --+ { --+ pat = XEXP (PATTERN (use_insn), 1); --+ new_pat = --+ gen_rtx_UNSPEC (SImode, --+ gen_rtvec (2, XEXP (pat, 0), XEXP (pat, 1)), --+ UNSPEC_ADD32); --+ validate_replace_rtx (pat, new_pat, use_insn); --+ nds32_group_infos.safe_push (use_insn); --+ } --+ else if (nds32_plus_reg_load_store_p (use_insn) --+ && !nds32_sp_base_or_plus_load_store_p (use_insn)) --+ nds32_group_infos.safe_push (use_insn); --+ else --+ return FALSE; --+ break; --+ --+ default: --+ return FALSE; --+ } --+ } --+ return TRUE; --+} --+ --+static int --+nds32_pic_tls_symbol_type (rtx x) --+{ --+ x = XEXP (SET_SRC (PATTERN (x)), 1); --+ --+ if (GET_CODE (x) == CONST) --+ { --+ x = XEXP (x, 0); --+ --+ if (GET_CODE (x) == PLUS) --+ x = XEXP (x, 0); --+ --+ return XINT (x, 1); --+ } --+ --+ return XINT (x, 1); --+} --+ --+/* Group the relax candidates with group id. */ --+static void --+nds32_group_insns (rtx sethi) --+{ --+ df_ref def_record, use_record; --+ df_link *link; --+ rtx_insn *use_insn = NULL; --+ rtx group_id; --+ bool valid; --+ --+ def_record = DF_INSN_DEFS (sethi); --+ --+ for (link = DF_REF_CHAIN (def_record); link; link = link->next) --+ { --+ if (!DF_REF_INSN_INFO (link->ref)) --+ continue; --+ --+ use_insn = DF_REF_INSN (link->ref); --+ --+ /* Skip if define insn and use insn not in the same basic block. */ --+ if (!dominated_by_p (CDI_DOMINATORS, --+ BLOCK_FOR_INSN (use_insn), --+ BLOCK_FOR_INSN (sethi))) --+ return; --+ --+ /* Skip if the low-part used register is from different high-part --+ instructions. */ --+ use_record = DF_INSN_USES (use_insn); --+ if (DF_REF_CHAIN (use_record) && DF_REF_CHAIN (use_record)->next) --+ return; --+ --+ /* Skip if use_insn not active insn. */ --+ if (!active_insn_p (use_insn)) --+ return; --+ --+ /* Initial use_insn_type. */ --+ if (!(recog_memoized (use_insn) == CODE_FOR_lo_sum --+ || nds32_symbol_load_store_p (use_insn) --+ || (nds32_reg_base_load_store_p (use_insn) --+ &&!nds32_sp_base_or_plus_load_store_p (use_insn)))) --+ return; --+ } --+ --+ group_id = GEN_INT (relax_group_id); --+ /* Insert .relax_* directive for sethi. */ --+ emit_insn_before (gen_relax_group (group_id), sethi); --+ --+ /* Scan the use insns and insert the directive. */ --+ for (link = DF_REF_CHAIN (def_record); link; link = link->next) --+ { --+ if (!DF_REF_INSN_INFO (link->ref)) --+ continue; --+ --+ use_insn = DF_REF_INSN (link->ref); --+ --+ /* Insert .relax_* directive. */ --+ if (active_insn_p (use_insn)) --+ emit_insn_before (gen_relax_group (group_id), use_insn); --+ --+ /* Find ori ra, ra, unspec(symbol) instruction. */ --+ if (use_insn != NULL --+ && recog_memoized (use_insn) == CODE_FOR_lo_sum --+ && !nds32_const_unspec_p (XEXP (SET_SRC (PATTERN (use_insn)), 1))) --+ { --+ int sym_type = nds32_pic_tls_symbol_type (use_insn); --+ valid = nds32_pic_tls_group (use_insn, RELAX_ORI, sym_type); --+ --+ /* Insert .relax_* directive. */ --+ while (!nds32_group_infos.is_empty ()) --+ { --+ use_insn = nds32_group_infos.pop (); --+ if (valid) --+ emit_insn_before (gen_relax_group (group_id), use_insn); --+ } --+ } --+ } --+ --+ relax_group_id++; --+} --+ --+/* Convert relax group id in rtl. */ --+ --+static void --+nds32_group_tls_insn (rtx insn) --+{ --+ rtx pat = PATTERN (insn); --+ rtx unspec_relax_group = XEXP (XVECEXP (pat, 0, 1), 0); --+ --+ while (GET_CODE (pat) != SET && GET_CODE (pat) == PARALLEL) --+ { --+ pat = XVECEXP (pat, 0, 0); --+ } --+ --+ if (GET_CODE (unspec_relax_group) == UNSPEC --+ && XINT (unspec_relax_group, 1) == UNSPEC_VOLATILE_RELAX_GROUP) --+ { --+ XVECEXP (unspec_relax_group, 0, 0) = GEN_INT (relax_group_id); --+ } --+ --+ relax_group_id++; --+} --+ --+static bool --+nds32_float_reg_load_store_p (rtx_insn *insn) --+{ --+ rtx pat = PATTERN (insn); --+ --+ if (get_attr_type (insn) == TYPE_FLOAD --+ && GET_CODE (pat) == SET --+ && (GET_MODE (XEXP (pat, 0)) == SFmode --+ || GET_MODE (XEXP (pat, 0)) == DFmode) --+ && MEM_P (XEXP (pat, 1))) --+ { --+ rtx addr = XEXP (XEXP (pat, 1), 0); --+ --+ /* [$ra] */ --+ if (REG_P (addr)) --+ return true; --+ /* [$ra + offset] */ --+ if (GET_CODE (addr) == PLUS --+ && REG_P (XEXP (addr, 0)) --+ && CONST_INT_P (XEXP (addr, 1))) --+ return true; --+ } --+ return false; --+} --+ --+ --+/* Group float load-store instructions: --+ la $ra, symbol --+ flsi $rt, [$ra + offset] */ --+ --+static void --+nds32_group_float_insns (rtx insn) --+{ --+ df_ref def_record, use_record; --+ df_link *link; --+ rtx_insn *use_insn = NULL; --+ rtx group_id; --+ --+ def_record = DF_INSN_DEFS (insn); --+ --+ for (link = DF_REF_CHAIN (def_record); link; link = link->next) --+ { --+ if (!DF_REF_INSN_INFO (link->ref)) --+ continue; --+ --+ use_insn = DF_REF_INSN (link->ref); --+ --+ /* Skip if define insn and use insn not in the same basic block. */ --+ if (!dominated_by_p (CDI_DOMINATORS, --+ BLOCK_FOR_INSN (use_insn), --+ BLOCK_FOR_INSN (insn))) --+ return; --+ --+ /* Skip if the low-part used register is from different high-part --+ instructions. */ --+ use_record = DF_INSN_USES (use_insn); --+ if (DF_REF_CHAIN (use_record) && DF_REF_CHAIN (use_record)->next) --+ return; --+ --+ /* Skip if use_insn not active insn. */ --+ if (!active_insn_p (use_insn)) --+ return; --+ --+ if (!nds32_float_reg_load_store_p (use_insn) --+ || find_post_update_rtx (use_insn) != -1) --+ return; --+ } --+ --+ group_id = GEN_INT (relax_group_id); --+ /* Insert .relax_* directive for insn. */ --+ emit_insn_before (gen_relax_group (group_id), insn); --+ --+ /* Scan the use insns and insert the directive. */ --+ for (link = DF_REF_CHAIN (def_record); link; link = link->next) --+ { --+ if (!DF_REF_INSN_INFO (link->ref)) --+ continue; --+ --+ use_insn = DF_REF_INSN (link->ref); --+ --+ /* Insert .relax_* directive. */ --+ emit_insn_before (gen_relax_group (group_id), use_insn); --+ } --+ --+ relax_group_id++; --+} --+ --+/* Group the relax candidate instructions for linker. */ --+static void --+nds32_relax_group (void) --+{ --+ rtx_insn *insn; --+ --+ compute_bb_for_insn (); --+ --+ df_chain_add_problem (DF_DU_CHAIN | DF_UD_CHAIN); --+ df_insn_rescan_all (); --+ df_analyze (); --+ df_set_flags (DF_DEFER_INSN_RESCAN); --+ calculate_dominance_info (CDI_DOMINATORS); --+ --+ insn = get_insns (); --+ gcc_assert (NOTE_P (insn)); --+ --+ for (insn = next_active_insn (insn); insn; insn = next_active_insn (insn)) --+ { --+ if (NONJUMP_INSN_P (insn)) --+ { --+ /* Find sethi ra, symbol instruction. */ --+ if (recog_memoized (insn) == CODE_FOR_sethi --+ && nds32_symbolic_operand (XEXP (SET_SRC (PATTERN (insn)), 0), --+ SImode) --+ && !nds32_ict_const_p (XEXP (SET_SRC (PATTERN (insn)), 0)) --+ && !nds32_hwloop_last_insn_p (next_active_insn (insn))) --+ --+ nds32_group_insns (insn); --+ else if (recog_memoized (insn) == CODE_FOR_tls_ie) --+ nds32_group_tls_insn (insn); --+ else if (TARGET_FPU_SINGLE --+ && recog_memoized (insn) == CODE_FOR_move_addr --+ && !nds32_ict_const_p (XEXP (SET_SRC (PATTERN (insn)), 0)) --+ && !nds32_hwloop_last_insn_p (next_active_insn (insn))) --+ { --+ nds32_group_float_insns (insn); --+ } --+ } --+ else if (CALL_P (insn) && recog_memoized (insn) == CODE_FOR_tls_desc) --+ { --+ nds32_group_tls_insn (insn); --+ } --+ } --+ --+ /* We must call df_finish_pass manually because it should be invoked before --+ BB information is destroyed. Hence we cannot set the TODO_df_finish flag --+ to the pass manager. */ --+ df_insn_rescan_all (); --+ df_finish_pass (false); --+ free_dominance_info (CDI_DOMINATORS); --+} --+ --+static unsigned int --+nds32_relax_opt (void) --+{ --+ if (TARGET_RELAX_HINT) --+ nds32_relax_group (); --+ return 1; --+} --+ --+const pass_data pass_data_nds32_relax_opt = --+{ --+ RTL_PASS, /* type */ --+ "relax_opt", /* name */ --+ OPTGROUP_NONE, /* optinfo_flags */ --+ TV_MACH_DEP, /* tv_id */ --+ 0, /* properties_required */ --+ 0, /* properties_provided */ --+ 0, /* properties_destroyed */ --+ 0, /* todo_flags_start */ --+ TODO_df_finish, /* todo_flags_finish */ --+}; --+ --+class pass_nds32_relax_opt : public rtl_opt_pass --+{ --+public: --+ pass_nds32_relax_opt (gcc::context *ctxt) --+ : rtl_opt_pass (pass_data_nds32_relax_opt, ctxt) --+ {} --+ --+ /* opt_pass methods: */ --+ bool gate (function *) { return TARGET_RELAX_HINT; } --+ unsigned int execute (function *) { return nds32_relax_opt (); } --+}; --+ --+rtl_opt_pass * --+make_pass_nds32_relax_opt (gcc::context *ctxt) --+{ --+ return new pass_nds32_relax_opt (ctxt); --+} --diff --git a/gcc/config/nds32/nds32-scalbn-transform.c b/gcc/config/nds32/nds32-scalbn-transform.c --new file mode 100644 --index 0000000..fba7c6f ----- /dev/null --+++ b/gcc/config/nds32/nds32-scalbn-transform.c --@@ -0,0 +1,364 @@ --+/* A Gimple-level pass of Andes NDS32 cpu for GNU compiler. --+ This pass transforms the multiplications whose multiplier is a --+ power of 2. --+ --+ Copyright (C) 2012-2016 Free Software Foundation, Inc. --+ Contributed by Andes Technology Corporation. --+ --+This file is part of GCC. --+ --+GCC is free software; you can redistribute it and/or modify it under --+the terms of the GNU General Public License as published by the Free --+Software Foundation; either version 3, or (at your option) any later --+version. --+ --+GCC is distributed in the hope that it will be useful, but WITHOUT ANY --+WARRANTY; without even the implied warranty of MERCHANTABILITY or --+FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License --+for more details. --+ --+You should have received a copy of the GNU General Public License --+along with GCC; see the file COPYING3. If not see --+. */ --+ --+ --+#include "config.h" --+#include "system.h" --+#include "coretypes.h" --+#include "tm.h" --+#include "hash-set.h" --+#include "machmode.h" --+#include "vec.h" --+#include "double-int.h" --+#include "input.h" --+#include "alias.h" --+#include "symtab.h" --+#include "wide-int.h" --+#include "inchash.h" --+#include "tree.h" --+#include "stor-layout.h" --+#include "varasm.h" --+#include "calls.h" --+#include "rtl.h" --+#include "regs.h" --+#include "hard-reg-set.h" --+#include "insn-config.h" /* Required by recog.h. */ --+#include "conditions.h" --+#include "output.h" --+#include "insn-attr.h" /* For DFA state_t. */ --+#include "insn-codes.h" /* For CODE_FOR_xxx. */ --+#include "reload.h" /* For push_reload (). */ --+#include "flags.h" --+#include "input.h" --+#include "function.h" --+#include "expr.h" --+#include "recog.h" --+#include "diagnostic-core.h" --+#include "dominance.h" --+#include "cfg.h" --+#include "cfgrtl.h" --+#include "cfganal.h" --+#include "lcm.h" --+#include "cfgbuild.h" --+#include "cfgcleanup.h" --+#include "predict.h" --+#include "basic-block.h" --+#include "bitmap.h" --+#include "df.h" --+#include "tm_p.h" --+#include "tm-constrs.h" --+#include "optabs.h" /* For GEN_FCN. */ --+#include "target.h" --+#include "langhooks.h" /* For add_builtin_function (). */ --+#include "ggc.h" --+#include "tree-pass.h" --+#include "tree-ssa-alias.h" --+#include "fold-const.h" --+#include "gimple-expr.h" --+#include "is-a.h" --+#include "gimple.h" --+#include "gimplify.h" --+#include "gimple-iterator.h" --+#include "gimplify-me.h" --+#include "gimple-ssa.h" --+#include "ipa-ref.h" --+#include "lto-streamer.h" --+#include "cgraph.h" --+#include "tree-cfg.h" --+#include "tree-phinodes.h" --+#include "stringpool.h" --+#include "tree-ssanames.h" --+#include "tree-pass.h" --+#include "gimple-pretty-print.h" --+#include "gimple-fold.h" --+ --+ --+/* Return true if the current function name is scalbn/scalbnf, or its alias --+ includes scalbn/scalbnf, otherwise return false. */ --+ --+static bool --+nds32_is_scalbn_alias_func_p (void) --+{ --+ int i; --+ struct ipa_ref *ref; --+ struct cgraph_node *cfun_node; --+ --+ if (!strcmp (function_name (cfun), "scalbn") --+ || !strcmp (function_name (cfun), "scalbnf")) --+ return true; --+ --+ cfun_node = cgraph_node::get (current_function_decl); --+ --+ if (!cfun_node) --+ return false; --+ --+ for (i = 0; cfun_node->iterate_referring (i, ref); i++) --+ if (ref->use == IPA_REF_ALIAS) --+ { --+ struct cgraph_node *alias = dyn_cast (ref->referring); --+ if (!strcmp (alias->asm_name (), "scalbn") --+ || !strcmp (alias->asm_name (), "scalbnf")) --+ return true; --+ } --+ --+ return false; --+} --+ --+/* Return true if value of tree node RT is power of 2. */ --+ --+static bool --+nds32_real_ispow2_p (tree rt) --+{ --+ if (TREE_CODE (rt) != REAL_CST) --+ return false; --+ --+ if (TREE_REAL_CST_PTR (rt)->cl != rvc_normal) --+ return false; --+ --+ int i; --+ for (i = 0; i < SIGSZ-1; ++i) --+ if (TREE_REAL_CST_PTR (rt)->sig[i] != 0) --+ return false; --+ if (TREE_REAL_CST_PTR (rt)->sig[SIGSZ-1] != SIG_MSB) --+ return false; --+ --+ return true; --+} --+ --+/* Return the exponent of tree node RT in base 2. */ --+ --+static int --+nds32_real_pow2exp (tree rt) --+{ --+ return REAL_EXP (TREE_REAL_CST_PTR (rt)) - 1; --+} --+ --+/* Return true if GS is the target of scalbn transform. */ --+ --+static bool --+nds32_scalbn_transform_target_p (gimple *gs) --+{ --+ if (is_gimple_assign (gs)) --+ if ((gimple_assign_rhs_code (gs) == MULT_EXPR) --+ && (TREE_CODE (TREE_TYPE (gimple_assign_rhs1 (gs))) == REAL_TYPE) --+ && nds32_real_ispow2_p (gimple_assign_rhs2 (gs))) --+ return true; --+ return false; --+} --+ --+/* Do scalbn transform for a GIMPLE statement GS. --+ --+ When the multiplier of GIMPLE statement GS is a positive number, --+ GS will be transform to one gimple_call statement and one --+ gimple_assign statement as follows: --+ A = B * 128.0 -> temp = BUILT_IN_SCALBN (B, 7) --+ A = temp --+ --+ When the multiplier is a negative number, the multiplier will be --+ conversed the sign first since BUILT_IN_SCALBN can't handle --+ negative multiplier. The example is shown below: --+ A = B * -128.0 -> temp = BUILT_IN_SCALBN (B, 7) --+ A = -temp --+*/ --+ --+static void --+nds32_do_scalbn_transform (gimple *gs) --+{ --+ tree mult_cand = gimple_assign_rhs1 (gs); /* Multiplicand */ --+ tree mult_er = gimple_assign_rhs2 (gs); /* Multiplier */ --+ bool is_neg = false; --+ --+ /* Choose the function by type of arg. */ --+ enum built_in_function fn_name; --+ tree type = TREE_TYPE (mult_cand); --+ if (TYPE_MAIN_VARIANT (type) == double_type_node) --+ fn_name = BUILT_IN_SCALBN; --+ else if (TYPE_MAIN_VARIANT (type) == float_type_node) --+ fn_name = BUILT_IN_SCALBNF; --+ /* Do not transform long double to scalbnl since some c library don't provide --+ it if target don't have real long double type --+ else if (TYPE_MAIN_VARIANT (type) == long_double_type_node) --+ fn_name = BUILT_IN_SCALBNL; --+ */ --+ else --+ return; --+ --+ /* Converse the sign of negative number. */ --+ if (REAL_VALUE_NEGATIVE (TREE_REAL_CST (mult_er))) --+ { --+ is_neg = true; --+ mult_er = build_real (TREE_TYPE (mult_er), --+ real_value_negate (&TREE_REAL_CST (mult_er))); --+ } --+ --+ /* Set function name for building gimple_call. */ --+ tree fndecl = builtin_decl_explicit (fn_name); --+ --+ /* Set last arg for building gimple_call. */ --+ tree exp = build_int_cst (integer_type_node, --+ nds32_real_pow2exp (mult_er)); --+ --+ /* Build a new temp ssa. */ --+ tree temp_call_ssa = make_ssa_name (TREE_TYPE (gimple_assign_lhs (gs)), NULL); --+ --+ /* Build gimple_call stmt to replace GS. */ --+ gimple *call_stmt = gimple_build_call (fndecl, --+ 2, --+ mult_cand, --+ exp); --+ gimple_call_set_lhs (call_stmt, temp_call_ssa); --+ --+ enum tree_code subcode = NOP_EXPR; --+ /* Handle negative value. */ --+ if (is_neg) --+ subcode = NEGATE_EXPR; --+ --+ /* Build gimple_assign for return value or change the sign. */ --+ gimple *assign_stmt = --+ gimple_build_assign (gimple_assign_lhs (gs), --+ subcode, --+ gimple_call_lhs (call_stmt)); --+ --+ /* Replace gimple_assign GS by new gimple_call. */ --+ gimple_stmt_iterator gsi = gsi_for_stmt (gs); --+ update_stmt (call_stmt); --+ gsi_insert_before (&gsi, call_stmt, GSI_NEW_STMT); --+ --+ /* Insert the gimple_assign after the scalbn call. */ --+ update_stmt (assign_stmt); --+ gsi_next (&gsi); --+ gsi_replace (&gsi, assign_stmt, false); --+} --+ --+/* Do scalbn transform for each basic block BB. */ --+ --+static int --+nds32_scalbn_transform_basic_block (basic_block bb) --+{ --+ gimple_stmt_iterator gsi; --+ int transform_number = 0; --+ --+ if (dump_file) --+ fprintf (dump_file, --+ "\n;; Transforming the multiplication for basic block %d\n", --+ bb->index); --+ --+ for (gsi = gsi_start_bb (bb); !gsi_end_p (gsi); gsi_next (&gsi)) --+ { --+ gimple *stmt = gsi_stmt (gsi); --+ --+ if (nds32_scalbn_transform_target_p (stmt)) --+ { --+ if (dump_file) --+ { --+ fprintf (dump_file, --+ "* The multiplier of stmt %d is transforming.\n", --+ gimple_uid (stmt)); --+ print_gimple_stmt (dump_file, stmt, 0, TDF_SLIM|TDF_RAW); --+ } --+ nds32_do_scalbn_transform (stmt); --+ transform_number++; --+ } --+ } --+ --+ return transform_number; --+} --+ --+/* This function is the entry of scalbn transform pass. */ --+ --+static int --+nds32_scalbn_transform_opt (void) --+{ --+ basic_block bb; --+ int total_transform_number = 0; --+ --+ /* Ignore current and builtin function name are the same. */ --+ if (nds32_is_scalbn_alias_func_p ()) --+ { --+ if (dump_file) --+ fprintf (dump_file, --+ "* Ignore function %s. " --+ "Transform it will cause infinite loop.\n", --+ function_name (cfun)); --+ return 0; --+ } --+ --+ FOR_EACH_BB_FN (bb, cfun) --+ { --+ total_transform_number += nds32_scalbn_transform_basic_block (bb); --+ } --+ --+ if (dump_file) --+ { --+ if (total_transform_number > 0) --+ fprintf (dump_file, --+ "\n;; Transform %d multiplication stmt in function %s\n", --+ total_transform_number, --+ current_function_name ()); --+ else --+ fprintf (dump_file, --+ "\n;; No multiplication stmt is transformed in function %s\n", --+ current_function_name ()); --+ } --+ --+ return 1; --+} --+ --+static bool --+gate_nds32_scalbn_transform (void) --+{ --+ return flag_nds32_scalbn_transform --+ && !TARGET_FPU_SINGLE --+ && !flag_no_builtin; --+} --+ --+const pass_data pass_data_nds32_scalbn_transform_opt = --+{ --+ GIMPLE_PASS, /* type */ --+ "scalbn_transform", /* name */ --+ OPTGROUP_NONE, /* optinfo_flags */ --+ TV_MACH_DEP, /* tv_id */ --+ ( PROP_cfg | PROP_ssa ), /* properties_required */ --+ 0, /* properties_provided */ --+ 0, /* properties_destroyed */ --+ 0, /* todo_flags_start */ --+ TODO_update_ssa, /* todo_flags_finish */ --+}; --+ --+class pass_nds32_scalbn_transform_opt : public gimple_opt_pass --+{ --+public: --+ pass_nds32_scalbn_transform_opt (gcc::context *ctxt) --+ : gimple_opt_pass (pass_data_nds32_scalbn_transform_opt, ctxt) --+ {} --+ --+ /* opt_pass methods: */ --+ bool gate (function *) { return gate_nds32_scalbn_transform (); } --+ unsigned int execute (function *) { return nds32_scalbn_transform_opt (); } --+}; --+ --+gimple_opt_pass * --+make_pass_nds32_scalbn_transform_opt (gcc::context *ctxt) --+{ --+ return new pass_nds32_scalbn_transform_opt (ctxt); --+} --diff --git a/gcc/config/nds32/nds32-sign-conversion.c b/gcc/config/nds32/nds32-sign-conversion.c --new file mode 100644 --index 0000000..74eefba ----- /dev/null --+++ b/gcc/config/nds32/nds32-sign-conversion.c --@@ -0,0 +1,218 @@ --+/* A Gimple-level pass of Andes NDS32 cpu for GNU compiler that --+ converse the sign of constant operand when the FPU do not be --+ accessed. --+ --+ Copyright (C) 2012-2016 Free Software Foundation, Inc. --+ Contributed by Andes Technology Corporation. --+ --+This file is part of GCC. --+ --+GCC is free software; you can redistribute it and/or modify it under --+the terms of the GNU General Public License as published by the Free --+Software Foundation; either version 3, or (at your option) any later --+version. --+ --+GCC is distributed in the hope that it will be useful, but WITHOUT ANY --+WARRANTY; without even the implied warranty of MERCHANTABILITY or --+FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License --+for more details. --+ --+You should have received a copy of the GNU General Public License --+along with GCC; see the file COPYING3. If not see --+. */ --+ --+ --+#include "config.h" --+#include "system.h" --+#include "coretypes.h" --+#include "tm.h" --+#include "hash-set.h" --+#include "machmode.h" --+#include "vec.h" --+#include "double-int.h" --+#include "input.h" --+#include "alias.h" --+#include "symtab.h" --+#include "wide-int.h" --+#include "inchash.h" --+#include "tree.h" --+#include "stor-layout.h" --+#include "varasm.h" --+#include "calls.h" --+#include "rtl.h" --+#include "regs.h" --+#include "hard-reg-set.h" --+#include "insn-config.h" /* Required by recog.h. */ --+#include "conditions.h" --+#include "output.h" --+#include "insn-attr.h" /* For DFA state_t. */ --+#include "insn-codes.h" /* For CODE_FOR_xxx. */ --+#include "reload.h" /* For push_reload (). */ --+#include "flags.h" --+#include "input.h" --+#include "function.h" --+#include "expr.h" --+#include "recog.h" --+#include "diagnostic-core.h" --+#include "dominance.h" --+#include "cfg.h" --+#include "cfgrtl.h" --+#include "cfganal.h" --+#include "lcm.h" --+#include "cfgbuild.h" --+#include "cfgcleanup.h" --+#include "predict.h" --+#include "basic-block.h" --+#include "bitmap.h" --+#include "df.h" --+#include "tm_p.h" --+#include "tm-constrs.h" --+#include "optabs.h" /* For GEN_FCN. */ --+#include "target.h" --+#include "langhooks.h" /* For add_builtin_function (). */ --+#include "ggc.h" --+#include "tree-pass.h" --+#include "tree-ssa-alias.h" --+#include "fold-const.h" --+#include "gimple-expr.h" --+#include "is-a.h" --+#include "gimple.h" --+#include "gimplify.h" --+#include "gimple-iterator.h" --+#include "gimplify-me.h" --+#include "gimple-ssa.h" --+#include "ipa-ref.h" --+#include "lto-streamer.h" --+#include "cgraph.h" --+#include "tree-cfg.h" --+#include "tree-phinodes.h" --+#include "stringpool.h" --+#include "tree-ssanames.h" --+#include "tree-pass.h" --+#include "gimple-pretty-print.h" --+#include "gimple-fold.h" --+ --+/* Return true if GS is the target of sign conversion. */ --+ --+static bool --+nds32_sign_conversion_target_p (gimple *gs) --+{ --+ if (is_gimple_assign (gs)) --+ if ((gimple_assign_rhs_code (gs) == MINUS_EXPR) --+ && (TREE_CODE (gimple_assign_rhs2 (gs)) == REAL_CST)) --+ return true; --+ return false; --+} --+ --+/* Do sign conversion for a GIMPLE statement GS. */ --+ --+static void --+nds32_do_sign_conversion (gimple *gs) --+{ --+ /* Rewrite the rhs operand. */ --+ enum tree_code op_code = gimple_assign_rhs_code (gs); --+ op_code = PLUS_EXPR; --+ gimple_assign_set_rhs_code (gs, op_code); --+ /* Rewrite the constant value. */ --+ tree rhs2 = gimple_assign_rhs2 (gs); --+ rhs2 = build_real (TREE_TYPE (rhs2), --+ real_value_negate (&TREE_REAL_CST (rhs2))); --+ gimple_assign_set_rhs2 (gs, rhs2); --+ /* When the statement is modified, please mark this statement is modified. */ --+ update_stmt (gs); --+} --+ --+/* Do sign conversion for each basic block BB. */ --+ --+static int --+nds32_sign_conversion_basic_block (basic_block bb) --+{ --+ gimple_stmt_iterator gsi; --+ int converse_number = 0; --+ --+ if (dump_file) --+ fprintf (dump_file, --+ "\n;; Conversing the sign of gimple stmts for basic block %d\n", --+ bb->index); --+ --+ for (gsi = gsi_start_bb (bb); !gsi_end_p (gsi); gsi_next (&gsi)) --+ { --+ gimple *stmt = gsi_stmt (gsi); --+ --+ if (nds32_sign_conversion_target_p (stmt)) --+ { --+ if (dump_file) --+ { --+ fprintf (dump_file, "* The sign of stmt %d is conversing.\n", --+ gimple_uid (stmt)); --+ print_gimple_stmt (dump_file, stmt, 0, TDF_SLIM|TDF_RAW); --+ } --+ nds32_do_sign_conversion (stmt); --+ converse_number++; --+ } --+ } --+ --+ return converse_number; --+} --+ --+/* This function is the entry of sign conversion pass. */ --+ --+static int --+nds32_sign_conversion_opt (void) --+{ --+ basic_block bb; --+ int total_converse_number = 0; --+ --+ FOR_EACH_BB_FN (bb, cfun) --+ { --+ total_converse_number += nds32_sign_conversion_basic_block (bb); --+ } --+ --+ if (dump_file) --+ { --+ if (total_converse_number > 0) --+ fprintf (dump_file, "\n;; Converse %d stmts in function %s\n", --+ total_converse_number, --+ current_function_name ()); --+ else --+ fprintf (dump_file, --+ "\n;; No sign of stmt is conversed in function %s\n", --+ current_function_name ()); --+ } --+ --+ return 1; --+} --+ --+const pass_data pass_data_nds32_sign_conversion_opt = --+{ --+ GIMPLE_PASS, /* type */ --+ "sign_conversion", /* name */ --+ OPTGROUP_NONE, /* optinfo_flags */ --+ TV_MACH_DEP, /* tv_id */ --+ ( PROP_cfg | PROP_ssa ), /* properties_required */ --+ 0, /* properties_provided */ --+ 0, /* properties_destroyed */ --+ 0, /* todo_flags_start */ --+ TODO_update_ssa, /* todo_flags_finish */ --+}; --+ --+class pass_nds32_sign_conversion_opt : public gimple_opt_pass --+{ --+public: --+ pass_nds32_sign_conversion_opt (gcc::context *ctxt) --+ : gimple_opt_pass (pass_data_nds32_sign_conversion_opt, ctxt) --+ {} --+ --+ /* opt_pass methods: */ --+ bool gate (function *) --+ { --+ return flag_nds32_sign_conversion && !TARGET_FPU_SINGLE; --+ } --+ unsigned int execute (function *) { return nds32_sign_conversion_opt (); } --+}; --+ --+gimple_opt_pass * --+make_pass_nds32_sign_conversion_opt (gcc::context *ctxt) --+{ --+ return new pass_nds32_sign_conversion_opt (ctxt); --+} --diff --git a/gcc/config/nds32/nds32-soft-fp-comm.c b/gcc/config/nds32/nds32-soft-fp-comm.c --new file mode 100644 --index 0000000..98ba3d5 ----- /dev/null --+++ b/gcc/config/nds32/nds32-soft-fp-comm.c --@@ -0,0 +1,205 @@ --+/* Operand commutative for soft floating point arithmetic pass --+ of Andes NDS32 cpu for GNU compiler --+ Copyright (C) 2012-2016 Free Software Foundation, Inc. --+ Contributed by Andes Technology Corporation. --+ --+ This file is part of GCC. --+ --+ GCC is free software; you can redistribute it and/or modify it --+ under the terms of the GNU General Public License as published --+ by the Free Software Foundation; either version 3, or (at your --+ option) any later version. --+ --+ GCC is distributed in the hope that it will be useful, but WITHOUT --+ ANY WARRANTY; without even the implied warranty of MERCHANTABILITY --+ or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public --+ License for more details. --+ --+ You should have received a copy of the GNU General Public License --+ along with GCC; see the file COPYING3. If not see --+ . */ --+ --+ --+#include "config.h" --+#include "system.h" --+#include "coretypes.h" --+#include "backend.h" --+#include "tree.h" --+#include "rtl.h" --+#include "df.h" --+#include "alias.h" --+#include "stor-layout.h" --+#include "varasm.h" --+#include "calls.h" --+#include "regs.h" --+#include "insn-config.h" /* Required by recog.h. */ --+#include "conditions.h" --+#include "output.h" --+#include "insn-attr.h" /* For DFA state_t. */ --+#include "insn-codes.h" /* For CODE_FOR_xxx. */ --+#include "reload.h" /* For push_reload(). */ --+#include "flags.h" --+#include "insn-config.h" --+#include "expmed.h" --+#include "dojump.h" --+#include "explow.h" --+#include "emit-rtl.h" --+#include "stmt.h" --+#include "expr.h" --+#include "recog.h" --+#include "diagnostic-core.h" --+#include "cfgrtl.h" --+#include "cfganal.h" --+#include "lcm.h" --+#include "cfgbuild.h" --+#include "cfgcleanup.h" --+#include "tm_p.h" --+#include "tm-constrs.h" --+#include "optabs.h" /* For GEN_FCN. */ --+#include "target.h" --+#include "langhooks.h" /* For add_builtin_function(). */ --+#include "builtins.h" --+#include "cpplib.h" --+#include "params.h" --+#include "tree-pass.h" --+ --+#define SF_ARG0_REGNO 0 --+#define SF_ARG1_REGNO 1 --+ --+#define DF_ARG0_REGNO 0 --+#define DF_ARG1_REGNO 2 --+ --+static int --+nds32_soft_fp_arith_comm_opt (void) --+{ --+ basic_block bb; --+ rtx_insn *insn; --+ FOR_EACH_BB_FN (bb, cfun) --+ { --+ FOR_BB_INSNS (bb, insn) --+ { --+ if (!CALL_P (insn)) --+ continue; --+ --+ rtx pat = PATTERN (insn); --+ rtx call_rtx = XVECEXP (pat, 0, 0); --+ --+ if (GET_CODE (call_rtx) == SET) --+ call_rtx = SET_SRC (call_rtx); --+ --+ rtx func_mem = XEXP (call_rtx, 0); --+ rtx symbol = XEXP (func_mem, 0); --+ --+ if (GET_CODE (symbol) != SYMBOL_REF) --+ continue; --+ --+ const char *func_name = XSTR (symbol, 0); --+ bool df_p; --+ if (((strcmp("__mulsf3", func_name) == 0) --+ || (strcmp("__addsf3", func_name) == 0))) --+ df_p = false; --+ else if (((strcmp("__muldf3", func_name) == 0) --+ || (strcmp("__adddf3", func_name) == 0))) --+ df_p = true; --+ else --+ continue; --+ --+ rtx_insn *prev_insn = insn; --+ rtx_insn *arg0_insn = NULL; --+ rtx_insn *arg1_insn = NULL; --+ unsigned arg0_regno = df_p ? DF_ARG0_REGNO : SF_ARG0_REGNO; --+ unsigned arg1_regno = df_p ? DF_ARG1_REGNO : SF_ARG1_REGNO; --+ enum machine_mode mode = df_p ? DFmode : SFmode; --+ while ((prev_insn = PREV_INSN (prev_insn)) && prev_insn) --+ { --+ if (arg0_insn != NULL && arg1_insn != NULL) --+ break; --+ --+ if (BLOCK_FOR_INSN (prev_insn) != BLOCK_FOR_INSN (insn)) --+ break; --+ --+ if (!NONJUMP_INSN_P (prev_insn)) --+ break; --+ --+ if (!INSN_P (prev_insn)) --+ continue; --+ --+ rtx set = PATTERN (prev_insn); --+ --+ if (GET_CODE (set) != SET) --+ continue; --+ --+ rtx dst_reg = SET_DEST (set); --+ --+ if (!REG_P (dst_reg)) --+ break; --+ --+ unsigned regno = REGNO (dst_reg); --+ --+ if (regno == arg0_regno) --+ { --+ arg0_insn = prev_insn; --+ continue; --+ } --+ else if (regno == arg1_regno) --+ { --+ arg1_insn = prev_insn; --+ continue; --+ } --+ break; --+ } --+ if (arg0_insn == NULL || arg1_insn == NULL) --+ continue; --+ --+ rtx arg0_src = SET_SRC (PATTERN (arg0_insn)); --+ rtx arg1_src = SET_SRC (PATTERN (arg1_insn)); --+ --+ if ((REG_P (arg0_src) --+ && GET_MODE (arg0_src) == mode --+ && REGNO (arg0_src) == arg1_regno) --+ || (REG_P (arg1_src) --+ && GET_MODE (arg1_src) == mode --+ && REGNO (arg1_src) == arg0_regno)) --+ { --+ /* Swap operand! */ --+ rtx tmp = SET_DEST (PATTERN (arg0_insn)); --+ SET_DEST (PATTERN (arg0_insn)) = SET_DEST (PATTERN (arg1_insn)); --+ SET_DEST (PATTERN (arg1_insn)) = tmp; --+ } --+ } --+ } --+ return 1; --+} --+ --+const pass_data pass_data_nds32_soft_fp_arith_comm_opt = --+{ --+ RTL_PASS, /* type */ --+ "soft_fp_arith_comm", /* name */ --+ OPTGROUP_NONE, /* optinfo_flags */ --+ TV_MACH_DEP, /* tv_id */ --+ 0, /* properties_required */ --+ 0, /* properties_provided */ --+ 0, /* properties_destroyed */ --+ 0, /* todo_flags_start */ --+ 0, /* todo_flags_finish */ --+}; --+ --+class pass_nds32_soft_fp_arith_comm_opt : public rtl_opt_pass --+{ --+public: --+ pass_nds32_soft_fp_arith_comm_opt (gcc::context *ctxt) --+ : rtl_opt_pass (pass_data_nds32_soft_fp_arith_comm_opt, ctxt) --+ {} --+ --+ /* opt_pass methods: */ --+ bool gate (function *) { --+ return TARGET_SOFT_FP_ARITH_COMM && !TARGET_FPU_SINGLE; --+ } --+ unsigned int execute (function *) { return nds32_soft_fp_arith_comm_opt (); } --+}; --+ --+rtl_opt_pass * --+make_pass_nds32_soft_fp_arith_comm_opt (gcc::context *ctxt) --+{ --+ return new pass_nds32_soft_fp_arith_comm_opt (ctxt); --+} --diff --git a/gcc/config/nds32/nds32-utils.c b/gcc/config/nds32/nds32-utils.c --new file mode 100644 --index 0000000..3b16738 ----- /dev/null --+++ b/gcc/config/nds32/nds32-utils.c --@@ -0,0 +1,923 @@ --+/* Auxiliary functions for pipeline descriptions pattern of Andes --+ NDS32 cpu for GNU compiler --+ Copyright (C) 2012-2016 Free Software Foundation, Inc. --+ Contributed by Andes Technology Corporation. --+ --+ This file is part of GCC. --+ --+ GCC is free software; you can redistribute it and/or modify it --+ under the terms of the GNU General Public License as published --+ by the Free Software Foundation; either version 3, or (at your --+ option) any later version. --+ --+ GCC is distributed in the hope that it will be useful, but WITHOUT --+ ANY WARRANTY; without even the implied warranty of MERCHANTABILITY --+ or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public --+ License for more details. --+ --+ You should have received a copy of the GNU General Public License --+ along with GCC; see the file COPYING3. If not see --+ . */ --+ --+/* ------------------------------------------------------------------------ */ --+ --+#include "config.h" --+#include "system.h" --+#include "coretypes.h" --+#include "tm.h" --+#include "hash-set.h" --+#include "machmode.h" --+#include "vec.h" --+#include "double-int.h" --+#include "input.h" --+#include "alias.h" --+#include "symtab.h" --+#include "wide-int.h" --+#include "inchash.h" --+#include "tree.h" --+#include "stor-layout.h" --+#include "varasm.h" --+#include "calls.h" --+#include "rtl.h" --+#include "regs.h" --+#include "hard-reg-set.h" --+#include "insn-config.h" /* Required by recog.h. */ --+#include "conditions.h" --+#include "output.h" --+#include "insn-attr.h" /* For DFA state_t. */ --+#include "insn-codes.h" /* For CODE_FOR_xxx. */ --+#include "reload.h" /* For push_reload(). */ --+#include "flags.h" --+#include "input.h" --+#include "function.h" --+#include "expr.h" --+#include "recog.h" --+#include "diagnostic-core.h" --+#include "dominance.h" --+#include "cfg.h" --+#include "cfgrtl.h" --+#include "cfganal.h" --+#include "lcm.h" --+#include "cfgbuild.h" --+#include "cfgcleanup.h" --+#include "predict.h" --+#include "basic-block.h" --+#include "nds32-protos.h" --+ --+namespace nds32 { --+ --+/* Get the rtx in the PATTERN field of an insn. If INSN is not an insn, --+ the funciton doesn't change anything and returns it directly. */ --+rtx --+extract_pattern_from_insn (rtx insn) --+{ --+ if (INSN_P (insn)) --+ return PATTERN (insn); --+ --+ return insn; --+} --+ --+/* Get the number of elements in a parallel rtx. */ --+size_t --+parallel_elements (rtx parallel_rtx) --+{ --+ parallel_rtx = extract_pattern_from_insn (parallel_rtx); --+ gcc_assert (GET_CODE (parallel_rtx) == PARALLEL); --+ --+ return XVECLEN (parallel_rtx, 0); --+} --+ --+/* Extract an rtx from a parallel rtx with index NTH. If NTH is a negative --+ value, the function returns the last NTH rtx. */ --+rtx --+parallel_element (rtx parallel_rtx, int nth) --+{ --+ parallel_rtx = extract_pattern_from_insn (parallel_rtx); --+ gcc_assert (GET_CODE (parallel_rtx) == PARALLEL); --+ --+ int len = parallel_elements (parallel_rtx); --+ --+ if (nth >= 0) --+ { --+ if (nth >= len) --+ return NULL_RTX; --+ --+ return XVECEXP (parallel_rtx, 0, nth); --+ } --+ else --+ { --+ if (len + nth < 0) --+ return NULL_RTX; --+ --+ return XVECEXP (parallel_rtx, 0, len + nth); --+ } --+} --+ --+/* Return true if an insn is a pseudo NOP that is not a real instruction --+ occupying a real cycle and space of the text section. */ --+bool --+insn_pseudo_nop_p (rtx_insn *insn) --+{ --+ if (INSN_CODE (insn) == CODE_FOR_nop_data_dep --+ || INSN_CODE (insn) == CODE_FOR_nop_res_dep) --+ return true; --+ --+ return false; --+} --+ --+/* Indicate whether an insn is a real insn which occupy at least one cycle --+ or not. The determination cannot be target-independent because some targets --+ use UNSPEC or UNSPEC_VOLATILE insns to represent real instructions. */ --+bool --+insn_executable_p (rtx_insn *insn) --+{ --+ if (!INSN_P (insn)) --+ return false; --+ --+ if (insn_pseudo_nop_p (insn)) --+ return true; --+ --+ if (get_attr_length (insn) == 0) --+ return false; --+ --+ switch (GET_CODE (PATTERN (insn))) --+ { --+ case CONST_INT: --+ case USE: --+ case CLOBBER: --+ case ADDR_VEC: --+ case ADDR_DIFF_VEC: --+ case UNSPEC: --+ case UNSPEC_VOLATILE: --+ return false; --+ --+ default: --+ return true; --+ } --+ --+ return true; --+} --+ --+/* Find the previous executable insn. */ --+rtx_insn * --+prev_executable_insn (rtx_insn *insn) --+{ --+ insn = PREV_INSN (insn); --+ while (insn && !insn_executable_p (insn)) --+ insn = PREV_INSN (insn); --+ --+ return insn; --+} --+ --+/* Find the next executable insn. */ --+rtx_insn * --+next_executable_insn (rtx_insn *insn) --+{ --+ insn = NEXT_INSN (insn); --+ while (insn && !insn_executable_p (insn)) --+ insn = NEXT_INSN (insn); --+ --+ return insn; --+} --+ --+/* Find the previous executable insn in the current basic block. */ --+rtx_insn * --+prev_executable_insn_local (rtx_insn *insn) --+{ --+ insn = PREV_INSN (insn); --+ while (insn && !insn_executable_p (insn)) --+ { --+ if(LABEL_P (insn) || JUMP_P (insn) || CALL_P (insn)) --+ return NULL; --+ --+ insn = PREV_INSN (insn); --+ } --+ --+ return insn; --+} --+ --+/* Find the next executable insn in the current basic block. */ --+rtx_insn * --+next_executable_insn_local (rtx_insn *insn) --+{ --+ insn = NEXT_INSN (insn); --+ while (insn && !insn_executable_p (insn)) --+ { --+ if(LABEL_P (insn) || JUMP_P (insn) || CALL_P (insn)) --+ return NULL; --+ --+ insn = NEXT_INSN (insn); --+ } --+ --+ return insn; --+} --+ --+/* Return true if an insn is marked as deleted. */ --+bool --+insn_deleted_p (rtx_insn *insn) --+{ --+ if (insn->deleted ()) --+ return true; --+ --+ if (NOTE_P (insn) && NOTE_KIND (insn) == NOTE_INSN_DELETED) --+ return true; --+ --+ return false; --+} --+ --+/* Functions to determine whether INSN is single-word, double-word --+ or partial-word load/store insn. */ --+ --+bool --+load_single_p (rtx_insn *insn) --+{ --+ if (get_attr_type (insn) != TYPE_LOAD) --+ return false; --+ --+ if (INSN_CODE (insn) == CODE_FOR_move_di || --+ INSN_CODE (insn) == CODE_FOR_move_df) --+ return false; --+ --+ return true; --+} --+ --+bool --+store_single_p (rtx_insn *insn) --+{ --+ if (get_attr_type (insn) != TYPE_STORE) --+ return false; --+ --+ if (INSN_CODE (insn) == CODE_FOR_move_di || --+ INSN_CODE (insn) == CODE_FOR_move_df) --+ return false; --+ --+ return true; --+} --+ --+bool --+load_double_p (rtx_insn *insn) --+{ --+ if (get_attr_type (insn) != TYPE_LOAD) --+ return false; --+ --+ if (INSN_CODE (insn) != CODE_FOR_move_di && --+ INSN_CODE (insn) != CODE_FOR_move_df) --+ return false; --+ --+ return true; --+} --+ --+bool --+store_double_p (rtx_insn *insn) --+{ --+ if (get_attr_type (insn) != TYPE_STORE) --+ return false; --+ --+ if (INSN_CODE (insn) != CODE_FOR_move_di && --+ INSN_CODE (insn) != CODE_FOR_move_df) --+ return false; --+ --+ return true; --+} --+ --+bool --+store_offset_reg_p (rtx_insn *insn) --+{ --+ if (get_attr_type (insn) != TYPE_STORE) --+ return false; --+ --+ rtx offset_rtx = extract_offset_rtx (insn); --+ --+ if (offset_rtx == NULL_RTX) --+ return false; --+ --+ if (REG_P (offset_rtx)) --+ return true; --+ --+ return false; --+} --+ --+bool --+load_full_word_p (rtx_insn *insn) --+{ --+ if (!nds32::load_single_p (insn)) --+ return false; --+ --+ if (GET_MODE (SET_SRC (PATTERN (insn))) == SImode) --+ return true; --+ --+ return false; --+} --+ --+bool --+load_partial_word_p (rtx_insn *insn) --+{ --+ if (!nds32::load_single_p (insn)) --+ return false; --+ --+ if (GET_MODE (SET_SRC (PATTERN (insn))) == HImode --+ || GET_MODE (SET_SRC (PATTERN (insn))) == QImode) --+ return true; --+ --+ return false; --+} --+ --+/* Determine if INSN is a post update insn. */ --+bool --+post_update_insn_p (rtx_insn *insn) --+{ --+ if (find_post_update_rtx (insn) == -1) --+ return false; --+ else --+ return true; --+} --+ --+/* Check if the address of MEM_RTX consists of a base register and an --+ immediate offset. */ --+bool --+immed_offset_p (rtx mem_rtx) --+{ --+ gcc_assert (MEM_P (mem_rtx)); --+ --+ rtx addr_rtx = XEXP (mem_rtx, 0); --+ --+ /* (mem (reg)) is equivalent to (mem (plus (reg) (const_int 0))) */ --+ if (REG_P (addr_rtx)) --+ return true; --+ --+ /* (mem (plus (reg) (const_int))) */ --+ if (GET_CODE (addr_rtx) == PLUS --+ && GET_CODE (XEXP (addr_rtx, 1)) == CONST_INT) --+ return true; --+ --+ return false; --+} --+ --+/* Find the post update rtx in INSN. If INSN is a load/store multiple insn, --+ the function returns the vector index of its parallel part. If INSN is a --+ single load/store insn, the function returns 0. If INSN is not a post- --+ update insn, the function returns -1. */ --+int --+find_post_update_rtx (rtx_insn *insn) --+{ --+ rtx mem_rtx; --+ int i, len; --+ --+ switch (get_attr_type (insn)) --+ { --+ case TYPE_LOAD_MULTIPLE: --+ case TYPE_STORE_MULTIPLE: --+ /* Find a pattern in a parallel rtx: --+ (set (reg) (plus (reg) (const_int))) */ --+ len = parallel_elements (insn); --+ for (i = 0; i < len; ++i) --+ { --+ rtx curr_insn = parallel_element (insn, i); --+ --+ if (GET_CODE (curr_insn) == SET --+ && REG_P (SET_DEST (curr_insn)) --+ && GET_CODE (SET_SRC (curr_insn)) == PLUS) --+ return i; --+ } --+ return -1; --+ --+ case TYPE_LOAD: --+ case TYPE_FLOAD: --+ case TYPE_STORE: --+ case TYPE_FSTORE: --+ mem_rtx = extract_mem_rtx (insn); --+ /* (mem (post_inc (reg))) */ --+ switch (GET_CODE (XEXP (mem_rtx, 0))) --+ { --+ case POST_INC: --+ case POST_DEC: --+ case POST_MODIFY: --+ return 0; --+ --+ default: --+ return -1; --+ } --+ --+ default: --+ gcc_unreachable (); --+ } --+} --+ --+/* Extract the MEM rtx from a load/store insn. */ --+rtx --+extract_mem_rtx (rtx_insn *insn) --+{ --+ rtx body = PATTERN (insn); --+ --+ switch (get_attr_type (insn)) --+ { --+ case TYPE_LOAD: --+ case TYPE_FLOAD: --+ if (MEM_P (SET_SRC (body))) --+ return SET_SRC (body); --+ --+ /* unaligned address: (unspec [(mem)]) */ --+ if (GET_CODE (SET_SRC (body)) == UNSPEC) --+ { --+ gcc_assert (MEM_P (XVECEXP (SET_SRC (body), 0, 0))); --+ return XVECEXP (SET_SRC (body), 0, 0); --+ } --+ --+ /* (sign_extend (mem)) */ --+ gcc_assert (MEM_P (XEXP (SET_SRC (body), 0))); --+ return XEXP (SET_SRC (body), 0); --+ --+ case TYPE_STORE: --+ case TYPE_FSTORE: --+ if (MEM_P (SET_DEST (body))) --+ return SET_DEST (body); --+ --+ /* unaligned address: (unspec [(mem)]) */ --+ if (GET_CODE (SET_DEST (body)) == UNSPEC) --+ { --+ gcc_assert (MEM_P (XVECEXP (SET_DEST (body), 0, 0))); --+ return XVECEXP (SET_DEST (body), 0, 0); --+ } --+ --+ /* (sign_extend (mem)) */ --+ gcc_assert (MEM_P (XEXP (SET_DEST (body), 0))); --+ return XEXP (SET_DEST (body), 0); --+ --+ default: --+ gcc_unreachable (); --+ } --+} --+ --+/* Extract the base register from load/store insns. The function returns --+ NULL_RTX if the address is not consist of any registers. */ --+rtx --+extract_base_reg (rtx_insn *insn) --+{ --+ int post_update_rtx_index; --+ rtx mem_rtx; --+ rtx plus_rtx; --+ --+ /* Find the MEM rtx. If we can find an insn updating the base register, --+ the base register will be returned directly. */ --+ switch (get_attr_type (insn)) --+ { --+ case TYPE_LOAD_MULTIPLE: --+ post_update_rtx_index = find_post_update_rtx (insn); --+ --+ if (post_update_rtx_index != -1) --+ return SET_DEST (parallel_element (insn, post_update_rtx_index)); --+ --+ mem_rtx = SET_SRC (parallel_element (insn, 0)); --+ break; --+ --+ case TYPE_STORE_MULTIPLE: --+ post_update_rtx_index = find_post_update_rtx (insn); --+ --+ if (post_update_rtx_index != -1) --+ return SET_DEST (parallel_element (insn, post_update_rtx_index)); --+ --+ mem_rtx = SET_DEST (parallel_element (insn, 0)); --+ break; --+ --+ case TYPE_LOAD: --+ case TYPE_FLOAD: --+ case TYPE_STORE: --+ case TYPE_FSTORE: --+ mem_rtx = extract_mem_rtx (insn); --+ break; --+ --+ default: --+ gcc_unreachable (); --+ } --+ --+ gcc_assert (MEM_P (mem_rtx)); --+ --+ /* (mem (reg)) */ --+ if (REG_P (XEXP (mem_rtx, 0))) --+ return XEXP (mem_rtx, 0); --+ --+ /* (mem (lo_sum (reg) (symbol_ref)) */ --+ if (GET_CODE (XEXP (mem_rtx, 0)) == LO_SUM) --+ return XEXP (XEXP (mem_rtx, 0), 0); --+ --+ plus_rtx = XEXP (mem_rtx, 0); --+ --+ if (GET_CODE (plus_rtx) == SYMBOL_REF --+ || GET_CODE (plus_rtx) == CONST) --+ return NULL_RTX; --+ --+ /* (mem (plus (reg) (const_int))) or --+ (mem (plus (mult (reg) (const_int 4)) (reg))) or --+ (mem (post_inc (reg))) or --+ (mem (post_dec (reg))) or --+ (mem (post_modify (reg) (plus (reg) (reg)))) */ --+ gcc_assert (GET_CODE (plus_rtx) == PLUS --+ || GET_CODE (plus_rtx) == POST_INC --+ || GET_CODE (plus_rtx) == POST_DEC --+ || GET_CODE (plus_rtx) == POST_MODIFY); --+ --+ if (REG_P (XEXP (plus_rtx, 0))) --+ return XEXP (plus_rtx, 0); --+ --+ gcc_assert (REG_P (XEXP (plus_rtx, 1))); --+ return XEXP (plus_rtx, 1); --+} --+ --+/* Extract the offset rtx from load/store insns. The function returns --+ NULL_RTX if offset is absent. */ --+rtx --+extract_offset_rtx (rtx_insn *insn) --+{ --+ rtx mem_rtx; --+ rtx plus_rtx; --+ rtx offset_rtx; --+ --+ /* Find the MEM rtx. The multiple load/store insns doens't have --+ the offset field so we can return NULL_RTX here. */ --+ switch (get_attr_type (insn)) --+ { --+ case TYPE_LOAD_MULTIPLE: --+ case TYPE_STORE_MULTIPLE: --+ return NULL_RTX; --+ --+ case TYPE_LOAD: --+ case TYPE_FLOAD: --+ case TYPE_STORE: --+ case TYPE_FSTORE: --+ mem_rtx = extract_mem_rtx (insn); --+ break; --+ --+ default: --+ gcc_unreachable (); --+ } --+ --+ gcc_assert (MEM_P (mem_rtx)); --+ --+ /* (mem (reg)) */ --+ if (REG_P (XEXP (mem_rtx, 0))) --+ return NULL_RTX; --+ --+ plus_rtx = XEXP (mem_rtx, 0); --+ --+ switch (GET_CODE (plus_rtx)) --+ { --+ case SYMBOL_REF: --+ case CONST: --+ case POST_INC: --+ case POST_DEC: --+ return NULL_RTX; --+ --+ case PLUS: --+ /* (mem (plus (reg) (const_int))) or --+ (mem (plus (mult (reg) (const_int 4)) (reg))) */ --+ if (REG_P (XEXP (plus_rtx, 0))) --+ offset_rtx = XEXP (plus_rtx, 1); --+ else --+ { --+ gcc_assert (REG_P (XEXP (plus_rtx, 1))); --+ offset_rtx = XEXP (plus_rtx, 0); --+ } --+ --+ if (ARITHMETIC_P (offset_rtx)) --+ { --+ gcc_assert (GET_CODE (offset_rtx) == MULT); --+ gcc_assert (REG_P (XEXP (offset_rtx, 0))); --+ offset_rtx = XEXP (offset_rtx, 0); --+ } --+ break; --+ --+ case LO_SUM: --+ /* (mem (lo_sum (reg) (symbol_ref)) */ --+ offset_rtx = XEXP (plus_rtx, 1); --+ break; --+ --+ case POST_MODIFY: --+ /* (mem (post_modify (reg) (plus (reg) (reg / const_int)))) */ --+ gcc_assert (REG_P (XEXP (plus_rtx, 0))); --+ plus_rtx = XEXP (plus_rtx, 1); --+ gcc_assert (GET_CODE (plus_rtx) == PLUS); --+ offset_rtx = XEXP (plus_rtx, 0); --+ break; --+ --+ default: --+ gcc_unreachable (); --+ } --+ --+ return offset_rtx; --+} --+ --+/* Extract the register of the shift operand from an ALU_SHIFT rtx. */ --+rtx --+extract_shift_reg (rtx_insn *insn) --+{ --+ rtx alu_shift_rtx = extract_pattern_from_insn (insn); --+ --+ rtx alu_rtx = SET_SRC (alu_shift_rtx); --+ rtx shift_rtx; --+ --+ /* Various forms of ALU_SHIFT can be made by the combiner. --+ See the difference between add_slli and sub_slli in nds32.md. */ --+ if (REG_P (XEXP (alu_rtx, 0))) --+ shift_rtx = XEXP (alu_rtx, 1); --+ else --+ shift_rtx = XEXP (alu_rtx, 0); --+ --+ return XEXP (shift_rtx, 0); --+} --+ --+/* Check if INSN is a movd44 insn. */ --+bool --+movd44_insn_p (rtx_insn *insn) --+{ --+ if (get_attr_type (insn) == TYPE_ALU --+ && (INSN_CODE (insn) == CODE_FOR_move_di --+ || INSN_CODE (insn) == CODE_FOR_move_df)) --+ { --+ rtx body = PATTERN (insn); --+ gcc_assert (GET_CODE (body) == SET); --+ --+ rtx src = SET_SRC (body); --+ rtx dest = SET_DEST (body); --+ --+ if ((REG_P (src) || GET_CODE (src) == SUBREG) --+ && (REG_P (dest) || GET_CODE (dest) == SUBREG)) --+ return true; --+ --+ return false; --+ } --+ --+ return false; --+} --+ --+/* Extract the first result (even reg) of a movd44 insn. */ --+rtx --+extract_movd44_even_reg (rtx_insn *insn) --+{ --+ gcc_assert (movd44_insn_p (insn)); --+ --+ rtx def_reg = SET_DEST (PATTERN (insn)); --+ enum machine_mode mode; --+ --+ gcc_assert (REG_P (def_reg) || GET_CODE (def_reg) == SUBREG); --+ switch (GET_MODE (def_reg)) --+ { --+ case DImode: --+ mode = SImode; --+ break; --+ --+ case DFmode: --+ mode = SFmode; --+ break; --+ --+ default: --+ gcc_unreachable (); --+ } --+ --+ return gen_lowpart (mode, def_reg); --+} --+ --+/* Extract the second result (odd reg) of a movd44 insn. */ --+rtx --+extract_movd44_odd_reg (rtx_insn *insn) --+{ --+ gcc_assert (movd44_insn_p (insn)); --+ --+ rtx def_reg = SET_DEST (PATTERN (insn)); --+ enum machine_mode mode; --+ --+ gcc_assert (REG_P (def_reg) || GET_CODE (def_reg) == SUBREG); --+ switch (GET_MODE (def_reg)) --+ { --+ case DImode: --+ mode = SImode; --+ break; --+ --+ case DFmode: --+ mode = SFmode; --+ break; --+ --+ default: --+ gcc_unreachable (); --+ } --+ --+ return gen_highpart (mode, def_reg); --+} --+ --+/* Extract the rtx representing the accumulation operand of a MAC insn. */ --+rtx --+extract_mac_acc_rtx (rtx_insn *insn) --+{ --+ return SET_DEST (PATTERN (insn)); --+} --+ --+/* Extract the rtx representing non-accumulation operands of a MAC insn. */ --+rtx --+extract_mac_non_acc_rtx (rtx_insn *insn) --+{ --+ rtx exp = SET_SRC (PATTERN (insn)); --+ --+ switch (get_attr_type (insn)) --+ { --+ case TYPE_MAC: --+ case TYPE_DMAC: --+ if (REG_P (XEXP (exp, 0))) --+ return XEXP (exp, 1); --+ else --+ return XEXP (exp, 0); --+ --+ default: --+ gcc_unreachable (); --+ } --+} --+ --+/* Check if the DIV insn needs two write ports. */ --+bool --+divmod_p (rtx_insn *insn) --+{ --+ gcc_assert (get_attr_type (insn) == TYPE_DIV); --+ --+ if (INSN_CODE (insn) == CODE_FOR_divmodsi4 --+ || INSN_CODE (insn) == CODE_FOR_udivmodsi4) --+ return true; --+ --+ return false; --+} --+ --+/* Extract the rtx representing the branch target to help recognize --+ data hazards. */ --+rtx --+extract_branch_target_rtx (rtx_insn *insn) --+{ --+ gcc_assert (CALL_P (insn) || JUMP_P (insn)); --+ --+ rtx body = PATTERN (insn); --+ --+ if (GET_CODE (body) == SET) --+ { --+ /* RTXs in IF_THEN_ELSE are branch conditions. */ --+ if (GET_CODE (SET_SRC (body)) == IF_THEN_ELSE) --+ return NULL_RTX; --+ --+ return SET_SRC (body); --+ } --+ --+ if (GET_CODE (body) == CALL) --+ return XEXP (body, 0); --+ --+ if (GET_CODE (body) == PARALLEL) --+ { --+ rtx first_rtx = parallel_element (body, 0); --+ --+ if (GET_CODE (first_rtx) == SET) --+ return SET_SRC (first_rtx); --+ --+ if (GET_CODE (first_rtx) == CALL) --+ return XEXP (first_rtx, 0); --+ } --+ --+ /* Handle special cases of bltzal, bgezal and jralnez. */ --+ if (GET_CODE (body) == COND_EXEC) --+ { --+ rtx addr_rtx = XEXP (body, 1); --+ --+ if (GET_CODE (addr_rtx) == SET) --+ return SET_SRC (addr_rtx); --+ --+ if (GET_CODE (addr_rtx) == PARALLEL) --+ { --+ rtx first_rtx = parallel_element (addr_rtx, 0); --+ --+ if (GET_CODE (first_rtx) == SET) --+ { --+ rtx call_rtx = SET_SRC (first_rtx); --+ gcc_assert (GET_CODE (call_rtx) == CALL); --+ --+ return XEXP (call_rtx, 0); --+ } --+ --+ if (GET_CODE (first_rtx) == CALL) --+ return XEXP (first_rtx, 0); --+ } --+ } --+ --+ gcc_unreachable (); --+} --+ --+/* Extract the rtx representing the branch condition to help recognize --+ data hazards. */ --+rtx --+extract_branch_condition_rtx (rtx_insn *insn) --+{ --+ gcc_assert (CALL_P (insn) || JUMP_P (insn)); --+ --+ rtx body = PATTERN (insn); --+ --+ if (GET_CODE (body) == SET) --+ { --+ rtx if_then_else_rtx = SET_SRC (body); --+ --+ if (GET_CODE (if_then_else_rtx) == IF_THEN_ELSE) --+ return XEXP (if_then_else_rtx, 0); --+ --+ return NULL_RTX; --+ } --+ --+ if (GET_CODE (body) == COND_EXEC) --+ return XEXP (body, 0); --+ --+ return NULL_RTX; --+} --+ --+/* Building the CFG in later back end passes cannot call compute_bb_for_insn () --+ directly because calling to BLOCK_FOR_INSN (insn) when some insns have been --+ deleted can cause a segmentation fault. Use this function to rebuild the CFG --+ can avoid such issues. */ --+void --+compute_bb_for_insn_safe () --+{ --+ basic_block bb; --+ --+ FOR_EACH_BB_FN (bb, cfun) --+ { --+ rtx_insn *insn, *next_insn, *last_insn; --+ bool after_last_insn = false; --+ --+ /* Find the last non-deleted insn. */ --+ for (last_insn = BB_END (bb); --+ PREV_INSN (last_insn) && insn_deleted_p (last_insn); --+ last_insn = PREV_INSN (last_insn)); --+ --+ /* Bind each insn to its BB and adjust BB_END (bb). */ --+ for (insn = BB_HEAD (bb); insn; insn = NEXT_INSN (insn)) --+ { --+ BLOCK_FOR_INSN (insn) = bb; --+ --+ if (insn == last_insn) --+ after_last_insn = true; --+ --+ next_insn = NEXT_INSN (insn); --+ --+ if (after_last_insn --+ && (!next_insn --+ || LABEL_P (next_insn) --+ || NOTE_INSN_BASIC_BLOCK_P (next_insn))) --+ { --+ BB_END (bb) = insn; --+ break; --+ } --+ } --+ } --+} --+ --+/* Exchange insns positions. */ --+void --+exchange_insns (rtx_insn *insn1, rtx_insn *insn2) --+{ --+ if (INSN_UID (insn1) == INSN_UID (insn2)) --+ return; --+ --+ rtx_insn *insn1_from = insn1; --+ rtx_insn *insn1_to = insn1; --+ rtx_insn *insn2_from = insn2; --+ rtx_insn *insn2_to = insn2; --+ --+ if (PREV_INSN (insn1) --+ && INSN_CODE (PREV_INSN (insn1)) == CODE_FOR_relax_group) --+ insn1_from = PREV_INSN (insn1); --+ --+ if (PREV_INSN (insn2) --+ && INSN_CODE (PREV_INSN (insn2)) == CODE_FOR_relax_group) --+ insn2_from = PREV_INSN (insn2); --+ --+ if (GET_MODE (insn1) == TImode && GET_MODE (insn2) == VOIDmode) --+ { --+ PUT_MODE (insn1, VOIDmode); --+ PUT_MODE (insn2, TImode); --+ } --+ else if (GET_MODE (insn1) == VOIDmode && GET_MODE (insn2) == TImode) --+ { --+ PUT_MODE (insn1, TImode); --+ PUT_MODE (insn2, VOIDmode); --+ } --+ --+ if (PREV_INSN (insn1_from)) --+ { --+ rtx_insn *insn1_prev = PREV_INSN (insn1_from); --+ --+ reorder_insns (insn1_from, insn1_to, insn2); --+ reorder_insns (insn2_from, insn2_to, insn1_prev); --+ --+ return; --+ } --+ --+ gcc_assert (PREV_INSN (insn2_from)); --+ --+ rtx_insn *insn2_prev = PREV_INSN (insn2_from); --+ --+ reorder_insns (insn2_from, insn2_to, insn1); --+ reorder_insns (insn1_from, insn1_to, insn2_prev); --+ --+ return; --+} --+ --+} // namespace nds32 --diff --git a/gcc/config/nds32/nds32.c b/gcc/config/nds32/nds32.c --index c47c122..5f5e668 100644 ----- a/gcc/config/nds32/nds32.c --+++ b/gcc/config/nds32/nds32.c --@@ -24,48 +24,103 @@ -- #include "system.h" -- #include "coretypes.h" -- #include "backend.h" ---#include "target.h" ---#include "rtl.h" -- #include "tree.h" --+#include "rtl.h" -- #include "df.h" ---#include "tm_p.h" ---#include "optabs.h" /* For GEN_FCN. */ ---#include "regs.h" ---#include "emit-rtl.h" ---#include "recog.h" ---#include "diagnostic-core.h" --+#include "alias.h" --+#include "stringpool.h" -- #include "stor-layout.h" -- #include "varasm.h" -- #include "calls.h" --+#include "regs.h" --+#include "insn-config.h" /* Required by recog.h. */ --+#include "conditions.h" -- #include "output.h" --+#include "insn-attr.h" /* For DFA state_t. */ --+#include "insn-codes.h" /* For CODE_FOR_xxx. */ --+#include "reload.h" /* For push_reload(). */ --+#include "flags.h" --+#include "insn-config.h" --+#include "expmed.h" --+#include "dojump.h" -- #include "explow.h" --+#include "emit-rtl.h" --+#include "stmt.h" -- #include "expr.h" --+#include "recog.h" --+#include "diagnostic-core.h" --+#include "cfgrtl.h" --+#include "cfganal.h" --+#include "lcm.h" --+#include "cfgbuild.h" --+#include "cfgcleanup.h" --+#include "tm_p.h" -- #include "tm-constrs.h" --+#include "optabs.h" /* For GEN_FCN. */ --+#include "target.h" --+#include "langhooks.h" /* For add_builtin_function(). */ -- #include "builtins.h" --+#include "cpplib.h" --+#include "params.h" --+#include "tree-pass.h" --+#include "cfgloop.h" --+#include "cfghooks.h" --+#include "hw-doloop.h" --+#include "context.h" --+#include "sched-int.h" -- -- /* This file should be included last. */ -- #include "target-def.h" -- -- /* ------------------------------------------------------------------------ */ -- ---/* This file is divided into five parts: --+/* This file is divided into six parts: -- --- PART 1: Auxiliary static variable definitions and --- target hook static variable definitions. --+ PART 1: Auxiliary external function and variable declarations. -- --- PART 2: Auxiliary static function definitions. --+ PART 2: Auxiliary static variable definitions and --+ target hook static variable definitions. -- --- PART 3: Implement target hook stuff definitions. --+ PART 3: Auxiliary static function definitions. -- --- PART 4: Implemet extern function definitions, --- the prototype is in nds32-protos.h. --+ PART 4: Implement target hook stuff definitions. -- --- PART 5: Initialize target hook structure and definitions. */ --+ PART 5: Implemet extern function definitions, --+ the prototype is in nds32-protos.h. --+ --+ PART 6: Initialize target hook structure and definitions. */ --+ --+/* ------------------------------------------------------------------------ */ --+ --+/* PART 1: Auxiliary function and variable declarations. */ --+ --+namespace nds32 { --+namespace scheduling { --+ --+rtl_opt_pass *make_pass_nds32_print_stalls (gcc::context *); --+ --+} // namespace scheduling --+} // namespace nds32 --+ --+rtl_opt_pass *make_pass_nds32_fp_as_gp (gcc::context *); --+rtl_opt_pass *make_pass_nds32_load_store_opt (gcc::context *); --+rtl_opt_pass *make_pass_nds32_soft_fp_arith_comm_opt(gcc::context *); --+rtl_opt_pass *make_pass_nds32_regrename_opt (gcc::context *); --+rtl_opt_pass *make_pass_nds32_gcse_opt (gcc::context *); --+rtl_opt_pass *make_pass_nds32_relax_opt (gcc::context *); --+rtl_opt_pass *make_pass_nds32_rename_lmwsmw_opt (gcc::context *); --+rtl_opt_pass *make_pass_nds32_gen_lmwsmw_opt (gcc::context *); --+rtl_opt_pass *make_pass_nds32_const_remater_opt (gcc::context *); --+rtl_opt_pass *make_pass_nds32_cprop_acc_opt (gcc::context *); --+ --+gimple_opt_pass *make_pass_nds32_sign_conversion_opt (gcc::context *); --+gimple_opt_pass *make_pass_nds32_scalbn_transform_opt (gcc::context *); --+gimple_opt_pass *make_pass_nds32_abi_compatible (gcc::context *); -- -- /* ------------------------------------------------------------------------ */ -- ---/* PART 1: Auxiliary static variable definitions and --- target hook static variable definitions. */ --+/* PART 2: Auxiliary static variable definitions and --+ target hook static variable definitions. */ -- -- /* Define intrinsic register names. -- Please refer to nds32_intrinsic.h file, the index is corresponding to --@@ -73,14 +128,217 @@ -- NOTE that the base value starting from 1024. */ -- static const char * const nds32_intrinsic_register_names[] = -- { --- "$PSW", "$IPSW", "$ITYPE", "$IPC" --+ "$CPU_VER", --+ "$ICM_CFG", --+ "$DCM_CFG", --+ "$MMU_CFG", --+ "$MSC_CFG", --+ "$MSC_CFG2", --+ "$CORE_ID", --+ "$FUCOP_EXIST", --+ --+ "$PSW", --+ "$IPSW", --+ "$P_IPSW", --+ "$IVB", --+ "$EVA", --+ "$P_EVA", --+ "$ITYPE", --+ "$P_ITYPE", --+ --+ "$MERR", --+ "$IPC", --+ "$P_IPC", --+ "$OIPC", --+ "$P_P0", --+ "$P_P1", --+ --+ "$INT_MASK", --+ "$INT_MASK2", --+ "$INT_MASK3", --+ "$INT_PEND", --+ "$INT_PEND2", --+ "$INT_PEND3", --+ "$SP_USR", --+ "$SP_PRIV", --+ "$INT_PRI", --+ "$INT_PRI2", --+ "$INT_PRI3", --+ "$INT_PRI4", --+ "$INT_CTRL", --+ "$INT_TRIGGER", --+ "$INT_TRIGGER2", --+ "$INT_GPR_PUSH_DIS", --+ --+ "$MMU_CTL", --+ "$L1_PPTB", --+ "$TLB_VPN", --+ "$TLB_DATA", --+ "$TLB_MISC", --+ "$VLPT_IDX", --+ "$ILMB", --+ "$DLMB", --+ --+ "$CACHE_CTL", --+ "$HSMP_SADDR", --+ "$HSMP_EADDR", --+ "$SDZ_CTL", --+ "$N12MISC_CTL", --+ "$MISC_CTL", --+ "$ECC_MISC", --+ --+ "$BPC0", --+ "$BPC1", --+ "$BPC2", --+ "$BPC3", --+ "$BPC4", --+ "$BPC5", --+ "$BPC6", --+ "$BPC7", --+ --+ "$BPA0", --+ "$BPA1", --+ "$BPA2", --+ "$BPA3", --+ "$BPA4", --+ "$BPA5", --+ "$BPA6", --+ "$BPA7", --+ --+ "$BPAM0", --+ "$BPAM1", --+ "$BPAM2", --+ "$BPAM3", --+ "$BPAM4", --+ "$BPAM5", --+ "$BPAM6", --+ "$BPAM7", --+ --+ "$BPV0", --+ "$BPV1", --+ "$BPV2", --+ "$BPV3", --+ "$BPV4", --+ "$BPV5", --+ "$BPV6", --+ "$BPV7", --+ --+ "$BPCID0", --+ "$BPCID1", --+ "$BPCID2", --+ "$BPCID3", --+ "$BPCID4", --+ "$BPCID5", --+ "$BPCID6", --+ "$BPCID7", --+ --+ "$EDM_CFG", --+ "$EDMSW", --+ "$EDM_CTL", --+ "$EDM_DTR", --+ "$BPMTC", --+ "$DIMBR", --+ --+ "$TECR0", --+ "$TECR1", --+ "$PFMC0", --+ "$PFMC1", --+ "$PFMC2", --+ "$PFM_CTL", --+ "$PFT_CTL", --+ "$HSP_CTL", --+ "$SP_BOUND", --+ "$SP_BOUND_PRIV", --+ "$SP_BASE", --+ "$SP_BASE_PRIV", --+ "$FUCOP_CTL", --+ "$PRUSR_ACC_CTL", --+ --+ "$DMA_CFG", --+ "$DMA_GCSW", --+ "$DMA_CHNSEL", --+ "$DMA_ACT", --+ "$DMA_SETUP", --+ "$DMA_ISADDR", --+ "$DMA_ESADDR", --+ "$DMA_TCNT", --+ "$DMA_STATUS", --+ "$DMA_2DSET", --+ "$DMA_2DSCTL", --+ "$DMA_RCNT", --+ "$DMA_HSTATUS", --+ --+ "$PC", --+ "$SP_USR1", --+ "$SP_USR2", --+ "$SP_USR3", --+ "$SP_PRIV1", --+ "$SP_PRIV2", --+ "$SP_PRIV3", --+ "$BG_REGION", --+ "$SFCR", --+ "$SIGN", --+ "$ISIGN", --+ "$P_ISIGN", --+ "$IFC_LP", --+ "$ITB" --+}; --+ --+/* Define instrinsic cctl names. */ --+static const char * const nds32_cctl_names[] = --+{ --+ "L1D_VA_FILLCK", --+ "L1D_VA_ULCK", --+ "L1I_VA_FILLCK", --+ "L1I_VA_ULCK", --+ --+ "L1D_IX_WBINVAL", --+ "L1D_IX_INVAL", --+ "L1D_IX_WB", --+ "L1I_IX_INVAL", --+ --+ "L1D_VA_INVAL", --+ "L1D_VA_WB", --+ "L1D_VA_WBINVAL", --+ "L1I_VA_INVAL", --+ --+ "L1D_IX_RTAG", --+ "L1D_IX_RWD", --+ "L1I_IX_RTAG", --+ "L1I_IX_RWD", --+ --+ "L1D_IX_WTAG", --+ "L1D_IX_WWD", --+ "L1I_IX_WTAG", --+ "L1I_IX_WWD" --+}; --+ --+static const char * const nds32_dpref_names[] = --+{ --+ "SRD", --+ "MRD", --+ "SWR", --+ "MWR", --+ "PTE", --+ "CLWR" --+}; --+ --+/* Defining register allocation order for performance. --+ We want to allocate callee-saved registers after others. --+ It may be used by nds32_adjust_reg_alloc_order(). */ --+static const int nds32_reg_alloc_order_for_speed[] = --+{ --+ 0, 1, 2, 3, 4, 5, 16, 17, --+ 18, 19, 20, 21, 22, 23, 24, 25, --+ 26, 27, 6, 7, 8, 9, 10, 11, --+ 12, 13, 14, 15 -- }; -- -- /* Defining target-specific uses of __attribute__. */ -- static const struct attribute_spec nds32_attribute_table[] = -- { -- /* Syntax: { name, min_len, max_len, decl_required, type_required, --- function_type_required, handler, affects_type_identity } */ --+ function_type_required, handler, affects_type_identity } */ -- -- /* The interrupt vid: [0-63]+ (actual vector number starts from 9 to 72). */ -- { "interrupt", 1, 64, false, false, false, NULL, false }, --@@ -93,6 +351,7 @@ static const struct attribute_spec nds32_attribute_table[] = -- { "nested", 0, 0, false, false, false, NULL, false }, -- { "not_nested", 0, 0, false, false, false, NULL, false }, -- { "nested_ready", 0, 0, false, false, false, NULL, false }, --+ { "critical", 0, 0, false, false, false, NULL, false }, -- -- /* The attributes describing isr register save scheme. */ -- { "save_all", 0, 0, false, false, false, NULL, false }, --@@ -102,17 +361,32 @@ static const struct attribute_spec nds32_attribute_table[] = -- { "nmi", 1, 1, false, false, false, NULL, false }, -- { "warm", 1, 1, false, false, false, NULL, false }, -- --+ /* The attributes describing isr security level. */ --+ { "secure", 1, 1, false, false, false, NULL, false }, --+ -- /* The attribute telling no prologue/epilogue. */ -- { "naked", 0, 0, false, false, false, NULL, false }, -- --+ /* The attribute is used to set signature. */ --+ { "signature", 0, 0, false, false, false, NULL, false }, --+ --+ /* The attribute is used to tell this function to be ROM patch. */ --+ { "indirect_call",0, 0, false, false, false, NULL, false }, --+ --+ /* FOR BACKWARD COMPATIBILITY, --+ this attribute also tells no prologue/epilogue. */ --+ { "no_prologue", 0, 0, false, false, false, NULL, false }, --+ --+ /* The attribute turn off hwloop optimization. */ --+ { "no_ext_zol", 0, 0, false, false, false, NULL, false}, --+ -- /* The last attribute spec is set to be NULL. */ -- { NULL, 0, 0, false, false, false, NULL, false } -- }; -- --- -- /* ------------------------------------------------------------------------ */ -- ---/* PART 2: Auxiliary static function definitions. */ --+/* PART 3: Auxiliary static function definitions. */ -- -- /* Function to save and restore machine-specific function data. */ -- static struct machine_function * --@@ -121,12 +395,24 @@ nds32_init_machine_status (void) -- struct machine_function *machine; -- machine = ggc_cleared_alloc (); -- --+ /* Initially assume this function does not use __builtin_eh_return. */ --+ machine->use_eh_return_p = 0; --+ -- /* Initially assume this function needs prologue/epilogue. */ -- machine->naked_p = 0; -- -- /* Initially assume this function does NOT use fp_as_gp optimization. */ -- machine->fp_as_gp_p = 0; -- --+ /* Initially this function is not under strictly aligned situation. */ --+ machine->strict_aligned_p = 0; --+ --+ /* Initially this function has no naked and no_prologue attributes. */ --+ machine->attr_naked_p = 0; --+ machine->attr_no_prologue_p = 0; --+ --+ /* Initially this function hwloop group ID number. */ --+ machine->hwloop_group_id = 0; -- return machine; -- } -- --@@ -137,23 +423,63 @@ nds32_compute_stack_frame (void) -- { -- int r; -- int block_size; --+ bool v3pushpop_p; -- -- /* Because nds32_compute_stack_frame() will be called from different place, -- everytime we enter this function, we have to assume this function -- needs prologue/epilogue. */ -- cfun->machine->naked_p = 0; -- --+ /* We need to mark whether this function has naked and no_prologue --+ attribute so that we can distinguish the difference if users applies --+ -mret-in-naked-func option. */ --+ cfun->machine->attr_naked_p --+ = lookup_attribute ("naked", DECL_ATTRIBUTES (current_function_decl)) --+ ? 1 : 0; --+ cfun->machine->attr_no_prologue_p --+ = lookup_attribute ("no_prologue", DECL_ATTRIBUTES (current_function_decl)) --+ ? 1 : 0; --+ --+ /* If __builtin_eh_return is used, we better have frame pointer needed --+ so that we can easily locate the stack slot of return address. */ --+ if (crtl->calls_eh_return) --+ { --+ frame_pointer_needed = 1; --+ --+ /* We need to mark eh data registers that need to be saved --+ in the stack. */ --+ cfun->machine->eh_return_data_first_regno = EH_RETURN_DATA_REGNO (0); --+ for (r = 0; EH_RETURN_DATA_REGNO (r) != INVALID_REGNUM; r++) --+ cfun->machine->eh_return_data_last_regno = r; --+ --+ cfun->machine->eh_return_data_regs_size --+ = 4 * (cfun->machine->eh_return_data_last_regno --+ - cfun->machine->eh_return_data_first_regno --+ + 1); --+ cfun->machine->use_eh_return_p = 1; --+ } --+ else --+ { --+ /* Assigning SP_REGNUM to eh_first_regno and eh_last_regno means we --+ do not need to handle __builtin_eh_return case in this function. */ --+ cfun->machine->eh_return_data_first_regno = SP_REGNUM; --+ cfun->machine->eh_return_data_last_regno = SP_REGNUM; --+ --+ cfun->machine->eh_return_data_regs_size = 0; --+ cfun->machine->use_eh_return_p = 0; --+ } --+ -- /* Get variadic arguments size to prepare pretend arguments and -- we will push them into stack at prologue by ourself. */ -- cfun->machine->va_args_size = crtl->args.pretend_args_size; -- if (cfun->machine->va_args_size != 0) -- { -- cfun->machine->va_args_first_regno --- = NDS32_GPR_ARG_FIRST_REGNUM --- + NDS32_MAX_GPR_REGS_FOR_ARGS --- - (crtl->args.pretend_args_size / UNITS_PER_WORD); --+ = NDS32_GPR_ARG_FIRST_REGNUM --+ + NDS32_MAX_GPR_REGS_FOR_ARGS --+ - (crtl->args.pretend_args_size / UNITS_PER_WORD); -- cfun->machine->va_args_last_regno --- = NDS32_GPR_ARG_FIRST_REGNUM + NDS32_MAX_GPR_REGS_FOR_ARGS - 1; --+ = NDS32_GPR_ARG_FIRST_REGNUM + NDS32_MAX_GPR_REGS_FOR_ARGS - 1; -- } -- else -- { --@@ -183,11 +509,13 @@ nds32_compute_stack_frame (void) -- -- /* If $gp value is required to be saved on stack, it needs 4 bytes space. -- Check whether we are using PIC code genration. */ --- cfun->machine->gp_size = (flag_pic) ? 4 : 0; --+ cfun->machine->gp_size = --+ (flag_pic && df_regs_ever_live_p (PIC_OFFSET_TABLE_REGNUM)) ? 4 : 0; -- -- /* If $lp value is required to be saved on stack, it needs 4 bytes space. -- Check whether $lp is ever live. */ --- cfun->machine->lp_size = (df_regs_ever_live_p (LP_REGNUM)) ? 4 : 0; --+ cfun->machine->lp_size --+ = (flag_always_save_lp || df_regs_ever_live_p (LP_REGNUM)) ? 4 : 0; -- -- /* Initially there is no padding bytes. */ -- cfun->machine->callee_saved_area_gpr_padding_bytes = 0; --@@ -196,6 +524,10 @@ nds32_compute_stack_frame (void) -- cfun->machine->callee_saved_gpr_regs_size = 0; -- cfun->machine->callee_saved_first_gpr_regno = SP_REGNUM; -- cfun->machine->callee_saved_last_gpr_regno = SP_REGNUM; --+ cfun->machine->callee_saved_fpr_regs_size = 0; --+ cfun->machine->callee_saved_first_fpr_regno = SP_REGNUM; --+ cfun->machine->callee_saved_last_fpr_regno = SP_REGNUM; --+ -- /* Currently, there is no need to check $r28~$r31 -- because we will save them in another way. */ -- for (r = 0; r < 28; r++) --@@ -213,43 +545,77 @@ nds32_compute_stack_frame (void) -- } -- } -- --+ /* Recording fpu callee-saved register. */ --+ if (TARGET_HARD_FLOAT) --+ { --+ for (r = NDS32_FIRST_FPR_REGNUM; r < NDS32_LAST_FPR_REGNUM; r++) --+ { --+ if (NDS32_REQUIRED_CALLEE_SAVED_P (r)) --+ { --+ /* Mark the first required callee-saved register. */ --+ if (cfun->machine->callee_saved_first_fpr_regno == SP_REGNUM) --+ { --+ /* Make first callee-saved number is even, --+ bacause we use doubleword access, and this way --+ promise 8-byte alignemt. */ --+ if (!NDS32_FPR_REGNO_OK_FOR_DOUBLE (r)) --+ cfun->machine->callee_saved_first_fpr_regno = r - 1; --+ else --+ cfun->machine->callee_saved_first_fpr_regno = r; --+ } --+ cfun->machine->callee_saved_last_fpr_regno = r; --+ } --+ } --+ --+ /* Make last callee-saved register number is odd, --+ we hope callee-saved register is even. */ --+ int last_fpr = cfun->machine->callee_saved_last_fpr_regno; --+ if (NDS32_FPR_REGNO_OK_FOR_DOUBLE (last_fpr)) --+ cfun->machine->callee_saved_last_fpr_regno++; --+ } --+ -- /* Check if this function can omit prologue/epilogue code fragment. --- If there is 'naked' attribute in this function, --+ If there is 'no_prologue'/'naked'/'secure' attribute in this function, -- we can set 'naked_p' flag to indicate that -- we do not have to generate prologue/epilogue. -- Or, if all the following conditions succeed, -- we can set this function 'naked_p' as well: -- condition 1: first_regno == last_regno == SP_REGNUM, --- which means we do not have to save --- any callee-saved registers. --+ which means we do not have to save --+ any callee-saved registers. -- condition 2: Both $lp and $fp are NOT live in this function, --- which means we do not need to save them and there --- is no outgoing size. --+ which means we do not need to save them and there --+ is no outgoing size. -- condition 3: There is no local_size, which means --- we do not need to adjust $sp. */ --- if (lookup_attribute ("naked", DECL_ATTRIBUTES (current_function_decl)) --+ we do not need to adjust $sp. */ --+ if (lookup_attribute ("no_prologue", DECL_ATTRIBUTES (current_function_decl)) --+ || lookup_attribute ("naked", DECL_ATTRIBUTES (current_function_decl)) --+ || lookup_attribute ("secure", DECL_ATTRIBUTES (current_function_decl)) -- || (cfun->machine->callee_saved_first_gpr_regno == SP_REGNUM -- && cfun->machine->callee_saved_last_gpr_regno == SP_REGNUM --+ && cfun->machine->callee_saved_first_fpr_regno == SP_REGNUM --+ && cfun->machine->callee_saved_last_fpr_regno == SP_REGNUM -- && !df_regs_ever_live_p (FP_REGNUM) -- && !df_regs_ever_live_p (LP_REGNUM) --- && cfun->machine->local_size == 0)) --+ && cfun->machine->local_size == 0 --+ && !flag_pic)) -- { -- /* Set this function 'naked_p' and other functions can check this flag. --- Note that in nds32 port, the 'naked_p = 1' JUST means there is no --- callee-saved, local size, and outgoing size. --- The varargs space and ret instruction may still present in --- the prologue/epilogue expanding. */ --+ Note that in nds32 port, the 'naked_p = 1' JUST means there is no --+ callee-saved, local size, and outgoing size. --+ The varargs space and ret instruction may still present in --+ the prologue/epilogue expanding. */ -- cfun->machine->naked_p = 1; -- -- /* No need to save $fp, $gp, and $lp. --- We should set these value to be zero --- so that nds32_initial_elimination_offset() can work properly. */ --+ We should set these value to be zero --+ so that nds32_initial_elimination_offset() can work properly. */ -- cfun->machine->fp_size = 0; -- cfun->machine->gp_size = 0; -- cfun->machine->lp_size = 0; -- -- /* If stack usage computation is required, --- we need to provide the static stack size. */ --+ we need to provide the static stack size. */ -- if (flag_stack_usage_info) -- current_function_static_stack_size = 0; -- --@@ -257,6 +623,8 @@ nds32_compute_stack_frame (void) -- return; -- } -- --+ v3pushpop_p = NDS32_V3PUSH_AVAILABLE_P; --+ -- /* Adjustment for v3push instructions: -- If we are using v3push (push25/pop25) instructions, -- we need to make sure Rb is $r6 and Re is --@@ -264,16 +632,14 @@ nds32_compute_stack_frame (void) -- Some results above will be discarded and recomputed. -- Note that it is only available under V3/V3M ISA and we -- DO NOT setup following stuff for isr or variadic function. */ --- if (TARGET_V3PUSH --- && !nds32_isr_function_p (current_function_decl) --- && (cfun->machine->va_args_size == 0)) --+ if (v3pushpop_p) -- { -- /* Recompute: --- cfun->machine->fp_size --- cfun->machine->gp_size --- cfun->machine->lp_size --- cfun->machine->callee_saved_regs_first_regno --- cfun->machine->callee_saved_regs_last_regno */ --+ cfun->machine->fp_size --+ cfun->machine->gp_size --+ cfun->machine->lp_size --+ cfun->machine->callee_saved_first_gpr_regno --+ cfun->machine->callee_saved_last_gpr_regno */ -- -- /* For v3push instructions, $fp, $gp, and $lp are always saved. */ -- cfun->machine->fp_size = 4; --@@ -316,11 +682,46 @@ nds32_compute_stack_frame (void) -- } -- } -- --- /* We have correctly set callee_saved_regs_first_regno --- and callee_saved_regs_last_regno. --- Initially, the callee_saved_regs_size is supposed to be 0. --- As long as callee_saved_regs_last_regno is not SP_REGNUM, --- we can update callee_saved_regs_size with new size. */ --+ int sp_adjust = cfun->machine->local_size --+ + cfun->machine->out_args_size --+ + cfun->machine->callee_saved_area_gpr_padding_bytes --+ + cfun->machine->callee_saved_fpr_regs_size; --+ --+ if (!v3pushpop_p --+ && nds32_memory_model_option == MEMORY_MODEL_FAST --+ && sp_adjust == 0 --+ && !frame_pointer_needed) --+ { --+ block_size = cfun->machine->fp_size --+ + cfun->machine->gp_size --+ + cfun->machine->lp_size --+ + (4 * (cfun->machine->callee_saved_last_gpr_regno --+ - cfun->machine->callee_saved_first_gpr_regno --+ + 1)); --+ --+ if (!NDS32_DOUBLE_WORD_ALIGN_P (block_size)) --+ { --+ /* $r14 is last callee save register. */ --+ if (cfun->machine->callee_saved_last_gpr_regno --+ < NDS32_LAST_CALLEE_SAVE_GPR_REGNUM) --+ { --+ cfun->machine->callee_saved_last_gpr_regno++; --+ } --+ else if (cfun->machine->callee_saved_first_gpr_regno == SP_REGNUM) --+ { --+ cfun->machine->callee_saved_first_gpr_regno --+ = NDS32_FIRST_CALLEE_SAVE_GPR_REGNUM; --+ cfun->machine->callee_saved_last_gpr_regno --+ = NDS32_FIRST_CALLEE_SAVE_GPR_REGNUM; --+ } --+ } --+ } --+ --+ /* We have correctly set callee_saved_first_gpr_regno --+ and callee_saved_last_gpr_regno. --+ Initially, the callee_saved_gpr_regs_size is supposed to be 0. --+ As long as callee_saved_last_gpr_regno is not SP_REGNUM, --+ we can update callee_saved_gpr_regs_size with new size. */ -- if (cfun->machine->callee_saved_last_gpr_regno != SP_REGNUM) -- { -- /* Compute pushed size of callee-saved registers. */ --@@ -330,10 +731,22 @@ nds32_compute_stack_frame (void) -- + 1); -- } -- --+ if (TARGET_HARD_FLOAT) --+ { --+ /* Compute size of callee svaed floating-point registers. */ --+ if (cfun->machine->callee_saved_last_fpr_regno != SP_REGNUM) --+ { --+ cfun->machine->callee_saved_fpr_regs_size --+ = 4 * (cfun->machine->callee_saved_last_fpr_regno --+ - cfun->machine->callee_saved_first_fpr_regno --+ + 1); --+ } --+ } --+ -- /* Important: We need to make sure that --- (fp_size + gp_size + lp_size + callee_saved_regs_size) --- is 8-byte alignment. --- If it is not, calculate the padding bytes. */ --+ (fp_size + gp_size + lp_size + callee_saved_gpr_regs_size) --+ is 8-byte alignment. --+ If it is not, calculate the padding bytes. */ -- block_size = cfun->machine->fp_size -- + cfun->machine->gp_size -- + cfun->machine->lp_size --@@ -361,14 +774,15 @@ nds32_compute_stack_frame (void) -- "push registers to memory", -- "adjust stack pointer". */ -- static void ---nds32_emit_stack_push_multiple (rtx Rb, rtx Re, rtx En4, bool vaarg_p) --+nds32_emit_stack_push_multiple (unsigned Rb, unsigned Re, --+ bool save_fp_p, bool save_gp_p, bool save_lp_p, --+ bool vaarg_p) -- { --- int regno; --+ unsigned regno; -- int extra_count; -- int num_use_regs; -- int par_index; -- int offset; --- int save_fp, save_gp, save_lp; -- -- rtx reg; -- rtx mem; --@@ -381,39 +795,34 @@ nds32_emit_stack_push_multiple (rtx Rb, rtx Re, rtx En4, bool vaarg_p) -- necessary information for data analysis, -- so we create a parallel rtx like this: -- (parallel [(set (mem (plus (reg:SI SP_REGNUM) (const_int -32))) --- (reg:SI Rb)) --- (set (mem (plus (reg:SI SP_REGNUM) (const_int -28))) --- (reg:SI Rb+1)) --- ... --- (set (mem (plus (reg:SI SP_REGNUM) (const_int -16))) --- (reg:SI Re)) --- (set (mem (plus (reg:SI SP_REGNUM) (const_int -12))) --- (reg:SI FP_REGNUM)) --- (set (mem (plus (reg:SI SP_REGNUM) (const_int -8))) --- (reg:SI GP_REGNUM)) --- (set (mem (plus (reg:SI SP_REGNUM) (const_int -4))) --- (reg:SI LP_REGNUM)) --- (set (reg:SI SP_REGNUM) --- (plus (reg:SI SP_REGNUM) (const_int -32)))]) */ --- --- /* Determine whether we need to save $fp, $gp, or $lp. */ --- save_fp = INTVAL (En4) & 0x8; --- save_gp = INTVAL (En4) & 0x4; --- save_lp = INTVAL (En4) & 0x2; --+ (reg:SI Rb)) --+ (set (mem (plus (reg:SI SP_REGNUM) (const_int -28))) --+ (reg:SI Rb+1)) --+ ... --+ (set (mem (plus (reg:SI SP_REGNUM) (const_int -16))) --+ (reg:SI Re)) --+ (set (mem (plus (reg:SI SP_REGNUM) (const_int -12))) --+ (reg:SI FP_REGNUM)) --+ (set (mem (plus (reg:SI SP_REGNUM) (const_int -8))) --+ (reg:SI GP_REGNUM)) --+ (set (mem (plus (reg:SI SP_REGNUM) (const_int -4))) --+ (reg:SI LP_REGNUM)) --+ (set (reg:SI SP_REGNUM) --+ (plus (reg:SI SP_REGNUM) (const_int -32)))]) */ -- -- /* Calculate the number of registers that will be pushed. */ -- extra_count = 0; --- if (save_fp) --+ if (save_fp_p) -- extra_count++; --- if (save_gp) --+ if (save_gp_p) -- extra_count++; --- if (save_lp) --+ if (save_lp_p) -- extra_count++; -- /* Note that Rb and Re may be SP_REGNUM. DO NOT count it in. */ --- if (REGNO (Rb) == SP_REGNUM && REGNO (Re) == SP_REGNUM) --+ if (Rb == SP_REGNUM && Re == SP_REGNUM) -- num_use_regs = extra_count; -- else --- num_use_regs = REGNO (Re) - REGNO (Rb) + 1 + extra_count; --+ num_use_regs = Re - Rb + 1 + extra_count; -- -- /* In addition to used registers, -- we need one more space for (set sp sp-x) rtx. */ --@@ -425,10 +834,10 @@ nds32_emit_stack_push_multiple (rtx Rb, rtx Re, rtx En4, bool vaarg_p) -- offset = -(num_use_regs * 4); -- -- /* Create (set mem regX) from Rb, Rb+1 up to Re. */ --- for (regno = REGNO (Rb); regno <= (int) REGNO (Re); regno++) --+ for (regno = Rb; regno <= Re; regno++) -- { -- /* Rb and Re may be SP_REGNUM. --- We need to break this loop immediately. */ --+ We need to break this loop immediately. */ -- if (regno == SP_REGNUM) -- break; -- --@@ -444,7 +853,7 @@ nds32_emit_stack_push_multiple (rtx Rb, rtx Re, rtx En4, bool vaarg_p) -- } -- -- /* Create (set mem fp), (set mem gp), and (set mem lp) if necessary. */ --- if (save_fp) --+ if (save_fp_p) -- { -- reg = gen_rtx_REG (SImode, FP_REGNUM); -- mem = gen_frame_mem (SImode, plus_constant (Pmode, --@@ -456,7 +865,7 @@ nds32_emit_stack_push_multiple (rtx Rb, rtx Re, rtx En4, bool vaarg_p) -- offset = offset + 4; -- par_index++; -- } --- if (save_gp) --+ if (save_gp_p) -- { -- reg = gen_rtx_REG (SImode, GP_REGNUM); -- mem = gen_frame_mem (SImode, plus_constant (Pmode, --@@ -468,7 +877,7 @@ nds32_emit_stack_push_multiple (rtx Rb, rtx Re, rtx En4, bool vaarg_p) -- offset = offset + 4; -- par_index++; -- } --- if (save_lp) --+ if (save_lp_p) -- { -- reg = gen_rtx_REG (SImode, LP_REGNUM); -- mem = gen_frame_mem (SImode, plus_constant (Pmode, --@@ -514,14 +923,14 @@ nds32_emit_stack_push_multiple (rtx Rb, rtx Re, rtx En4, bool vaarg_p) -- "pop registers from memory", -- "adjust stack pointer". */ -- static void ---nds32_emit_stack_pop_multiple (rtx Rb, rtx Re, rtx En4) --+nds32_emit_stack_pop_multiple (unsigned Rb, unsigned Re, --+ bool save_fp_p, bool save_gp_p, bool save_lp_p) -- { --- int regno; --+ unsigned regno; -- int extra_count; -- int num_use_regs; -- int par_index; -- int offset; --- int save_fp, save_gp, save_lp; -- -- rtx reg; -- rtx mem; --@@ -534,39 +943,34 @@ nds32_emit_stack_pop_multiple (rtx Rb, rtx Re, rtx En4) -- necessary information for data analysis, -- so we create a parallel rtx like this: -- (parallel [(set (reg:SI Rb) --- (mem (reg:SI SP_REGNUM))) --- (set (reg:SI Rb+1) --- (mem (plus (reg:SI SP_REGNUM) (const_int 4)))) --- ... --- (set (reg:SI Re) --- (mem (plus (reg:SI SP_REGNUM) (const_int 16)))) --- (set (reg:SI FP_REGNUM) --- (mem (plus (reg:SI SP_REGNUM) (const_int 20)))) --- (set (reg:SI GP_REGNUM) --- (mem (plus (reg:SI SP_REGNUM) (const_int 24)))) --- (set (reg:SI LP_REGNUM) --- (mem (plus (reg:SI SP_REGNUM) (const_int 28)))) --- (set (reg:SI SP_REGNUM) --- (plus (reg:SI SP_REGNUM) (const_int 32)))]) */ --- --- /* Determine whether we need to restore $fp, $gp, or $lp. */ --- save_fp = INTVAL (En4) & 0x8; --- save_gp = INTVAL (En4) & 0x4; --- save_lp = INTVAL (En4) & 0x2; --+ (mem (reg:SI SP_REGNUM))) --+ (set (reg:SI Rb+1) --+ (mem (plus (reg:SI SP_REGNUM) (const_int 4)))) --+ ... --+ (set (reg:SI Re) --+ (mem (plus (reg:SI SP_REGNUM) (const_int 16)))) --+ (set (reg:SI FP_REGNUM) --+ (mem (plus (reg:SI SP_REGNUM) (const_int 20)))) --+ (set (reg:SI GP_REGNUM) --+ (mem (plus (reg:SI SP_REGNUM) (const_int 24)))) --+ (set (reg:SI LP_REGNUM) --+ (mem (plus (reg:SI SP_REGNUM) (const_int 28)))) --+ (set (reg:SI SP_REGNUM) --+ (plus (reg:SI SP_REGNUM) (const_int 32)))]) */ -- -- /* Calculate the number of registers that will be poped. */ -- extra_count = 0; --- if (save_fp) --+ if (save_fp_p) -- extra_count++; --- if (save_gp) --+ if (save_gp_p) -- extra_count++; --- if (save_lp) --+ if (save_lp_p) -- extra_count++; -- /* Note that Rb and Re may be SP_REGNUM. DO NOT count it in. */ --- if (REGNO (Rb) == SP_REGNUM && REGNO (Re) == SP_REGNUM) --+ if (Rb == SP_REGNUM && Re == SP_REGNUM) -- num_use_regs = extra_count; -- else --- num_use_regs = REGNO (Re) - REGNO (Rb) + 1 + extra_count; --+ num_use_regs = Re - Rb + 1 + extra_count; -- -- /* In addition to used registers, -- we need one more space for (set sp sp+x) rtx. */ --@@ -578,10 +982,10 @@ nds32_emit_stack_pop_multiple (rtx Rb, rtx Re, rtx En4) -- offset = 0; -- -- /* Create (set regX mem) from Rb, Rb+1 up to Re. */ --- for (regno = REGNO (Rb); regno <= (int) REGNO (Re); regno++) --+ for (regno = Rb; regno <= Re; regno++) -- { -- /* Rb and Re may be SP_REGNUM. --- We need to break this loop immediately. */ --+ We need to break this loop immediately. */ -- if (regno == SP_REGNUM) -- break; -- --@@ -599,7 +1003,7 @@ nds32_emit_stack_pop_multiple (rtx Rb, rtx Re, rtx En4) -- } -- -- /* Create (set fp mem), (set gp mem), and (set lp mem) if necessary. */ --- if (save_fp) --+ if (save_fp_p) -- { -- reg = gen_rtx_REG (SImode, FP_REGNUM); -- mem = gen_frame_mem (SImode, plus_constant (Pmode, --@@ -613,7 +1017,7 @@ nds32_emit_stack_pop_multiple (rtx Rb, rtx Re, rtx En4) -- -- dwarf = alloc_reg_note (REG_CFA_RESTORE, reg, dwarf); -- } --- if (save_gp) --+ if (save_gp_p) -- { -- reg = gen_rtx_REG (SImode, GP_REGNUM); -- mem = gen_frame_mem (SImode, plus_constant (Pmode, --@@ -627,7 +1031,7 @@ nds32_emit_stack_pop_multiple (rtx Rb, rtx Re, rtx En4) -- -- dwarf = alloc_reg_note (REG_CFA_RESTORE, reg, dwarf); -- } --- if (save_lp) --+ if (save_lp_p) -- { -- reg = gen_rtx_REG (SImode, LP_REGNUM); -- mem = gen_frame_mem (SImode, plus_constant (Pmode, --@@ -670,12 +1074,11 @@ nds32_emit_stack_pop_multiple (rtx Rb, rtx Re, rtx En4) -- "push registers to memory", -- "adjust stack pointer". */ -- static void ---nds32_emit_stack_v3push (rtx Rb, --- rtx Re, --- rtx En4 ATTRIBUTE_UNUSED, --- rtx imm8u) --+nds32_emit_stack_v3push (unsigned Rb, --+ unsigned Re, --+ unsigned imm8u) -- { --- int regno; --+ unsigned regno; -- int num_use_regs; -- int par_index; -- int offset; --@@ -690,27 +1093,27 @@ nds32_emit_stack_v3push (rtx Rb, -- necessary information for data analysis, -- so we create a parallel rtx like this: -- (parallel [(set (mem (plus (reg:SI SP_REGNUM) (const_int -32))) --- (reg:SI Rb)) --- (set (mem (plus (reg:SI SP_REGNUM) (const_int -28))) --- (reg:SI Rb+1)) --- ... --- (set (mem (plus (reg:SI SP_REGNUM) (const_int -16))) --- (reg:SI Re)) --- (set (mem (plus (reg:SI SP_REGNUM) (const_int -12))) --- (reg:SI FP_REGNUM)) --- (set (mem (plus (reg:SI SP_REGNUM) (const_int -8))) --- (reg:SI GP_REGNUM)) --- (set (mem (plus (reg:SI SP_REGNUM) (const_int -4))) --- (reg:SI LP_REGNUM)) --- (set (reg:SI SP_REGNUM) --- (plus (reg:SI SP_REGNUM) (const_int -32-imm8u)))]) */ --+ (reg:SI Rb)) --+ (set (mem (plus (reg:SI SP_REGNUM) (const_int -28))) --+ (reg:SI Rb+1)) --+ ... --+ (set (mem (plus (reg:SI SP_REGNUM) (const_int -16))) --+ (reg:SI Re)) --+ (set (mem (plus (reg:SI SP_REGNUM) (const_int -12))) --+ (reg:SI FP_REGNUM)) --+ (set (mem (plus (reg:SI SP_REGNUM) (const_int -8))) --+ (reg:SI GP_REGNUM)) --+ (set (mem (plus (reg:SI SP_REGNUM) (const_int -4))) --+ (reg:SI LP_REGNUM)) --+ (set (reg:SI SP_REGNUM) --+ (plus (reg:SI SP_REGNUM) (const_int -32-imm8u)))]) */ -- -- /* Calculate the number of registers that will be pushed. -- Since $fp, $gp, and $lp is always pushed with v3push instruction, -- we need to count these three registers. -- Under v3push, Rb is $r6, while Re is $r6, $r8, $r10, or $r14. -- So there is no need to worry about Rb=Re=SP_REGNUM case. */ --- num_use_regs = REGNO (Re) - REGNO (Rb) + 1 + 3; --+ num_use_regs = Re - Rb + 1 + 3; -- -- /* In addition to used registers, -- we need one more space for (set sp sp-x-imm8u) rtx. */ --@@ -724,7 +1127,7 @@ nds32_emit_stack_v3push (rtx Rb, -- /* Create (set mem regX) from Rb, Rb+1 up to Re. -- Under v3push, Rb is $r6, while Re is $r6, $r8, $r10, or $r14. -- So there is no need to worry about Rb=Re=SP_REGNUM case. */ --- for (regno = REGNO (Rb); regno <= (int) REGNO (Re); regno++) --+ for (regno = Rb; regno <= Re; regno++) -- { -- reg = gen_rtx_REG (SImode, regno); -- mem = gen_frame_mem (SImode, plus_constant (Pmode, --@@ -776,7 +1179,7 @@ nds32_emit_stack_v3push (rtx Rb, -- = gen_rtx_SET (stack_pointer_rtx, -- plus_constant (Pmode, -- stack_pointer_rtx, --- offset - INTVAL (imm8u))); --+ offset - imm8u)); -- XVECEXP (parallel_insn, 0, par_index) = adjust_sp_rtx; -- RTX_FRAME_RELATED_P (adjust_sp_rtx) = 1; -- --@@ -794,12 +1197,11 @@ nds32_emit_stack_v3push (rtx Rb, -- "pop registers from memory", -- "adjust stack pointer". */ -- static void ---nds32_emit_stack_v3pop (rtx Rb, --- rtx Re, --- rtx En4 ATTRIBUTE_UNUSED, --- rtx imm8u) --+nds32_emit_stack_v3pop (unsigned Rb, --+ unsigned Re, --+ unsigned imm8u) -- { --- int regno; --+ unsigned regno; -- int num_use_regs; -- int par_index; -- int offset; --@@ -815,27 +1217,27 @@ nds32_emit_stack_v3pop (rtx Rb, -- necessary information for data analysis, -- so we create a parallel rtx like this: -- (parallel [(set (reg:SI Rb) --- (mem (reg:SI SP_REGNUM))) --- (set (reg:SI Rb+1) --- (mem (plus (reg:SI SP_REGNUM) (const_int 4)))) --- ... --- (set (reg:SI Re) --- (mem (plus (reg:SI SP_REGNUM) (const_int 16)))) --- (set (reg:SI FP_REGNUM) --- (mem (plus (reg:SI SP_REGNUM) (const_int 20)))) --- (set (reg:SI GP_REGNUM) --- (mem (plus (reg:SI SP_REGNUM) (const_int 24)))) --- (set (reg:SI LP_REGNUM) --- (mem (plus (reg:SI SP_REGNUM) (const_int 28)))) --- (set (reg:SI SP_REGNUM) --- (plus (reg:SI SP_REGNUM) (const_int 32+imm8u)))]) */ --+ (mem (reg:SI SP_REGNUM))) --+ (set (reg:SI Rb+1) --+ (mem (plus (reg:SI SP_REGNUM) (const_int 4)))) --+ ... --+ (set (reg:SI Re) --+ (mem (plus (reg:SI SP_REGNUM) (const_int 16)))) --+ (set (reg:SI FP_REGNUM) --+ (mem (plus (reg:SI SP_REGNUM) (const_int 20)))) --+ (set (reg:SI GP_REGNUM) --+ (mem (plus (reg:SI SP_REGNUM) (const_int 24)))) --+ (set (reg:SI LP_REGNUM) --+ (mem (plus (reg:SI SP_REGNUM) (const_int 28)))) --+ (set (reg:SI SP_REGNUM) --+ (plus (reg:SI SP_REGNUM) (const_int 32+imm8u)))]) */ -- -- /* Calculate the number of registers that will be poped. -- Since $fp, $gp, and $lp is always poped with v3pop instruction, -- we need to count these three registers. -- Under v3push, Rb is $r6, while Re is $r6, $r8, $r10, or $r14. -- So there is no need to worry about Rb=Re=SP_REGNUM case. */ --- num_use_regs = REGNO (Re) - REGNO (Rb) + 1 + 3; --+ num_use_regs = Re - Rb + 1 + 3; -- -- /* In addition to used registers, -- we need one more space for (set sp sp+x+imm8u) rtx. */ --@@ -849,7 +1251,7 @@ nds32_emit_stack_v3pop (rtx Rb, -- /* Create (set regX mem) from Rb, Rb+1 up to Re. -- Under v3pop, Rb is $r6, while Re is $r6, $r8, $r10, or $r14. -- So there is no need to worry about Rb=Re=SP_REGNUM case. */ --- for (regno = REGNO (Rb); regno <= (int) REGNO (Re); regno++) --+ for (regno = Rb; regno <= Re; regno++) -- { -- reg = gen_rtx_REG (SImode, regno); -- mem = gen_frame_mem (SImode, plus_constant (Pmode, --@@ -907,11 +1309,24 @@ nds32_emit_stack_v3pop (rtx Rb, -- = gen_rtx_SET (stack_pointer_rtx, -- plus_constant (Pmode, -- stack_pointer_rtx, --- offset + INTVAL (imm8u))); --+ offset + imm8u)); -- XVECEXP (parallel_insn, 0, par_index) = adjust_sp_rtx; -- --- /* Tell gcc we adjust SP in this insn. */ --- dwarf = alloc_reg_note (REG_CFA_ADJUST_CFA, copy_rtx (adjust_sp_rtx), dwarf); --+ if (frame_pointer_needed) --+ { --+ /* (expr_list:REG_CFA_DEF_CFA (plus:SI (reg/f:SI $sp) --+ (const_int 0)) --+ mean reset frame pointer to $sp and reset to offset 0. */ --+ rtx cfa_adjust_rtx = gen_rtx_PLUS (Pmode, stack_pointer_rtx, --+ const0_rtx); --+ dwarf = alloc_reg_note (REG_CFA_DEF_CFA, cfa_adjust_rtx, dwarf); --+ } --+ else --+ { --+ /* Tell gcc we adjust SP in this insn. */ --+ dwarf = alloc_reg_note (REG_CFA_ADJUST_CFA, --+ copy_rtx (adjust_sp_rtx), dwarf); --+ } -- -- parallel_insn = emit_insn (parallel_insn); -- --@@ -924,6 +1339,32 @@ nds32_emit_stack_v3pop (rtx Rb, -- REG_NOTES (parallel_insn) = dwarf; -- } -- --+static void --+nds32_emit_load_gp (void) --+{ --+ rtx got_symbol, pat; --+ --+ /* Initial GLOBAL OFFSET TABLE don't do the scheduling. */ --+ emit_insn (gen_blockage ()); --+ --+ got_symbol = gen_rtx_SYMBOL_REF (Pmode, "_GLOBAL_OFFSET_TABLE_"); --+ /* sethi $gp, _GLOBAL_OFFSET_TABLE_ -8 */ --+ pat = gen_rtx_UNSPEC (SImode, gen_rtvec (1, got_symbol), UNSPEC_GOTINIT); --+ pat = gen_rtx_CONST (SImode, gen_rtx_PLUS (Pmode, pat, GEN_INT (-8))); --+ emit_insn (gen_sethi (pic_offset_table_rtx,pat)); --+ --+ /* ori $gp, $gp, _GLOBAL_OFFSET_TABLE_ -4 */ --+ pat = gen_rtx_UNSPEC (SImode, gen_rtvec (1, got_symbol), UNSPEC_GOTINIT); --+ pat = gen_rtx_CONST (SImode, gen_rtx_PLUS (Pmode, pat, GEN_INT (-4))); --+ emit_insn (gen_lo_sum (pic_offset_table_rtx, pic_offset_table_rtx, pat)); --+ --+ /* add5.pc $gp */ --+ emit_insn (gen_add_pc (pic_offset_table_rtx, pic_offset_table_rtx)); --+ --+ /* Initial GLOBAL OFFSET TABLE don't do the scheduling. */ --+ emit_insn (gen_blockage ()); --+} --+ -- /* Function that may creates more instructions -- for large value on adjusting stack pointer. -- --@@ -933,79 +1374,70 @@ nds32_emit_stack_v3pop (rtx Rb, -- the adjustment value is not able to be fit in the 'addi' instruction. -- One solution is to move value into a register -- and then use 'add' instruction. --- In practice, we use TA_REGNUM ($r15) to accomplish this purpose. --- Also, we need to return zero for sp adjustment so that --- proglogue/epilogue knows there is no need to create 'addi' instruction. */ ---static int ---nds32_force_addi_stack_int (int full_value) --+ In practice, we use TA_REGNUM ($r15) to accomplish this purpose. */ --+static void --+nds32_emit_adjust_frame (rtx to_reg, rtx from_reg, int adjust_value) -- { --- int adjust_value; --- -- rtx tmp_reg; --- rtx sp_adjust_insn; --+ rtx frame_adjust_insn; --+ rtx adjust_value_rtx = GEN_INT (adjust_value); -- --- if (!satisfies_constraint_Is15 (GEN_INT (full_value))) --+ if (adjust_value == 0) --+ return; --+ --+ if (!satisfies_constraint_Is15 (adjust_value_rtx)) -- { -- /* The value is not able to fit in single addi instruction. --- Create more instructions of moving value into a register --- and then add stack pointer with it. */ --+ Create more instructions of moving value into a register --+ and then add stack pointer with it. */ -- -- /* $r15 is going to be temporary register to hold the value. */ -- tmp_reg = gen_rtx_REG (SImode, TA_REGNUM); -- -- /* Create one more instruction to move value --- into the temporary register. */ --- emit_move_insn (tmp_reg, GEN_INT (full_value)); --+ into the temporary register. */ --+ emit_move_insn (tmp_reg, adjust_value_rtx); -- -- /* Create new 'add' rtx. */ --- sp_adjust_insn = gen_addsi3 (stack_pointer_rtx, --- stack_pointer_rtx, --- tmp_reg); --+ frame_adjust_insn = gen_addsi3 (to_reg, --+ from_reg, --+ tmp_reg); -- /* Emit rtx into insn list and receive its transformed insn rtx. */ --- sp_adjust_insn = emit_insn (sp_adjust_insn); --- --- /* At prologue, we need to tell GCC that this is frame related insn, --- so that we can consider this instruction to output debug information. --- If full_value is NEGATIVE, it means this function --- is invoked by expand_prologue. */ --- if (full_value < 0) --- { --- /* Because (tmp_reg <- full_value) may be split into two --- rtl patterns, we can not set its RTX_FRAME_RELATED_P. --- We need to construct another (sp <- sp + full_value) --- and then insert it into sp_adjust_insn's reg note to --- represent a frame related expression. --- GCC knows how to refer it and output debug information. */ --- --- rtx plus_rtx; --- rtx set_rtx; --+ frame_adjust_insn = emit_insn (frame_adjust_insn); -- --- plus_rtx = plus_constant (Pmode, stack_pointer_rtx, full_value); --- set_rtx = gen_rtx_SET (stack_pointer_rtx, plus_rtx); --- add_reg_note (sp_adjust_insn, REG_FRAME_RELATED_EXPR, set_rtx); --+ /* Because (tmp_reg <- full_value) may be split into two --+ rtl patterns, we can not set its RTX_FRAME_RELATED_P. --+ We need to construct another (sp <- sp + full_value) --+ and then insert it into sp_adjust_insn's reg note to --+ represent a frame related expression. --+ GCC knows how to refer it and output debug information. */ -- --- RTX_FRAME_RELATED_P (sp_adjust_insn) = 1; --- } --+ rtx plus_rtx; --+ rtx set_rtx; -- --- /* We have used alternative way to adjust stack pointer value. --- Return zero so that prologue/epilogue --- will not generate other instructions. */ --- return 0; --+ plus_rtx = plus_constant (Pmode, from_reg, adjust_value); --+ set_rtx = gen_rtx_SET (to_reg, plus_rtx); --+ add_reg_note (frame_adjust_insn, REG_FRAME_RELATED_EXPR, set_rtx); -- } -- else -- { --- /* The value is able to fit in addi instruction. --- However, remember to make it to be positive value --- because we want to return 'adjustment' result. */ --- adjust_value = (full_value < 0) ? (-full_value) : (full_value); --- --- return adjust_value; --+ /* Generate sp adjustment instruction if and only if sp_adjust != 0. */ --+ frame_adjust_insn = gen_addsi3 (to_reg, --+ from_reg, --+ adjust_value_rtx); --+ /* Emit rtx into instructions list and receive INSN rtx form. */ --+ frame_adjust_insn = emit_insn (frame_adjust_insn); -- } --+ --+ /* The insn rtx 'sp_adjust_insn' will change frame layout. --+ We need to use RTX_FRAME_RELATED_P so that GCC is able to --+ generate CFI (Call Frame Information) stuff. */ --+ RTX_FRAME_RELATED_P (frame_adjust_insn) = 1; -- } -- -- /* Return true if MODE/TYPE need double word alignment. */ -- static bool ---nds32_needs_double_word_align (machine_mode mode, const_tree type) --+nds32_needs_double_word_align (enum machine_mode mode, const_tree type) -- { -- unsigned int align; -- --@@ -1015,18 +1447,25 @@ nds32_needs_double_word_align (machine_mode mode, const_tree type) -- return (align > PARM_BOUNDARY); -- } -- ---/* Return true if FUNC is a naked function. */ ---static bool --+bool -- nds32_naked_function_p (tree func) -- { --- tree t; --+ /* FOR BACKWARD COMPATIBILITY, --+ we need to support 'no_prologue' attribute as well. */ --+ tree t_naked; --+ tree t_no_prologue; -- -- if (TREE_CODE (func) != FUNCTION_DECL) -- abort (); -- --- t = lookup_attribute ("naked", DECL_ATTRIBUTES (func)); --+ /* We have to use lookup_attribute() to check attributes. --+ Because attr_naked_p and attr_no_prologue_p are set in --+ nds32_compute_stack_frame() and the function has not been --+ invoked yet. */ --+ t_naked = lookup_attribute ("naked", DECL_ATTRIBUTES (func)); --+ t_no_prologue = lookup_attribute ("no_prologue", DECL_ATTRIBUTES (func)); -- --- return (t != NULL_TREE); --+ return ((t_naked != NULL_TREE) || (t_no_prologue != NULL_TREE)); -- } -- -- /* Function that check if 'X' is a valid address register. --@@ -1035,7 +1474,7 @@ nds32_naked_function_p (tree func) -- -- STRICT : true -- => We are in reload pass or after reload pass. --- The register number should be strictly limited in general registers. --+ The register number should be strictly limited in general registers. -- -- STRICT : false -- => Before reload pass, we are free to use any register number. */ --@@ -1058,10 +1497,10 @@ nds32_address_register_rtx_p (rtx x, bool strict) -- /* Function that check if 'INDEX' is valid to be a index rtx for address. -- -- OUTER_MODE : Machine mode of outer address rtx. --- INDEX : Check if this rtx is valid to be a index for address. --+ INDEX : Check if this rtx is valid to be a index for address. -- STRICT : If it is true, we are in reload pass or after reload pass. */ -- static bool ---nds32_legitimate_index_p (machine_mode outer_mode, --+nds32_legitimate_index_p (enum machine_mode outer_mode, -- rtx index, -- bool strict) -- { --@@ -1074,7 +1513,7 @@ nds32_legitimate_index_p (machine_mode outer_mode, -- case REG: -- regno = REGNO (index); -- /* If we are in reload pass or after reload pass, --- we need to limit it to general register. */ --+ we need to limit it to general register. */ -- if (strict) -- return REGNO_OK_FOR_INDEX_P (regno); -- else --@@ -1082,45 +1521,73 @@ nds32_legitimate_index_p (machine_mode outer_mode, -- -- case CONST_INT: -- /* The alignment of the integer value is determined by 'outer_mode'. */ --- if (GET_MODE_SIZE (outer_mode) == 1) --+ switch (GET_MODE_SIZE (outer_mode)) -- { --+ case 1: -- /* Further check if the value is legal for the 'outer_mode'. */ --- if (!satisfies_constraint_Is15 (index)) --- return false; --+ if (satisfies_constraint_Is15 (index)) --+ return true; --+ break; -- --- /* Pass all test, the value is valid, return true. */ --- return true; --- } --- if (GET_MODE_SIZE (outer_mode) == 2 --- && NDS32_HALF_WORD_ALIGN_P (INTVAL (index))) --- { --+ case 2: -- /* Further check if the value is legal for the 'outer_mode'. */ --- if (!satisfies_constraint_Is16 (index)) --- return false; --+ if (satisfies_constraint_Is16 (index)) --+ { --+ /* If it is not under strictly aligned situation, --+ we can return true without checking alignment. */ --+ if (!cfun->machine->strict_aligned_p) --+ return true; --+ /* Make sure address is half word alignment. */ --+ else if (NDS32_HALF_WORD_ALIGN_P (INTVAL (index))) --+ return true; --+ } --+ break; -- --- /* Pass all test, the value is valid, return true. */ --- return true; --- } --- if (GET_MODE_SIZE (outer_mode) == 4 --- && NDS32_SINGLE_WORD_ALIGN_P (INTVAL (index))) --- { --+ case 4: -- /* Further check if the value is legal for the 'outer_mode'. */ --- if (!satisfies_constraint_Is17 (index)) --- return false; --+ if (satisfies_constraint_Is17 (index)) --+ { --+ if ((TARGET_FPU_SINGLE || TARGET_FPU_DOUBLE)) --+ { --+ if (!satisfies_constraint_Is14 (index)) --+ return false; --+ } --+ --+ /* If it is not under strictly aligned situation, --+ we can return true without checking alignment. */ --+ if (!cfun->machine->strict_aligned_p) --+ return true; --+ /* Make sure address is word alignment. */ --+ else if (NDS32_SINGLE_WORD_ALIGN_P (INTVAL (index))) --+ return true; --+ } --+ break; -- --- /* Pass all test, the value is valid, return true. */ --- return true; --- } --- if (GET_MODE_SIZE (outer_mode) == 8 --- && NDS32_SINGLE_WORD_ALIGN_P (INTVAL (index))) --- { --- /* Further check if the value is legal for the 'outer_mode'. */ --- if (!satisfies_constraint_Is17 (gen_int_mode (INTVAL (index) + 4, --- SImode))) --- return false; --+ case 8: --+ if (satisfies_constraint_Is17 (gen_int_mode (INTVAL (index) + 4, --+ SImode))) --+ { --+ if ((TARGET_FPU_SINGLE || TARGET_FPU_DOUBLE)) --+ { --+ if (!satisfies_constraint_Is14 (index)) --+ return false; --+ } --+ --+ /* If it is not under strictly aligned situation, --+ we can return true without checking alignment. */ --+ if (!cfun->machine->strict_aligned_p) --+ return true; --+ /* Make sure address is word alignment. --+ Currently we do not have 64-bit load/store yet, --+ so we will use two 32-bit load/store instructions to do --+ memory access and they are single word alignment. */ --+ else if (NDS32_SINGLE_WORD_ALIGN_P (INTVAL (index))) --+ return true; --+ } --+ break; -- --- /* Pass all test, the value is valid, return true. */ --- return true; --+ default: --+ return false; -- } -- -- return false; --@@ -1134,9 +1601,10 @@ nds32_legitimate_index_p (machine_mode outer_mode, -- int multiplier; -- multiplier = INTVAL (op1); -- --- /* We only allow (mult reg const_int_1) --- or (mult reg const_int_2) or (mult reg const_int_4). */ --- if (multiplier != 1 && multiplier != 2 && multiplier != 4) --+ /* We only allow (mult reg const_int_1), (mult reg const_int_2), --+ (mult reg const_int_4) or (mult reg const_int_8). */ --+ if (multiplier != 1 && multiplier != 2 --+ && multiplier != 4 && multiplier != 8) -- return false; -- -- regno = REGNO (op0); --@@ -1161,8 +1629,9 @@ nds32_legitimate_index_p (machine_mode outer_mode, -- sv = INTVAL (op1); -- -- /* We only allow (ashift reg const_int_0) --- or (ashift reg const_int_1) or (ashift reg const_int_2). */ --- if (sv != 0 && sv != 1 && sv !=2) --+ or (ashift reg const_int_1) or (ashift reg const_int_2) or --+ (ashift reg const_int_3). */ --+ if (sv != 0 && sv != 1 && sv !=2 && sv != 3) -- return false; -- -- regno = REGNO (op0); --@@ -1181,18 +1650,302 @@ nds32_legitimate_index_p (machine_mode outer_mode, -- } -- } -- --+static void --+nds32_insert_innermost_loop (void) --+{ --+ struct loop *loop; --+ basic_block *bbs, bb; --+ --+ compute_bb_for_insn (); --+ /* initial loop structure */ --+ loop_optimizer_init (AVOID_CFG_MODIFICATIONS); --+ --+ /* Scan all inner most loops. */ --+ FOR_EACH_LOOP (loop, LI_ONLY_INNERMOST) --+ { --+ bbs = get_loop_body (loop); --+ bb = *bbs; --+ free (bbs); --+ --+ emit_insn_before (gen_innermost_loop_begin (), --+ BB_HEAD (bb)); --+ --+ /* Find the final basic block in the loop. */ --+ while (bb) --+ { --+ if (bb->next_bb == NULL) --+ break; --+ --+ if (bb->next_bb->loop_father != loop) --+ break; --+ --+ bb = bb->next_bb; --+ } --+ --+ emit_insn_before (gen_innermost_loop_end (), --+ BB_END (bb)); --+ } --+ --+ /* release loop structre */ --+ loop_optimizer_finalize (); --+} --+ --+/* Insert isps for function with signature attribute. */ --+static void --+nds32_insert_isps (void) --+{ --+ rtx_insn *insn; --+ unsigned first = 0; --+ --+ if (!lookup_attribute ("signature", DECL_ATTRIBUTES (current_function_decl))) --+ return; --+ --+ insn = get_insns (); --+ while (insn) --+ { --+ /* In order to ensure protect whole function, emit the first --+ isps here rather than in prologue.*/ --+ if (!first && INSN_P (insn)) --+ { --+ emit_insn_before (gen_unspec_signature_begin (), insn); --+ first = 1; --+ } --+ --+ if (LABEL_P (insn) || CALL_P (insn) || any_condjump_p (insn) --+ || (INSN_P (insn) && GET_CODE (PATTERN (insn)) == UNSPEC_VOLATILE --+ && (XINT (PATTERN (insn), 1) == UNSPEC_VOLATILE_SYSCALL --+ || XINT (PATTERN (insn), 1) == UNSPEC_VOLATILE_TRAP --+ || XINT (PATTERN (insn), 1) == UNSPEC_VOLATILE_TEQZ --+ || XINT (PATTERN (insn), 1) == UNSPEC_VOLATILE_TNEZ))) --+ { --+ emit_insn_after (gen_unspec_signature_begin (), insn); --+ } --+ insn = NEXT_INSN (insn); --+ } --+} --+ --+static void --+nds32_register_pass ( --+ rtl_opt_pass *(*make_pass_func) (gcc::context *), --+ enum pass_positioning_ops pass_pos, --+ const char *ref_pass_name) --+{ --+ opt_pass *new_opt_pass = make_pass_func (g); --+ --+ struct register_pass_info insert_pass = --+ { --+ new_opt_pass, /* pass */ --+ ref_pass_name, /* reference_pass_name */ --+ 1, /* ref_pass_instance_number */ --+ pass_pos /* po_op */ --+ }; --+ --+ register_pass (&insert_pass); --+} --+ --+static void --+nds32_register_pass ( --+ gimple_opt_pass *(*make_pass_func) (gcc::context *), --+ enum pass_positioning_ops pass_pos, --+ const char *ref_pass_name) --+{ --+ opt_pass *new_opt_pass = make_pass_func (g); --+ --+ struct register_pass_info insert_pass = --+ { --+ new_opt_pass, /* pass */ --+ ref_pass_name, /* reference_pass_name */ --+ 1, /* ref_pass_instance_number */ --+ pass_pos /* po_op */ --+ }; --+ --+ register_pass (&insert_pass); --+} --+ --+/* This function is called from nds32_option_override (). --+ All new passes should be registered here. */ --+static void --+nds32_register_passes (void) --+{ --+ nds32_register_pass ( --+ make_pass_nds32_fp_as_gp, --+ PASS_POS_INSERT_BEFORE, --+ "ira"); --+ --+ nds32_register_pass ( --+ make_pass_nds32_relax_opt, --+ PASS_POS_INSERT_AFTER, --+ "mach"); --+ --+ nds32_register_pass ( --+ make_pass_nds32_load_store_opt, --+ PASS_POS_INSERT_AFTER, --+ "mach"); --+ --+ nds32_register_pass ( --+ make_pass_nds32_soft_fp_arith_comm_opt, --+ PASS_POS_INSERT_BEFORE, --+ "mach"); --+ --+ nds32_register_pass ( --+ make_pass_nds32_regrename_opt, --+ PASS_POS_INSERT_AFTER, --+ "mach"); --+ --+ nds32_register_pass ( --+ make_pass_nds32_gcse_opt, --+ PASS_POS_INSERT_BEFORE, --+ "cprop_hardreg"); --+ --+ nds32_register_pass ( --+ make_pass_nds32_cprop_acc_opt, --+ PASS_POS_INSERT_AFTER, --+ "cprop_hardreg"); --+ --+ nds32_register_pass ( --+ make_pass_cprop_hardreg, --+ PASS_POS_INSERT_AFTER, --+ "mach"); --+ --+ nds32_register_pass ( --+ make_pass_nds32_rename_lmwsmw_opt, --+ PASS_POS_INSERT_AFTER, --+ "jump2"); --+ --+ nds32_register_pass ( --+ make_pass_nds32_gen_lmwsmw_opt, --+ PASS_POS_INSERT_BEFORE, --+ "peephole2"); --+ --+ nds32_register_pass ( --+ make_pass_nds32_const_remater_opt, --+ PASS_POS_INSERT_BEFORE, --+ "ira"); --+ --+ nds32_register_pass ( --+ make_pass_nds32_scalbn_transform_opt, --+ PASS_POS_INSERT_AFTER, --+ "optimized"); --+ --+ nds32_register_pass ( --+ make_pass_nds32_sign_conversion_opt, --+ PASS_POS_INSERT_BEFORE, --+ "optimized"); --+ --+ nds32_register_pass ( --+ make_pass_nds32_abi_compatible, --+ PASS_POS_INSERT_BEFORE, --+ "optimized"); --+ --+ nds32_register_pass ( --+ nds32::scheduling::make_pass_nds32_print_stalls, --+ PASS_POS_INSERT_BEFORE, --+ "final"); --+} --+ -- /* ------------------------------------------------------------------------ */ -- ---/* PART 3: Implement target hook stuff definitions. */ --+/* PART 4: Implement target hook stuff definitions. */ --+ --+ --+/* Computing the Length of an Insn. --+ Modifies the length assigned to instruction INSN. --+ LEN is the initially computed length of the insn. */ --+int --+nds32_adjust_insn_length (rtx_insn *insn, int length) --+{ --+ int adjust_value = 0; --+ switch (recog_memoized (insn)) --+ { --+ case CODE_FOR_call_internal: --+ case CODE_FOR_call_value_internal: --+ { --+ if (NDS32_ALIGN_P ()) --+ { --+ rtx_insn *next_insn = next_active_insn (insn); --+ if (next_insn && get_attr_length (next_insn) != 2) --+ adjust_value += 2; --+ } --+ /* We need insert a nop after a noretun function call --+ to prevent software breakpoint corrupt the next function. */ --+ if (find_reg_note (insn, REG_NORETURN, NULL_RTX)) --+ { --+ if (TARGET_16_BIT) --+ adjust_value += 2; --+ else --+ adjust_value += 4; --+ } --+ } --+ return length + adjust_value; --+ --+ default: --+ return length; --+ } --+} --+ --+/* Storage Layout. */ --+ --+/* This function will be called just before expansion into rtl. */ --+static void --+nds32_expand_to_rtl_hook (void) --+{ --+ /* We need to set strictly aligned situation. --+ After that, the memory address checking in nds32_legitimate_address_p() --+ will take alignment offset into consideration so that it will not create --+ unaligned [base + offset] access during the rtl optimization. */ --+ cfun->machine->strict_aligned_p = 1; --+} --+ --+ --+/* Register Usage. */ --+ --+static void --+nds32_conditional_register_usage (void) --+{ --+ int regno; --+ --+ if (TARGET_LINUX_ABI) --+ fixed_regs[TP_REGNUM] = 1; --+ --+ if (TARGET_HARD_FLOAT) --+ { --+ for (regno = NDS32_FIRST_FPR_REGNUM; --+ regno <= NDS32_LAST_FPR_REGNUM; regno++) --+ { --+ fixed_regs[regno] = 0; --+ if (regno < NDS32_FIRST_FPR_REGNUM + NDS32_MAX_FPR_REGS_FOR_ARGS) --+ call_used_regs[regno] = 1; --+ else if (regno >= NDS32_FIRST_FPR_REGNUM + 22 --+ && regno < NDS32_FIRST_FPR_REGNUM + 48) --+ call_used_regs[regno] = 1; --+ else --+ call_used_regs[regno] = 0; --+ } --+ } --+ else if (TARGET_FPU_SINGLE || TARGET_FPU_DOUBLE) --+ { --+ for (regno = NDS32_FIRST_FPR_REGNUM; --+ regno <= NDS32_LAST_FPR_REGNUM; --+ regno++) --+ fixed_regs[regno] = 0; --+ } --+} --+ -- -- /* Register Classes. */ -- --+static reg_class_t --+nds32_preferred_rename_class (reg_class_t rclass) --+{ --+ return nds32_preferred_rename_class_impl (rclass); --+} --+ -- static unsigned char -- nds32_class_max_nregs (reg_class_t rclass ATTRIBUTE_UNUSED, --- machine_mode mode) --+ enum machine_mode mode) -- { -- /* Return the maximum number of consecutive registers --- needed to represent "mode" in a register of "rclass". */ --+ needed to represent MODE in a register of RCLASS. */ -- return ((GET_MODE_SIZE (mode) + UNITS_PER_WORD - 1) / UNITS_PER_WORD); -- } -- --@@ -1200,9 +1953,24 @@ static int -- nds32_register_priority (int hard_regno) -- { -- /* Encourage to use r0-r7 for LRA when optimize for size. */ --- if (optimize_size && hard_regno < 8) --- return 4; --- return 3; --+ if (optimize_size) --+ { --+ if (hard_regno < 8) --+ return 4; --+ else if (hard_regno < 16) --+ return 3; --+ else if (hard_regno < 28) --+ return 2; --+ else --+ return 1; --+ } --+ else --+ { --+ if (hard_regno > 27) --+ return 1; --+ else --+ return 4; --+ } -- } -- -- --@@ -1222,8 +1990,8 @@ nds32_register_priority (int hard_regno) -- 2. return address -- 3. callee-saved registers -- 4. (we will calculte in nds32_compute_stack_frame() --- and save it at --- cfun->machine->callee_saved_area_padding_bytes) --+ and save it at --+ cfun->machine->callee_saved_area_padding_bytes) -- -- [Block B] -- 1. local variables --@@ -1241,29 +2009,29 @@ nds32_register_priority (int hard_regno) -- By applying the basic frame/stack/argument pointers concept, -- the layout of a stack frame shoule be like this: -- --- | | --+ | | -- old stack pointer -> ---- --- | | \ --- | | saved arguments for --- | | vararg functions --- | | / --+ | | \ --+ | | saved arguments for --+ | | vararg functions --+ | | / -- hard frame pointer -> -- -- & argument pointer | | \ --- | | previous hardware frame pointer --- | | return address --- | | callee-saved registers --- | | / --- frame pointer -> -- --- | | \ --- | | local variables --- | | and incoming arguments --- | | / --- -- --- | | \ --- | | outgoing --- | | arguments --- | | / --- stack pointer -> ---- --+ | | previous hardware frame pointer --+ | | return address --+ | | callee-saved registers --+ | | / --+ frame pointer -> -- --+ | | \ --+ | | local variables --+ | | and incoming arguments --+ | | / --+ -- --+ | | \ --+ | | outgoing --+ | | arguments --+ | | / --+ stack pointer -> ---- -- -- $SFP and $AP are used to represent frame pointer and arguments pointer, -- which will be both eliminated as hard frame pointer. */ --@@ -1291,7 +2059,7 @@ nds32_can_eliminate (const int from_reg, const int to_reg) -- /* -- Passing Arguments in Registers. */ -- -- static rtx ---nds32_function_arg (cumulative_args_t ca, machine_mode mode, --+nds32_function_arg (cumulative_args_t ca, enum machine_mode mode, -- const_tree type, bool named) -- { -- unsigned int regno; --@@ -1306,7 +2074,7 @@ nds32_function_arg (cumulative_args_t ca, machine_mode mode, -- if (!named) -- { -- /* If we are under hard float abi, we have arguments passed on the --- stack and all situation can be handled by GCC itself. */ --+ stack and all situation can be handled by GCC itself. */ -- if (TARGET_HARD_FLOAT) -- return NULL_RTX; -- --@@ -1320,7 +2088,7 @@ nds32_function_arg (cumulative_args_t ca, machine_mode mode, -- } -- -- /* No register available, return NULL_RTX. --- The compiler will use stack to pass argument instead. */ --+ The compiler will use stack to pass argument instead. */ -- return NULL_RTX; -- } -- --@@ -1329,14 +2097,34 @@ nds32_function_arg (cumulative_args_t ca, machine_mode mode, -- are different. */ -- if (TARGET_HARD_FLOAT) -- { --- /* Currently we have not implemented hard float yet. */ --- gcc_unreachable (); --+ /* For TARGET_HARD_FLOAT calling convention, we use GPR and FPR --+ to pass argument. We have to further check TYPE and MODE so --+ that we can determine which kind of register we shall use. */ --+ --+ /* Note that we need to pass argument entirely in registers under --+ hard float abi. */ --+ if (GET_MODE_CLASS (mode) == MODE_FLOAT --+ && NDS32_ARG_ENTIRE_IN_FPR_REG_P (cum->fpr_offset, mode, type)) --+ { --+ /* Pick up the next available FPR register number. */ --+ regno --+ = NDS32_AVAILABLE_REGNUM_FOR_FPR_ARG (cum->fpr_offset, mode, type); --+ return gen_rtx_REG (mode, regno); --+ } --+ else if (GET_MODE_CLASS (mode) != MODE_FLOAT --+ && NDS32_ARG_ENTIRE_IN_GPR_REG_P (cum->gpr_offset, mode, type)) --+ { --+ /* Pick up the next available GPR register number. */ --+ regno --+ = NDS32_AVAILABLE_REGNUM_FOR_GPR_ARG (cum->gpr_offset, mode, type); --+ return gen_rtx_REG (mode, regno); --+ } -- } -- else -- { -- /* For !TARGET_HARD_FLOAT calling convention, we always use GPR to pass --- argument. Since we allow to pass argument partially in registers, --- we can just return it if there are still registers available. */ --+ argument. Since we allow to pass argument partially in registers, --+ we can just return it if there are still registers available. */ -- if (NDS32_ARG_PARTIAL_IN_GPR_REG_P (cum->gpr_offset, mode, type)) -- { -- /* Pick up the next available register number. */ --@@ -1353,7 +2141,7 @@ nds32_function_arg (cumulative_args_t ca, machine_mode mode, -- } -- -- static bool ---nds32_must_pass_in_stack (machine_mode mode, const_tree type) --+nds32_must_pass_in_stack (enum machine_mode mode, const_tree type) -- { -- /* Return true if a type must be passed in memory. -- If it is NOT using hard float abi, small aggregates can be --@@ -1366,7 +2154,7 @@ nds32_must_pass_in_stack (machine_mode mode, const_tree type) -- } -- -- static int ---nds32_arg_partial_bytes (cumulative_args_t ca, machine_mode mode, --+nds32_arg_partial_bytes (cumulative_args_t ca, enum machine_mode mode, -- tree type, bool named ATTRIBUTE_UNUSED) -- { -- /* Returns the number of bytes at the beginning of an argument that --@@ -1400,7 +2188,7 @@ nds32_arg_partial_bytes (cumulative_args_t ca, machine_mode mode, -- remaining_reg_count -- = NDS32_MAX_GPR_REGS_FOR_ARGS -- - (NDS32_AVAILABLE_REGNUM_FOR_GPR_ARG (cum->gpr_offset, mode, type) --- - NDS32_GPR_ARG_FIRST_REGNUM); --+ - NDS32_GPR_ARG_FIRST_REGNUM); -- -- /* Note that we have to return the nubmer of bytes, not registers count. */ -- if (needed_reg_count > remaining_reg_count) --@@ -1410,26 +2198,23 @@ nds32_arg_partial_bytes (cumulative_args_t ca, machine_mode mode, -- } -- -- static void ---nds32_function_arg_advance (cumulative_args_t ca, machine_mode mode, --+nds32_function_arg_advance (cumulative_args_t ca, enum machine_mode mode, -- const_tree type, bool named) -- { --- machine_mode sub_mode; -- CUMULATIVE_ARGS *cum = get_cumulative_args (ca); -- -- if (named) -- { -- /* We need to further check TYPE and MODE so that we can determine --- which kind of register we shall advance. */ --- if (type && TREE_CODE (type) == COMPLEX_TYPE) --- sub_mode = TYPE_MODE (TREE_TYPE (type)); --- else --- sub_mode = mode; --+ which kind of register we shall advance. */ -- -- /* Under hard float abi, we may advance FPR registers. */ --- if (TARGET_HARD_FLOAT && GET_MODE_CLASS (sub_mode) == MODE_FLOAT) --+ if (TARGET_HARD_FLOAT && GET_MODE_CLASS (mode) == MODE_FLOAT) -- { --- /* Currently we have not implemented hard float yet. */ --- gcc_unreachable (); --+ cum->fpr_offset --+ = NDS32_AVAILABLE_REGNUM_FOR_FPR_ARG (cum->fpr_offset, mode, type) --+ - NDS32_FPR_ARG_FIRST_REGNUM --+ + NDS32_NEED_N_REGS_FOR_ARG (mode, type); -- } -- else -- { --@@ -1442,9 +2227,9 @@ nds32_function_arg_advance (cumulative_args_t ca, machine_mode mode, -- else -- { -- /* If this nameless argument is NOT under TARGET_HARD_FLOAT, --- we can advance next register as well so that caller is --- able to pass arguments in registers and callee must be --- in charge of pushing all of them into stack. */ --+ we can advance next register as well so that caller is --+ able to pass arguments in registers and callee must be --+ in charge of pushing all of them into stack. */ -- if (!TARGET_HARD_FLOAT) -- { -- cum->gpr_offset --@@ -1456,13 +2241,23 @@ nds32_function_arg_advance (cumulative_args_t ca, machine_mode mode, -- } -- -- static unsigned int ---nds32_function_arg_boundary (machine_mode mode, const_tree type) --+nds32_function_arg_boundary (enum machine_mode mode, const_tree type) -- { -- return (nds32_needs_double_word_align (mode, type) -- ? NDS32_DOUBLE_WORD_ALIGNMENT -- : PARM_BOUNDARY); -- } -- --+bool --+nds32_vector_mode_supported_p (enum machine_mode mode) --+{ --+ if (mode == V4QImode --+ || mode == V2HImode) --+ return NDS32_EXT_DSP_P (); --+ --+ return false; --+} --+ -- /* -- How Scalar Function Values Are Returned. */ -- -- static rtx --@@ -1470,28 +2265,68 @@ nds32_function_value (const_tree ret_type, -- const_tree fn_decl_or_type ATTRIBUTE_UNUSED, -- bool outgoing ATTRIBUTE_UNUSED) -- { --- machine_mode mode; --+ enum machine_mode mode; -- int unsignedp; -- -- mode = TYPE_MODE (ret_type); -- unsignedp = TYPE_UNSIGNED (ret_type); -- --- mode = promote_mode (ret_type, mode, &unsignedp); --+ if (INTEGRAL_TYPE_P (ret_type)) --+ mode = promote_mode (ret_type, mode, &unsignedp); -- --- return gen_rtx_REG (mode, NDS32_GPR_RET_FIRST_REGNUM); --+ if (TARGET_HARD_FLOAT && (mode == SFmode || mode == DFmode)) --+ return gen_rtx_REG (mode, NDS32_FPR_RET_FIRST_REGNUM); --+ else --+ return gen_rtx_REG (mode, NDS32_GPR_RET_FIRST_REGNUM); -- } -- -- static rtx ---nds32_libcall_value (machine_mode mode, --+nds32_libcall_value (enum machine_mode mode, -- const_rtx fun ATTRIBUTE_UNUSED) -- { --+ if (TARGET_HARD_FLOAT && (mode == SFmode || mode == DFmode)) --+ return gen_rtx_REG (mode, NDS32_FPR_RET_FIRST_REGNUM); --+ -- return gen_rtx_REG (mode, NDS32_GPR_RET_FIRST_REGNUM); -- } -- -- static bool -- nds32_function_value_regno_p (const unsigned int regno) -- { --- return (regno == NDS32_GPR_RET_FIRST_REGNUM); --+ if (regno == NDS32_GPR_RET_FIRST_REGNUM --+ || (TARGET_HARD_FLOAT --+ && regno == NDS32_FPR_RET_FIRST_REGNUM)) --+ return true; --+ --+ return false; --+} --+ --+/* -- How Large Values Are Returned. */ --+ --+static bool --+nds32_return_in_memory (const_tree type, --+ const_tree fntype ATTRIBUTE_UNUSED) --+{ --+ /* Note that int_size_in_bytes can return -1 if the size can vary --+ or is larger than an integer. */ --+ HOST_WIDE_INT size = int_size_in_bytes (type); --+ --+ /* For COMPLEX_TYPE, if the total size cannot be hold within two registers, --+ the return value is supposed to be in memory. We need to be aware of --+ that the size may be -1. */ --+ if (TREE_CODE (type) == COMPLEX_TYPE) --+ if (size < 0 || size > 2 * UNITS_PER_WORD) --+ return true; --+ --+ /* If it is BLKmode and the total size cannot be hold within two registers, --+ the return value is supposed to be in memory. We need to be aware of --+ that the size may be -1. */ --+ if (TYPE_MODE (type) == BLKmode) --+ if (size < 0 || size > 2 * UNITS_PER_WORD) --+ return true; --+ --+ /* For other cases, having result in memory is unnecessary. */ --+ return false; -- } -- -- /* -- Function Entry and Exit. */ --@@ -1522,7 +2357,7 @@ nds32_asm_function_prologue (FILE *file, -- /* Use df_regs_ever_live_p() to detect if the register -- is ever used in the current function. */ -- fprintf (file, "\t! registers ever_live: "); --- for (r = 0; r < 32; r++) --+ for (r = 0; r < 65; r++) -- { -- if (df_regs_ever_live_p (r)) -- fprintf (file, "%s, ", reg_names[r]); --@@ -1554,6 +2389,10 @@ nds32_asm_function_prologue (FILE *file, -- attrs = TREE_CHAIN (attrs); -- } -- fputc ('\n', file); --+ --+ /* If there is any critical isr in this file, disable linker ifc. */ --+ if (nds32_isr_function_critical_p (current_function_decl)) --+ fprintf (file, "\t.no_relax ifc\n"); -- } -- -- /* After rtl prologue has been expanded, this function is used. */ --@@ -1561,56 +2400,12 @@ static void -- nds32_asm_function_end_prologue (FILE *file) -- { -- fprintf (file, "\t! END PROLOGUE\n"); --- --- /* If frame pointer is NOT needed and -mfp-as-gp is issued, --- we can generate special directive: ".omit_fp_begin" --- to guide linker doing fp-as-gp optimization. --- However, for a naked function, which means --- it should not have prologue/epilogue, --- using fp-as-gp still requires saving $fp by push/pop behavior and --- there is no benefit to use fp-as-gp on such small function. --- So we need to make sure this function is NOT naked as well. */ --- if (!frame_pointer_needed --- && !cfun->machine->naked_p --- && cfun->machine->fp_as_gp_p) --- { --- fprintf (file, "\t! ----------------------------------------\n"); --- fprintf (file, "\t! Guide linker to do " --- "link time optimization: fp-as-gp\n"); --- fprintf (file, "\t! We add one more instruction to " --- "initialize $fp near to $gp location.\n"); --- fprintf (file, "\t! If linker fails to use fp-as-gp transformation,\n"); --- fprintf (file, "\t! this extra instruction should be " --- "eliminated at link stage.\n"); --- fprintf (file, "\t.omit_fp_begin\n"); --- fprintf (file, "\tla\t$fp,_FP_BASE_\n"); --- fprintf (file, "\t! ----------------------------------------\n"); --- } -- } -- -- /* Before rtl epilogue has been expanded, this function is used. */ -- static void -- nds32_asm_function_begin_epilogue (FILE *file) -- { --- /* If frame pointer is NOT needed and -mfp-as-gp is issued, --- we can generate special directive: ".omit_fp_end" --- to claim fp-as-gp optimization range. --- However, for a naked function, --- which means it should not have prologue/epilogue, --- using fp-as-gp still requires saving $fp by push/pop behavior and --- there is no benefit to use fp-as-gp on such small function. --- So we need to make sure this function is NOT naked as well. */ --- if (!frame_pointer_needed --- && !cfun->machine->naked_p --- && cfun->machine->fp_as_gp_p) --- { --- fprintf (file, "\t! ----------------------------------------\n"); --- fprintf (file, "\t! Claim the range of fp-as-gp " --- "link time optimization\n"); --- fprintf (file, "\t.omit_fp_end\n"); --- fprintf (file, "\t! ----------------------------------------\n"); --- } --- -- fprintf (file, "\t! BEGIN EPILOGUE\n"); -- } -- --@@ -1638,41 +2433,104 @@ nds32_asm_output_mi_thunk (FILE *file, tree thunk ATTRIBUTE_UNUSED, -- ? 1 -- : 0); -- --+ if (flag_pic) --+ { --+ fprintf (file, "\tsmw.adm\t$r31, [$r31], $r31, 4\n"); --+ fprintf (file, "\tsethi\t%s, hi20(_GLOBAL_OFFSET_TABLE_-8)\n", --+ reg_names [PIC_OFFSET_TABLE_REGNUM]); --+ fprintf (file, "\tori\t%s, %s, lo12(_GLOBAL_OFFSET_TABLE_-4)\n", --+ reg_names [PIC_OFFSET_TABLE_REGNUM], --+ reg_names [PIC_OFFSET_TABLE_REGNUM]); --+ --+ if (TARGET_ISA_V3) --+ fprintf (file, "\tadd5.pc\t$gp\n"); --+ else --+ { --+ fprintf (file, "\tmfusr\t$ta, $pc\n"); --+ fprintf (file, "\tadd\t%s, $ta, %s\n", --+ reg_names [PIC_OFFSET_TABLE_REGNUM], --+ reg_names [PIC_OFFSET_TABLE_REGNUM]); --+ } --+ } --+ -- if (delta != 0) -- { -- if (satisfies_constraint_Is15 (GEN_INT (delta))) -- { --- fprintf (file, "\taddi\t$r%d, $r%d, %ld\n", --+ fprintf (file, "\taddi\t$r%d, $r%d, " HOST_WIDE_INT_PRINT_DEC "\n", -- this_regno, this_regno, delta); -- } -- else if (satisfies_constraint_Is20 (GEN_INT (delta))) -- { --- fprintf (file, "\tmovi\t$ta, %ld\n", delta); --+ fprintf (file, "\tmovi\t$ta, " HOST_WIDE_INT_PRINT_DEC "\n", delta); -- fprintf (file, "\tadd\t$r%d, $r%d, $ta\n", this_regno, this_regno); -- } -- else -- { --- fprintf (file, "\tsethi\t$ta, hi20(%ld)\n", delta); --- fprintf (file, "\tori\t$ta, $ta, lo12(%ld)\n", delta); --+ fprintf (file, --+ "\tsethi\t$ta, hi20(" HOST_WIDE_INT_PRINT_DEC ")\n", --+ delta); --+ fprintf (file, --+ "\tori\t$ta, $ta, lo12(" HOST_WIDE_INT_PRINT_DEC ")\n", --+ delta); -- fprintf (file, "\tadd\t$r%d, $r%d, $ta\n", this_regno, this_regno); -- } -- } -- --- fprintf (file, "\tb\t"); --- assemble_name (file, XSTR (XEXP (DECL_RTL (function), 0), 0)); --- fprintf (file, "\n"); --+ if (flag_pic) --+ { --+ fprintf (file, "\tla\t$ta, "); --+ assemble_name (file, XSTR (XEXP (DECL_RTL (function), 0), 0)); --+ fprintf (file, "@PLT\n"); --+ fprintf (file, "\t! epilogue\n"); --+ fprintf (file, "\tlwi.bi\t%s, [%s], 4\n", --+ reg_names[PIC_OFFSET_TABLE_REGNUM], --+ reg_names[STACK_POINTER_REGNUM]); --+ fprintf (file, "\tbr\t$ta\n"); --+ } --+ else --+ { --+ fprintf (file, "\tb\t"); --+ assemble_name (file, XSTR (XEXP (DECL_RTL (function), 0), 0)); --+ fprintf (file, "\n"); --+ } -- -- final_end_function (); -- } -- -- /* -- Permitting tail calls. */ -- --+/* Return true if it is ok to do sibling call optimization. */ --+static bool --+nds32_function_ok_for_sibcall (tree decl, --+ tree exp ATTRIBUTE_UNUSED) --+{ --+ /* The DECL is NULL if it is an indirect call. */ --+ --+ /* 1. Do not apply sibling call if -mv3push is enabled, --+ because pop25 instruction also represents return behavior. --+ 2. If this function is a isr function, do not apply sibling call --+ because it may perform the behavior that user does not expect. --+ 3. If this function is a variadic function, do not apply sibling call --+ because the stack layout may be a mess. --+ 4. We don't want to apply sibling call optimization for indirect --+ sibcall because the pop behavior in epilogue may pollute the --+ content of caller-saved regsiter when the register is used for --+ indirect sibcall. --+ 5. In pic mode, it may use some registers for PLT call. */ --+ return (!TARGET_V3PUSH --+ && !nds32_isr_function_p (current_function_decl) --+ && (cfun->machine->va_args_size == 0) --+ && decl --+ && !flag_pic); --+} --+ -- /* Determine whether we need to enable warning for function return check. */ -- static bool -- nds32_warn_func_return (tree decl) -- { ---/* Naked functions are implemented entirely in assembly, including the --- return sequence, so suppress warnings about this. */ --+ /* Naked functions are implemented entirely in assembly, including the --+ return sequence, so suppress warnings about this. */ -- return !nds32_naked_function_p (decl); -- } -- --@@ -1681,7 +2539,7 @@ nds32_warn_func_return (tree decl) -- -- static void -- nds32_setup_incoming_varargs (cumulative_args_t ca, --- machine_mode mode, --+ enum machine_mode mode, -- tree type, -- int *pretend_args_size, -- int second_time ATTRIBUTE_UNUSED) --@@ -1795,7 +2653,7 @@ nds32_trampoline_init (rtx m_tramp, tree fndecl, rtx chain_value) -- sorry ("a nested function is not supported for reduced registers"); -- -- /* STEP 1: Copy trampoline code template into stack, --- fill up essential data into stack. */ --+ fill up essential data into stack. */ -- -- /* Extract nested function address rtx. */ -- fnaddr = XEXP (DECL_RTL (fndecl), 0); --@@ -1831,8 +2689,8 @@ nds32_trampoline_init (rtx m_tramp, tree fndecl, rtx chain_value) -- && (tramp_align_in_bytes % nds32_cache_block_size) == 0) -- { -- /* Under this condition, the starting address of trampoline --- must be aligned to the starting address of each cache block --- and we do not have to worry about cross-boundary issue. */ --+ must be aligned to the starting address of each cache block --+ and we do not have to worry about cross-boundary issue. */ -- for (i = 0; -- i < (TRAMPOLINE_SIZE + nds32_cache_block_size - 1) -- / nds32_cache_block_size; --@@ -1847,10 +2705,10 @@ nds32_trampoline_init (rtx m_tramp, tree fndecl, rtx chain_value) -- else if (TRAMPOLINE_SIZE > nds32_cache_block_size) -- { -- /* The starting address of trampoline code --- may not be aligned to the cache block, --- so the trampoline code may be across two cache block. --- We need to sync the last element, which is 4-byte size, --- of trampoline template. */ --+ may not be aligned to the cache block, --+ so the trampoline code may be across two cache block. --+ We need to sync the last element, which is 4-byte size, --+ of trampoline template. */ -- for (i = 0; -- i < (TRAMPOLINE_SIZE + nds32_cache_block_size - 1) -- / nds32_cache_block_size; --@@ -1871,16 +2729,16 @@ nds32_trampoline_init (rtx m_tramp, tree fndecl, rtx chain_value) -- else -- { -- /* This is the simplest case. --- Because TRAMPOLINE_SIZE is less than or --- equal to nds32_cache_block_size, --- we can just sync start address and --- the last element of trampoline code. */ --+ Because TRAMPOLINE_SIZE is less than or --+ equal to nds32_cache_block_size, --+ we can just sync start address and --+ the last element of trampoline code. */ -- -- /* Sync starting address of tampoline code. */ -- emit_move_insn (tmp_reg, sync_cache_addr); -- emit_insn (isync_insn); -- /* Sync the last element, which is 4-byte size, --- of trampoline template. */ --+ of trampoline template. */ -- emit_move_insn (tmp_reg, -- plus_constant (Pmode, sync_cache_addr, -- TRAMPOLINE_SIZE - 4)); --@@ -1896,11 +2754,52 @@ nds32_trampoline_init (rtx m_tramp, tree fndecl, rtx chain_value) -- /* Addressing Modes. */ -- -- static bool ---nds32_legitimate_address_p (machine_mode mode, rtx x, bool strict) --+nds32_legitimate_address_p (enum machine_mode mode, rtx x, bool strict) -- { --+ if (TARGET_FPU_SINGLE || TARGET_FPU_DOUBLE) --+ { --+ /* When using floating-point instructions, --+ we don't allow 'addr' to be [symbol_ref], [CONST] pattern. */ --+ if ((mode == DFmode || mode == SFmode) --+ && (GET_CODE (x) == SYMBOL_REF --+ || GET_CODE(x) == CONST)) --+ return false; --+ --+ /* Allow [post_modify] addressing mode, when using FPU instructions. */ --+ if (GET_CODE (x) == POST_MODIFY --+ && mode == DFmode) --+ { --+ if (GET_CODE (XEXP (x, 0)) == REG --+ && GET_CODE (XEXP (x, 1)) == PLUS) --+ { --+ rtx plus_op = XEXP (x, 1); --+ rtx op0 = XEXP (plus_op, 0); --+ rtx op1 = XEXP (plus_op, 1); --+ --+ if (nds32_address_register_rtx_p (op0, strict) --+ && CONST_INT_P (op1)) --+ { --+ if (satisfies_constraint_Is14 (op1)) --+ { --+ /* If it is not under strictly aligned situation, --+ we can return true without checking alignment. */ --+ if (!cfun->machine->strict_aligned_p) --+ return true; --+ /* Make sure address is word alignment. --+ Currently we do not have 64-bit load/store yet, --+ so we will use two 32-bit load/store instructions to do --+ memory access and they are single word alignment. */ --+ else if (NDS32_SINGLE_WORD_ALIGN_P (INTVAL (op1))) --+ return true; --+ } --+ } --+ } --+ } --+ } --+ -- /* For (mem:DI addr) or (mem:DF addr) case, -- we only allow 'addr' to be [reg], [symbol_ref], --- [const], or [reg + const_int] pattern. */ --+ [const], or [reg + const_int] pattern. */ -- if (mode == DImode || mode == DFmode) -- { -- /* Allow [Reg + const_int] addressing mode. */ --@@ -1910,13 +2809,19 @@ nds32_legitimate_address_p (machine_mode mode, rtx x, bool strict) -- && nds32_legitimate_index_p (mode, XEXP (x, 1), strict) -- && CONST_INT_P (XEXP (x, 1))) -- return true; --- -- else if (nds32_address_register_rtx_p (XEXP (x, 1), strict) -- && nds32_legitimate_index_p (mode, XEXP (x, 0), strict) -- && CONST_INT_P (XEXP (x, 0))) -- return true; -- } -- --+ /* Allow [post_inc] and [post_dec] addressing mode. */ --+ if (GET_CODE (x) == POST_INC || GET_CODE (x) == POST_DEC) --+ { --+ if (nds32_address_register_rtx_p (XEXP (x, 0), strict)) --+ return true; --+ } --+ -- /* Now check [reg], [symbol_ref], and [const]. */ -- if (GET_CODE (x) != REG -- && GET_CODE (x) != SYMBOL_REF --@@ -1933,18 +2838,26 @@ nds32_legitimate_address_p (machine_mode mode, rtx x, bool strict) -- -- case SYMBOL_REF: -- /* (mem (symbol_ref A)) => [symbol_ref] */ --+ --+ if (flag_pic || SYMBOL_REF_TLS_MODEL (x)) --+ return false; --+ --+ if (TARGET_ICT_MODEL_LARGE && nds32_indirect_call_referenced_p (x)) --+ return false; --+ -- /* If -mcmodel=large, the 'symbol_ref' is not a valid address --- during or after LRA/reload phase. */ --+ during or after LRA/reload phase. */ -- if (TARGET_CMODEL_LARGE -- && (reload_completed -- || reload_in_progress -- || lra_in_progress)) -- return false; -- /* If -mcmodel=medium and the symbol references to rodata section, --- the 'symbol_ref' is not a valid address during or after --- LRA/reload phase. */ --+ the 'symbol_ref' is not a valid address during or after --+ LRA/reload phase. */ -- if (TARGET_CMODEL_MEDIUM --- && NDS32_SYMBOL_REF_RODATA_P (x) --+ && (NDS32_SYMBOL_REF_RODATA_P (x) --+ || CONSTANT_POOL_ADDRESS_P (x)) -- && (reload_completed -- || reload_in_progress -- || lra_in_progress)) --@@ -1954,7 +2867,7 @@ nds32_legitimate_address_p (machine_mode mode, rtx x, bool strict) -- -- case CONST: -- /* (mem (const (...))) --- => [ + const_addr ], where const_addr = symbol_ref + const_int */ --+ => [ + const_addr ], where const_addr = symbol_ref + const_int */ -- if (GET_CODE (XEXP (x, 0)) == PLUS) -- { -- rtx plus_op = XEXP (x, 0); --@@ -1965,17 +2878,21 @@ nds32_legitimate_address_p (machine_mode mode, rtx x, bool strict) -- if (GET_CODE (op0) == SYMBOL_REF && CONST_INT_P (op1)) -- { -- /* Now we see the [ + const_addr ] pattern, but we need --- some further checking. */ --+ some further checking. */ --+ --+ if (flag_pic) --+ return false; --+ -- /* If -mcmodel=large, the 'const_addr' is not a valid address --- during or after LRA/reload phase. */ --+ during or after LRA/reload phase. */ -- if (TARGET_CMODEL_LARGE -- && (reload_completed -- || reload_in_progress -- || lra_in_progress)) -- return false; -- /* If -mcmodel=medium and the symbol references to rodata section, --- the 'const_addr' is not a valid address during or after --- LRA/reload phase. */ --+ the 'const_addr' is not a valid address during or after --+ LRA/reload phase. */ -- if (TARGET_CMODEL_MEDIUM -- && NDS32_SYMBOL_REF_RODATA_P (op0) -- && (reload_completed --@@ -1993,9 +2910,9 @@ nds32_legitimate_address_p (machine_mode mode, rtx x, bool strict) -- -- case POST_MODIFY: -- /* (mem (post_modify (reg) (plus (reg) (reg)))) --- => [Ra], Rb */ --+ => [Ra], Rb */ -- /* (mem (post_modify (reg) (plus (reg) (const_int)))) --- => [Ra], const_int */ --+ => [Ra], const_int */ -- if (GET_CODE (XEXP (x, 0)) == REG -- && GET_CODE (XEXP (x, 1)) == PLUS) -- { --@@ -2018,7 +2935,7 @@ nds32_legitimate_address_p (machine_mode mode, rtx x, bool strict) -- /* (mem (post_inc reg)) => [Ra], 1/2/4 */ -- /* (mem (post_dec reg)) => [Ra], -1/-2/-4 */ -- /* The 1/2/4 or -1/-2/-4 have been displayed in nds32.md. --- We only need to deal with register Ra. */ --+ We only need to deal with register Ra. */ -- if (nds32_address_register_rtx_p (XEXP (x, 0), strict)) -- return true; -- else --@@ -2026,11 +2943,11 @@ nds32_legitimate_address_p (machine_mode mode, rtx x, bool strict) -- -- case PLUS: -- /* (mem (plus reg const_int)) --- => [Ra + imm] */ --+ => [Ra + imm] */ -- /* (mem (plus reg reg)) --- => [Ra + Rb] */ --+ => [Ra + Rb] */ -- /* (mem (plus (mult reg const_int) reg)) --- => [Ra + Rb << sv] */ --+ => [Ra + Rb << sv] */ -- if (nds32_address_register_rtx_p (XEXP (x, 0), strict) -- && nds32_legitimate_index_p (mode, XEXP (x, 1), strict)) -- return true; --@@ -2042,39 +2959,292 @@ nds32_legitimate_address_p (machine_mode mode, rtx x, bool strict) -- -- case LO_SUM: -- /* (mem (lo_sum (reg) (symbol_ref))) */ --- /* (mem (lo_sum (reg) (const))) */ --- gcc_assert (REG_P (XEXP (x, 0))); --- if (GET_CODE (XEXP (x, 1)) == SYMBOL_REF --- || GET_CODE (XEXP (x, 1)) == CONST) --- return nds32_legitimate_address_p (mode, XEXP (x, 1), strict); --- else --+ /* (mem (lo_sum (reg) (const (plus (symbol_ref) (reg)))) */ --+ /* TLS case: (mem (lo_sum (reg) (const (unspec symbol_ref X)))) */ --+ /* The LO_SUM is a valid address if and only if we would like to --+ generate 32-bit full address memory access with any of following --+ circumstance: --+ 1. -mcmodel=large. --+ 2. -mcmodel=medium and the symbol_ref references to rodata. */ --+ { --+ rtx sym = NULL_RTX; --+ --+ if (flag_pic) --+ return false; --+ --+ if (!REG_P (XEXP (x, 0))) --+ return false; --+ --+ if (GET_CODE (XEXP (x, 1)) == SYMBOL_REF) --+ sym = XEXP (x, 1); --+ else if (GET_CODE (XEXP (x, 1)) == CONST) --+ { --+ rtx plus = XEXP(XEXP (x, 1), 0); --+ if (GET_CODE (plus) == PLUS) --+ sym = XEXP (plus, 0); --+ else if (GET_CODE (plus) == UNSPEC) --+ sym = XVECEXP (plus, 0, 0); --+ } --+ else --+ return false; --+ --+ gcc_assert (GET_CODE (sym) == SYMBOL_REF); --+ --+ if (TARGET_ICT_MODEL_LARGE --+ && nds32_indirect_call_referenced_p (sym)) --+ return true; --+ --+ if (TARGET_CMODEL_LARGE) --+ return true; --+ else if (TARGET_CMODEL_MEDIUM --+ && NDS32_SYMBOL_REF_RODATA_P (sym)) --+ return true; --+ else --+ return false; --+ } --+ --+ default: --+ return false; --+ } --+} --+ --+static rtx --+nds32_legitimize_address (rtx x, --+ rtx oldx ATTRIBUTE_UNUSED, --+ enum machine_mode mode ATTRIBUTE_UNUSED) --+{ --+ if (nds32_tls_referenced_p (x)) --+ x = nds32_legitimize_tls_address (x); --+ else if (flag_pic && SYMBOLIC_CONST_P (x)) --+ x = nds32_legitimize_pic_address (x); --+ else if (TARGET_ICT_MODEL_LARGE && nds32_indirect_call_referenced_p (x)) --+ x = nds32_legitimize_ict_address (x); --+ --+ return x; --+} --+ --+static bool --+nds32_legitimate_constant_p (enum machine_mode mode, rtx x) --+{ --+ switch (GET_CODE (x)) --+ { --+ case CONST_DOUBLE: --+ if ((TARGET_FPU_SINGLE || TARGET_FPU_DOUBLE) --+ && (mode == DFmode || mode == SFmode)) --+ return false; --+ break; --+ case CONST: --+ x = XEXP (x, 0); --+ --+ if (GET_CODE (x) == PLUS) --+ { --+ if (!CONST_INT_P (XEXP (x, 1))) --+ return false; --+ x = XEXP (x, 0); --+ } --+ --+ if (GET_CODE (x) == UNSPEC) --+ { --+ switch (XINT (x, 1)) --+ { --+ case UNSPEC_GOT: --+ case UNSPEC_GOTOFF: --+ case UNSPEC_PLT: --+ case UNSPEC_TLSGD: --+ case UNSPEC_TLSLD: --+ case UNSPEC_TLSIE: --+ case UNSPEC_TLSLE: --+ case UNSPEC_ICT: --+ return false; --+ default: --+ return true; --+ } --+ } --+ break; --+ case SYMBOL_REF: --+ /* TLS symbols need a call to resolve in --+ precompute_register_parameters. */ --+ if (SYMBOL_REF_TLS_MODEL (x)) -- return false; --+ break; --+ default: --+ return true; --+ } --+ --+ return true; --+} --+ --+/* Reorgnize the UNSPEC CONST and return its direct symbol. */ --+static rtx --+nds32_delegitimize_address (rtx x) --+{ --+ x = delegitimize_mem_from_attrs (x); --+ --+ if (GET_CODE(x) == CONST) --+ { --+ rtx inner = XEXP (x, 0); --+ --+ /* Handle for GOTOFF. */ --+ if (GET_CODE (inner) == PLUS) --+ inner = XEXP (inner, 0); --+ --+ if (GET_CODE (inner) == UNSPEC) --+ { --+ switch (XINT (inner, 1)) --+ { --+ case UNSPEC_GOTINIT: --+ case UNSPEC_GOT: --+ case UNSPEC_GOTOFF: --+ case UNSPEC_PLT: --+ case UNSPEC_TLSGD: --+ case UNSPEC_TLSLD: --+ case UNSPEC_TLSIE: --+ case UNSPEC_TLSLE: --+ case UNSPEC_ICT: --+ x = XVECEXP (inner, 0, 0); --+ break; --+ default: --+ break; --+ } --+ } --+ } --+ return x; --+} --+ --+static enum machine_mode --+nds32_vectorize_preferred_simd_mode (enum machine_mode mode) --+{ --+ if (!NDS32_EXT_DSP_P ()) --+ return word_mode; --+ --+ switch (mode) --+ { --+ case QImode: --+ return V4QImode; --+ case HImode: --+ return V2HImode; --+ default: --+ return word_mode; --+ } --+} -- --+static bool --+nds32_cannot_force_const_mem (enum machine_mode mode ATTRIBUTE_UNUSED, rtx x) --+{ --+ switch (GET_CODE (x)) --+ { --+ case CONST: --+ return !nds32_legitimate_constant_p (mode, x); --+ case SYMBOL_REF: --+ /* All symbols have to be accessed through gp-relative in PIC mode. */ --+ /* We don't want to force symbol as constant pool in .text section, --+ because we use the gp-relatived instruction to load in small --+ or medium model. */ --+ if (flag_pic --+ || SYMBOL_REF_TLS_MODEL (x) --+ || TARGET_CMODEL_SMALL --+ || TARGET_CMODEL_MEDIUM) --+ return true; --+ break; --+ case CONST_INT: --+ case CONST_DOUBLE: --+ if (flag_pic && (lra_in_progress || reload_completed)) --+ return true; --+ break; -- default: -- return false; -- } --+ return false; --+} --+ --+ --+/* Condition Code Status. */ --+ --+/* -- Representation of condition codes using registers. */ --+ --+static void --+nds32_canonicalize_comparison (int *code, --+ rtx *op0 ATTRIBUTE_UNUSED, --+ rtx *op1, --+ bool op0_preserve_value ATTRIBUTE_UNUSED) --+{ --+ /* When the instruction combination pass tries to combine a comparison insn --+ with its previous insns, it also transforms the operator in order to --+ minimize its constant field. For example, it tries to transform a --+ comparison insn from --+ (set (reg:SI 54) --+ (ltu:SI (reg:SI 52) --+ (const_int 10 [0xa]))) --+ to --+ (set (reg:SI 54) --+ (leu:SI (reg:SI 52) --+ (const_int 9 [0x9]))) --+ --+ However, the nds32 target only provides instructions supporting the LTU --+ operation directly, and the implementation of the pattern "cbranchsi4" --+ only expands the LTU form. In order to handle the non-LTU operations --+ generated from passes other than the RTL expansion pass, we have to --+ implement this hook to revert those changes. Since we only expand the LTU --+ operator in the RTL expansion pass, we might only need to handle the LEU --+ case, unless we find other optimization passes perform more aggressive --+ transformations. */ --+ --+ if (*code == LEU && CONST_INT_P (*op1)) --+ { --+ *op1 = gen_int_mode (INTVAL (*op1) + 1, SImode); --+ *code = LTU; --+ } -- } -- -- -- /* Describing Relative Costs of Operations. */ -- -- static int ---nds32_register_move_cost (machine_mode mode ATTRIBUTE_UNUSED, --+nds32_register_move_cost (enum machine_mode mode, -- reg_class_t from, -- reg_class_t to) -- { --- if (from == HIGH_REGS || to == HIGH_REGS) --- return 6; --+ /* In garywolf cpu, FPR to GPR is chaper than other cpu. */ --+ if (TARGET_PIPELINE_GRAYWOLF) --+ { --+ if (GET_MODE_SIZE (mode) == 8) --+ { --+ /* DPR to GPR. */ --+ if (from == FP_REGS && to != FP_REGS) --+ return 3; --+ /* GPR to DPR. */ --+ if (from != FP_REGS && to == FP_REGS) --+ return 2; --+ } --+ else --+ { --+ if ((from == FP_REGS && to != FP_REGS) --+ || (from != FP_REGS && to == FP_REGS)) --+ return 2; --+ } --+ } -- --- return 2; --+ if ((from == FP_REGS && to != FP_REGS) --+ || (from != FP_REGS && to == FP_REGS)) --+ return 3; --+ else if (from == HIGH_REGS || to == HIGH_REGS) --+ return optimize_size ? 6 : 2; --+ else --+ return 2; -- } -- -- static int ---nds32_memory_move_cost (machine_mode mode ATTRIBUTE_UNUSED, --+nds32_memory_move_cost (enum machine_mode mode ATTRIBUTE_UNUSED, -- reg_class_t rclass ATTRIBUTE_UNUSED, -- bool in ATTRIBUTE_UNUSED) -- { --- return 8; --+ /* Memory access is only need 1 cycle in our low-end processor, --+ however memory access is most 4-byte instruction, --+ so let it 8 for optimize_size, otherwise be 2. */ --+ if (nds32_memory_model_option == MEMORY_MODEL_FAST) --+ return optimize_size ? 8 : 4; --+ else --+ return 8; -- } -- -- /* This target hook describes the relative costs of RTL expressions. --@@ -2094,7 +3264,7 @@ nds32_rtx_costs (rtx x, -- -- static int -- nds32_address_cost (rtx address, --- machine_mode mode, --+ enum machine_mode mode, -- addr_space_t as, -- bool speed) -- { --@@ -2102,6 +3272,55 @@ nds32_address_cost (rtx address, -- } -- -- --+/* Adjusting the Instruction Scheduler. */ --+ --+static int --+nds32_sched_issue_rate (void) --+{ --+ switch (nds32_cpu_option) --+ { --+ case CPU_GRAYWOLF: --+ case CPU_PANTHER: --+ return 2; --+ --+ default: --+ return 1; --+ } --+} --+ --+static int --+nds32_sched_adjust_cost (rtx_insn *insn ATTRIBUTE_UNUSED, rtx link, rtx_insn *dep ATTRIBUTE_UNUSED, int cost) --+{ --+ if (REG_NOTE_KIND (link) == REG_DEP_ANTI --+ || REG_NOTE_KIND (link) == REG_DEP_OUTPUT) --+ { --+ if (nds32_sched_issue_rate () > 1) --+ return 1; --+ --+ return 0; --+ } --+ --+ return cost; --+} --+ --+static void --+nds32_set_sched_flags (spec_info_t spec_info ATTRIBUTE_UNUSED) --+{ --+ if (!flag_reorg_out_of_order --+ || nds32_sched_issue_rate () < 2) --+ return; --+ --+ unsigned int *flags = &(current_sched_info->flags); --+ --+ // Disallow the sheculder to find inc/mem pairs and break dependencies by --+ // duplication address computations. Otherwise, after doing so, the --+ // scheduler will treat that the two insns can be issued at the same cycle --+ // so that the later insn isn't marked as TImode. It will result in a wrong --+ // behavior for out-of-order reorganization. --+ *flags |= DONT_BREAK_DEPENDENCIES; --+} --+ --+ -- /* Dividing the Output into Sections (Texts, Data, . . . ). */ -- -- /* If references to a symbol or a constant must be treated differently --@@ -2150,17 +3369,56 @@ nds32_asm_file_start (void) -- { -- default_file_start (); -- --+ if (flag_pic) --+ fprintf (asm_out_file, "\t.pic\n"); --+ -- /* Tell assembler which ABI we are using. */ -- fprintf (asm_out_file, "\t! ABI version\n"); --- fprintf (asm_out_file, "\t.abi_2\n"); --+ if (TARGET_HARD_FLOAT) --+ fprintf (asm_out_file, "\t.abi_2fp_plus\n"); --+ else --+ fprintf (asm_out_file, "\t.abi_2\n"); -- -- /* Tell assembler that this asm code is generated by compiler. */ -- fprintf (asm_out_file, "\t! This asm file is generated by compiler\n"); -- fprintf (asm_out_file, "\t.flag\tverbatim\n"); --- /* Give assembler the size of each vector for interrupt handler. */ --- fprintf (asm_out_file, "\t! This vector size directive is required " --- "for checking inconsistency on interrupt handler\n"); --- fprintf (asm_out_file, "\t.vec_size\t%d\n", nds32_isr_vector_size); --+ --+ /* We need to provide the size of each vector for interrupt handler --+ under elf toolchain. */ --+ if (!TARGET_LINUX_ABI) --+ { --+ fprintf (asm_out_file, "\t! This vector size directive is required " --+ "for checking inconsistency on interrupt handler\n"); --+ fprintf (asm_out_file, "\t.vec_size\t%d\n", nds32_isr_vector_size); --+ } --+ --+ /* If user enables '-mforce-fp-as-gp' or compiles programs with -Os, --+ the compiler may produce 'la $fp,_FP_BASE_' instruction --+ at prologue for fp-as-gp optimization. --+ We should emit weak reference of _FP_BASE_ to avoid undefined reference --+ in case user does not pass '--relax' option to linker. */ --+ if (!TARGET_LINUX_ABI && (TARGET_FORCE_FP_AS_GP || optimize_size)) --+ { --+ fprintf (asm_out_file, "\t! This weak reference is required to do " --+ "fp-as-gp link time optimization\n"); --+ fprintf (asm_out_file, "\t.weak\t_FP_BASE_\n"); --+ } --+ /* If user enables '-mifc', we should emit relaxation directive --+ to tell linker that this file is allowed to do ifc optimization. */ --+ if (TARGET_IFC) --+ { --+ fprintf (asm_out_file, "\t! This relaxation directive is required " --+ "to do ifc link time optimization\n"); --+ fprintf (asm_out_file, "\t.relax\tifc\n"); --+ } --+ /* If user enables '-mex9', we should emit relaxation directive --+ to tell linker that this file is allowed to do ex9 optimization. */ --+ if (TARGET_EX9) --+ { --+ fprintf (asm_out_file, "\t! This relaxation directive is required " --+ "to do ex9 link time optimization\n"); --+ fprintf (asm_out_file, "\t.relax\tex9\n"); --+ } -- -- fprintf (asm_out_file, "\t! ------------------------------------\n"); -- --@@ -2171,6 +3429,53 @@ nds32_asm_file_start (void) -- if (TARGET_ISA_V3M) -- fprintf (asm_out_file, "\t! ISA family\t\t: %s\n", "V3M"); -- --+ switch (nds32_cpu_option) --+ { --+ case CPU_N6: --+ fprintf (asm_out_file, "\t! Pipeline model\t: %s\n", "N6"); --+ break; --+ --+ case CPU_N7: --+ fprintf (asm_out_file, "\t! Pipeline model\t: %s\n", "N7"); --+ break; --+ --+ case CPU_N8: --+ fprintf (asm_out_file, "\t! Pipeline model\t: %s\n", "N8"); --+ break; --+ --+ case CPU_E8: --+ fprintf (asm_out_file, "\t! Pipeline model\t: %s\n", "E8"); --+ break; --+ --+ case CPU_N9: --+ fprintf (asm_out_file, "\t! Pipeline model\t: %s\n", "N9"); --+ break; --+ --+ case CPU_N10: --+ fprintf (asm_out_file, "\t! Pipeline model\t: %s\n", "N10"); --+ break; --+ --+ case CPU_GRAYWOLF: --+ fprintf (asm_out_file, "\t! Pipeline model\t: %s\n", "Graywolf"); --+ break; --+ --+ case CPU_N12: --+ case CPU_N13: --+ fprintf (asm_out_file, "\t! Pipeline model\t: %s\n", "N13"); --+ break; --+ --+ case CPU_PANTHER: --+ fprintf (asm_out_file, "\t! Pipeline model\t: %s\n", "Panther"); --+ break; --+ --+ case CPU_SIMPLE: --+ fprintf (asm_out_file, "\t! Pipeline model\t: %s\n", "SIMPLE"); --+ break; --+ --+ default: --+ gcc_unreachable (); --+ } --+ -- if (TARGET_CMODEL_SMALL) -- fprintf (asm_out_file, "\t! Code model\t\t: %s\n", "SMALL"); -- if (TARGET_CMODEL_MEDIUM) --@@ -2181,6 +3486,15 @@ nds32_asm_file_start (void) -- fprintf (asm_out_file, "\t! Endian setting\t: %s\n", -- ((TARGET_BIG_ENDIAN) ? "big-endian" -- : "little-endian")); --+ fprintf (asm_out_file, "\t! Use SP floating-point instruction\t: %s\n", --+ ((TARGET_FPU_SINGLE) ? "Yes" --+ : "No")); --+ fprintf (asm_out_file, "\t! Use DP floating-point instruction\t: %s\n", --+ ((TARGET_FPU_DOUBLE) ? "Yes" --+ : "No")); --+ fprintf (asm_out_file, "\t! ABI version\t\t: %s\n", --+ ((TARGET_HARD_FLOAT) ? "ABI2FP+" --+ : "ABI2")); -- -- fprintf (asm_out_file, "\t! ------------------------------------\n"); -- --@@ -2188,8 +3502,14 @@ nds32_asm_file_start (void) -- ((TARGET_CMOV) ? "Yes" -- : "No")); -- fprintf (asm_out_file, "\t! Use performance extension\t: %s\n", --- ((TARGET_PERF_EXT) ? "Yes" --+ ((TARGET_EXT_PERF) ? "Yes" -- : "No")); --+ fprintf (asm_out_file, "\t! Use performance extension 2\t: %s\n", --+ ((TARGET_EXT_PERF2) ? "Yes" --+ : "No")); --+ fprintf (asm_out_file, "\t! Use string extension\t\t: %s\n", --+ ((TARGET_EXT_STRING) ? "Yes" --+ : "No")); -- -- fprintf (asm_out_file, "\t! ------------------------------------\n"); -- --@@ -2203,10 +3523,18 @@ nds32_asm_file_start (void) -- ((TARGET_REDUCED_REGS) ? "Yes" -- : "No")); -- --+ fprintf (asm_out_file, "\t! Support unaligned access\t\t: %s\n", --+ (flag_unaligned_access ? "Yes" --+ : "No")); --+ -- fprintf (asm_out_file, "\t! ------------------------------------\n"); -- -- if (optimize_size) -- fprintf (asm_out_file, "\t! Optimization level\t: -Os\n"); --+ else if (optimize_fast) --+ fprintf (asm_out_file, "\t! Optimization level\t: -Ofast\n"); --+ else if (optimize_debug) --+ fprintf (asm_out_file, "\t! Optimization level\t: -Og\n"); -- else -- fprintf (asm_out_file, "\t! Optimization level\t: -O%d\n", optimize); -- --@@ -2225,9 +3553,65 @@ nds32_asm_file_end (void) -- { -- nds32_asm_file_end_for_isr (); -- --+ /* The NDS32 Linux stack is mapped non-executable by default, so add a --+ .note.GNU-stack section. */ --+ if (TARGET_LINUX_ABI) --+ file_end_indicate_exec_stack (); --+ -- fprintf (asm_out_file, "\t! ------------------------------------\n"); -- } -- --+static bool --+nds32_asm_output_addr_const_extra (FILE *file, rtx x) --+{ --+ if (GET_CODE (x) == UNSPEC) --+ { --+ switch (XINT (x, 1)) --+ { --+ case UNSPEC_GOTINIT: --+ output_addr_const (file, XVECEXP (x, 0, 0)); --+ break; --+ case UNSPEC_GOTOFF: --+ output_addr_const (file, XVECEXP (x, 0, 0)); --+ fputs ("@GOTOFF", file); --+ break; --+ case UNSPEC_GOT: --+ output_addr_const (file, XVECEXP (x, 0, 0)); --+ fputs ("@GOT", file); --+ break; --+ case UNSPEC_PLT: --+ output_addr_const (file, XVECEXP (x, 0, 0)); --+ fputs ("@PLT", file); --+ break; --+ case UNSPEC_TLSGD: --+ output_addr_const (file, XVECEXP (x, 0, 0)); --+ fputs ("@TLSDESC", file); --+ break; --+ case UNSPEC_TLSLD: --+ output_addr_const (file, XVECEXP (x, 0, 0)); --+ fputs ("@TLSDESC", file); --+ break; --+ case UNSPEC_TLSIE: --+ output_addr_const (file, XVECEXP (x, 0, 0)); --+ fputs ("@GOTTPOFF", file); --+ break; --+ case UNSPEC_TLSLE: --+ output_addr_const (file, XVECEXP (x, 0, 0)); --+ fputs ("@TPOFF", file); --+ break; --+ case UNSPEC_ICT: --+ output_addr_const (file, XVECEXP (x, 0, 0)); --+ fputs ("@ICT", file); --+ break; --+ default: --+ return false; --+ } --+ return true; --+ } --+ else --+ return false; --+} --+ -- /* -- Output and Generation of Labels. */ -- -- static void --@@ -2243,7 +3627,15 @@ nds32_asm_globalize_label (FILE *stream, const char *name) -- static void -- nds32_print_operand (FILE *stream, rtx x, int code) -- { --- int op_value; --+ HOST_WIDE_INT op_value = 0; --+ HOST_WIDE_INT one_position; --+ HOST_WIDE_INT zero_position; --+ bool pick_lsb_p = false; --+ bool pick_msb_p = false; --+ int regno; --+ --+ if (CONST_INT_P (x)) --+ op_value = INTVAL (x); -- -- switch (code) -- { --@@ -2251,29 +3643,82 @@ nds32_print_operand (FILE *stream, rtx x, int code) -- /* Do nothing special. */ -- break; -- --- case 'V': --- /* 'x' is supposed to be CONST_INT, get the value. */ --+ case 'b': --+ /* Use exact_log2() to search the 0-bit position. */ -- gcc_assert (CONST_INT_P (x)); --- op_value = INTVAL (x); --+ zero_position = exact_log2 (~UINTVAL (x) & GET_MODE_MASK (SImode)); --+ gcc_assert (zero_position != -1); --+ fprintf (stream, HOST_WIDE_INT_PRINT_DEC, zero_position); -- --- /* According to the Andes architecture, --- the system/user register index range is 0 ~ 1023. --- In order to avoid conflict between user-specified-integer value --- and enum-specified-register value, --- the 'enum nds32_intrinsic_registers' value --- in nds32_intrinsic.h starts from 1024. */ --- if (op_value < 1024 && op_value >= 0) --- { --- /* If user gives integer value directly (0~1023), --- we just print out the value. */ --- fprintf (stream, "%d", op_value); --- } --- else if (op_value < 0 --- || op_value >= ((int) ARRAY_SIZE (nds32_intrinsic_register_names) --- + 1024)) --- { --- /* The enum index value for array size is out of range. */ --- error ("intrinsic register index is out of range"); --+ /* No need to handle following process, so return immediately. */ --+ return; --+ --+ case 'e': --+ gcc_assert (MEM_P (x) --+ && GET_CODE (XEXP (x, 0)) == PLUS --+ && GET_CODE (XEXP (XEXP (x, 0), 1)) == CONST_INT); --+ fprintf (stream, HOST_WIDE_INT_PRINT_DEC, INTVAL (XEXP (XEXP (x, 0), 1))); --+ --+ /* No need to handle following process, so return immediately. */ --+ return; --+ --+ case 'v': --+ gcc_assert (CONST_INT_P (x) --+ && (INTVAL (x) == 0 --+ || INTVAL (x) == 8 --+ || INTVAL (x) == 16 --+ || INTVAL (x) == 24)); --+ fprintf (stream, HOST_WIDE_INT_PRINT_DEC, INTVAL (x) / 8); --+ --+ /* No need to handle following process, so return immediately. */ --+ return; --+ --+ case 'B': --+ /* Use exact_log2() to search the 1-bit position. */ --+ gcc_assert (CONST_INT_P (x)); --+ one_position = exact_log2 (UINTVAL (x) & GET_MODE_MASK (SImode)); --+ gcc_assert (one_position != -1); --+ fprintf (stream, HOST_WIDE_INT_PRINT_DEC, one_position); --+ --+ /* No need to handle following process, so return immediately. */ --+ return; --+ --+ case 'L': --+ /* X is supposed to be REG rtx. */ --+ gcc_assert (REG_P (x)); --+ /* Claim that we are going to pick LSB part of X. */ --+ pick_lsb_p = true; --+ break; --+ --+ case 'H': --+ /* X is supposed to be REG rtx. */ --+ gcc_assert (REG_P (x)); --+ /* Claim that we are going to pick MSB part of X. */ --+ pick_msb_p = true; --+ break; --+ --+ case 'V': --+ /* X is supposed to be CONST_INT, get the value. */ --+ gcc_assert (CONST_INT_P (x)); --+ --+ /* According to the Andes architecture, --+ the system/user register index range is 0 ~ 1023. --+ In order to avoid conflict between user-specified-integer value --+ and enum-specified-register value, --+ the 'enum nds32_intrinsic_registers' value --+ in nds32_intrinsic.h starts from 1024. */ --+ if (op_value < 1024 && op_value >= 0) --+ { --+ /* If user gives integer value directly (0~1023), --+ we just print out the value. */ --+ fprintf (stream, HOST_WIDE_INT_PRINT_DEC, op_value); --+ } --+ else if (op_value < 0 --+ || op_value >= ((int) ARRAY_SIZE (nds32_intrinsic_register_names) --+ + 1024)) --+ { --+ /* The enum index value for array size is out of range. */ --+ error ("intrinsic register index is out of range"); -- } -- else -- { --@@ -2286,6 +3731,45 @@ nds32_print_operand (FILE *stream, rtx x, int code) -- /* No need to handle following process, so return immediately. */ -- return; -- --+ case 'R': /* cctl valck */ --+ /* Note the cctl divide to 5 group and share the same name table. */ --+ if (op_value < 0 || op_value > 4) --+ error ("CCTL intrinsic function subtype out of range!"); --+ fprintf (stream, "%s", nds32_cctl_names[op_value]); --+ return; --+ --+ case 'T': /* cctl idxwbinv */ --+ /* Note the cctl divide to 5 group and share the same name table. */ --+ if (op_value < 0 || op_value > 4) --+ error ("CCTL intrinsic function subtype out of range!"); --+ fprintf (stream, "%s", nds32_cctl_names[op_value + 4]); --+ return; --+ --+ case 'U': /* cctl vawbinv */ --+ /* Note the cctl divide to 5 group and share the same name table. */ --+ if (op_value < 0 || op_value > 4) --+ error ("CCTL intrinsic function subtype out of range!"); --+ fprintf (stream, "%s", nds32_cctl_names[op_value + 8]); --+ return; --+ --+ case 'X': /* cctl idxread */ --+ /* Note the cctl divide to 5 group and share the same name table. */ --+ if (op_value < 0 || op_value > 4) --+ error ("CCTL intrinsic function subtype out of range!"); --+ fprintf (stream, "%s", nds32_cctl_names[op_value + 12]); --+ return; --+ --+ case 'W': /* cctl idxwitre */ --+ /* Note the cctl divide to 5 group and share the same name table. */ --+ if (op_value < 0 || op_value > 4) --+ error ("CCTL intrinsic function subtype out of range!"); --+ fprintf (stream, "%s", nds32_cctl_names[op_value + 16]); --+ return; --+ --+ case 'Z': /* dpref */ --+ fprintf (stream, "%s", nds32_dpref_names[op_value]); --+ return; --+ -- default : -- /* Unknown flag. */ -- output_operand_lossage ("invalid operand output code"); --@@ -2295,35 +3779,113 @@ nds32_print_operand (FILE *stream, rtx x, int code) -- switch (GET_CODE (x)) -- { -- case LABEL_REF: --+ output_addr_const (stream, x); --+ break; --+ -- case SYMBOL_REF: -- output_addr_const (stream, x); --+ --+ if (!TARGET_LINUX_ABI && nds32_indirect_call_referenced_p (x)) --+ fprintf (stream, "@ICT"); --+ -- break; -- -- case REG: --+ /* Print a Double-precision register name. */ --+ if ((GET_MODE (x) == DImode || GET_MODE (x) == DFmode) --+ && NDS32_IS_FPR_REGNUM (REGNO (x))) --+ { --+ regno = REGNO (x); --+ if (!NDS32_FPR_REGNO_OK_FOR_DOUBLE (regno)) --+ { --+ output_operand_lossage ("invalid operand for code '%c'", code); --+ break; --+ } --+ fprintf (stream, "$fd%d", (regno - NDS32_FIRST_FPR_REGNUM) >> 1); --+ break; --+ } --+ --+ /* Print LSB or MSB part of register pair if the --+ constraint modifier 'L' or 'H' is specified. */ --+ if ((GET_MODE (x) == DImode || GET_MODE (x) == DFmode) --+ && NDS32_IS_GPR_REGNUM (REGNO (x))) --+ { --+ if ((pick_lsb_p && WORDS_BIG_ENDIAN) --+ || (pick_msb_p && !WORDS_BIG_ENDIAN)) --+ { --+ /* If we would like to print out LSB register under big-endian, --+ or print out MSB register under little-endian, we need to --+ increase register number. */ --+ regno = REGNO (x); --+ regno++; --+ fputs (reg_names[regno], stream); --+ break; --+ } --+ } --+ -- /* Forbid using static chain register ($r16) --- on reduced-set registers configuration. */ --+ on reduced-set registers configuration. */ -- if (TARGET_REDUCED_REGS -- && REGNO (x) == STATIC_CHAIN_REGNUM) -- sorry ("a nested function is not supported for reduced registers"); -- -- /* Normal cases, print out register name. */ --- fputs (reg_names[REGNO (x)], stream); --+ regno = REGNO (x); --+ fputs (reg_names[regno], stream); -- break; -- -- case MEM: -- output_address (GET_MODE (x), XEXP (x, 0)); -- break; -- --+ case HIGH: --+ if (GET_CODE (XEXP (x, 0)) == CONST_DOUBLE) --+ { --+ const REAL_VALUE_TYPE *rv; --+ long val; --+ gcc_assert (GET_MODE (x) == SFmode); --+ --+ rv = CONST_DOUBLE_REAL_VALUE (XEXP (x, 0)); --+ REAL_VALUE_TO_TARGET_SINGLE (*rv, val); --+ --+ fprintf (stream, "hi20(0x%lx)", val); --+ } --+ else --+ gcc_unreachable (); --+ break; --+ --+ case CONST_DOUBLE: --+ const REAL_VALUE_TYPE *rv; --+ long val; --+ gcc_assert (GET_MODE (x) == SFmode); --+ --+ rv = CONST_DOUBLE_REAL_VALUE (x); --+ REAL_VALUE_TO_TARGET_SINGLE (*rv, val); --+ --+ fprintf (stream, "0x%lx", val); --+ break; --+ -- case CODE_LABEL: -- case CONST_INT: -- case CONST: -- output_addr_const (stream, x); -- break; -- --+ case CONST_VECTOR: --+ fprintf (stream, HOST_WIDE_INT_PRINT_HEX, const_vector_to_hwint (x)); --+ break; --+ --+ case LO_SUM: --+ /* This is a special case for inline assembly using memory address 'p'. --+ The inline assembly code is expected to use pesudo instruction --+ for the operand. EX: la */ --+ output_addr_const (stream, XEXP(x, 1)); --+ break; --+ -- default: -- /* Generally, output_addr_const () is able to handle most cases. --- We want to see what CODE could appear, --- so we use gcc_unreachable() to stop it. */ --+ We want to see what CODE could appear, --+ so we use gcc_unreachable() to stop it. */ -- debug_rtx (x); -- gcc_unreachable (); -- break; --@@ -2331,7 +3893,9 @@ nds32_print_operand (FILE *stream, rtx x, int code) -- } -- -- static void ---nds32_print_operand_address (FILE *stream, machine_mode /*mode*/, rtx x) --+nds32_print_operand_address (FILE *stream, --+ machine_mode mode ATTRIBUTE_UNUSED, --+ rtx x) -- { -- rtx op0, op1; -- --@@ -2346,15 +3910,25 @@ nds32_print_operand_address (FILE *stream, machine_mode /*mode*/, rtx x) -- fputs ("]", stream); -- break; -- --+ case LO_SUM: --+ /* This is a special case for inline assembly using memory operand 'm'. --+ The inline assembly code is expected to use pesudo instruction --+ for the operand. EX: [ls].[bhw] */ --+ fputs ("[ + ", stream); --+ op1 = XEXP (x, 1); --+ output_addr_const (stream, op1); --+ fputs ("]", stream); --+ break; --+ -- case REG: -- /* Forbid using static chain register ($r16) --- on reduced-set registers configuration. */ --+ on reduced-set registers configuration. */ -- if (TARGET_REDUCED_REGS -- && REGNO (x) == STATIC_CHAIN_REGNUM) -- sorry ("a nested function is not supported for reduced registers"); -- -- /* [Ra] */ --- fprintf (stream, "[%s]", reg_names[REGNO (x)]); --+ fprintf (stream, "[%s + 0]", reg_names[REGNO (x)]); -- break; -- -- case PLUS: --@@ -2362,13 +3936,13 @@ nds32_print_operand_address (FILE *stream, machine_mode /*mode*/, rtx x) -- op1 = XEXP (x, 1); -- -- /* Checking op0, forbid using static chain register ($r16) --- on reduced-set registers configuration. */ --+ on reduced-set registers configuration. */ -- if (TARGET_REDUCED_REGS -- && REG_P (op0) -- && REGNO (op0) == STATIC_CHAIN_REGNUM) -- sorry ("a nested function is not supported for reduced registers"); -- /* Checking op1, forbid using static chain register ($r16) --- on reduced-set registers configuration. */ --+ on reduced-set registers configuration. */ -- if (TARGET_REDUCED_REGS -- && REG_P (op1) -- && REGNO (op1) == STATIC_CHAIN_REGNUM) --@@ -2377,8 +3951,8 @@ nds32_print_operand_address (FILE *stream, machine_mode /*mode*/, rtx x) -- if (REG_P (op0) && CONST_INT_P (op1)) -- { -- /* [Ra + imm] */ --- fprintf (stream, "[%s + (%d)]", --- reg_names[REGNO (op0)], (int)INTVAL (op1)); --+ fprintf (stream, "[%s + (" HOST_WIDE_INT_PRINT_DEC ")]", --+ reg_names[REGNO (op0)], INTVAL (op1)); -- } -- else if (REG_P (op0) && REG_P (op1)) -- { --@@ -2391,8 +3965,8 @@ nds32_print_operand_address (FILE *stream, machine_mode /*mode*/, rtx x) -- /* [Ra + Rb << sv] -- From observation, the pattern looks like: -- (plus:SI (mult:SI (reg:SI 58) --- (const_int 4 [0x4])) --- (reg/f:SI 57)) */ --+ (const_int 4 [0x4])) --+ (reg/f:SI 57)) */ -- int sv; -- -- /* We need to set sv to output shift value. */ --@@ -2402,6 +3976,8 @@ nds32_print_operand_address (FILE *stream, machine_mode /*mode*/, rtx x) -- sv = 1; -- else if (INTVAL (XEXP (op0, 1)) == 4) -- sv = 2; --+ else if (INTVAL (XEXP (op0, 1)) == 8) --+ sv = 3; -- else -- gcc_unreachable (); -- --@@ -2410,6 +3986,20 @@ nds32_print_operand_address (FILE *stream, machine_mode /*mode*/, rtx x) -- reg_names[REGNO (XEXP (op0, 0))], -- sv); -- } --+ else if (GET_CODE (op0) == ASHIFT && REG_P (op1)) --+ { --+ /* [Ra + Rb << sv] --+ In normal, ASHIFT can be converted to MULT like above case. --+ But when the address rtx does not go through canonicalize_address --+ defined in fwprop, we'll need this case. */ --+ int sv = INTVAL (XEXP (op0, 1)); --+ gcc_assert (sv <= 3 && sv >=0); --+ --+ fprintf (stream, "[%s + %s << %d]", --+ reg_names[REGNO (op1)], --+ reg_names[REGNO (XEXP (op0, 0))], --+ sv); --+ } -- else -- { -- /* The control flow is not supposed to be here. */ --@@ -2421,20 +4011,20 @@ nds32_print_operand_address (FILE *stream, machine_mode /*mode*/, rtx x) -- -- case POST_MODIFY: -- /* (post_modify (regA) (plus (regA) (regB))) --- (post_modify (regA) (plus (regA) (const_int))) --- We would like to extract --- regA and regB (or const_int) from plus rtx. */ --+ (post_modify (regA) (plus (regA) (const_int))) --+ We would like to extract --+ regA and regB (or const_int) from plus rtx. */ -- op0 = XEXP (XEXP (x, 1), 0); -- op1 = XEXP (XEXP (x, 1), 1); -- -- /* Checking op0, forbid using static chain register ($r16) --- on reduced-set registers configuration. */ --+ on reduced-set registers configuration. */ -- if (TARGET_REDUCED_REGS -- && REG_P (op0) -- && REGNO (op0) == STATIC_CHAIN_REGNUM) -- sorry ("a nested function is not supported for reduced registers"); -- /* Checking op1, forbid using static chain register ($r16) --- on reduced-set registers configuration. */ --+ on reduced-set registers configuration. */ -- if (TARGET_REDUCED_REGS -- && REG_P (op1) -- && REGNO (op1) == STATIC_CHAIN_REGNUM) --@@ -2449,8 +4039,8 @@ nds32_print_operand_address (FILE *stream, machine_mode /*mode*/, rtx x) -- else if (REG_P (op0) && CONST_INT_P (op1)) -- { -- /* [Ra], imm */ --- fprintf (stream, "[%s], %d", --- reg_names[REGNO (op0)], (int)INTVAL (op1)); --+ fprintf (stream, "[%s], " HOST_WIDE_INT_PRINT_DEC, --+ reg_names[REGNO (op0)], INTVAL (op1)); -- } -- else -- { --@@ -2466,7 +4056,7 @@ nds32_print_operand_address (FILE *stream, machine_mode /*mode*/, rtx x) -- op0 = XEXP (x, 0); -- -- /* Checking op0, forbid using static chain register ($r16) --- on reduced-set registers configuration. */ --+ on reduced-set registers configuration. */ -- if (TARGET_REDUCED_REGS -- && REG_P (op0) -- && REGNO (op0) == STATIC_CHAIN_REGNUM) --@@ -2490,14 +4080,92 @@ nds32_print_operand_address (FILE *stream, machine_mode /*mode*/, rtx x) -- -- default : -- /* Generally, output_addr_const () is able to handle most cases. --- We want to see what CODE could appear, --- so we use gcc_unreachable() to stop it. */ --+ We want to see what CODE could appear, --+ so we use gcc_unreachable() to stop it. */ -- debug_rtx (x); -- gcc_unreachable (); -- break; -- } -- } -- --+/* -- Assembler Commands for Exception Regions. */ --+ --+static rtx --+nds32_dwarf_register_span (rtx reg) --+{ --+ rtx dwarf_high, dwarf_low; --+ rtx dwarf_single; --+ enum machine_mode mode; --+ int regno; --+ --+ mode = GET_MODE (reg); --+ regno = REGNO (reg); --+ --+ /* We need to adjust dwarf register information for floating-point registers --+ rather than using default register number mapping. */ --+ if (regno >= NDS32_FIRST_FPR_REGNUM --+ && regno <= NDS32_LAST_FPR_REGNUM) --+ { --+ if (mode == DFmode || mode == SCmode) --+ { --+ /* By default, GCC maps increasing register numbers to increasing --+ memory locations, but paired FPRs in NDS32 target are always --+ big-endian, i.e.: --+ --+ fd0 : fs0 fs1 --+ (MSB) (LSB) --+ --+ We must return parallel rtx to represent such layout. */ --+ dwarf_high = gen_rtx_REG (word_mode, regno); --+ dwarf_low = gen_rtx_REG (word_mode, regno + 1); --+ return gen_rtx_PARALLEL (VOIDmode, --+ gen_rtvec (2, dwarf_low, dwarf_high)); --+ } --+ else if (mode == DCmode) --+ { --+ rtx dwarf_high_re = gen_rtx_REG (word_mode, regno); --+ rtx dwarf_low_re = gen_rtx_REG (word_mode, regno + 1); --+ rtx dwarf_high_im = gen_rtx_REG (word_mode, regno); --+ rtx dwarf_low_im = gen_rtx_REG (word_mode, regno + 1); --+ return gen_rtx_PARALLEL (VOIDmode, --+ gen_rtvec (4, dwarf_low_re, dwarf_high_re, --+ dwarf_high_im, dwarf_low_im)); --+ } --+ else if (mode == SFmode || mode == SImode) --+ { --+ /* Create new dwarf information with adjusted register number. */ --+ dwarf_single = gen_rtx_REG (word_mode, regno); --+ return gen_rtx_PARALLEL (VOIDmode, gen_rtvec (1, dwarf_single)); --+ } --+ else --+ { --+ /* We should not be here. */ --+ gcc_unreachable (); --+ } --+ } --+ --+ return NULL_RTX; --+} --+ --+/* Map internal gcc register numbers to DWARF2 register numbers. */ --+ --+unsigned int --+nds32_dbx_register_number (unsigned int regno) --+{ --+ /* The nds32 port in GDB maintains a mapping between dwarf register --+ number and displayed register name. For backward compatibility to --+ previous toolchain, currently our gdb still has four registers --+ (d0.l, d0.h, d1.l, and d1.h) between GPR and FPR while compiler --+ does not count those four registers in its register number table. --+ So we have to add 4 on its register number and then create new --+ dwarf information. Hopefully we can discard such workaround --+ in the future. */ --+ if (NDS32_IS_FPR_REGNUM (regno)) --+ return regno + 4; --+ --+ return regno; --+} --+ -- -- /* Defining target-specific uses of __attribute__. */ -- --@@ -2526,6 +4194,27 @@ nds32_merge_decl_attributes (tree olddecl, tree newdecl) -- static void -- nds32_insert_attributes (tree decl, tree *attributes) -- { --+ /* A "indirect_call" function attribute implies "noinline" and "noclone" --+ for elf toolchain to support ROM patch mechanism. */ --+ if (TREE_CODE (decl) == FUNCTION_DECL --+ && lookup_attribute ("indirect_call", *attributes) != NULL) --+ { --+ tree new_attrs = *attributes; --+ --+ if (TARGET_LINUX_ABI) --+ error("cannot use indirect_call attribute under linux toolchain"); --+ --+ if (lookup_attribute ("noinline", new_attrs) == NULL) --+ new_attrs = tree_cons (get_identifier ("noinline"), NULL, new_attrs); --+ if (lookup_attribute ("noclone", new_attrs) == NULL) --+ new_attrs = tree_cons (get_identifier ("noclone"), NULL, new_attrs); --+ --+ if (!TREE_PUBLIC (decl)) --+ error("indirect_call attribute can't apply for static function"); --+ --+ *attributes = new_attrs; --+ } --+ -- /* For function declaration, we need to check isr-specific attributes: -- 1. Call nds32_check_isr_attrs_conflict() to check any conflict. -- 2. Check valid integer value for interrupt/exception. --@@ -2543,14 +4232,46 @@ nds32_insert_attributes (tree decl, tree *attributes) -- nds32_check_isr_attrs_conflict (decl, func_attrs); -- -- /* Now we are starting to check valid id value --- for interrupt/exception/reset. --- Note that we ONLY check its validity here. --- To construct isr vector information, it is still performed --- by nds32_construct_isr_vectors_information(). */ --+ for interrupt/exception/reset. --+ Note that we ONLY check its validity here. --+ To construct isr vector information, it is still performed --+ by nds32_construct_isr_vectors_information(). */ -- intr = lookup_attribute ("interrupt", func_attrs); -- excp = lookup_attribute ("exception", func_attrs); -- reset = lookup_attribute ("reset", func_attrs); -- --+ /* The following code may use attribute arguments. If there is no --+ argument from source code, it will cause segmentation fault. --+ Therefore, return dircetly and report error message later. */ --+ if ((intr && TREE_VALUE (intr) == NULL) --+ || (excp && TREE_VALUE (excp) == NULL) --+ || (reset && TREE_VALUE (reset) == NULL)) --+ return; --+ --+ /* ------------------------------------------------------------- */ --+ /* FIXME: --+ FOR BACKWARD COMPATIBILITY, we need to support following patterns: --+ --+ __attribute__((interrupt("XXX;YYY;id=ZZZ"))) --+ __attribute__((exception("XXX;YYY;id=ZZZ"))) --+ __attribute__((reset("vectors=XXX;nmi_func=YYY;warm_func=ZZZ"))) --+ --+ If interrupt/exception/reset appears and its argument is a --+ STRING_CST, we will use other functions to parse string in the --+ nds32_construct_isr_vectors_information() and then set necessary --+ isr information in the nds32_isr_vectors[] array. Here we can --+ just return immediately to avoid new-syntax checking. */ --+ if (intr != NULL_TREE --+ && TREE_CODE (TREE_VALUE (TREE_VALUE (intr))) == STRING_CST) --+ return; --+ if (excp != NULL_TREE --+ && TREE_CODE (TREE_VALUE (TREE_VALUE (excp))) == STRING_CST) --+ return; --+ if (reset != NULL_TREE --+ && TREE_CODE (TREE_VALUE (TREE_VALUE (reset))) == STRING_CST) --+ return; --+ /* ------------------------------------------------------------- */ --+ -- if (intr || excp) -- { -- /* Deal with interrupt/exception. */ --@@ -2576,8 +4297,8 @@ nds32_insert_attributes (tree decl, tree *attributes) -- id = TREE_VALUE (id_list); -- /* Issue error if it is not a valid integer value. */ -- if (TREE_CODE (id) != INTEGER_CST --- || wi::ltu_p (id, lower_bound) --- || wi::gtu_p (id, upper_bound)) --+ || TREE_INT_CST_LOW (id) < lower_bound --+ || TREE_INT_CST_LOW (id) > upper_bound) -- error ("invalid id value for interrupt/exception attribute"); -- -- /* Advance to next id. */ --@@ -2604,8 +4325,8 @@ nds32_insert_attributes (tree decl, tree *attributes) -- -- /* 3. Check valid integer value for reset. */ -- if (TREE_CODE (id) != INTEGER_CST --- || wi::ltu_p (id, lower_bound) --- || wi::gtu_p (id, upper_bound)) --+ || TREE_INT_CST_LOW (id) < lower_bound --+ || TREE_INT_CST_LOW (id) > upper_bound) -- error ("invalid id value for reset attribute"); -- -- /* 4. Check valid function for nmi/warm. */ --@@ -2667,17 +4388,40 @@ nds32_option_override (void) -- { -- /* Under V2 ISA, we need to strictly disable TARGET_V3PUSH. */ -- target_flags &= ~MASK_V3PUSH; --+ /* Under V2 ISA, we need to strictly disable TARGET_IFC. */ --+ target_flags &= ~MASK_IFC; --+ /* Under V2 ISA, we need to strictly disable TARGET_EX9. */ --+ target_flags &= ~MASK_EX9; --+ /* If this is ARCH_V2J, we need to enable TARGET_REDUCED_REGS. */ --+ if (nds32_arch_option == ARCH_V2J) --+ target_flags |= MASK_REDUCED_REGS; -- } -- if (TARGET_ISA_V3) -- { --- /* Under V3 ISA, currently nothing should be strictly set. */ --+ /* If this is ARCH_V3J, we need to enable TARGET_REDUCED_REGS. */ --+ if (nds32_arch_option == ARCH_V3J) --+ target_flags |= MASK_REDUCED_REGS; -- } -- if (TARGET_ISA_V3M) -- { -- /* Under V3M ISA, we need to strictly enable TARGET_REDUCED_REGS. */ -- target_flags |= MASK_REDUCED_REGS; --- /* Under V3M ISA, we need to strictly disable TARGET_PERF_EXT. */ --- target_flags &= ~MASK_PERF_EXT; --+ if (nds32_arch_option != ARCH_V3M_PLUS) --+ { --+ /* Under V3M ISA, we need to strictly disable TARGET_IFC. */ --+ target_flags &= ~MASK_IFC; --+ /* Under V3M ISA, we need to strictly disable TARGET_EX9. */ --+ target_flags &= ~MASK_EX9; --+ } --+ /* Under V3M ISA, we need to strictly disable TARGET_EXT_PERF. */ --+ target_flags &= ~MASK_EXT_PERF; --+ /* Under V3M ISA, we need to strictly disable TARGET_EXT_PERF2. */ --+ target_flags &= ~MASK_EXT_PERF2; --+ /* Under V3M ISA, we need to strictly disable TARGET_EXT_STRING. */ --+ target_flags &= ~MASK_EXT_STRING; --+ --+ if (flag_pic) --+ error ("not support -fpic option for v3m toolchain"); -- } -- -- /* See if we are using reduced-set registers: --@@ -2688,48 +4432,568 @@ nds32_option_override (void) -- int r; -- -- /* Prevent register allocator from --- choosing it as doing register allocation. */ --+ choosing it as doing register allocation. */ -- for (r = 11; r <= 14; r++) -- fixed_regs[r] = call_used_regs[r] = 1; -- for (r = 16; r <= 27; r++) -- fixed_regs[r] = call_used_regs[r] = 1; -- } -- --+ /* See if user explicitly would like to use fp-as-gp optimization. --+ If so, we must prevent $fp from being allocated --+ during register allocation. */ --+ if (TARGET_FORCE_FP_AS_GP) --+ fixed_regs[FP_REGNUM] = call_used_regs[FP_REGNUM] = 1; --+ -- if (!TARGET_16_BIT) -- { -- /* Under no 16 bit ISA, we need to strictly disable TARGET_V3PUSH. */ -- target_flags &= ~MASK_V3PUSH; -- } -- --- /* Currently, we don't support PIC code generation yet. */ --- if (flag_pic) --- sorry ("not support -fpic"); --+ if (TARGET_HARD_FLOAT && !(TARGET_FPU_SINGLE || TARGET_FPU_DOUBLE)) --+ { --+ if (nds32_arch_option == ARCH_V3S || nds32_arch_option == ARCH_V3F) --+ error ("Disable FPU ISA, " --+ "the ABI option must be enable '-mfloat-abi=soft'"); --+ else --+ error ("'-mabi=2fp+' option only support when FPU available, " --+ "must be enable '-mext-fpu-sp' or '-mext-fpu-dp'"); --+ } --+ --+ nds32_register_passes (); --+ --+ nds32_init_rtx_costs (); -- } -- -- -- /* Miscellaneous Parameters. */ -- --+static rtx_insn * --+nds32_md_asm_adjust (vec &outputs ATTRIBUTE_UNUSED, --+ vec &inputs ATTRIBUTE_UNUSED, --+ vec &constraints ATTRIBUTE_UNUSED, --+ vec &clobbers, HARD_REG_SET &clobbered_regs) --+{ --+ clobbers.safe_push (gen_rtx_REG (SImode, TA_REGNUM)); --+ SET_HARD_REG_BIT (clobbered_regs, TA_REGNUM); --+ return NULL; --+} --+/* Insert end_label and check loop body whether is empty. */ --+static bool --+nds32_hwloop_insert_end_label (rtx loop_id, rtx end_label) --+{ --+ rtx_insn *insn = NULL; --+ basic_block bb; --+ rtx cfg_id; --+ rtx_insn *last_insn; --+ --+ FOR_EACH_BB_FN (bb, cfun) --+ { --+ FOR_BB_INSNS (bb, insn) --+ { --+ if (NOTE_P (insn)) --+ continue; --+ --+ if (recog_memoized (insn) == CODE_FOR_hwloop_cfg --+ && INSN_P (insn)) --+ { --+ cfg_id = XVECEXP (XVECEXP (PATTERN (insn), 0, 5), 0, 0); --+ if (cfg_id == loop_id) --+ { --+ for (last_insn = PREV_INSN (insn); last_insn != BB_HEAD (bb); --+ last_insn = PREV_INSN (last_insn)) --+ { --+ if (NONDEBUG_INSN_P (last_insn)) --+ { --+ emit_label_before (end_label, last_insn); --+ if (TARGET_IFC) --+ { --+ /* The last_insn don't do ifcall. */ --+ emit_insn_before (gen_no_ifc_begin (), last_insn); --+ emit_insn_after (gen_no_ifc_end (), last_insn); --+ } --+ if (TARGET_EX9) --+ { --+ /* The last_insn don't do ex9. */ --+ emit_insn_before (gen_no_ex9_begin (), last_insn); --+ emit_insn_after (gen_no_ex9_end (), last_insn); --+ } --+ /* Record last instruction for identify in relax pass. */ --+ emit_insn_after (gen_hwloop_last_insn (), last_insn); --+ return true; --+ } --+ } --+ --+ if (NOTE_INSN_BASIC_BLOCK_P (last_insn)) --+ { --+ rtx_insn *nop = emit_insn_before (gen_unspec_nop (), --+ last_insn); --+ emit_label_before (end_label, nop); --+ if (TARGET_IFC) --+ { --+ /* The last_insn don't do ifcall. */ --+ emit_insn_before (gen_no_ifc_begin (), last_insn); --+ emit_insn_after (gen_no_ifc_end (), last_insn); --+ } --+ if (TARGET_EX9) --+ { --+ /* The last_insn don't do ex9. */ --+ emit_insn_before (gen_no_ex9_begin (), last_insn); --+ emit_insn_after (gen_no_ex9_end (), last_insn); --+ } --+ return true; --+ } --+ } --+ } --+ } --+ } --+ --+ if (insn != NULL) --+ delete_insn (insn); --+ return false; --+} --+ --+static void --+nds32_hwloop_remove (rtx loop_id) --+{ --+ rtx_insn *insn; --+ rtx le_id; --+ basic_block bb; --+ --+ FOR_EACH_BB_FN (bb, cfun) --+ { --+ FOR_BB_INSNS (bb, insn) --+ { --+ if (NOTE_P (insn)) --+ continue; --+ --+ if (recog_memoized (insn) == CODE_FOR_init_lc --+ && INSN_P (insn)) --+ { --+ le_id = XVECEXP (XVECEXP (PATTERN (insn), 0, 1), 0, 0); --+ if (loop_id == le_id) --+ { --+ delete_insn (insn); --+ return; --+ } --+ } --+ } --+ } --+} --+ --+/* Insert isb instruction for hwloop. */ --+static void --+nds32_hwloop_insert_isb (rtx loop_id) --+{ --+ rtx_insn *insn; --+ rtx le_id; --+ basic_block bb; --+ --+ FOR_EACH_BB_FN (bb, cfun) --+ { --+ FOR_BB_INSNS (bb, insn) --+ { --+ if (NOTE_P (insn)) --+ continue; --+ --+ if (recog_memoized (insn) == CODE_FOR_init_lc --+ && INSN_P (insn)) --+ { --+ le_id = XVECEXP (XVECEXP (PATTERN (insn), 0, 1), 0, 0); --+ if (loop_id == le_id) --+ { --+ emit_insn_after (gen_unspec_volatile_isb (), insn); --+ return; --+ } --+ } --+ } --+ } --+} --+/* Insert mtlei instruction for hwloop. */ --+static void --+nds32_hwloop_insert_init_end () --+{ --+ rtx_insn *insn; --+ basic_block bb; --+ rtx loop_id, end_label; --+ bool hwloop_p; --+ --+ FOR_EACH_BB_FN (bb, cfun) --+ { --+ FOR_BB_INSNS (bb, insn) --+ { --+ if (NOTE_P (insn)) --+ continue; --+ --+ if (recog_memoized (insn) == CODE_FOR_mtlbi_hint --+ && INSN_P (insn)) --+ { --+ end_label = gen_label_rtx (); --+ loop_id = XVECEXP (XVECEXP (PATTERN (insn), 0, 1), 0, 0); --+ hwloop_p = nds32_hwloop_insert_end_label (loop_id, end_label); --+ --+ if (!hwloop_p) --+ { --+ delete_insn (insn); --+ nds32_hwloop_remove (loop_id); --+ } --+ else --+ { --+ emit_insn_after (gen_mtlei (gen_rtx_LABEL_REF (Pmode, end_label)), insn); --+ nds32_hwloop_insert_isb (loop_id); --+ } --+ } --+ } --+ } --+} --+ --+/* Reorganize insns issued at the same cycle in out of order. */ --+static void --+nds32_reorg_out_of_order () --+{ --+ using namespace nds32; --+ --+ // The function is controoled by -mreorg-out-of-order and the issue rate. --+ if (!flag_reorg_out_of_order --+ || nds32_sched_issue_rate () < 2) --+ return; --+ --+ // We only move load insns up at this moment. --+ rtx_insn *insn; --+ --+ for (insn = get_insns (); insn; insn = NEXT_INSN (insn)) --+ { --+ if (!insn_executable_p (insn) --+ || GET_MODE (insn) != TImode --+ || get_attr_type (insn) == TYPE_STORE_MULTIPLE --+ || get_attr_type (insn) == TYPE_LOAD_MULTIPLE --+ || get_attr_type (insn) == TYPE_LOAD --+ || get_attr_type (insn) == TYPE_FLOAD --+ || get_attr_type (insn) == TYPE_STORE --+ || get_attr_type (insn) == TYPE_FSTORE) --+ continue; --+ --+ rtx_insn *load_insn = insn; --+ --+ while ((load_insn = next_executable_insn_local (load_insn))) --+ { --+ if (GET_MODE (load_insn) == TImode) --+ { --+ load_insn = NULL; --+ break; --+ } --+ --+ if ((get_attr_type (load_insn) == TYPE_LOAD --+ || get_attr_type (load_insn) == TYPE_FLOAD) --+ && get_attr_length (load_insn) < 4) --+ break; --+ } --+ --+ if (load_insn == NULL_RTX) --+ continue; --+ --+ exchange_insns (insn, load_insn); --+ } --+} --+ --+/* Perform machine-dependent processing. */ --+static void --+nds32_machine_dependent_reorg (void) --+{ --+ /* We are freeing block_for_insn in the toplev to keep compatibility --+ with old MDEP_REORGS that are not CFG based. Recompute it --+ now. */ --+ compute_bb_for_insn (); --+ --+ nds32_reorg_out_of_order (); --+ --+ if (TARGET_HWLOOP) --+ nds32_hwloop_insert_init_end (); --+ --+ if (flag_var_tracking) --+ { --+ df_analyze (); --+ timevar_push (TV_VAR_TRACKING); --+ variable_tracking_main (); --+ timevar_pop (TV_VAR_TRACKING); --+ df_finish_pass (false); --+ } --+ --+ /* Use -minnermost-loop to enable, --+ need more testing to verify result. */ --+ if (TARGET_INNERMOST_LOOP) --+ nds32_insert_innermost_loop (); --+ --+ nds32_insert_isps (); --+} --+ -- static void -- nds32_init_builtins (void) -- { -- nds32_init_builtins_impl (); -- } -- --+static tree --+nds32_builtin_decl (unsigned code, bool initialize_p) --+{ --+ /* Implement in nds32-intrinsic.c. */ --+ return nds32_builtin_decl_impl (code, initialize_p); --+} --+ -- static rtx -- nds32_expand_builtin (tree exp, -- rtx target, -- rtx subtarget, --- machine_mode mode, --+ enum machine_mode mode, -- int ignore) -- { --+ /* Implement in nds32-intrinsic.c. */ -- return nds32_expand_builtin_impl (exp, target, subtarget, mode, ignore); -- } -- --+static bool --+nds32_have_conditional_execution (void) --+{ --+ /* Lie to gcc that we have conditional execution for change optimization flow --+ in if-conversion, LRA and scheduling phase. --+ In our experiment result show that cand reduce about 2% code size with very --+ minor performance degradation in average. */ --+ return optimize_size; --+} --+ --+/* Implement TARGET_INIT_LIBFUNCS. */ --+static void --+nds32_init_libfuncs (void) --+{ --+ if (TARGET_LINUX_ABI) --+ init_sync_libfuncs (UNITS_PER_WORD); --+} --+ --+/* Implement TARGET_CAN_USE_DOLOOP_P. */ --+static bool --+nds32_can_use_doloop_p (const widest_int &, const widest_int &iterations_max, --+ unsigned int, bool entered_at_top) --+{ --+ /* Using hwloop must be entered from the top. */ --+ if (!entered_at_top) --+ return false; --+ --+ if (lookup_attribute ("no_ext_zol", DECL_ATTRIBUTES (current_function_decl))) --+ return false; --+ --+ /* Initial hardware loops too costly, so we must avoid to --+ generate a hardware loops when loop count less then 8. */ --+ if (!NDS32_HW_LOOP_P () --+ || iterations_max.ulow() < 8) --+ return false; --+ return true; --+} --+ --+/* NULL if INSN insn is valid within a low-overhead loop. --+ Otherwise return why doloop cannot be applied. */ --+static const char * --+nds32_invalid_within_doloop (const rtx_insn *insn) --+{ --+ if (CALL_P (insn)) --+ return "Function call in the loop."; --+ else if (INSN_CODE (insn) == CODE_FOR_pop25return --+ || INSN_CODE (insn) == CODE_FOR_return_internal) --+ return "Simple return in the loop."; --+ else if (INSN_CODE (insn) == CODE_FOR_unspec_no_hwloop) --+ return "no_hwloop hint in the loop"; --+ --+ return NULL; --+} -- -- /* ------------------------------------------------------------------------ */ -- ---/* PART 4: Implemet extern function definitions, --- the prototype is in nds32-protos.h. */ --+/* PART 5: Implemet extern function definitions, --+ the prototype is in nds32-protos.h. */ --+ --+/* Run-time Target Specification. */ --+ --+void --+nds32_cpu_cpp_builtins(struct cpp_reader *pfile) --+{ --+#define builtin_define(TXT) cpp_define (pfile, TXT) --+#define builtin_assert(TXT) cpp_assert (pfile, TXT) --+ builtin_define ("__nds32__"); --+ builtin_define ("__NDS32__"); --+ --+ /* We need to provide builtin macro to describe the size of --+ each vector for interrupt handler under elf toolchain. */ --+ if (!TARGET_LINUX_ABI) --+ { --+ if (TARGET_ISR_VECTOR_SIZE_4_BYTE) --+ builtin_define ("__NDS32_ISR_VECTOR_SIZE_4__"); --+ else --+ builtin_define ("__NDS32_ISR_VECTOR_SIZE_16__"); --+ } --+ --+ if (TARGET_HARD_FLOAT) --+ builtin_define ("__NDS32_ABI_2FP_PLUS__"); --+ else --+ builtin_define ("__NDS32_ABI_2__"); --+ --+ if (TARGET_ISA_V2) --+ builtin_define ("__NDS32_ISA_V2__"); --+ if (TARGET_ISA_V3) --+ builtin_define ("__NDS32_ISA_V3__"); --+ if (TARGET_ISA_V3M) --+ builtin_define ("__NDS32_ISA_V3M__"); --+ --+ if (TARGET_FPU_SINGLE) --+ builtin_define ("__NDS32_EXT_FPU_SP__"); --+ if (TARGET_FPU_DOUBLE) --+ builtin_define ("__NDS32_EXT_FPU_DP__"); --+ --+ if (TARGET_EXT_FPU_FMA) --+ builtin_define ("__NDS32_EXT_FPU_FMA__"); --+ if (NDS32_EXT_FPU_DOT_E) --+ builtin_define ("__NDS32_EXT_FPU_DOT_E__"); --+ if (TARGET_FPU_SINGLE || TARGET_FPU_DOUBLE) --+ { --+ switch (nds32_fp_regnum) --+ { --+ case 0: --+ case 4: --+ builtin_define ("__NDS32_EXT_FPU_CONFIG_0__"); --+ break; --+ case 1: --+ case 5: --+ builtin_define ("__NDS32_EXT_FPU_CONFIG_1__"); --+ break; --+ case 2: --+ case 6: --+ builtin_define ("__NDS32_EXT_FPU_CONFIG_2__"); --+ break; --+ case 3: --+ case 7: --+ builtin_define ("__NDS32_EXT_FPU_CONFIG_3__"); --+ break; --+ default: --+ abort (); --+ } --+ } --+ --+ if (TARGET_BIG_ENDIAN) --+ builtin_define ("__NDS32_EB__"); --+ else --+ builtin_define ("__NDS32_EL__"); --+ --+ if (TARGET_REDUCED_REGS) --+ builtin_define ("__NDS32_REDUCED_REGS__"); --+ if (TARGET_CMOV) --+ builtin_define ("__NDS32_CMOV__"); --+ if (TARGET_EXT_PERF) --+ builtin_define ("__NDS32_EXT_PERF__"); --+ if (TARGET_EXT_PERF2) --+ builtin_define ("__NDS32_EXT_PERF2__"); --+ if (TARGET_EXT_STRING) --+ builtin_define ("__NDS32_EXT_STRING__"); --+ if (TARGET_16_BIT) --+ builtin_define ("__NDS32_16_BIT__"); --+ if (TARGET_GP_DIRECT) --+ builtin_define ("__NDS32_GP_DIRECT__"); --+ if (TARGET_VH) --+ builtin_define ("__NDS32_VH__"); --+ if (NDS32_EXT_DSP_P ()) --+ builtin_define ("__NDS32_EXT_DSP__"); --+ if (NDS32_HW_LOOP_P ()) --+ builtin_define ("__NDS32_EXT_ZOL__"); --+ --+ /* Extra builtin macros. */ --+ if (TARGET_ISA_V3 || TARGET_ISA_V3M_PLUS) --+ builtin_define ("__NDS32_EXT_IFC__"); --+ if (TARGET_ISA_V3 || TARGET_ISA_V3M_PLUS) --+ builtin_define ("__NDS32_EXT_EX9__"); --+ if (TARGET_BIG_ENDIAN) --+ builtin_define ("__big_endian__"); --+ --+ builtin_assert ("cpu=nds32"); --+ builtin_assert ("machine=nds32"); --+ --+ /* FOR BACKWARD COMPATIBILITY. */ --+ if (TARGET_ISA_V2) --+ builtin_define ("__NDS32_BASELINE_V2__"); --+ if (TARGET_ISA_V3) --+ builtin_define ("__NDS32_BASELINE_V3__"); --+ if (TARGET_ISA_V3M) --+ builtin_define ("__NDS32_BASELINE_V3M__"); --+ if (TARGET_REDUCED_REGS) --+ builtin_define ("__NDS32_REDUCE_REGS__"); --+ --+ if (TARGET_ISA_V2) --+ builtin_define ("NDS32_BASELINE_V2"); --+ if (TARGET_ISA_V3) --+ builtin_define ("NDS32_BASELINE_V3"); --+ if (TARGET_ISA_V3M) --+ builtin_define ("NDS32_BASELINE_V3M"); --+ if (TARGET_REDUCED_REGS) --+ builtin_define ("NDS32_REDUCE_REGS"); --+ if (TARGET_FPU_SINGLE) --+ builtin_define ("NDS32_EXT_FPU_SP"); --+ if (TARGET_FPU_DOUBLE) --+ builtin_define ("NDS32_EXT_FPU_DP"); --+ if (TARGET_EXT_PERF) --+ builtin_define ("NDS32_EXT_PERF"); --+ if (TARGET_EXT_PERF2) --+ builtin_define ("NDS32_EXT_PERF2"); --+ if (TARGET_EXT_STRING) --+ builtin_define ("NDS32_EXT_STRING"); --+ if (TARGET_ISA_V3) --+ builtin_define ("NDS32_EXT_IFC"); --+ if (TARGET_ISA_V3) --+ builtin_define ("NDS32_EXT_EX9"); --+ --+ if (TARGET_HARD_FLOAT) --+ builtin_define ("NDS32_ABI_2FP_PLUS"); --+ else --+ builtin_define ("NDS32_ABI_2"); --+ --+ if (TARGET_BIG_ENDIAN) --+ builtin_define ("NDS32_EB"); --+ else --+ builtin_define ("NDS32_EL"); --+ --+ if (TARGET_ISA_V2) --+ builtin_define ("__NDS32_BASELINE_V2"); --+ if (TARGET_ISA_V3) --+ builtin_define ("__NDS32_BASELINE_V3"); --+ if (TARGET_ISA_V3M) --+ builtin_define ("__NDS32_BASELINE_V3M"); --+ if (TARGET_REDUCED_REGS) --+ builtin_define ("__NDS32_REDUCE_REGS"); --+ if (TARGET_FPU_SINGLE) --+ builtin_define ("__NDS32_EXT_FPU_SP"); --+ if (TARGET_FPU_DOUBLE) --+ builtin_define ("__NDS32_EXT_FPU_DP"); --+ if (TARGET_EXT_PERF) --+ builtin_define ("__NDS32_EXT_PERF"); --+ if (TARGET_EXT_PERF2) --+ builtin_define ("__NDS32_EXT_PERF2"); --+ if (TARGET_EXT_STRING) --+ builtin_define ("__NDS32_EXT_STRING"); --+ if (TARGET_ISA_V3) --+ builtin_define ("__NDS32_EXT_IFC"); --+ --+ if (TARGET_ISA_V3) --+ builtin_define ("__NDS32_EXT_EX9"); --+ --+ if (TARGET_HARD_FLOAT) --+ builtin_define ("__NDS32_ABI_2FP_PLUS"); --+ else --+ builtin_define ("__NDS32_ABI_2"); --+ --+ if (TARGET_BIG_ENDIAN) --+ builtin_define ("__NDS32_EB"); --+ else --+ builtin_define ("__NDS32_EL"); --+#undef builtin_define --+#undef builtin_assert --+} --+ -- -- /* Defining Data Structures for Per-function Information. */ -- --@@ -2743,26 +5007,80 @@ nds32_init_expanders (void) -- -- /* Register Usage. */ -- --+/* -- Order of Allocation of Registers. */ --+ --+void --+nds32_adjust_reg_alloc_order (void) --+{ --+ const int nds32_reg_alloc_order[] = REG_ALLOC_ORDER; --+ --+ /* Copy the default register allocation order, which is designed --+ to optimize for code size. */ --+ memcpy(reg_alloc_order, nds32_reg_alloc_order, sizeof (reg_alloc_order)); --+ --+ /* Adjust few register allocation order when optimizing for speed. */ --+ if (!optimize_size) --+ { --+ memcpy (reg_alloc_order, nds32_reg_alloc_order_for_speed, --+ sizeof (nds32_reg_alloc_order_for_speed)); --+ } --+} --+ -- /* -- How Values Fit in Registers. */ -- -- int -- nds32_hard_regno_nregs (int regno ATTRIBUTE_UNUSED, --- machine_mode mode) --+ enum machine_mode mode) -- { -- return ((GET_MODE_SIZE (mode) + UNITS_PER_WORD - 1) / UNITS_PER_WORD); -- } -- -- int ---nds32_hard_regno_mode_ok (int regno, machine_mode mode) --+nds32_hard_regno_mode_ok (int regno, enum machine_mode mode) -- { --+ if (regno > FIRST_PSEUDO_REGISTER) --+ return true; --+ --+ if ((TARGET_FPU_SINGLE || TARGET_FPU_DOUBLE) && NDS32_IS_FPR_REGNUM (regno)) --+ { --+ if (NDS32_IS_EXT_FPR_REGNUM(regno)) --+ return (NDS32_FPR_REGNO_OK_FOR_DOUBLE(regno) && (mode == DFmode)); --+ else if (mode == SFmode || mode == SImode) --+ return NDS32_FPR_REGNO_OK_FOR_SINGLE (regno); --+ else if (mode == DFmode) --+ return NDS32_FPR_REGNO_OK_FOR_DOUBLE (regno); --+ --+ return false; --+ } --+ -- /* Restrict double-word quantities to even register pairs. */ --- if (HARD_REGNO_NREGS (regno, mode) == 1 --- || !((regno) & 1)) --- return 1; --+ if (regno <= NDS32_LAST_GPR_REGNUM) --+ return (HARD_REGNO_NREGS (regno, mode) == 1 --+ || !((regno) & 1)); -- --- return 0; --+ return false; -- } -- --+int --+nds32_modes_tieable_p (enum machine_mode mode1, enum machine_mode mode2) --+{ --+ if ((GET_MODE_CLASS (mode1) == MODE_INT --+ && GET_MODE_CLASS (mode2) == MODE_INT) --+ && GET_MODE_SIZE (mode1) <= UNITS_PER_WORD --+ && GET_MODE_SIZE (mode2) <= UNITS_PER_WORD) --+ return true; --+ --+ if (GET_MODE_SIZE (mode1) == GET_MODE_SIZE (mode2)) --+ { --+ if ((TARGET_FPU_SINGLE && !TARGET_FPU_DOUBLE) --+ && (mode1 == DFmode || mode2 == DFmode)) --+ return false; --+ else --+ return true; --+ } --+ --+ return false; --+} -- -- /* Register Classes. */ -- --@@ -2784,7 +5102,16 @@ nds32_regno_reg_class (int regno) -- else if (regno >= 20 && regno <= 31) -- return HIGH_REGS; -- else if (regno == 32 || regno == 33) --- return FRAME_REGS; --+ { --+ /* $SFP and $AP is FRAME_REGS in fact, However prevent IRA don't --+ know how to allocate register for $SFP and $AP, just tell IRA they --+ are GENERAL_REGS, and ARM do this hack too. */ --+ return GENERAL_REGS; --+ } --+ else if (regno >= 34 && regno <= 97) --+ return FP_REGS; --+ else if (regno >= 98 && regno <= 100) --+ return LOOP_REGS; -- else -- return NO_REGS; -- } --@@ -2795,14 +5122,39 @@ nds32_regno_reg_class (int regno) -- /* -- Basic Stack Layout. */ -- -- rtx --+nds32_dynamic_chain_address (rtx frameaddr) --+{ --+ if (TARGET_V3PUSH) --+ { --+ /* If -mv3push is specified, we push $fp, $gp, and $lp into stack. --+ We can access dynamic chain address from stack by [$fp - 12]. */ --+ return plus_constant (Pmode, frameaddr, -12); --+ } --+ else --+ { --+ /* For general case we push $fp and $lp into stack at prologue. --+ We can access dynamic chain address from stack by [$fp - 8]. */ --+ return plus_constant (Pmode, frameaddr, -8); --+ } --+} --+ --+rtx -- nds32_return_addr_rtx (int count, --- rtx frameaddr ATTRIBUTE_UNUSED) --+ rtx frameaddr) -- { --- /* There is no way to determine the return address --- if frameaddr is the frame that has 'count' steps --- up from current frame. */ --+ int offset; --+ rtx addr; --+ -- if (count != 0) --- return NULL_RTX; --+ { --+ /* In nds32 ABI design, we can expect that $lp is always available --+ from stack by [$fp - 4] location. */ --+ offset = -4; --+ addr = plus_constant (Pmode, frameaddr, offset); --+ addr = memory_address (Pmode, addr); --+ --+ return gen_rtx_MEM (Pmode, addr); --+ } -- -- /* If count == 0, it means we are at current frame, -- the return address is $r30 ($lp). */ --@@ -2821,15 +5173,18 @@ nds32_initial_elimination_offset (unsigned int from_reg, unsigned int to_reg) -- nds32_compute_stack_frame (); -- -- /* Remember to consider --- cfun->machine->callee_saved_area_padding_bytes --+ cfun->machine->callee_saved_area_gpr_padding_bytes and --+ cfun->machine->eh_return_data_regs_size -- when calculating offset. */ -- if (from_reg == ARG_POINTER_REGNUM && to_reg == STACK_POINTER_REGNUM) -- { -- offset = (cfun->machine->fp_size --- + cfun->machine->gp_size --+ + cfun->machine->gp_size -- + cfun->machine->lp_size -- + cfun->machine->callee_saved_gpr_regs_size -- + cfun->machine->callee_saved_area_gpr_padding_bytes --+ + cfun->machine->callee_saved_fpr_regs_size --+ + cfun->machine->eh_return_data_regs_size -- + cfun->machine->local_size -- + cfun->machine->out_args_size); -- } --@@ -2850,7 +5205,9 @@ nds32_initial_elimination_offset (unsigned int from_reg, unsigned int to_reg) -- + cfun->machine->gp_size -- + cfun->machine->lp_size -- + cfun->machine->callee_saved_gpr_regs_size --- + cfun->machine->callee_saved_area_gpr_padding_bytes); --+ + cfun->machine->callee_saved_area_gpr_padding_bytes --+ + cfun->machine->callee_saved_fpr_regs_size --+ + cfun->machine->eh_return_data_regs_size); -- } -- else -- { --@@ -2869,10 +5226,11 @@ nds32_init_cumulative_args (CUMULATIVE_ARGS *cum, -- tree fndecl ATTRIBUTE_UNUSED, -- int n_named_args ATTRIBUTE_UNUSED) -- { --- /* Initial available registers --- (in offset, corresponding to NDS32_GPR_ARG_FIRST_REGNUM) --+ /* Initial available registers. The values are offset against --+ NDS32_GPR_ARG_FIRST_REGNUM and NDS32_FPR_ARG_FIRST_REGNUM -- for passing arguments. */ -- cum->gpr_offset = 0; --+ cum->fpr_offset = 0; -- } -- -- /* -- Function Entry and Exit. */ --@@ -2883,125 +5241,178 @@ nds32_expand_prologue (void) -- { -- int fp_adjust; -- int sp_adjust; --- int en4_const; --- --- rtx Rb, Re; --- rtx fp_adjust_insn, sp_adjust_insn; --+ unsigned Rb, Re; -- -- /* Compute and setup stack frame size. -- The result will be in cfun->machine. */ -- nds32_compute_stack_frame (); -- --+ /* Check frame_pointer_needed again to prevent fp is need after reload. */ --+ if (frame_pointer_needed) --+ cfun->machine->fp_as_gp_p = false; --+ -- /* If this is a variadic function, first we need to push argument -- registers that hold the unnamed argument value. */ -- if (cfun->machine->va_args_size != 0) -- { --- Rb = gen_rtx_REG (SImode, cfun->machine->va_args_first_regno); --- Re = gen_rtx_REG (SImode, cfun->machine->va_args_last_regno); --- /* No need to push $fp, $gp, or $lp, so use GEN_INT(0). */ --- nds32_emit_stack_push_multiple (Rb, Re, GEN_INT (0), true); --+ Rb = cfun->machine->va_args_first_regno; --+ Re = cfun->machine->va_args_last_regno; --+ /* No need to push $fp, $gp, or $lp. */ --+ nds32_emit_stack_push_multiple (Rb, Re, false, false, false, true); -- -- /* We may also need to adjust stack pointer for padding bytes --- because varargs may cause $sp not 8-byte aligned. */ --+ because varargs may cause $sp not 8-byte aligned. */ -- if (cfun->machine->va_args_area_padding_bytes) -- { -- /* Generate sp adjustment instruction. */ -- sp_adjust = cfun->machine->va_args_area_padding_bytes; --- sp_adjust_insn = gen_addsi3 (stack_pointer_rtx, --- stack_pointer_rtx, --- GEN_INT (-1 * sp_adjust)); -- --- /* Emit rtx into instructions list and receive INSN rtx form. */ --- sp_adjust_insn = emit_insn (sp_adjust_insn); --- --- /* The insn rtx 'sp_adjust_insn' will change frame layout. --- We need to use RTX_FRAME_RELATED_P so that GCC is able to --- generate CFI (Call Frame Information) stuff. */ --- RTX_FRAME_RELATED_P (sp_adjust_insn) = 1; --+ nds32_emit_adjust_frame (stack_pointer_rtx, --+ stack_pointer_rtx, --+ -1 * sp_adjust); -- } -- } -- -- /* If the function is 'naked', -- we do not have to generate prologue code fragment. */ --- if (cfun->machine->naked_p) --+ if (cfun->machine->naked_p && !flag_pic) -- return; -- -- /* Get callee_first_regno and callee_last_regno. */ --- Rb = gen_rtx_REG (SImode, cfun->machine->callee_saved_first_gpr_regno); --- Re = gen_rtx_REG (SImode, cfun->machine->callee_saved_last_gpr_regno); --- --- /* nds32_emit_stack_push_multiple(first_regno, last_regno), --- the pattern 'stack_push_multiple' is implemented in nds32.md. --- For En4 field, we have to calculate its constant value. --- Refer to Andes ISA for more information. */ --- en4_const = 0; --- if (cfun->machine->fp_size) --- en4_const += 8; --- if (cfun->machine->gp_size) --- en4_const += 4; --- if (cfun->machine->lp_size) --- en4_const += 2; --+ Rb = cfun->machine->callee_saved_first_gpr_regno; --+ Re = cfun->machine->callee_saved_last_gpr_regno; -- -- /* If $fp, $gp, $lp, and all callee-save registers are NOT required -- to be saved, we don't have to create multiple push instruction. -- Otherwise, a multiple push instruction is needed. */ --- if (!(REGNO (Rb) == SP_REGNUM && REGNO (Re) == SP_REGNUM && en4_const == 0)) --+ if (!(Rb == SP_REGNUM && Re == SP_REGNUM --+ && cfun->machine->fp_size == 0 --+ && cfun->machine->gp_size == 0 --+ && cfun->machine->lp_size == 0)) -- { -- /* Create multiple push instruction rtx. */ --- nds32_emit_stack_push_multiple (Rb, Re, GEN_INT (en4_const), false); --+ nds32_emit_stack_push_multiple ( --+ Rb, Re, --+ cfun->machine->fp_size, cfun->machine->gp_size, cfun->machine->lp_size, --+ false); --+ } --+ --+ /* Save eh data registers. */ --+ if (cfun->machine->use_eh_return_p) --+ { --+ Rb = cfun->machine->eh_return_data_first_regno; --+ Re = cfun->machine->eh_return_data_last_regno; --+ --+ /* No need to push $fp, $gp, or $lp. --+ Also, this is not variadic arguments push. */ --+ nds32_emit_stack_push_multiple (Rb, Re, false, false, false, false); -- } -- --- /* Check frame_pointer_needed to see --- if we shall emit fp adjustment instruction. */ --- if (frame_pointer_needed) --- { --- /* adjust $fp = $sp + ($fp size) + ($gp size) + ($lp size) --- + (4 * callee-saved-registers) --- Note: No need to adjust --- cfun->machine->callee_saved_area_padding_bytes, --- because, at this point, stack pointer is just --- at the position after push instruction. */ --- fp_adjust = cfun->machine->fp_size --- + cfun->machine->gp_size --- + cfun->machine->lp_size --- + cfun->machine->callee_saved_gpr_regs_size; --- fp_adjust_insn = gen_addsi3 (hard_frame_pointer_rtx, --+ /* Check frame_pointer_needed to see --+ if we shall emit fp adjustment instruction. */ --+ if (frame_pointer_needed) --+ { --+ /* adjust $fp = $sp + ($fp size) + ($gp size) + ($lp size) --+ + (4 * callee-saved-registers) --+ + (4 * exception-handling-data-registers) --+ Note: No need to adjust --+ cfun->machine->callee_saved_area_gpr_padding_bytes, --+ because, at this point, stack pointer is just --+ at the position after push instruction. */ --+ fp_adjust = cfun->machine->fp_size --+ + cfun->machine->gp_size --+ + cfun->machine->lp_size --+ + cfun->machine->callee_saved_gpr_regs_size --+ + cfun->machine->eh_return_data_regs_size; --+ --+ nds32_emit_adjust_frame (hard_frame_pointer_rtx, --+ stack_pointer_rtx, --+ fp_adjust); --+ } --+ --+ /* Save fpu registers. */ --+ if (cfun->machine->callee_saved_first_fpr_regno != SP_REGNUM) --+ { --+ /* When $sp moved to bottom of stack, we need to check whether --+ the range of offset in the FPU instruction. */ --+ int fpr_offset = cfun->machine->local_size --+ + cfun->machine->out_args_size --+ + cfun->machine->callee_saved_fpr_regs_size; --+ --+ /* Check FPU instruction offset imm14s. */ --+ if (!satisfies_constraint_Is14 (GEN_INT (fpr_offset))) --+ { --+ int fpr_space = cfun->machine->callee_saved_area_gpr_padding_bytes --+ + cfun->machine->callee_saved_fpr_regs_size; --+ --+ /* Save fpu registers, need to allocate stack space --+ for fpu callee registers. And now $sp position --+ on callee saved fpr registers. */ --+ nds32_emit_adjust_frame (stack_pointer_rtx, --+ stack_pointer_rtx, --+ -1 * fpr_space); --+ --+ /* Emit fpu store instruction, using [$sp + offset] store --+ fpu registers. */ --+ nds32_emit_push_fpr_callee_saved (0); --+ --+ /* Adjust $sp = $sp - local_size - out_args_size. */ --+ sp_adjust = cfun->machine->local_size --+ + cfun->machine->out_args_size; --+ --+ /* Allocate stack space for local size and out args size. */ --+ nds32_emit_adjust_frame (stack_pointer_rtx, --+ stack_pointer_rtx, --+ -1 * sp_adjust); --+ } --+ else --+ { --+ /* Offset range in Is14, so $sp moved to bottom of stack. */ --+ --+ /* Adjust $sp = $sp - local_size - out_args_size --+ - callee_saved_area_gpr_padding_bytes --+ - callee_saved_fpr_regs_size. */ --+ sp_adjust = cfun->machine->local_size --+ + cfun->machine->out_args_size --+ + cfun->machine->callee_saved_area_gpr_padding_bytes --+ + cfun->machine->callee_saved_fpr_regs_size; --+ --+ nds32_emit_adjust_frame (stack_pointer_rtx, -- stack_pointer_rtx, --- GEN_INT (fp_adjust)); --- /* Emit rtx into instructions list and receive INSN rtx form. */ --- fp_adjust_insn = emit_insn (fp_adjust_insn); --+ -1 * sp_adjust); -- --- /* The insn rtx 'fp_adjust_insn' will change frame layout. */ --- RTX_FRAME_RELATED_P (fp_adjust_insn) = 1; --+ /* Emit fpu store instruction, using [$sp + offset] store --+ fpu registers. */ --+ int fpr_position = cfun->machine->out_args_size --+ + cfun->machine->local_size; --+ nds32_emit_push_fpr_callee_saved (fpr_position); --+ } -- } --- --- /* Adjust $sp = $sp - local_size - out_args_size --- - callee_saved_area_padding_bytes. */ --- sp_adjust = cfun->machine->local_size --- + cfun->machine->out_args_size --- + cfun->machine->callee_saved_area_gpr_padding_bytes; --- /* sp_adjust value may be out of range of the addi instruction, --- create alternative add behavior with TA_REGNUM if necessary, --- using NEGATIVE value to tell that we are decreasing address. */ --- sp_adjust = nds32_force_addi_stack_int ( (-1) * sp_adjust); --- if (sp_adjust) --+ else -- { --- /* Generate sp adjustment instruction if and only if sp_adjust != 0. */ --- sp_adjust_insn = gen_addsi3 (stack_pointer_rtx, --- stack_pointer_rtx, --- GEN_INT (-1 * sp_adjust)); --- /* Emit rtx into instructions list and receive INSN rtx form. */ --- sp_adjust_insn = emit_insn (sp_adjust_insn); --+ /* Adjust $sp = $sp - local_size - out_args_size --+ - callee_saved_area_gpr_padding_bytes. */ --+ sp_adjust = cfun->machine->local_size --+ + cfun->machine->out_args_size --+ + cfun->machine->callee_saved_area_gpr_padding_bytes; -- --- /* The insn rtx 'sp_adjust_insn' will change frame layout. --- We need to use RTX_FRAME_RELATED_P so that GCC is able to --- generate CFI (Call Frame Information) stuff. */ --- RTX_FRAME_RELATED_P (sp_adjust_insn) = 1; --+ /* sp_adjust value may be out of range of the addi instruction, --+ create alternative add behavior with TA_REGNUM if necessary, --+ using NEGATIVE value to tell that we are decreasing address. */ --+ nds32_emit_adjust_frame (stack_pointer_rtx, --+ stack_pointer_rtx, --+ -1 * sp_adjust); -- } -- --- /* Prevent the instruction scheduler from --- moving instructions across the boundary. */ --- emit_insn (gen_blockage ()); --+ /* Emit gp setup instructions for -fpic. */ --+ if (flag_pic && df_regs_ever_live_p (PIC_OFFSET_TABLE_REGNUM)) --+ nds32_emit_load_gp (); --+ --+ /* If user applies -mno-sched-prolog-epilog option, --+ we need to prevent instructions of function body from being --+ scheduled with stack adjustment in prologue. */ --+ if (!flag_sched_prolog_epilog) --+ emit_insn (gen_blockage ()); -- } -- -- /* Function for normal multiple pop epilogue. */ --@@ -3009,18 +5420,17 @@ void -- nds32_expand_epilogue (bool sibcall_p) -- { -- int sp_adjust; --- int en4_const; --- --- rtx Rb, Re; --- rtx sp_adjust_insn; --+ unsigned Rb, Re; -- -- /* Compute and setup stack frame size. -- The result will be in cfun->machine. */ -- nds32_compute_stack_frame (); -- --- /* Prevent the instruction scheduler from --- moving instructions across the boundary. */ --- emit_insn (gen_blockage ()); --+ /* If user applies -mno-sched-prolog-epilog option, --+ we need to prevent instructions of function body from being --+ scheduled with stack adjustment in epilogue. */ --+ if (!flag_sched_prolog_epilog) --+ emit_insn (gen_blockage ()); -- -- /* If the function is 'naked', we do not have to generate -- epilogue code fragment BUT 'ret' instruction. --@@ -3029,110 +5439,156 @@ nds32_expand_epilogue (bool sibcall_p) -- if (cfun->machine->naked_p) -- { -- /* If this is a variadic function, we do not have to restore argument --- registers but need to adjust stack pointer back to previous stack --- frame location before return. */ --+ registers but need to adjust stack pointer back to previous stack --+ frame location before return. */ -- if (cfun->machine->va_args_size != 0) -- { -- /* Generate sp adjustment instruction. -- We need to consider padding bytes here. */ -- sp_adjust = cfun->machine->va_args_size -- + cfun->machine->va_args_area_padding_bytes; --- sp_adjust_insn = gen_addsi3 (stack_pointer_rtx, --- stack_pointer_rtx, --- GEN_INT (sp_adjust)); --- /* Emit rtx into instructions list and receive INSN rtx form. */ --- sp_adjust_insn = emit_insn (sp_adjust_insn); -- --- /* The insn rtx 'sp_adjust_insn' will change frame layout. --- We need to use RTX_FRAME_RELATED_P so that GCC is able to --- generate CFI (Call Frame Information) stuff. */ --- RTX_FRAME_RELATED_P (sp_adjust_insn) = 1; --+ nds32_emit_adjust_frame (stack_pointer_rtx, --+ stack_pointer_rtx, --+ sp_adjust); -- } -- -- /* Generate return instruction by using 'return_internal' pattern. --- Make sure this instruction is after gen_blockage(). */ --+ Make sure this instruction is after gen_blockage(). --+ First we need to check this is a function without sibling call. */ -- if (!sibcall_p) --- emit_jump_insn (gen_return_internal ()); --+ { --+ /* We need to further check attributes to determine whether --+ there should be return instruction at epilogue. --+ If the attribute naked exists but -mno-ret-in-naked-func --+ is issued, there is NO need to generate return instruction. */ --+ if (cfun->machine->attr_naked_p && !flag_ret_in_naked_func) --+ return; --+ --+ emit_jump_insn (gen_return_internal ()); --+ } -- return; -- } -- -- if (frame_pointer_needed) -- { --- /* adjust $sp = $fp - ($fp size) - ($gp size) - ($lp size) --- - (4 * callee-saved-registers) --- Note: No need to adjust --- cfun->machine->callee_saved_area_padding_bytes, --- because we want to adjust stack pointer --- to the position for pop instruction. */ --- sp_adjust = cfun->machine->fp_size --- + cfun->machine->gp_size --- + cfun->machine->lp_size --- + cfun->machine->callee_saved_gpr_regs_size; --- sp_adjust_insn = gen_addsi3 (stack_pointer_rtx, --+ /* Restore fpu registers. */ --+ if (cfun->machine->callee_saved_first_fpr_regno != SP_REGNUM) --+ { --+ int gpr_padding = cfun->machine->callee_saved_area_gpr_padding_bytes; --+ --+ /* adjust $sp = $fp - ($fp size) - ($gp size) - ($lp size) --+ - (4 * callee-saved-registers) --+ - (4 * exception-handling-data-registers) --+ - (4 * callee-saved-gpr-registers padding byte) --+ - (4 * callee-saved-fpr-registers) --+ Note: we want to adjust stack pointer --+ to the position for callee-saved fpr register, --+ And restore fpu register use .bi instruction to adjust $sp --+ from callee-saved fpr register to pop instruction. */ --+ sp_adjust = cfun->machine->fp_size --+ + cfun->machine->gp_size --+ + cfun->machine->lp_size --+ + cfun->machine->callee_saved_gpr_regs_size --+ + cfun->machine->eh_return_data_regs_size --+ + cfun->machine->callee_saved_area_gpr_padding_bytes --+ + cfun->machine->callee_saved_fpr_regs_size; --+ --+ nds32_emit_adjust_frame (stack_pointer_rtx, -- hard_frame_pointer_rtx, --- GEN_INT (-1 * sp_adjust)); --- /* Emit rtx into instructions list and receive INSN rtx form. */ --- sp_adjust_insn = emit_insn (sp_adjust_insn); --+ -1 * sp_adjust); --+ --+ /* Emit fpu load instruction, using .bi instruction --+ load fpu registers. */ --+ nds32_emit_pop_fpr_callee_saved (gpr_padding); --+ } --+ else --+ { --+ /* adjust $sp = $fp - ($fp size) - ($gp size) - ($lp size) --+ - (4 * callee-saved-registers) --+ - (4 * exception-handling-data-registers) --+ Note: No need to adjust --+ cfun->machine->callee_saved_area_gpr_padding_bytes, --+ because we want to adjust stack pointer --+ to the position for pop instruction. */ --+ sp_adjust = cfun->machine->fp_size --+ + cfun->machine->gp_size --+ + cfun->machine->lp_size --+ + cfun->machine->callee_saved_gpr_regs_size --+ + cfun->machine->eh_return_data_regs_size; -- --- /* The insn rtx 'sp_adjust_insn' will change frame layout. */ --- RTX_FRAME_RELATED_P (sp_adjust_insn) = 1; --+ nds32_emit_adjust_frame (stack_pointer_rtx, --+ hard_frame_pointer_rtx, --+ -1 * sp_adjust); --+ } -- } -- else -- { --- /* If frame pointer is NOT needed, --- we cannot calculate the sp adjustment from frame pointer. --- Instead, we calculate the adjustment by local_size, --- out_args_size, and callee_saved_area_padding_bytes. --- Notice that such sp adjustment value may be out of range, --- so we have to deal with it as well. */ --+ /* Restore fpu registers. */ --+ if (cfun->machine->callee_saved_first_fpr_regno != SP_REGNUM) --+ { --+ int gpr_padding = cfun->machine->callee_saved_area_gpr_padding_bytes; -- --- /* Adjust $sp = $sp + local_size + out_args_size --- + callee_saved_area_padding_bytes. */ --- sp_adjust = cfun->machine->local_size --- + cfun->machine->out_args_size --- + cfun->machine->callee_saved_area_gpr_padding_bytes; --- /* sp_adjust value may be out of range of the addi instruction, --- create alternative add behavior with TA_REGNUM if necessary, --- using POSITIVE value to tell that we are increasing address. */ --- sp_adjust = nds32_force_addi_stack_int (sp_adjust); --- if (sp_adjust) --- { --- /* Generate sp adjustment instruction --- if and only if sp_adjust != 0. */ --- sp_adjust_insn = gen_addsi3 (stack_pointer_rtx, --- stack_pointer_rtx, --- GEN_INT (sp_adjust)); --- /* Emit rtx into instructions list and receive INSN rtx form. */ --- sp_adjust_insn = emit_insn (sp_adjust_insn); --+ /* Adjust $sp = $sp + local_size + out_args_size. */ --+ sp_adjust = cfun->machine->local_size --+ + cfun->machine->out_args_size; -- --- /* The insn rtx 'sp_adjust_insn' will change frame layout. */ --- RTX_FRAME_RELATED_P (sp_adjust_insn) = 1; --+ nds32_emit_adjust_frame (stack_pointer_rtx, --+ stack_pointer_rtx, --+ sp_adjust); --+ --+ /* Emit fpu load instruction, using .bi instruction --+ load fpu registers, and adjust $sp from callee-saved fpr register --+ to callee-saved gpr register. */ --+ nds32_emit_pop_fpr_callee_saved (gpr_padding); --+ } --+ else --+ { --+ /* If frame pointer is NOT needed, --+ we cannot calculate the sp adjustment from frame pointer. --+ Instead, we calculate the adjustment by local_size, --+ out_args_size, and callee_saved_area_gpr_padding_bytes. --+ Notice that such sp adjustment value may be out of range, --+ so we have to deal with it as well. */ --+ --+ /* Adjust $sp = $sp + local_size + out_args_size --+ + callee_saved_area_gpr_padding_bytes. */ --+ sp_adjust = cfun->machine->local_size --+ + cfun->machine->out_args_size --+ + cfun->machine->callee_saved_area_gpr_padding_bytes; --+ --+ nds32_emit_adjust_frame (stack_pointer_rtx, --+ stack_pointer_rtx, --+ sp_adjust); -- } -- } -- --+ /* Restore eh data registers. */ --+ if (cfun->machine->use_eh_return_p) --+ { --+ Rb = cfun->machine->eh_return_data_first_regno; --+ Re = cfun->machine->eh_return_data_last_regno; --+ --+ /* No need to pop $fp, $gp, or $lp. */ --+ nds32_emit_stack_pop_multiple (Rb, Re, false, false, false); --+ } --+ -- /* Get callee_first_regno and callee_last_regno. */ --- Rb = gen_rtx_REG (SImode, cfun->machine->callee_saved_first_gpr_regno); --- Re = gen_rtx_REG (SImode, cfun->machine->callee_saved_last_gpr_regno); --- --- /* nds32_emit_stack_pop_multiple(first_regno, last_regno), --- the pattern 'stack_pop_multiple' is implementad in nds32.md. --- For En4 field, we have to calculate its constant value. --- Refer to Andes ISA for more information. */ --- en4_const = 0; --- if (cfun->machine->fp_size) --- en4_const += 8; --- if (cfun->machine->gp_size) --- en4_const += 4; --- if (cfun->machine->lp_size) --- en4_const += 2; --+ Rb = cfun->machine->callee_saved_first_gpr_regno; --+ Re = cfun->machine->callee_saved_last_gpr_regno; -- -- /* If $fp, $gp, $lp, and all callee-save registers are NOT required -- to be saved, we don't have to create multiple pop instruction. -- Otherwise, a multiple pop instruction is needed. */ --- if (!(REGNO (Rb) == SP_REGNUM && REGNO (Re) == SP_REGNUM && en4_const == 0)) --+ if (!(Rb == SP_REGNUM && Re == SP_REGNUM --+ && cfun->machine->fp_size == 0 --+ && cfun->machine->gp_size == 0 --+ && cfun->machine->lp_size == 0)) -- { -- /* Create multiple pop instruction rtx. */ --- nds32_emit_stack_pop_multiple (Rb, Re, GEN_INT (en4_const)); --+ nds32_emit_stack_pop_multiple ( --+ Rb, Re, --+ cfun->machine->fp_size, cfun->machine->gp_size, cfun->machine->lp_size); -- } -- -- /* If this is a variadic function, we do not have to restore argument --@@ -3141,19 +5597,49 @@ nds32_expand_epilogue (bool sibcall_p) -- if (cfun->machine->va_args_size != 0) -- { -- /* Generate sp adjustment instruction. --- We need to consider padding bytes here. */ --+ We need to consider padding bytes here. */ -- sp_adjust = cfun->machine->va_args_size -- + cfun->machine->va_args_area_padding_bytes; --- sp_adjust_insn = gen_addsi3 (stack_pointer_rtx, --- stack_pointer_rtx, --- GEN_INT (sp_adjust)); --- /* Emit rtx into instructions list and receive INSN rtx form. */ --- sp_adjust_insn = emit_insn (sp_adjust_insn); -- --- /* The insn rtx 'sp_adjust_insn' will change frame layout. --- We need to use RTX_FRAME_RELATED_P so that GCC is able to --- generate CFI (Call Frame Information) stuff. */ --- RTX_FRAME_RELATED_P (sp_adjust_insn) = 1; --+ nds32_emit_adjust_frame (stack_pointer_rtx, --+ stack_pointer_rtx, --+ sp_adjust); --+ } --+ --+ /* If this function uses __builtin_eh_return, make stack adjustment --+ for exception handler. */ --+ if (cfun->machine->use_eh_return_p) --+ { --+ /* We need to unwind the stack by the offset computed by --+ EH_RETURN_STACKADJ_RTX. However, at this point the CFA is --+ based on SP. Ideally we would update the SP and define the --+ CFA along the lines of: --+ --+ SP = SP + EH_RETURN_STACKADJ_RTX --+ (regnote CFA = SP - EH_RETURN_STACKADJ_RTX) --+ --+ However the dwarf emitter only understands a constant --+ register offset. --+ --+ The solution chosen here is to use the otherwise $ta ($r15) --+ as a temporary register to hold the current SP value. The --+ CFA is described using $ta then SP is modified. */ --+ --+ rtx ta_reg; --+ rtx insn; --+ --+ ta_reg = gen_rtx_REG (SImode, TA_REGNUM); --+ --+ insn = emit_move_insn (ta_reg, stack_pointer_rtx); --+ add_reg_note (insn, REG_CFA_DEF_CFA, ta_reg); --+ RTX_FRAME_RELATED_P (insn) = 1; --+ --+ emit_insn (gen_addsi3 (stack_pointer_rtx, --+ stack_pointer_rtx, --+ EH_RETURN_STACKADJ_RTX)); --+ --+ /* Ensure the assignment to $ta does not get optimized away. */ --+ emit_use (ta_reg); -- } -- -- /* Generate return instruction. */ --@@ -3167,28 +5653,35 @@ nds32_expand_prologue_v3push (void) -- { -- int fp_adjust; -- int sp_adjust; --- --- rtx Rb, Re; --- rtx fp_adjust_insn, sp_adjust_insn; --+ int fpr_space = 0; --+ unsigned Rb, Re; -- -- /* Compute and setup stack frame size. -- The result will be in cfun->machine. */ -- nds32_compute_stack_frame (); -- --+ if (cfun->machine->callee_saved_gpr_regs_size > 0) --+ df_set_regs_ever_live (FP_REGNUM, 1); --+ --+ /* Check frame_pointer_needed again to prevent fp is need after reload. */ --+ if (frame_pointer_needed) --+ cfun->machine->fp_as_gp_p = false; --+ -- /* If the function is 'naked', -- we do not have to generate prologue code fragment. */ --- if (cfun->machine->naked_p) --+ if (cfun->machine->naked_p && !flag_pic) -- return; -- -- /* Get callee_first_regno and callee_last_regno. */ --- Rb = gen_rtx_REG (SImode, cfun->machine->callee_saved_first_gpr_regno); --- Re = gen_rtx_REG (SImode, cfun->machine->callee_saved_last_gpr_regno); --+ Rb = cfun->machine->callee_saved_first_gpr_regno; --+ Re = cfun->machine->callee_saved_last_gpr_regno; -- -- /* Calculate sp_adjust first to test if 'push25 Re,imm8u' is available, -- where imm8u has to be 8-byte alignment. */ -- sp_adjust = cfun->machine->local_size -- + cfun->machine->out_args_size --- + cfun->machine->callee_saved_area_gpr_padding_bytes; --+ + cfun->machine->callee_saved_area_gpr_padding_bytes --+ + cfun->machine->callee_saved_fpr_regs_size; -- -- if (satisfies_constraint_Iu08 (GEN_INT (sp_adjust)) -- && NDS32_DOUBLE_WORD_ALIGN_P (sp_adjust)) --@@ -3196,94 +5689,118 @@ nds32_expand_prologue_v3push (void) -- /* We can use 'push25 Re,imm8u'. */ -- -- /* nds32_emit_stack_v3push(last_regno, sp_adjust), --- the pattern 'stack_v3push' is implemented in nds32.md. --- The (const_int 14) means v3push always push { $fp $gp $lp }. */ --- nds32_emit_stack_v3push (Rb, Re, --- GEN_INT (14), GEN_INT (sp_adjust)); --+ the pattern 'stack_v3push' is implemented in nds32.md. */ --+ nds32_emit_stack_v3push (Rb, Re, sp_adjust); --+ --+ /* Save fpu registers. */ --+ if (cfun->machine->callee_saved_first_fpr_regno != SP_REGNUM) --+ { --+ /* Calculate fpr position. */ --+ int fpr_position = cfun->machine->local_size --+ + cfun->machine->out_args_size; --+ /* Emit fpu store instruction, using [$sp + offset] store --+ fpu registers. */ --+ nds32_emit_push_fpr_callee_saved (fpr_position); --+ } -- -- /* Check frame_pointer_needed to see --- if we shall emit fp adjustment instruction. */ --+ if we shall emit fp adjustment instruction. */ -- if (frame_pointer_needed) -- { -- /* adjust $fp = $sp + 4 ($fp size) --- + 4 ($gp size) --- + 4 ($lp size) --- + (4 * n) (callee-saved registers) --- + sp_adjust ('push25 Re,imm8u') --+ + 4 ($gp size) --+ + 4 ($lp size) --+ + (4 * n) (callee-saved registers) --+ + sp_adjust ('push25 Re,imm8u') -- Note: Since we use 'push25 Re,imm8u', --- the position of stack pointer is further --- changed after push instruction. --- Hence, we need to take sp_adjust value --- into consideration. */ --+ the position of stack pointer is further --+ changed after push instruction. --+ Hence, we need to take sp_adjust value --+ into consideration. */ -- fp_adjust = cfun->machine->fp_size -- + cfun->machine->gp_size -- + cfun->machine->lp_size -- + cfun->machine->callee_saved_gpr_regs_size -- + sp_adjust; --- fp_adjust_insn = gen_addsi3 (hard_frame_pointer_rtx, --- stack_pointer_rtx, --- GEN_INT (fp_adjust)); --- /* Emit rtx into instructions list and receive INSN rtx form. */ --- fp_adjust_insn = emit_insn (fp_adjust_insn); --+ --+ nds32_emit_adjust_frame (hard_frame_pointer_rtx, --+ stack_pointer_rtx, --+ fp_adjust); -- } -- } -- else -- { --- /* We have to use 'push25 Re,0' and --- expand one more instruction to adjust $sp later. */ --+ if (cfun->machine->callee_saved_first_fpr_regno != SP_REGNUM) --+ { --+ /* Calculate fpr space. */ --+ fpr_space = cfun->machine->callee_saved_area_gpr_padding_bytes --+ + cfun->machine->callee_saved_fpr_regs_size; --+ --+ /* We have to use 'push25 Re, fpr_space', to pre-allocate --+ callee saved fpr registers space. */ --+ nds32_emit_stack_v3push (Rb, Re, fpr_space); --+ nds32_emit_push_fpr_callee_saved (0); --+ } --+ else --+ { --+ /* We have to use 'push25 Re,0' and --+ expand one more instruction to adjust $sp later. */ -- --- /* nds32_emit_stack_v3push(last_regno, sp_adjust), --- the pattern 'stack_v3push' is implemented in nds32.md. --- The (const_int 14) means v3push always push { $fp $gp $lp }. */ --- nds32_emit_stack_v3push (Rb, Re, --- GEN_INT (14), GEN_INT (0)); --+ /* nds32_emit_stack_v3push(last_regno, sp_adjust), --+ the pattern 'stack_v3push' is implemented in nds32.md. */ --+ nds32_emit_stack_v3push (Rb, Re, 0); --+ } -- -- /* Check frame_pointer_needed to see --- if we shall emit fp adjustment instruction. */ --+ if we shall emit fp adjustment instruction. */ -- if (frame_pointer_needed) -- { -- /* adjust $fp = $sp + 4 ($fp size) --- + 4 ($gp size) --- + 4 ($lp size) --- + (4 * n) (callee-saved registers) --+ + 4 ($gp size) --+ + 4 ($lp size) --+ + (4 * n) (callee-saved registers) -- Note: Since we use 'push25 Re,0', --- the stack pointer is just at the position --- after push instruction. --- No need to take sp_adjust into consideration. */ --+ the stack pointer is just at the position --+ after push instruction. --+ No need to take sp_adjust into consideration. */ -- fp_adjust = cfun->machine->fp_size -- + cfun->machine->gp_size -- + cfun->machine->lp_size -- + cfun->machine->callee_saved_gpr_regs_size; --- fp_adjust_insn = gen_addsi3 (hard_frame_pointer_rtx, --- stack_pointer_rtx, --- GEN_INT (fp_adjust)); --- /* Emit rtx into instructions list and receive INSN rtx form. */ --- fp_adjust_insn = emit_insn (fp_adjust_insn); --- } -- --- /* Because we use 'push25 Re,0', --- we need to expand one more instruction to adjust $sp. --- However, sp_adjust value may be out of range of the addi instruction, --- create alternative add behavior with TA_REGNUM if necessary, --- using NEGATIVE value to tell that we are decreasing address. */ --- sp_adjust = nds32_force_addi_stack_int ( (-1) * sp_adjust); --- if (sp_adjust) --- { --- /* Generate sp adjustment instruction --- if and only if sp_adjust != 0. */ --- sp_adjust_insn = gen_addsi3 (stack_pointer_rtx, --- stack_pointer_rtx, --- GEN_INT (-1 * sp_adjust)); --- /* Emit rtx into instructions list and receive INSN rtx form. */ --- sp_adjust_insn = emit_insn (sp_adjust_insn); --+ if (cfun->machine->callee_saved_first_fpr_regno != SP_REGNUM) --+ { --+ /* We use 'push25 Re, fpr_space', the $sp is --+ on callee saved fpr position, so need to consider --+ fpr space. */ --+ fp_adjust = fp_adjust + fpr_space; --+ } --+ --+ nds32_emit_adjust_frame (hard_frame_pointer_rtx, --+ stack_pointer_rtx, --+ fp_adjust); --+ } -- --- /* The insn rtx 'sp_adjust_insn' will change frame layout. --- We need to use RTX_FRAME_RELATED_P so that GCC is able to --- generate CFI (Call Frame Information) stuff. */ --- RTX_FRAME_RELATED_P (sp_adjust_insn) = 1; --+ if (cfun->machine->callee_saved_first_fpr_regno != SP_REGNUM) --+ { --+ /* We use 'push25 Re, fpr_space', --+ the $sp is on callee saved fpr position, --+ no need to consider fpr space. */ --+ sp_adjust = sp_adjust - fpr_space; -- } --+ --+ /* Because we use 'push25 Re,0', --+ we need to expand one more instruction to adjust $sp. --+ using NEGATIVE value to tell that we are decreasing address. */ --+ nds32_emit_adjust_frame (stack_pointer_rtx, --+ stack_pointer_rtx, --+ -1 * sp_adjust); -- } -- --+ /* Emit gp setup instructions for -fpic. */ --+ if (flag_pic && df_regs_ever_live_p (PIC_OFFSET_TABLE_REGNUM)) --+ nds32_emit_load_gp (); --+ -- /* Prevent the instruction scheduler from -- moving instructions across the boundary. */ -- emit_insn (gen_blockage ()); --@@ -3294,9 +5811,7 @@ void -- nds32_expand_epilogue_v3pop (bool sibcall_p) -- { -- int sp_adjust; --- --- rtx Rb, Re; --- rtx sp_adjust_insn; --+ unsigned Rb, Re; -- -- /* Compute and setup stack frame size. -- The result will be in cfun->machine. */ --@@ -3311,21 +5826,32 @@ nds32_expand_epilogue_v3pop (bool sibcall_p) -- if (cfun->machine->naked_p) -- { -- /* Generate return instruction by using 'return_internal' pattern. --- Make sure this instruction is after gen_blockage(). */ --+ Make sure this instruction is after gen_blockage(). --+ First we need to check this is a function without sibling call. */ -- if (!sibcall_p) --- emit_jump_insn (gen_return_internal ()); --+ { --+ /* We need to further check attributes to determine whether --+ there should be return instruction at epilogue. --+ If the attribute naked exists but -mno-ret-in-naked-func --+ is issued, there is NO need to generate return instruction. */ --+ if (cfun->machine->attr_naked_p && !flag_ret_in_naked_func) --+ return; --+ --+ emit_jump_insn (gen_return_internal ()); --+ } -- return; -- } -- -- /* Get callee_first_regno and callee_last_regno. */ --- Rb = gen_rtx_REG (SImode, cfun->machine->callee_saved_first_gpr_regno); --- Re = gen_rtx_REG (SImode, cfun->machine->callee_saved_last_gpr_regno); --+ Rb = cfun->machine->callee_saved_first_gpr_regno; --+ Re = cfun->machine->callee_saved_last_gpr_regno; -- -- /* Calculate sp_adjust first to test if 'pop25 Re,imm8u' is available, -- where imm8u has to be 8-byte alignment. */ -- sp_adjust = cfun->machine->local_size -- + cfun->machine->out_args_size --- + cfun->machine->callee_saved_area_gpr_padding_bytes; --+ + cfun->machine->callee_saved_area_gpr_padding_bytes --+ + cfun->machine->callee_saved_fpr_regs_size; -- -- /* We have to consider alloca issue as well. -- If the function does call alloca(), the stack pointer is not fixed. --@@ -3338,38 +5864,65 @@ nds32_expand_epilogue_v3pop (bool sibcall_p) -- && NDS32_DOUBLE_WORD_ALIGN_P (sp_adjust) -- && !cfun->calls_alloca) -- { --+ /* Restore fpu registers. */ --+ if (cfun->machine->callee_saved_first_fpr_regno != SP_REGNUM) --+ { --+ int fpr_position = cfun->machine->local_size --+ + cfun->machine->out_args_size; --+ /* Emit fpu load instruction, using [$sp + offset] restore --+ fpu registers. */ --+ nds32_emit_v3pop_fpr_callee_saved (fpr_position); --+ } --+ -- /* We can use 'pop25 Re,imm8u'. */ -- -- /* nds32_emit_stack_v3pop(last_regno, sp_adjust), --- the pattern 'stack_v3pop' is implementad in nds32.md. --- The (const_int 14) means v3pop always pop { $fp $gp $lp }. */ --- nds32_emit_stack_v3pop (Rb, Re, --- GEN_INT (14), GEN_INT (sp_adjust)); --+ the pattern 'stack_v3pop' is implementad in nds32.md. */ --+ nds32_emit_stack_v3pop (Rb, Re, sp_adjust); -- } -- else -- { -- /* We have to use 'pop25 Re,0', and prior to it, --- we must expand one more instruction to adjust $sp. */ --+ we must expand one more instruction to adjust $sp. */ -- -- if (frame_pointer_needed) -- { -- /* adjust $sp = $fp - 4 ($fp size) --- - 4 ($gp size) --- - 4 ($lp size) --- - (4 * n) (callee-saved registers) --+ - 4 ($gp size) --+ - 4 ($lp size) --+ - (4 * n) (callee-saved registers) -- Note: No need to adjust --- cfun->machine->callee_saved_area_padding_bytes, --- because we want to adjust stack pointer --- to the position for pop instruction. */ --+ cfun->machine->callee_saved_area_gpr_padding_bytes, --+ because we want to adjust stack pointer --+ to the position for pop instruction. */ -- sp_adjust = cfun->machine->fp_size -- + cfun->machine->gp_size -- + cfun->machine->lp_size -- + cfun->machine->callee_saved_gpr_regs_size; --- sp_adjust_insn = gen_addsi3 (stack_pointer_rtx, --+ --+ /* Restore fpu registers. */ --+ if (cfun->machine->callee_saved_first_fpr_regno != SP_REGNUM) --+ { --+ /* Set $sp to callee saved fpr position, we need to restore --+ fpr registers. */ --+ sp_adjust = sp_adjust --+ + cfun->machine->callee_saved_area_gpr_padding_bytes --+ + cfun->machine->callee_saved_fpr_regs_size; --+ --+ nds32_emit_adjust_frame (stack_pointer_rtx, --+ hard_frame_pointer_rtx, --+ -1 * sp_adjust); --+ --+ /* Emit fpu load instruction, using [$sp + offset] restore --+ fpu registers. */ --+ nds32_emit_v3pop_fpr_callee_saved (0); --+ } --+ else --+ { --+ nds32_emit_adjust_frame (stack_pointer_rtx, -- hard_frame_pointer_rtx, --- GEN_INT (-1 * sp_adjust)); --- /* Emit rtx into instructions list and receive INSN rtx form. */ --- sp_adjust_insn = emit_insn (sp_adjust_insn); --+ -1 * sp_adjust); --+ } -- } -- else -- { --@@ -3381,33 +5934,57 @@ nds32_expand_epilogue_v3pop (bool sibcall_p) -- so we have to deal with it as well. */ -- -- /* Adjust $sp = $sp + local_size + out_args_size --- + callee_saved_area_padding_bytes. */ --+ + callee_saved_area_gpr_padding_bytes --+ + callee_saved_fpr_regs_size. */ -- sp_adjust = cfun->machine->local_size -- + cfun->machine->out_args_size --- + cfun->machine->callee_saved_area_gpr_padding_bytes; --- /* sp_adjust value may be out of range of the addi instruction, --- create alternative add behavior with TA_REGNUM if necessary, --- using POSITIVE value to tell that we are increasing address. */ --- sp_adjust = nds32_force_addi_stack_int (sp_adjust); --- if (sp_adjust) --+ + cfun->machine->callee_saved_area_gpr_padding_bytes --+ + cfun->machine->callee_saved_fpr_regs_size; --+ --+ /* Restore fpu registers. */ --+ if (cfun->machine->callee_saved_first_fpr_regno != SP_REGNUM) --+ { --+ /* Set $sp to callee saved fpr position, we need to restore --+ fpr registers. */ --+ sp_adjust = sp_adjust --+ - cfun->machine->callee_saved_area_gpr_padding_bytes --+ - cfun->machine->callee_saved_fpr_regs_size; --+ --+ nds32_emit_adjust_frame (stack_pointer_rtx, --+ stack_pointer_rtx, --+ sp_adjust); --+ --+ /* Emit fpu load instruction, using [$sp + offset] restore --+ fpu registers. */ --+ nds32_emit_v3pop_fpr_callee_saved (0); --+ } --+ else -- { --- /* Generate sp adjustment instruction --- if and only if sp_adjust != 0. */ --- sp_adjust_insn = gen_addsi3 (stack_pointer_rtx, --- stack_pointer_rtx, --- GEN_INT (sp_adjust)); --- /* Emit rtx into instructions list and receive INSN rtx form. */ --- sp_adjust_insn = emit_insn (sp_adjust_insn); --+ /* sp_adjust value may be out of range of the addi instruction, --+ create alternative add behavior with TA_REGNUM if necessary, --+ using POSITIVE value to tell that we are increasing --+ address. */ --+ nds32_emit_adjust_frame (stack_pointer_rtx, --+ stack_pointer_rtx, --+ sp_adjust); -- } -- } -- --- /* nds32_emit_stack_v3pop(last_regno, sp_adjust), --- the pattern 'stack_v3pop' is implementad in nds32.md. */ --- /* The (const_int 14) means v3pop always pop { $fp $gp $lp }. */ --- nds32_emit_stack_v3pop (Rb, Re, --- GEN_INT (14), GEN_INT (0)); --+ if (cfun->machine->callee_saved_first_fpr_regno != SP_REGNUM) --+ { --+ /* We have fpr need to restore, so $sp is set on callee saved fpr --+ position. And we use 'pop25 Re, fpr_space' to adjust $sp. */ --+ int fpr_space = cfun->machine->callee_saved_area_gpr_padding_bytes --+ + cfun->machine->callee_saved_fpr_regs_size; --+ nds32_emit_stack_v3pop (Rb, Re, fpr_space); --+ } --+ else --+ { --+ /* nds32_emit_stack_v3pop(last_regno, sp_adjust), --+ the pattern 'stack_v3pop' is implementad in nds32.md. */ --+ nds32_emit_stack_v3pop (Rb, Re, 0); --+ } -- } --- -- /* Generate return instruction. */ -- emit_jump_insn (gen_pop25return ()); -- } --@@ -3418,97 +5995,179 @@ nds32_expand_epilogue_v3pop (bool sibcall_p) -- int -- nds32_can_use_return_insn (void) -- { --+ int sp_adjust; --+ -- /* Prior to reloading, we can't tell how many registers must be saved. -- Thus we can not determine whether this function has null epilogue. */ -- if (!reload_completed) -- return 0; -- --+ /* If attribute 'naked' appears but -mno-ret-in-naked-func is used, --+ we cannot use return instruction. */ --+ if (cfun->machine->attr_naked_p && !flag_ret_in_naked_func) --+ return 0; --+ --+ sp_adjust = cfun->machine->local_size --+ + cfun->machine->out_args_size --+ + cfun->machine->callee_saved_area_gpr_padding_bytes --+ + cfun->machine->callee_saved_fpr_regs_size; --+ if (!cfun->machine->fp_as_gp_p --+ && satisfies_constraint_Iu08 (GEN_INT (sp_adjust)) --+ && NDS32_DOUBLE_WORD_ALIGN_P (sp_adjust) --+ && !cfun->calls_alloca --+ && NDS32_V3PUSH_AVAILABLE_P --+ && !(TARGET_HARD_FLOAT --+ && (cfun->machine->callee_saved_first_fpr_regno != SP_REGNUM))) --+ return 1; --+ -- /* If no stack was created, two conditions must be satisfied: -- 1. This is a naked function. --- So there is no callee-saved, local size, or outgoing size. --+ So there is no callee-saved, local size, or outgoing size. -- 2. This is NOT a variadic function. --- So there is no pushing arguement registers into the stack. */ --- return (cfun->machine->naked_p && (cfun->machine->va_args_size == 0)); --+ So there is no pushing arguement registers into the stack. */ --+ return ((cfun->machine->naked_p && (cfun->machine->va_args_size == 0))); -- } -- ---/* ------------------------------------------------------------------------ */ --- ---/* Function to test 333-form for load/store instructions. --- This is auxiliary extern function for auxiliary macro in nds32.h. --- Because it is a little complicated, we use function instead of macro. */ ---bool ---nds32_ls_333_p (rtx rt, rtx ra, rtx imm, machine_mode mode) --+enum machine_mode --+nds32_case_vector_shorten_mode (int min_offset, int max_offset, --+ rtx body ATTRIBUTE_UNUSED) -- { --- if (REGNO_REG_CLASS (REGNO (rt)) == LOW_REGS --- && REGNO_REG_CLASS (REGNO (ra)) == LOW_REGS) --+ if (min_offset < 0 || max_offset >= 0x2000) --+ return SImode; --+ else -- { --- if (GET_MODE_SIZE (mode) == 4) --- return satisfies_constraint_Iu05 (imm); --- --- if (GET_MODE_SIZE (mode) == 2) --- return satisfies_constraint_Iu04 (imm); --- --- if (GET_MODE_SIZE (mode) == 1) --- return satisfies_constraint_Iu03 (imm); --+ /* The jump table maybe need to 2 byte alignment, --+ so reserved 1 byte for check max_offset. */ --+ if (max_offset >= 0xff) --+ return HImode; --+ else --+ return QImode; -- } --+} --+ --+static bool --+nds32_cannot_copy_insn_p (rtx_insn *insn) --+{ --+ /* The hwloop_cfg insn cannot be copied. */ --+ if (recog_memoized (insn) == CODE_FOR_hwloop_cfg) --+ return true; -- -- return false; -- } -- --- ---/* Computing the Length of an Insn. --- Modifies the length assigned to instruction INSN. --- LEN is the initially computed length of the insn. */ --+/* Return alignment for the label. */ -- int ---nds32_adjust_insn_length (rtx_insn *insn, int length) --+nds32_target_alignment (rtx label) -- { --- rtx src, dst; --+ rtx_insn *insn; -- --- switch (recog_memoized (insn)) --+ if (!NDS32_ALIGN_P ()) --+ return 0; --+ --+ insn = next_active_insn (label); --+ --+ /* Always align to 4 byte when first instruction after label is jump --+ instruction since length for that might changed, so let's always align --+ it for make sure we don't lose any perfomance here. */ --+ if (insn == 0 --+ || (get_attr_length (insn) == 2 --+ && !JUMP_P (insn) && !CALL_P (insn))) --+ return 0; --+ else --+ return 2; --+} --+ --+/* Return alignment for data. */ --+unsigned int --+nds32_data_alignment (tree data, --+ unsigned int basic_align) --+{ --+ if ((basic_align < BITS_PER_WORD) --+ && (TREE_CODE (data) == ARRAY_TYPE --+ || TREE_CODE (data) == UNION_TYPE --+ || TREE_CODE (data) == RECORD_TYPE)) --+ return BITS_PER_WORD; --+ else --+ return basic_align; --+} --+ --+/* Return alignment for constant value. */ --+unsigned int --+nds32_constant_alignment (tree constant, --+ unsigned int basic_align) --+{ --+ /* Make string literal and constant for constructor to word align. */ --+ if (((TREE_CODE (constant) == STRING_CST --+ || TREE_CODE (constant) == CONSTRUCTOR --+ || TREE_CODE (constant) == UNION_TYPE --+ || TREE_CODE (constant) == RECORD_TYPE --+ || TREE_CODE (constant) == ARRAY_TYPE) --+ && basic_align < BITS_PER_WORD)) --+ return BITS_PER_WORD; --+ else --+ return basic_align; --+} --+ --+/* Return alignment for local variable. */ --+unsigned int --+nds32_local_alignment (tree local ATTRIBUTE_UNUSED, --+ unsigned int basic_align) --+{ --+ bool at_least_align_to_word = false; --+ /* Make local array, struct and union at least align to word for make --+ sure it can unroll memcpy when initialize by constant. */ --+ switch (TREE_CODE (local)) -- { --- case CODE_FOR_move_df: --- case CODE_FOR_move_di: --- /* Adjust length of movd44 to 2. */ --- src = XEXP (PATTERN (insn), 1); --- dst = XEXP (PATTERN (insn), 0); --- --- if (REG_P (src) --- && REG_P (dst) --- && (REGNO (src) % 2) == 0 --- && (REGNO (dst) % 2) == 0) --- length = 2; --+ case ARRAY_TYPE: --+ case RECORD_TYPE: --+ case UNION_TYPE: --+ at_least_align_to_word = true; -- break; --- -- default: --+ at_least_align_to_word = false; -- break; -- } --- --- return length; --+ if (at_least_align_to_word --+ && (basic_align < BITS_PER_WORD)) --+ return BITS_PER_WORD; --+ else --+ return basic_align; -- } -- --- ---/* Return align 2 (log base 2) if the next instruction of LABEL is 4 byte. */ ---int ---nds32_target_alignment (rtx label) --+bool --+nds32_split_double_word_load_store_p(rtx *operands, bool load_p) -- { --- rtx_insn *insn; --+ rtx mem = load_p ? operands[1] : operands[0]; --+ /* Do split at split2 if -O0 or schedule 2 not enable. */ --+ if (optimize == 0 || !flag_schedule_insns_after_reload) --+ return !satisfies_constraint_Da (mem) || MEM_VOLATILE_P (mem); -- --- if (optimize_size) --- return 0; --+ /* Split double word load store after copy propgation. */ --+ if (current_pass == NULL) --+ return false; -- --- insn = next_active_insn (label); --+ const char *pass_name = current_pass->name; --+ if (pass_name && ((strcmp (pass_name, "split4") == 0) --+ || (strcmp (pass_name, "split5") == 0))) --+ return !satisfies_constraint_Da (mem) || MEM_VOLATILE_P (mem); -- --- if (insn == 0) --- return 0; --- else if ((get_attr_length (insn) % 4) == 0) --- return 2; --+ return false; --+} --+ --+static bool --+nds32_use_blocks_for_constant_p (enum machine_mode mode, --+ const_rtx x ATTRIBUTE_UNUSED) --+{ --+ if ((TARGET_FPU_SINGLE || TARGET_FPU_DOUBLE) --+ && (mode == DFmode || mode == SFmode)) --+ return true; -- else --- return 0; --+ return false; -- } -- -- /* ------------------------------------------------------------------------ */ -- ---/* PART 5: Initialize target hook structure and definitions. */ --+/* PART 6: Initialize target hook structure and definitions. */ -- -- /* Controlling the Compilation Driver. */ -- --@@ -3525,6 +6184,9 @@ nds32_target_alignment (rtx label) -- #define TARGET_PROMOTE_FUNCTION_MODE \ -- default_promote_function_mode_always_promote -- --+#undef TARGET_EXPAND_TO_RTL_HOOK --+#define TARGET_EXPAND_TO_RTL_HOOK nds32_expand_to_rtl_hook --+ -- -- /* Layout of Source Language Data Types. */ -- --@@ -3533,6 +6195,9 @@ nds32_target_alignment (rtx label) -- -- /* -- Basic Characteristics of Registers. */ -- --+#undef TARGET_CONDITIONAL_REGISTER_USAGE --+#define TARGET_CONDITIONAL_REGISTER_USAGE nds32_conditional_register_usage --+ -- /* -- Order of Allocation of Registers. */ -- -- /* -- How Values Fit in Registers. */ --@@ -3544,6 +6209,9 @@ nds32_target_alignment (rtx label) -- -- /* Register Classes. */ -- --+#undef TARGET_PREFERRED_RENAME_CLASS --+#define TARGET_PREFERRED_RENAME_CLASS nds32_preferred_rename_class --+ -- #undef TARGET_CLASS_MAX_NREGS -- #define TARGET_CLASS_MAX_NREGS nds32_class_max_nregs -- --@@ -3591,6 +6259,9 @@ nds32_target_alignment (rtx label) -- #undef TARGET_FUNCTION_ARG_BOUNDARY -- #define TARGET_FUNCTION_ARG_BOUNDARY nds32_function_arg_boundary -- --+#undef TARGET_VECTOR_MODE_SUPPORTED_P --+#define TARGET_VECTOR_MODE_SUPPORTED_P nds32_vector_mode_supported_p --+ -- /* -- How Scalar Function Values Are Returned. */ -- -- #undef TARGET_FUNCTION_VALUE --@@ -3604,6 +6275,9 @@ nds32_target_alignment (rtx label) -- -- /* -- How Large Values Are Returned. */ -- --+#undef TARGET_RETURN_IN_MEMORY --+#define TARGET_RETURN_IN_MEMORY nds32_return_in_memory --+ -- /* -- Caller-Saves Register Allocation. */ -- -- /* -- Function Entry and Exit. */ --@@ -3630,6 +6304,9 @@ nds32_target_alignment (rtx label) -- -- /* -- Permitting tail calls. */ -- --+#undef TARGET_FUNCTION_OK_FOR_SIBCALL --+#define TARGET_FUNCTION_OK_FOR_SIBCALL nds32_function_ok_for_sibcall --+ -- #undef TARGET_WARN_FUNC_RETURN -- #define TARGET_WARN_FUNC_RETURN nds32_warn_func_return -- --@@ -3662,6 +6339,21 @@ nds32_target_alignment (rtx label) -- #undef TARGET_LEGITIMATE_ADDRESS_P -- #define TARGET_LEGITIMATE_ADDRESS_P nds32_legitimate_address_p -- --+#undef TARGET_LEGITIMIZE_ADDRESS --+#define TARGET_LEGITIMIZE_ADDRESS nds32_legitimize_address --+ --+#undef TARGET_LEGITIMATE_CONSTANT_P --+#define TARGET_LEGITIMATE_CONSTANT_P nds32_legitimate_constant_p --+ --+#undef TARGET_VECTORIZE_PREFERRED_SIMD_MODE --+#define TARGET_VECTORIZE_PREFERRED_SIMD_MODE nds32_vectorize_preferred_simd_mode --+ --+#undef TARGET_CANNOT_FORCE_CONST_MEM --+#define TARGET_CANNOT_FORCE_CONST_MEM nds32_cannot_force_const_mem --+ --+#undef TARGET_DELEGITIMIZE_ADDRESS --+#define TARGET_DELEGITIMIZE_ADDRESS nds32_delegitimize_address --+ -- -- /* Anchored Addresses. */ -- --@@ -3672,6 +6364,9 @@ nds32_target_alignment (rtx label) -- -- /* -- Representation of condition codes using registers. */ -- --+#undef TARGET_CANONICALIZE_COMPARISON --+#define TARGET_CANONICALIZE_COMPARISON nds32_canonicalize_comparison --+ -- /* -- Macros to control conditional execution. */ -- -- --@@ -3692,6 +6387,15 @@ nds32_target_alignment (rtx label) -- -- /* Adjusting the Instruction Scheduler. */ -- --+#undef TARGET_SCHED_ISSUE_RATE --+#define TARGET_SCHED_ISSUE_RATE nds32_sched_issue_rate --+ --+#undef TARGET_SCHED_ADJUST_COST --+#define TARGET_SCHED_ADJUST_COST nds32_sched_adjust_cost --+ --+#undef TARGET_SCHED_SET_SCHED_FLAGS --+#define TARGET_SCHED_SET_SCHED_FLAGS nds32_set_sched_flags --+ -- -- /* Dividing the Output into Sections (Texts, Data, . . . ). */ -- --@@ -3719,6 +6423,9 @@ nds32_target_alignment (rtx label) -- #undef TARGET_ASM_ALIGNED_SI_OP -- #define TARGET_ASM_ALIGNED_SI_OP "\t.word\t" -- --+#undef TARGET_ASM_OUTPUT_ADDR_CONST_EXTRA --+#define TARGET_ASM_OUTPUT_ADDR_CONST_EXTRA nds32_asm_output_addr_const_extra --+ -- /* -- Output of Uninitialized Variables. */ -- -- /* -- Output and Generation of Labels. */ --@@ -3741,6 +6448,9 @@ nds32_target_alignment (rtx label) -- -- /* -- Assembler Commands for Exception Regions. */ -- --+#undef TARGET_DWARF_REGISTER_SPAN --+#define TARGET_DWARF_REGISTER_SPAN nds32_dwarf_register_span --+ -- /* -- Assembler Commands for Alignment. */ -- -- --@@ -3756,6 +6466,11 @@ nds32_target_alignment (rtx label) -- -- /* -- Macros for SDB and DWARF Output. */ -- --+/* Variable tracking should be run after all optimizations which --+ change order of insns. It also needs a valid CFG. */ --+#undef TARGET_DELAY_VARTRACK --+#define TARGET_DELAY_VARTRACK true --+ -- /* -- Macros for VMS Debug Format. */ -- -- --@@ -3785,6 +6500,9 @@ nds32_target_alignment (rtx label) -- -- /* Emulating TLS. */ -- --+#undef TARGET_HAVE_TLS --+#define TARGET_HAVE_TLS TARGET_LINUX_ABI --+ -- -- /* Defining coprocessor specifics for MIPS targets. */ -- --@@ -3800,12 +6518,43 @@ nds32_target_alignment (rtx label) -- -- /* Miscellaneous Parameters. */ -- --+#undef TARGET_MD_ASM_ADJUST --+#define TARGET_MD_ASM_ADJUST nds32_md_asm_adjust --+ --+#undef TARGET_MACHINE_DEPENDENT_REORG --+#define TARGET_MACHINE_DEPENDENT_REORG nds32_machine_dependent_reorg --+ -- #undef TARGET_INIT_BUILTINS -- #define TARGET_INIT_BUILTINS nds32_init_builtins -- --+#undef TARGET_BUILTIN_DECL --+#define TARGET_BUILTIN_DECL nds32_builtin_decl --+ -- #undef TARGET_EXPAND_BUILTIN -- #define TARGET_EXPAND_BUILTIN nds32_expand_builtin -- --+#undef TARGET_HAVE_CONDITIONAL_EXECUTION --+#define TARGET_HAVE_CONDITIONAL_EXECUTION nds32_have_conditional_execution --+ --+#undef TARGET_INIT_LIBFUNCS --+#define TARGET_INIT_LIBFUNCS nds32_init_libfuncs --+ --+#undef TARGET_CAN_USE_DOLOOP_P --+#define TARGET_CAN_USE_DOLOOP_P nds32_can_use_doloop_p --+ --+#undef TARGET_INVALID_WITHIN_DOLOOP --+#define TARGET_INVALID_WITHIN_DOLOOP nds32_invalid_within_doloop --+ --+#undef TARGET_CANNOT_COPY_INSN_P --+#define TARGET_CANNOT_COPY_INSN_P nds32_cannot_copy_insn_p --+ --+#undef TARGET_MIN_ANCHOR_OFFSET --+#define TARGET_MIN_ANCHOR_OFFSET -((long long int) 1 << 14) --+#undef TARGET_MAX_ANCHOR_OFFSET --+#define TARGET_MAX_ANCHOR_OFFSET (((long long int) 1 << 14) - 1) --+#undef TARGET_USE_BLOCKS_FOR_CONSTANT_P --+#define TARGET_USE_BLOCKS_FOR_CONSTANT_P nds32_use_blocks_for_constant_p --+ -- -- /* ------------------------------------------------------------------------ */ -- --diff --git a/gcc/config/nds32/nds32.h b/gcc/config/nds32/nds32.h --index eb4558c..a3e07cd 100644 ----- a/gcc/config/nds32/nds32.h --+++ b/gcc/config/nds32/nds32.h --@@ -24,6 +24,9 @@ -- /* The following are auxiliary macros or structure declarations -- that are used all over the nds32.c and nds32.h. */ -- --+#define ADJUST_INSN_LENGTH(INSN, LENGTH) \ --+ (LENGTH = nds32_adjust_insn_length (INSN, LENGTH)) --+ -- /* Use SYMBOL_FLAG_MACH_DEP to define our own symbol_ref flag. -- It is used in nds32_encode_section_info() to store flag in symbol_ref -- in case the symbol should be placed in .rodata section. --@@ -33,68 +36,23 @@ -- #define NDS32_SYMBOL_REF_RODATA_P(x) \ -- ((SYMBOL_REF_FLAGS (x) & NDS32_SYMBOL_FLAG_RODATA) != 0) -- ---/* Computing the Length of an Insn. */ ---#define ADJUST_INSN_LENGTH(INSN, LENGTH) \ --- (LENGTH = nds32_adjust_insn_length (INSN, LENGTH)) --+enum nds32_relax_insn_type --+{ --+ RELAX_ORI, --+ RELAX_PLT_ADD, --+ RELAX_TLS_ADD_or_LW, --+ RELAX_TLS_ADD_LW, --+ RELAX_TLS_LW_JRAL, --+ RELAX_DONE --+}; -- ---/* Check instruction LS-37-FP-implied form. --- Note: actually its immediate range is imm9u --- since it is used for lwi37/swi37 instructions. */ ---#define NDS32_LS_37_FP_P(rt, ra, imm) \ --- (REGNO_REG_CLASS (REGNO (rt)) == LOW_REGS \ --- && REGNO (ra) == FP_REGNUM \ --- && satisfies_constraint_Iu09 (imm)) --- ---/* Check instruction LS-37-SP-implied form. --- Note: actually its immediate range is imm9u --- since it is used for lwi37/swi37 instructions. */ ---#define NDS32_LS_37_SP_P(rt, ra, imm) \ --- (REGNO_REG_CLASS (REGNO (rt)) == LOW_REGS \ --- && REGNO (ra) == SP_REGNUM \ --- && satisfies_constraint_Iu09 (imm)) --- --- ---/* Check load/store instruction form : Rt3, Ra3, imm3u. */ ---#define NDS32_LS_333_P(rt, ra, imm, mode) nds32_ls_333_p (rt, ra, imm, mode) --- ---/* Check load/store instruction form : Rt4, Ra5, const_int_0. --- Note: no need to check ra because Ra5 means it covers all registers. */ ---#define NDS32_LS_450_P(rt, ra, imm) \ --- ((imm == const0_rtx) \ --- && (REGNO_REG_CLASS (REGNO (rt)) == LOW_REGS \ --- || REGNO_REG_CLASS (REGNO (rt)) == MIDDLE_REGS)) --- ---/* Check instruction RRI-333-form. */ ---#define NDS32_RRI_333_P(rt, ra, imm) \ --- (REGNO_REG_CLASS (REGNO (rt)) == LOW_REGS \ --- && REGNO_REG_CLASS (REGNO (ra)) == LOW_REGS \ --- && satisfies_constraint_Iu03 (imm)) --- ---/* Check instruction RI-45-form. */ ---#define NDS32_RI_45_P(rt, ra, imm) \ --- (REGNO (rt) == REGNO (ra) \ --- && (REGNO_REG_CLASS (REGNO (rt)) == LOW_REGS \ --- || REGNO_REG_CLASS (REGNO (rt)) == MIDDLE_REGS) \ --- && satisfies_constraint_Iu05 (imm)) --- --- ---/* Check instruction RR-33-form. */ ---#define NDS32_RR_33_P(rt, ra) \ --- (REGNO_REG_CLASS (REGNO (rt)) == LOW_REGS \ --- && REGNO_REG_CLASS (REGNO (ra)) == LOW_REGS) --- ---/* Check instruction RRR-333-form. */ ---#define NDS32_RRR_333_P(rt, ra, rb) \ --- (REGNO_REG_CLASS (REGNO (rt)) == LOW_REGS \ --- && REGNO_REG_CLASS (REGNO (ra)) == LOW_REGS \ --- && REGNO_REG_CLASS (REGNO (rb)) == LOW_REGS) --- ---/* Check instruction RR-45-form. --- Note: no need to check rb because Rb5 means it covers all registers. */ ---#define NDS32_RR_45_P(rt, ra, rb) \ --- (REGNO (rt) == REGNO (ra) \ --- && (REGNO_REG_CLASS (REGNO (rt)) == LOW_REGS \ --- || REGNO_REG_CLASS (REGNO (rt)) == MIDDLE_REGS)) --+/* Classifies expand result for expand helper function. */ --+enum nds32_expand_result_type --+{ --+ EXPAND_DONE, --+ EXPAND_FAIL, --+ EXPAND_CREATE_TEMPLATE --+}; -- -- /* Classifies address type to distinguish 16-bit/32-bit format. */ -- enum nds32_16bit_address_type --@@ -105,6 +63,10 @@ enum nds32_16bit_address_type -- ADDRESS_LO_REG_IMM3U, -- /* post_inc [lo_reg + imm3u]: 333 format address. */ -- ADDRESS_POST_INC_LO_REG_IMM3U, --+ /* post_modify [lo_reg + imm3u]: 333 format address. */ --+ ADDRESS_POST_MODIFY_LO_REG_IMM3U, --+ /* [$r8 + imm7u]: r8 imply address. */ --+ ADDRESS_R8_IMM7U, -- /* [$fp + imm7u]: fp imply address. */ -- ADDRESS_FP_IMM7U, -- /* [$sp + imm7u]: sp imply address. */ --@@ -113,23 +75,67 @@ enum nds32_16bit_address_type -- ADDRESS_NOT_16BIT_FORMAT -- }; -- --- -- /* ------------------------------------------------------------------------ */ -- -- /* Define maximum numbers of registers for passing arguments. */ -- #define NDS32_MAX_GPR_REGS_FOR_ARGS 6 --+#define NDS32_MAX_FPR_REGS_FOR_ARGS 6 -- -- /* Define the register number for first argument. */ -- #define NDS32_GPR_ARG_FIRST_REGNUM 0 --+#define NDS32_FPR_ARG_FIRST_REGNUM 34 -- -- /* Define the register number for return value. */ -- #define NDS32_GPR_RET_FIRST_REGNUM 0 --+#define NDS32_FPR_RET_FIRST_REGNUM 34 -- -- /* Define the first integer register number. */ -- #define NDS32_FIRST_GPR_REGNUM 0 -- /* Define the last integer register number. */ -- #define NDS32_LAST_GPR_REGNUM 31 -- --+#define NDS32_FIRST_CALLEE_SAVE_GPR_REGNUM 6 --+#define NDS32_LAST_CALLEE_SAVE_GPR_REGNUM \ --+ (TARGET_REDUCED_REGS ? 10 : 14) --+ --+/* Define the floating-point number of registers. */ --+#define NDS32_FLOAT_REGISTER_NUMBER \ --+ (((nds32_fp_regnum == NDS32_CONFIG_FPU_0) \ --+ || (nds32_fp_regnum == NDS32_CONFIG_FPU_4)) ? 8 \ --+ : ((nds32_fp_regnum == NDS32_CONFIG_FPU_1) \ --+ || (nds32_fp_regnum == NDS32_CONFIG_FPU_5)) ? 16 \ --+ : ((nds32_fp_regnum == NDS32_CONFIG_FPU_2) \ --+ || (nds32_fp_regnum == NDS32_CONFIG_FPU_6)) ? 32 \ --+ : ((nds32_fp_regnum == NDS32_CONFIG_FPU_3) \ --+ || (nds32_fp_regnum == NDS32_CONFIG_FPU_7)) ? 64 \ --+ : 32) --+ --+#define NDS32_EXT_FPU_DOT_E (nds32_fp_regnum >= 4) --+ --+/* Define the first floating-point register number. */ --+#define NDS32_FIRST_FPR_REGNUM 34 --+/* Define the last floating-point register number. */ --+#define NDS32_LAST_FPR_REGNUM \ --+ (NDS32_FIRST_FPR_REGNUM + NDS32_FLOAT_REGISTER_NUMBER - 1) --+ --+ --+#define NDS32_IS_EXT_FPR_REGNUM(regno) \ --+ (((regno) >= NDS32_FIRST_FPR_REGNUM + 32) \ --+ && ((regno) < NDS32_FIRST_FPR_REGNUM + 64)) --+ --+#define NDS32_IS_FPR_REGNUM(regno) \ --+ (((regno) >= NDS32_FIRST_FPR_REGNUM) \ --+ && ((regno) <= NDS32_LAST_FPR_REGNUM)) --+ --+#define NDS32_FPR_REGNO_OK_FOR_SINGLE(regno) \ --+ ((regno) <= NDS32_LAST_FPR_REGNUM) --+ --+#define NDS32_FPR_REGNO_OK_FOR_DOUBLE(regno) \ --+ ((((regno) - NDS32_FIRST_FPR_REGNUM) & 1) == 0) --+ --+#define NDS32_IS_GPR_REGNUM(regno) \ --+ (((regno) <= NDS32_LAST_GPR_REGNUM)) --+ -- /* Define double word alignment bits. */ -- #define NDS32_DOUBLE_WORD_ALIGNMENT 64 -- --@@ -138,6 +144,16 @@ enum nds32_16bit_address_type -- #define NDS32_SINGLE_WORD_ALIGN_P(value) (((value) & 0x03) == 0) -- #define NDS32_DOUBLE_WORD_ALIGN_P(value) (((value) & 0x07) == 0) -- --+/* Determine whether we would like to have code generation strictly aligned. --+ We set it strictly aligned when -malways-align is enabled. --+ Check gcc/common/config/nds32/nds32-common.c for the optimizations that --+ apply -malways-align. */ --+#define NDS32_ALIGN_P() (TARGET_ALWAYS_ALIGN) --+ --+#define NDS32_HW_LOOP_P() (TARGET_HWLOOP && !TARGET_FORCE_NO_HWLOOP) --+ --+#define NDS32_EXT_DSP_P() (TARGET_EXT_DSP && !TARGET_FORCE_NO_EXT_DSP) --+ -- /* Get alignment according to mode or type information. -- When 'type' is nonnull, there is no need to look at 'mode'. */ -- #define NDS32_MODE_TYPE_ALIGN(mode, type) \ --@@ -159,21 +175,28 @@ enum nds32_16bit_address_type -- /* This macro is used to return the register number for passing argument. -- We need to obey the following rules: -- 1. If it is required MORE THAN one register, --- we need to further check if it really needs to be --- aligned on double words. --- a) If double word alignment is necessary, --- the register number must be even value. --- b) Otherwise, the register number can be odd or even value. --+ we need to further check if it really needs to be --+ aligned on double words. --+ a) If double word alignment is necessary, --+ the register number must be even value. --+ b) Otherwise, the register number can be odd or even value. -- 2. If it is required ONLY one register, --- the register number can be odd or even value. */ ---#define NDS32_AVAILABLE_REGNUM_FOR_GPR_ARG(reg_offset, mode, type) \ --- ((NDS32_NEED_N_REGS_FOR_ARG (mode, type) > 1) \ --- ? ((NDS32_MODE_TYPE_ALIGN (mode, type) > PARM_BOUNDARY) \ --- ? (((reg_offset) + NDS32_GPR_ARG_FIRST_REGNUM + 1) & ~1) \ --- : ((reg_offset) + NDS32_GPR_ARG_FIRST_REGNUM)) \ --+ the register number can be odd or even value. */ --+#define NDS32_AVAILABLE_REGNUM_FOR_GPR_ARG(reg_offset, mode, type) \ --+ ((NDS32_NEED_N_REGS_FOR_ARG (mode, type) > 1) \ --+ ? ((NDS32_MODE_TYPE_ALIGN (mode, type) > PARM_BOUNDARY) \ --+ ? (((reg_offset) + NDS32_GPR_ARG_FIRST_REGNUM + 1) & ~1) \ --+ : ((reg_offset) + NDS32_GPR_ARG_FIRST_REGNUM)) \ -- : ((reg_offset) + NDS32_GPR_ARG_FIRST_REGNUM)) -- ---/* This macro is to check if there are still available registers --+#define NDS32_AVAILABLE_REGNUM_FOR_FPR_ARG(reg_offset, mode, type) \ --+ ((NDS32_NEED_N_REGS_FOR_ARG (mode, type) > 1) \ --+ ? ((NDS32_MODE_TYPE_ALIGN (mode, type) > PARM_BOUNDARY) \ --+ ? (((reg_offset) + NDS32_FPR_ARG_FIRST_REGNUM + 1) & ~1) \ --+ : ((reg_offset) + NDS32_FPR_ARG_FIRST_REGNUM)) \ --+ : ((reg_offset) + NDS32_FPR_ARG_FIRST_REGNUM)) --+ --+/* These two macros are to check if there are still available registers -- for passing argument, which must be entirely in registers. */ -- #define NDS32_ARG_ENTIRE_IN_GPR_REG_P(reg_offset, mode, type) \ -- ((NDS32_AVAILABLE_REGNUM_FOR_GPR_ARG (reg_offset, mode, type) \ --@@ -181,13 +204,23 @@ enum nds32_16bit_address_type -- <= (NDS32_GPR_ARG_FIRST_REGNUM \ -- + NDS32_MAX_GPR_REGS_FOR_ARGS)) -- ---/* This macro is to check if there are still available registers --+#define NDS32_ARG_ENTIRE_IN_FPR_REG_P(reg_offset, mode, type) \ --+ ((NDS32_AVAILABLE_REGNUM_FOR_FPR_ARG (reg_offset, mode, type) \ --+ + NDS32_NEED_N_REGS_FOR_ARG (mode, type)) \ --+ <= (NDS32_FPR_ARG_FIRST_REGNUM \ --+ + NDS32_MAX_FPR_REGS_FOR_ARGS)) --+ --+/* These two macros are to check if there are still available registers -- for passing argument, either entirely in registers or partially -- in registers. */ -- #define NDS32_ARG_PARTIAL_IN_GPR_REG_P(reg_offset, mode, type) \ -- (NDS32_AVAILABLE_REGNUM_FOR_GPR_ARG (reg_offset, mode, type) \ -- < NDS32_GPR_ARG_FIRST_REGNUM + NDS32_MAX_GPR_REGS_FOR_ARGS) -- --+#define NDS32_ARG_PARTIAL_IN_FPR_REG_P(reg_offset, mode, type) \ --+ (NDS32_AVAILABLE_REGNUM_FOR_FPR_ARG (reg_offset, mode, type) \ --+ < NDS32_FPR_ARG_FIRST_REGNUM + NDS32_MAX_FPR_REGS_FOR_ARGS) --+ -- /* This macro is to check if the register is required to be saved on stack. -- If call_used_regs[regno] == 0, regno is the callee-saved register. -- If df_regs_ever_live_p(regno) == true, it is used in the current function. --@@ -196,6 +229,19 @@ enum nds32_16bit_address_type -- #define NDS32_REQUIRED_CALLEE_SAVED_P(regno) \ -- ((!call_used_regs[regno]) && (df_regs_ever_live_p (regno))) -- --+/* This macro is to check if the push25/pop25 are available to be used --+ for code generation. Because pop25 also performs return behavior, --+ the instructions may not be available for some cases. --+ If we want to use push25/pop25, all the following conditions must --+ be satisfied: --+ 1. TARGET_V3PUSH is set. --+ 2. Current function is not an ISR function. --+ 3. Current function is not a variadic function.*/ --+#define NDS32_V3PUSH_AVAILABLE_P \ --+ (TARGET_V3PUSH \ --+ && !nds32_isr_function_p (current_function_decl) \ --+ && (cfun->machine->va_args_size == 0)) --+ -- /* ------------------------------------------------------------------------ */ -- -- /* A C structure for machine-specific, per-function data. --@@ -222,6 +268,10 @@ struct GTY(()) machine_function -- callee-saved registers. */ -- int callee_saved_gpr_regs_size; -- --+ /* Number of bytes on the stack for saving floating-point --+ callee-saved registers. */ --+ int callee_saved_fpr_regs_size; --+ -- /* The padding bytes in callee-saved area may be required. */ -- int callee_saved_area_gpr_padding_bytes; -- --@@ -230,26 +280,57 @@ struct GTY(()) machine_function -- /* The last required general purpose callee-saved register. */ -- int callee_saved_last_gpr_regno; -- --+ /* The first required floating-point callee-saved register. */ --+ int callee_saved_first_fpr_regno; --+ /* The last required floating-point callee-saved register. */ --+ int callee_saved_last_fpr_regno; --+ -- /* The padding bytes in varargs area may be required. */ -- int va_args_area_padding_bytes; --- -- /* The first required register that should be saved on stack for va_args. */ -- int va_args_first_regno; -- /* The last required register that should be saved on stack for va_args. */ -- int va_args_last_regno; -- --+ /* Number of bytes on the stack for saving exception handling registers. */ --+ int eh_return_data_regs_size; --+ /* The first register of passing exception handling information. */ --+ int eh_return_data_first_regno; --+ /* The last register of passing exception handling information. */ --+ int eh_return_data_last_regno; --+ --+ /* Indicate that whether this function --+ calls __builtin_eh_return. */ --+ int use_eh_return_p; --+ -- /* Indicate that whether this function needs -- prologue/epilogue code generation. */ -- int naked_p; -- /* Indicate that whether this function -- uses fp_as_gp optimization. */ -- int fp_as_gp_p; --+ /* Indicate that whether this function is under strictly aligned --+ situation for legitimate address checking. This flag informs --+ nds32_legitimate_address_p() how to treat offset alignment: --+ 1. The IVOPT phase needs to detect available range for memory access, --+ such as checking [base + 32767] ~ [base + (-32768)]. --+ For this case we do not want address to be strictly aligned. --+ 2. The rtl lowering and optimization are close to target code. --+ For this case we need address to be strictly aligned. */ --+ int strict_aligned_p; --+ --+ /* Record two similar attributes status. */ --+ int attr_naked_p; --+ int attr_no_prologue_p; --+ /* Record hwloop group, use in reorg pass. */ --+ int hwloop_group_id; -- }; -- -- /* A C structure that contains the arguments information. */ -- typedef struct -- { -- unsigned int gpr_offset; --+ unsigned int fpr_offset; -- } nds32_cumulative_args; -- -- /* ------------------------------------------------------------------------ */ --@@ -288,7 +369,8 @@ enum nds32_isr_nested_type -- { -- NDS32_NESTED, -- NDS32_NOT_NESTED, --- NDS32_NESTED_READY --+ NDS32_NESTED_READY, --+ NDS32_CRITICAL -- }; -- -- /* Define structure to record isr information. --@@ -316,6 +398,13 @@ struct nds32_isr_info -- unless user specifies attribute to change it. */ -- enum nds32_isr_nested_type nested_type; -- --+ /* Secure isr level. --+ Currently we have 0-3 security level. --+ It should be set to 0 by default. --+ For security processors, this is determined by secure --+ attribute or compiler options. */ --+ unsigned int security_level; --+ -- /* Total vectors. -- The total vectors = interrupt + exception numbers + reset. -- It should be set to 0 by default. --@@ -340,19 +429,477 @@ enum nds32_builtins -- { -- NDS32_BUILTIN_ISYNC, -- NDS32_BUILTIN_ISB, --+ NDS32_BUILTIN_DSB, --+ NDS32_BUILTIN_MSYNC_ALL, --+ NDS32_BUILTIN_MSYNC_STORE, -- NDS32_BUILTIN_MFSR, -- NDS32_BUILTIN_MFUSR, -- NDS32_BUILTIN_MTSR, --+ NDS32_BUILTIN_MTSR_ISB, --+ NDS32_BUILTIN_MTSR_DSB, -- NDS32_BUILTIN_MTUSR, -- NDS32_BUILTIN_SETGIE_EN, --- NDS32_BUILTIN_SETGIE_DIS --+ NDS32_BUILTIN_SETGIE_DIS, --+ NDS32_BUILTIN_FMFCFG, --+ NDS32_BUILTIN_FMFCSR, --+ NDS32_BUILTIN_FMTCSR, --+ NDS32_BUILTIN_FCPYNSS, --+ NDS32_BUILTIN_FCPYSS, --+ NDS32_BUILTIN_FCPYNSD, --+ NDS32_BUILTIN_FCPYSD, --+ NDS32_BUILTIN_FABSS, --+ NDS32_BUILTIN_FABSD, --+ NDS32_BUILTIN_FSQRTS, --+ NDS32_BUILTIN_FSQRTD, --+ NDS32_BUILTIN_ABS, --+ NDS32_BUILTIN_AVE, --+ NDS32_BUILTIN_BCLR, --+ NDS32_BUILTIN_BSET, --+ NDS32_BUILTIN_BTGL, --+ NDS32_BUILTIN_BTST, --+ NDS32_BUILTIN_CLIP, --+ NDS32_BUILTIN_CLIPS, --+ NDS32_BUILTIN_CLZ, --+ NDS32_BUILTIN_CLO, --+ NDS32_BUILTIN_MAX, --+ NDS32_BUILTIN_MIN, --+ NDS32_BUILTIN_PBSAD, --+ NDS32_BUILTIN_PBSADA, --+ NDS32_BUILTIN_BSE, --+ NDS32_BUILTIN_BSP, --+ NDS32_BUILTIN_FFB, --+ NDS32_BUILTIN_FFMISM, --+ NDS32_BUILTIN_FLMISM, --+ NDS32_BUILTIN_KADDW, --+ NDS32_BUILTIN_KSUBW, --+ NDS32_BUILTIN_KADDH, --+ NDS32_BUILTIN_KSUBH, --+ NDS32_BUILTIN_KDMBB, --+ NDS32_BUILTIN_V_KDMBB, --+ NDS32_BUILTIN_KDMBT, --+ NDS32_BUILTIN_V_KDMBT, --+ NDS32_BUILTIN_KDMTB, --+ NDS32_BUILTIN_V_KDMTB, --+ NDS32_BUILTIN_KDMTT, --+ NDS32_BUILTIN_V_KDMTT, --+ NDS32_BUILTIN_KHMBB, --+ NDS32_BUILTIN_V_KHMBB, --+ NDS32_BUILTIN_KHMBT, --+ NDS32_BUILTIN_V_KHMBT, --+ NDS32_BUILTIN_KHMTB, --+ NDS32_BUILTIN_V_KHMTB, --+ NDS32_BUILTIN_KHMTT, --+ NDS32_BUILTIN_V_KHMTT, --+ NDS32_BUILTIN_KSLRAW, --+ NDS32_BUILTIN_KSLRAW_U, --+ NDS32_BUILTIN_RDOV, --+ NDS32_BUILTIN_CLROV, --+ NDS32_BUILTIN_ROTR, --+ NDS32_BUILTIN_SVA, --+ NDS32_BUILTIN_SVS, --+ NDS32_BUILTIN_WSBH, --+ NDS32_BUILTIN_JR_ITOFF, --+ NDS32_BUILTIN_JR_TOFF, --+ NDS32_BUILTIN_JRAL_ITON, --+ NDS32_BUILTIN_JRAL_TON, --+ NDS32_BUILTIN_RET_ITOFF, --+ NDS32_BUILTIN_RET_TOFF, --+ NDS32_BUILTIN_STANDBY_NO_WAKE_GRANT, --+ NDS32_BUILTIN_STANDBY_WAKE_GRANT, --+ NDS32_BUILTIN_STANDBY_WAKE_DONE, --+ NDS32_BUILTIN_TEQZ, --+ NDS32_BUILTIN_TNEZ, --+ NDS32_BUILTIN_TRAP, --+ NDS32_BUILTIN_SETEND_BIG, --+ NDS32_BUILTIN_SETEND_LITTLE, --+ NDS32_BUILTIN_SYSCALL, --+ NDS32_BUILTIN_BREAK, --+ NDS32_BUILTIN_NOP, --+ NDS32_BUILTIN_SCHE_BARRIER, --+ NDS32_BUILTIN_GET_CURRENT_SP, --+ NDS32_BUILTIN_SET_CURRENT_SP, --+ NDS32_BUILTIN_RETURN_ADDRESS, --+ NDS32_BUILTIN_LLW, --+ NDS32_BUILTIN_LWUP, --+ NDS32_BUILTIN_LBUP, --+ NDS32_BUILTIN_SCW, --+ NDS32_BUILTIN_SWUP, --+ NDS32_BUILTIN_SBUP, --+ NDS32_BUILTIN_CCTL_VA_LCK, --+ NDS32_BUILTIN_CCTL_IDX_WBINVAL, --+ NDS32_BUILTIN_CCTL_VA_WBINVAL_L1, --+ NDS32_BUILTIN_CCTL_VA_WBINVAL_LA, --+ NDS32_BUILTIN_CCTL_IDX_READ, --+ NDS32_BUILTIN_CCTL_IDX_WRITE, --+ NDS32_BUILTIN_CCTL_L1D_INVALALL, --+ NDS32_BUILTIN_CCTL_L1D_WBALL_ALVL, --+ NDS32_BUILTIN_CCTL_L1D_WBALL_ONE_LVL, --+ NDS32_BUILTIN_DPREF_QW, --+ NDS32_BUILTIN_DPREF_HW, --+ NDS32_BUILTIN_DPREF_W, --+ NDS32_BUILTIN_DPREF_DW, --+ NDS32_BUILTIN_TLBOP_TRD, --+ NDS32_BUILTIN_TLBOP_TWR, --+ NDS32_BUILTIN_TLBOP_RWR, --+ NDS32_BUILTIN_TLBOP_RWLK, --+ NDS32_BUILTIN_TLBOP_UNLK, --+ NDS32_BUILTIN_TLBOP_PB, --+ NDS32_BUILTIN_TLBOP_INV, --+ NDS32_BUILTIN_TLBOP_FLUA, --+ NDS32_BUILTIN_UALOAD_HW, --+ NDS32_BUILTIN_UALOAD_W, --+ NDS32_BUILTIN_UALOAD_DW, --+ NDS32_BUILTIN_UASTORE_HW, --+ NDS32_BUILTIN_UASTORE_W, --+ NDS32_BUILTIN_UASTORE_DW, --+ NDS32_BUILTIN_GIE_DIS, --+ NDS32_BUILTIN_GIE_EN, --+ NDS32_BUILTIN_ENABLE_INT, --+ NDS32_BUILTIN_DISABLE_INT, --+ NDS32_BUILTIN_SET_PENDING_SWINT, --+ NDS32_BUILTIN_CLR_PENDING_SWINT, --+ NDS32_BUILTIN_CLR_PENDING_HWINT, --+ NDS32_BUILTIN_GET_ALL_PENDING_INT, --+ NDS32_BUILTIN_GET_PENDING_INT, --+ NDS32_BUILTIN_SET_INT_PRIORITY, --+ NDS32_BUILTIN_GET_INT_PRIORITY, --+ NDS32_BUILTIN_SET_TRIG_LEVEL, --+ NDS32_BUILTIN_SET_TRIG_EDGE, --+ NDS32_BUILTIN_GET_TRIG_TYPE, --+ NDS32_BUILTIN_SIGNATURE_BEGIN, --+ NDS32_BUILTIN_SIGNATURE_END, --+ NDS32_BUILTIN_DSP_BEGIN, --+ NDS32_BUILTIN_ADD16, --+ NDS32_BUILTIN_V_UADD16, --+ NDS32_BUILTIN_V_SADD16, --+ NDS32_BUILTIN_RADD16, --+ NDS32_BUILTIN_V_RADD16, --+ NDS32_BUILTIN_URADD16, --+ NDS32_BUILTIN_V_URADD16, --+ NDS32_BUILTIN_KADD16, --+ NDS32_BUILTIN_V_KADD16, --+ NDS32_BUILTIN_UKADD16, --+ NDS32_BUILTIN_V_UKADD16, --+ NDS32_BUILTIN_SUB16, --+ NDS32_BUILTIN_V_USUB16, --+ NDS32_BUILTIN_V_SSUB16, --+ NDS32_BUILTIN_RSUB16, --+ NDS32_BUILTIN_V_RSUB16, --+ NDS32_BUILTIN_URSUB16, --+ NDS32_BUILTIN_V_URSUB16, --+ NDS32_BUILTIN_KSUB16, --+ NDS32_BUILTIN_V_KSUB16, --+ NDS32_BUILTIN_UKSUB16, --+ NDS32_BUILTIN_V_UKSUB16, --+ NDS32_BUILTIN_CRAS16, --+ NDS32_BUILTIN_V_UCRAS16, --+ NDS32_BUILTIN_V_SCRAS16, --+ NDS32_BUILTIN_RCRAS16, --+ NDS32_BUILTIN_V_RCRAS16, --+ NDS32_BUILTIN_URCRAS16, --+ NDS32_BUILTIN_V_URCRAS16, --+ NDS32_BUILTIN_KCRAS16, --+ NDS32_BUILTIN_V_KCRAS16, --+ NDS32_BUILTIN_UKCRAS16, --+ NDS32_BUILTIN_V_UKCRAS16, --+ NDS32_BUILTIN_CRSA16, --+ NDS32_BUILTIN_V_UCRSA16, --+ NDS32_BUILTIN_V_SCRSA16, --+ NDS32_BUILTIN_RCRSA16, --+ NDS32_BUILTIN_V_RCRSA16, --+ NDS32_BUILTIN_URCRSA16, --+ NDS32_BUILTIN_V_URCRSA16, --+ NDS32_BUILTIN_KCRSA16, --+ NDS32_BUILTIN_V_KCRSA16, --+ NDS32_BUILTIN_UKCRSA16, --+ NDS32_BUILTIN_V_UKCRSA16, --+ NDS32_BUILTIN_ADD8, --+ NDS32_BUILTIN_V_UADD8, --+ NDS32_BUILTIN_V_SADD8, --+ NDS32_BUILTIN_RADD8, --+ NDS32_BUILTIN_V_RADD8, --+ NDS32_BUILTIN_URADD8, --+ NDS32_BUILTIN_V_URADD8, --+ NDS32_BUILTIN_KADD8, --+ NDS32_BUILTIN_V_KADD8, --+ NDS32_BUILTIN_UKADD8, --+ NDS32_BUILTIN_V_UKADD8, --+ NDS32_BUILTIN_SUB8, --+ NDS32_BUILTIN_V_USUB8, --+ NDS32_BUILTIN_V_SSUB8, --+ NDS32_BUILTIN_RSUB8, --+ NDS32_BUILTIN_V_RSUB8, --+ NDS32_BUILTIN_URSUB8, --+ NDS32_BUILTIN_V_URSUB8, --+ NDS32_BUILTIN_KSUB8, --+ NDS32_BUILTIN_V_KSUB8, --+ NDS32_BUILTIN_UKSUB8, --+ NDS32_BUILTIN_V_UKSUB8, --+ NDS32_BUILTIN_SRA16, --+ NDS32_BUILTIN_V_SRA16, --+ NDS32_BUILTIN_SRA16_U, --+ NDS32_BUILTIN_V_SRA16_U, --+ NDS32_BUILTIN_SRL16, --+ NDS32_BUILTIN_V_SRL16, --+ NDS32_BUILTIN_SRL16_U, --+ NDS32_BUILTIN_V_SRL16_U, --+ NDS32_BUILTIN_SLL16, --+ NDS32_BUILTIN_V_SLL16, --+ NDS32_BUILTIN_KSLL16, --+ NDS32_BUILTIN_V_KSLL16, --+ NDS32_BUILTIN_KSLRA16, --+ NDS32_BUILTIN_V_KSLRA16, --+ NDS32_BUILTIN_KSLRA16_U, --+ NDS32_BUILTIN_V_KSLRA16_U, --+ NDS32_BUILTIN_CMPEQ16, --+ NDS32_BUILTIN_V_SCMPEQ16, --+ NDS32_BUILTIN_V_UCMPEQ16, --+ NDS32_BUILTIN_SCMPLT16, --+ NDS32_BUILTIN_V_SCMPLT16, --+ NDS32_BUILTIN_SCMPLE16, --+ NDS32_BUILTIN_V_SCMPLE16, --+ NDS32_BUILTIN_UCMPLT16, --+ NDS32_BUILTIN_V_UCMPLT16, --+ NDS32_BUILTIN_UCMPLE16, --+ NDS32_BUILTIN_V_UCMPLE16, --+ NDS32_BUILTIN_CMPEQ8, --+ NDS32_BUILTIN_V_SCMPEQ8, --+ NDS32_BUILTIN_V_UCMPEQ8, --+ NDS32_BUILTIN_SCMPLT8, --+ NDS32_BUILTIN_V_SCMPLT8, --+ NDS32_BUILTIN_SCMPLE8, --+ NDS32_BUILTIN_V_SCMPLE8, --+ NDS32_BUILTIN_UCMPLT8, --+ NDS32_BUILTIN_V_UCMPLT8, --+ NDS32_BUILTIN_UCMPLE8, --+ NDS32_BUILTIN_V_UCMPLE8, --+ NDS32_BUILTIN_SMIN16, --+ NDS32_BUILTIN_V_SMIN16, --+ NDS32_BUILTIN_UMIN16, --+ NDS32_BUILTIN_V_UMIN16, --+ NDS32_BUILTIN_SMAX16, --+ NDS32_BUILTIN_V_SMAX16, --+ NDS32_BUILTIN_UMAX16, --+ NDS32_BUILTIN_V_UMAX16, --+ NDS32_BUILTIN_SCLIP16, --+ NDS32_BUILTIN_V_SCLIP16, --+ NDS32_BUILTIN_UCLIP16, --+ NDS32_BUILTIN_V_UCLIP16, --+ NDS32_BUILTIN_KHM16, --+ NDS32_BUILTIN_V_KHM16, --+ NDS32_BUILTIN_KHMX16, --+ NDS32_BUILTIN_V_KHMX16, --+ NDS32_BUILTIN_KABS16, --+ NDS32_BUILTIN_V_KABS16, --+ NDS32_BUILTIN_SMIN8, --+ NDS32_BUILTIN_V_SMIN8, --+ NDS32_BUILTIN_UMIN8, --+ NDS32_BUILTIN_V_UMIN8, --+ NDS32_BUILTIN_SMAX8, --+ NDS32_BUILTIN_V_SMAX8, --+ NDS32_BUILTIN_UMAX8, --+ NDS32_BUILTIN_V_UMAX8, --+ NDS32_BUILTIN_KABS8, --+ NDS32_BUILTIN_V_KABS8, --+ NDS32_BUILTIN_SUNPKD810, --+ NDS32_BUILTIN_V_SUNPKD810, --+ NDS32_BUILTIN_SUNPKD820, --+ NDS32_BUILTIN_V_SUNPKD820, --+ NDS32_BUILTIN_SUNPKD830, --+ NDS32_BUILTIN_V_SUNPKD830, --+ NDS32_BUILTIN_SUNPKD831, --+ NDS32_BUILTIN_V_SUNPKD831, --+ NDS32_BUILTIN_ZUNPKD810, --+ NDS32_BUILTIN_V_ZUNPKD810, --+ NDS32_BUILTIN_ZUNPKD820, --+ NDS32_BUILTIN_V_ZUNPKD820, --+ NDS32_BUILTIN_ZUNPKD830, --+ NDS32_BUILTIN_V_ZUNPKD830, --+ NDS32_BUILTIN_ZUNPKD831, --+ NDS32_BUILTIN_V_ZUNPKD831, --+ NDS32_BUILTIN_RADDW, --+ NDS32_BUILTIN_URADDW, --+ NDS32_BUILTIN_RSUBW, --+ NDS32_BUILTIN_URSUBW, --+ NDS32_BUILTIN_SRA_U, --+ NDS32_BUILTIN_KSLL, --+ NDS32_BUILTIN_PKBB16, --+ NDS32_BUILTIN_V_PKBB16, --+ NDS32_BUILTIN_PKBT16, --+ NDS32_BUILTIN_V_PKBT16, --+ NDS32_BUILTIN_PKTB16, --+ NDS32_BUILTIN_V_PKTB16, --+ NDS32_BUILTIN_PKTT16, --+ NDS32_BUILTIN_V_PKTT16, --+ NDS32_BUILTIN_SMMUL, --+ NDS32_BUILTIN_SMMUL_U, --+ NDS32_BUILTIN_KMMAC, --+ NDS32_BUILTIN_KMMAC_U, --+ NDS32_BUILTIN_KMMSB, --+ NDS32_BUILTIN_KMMSB_U, --+ NDS32_BUILTIN_KWMMUL, --+ NDS32_BUILTIN_KWMMUL_U, --+ NDS32_BUILTIN_SMMWB, --+ NDS32_BUILTIN_V_SMMWB, --+ NDS32_BUILTIN_SMMWB_U, --+ NDS32_BUILTIN_V_SMMWB_U, --+ NDS32_BUILTIN_SMMWT, --+ NDS32_BUILTIN_V_SMMWT, --+ NDS32_BUILTIN_SMMWT_U, --+ NDS32_BUILTIN_V_SMMWT_U, --+ NDS32_BUILTIN_KMMAWB, --+ NDS32_BUILTIN_V_KMMAWB, --+ NDS32_BUILTIN_KMMAWB_U, --+ NDS32_BUILTIN_V_KMMAWB_U, --+ NDS32_BUILTIN_KMMAWT, --+ NDS32_BUILTIN_V_KMMAWT, --+ NDS32_BUILTIN_KMMAWT_U, --+ NDS32_BUILTIN_V_KMMAWT_U, --+ NDS32_BUILTIN_SMBB, --+ NDS32_BUILTIN_V_SMBB, --+ NDS32_BUILTIN_SMBT, --+ NDS32_BUILTIN_V_SMBT, --+ NDS32_BUILTIN_SMTT, --+ NDS32_BUILTIN_V_SMTT, --+ NDS32_BUILTIN_KMDA, --+ NDS32_BUILTIN_V_KMDA, --+ NDS32_BUILTIN_KMXDA, --+ NDS32_BUILTIN_V_KMXDA, --+ NDS32_BUILTIN_SMDS, --+ NDS32_BUILTIN_V_SMDS, --+ NDS32_BUILTIN_SMDRS, --+ NDS32_BUILTIN_V_SMDRS, --+ NDS32_BUILTIN_SMXDS, --+ NDS32_BUILTIN_V_SMXDS, --+ NDS32_BUILTIN_KMABB, --+ NDS32_BUILTIN_V_KMABB, --+ NDS32_BUILTIN_KMABT, --+ NDS32_BUILTIN_V_KMABT, --+ NDS32_BUILTIN_KMATT, --+ NDS32_BUILTIN_V_KMATT, --+ NDS32_BUILTIN_KMADA, --+ NDS32_BUILTIN_V_KMADA, --+ NDS32_BUILTIN_KMAXDA, --+ NDS32_BUILTIN_V_KMAXDA, --+ NDS32_BUILTIN_KMADS, --+ NDS32_BUILTIN_V_KMADS, --+ NDS32_BUILTIN_KMADRS, --+ NDS32_BUILTIN_V_KMADRS, --+ NDS32_BUILTIN_KMAXDS, --+ NDS32_BUILTIN_V_KMAXDS, --+ NDS32_BUILTIN_KMSDA, --+ NDS32_BUILTIN_V_KMSDA, --+ NDS32_BUILTIN_KMSXDA, --+ NDS32_BUILTIN_V_KMSXDA, --+ NDS32_BUILTIN_SMAL, --+ NDS32_BUILTIN_V_SMAL, --+ NDS32_BUILTIN_BITREV, --+ NDS32_BUILTIN_WEXT, --+ NDS32_BUILTIN_BPICK, --+ NDS32_BUILTIN_INSB, --+ NDS32_BUILTIN_SADD64, --+ NDS32_BUILTIN_UADD64, --+ NDS32_BUILTIN_RADD64, --+ NDS32_BUILTIN_URADD64, --+ NDS32_BUILTIN_KADD64, --+ NDS32_BUILTIN_UKADD64, --+ NDS32_BUILTIN_SSUB64, --+ NDS32_BUILTIN_USUB64, --+ NDS32_BUILTIN_RSUB64, --+ NDS32_BUILTIN_URSUB64, --+ NDS32_BUILTIN_KSUB64, --+ NDS32_BUILTIN_UKSUB64, --+ NDS32_BUILTIN_SMAR64, --+ NDS32_BUILTIN_SMSR64, --+ NDS32_BUILTIN_UMAR64, --+ NDS32_BUILTIN_UMSR64, --+ NDS32_BUILTIN_KMAR64, --+ NDS32_BUILTIN_KMSR64, --+ NDS32_BUILTIN_UKMAR64, --+ NDS32_BUILTIN_UKMSR64, --+ NDS32_BUILTIN_SMALBB, --+ NDS32_BUILTIN_V_SMALBB, --+ NDS32_BUILTIN_SMALBT, --+ NDS32_BUILTIN_V_SMALBT, --+ NDS32_BUILTIN_SMALTT, --+ NDS32_BUILTIN_V_SMALTT, --+ NDS32_BUILTIN_SMALDA, --+ NDS32_BUILTIN_V_SMALDA, --+ NDS32_BUILTIN_SMALXDA, --+ NDS32_BUILTIN_V_SMALXDA, --+ NDS32_BUILTIN_SMALDS, --+ NDS32_BUILTIN_V_SMALDS, --+ NDS32_BUILTIN_SMALDRS, --+ NDS32_BUILTIN_V_SMALDRS, --+ NDS32_BUILTIN_SMALXDS, --+ NDS32_BUILTIN_V_SMALXDS, --+ NDS32_BUILTIN_SMUL16, --+ NDS32_BUILTIN_V_SMUL16, --+ NDS32_BUILTIN_SMULX16, --+ NDS32_BUILTIN_V_SMULX16, --+ NDS32_BUILTIN_UMUL16, --+ NDS32_BUILTIN_V_UMUL16, --+ NDS32_BUILTIN_UMULX16, --+ NDS32_BUILTIN_V_UMULX16, --+ NDS32_BUILTIN_SMSLDA, --+ NDS32_BUILTIN_V_SMSLDA, --+ NDS32_BUILTIN_SMSLXDA, --+ NDS32_BUILTIN_V_SMSLXDA, --+ NDS32_BUILTIN_UCLIP32, --+ NDS32_BUILTIN_SCLIP32, --+ NDS32_BUILTIN_KABS, --+ NDS32_BUILTIN_UALOAD_U16, --+ NDS32_BUILTIN_UALOAD_S16, --+ NDS32_BUILTIN_UALOAD_U8, --+ NDS32_BUILTIN_UALOAD_S8, --+ NDS32_BUILTIN_UASTORE_U16, --+ NDS32_BUILTIN_UASTORE_S16, --+ NDS32_BUILTIN_UASTORE_U8, --+ NDS32_BUILTIN_UASTORE_S8, --+ NDS32_BUILTIN_DSP_END, --+ NDS32_BUILTIN_NO_HWLOOP, --+ NDS32_BUILTIN_UNALIGNED_FEATURE, --+ NDS32_BUILTIN_ENABLE_UNALIGNED, --+ NDS32_BUILTIN_DISABLE_UNALIGNED, --+ NDS32_BUILTIN_COUNT -- }; -- -- /* ------------------------------------------------------------------------ */ -- ---#define TARGET_ISA_V2 (nds32_arch_option == ARCH_V2) ---#define TARGET_ISA_V3 (nds32_arch_option == ARCH_V3) ---#define TARGET_ISA_V3M (nds32_arch_option == ARCH_V3M) --+#define TARGET_ISR_VECTOR_SIZE_4_BYTE \ --+ (nds32_isr_vector_size == 4) --+ --+#define TARGET_ISA_V2 \ --+ (nds32_arch_option == ARCH_V2 || nds32_arch_option == ARCH_V2J) --+#define TARGET_ISA_V3 \ --+ (nds32_arch_option == ARCH_V3 \ --+ || nds32_arch_option == ARCH_V3J \ --+ || nds32_arch_option == ARCH_V3F \ --+ || nds32_arch_option == ARCH_V3S) --+#define TARGET_ISA_V3M \ --+ (nds32_arch_option == ARCH_V3M || \ --+ nds32_arch_option == ARCH_V3M_PLUS) --+ --+#define TARGET_ISA_V3M_PLUS \ --+ (nds32_arch_option == ARCH_V3M_PLUS) --+ --+#define TARGET_PIPELINE_N7 \ --+ (nds32_cpu_option == CPU_N7) --+#define TARGET_PIPELINE_N8 \ --+ (nds32_cpu_option == CPU_N6 \ --+ || nds32_cpu_option == CPU_N8) --+#define TARGET_PIPELINE_N9 \ --+ (nds32_cpu_option == CPU_N9) --+#define TARGET_PIPELINE_N10 \ --+ (nds32_cpu_option == CPU_N10) --+#define TARGET_PIPELINE_N13 \ --+ (nds32_cpu_option == CPU_N12 || nds32_cpu_option == CPU_N13) --+#define TARGET_PIPELINE_GRAYWOLF \ --+ (nds32_cpu_option == CPU_GRAYWOLF) --+#define TARGET_PIPELINE_PANTHER \ --+ (nds32_cpu_option == CPU_PANTHER) --+#define TARGET_PIPELINE_SIMPLE \ --+ (nds32_cpu_option == CPU_SIMPLE) -- -- #define TARGET_CMODEL_SMALL \ -- (nds32_cmodel_option == CMODEL_SMALL) --@@ -361,55 +908,153 @@ enum nds32_builtins -- #define TARGET_CMODEL_LARGE \ -- (nds32_cmodel_option == CMODEL_LARGE) -- --+#define TARGET_ICT_MODEL_SMALL \ --+ (nds32_ict_model == ICT_MODEL_SMALL) --+ --+#define TARGET_ICT_MODEL_LARGE \ --+ (nds32_ict_model == ICT_MODEL_LARGE) --+ -- /* When -mcmodel=small or -mcmodel=medium, -- compiler may generate gp-base instruction directly. */ -- #define TARGET_GP_DIRECT \ -- (nds32_cmodel_option == CMODEL_SMALL\ -- || nds32_cmodel_option == CMODEL_MEDIUM) -- ---#define TARGET_SOFT_FLOAT 1 ---#define TARGET_HARD_FLOAT 0 --+/* There are three kinds of mul configurations: --+ 1-cycle fast mul, 2-cycle fast mul, and slow mul operation. */ --+#define TARGET_MUL_FAST_1 \ --+ (nds32_mul_config == MUL_TYPE_FAST_1) --+#define TARGET_MUL_FAST_2 \ --+ (nds32_mul_config == MUL_TYPE_FAST_2) --+#define TARGET_MUL_SLOW \ --+ (nds32_mul_config == MUL_TYPE_SLOW) --+ --+/* Run-time Target Specification. */ --+#define TARGET_SOFT_FLOAT (nds32_abi == NDS32_ABI_V2) --+/* Use hardware floating point calling convention. */ --+#define TARGET_HARD_FLOAT (nds32_abi == NDS32_ABI_V2_FP_PLUS) --+ --+/* Record arch version in TARGET_ARCH_DEFAULT. 0 means soft ABI, --+ 1 means hard ABI and using full floating-point instruction, --+ 2 means hard ABI and only using single-precision floating-point --+ instruction */ --+#if TARGET_ARCH_DEFAULT == 1 --+# define TARGET_DEFAULT_ABI NDS32_ABI_V2_FP_PLUS --+# define TARGET_DEFAULT_FPU_ISA MASK_FPU_DOUBLE | MASK_FPU_SINGLE --+# define TARGET_DEFAULT_FPU_FMA 0 --+#else --+# if TARGET_ARCH_DEFAULT == 2 --+# define TARGET_DEFAULT_ABI NDS32_ABI_V2_FP_PLUS --+# define TARGET_DEFAULT_FPU_ISA MASK_FPU_SINGLE --+# define TARGET_DEFAULT_FPU_FMA 0 --+# else --+# define TARGET_DEFAULT_ABI NDS32_ABI_V2 --+# define TARGET_DEFAULT_FPU_ISA 0 --+# define TARGET_DEFAULT_FPU_FMA 0 --+# endif --+#endif --+ --+#define TARGET_CONFIG_FPU_DEFAULT NDS32_CONFIG_FPU_2 --+ --+#define TARGET_LMWSMW_OPT_AUTO \ --+ (flag_lmwsmw_cost == LMWSMW_OPT_AUTO) --+ --+#define TARGET_LMWSMW_OPT_SIZE \ --+ (flag_lmwsmw_cost == LMWSMW_OPT_SIZE) --+ --+#define TARGET_LMWSMW_OPT_SPEED \ --+ (flag_lmwsmw_cost == LMWSMW_OPT_SPEED) --+ --+#define TARGET_LMWSMW_OPT_ALL \ --+ (flag_lmwsmw_cost == LMWSMW_OPT_ALL) --+ --+/* ------------------------------------------------------------------------ */ --+ --+#ifdef TARGET_DEFAULT_RELAX --+# define NDS32_RELAX_SPEC " %{!mno-relax:--relax}" --+#else --+# define NDS32_RELAX_SPEC " %{mrelax:--relax}" --+#endif --+ --+#ifdef TARGET_OS_DEFAULT_IFC --+# define NDS32_IFC_SPEC " %{Os3|Os|mifc:%{!mno-ifc:--mifc}}" --+#else --+# define NDS32_IFC_SPEC " %{mifc:--mifc}" --+#endif --+#define NDS32_IFC_V3M_PLUS_SPEC " %{march=v3m+:%{Os3|Os|mifc:%{!mno-ifc:-mifc}}}" --+ --+#ifdef TARGET_OS_DEFAULT_EX9 --+# define NDS32_EX9_SPEC " %{Os3|Os|mex9:%{!mno-ex9:--mex9}}" --+#else --+# define NDS32_EX9_SPEC " %{mex9:--mex9}" --+#endif --+#define NDS32_EX9_V3M_PLUS_SPEC " %{march=v3m+:%{Os3|Os|mex9:%{!mno-ex9:-mex9}}}" --+ --+#ifdef TARGET_DEFAULT_EXT_DSP --+# define NDS32_EXT_DSP_SPEC " %{!mno-ext-dsp:-mext-dsp}" --+#else --+# define NDS32_EXT_DSP_SPEC "" --+#endif --+ --+#ifdef TARGET_DEFAULT_HWLOOP --+# define NDS32_HWLOOP_SPEC " %{!mno-ext-zol:-mext-zol}" --+#else --+# define NDS32_HWLOOP_SPEC "" --+#endif --+ --+#ifdef TARGET_DEFAULT_16BIT --+# define NDS32_16BIT_SPEC " %{!mno-16-bit:%{!mno-16bit:-m16bit}}" --+#else --+# define NDS32_16BIT_SPEC " %{!m16-bit:%{!m16bit:-mno-16bit}}" --+#endif -- -- /* ------------------------------------------------------------------------ */ -- -- /* Controlling the Compilation Driver. */ -- --+#define DRIVER_SELF_SPECS \ --+ " %{mno-16bit|mno-16-bit:-mno-ifc -mno-ex9}" \ --+ NDS32_IFC_V3M_PLUS_SPEC \ --+ NDS32_EX9_V3M_PLUS_SPEC \ --+ NDS32_16BIT_SPEC --+ -- #define OPTION_DEFAULT_SPECS \ --- {"arch", "%{!march=*:-march=%(VALUE)}" } --+ {"arch", " %{!march=*:-march=%(VALUE)}" \ --+ " %{march=v3f:%{!mfloat-abi=*:-mfloat-abi=hard}" \ --+ " %{!mno-ext-fpu-sp:%{!mext-fpu-sp:-mext-fpu-sp}}" \ --+ " %{!mno-ext-fpu-dp:%{!mext-fpu-dp:-mext-fpu-dp}}}" \ --+ " %{march=v3s:%{!mfloat-abi=*:-mfloat-abi=hard}" \ --+ " %{!mno-ext-fpu-sp:%{!mext-fpu-sp:-mext-fpu-sp}}}" }, \ --+ {"cpu", "%{!mcpu=*:-mcpu=%(VALUE)}" }, \ --+ {"memory_model", "%{!mmemory-model=*:-mmemory-model=%(VALUE)}"}, \ --+ {"float", "%{!mfloat-abi=*:-mfloat-abi=%(VALUE)}" } -- -- #define CC1_SPEC \ --- "" --+ " %{Os1:-Os -mno-ifc -mno-ex9;" \ --+ "Os2:-Os -minnermost-loop;" \ --+ "Os3:-Os}" \ --+ " %{ffast-math:%{!mno-soft-fp-arith-comm:-msoft-fp-arith-comm}}" \ --+ NDS32_EXT_DSP_SPEC \ --+ NDS32_HWLOOP_SPEC -- -- #define ASM_SPEC \ --- " %{mbig-endian:-EB} %{mlittle-endian:-EL}" --- ---/* If user issues -mrelax, we need to pass '--relax' to linker. */ ---#define LINK_SPEC \ -- " %{mbig-endian:-EB} %{mlittle-endian:-EL}" \ --- " %{mrelax:--relax}" --- ---#define LIB_SPEC \ --- " -lc -lgloss" --- ---/* The option -mno-ctor-dtor can disable constructor/destructor feature --- by applying different crt stuff. In the convention, crt0.o is the --- startup file without constructor/destructor; --- crt1.o, crti.o, crtbegin.o, crtend.o, and crtn.o are the --- startup files with constructor/destructor. --- Note that crt0.o, crt1.o, crti.o, and crtn.o are provided --- by newlib/mculib/glibc/ublic, while crtbegin.o and crtend.o are --- currently provided by GCC for nds32 target. --- --- For nds32 target so far: --- If -mno-ctor-dtor, we are going to link --- "crt0.o [user objects]". --- If general cases, we are going to link --- "crt1.o crtbegin1.o [user objects] crtend1.o". */ ---#define STARTFILE_SPEC \ --- " %{!mno-ctor-dtor:crt1.o%s;:crt0.o%s}" \ --- " %{!mno-ctor-dtor:crtbegin1.o%s}" ---#define ENDFILE_SPEC \ --- " %{!mno-ctor-dtor:crtend1.o%s}" --+ " %{march=*:-march=%*}" \ --+ " %{mno-16-bit|mno-16bit:-mno-16bit-ext}" \ --+ " %{march=v3m:%{!mfull-regs:%{!mreduced-regs:-mreduced-regs}}}" \ --+ " %{mfull-regs:-mno-reduced-regs}" \ --+ " %{mreduced-regs:-mreduced-regs}" \ --+ " %{mabi=*:-mabi=v%*}" \ --+ " %{mconfig-fpu=*:-mfpu-freg=%*}" \ --+ " %{mext-fpu-mac:-mmac}" \ --+ " %{mno-ext-fpu-mac:-mno-mac}" \ --+ " %{mext-fpu-sp:-mfpu-sp-ext}" \ --+ " %{mno-ext-fpu-sp:-mno-fpu-sp-ext}" \ --+ " %{mext-fpu-dp:-mfpu-dp-ext}" \ --+ " %{mno-ext-fpu-sp:-mno-fpu-dp-ext}" \ --+ " %{mext-dsp:-mdsp-ext}" \ --+ " %{mext-zol:-mzol-ext}" \ --+ " %{O|O1|O2|O3|Ofast:-O1;:-Os}" -- -- /* The TARGET_BIG_ENDIAN_DEFAULT is defined if we -- configure gcc with --target=nds32be-* setting. --@@ -422,7 +1067,11 @@ enum nds32_builtins -- -- /* Currently we only have elf toolchain, -- where -mcmodel=medium is always the default. */ ---#define NDS32_CMODEL_DEFAULT "mcmodel=medium" --+#if TARGET_ELF --+# define NDS32_CMODEL_DEFAULT "mcmodel=medium" --+#else --+# define NDS32_CMODEL_DEFAULT "mcmodel=medium" --+#endif -- -- #define MULTILIB_DEFAULTS \ -- { NDS32_ENDIAN_DEFAULT, NDS32_CMODEL_DEFAULT } --@@ -430,34 +1079,8 @@ enum nds32_builtins -- -- /* Run-time Target Specification. */ -- ---#define TARGET_CPU_CPP_BUILTINS() \ --- do \ --- { \ --- builtin_define ("__nds32__"); \ --- \ --- if (TARGET_ISA_V2) \ --- builtin_define ("__NDS32_ISA_V2__"); \ --- if (TARGET_ISA_V3) \ --- builtin_define ("__NDS32_ISA_V3__"); \ --- if (TARGET_ISA_V3M) \ --- builtin_define ("__NDS32_ISA_V3M__"); \ --- \ --- if (TARGET_BIG_ENDIAN) \ --- builtin_define ("__big_endian__"); \ --- if (TARGET_REDUCED_REGS) \ --- builtin_define ("__NDS32_REDUCED_REGS__"); \ --- if (TARGET_CMOV) \ --- builtin_define ("__NDS32_CMOV__"); \ --- if (TARGET_PERF_EXT) \ --- builtin_define ("__NDS32_PERF_EXT__"); \ --- if (TARGET_16_BIT) \ --- builtin_define ("__NDS32_16_BIT__"); \ --- if (TARGET_GP_DIRECT) \ --- builtin_define ("__NDS32_GP_DIRECT__"); \ --- \ --- builtin_assert ("cpu=nds32"); \ --- builtin_assert ("machine=nds32"); \ --- } while (0) --+#define TARGET_CPU_CPP_BUILTINS() \ --+ nds32_cpu_cpp_builtins (pfile) -- -- -- /* Defining Data Structures for Per-function Information. */ --@@ -487,10 +1110,20 @@ enum nds32_builtins -- -- #define STACK_BOUNDARY 64 -- ---#define FUNCTION_BOUNDARY 32 --+#define FUNCTION_BOUNDARY \ --+ ((NDS32_ALIGN_P () || TARGET_ALIGN_FUNCTION) ? (TARGET_PIPELINE_PANTHER ? 64 : 32) : 16) -- -- #define BIGGEST_ALIGNMENT 64 -- --+#define DATA_ALIGNMENT(constant, basic_align) \ --+ nds32_data_alignment (constant, basic_align) --+ --+#define CONSTANT_ALIGNMENT(constant, basic_align) \ --+ nds32_constant_alignment (constant, basic_align) --+ --+#define LOCAL_ALIGNMENT(type, basic_align) \ --+ nds32_local_alignment (type, basic_align) --+ -- #define EMPTY_FIELD_BOUNDARY 32 -- -- #define STRUCTURE_SIZE_BOUNDARY 8 --@@ -515,8 +1148,8 @@ enum nds32_builtins -- -- #define SIZE_TYPE "long unsigned int" -- #define PTRDIFF_TYPE "long int" ---#define WCHAR_TYPE "short unsigned int" ---#define WCHAR_TYPE_SIZE 16 --+#define WCHAR_TYPE "unsigned int" --+#define WCHAR_TYPE_SIZE 32 -- -- -- /* Register Usage. */ --@@ -526,7 +1159,7 @@ enum nds32_builtins -- from 0 to just below FIRST_PSEUDO_REGISTER. -- All registers that the compiler knows about must be given numbers, -- even those that are not normally considered general registers. */ ---#define FIRST_PSEUDO_REGISTER 34 --+#define FIRST_PSEUDO_REGISTER 101 -- -- /* An initializer that says which registers are used for fixed -- purposes all throughout the compiled code and are therefore --@@ -537,24 +1170,38 @@ enum nds32_builtins -- $r30 : $lp -- $r31 : $sp -- --- caller-save registers: $r0 ~ $r5, $r16 ~ $r23 --- callee-save registers: $r6 ~ $r10, $r11 ~ $r14 --+ caller-save registers: $r0 ~ $r5, $r16 ~ $r23, $fs0 ~ $fs5, $fs22 ~ $fs47 --+ callee-save registers: $r6 ~ $r10, $r11 ~ $r14, $fs6 ~ $fs21, $fs48 ~ $fs63 -- -- reserved for assembler : $r15 -- reserved for other use : $r24, $r25, $r26, $r27 */ ---#define FIXED_REGISTERS \ ---{ /* r0 r1 r2 r3 r4 r5 r6 r7 */ \ --- 0, 0, 0, 0, 0, 0, 0, 0, \ --- /* r8 r9 r10 r11 r12 r13 r14 r15 */ \ --- 0, 0, 0, 0, 0, 0, 0, 1, \ --- /* r16 r17 r18 r19 r20 r21 r22 r23 */ \ --- 0, 0, 0, 0, 0, 0, 0, 0, \ --- /* r24 r25 r26 r27 r28 r29 r30 r31 */ \ --- 1, 1, 1, 1, 0, 1, 0, 1, \ --- /* ARG_POINTER:32 */ \ --- 1, \ --- /* FRAME_POINTER:33 */ \ --- 1 \ --+#define FIXED_REGISTERS \ --+{ /* r0 r1 r2 r3 r4 r5 r6 r7 */ \ --+ 0, 0, 0, 0, 0, 0, 0, 0, \ --+ /* r8 r9 r10 r11 r12 r13 r14 r15 */ \ --+ 0, 0, 0, 0, 0, 0, 0, 0, \ --+ /* r16 r17 r18 r19 r20 r21 r22 r23 */ \ --+ 0, 0, 0, 0, 0, 0, 0, 0, \ --+ /* r24 r25 r26 r27 r28 r29 r30 r31 */ \ --+ 0, 0, 1, 1, 0, 1, 0, 1, \ --+ /* AP FP fs0 fs1 fs2 fs3 fs4 fs5 */ \ --+ 1, 1, 1, 1, 1, 1, 1, 1, \ --+ /* fs6 fs7 fs8 fs9 fs10 fs11 fs12 fs13 */ \ --+ 1, 1, 1, 1, 1, 1, 1, 1, \ --+ /* fs14 fs15 fs16 fs17 fs18 fs19 fs20 fs21 */ \ --+ 1, 1, 1, 1, 1, 1, 1, 1, \ --+ /* fs22 fs23 fs24 fs25 fs26 fs27 fs28 fs29 */ \ --+ 1, 1, 1, 1, 1, 1, 1, 1, \ --+ /* fs30 fs31 fd16 fd17 fd18 */ \ --+ 1, 1, 1, 1, 1, 1, 1, 1, \ --+ /* fd19 fd20 fd21 fd22 */ \ --+ 1, 1, 1, 1, 1, 1, 1, 1, \ --+ /* fd23 fd24 fd25 fd26 */ \ --+ 1, 1, 1, 1, 1, 1, 1, 1, \ --+ /* fd27 fd28 fd29 fd30 */ \ --+ 1, 1, 1, 1, 1, 1, 1, 1, \ --+ /* fd31 LB LE LC */ \ --+ 1, 1, 1, 1, 1 \ -- } -- -- /* Identifies the registers that are not available for --@@ -563,35 +1210,59 @@ enum nds32_builtins -- -- 0 : callee-save registers -- 1 : caller-save registers */ ---#define CALL_USED_REGISTERS \ ---{ /* r0 r1 r2 r3 r4 r5 r6 r7 */ \ --- 1, 1, 1, 1, 1, 1, 0, 0, \ --- /* r8 r9 r10 r11 r12 r13 r14 r15 */ \ --- 0, 0, 0, 0, 0, 0, 0, 1, \ --- /* r16 r17 r18 r19 r20 r21 r22 r23 */ \ --- 1, 1, 1, 1, 1, 1, 1, 1, \ --- /* r24 r25 r26 r27 r28 r29 r30 r31 */ \ --- 1, 1, 1, 1, 0, 1, 0, 1, \ --- /* ARG_POINTER:32 */ \ --- 1, \ --- /* FRAME_POINTER:33 */ \ --- 1 \ --+#define CALL_USED_REGISTERS \ --+{ /* r0 r1 r2 r3 r4 r5 r6 r7 */ \ --+ 1, 1, 1, 1, 1, 1, 0, 0, \ --+ /* r8 r9 r10 r11 r12 r13 r14 r15 */ \ --+ 0, 0, 0, 0, 0, 0, 0, 1, \ --+ /* r16 r17 r18 r19 r20 r21 r22 r23 */ \ --+ 1, 1, 1, 1, 1, 1, 1, 1, \ --+ /* r24 r25 r26 r27 r28 r29 r30 r31 */ \ --+ 1, 1, 1, 1, 0, 1, 0, 1, \ --+ /* AP FP fs0 fs1 fs2 fs3 fs4 fs5 */ \ --+ 1, 1, 1, 1, 1, 1, 1, 1, \ --+ /* fs6 fs7 fs8 fs9 fs10 fs11 fs12 fs13 */ \ --+ 1, 1, 1, 1, 1, 1, 1, 1, \ --+ /* fs14 fs15 fs16 fs17 fs18 fs19 fs20 fs21 */ \ --+ 1, 1, 1, 1, 1, 1, 1, 1, \ --+ /* fs22 fs23 fs24 fs25 fs26 fs27 fs28 fs29 */ \ --+ 1, 1, 1, 1, 1, 1, 1, 1, \ --+ /* fs30 fs31 fd16 fd17 fd18 */ \ --+ 1, 1, 1, 1, 1, 1, 1, 1, \ --+ /* fd19 fd20 fd21 fd22 */ \ --+ 1, 1, 1, 1, 1, 1, 1, 1, \ --+ /* fd23 fd24 fd25 fd26 */ \ --+ 1, 1, 1, 1, 1, 1, 1, 1, \ --+ /* fd27 fd28 fd29 fd30 */ \ --+ 1, 1, 1, 1, 1, 1, 1, 1, \ --+ /* fd31 LB LE LC */ \ --+ 1, 1, 1, 1, 1 \ -- } -- -- /* In nds32 target, we have three levels of registers: -- LOW_COST_REGS : $r0 ~ $r7 -- MIDDLE_COST_REGS : $r8 ~ $r11, $r16 ~ $r19 -- HIGH_COST_REGS : $r12 ~ $r14, $r20 ~ $r31 */ ---#define REG_ALLOC_ORDER \ ---{ \ --- 0, 1, 2, 3, 4, 5, 6, 7, \ --- 8, 9, 10, 11, 16, 17, 18, 19, \ --- 12, 13, 14, 15, 20, 21, 22, 23, \ --- 24, 25, 26, 27, 28, 29, 30, 31, \ --- 32, \ --- 33 \ --+#define REG_ALLOC_ORDER \ --+{ 0, 1, 2, 3, 4, 5, 6, 7, \ --+ 16, 17, 18, 19, 9, 10, 11, 12, \ --+ 13, 14, 8, 15, 20, 21, 22, 23, \ --+ 24, 25, 26, 27, 28, 29, 30, 31, \ --+ 32, 33, 34, 35, 36, 37, 38, 39, \ --+ 40, 41, 42, 43, 44, 45, 46, 47, \ --+ 48, 49, 50, 51, 52, 53, 54, 55, \ --+ 56, 57, 58, 59, 60, 61, 62, 63, \ --+ 64, 65, 66, 67, 68, 69, 70, 71, \ --+ 72, 73, 74, 75, 76, 77, 78, 79, \ --+ 80, 81, 82, 83, 84, 85, 86, 87, \ --+ 88, 89, 90, 91, 92, 93, 94, 95, \ --+ 96, 97, 98, 99, 100, \ -- } -- --+/* ADJUST_REG_ALLOC_ORDER is a macro which permits reg_alloc_order --+ to be rearranged based on optimizing for speed or size. */ --+#define ADJUST_REG_ALLOC_ORDER nds32_adjust_reg_alloc_order () --+ -- /* Tell IRA to use the order we define rather than messing it up with its -- own cost calculations. */ -- #define HONOR_REG_ALLOC_ORDER optimize_size --@@ -609,11 +1280,7 @@ enum nds32_builtins -- Define this macro to return nonzero in as many cases as possible -- since doing so will allow GCC to perform better register allocation. -- We can use general registers to tie QI/HI/SI modes together. */ ---#define MODES_TIEABLE_P(mode1, mode2) \ --- (GET_MODE_CLASS (mode1) == MODE_INT \ --- && GET_MODE_CLASS (mode2) == MODE_INT \ --- && GET_MODE_SIZE (mode1) <= UNITS_PER_WORD \ --- && GET_MODE_SIZE (mode2) <= UNITS_PER_WORD) --+#define MODES_TIEABLE_P(mode1, mode2) nds32_modes_tieable_p (mode1, mode2) -- -- -- /* Register Classes. */ --@@ -628,13 +1295,18 @@ enum nds32_builtins -- enum reg_class -- { -- NO_REGS, --+ R5_REG, --+ R8_REG, -- R15_TA_REG, -- STACK_REG, --+ FRAME_POINTER_REG, -- LOW_REGS, -- MIDDLE_REGS, -- HIGH_REGS, -- GENERAL_REGS, -- FRAME_REGS, --+ FP_REGS, --+ LOOP_REGS, -- ALL_REGS, -- LIM_REG_CLASSES -- }; --@@ -644,27 +1316,50 @@ enum reg_class -- #define REG_CLASS_NAMES \ -- { \ -- "NO_REGS", \ --+ "R5_REG", \ --+ "R8_REG", \ -- "R15_TA_REG", \ -- "STACK_REG", \ --+ "FRAME_POINTER_REG", \ -- "LOW_REGS", \ -- "MIDDLE_REGS", \ -- "HIGH_REGS", \ -- "GENERAL_REGS", \ -- "FRAME_REGS", \ --+ "FP_REGS", \ --+ "LOOP_REGS", \ -- "ALL_REGS" \ -- } -- -- #define REG_CLASS_CONTENTS \ ---{ \ --- {0x00000000, 0x00000000}, /* NO_REGS : */ \ --- {0x00008000, 0x00000000}, /* R15_TA_REG : 15 */ \ --- {0x80000000, 0x00000000}, /* STACK_REG : 31 */ \ --- {0x000000ff, 0x00000000}, /* LOW_REGS : 0-7 */ \ --- {0x000f0fff, 0x00000000}, /* MIDDLE_REGS : 0-11, 16-19 */ \ --- {0xfff07000, 0x00000000}, /* HIGH_REGS : 12-14, 20-31 */ \ --- {0xffffffff, 0x00000000}, /* GENERAL_REGS: 0-31 */ \ --- {0x00000000, 0x00000003}, /* FRAME_REGS : 32, 33 */ \ --- {0xffffffff, 0x00000003} /* ALL_REGS : 0-31, 32, 33 */ \ --+{ /* NO_REGS */ \ --+ {0x00000000, 0x00000000, 0x00000000, 0x00000000}, \ --+ /* R5_REG : 5 */ \ --+ {0x00000020, 0x00000000, 0x00000000, 0x00000000}, \ --+ /* R8_REG : 8 */ \ --+ {0x00000100, 0x00000000, 0x00000000, 0x00000000}, \ --+ /* R15_TA_REG : 15 */ \ --+ {0x00008000, 0x00000000, 0x00000000, 0x00000000}, \ --+ /* STACK_REG : 31 */ \ --+ {0x80000000, 0x00000000, 0x00000000, 0x00000000}, \ --+ /* FRAME_POINTER_REG : 28 */ \ --+ {0x10000000, 0x00000000, 0x00000000, 0x00000000}, \ --+ /* LOW_REGS : 0-7 */ \ --+ {0x000000ff, 0x00000000, 0x00000000, 0x00000000}, \ --+ /* MIDDLE_REGS : 0-11, 16-19 */ \ --+ {0x000f0fff, 0x00000000, 0x00000000, 0x00000000}, \ --+ /* HIGH_REGS : 12-14, 20-31 */ \ --+ {0xfff07000, 0x00000000, 0x00000000, 0x00000000}, \ --+ /* GENERAL_REGS : 0-31 */ \ --+ {0xffffffff, 0x00000000, 0x00000000, 0x00000000}, \ --+ /* FRAME_REGS : 32, 33 */ \ --+ {0x00000000, 0x00000003, 0x00000000, 0x00000000}, \ --+ /* FP_REGS : 34-98 */ \ --+ {0x00000000, 0xfffffffc, 0xffffffff, 0x00000003}, \ --+ /* LOOP_REGS 99-101 */ \ --+ {0x00000000, 0x00000000, 0x00000000, 0x0000001c}, \ --+ /* ALL_REGS : 0-101 */ \ --+ {0xffffffff, 0xffffffff, 0xffffffff, 0x0000001f} \ -- } -- -- #define REGNO_REG_CLASS(regno) nds32_regno_reg_class (regno) --@@ -672,13 +1367,18 @@ enum reg_class -- #define BASE_REG_CLASS GENERAL_REGS -- #define INDEX_REG_CLASS GENERAL_REGS -- --+#define TEST_REGNO(R, TEST, VALUE) \ --+ ((R TEST VALUE) || ((unsigned) reg_renumber[R] TEST VALUE)) --+ -- /* Return nonzero if it is suitable for use as a -- base register in operand addresses. -- So far, we return nonzero only if "num" is a hard reg -- of the suitable class or a pseudo register which is -- allocated to a suitable hard reg. */ -- #define REGNO_OK_FOR_BASE_P(num) \ --- ((num) < 32 || (unsigned) reg_renumber[num] < 32) --+ (TEST_REGNO (num, <, 32) \ --+ || TEST_REGNO (num, ==, FRAME_POINTER_REGNUM) \ --+ || TEST_REGNO (num, ==, ARG_POINTER_REGNUM)) -- -- /* Return nonzero if it is suitable for use as a -- index register in operand addresses. --@@ -688,7 +1388,15 @@ enum reg_class -- The difference between an index register and a base register is that -- the index register may be scaled. */ -- #define REGNO_OK_FOR_INDEX_P(num) \ --- ((num) < 32 || (unsigned) reg_renumber[num] < 32) --+ (TEST_REGNO (num, <, 32) \ --+ || TEST_REGNO (num, ==, FRAME_POINTER_REGNUM) \ --+ || TEST_REGNO (num, ==, ARG_POINTER_REGNUM)) --+ --+/* Don't spill double-precision register to two singal-precision registers */ --+#define CANNOT_CHANGE_MODE_CLASS(FROM, TO, CLASS) \ --+ ((TARGET_FPU_SINGLE || TARGET_FPU_DOUBLE) \ --+ && GET_MODE_SIZE (FROM) != GET_MODE_SIZE (TO) \ --+ ? reg_classes_intersect_p (CLASS, FP_REGS) : 0) -- -- -- /* Obsolete Macros for Defining Constraints. */ --@@ -707,6 +1415,11 @@ enum reg_class -- #define FIRST_PARM_OFFSET(fundecl) \ -- (NDS32_DOUBLE_WORD_ALIGN_P (crtl->args.pretend_args_size) ? 0 : 4) -- --+/* A C expression whose value is RTL representing the address in a stack frame --+ where the pointer to the caller's frame is stored. */ --+#define DYNAMIC_CHAIN_ADDRESS(frameaddr) \ --+ nds32_dynamic_chain_address (frameaddr) --+ -- #define RETURN_ADDR_RTX(count, frameaddr) \ -- nds32_return_addr_rtx (count, frameaddr) -- --@@ -718,6 +1431,15 @@ enum reg_class -- #define INCOMING_RETURN_ADDR_RTX gen_rtx_REG (Pmode, LP_REGNUM) -- #define DWARF_FRAME_RETURN_COLUMN DWARF_FRAME_REGNUM (LP_REGNUM) -- --+/* Use $r0 $r1 to pass exception handling information. */ --+#define EH_RETURN_DATA_REGNO(N) (((N) < 2) ? (N) : INVALID_REGNUM) --+/* The register $r2 that represents a location in which to store a stack --+ adjustment to be applied before function return. --+ This is used to unwind the stack to an exception handler's call frame. */ --+#define EH_RETURN_STACKADJ_RTX gen_rtx_REG (Pmode, 2) --+ --+#define DBX_REGISTER_NUMBER(REGNO) nds32_dbx_register_number (REGNO) --+ -- #define STACK_POINTER_REGNUM SP_REGNUM -- -- #define FRAME_POINTER_REGNUM 33 --@@ -746,12 +1468,11 @@ enum reg_class -- #define INIT_CUMULATIVE_ARGS(cum, fntype, libname, fndecl, n_named_args) \ -- nds32_init_cumulative_args (&cum, fntype, libname, fndecl, n_named_args) -- ---/* The REGNO is an unsigned integer but NDS32_GPR_ARG_FIRST_REGNUM may be 0. --- We better cast REGNO into signed integer so that we can avoid --- 'comparison of unsigned expression >= 0 is always true' warning. */ ---#define FUNCTION_ARG_REGNO_P(regno) \ --- (((int) regno - NDS32_GPR_ARG_FIRST_REGNUM >= 0) \ --- && ((int) regno - NDS32_GPR_ARG_FIRST_REGNUM < NDS32_MAX_GPR_REGS_FOR_ARGS)) --+#define FUNCTION_ARG_REGNO_P(regno) \ --+ (IN_RANGE ((regno), NDS32_FIRST_GPR_REGNUM, NDS32_MAX_GPR_REGS_FOR_ARGS - 1) \ --+ || ((TARGET_FPU_SINGLE || TARGET_FPU_DOUBLE) \ --+ && IN_RANGE ((regno), NDS32_FPR_ARG_FIRST_REGNUM, \ --+ NDS32_FIRST_FPR_REGNUM + NDS32_MAX_FPR_REGS_FOR_ARGS - 1))) -- -- #define DEFAULT_PCC_STRUCT_RETURN 0 -- --@@ -763,7 +1484,15 @@ enum reg_class -- #define EXIT_IGNORE_STACK 1 -- -- #define FUNCTION_PROFILER(file, labelno) \ --- fprintf (file, "/* profiler %d */", (labelno)) --+ fprintf (file, "/* profiler %d */\n", (labelno)) --+ --+#define PROFILE_HOOK(LABEL) \ --+ { \ --+ rtx fun, lp; \ --+ lp = get_hard_reg_initial_val (Pmode, LP_REGNUM); \ --+ fun = gen_rtx_SYMBOL_REF (Pmode, "_mcount"); \ --+ emit_library_call (fun, LCT_NORMAL, VOIDmode, 1, lp, Pmode); \ --+ } -- -- -- /* Implementing the Varargs Macros. */ --@@ -780,13 +1509,13 @@ enum reg_class -- The trampoline code for nds32 target must contains following parts: -- -- 1. instructions (4 * 4 = 16 bytes): --- get $pc first --- load chain_value to static chain register via $pc --- load nested function address to $r15 via $pc --- jump to desired nested function via $r15 --+ get $pc first --+ load chain_value to static chain register via $pc --+ load nested function address to $r15 via $pc --+ jump to desired nested function via $r15 -- 2. data (4 * 2 = 8 bytes): --- chain_value --- nested function address --+ chain_value --+ nested function address -- -- Please check nds32.c implementation for more information. */ -- #define TRAMPOLINE_SIZE 24 --@@ -811,9 +1540,22 @@ enum reg_class -- /* We have "LW.bi Rt, [Ra], Rb" instruction form. */ -- #define HAVE_POST_MODIFY_REG 1 -- ---#define CONSTANT_ADDRESS_P(x) (CONSTANT_P (x) && GET_CODE (x) != CONST_DOUBLE) --+#define USE_LOAD_POST_INCREMENT(mode) \ --+ (GET_MODE_SIZE (mode) <= GET_MODE_SIZE(DImode)) --+#define USE_LOAD_POST_DECREMENT(mode) \ --+ (GET_MODE_SIZE (mode) <= GET_MODE_SIZE(DImode)) --+#define USE_STORE_POST_DECREMENT(mode) USE_LOAD_POST_DECREMENT(mode) --+#define USE_STORE_POST_INCREMENT(mode) USE_LOAD_POST_INCREMENT(mode) --+ --+#define CONSTANT_ADDRESS_P(x) \ --+ (CONSTANT_P (x) && memory_address_p (GET_MODE (x), x)) -- ---#define MAX_REGS_PER_ADDRESS 2 --+/* CONST_DOUBLE is legal without TARGET_FPU in legitimate_constant_p. --+ Therefore, let it be a legal PIC operand and split it later.*/ --+#define LEGITIMATE_PIC_OPERAND_P(x) \ --+ (GET_CODE (x) != CONST_DOUBLE || !(TARGET_FPU_SINGLE || TARGET_FPU_DOUBLE)) --+ --+#define MAX_REGS_PER_ADDRESS 3 -- -- -- /* Anchored Addresses. */ --@@ -827,7 +1569,11 @@ enum reg_class -- /* A C expression for the cost of a branch instruction. -- A value of 1 is the default; -- other values are interpreted relative to that. */ ---#define BRANCH_COST(speed_p, predictable_p) ((speed_p) ? 2 : 0) --+#define BRANCH_COST(speed_p, predictable_p) ((speed_p) ? 2 : 1) --+ --+/* Override BRANCH_COST heuristic which empirically produces worse --+ performance for removing short circuiting from the logical ops. */ --+#define LOGICAL_OP_NON_SHORT_CIRCUIT 0 -- -- #define SLOW_BYTE_ACCESS 1 -- --@@ -857,12 +1603,17 @@ enum reg_class -- -- #define PIC_OFFSET_TABLE_REGNUM GP_REGNUM -- --+#define SYMBOLIC_CONST_P(X) \ --+(GET_CODE (X) == SYMBOL_REF \ --+ || GET_CODE (X) == LABEL_REF \ --+ || (GET_CODE (X) == CONST && symbolic_reference_mentioned_p (X))) --+ -- -- /* Defining the Output Assembler Language. */ -- -- #define ASM_COMMENT_START "!" -- ---#define ASM_APP_ON "! #APP" --+#define ASM_APP_ON "! #APP\n" -- -- #define ASM_APP_OFF "! #NO_APP\n" -- --@@ -877,14 +1628,77 @@ enum reg_class -- -- #define LOCAL_LABEL_PREFIX "." -- ---#define REGISTER_NAMES \ ---{ \ --- "$r0", "$r1", "$r2", "$r3", "$r4", "$r5", "$r6", "$r7", \ --+#define REGISTER_NAMES \ --+{ "$r0", "$r1", "$r2", "$r3", "$r4", "$r5", "$r6", "$r7", \ -- "$r8", "$r9", "$r10", "$r11", "$r12", "$r13", "$r14", "$ta", \ -- "$r16", "$r17", "$r18", "$r19", "$r20", "$r21", "$r22", "$r23", \ -- "$r24", "$r25", "$r26", "$r27", "$fp", "$gp", "$lp", "$sp", \ --- "$AP", \ --- "$SFP" \ --+ "$AP", "$SFP", "$fs0", "$fs1", "$fs2", "$fs3", "$fs4", "$fs5", \ --+ "$fs6", "$fs7", "$fs8", "$fs9", "$fs10","$fs11","$fs12","$fs13",\ --+ "$fs14","$fs15","$fs16","$fs17","$fs18","$fs19","$fs20","$fs21",\ --+ "$fs22","$fs23","$fs24","$fs25","$fs26","$fs27","$fs28","$fs29",\ --+ "$fs30","$fs31","$fs32","$fs33","$fs34","$fs35","$fs36","$fs37",\ --+ "$fs38","$fs39","$fs40","$fs41","$fs42","$fs43","$fs44","$fs45",\ --+ "$fs46","$fs47","$fs48","$fs49","$fs50","$fs51","$fs52","$fs53",\ --+ "$fs54","$fs55","$fs56","$fs57","$fs58","$fs59","$fs60","$fs61",\ --+ "$fs62","$fs63", "LB", "LE", "LC" \ --+} --+ --+#define ADDITIONAL_REGISTER_NAMES \ --+{ \ --+ {"$r15", 15}, \ --+ {"$r28", 28}, {"$r29", 29}, {"$r30", 30}, {"$r31", 31}, \ --+ {"$a0", 0}, {"$a1", 1}, {"$a2", 2}, \ --+ {"$a3", 3}, {"$a4", 4}, {"$a5", 5}, \ --+ {"$s0", 6}, {"$s1", 7}, {"$s2", 8}, {"$s3", 9}, \ --+ {"$s4", 10}, {"$s5", 11}, {"$s6", 12}, {"$s7", 13}, \ --+ {"$s8", 14}, \ --+ {"$t0", 16}, {"$t1", 17}, {"$t2", 18}, {"$t3", 19}, \ --+ {"$t4", 20}, {"$t5", 21}, {"$t6", 22}, {"$t7", 23}, \ --+ {"$t8", 24}, {"$t9", 25}, \ --+ {"$p0", 26}, {"$p1", 27}, \ --+ {"$h0", 0}, {"$h1", 1}, {"$h2", 2}, {"$h3", 3}, \ --+ {"$h4", 4}, {"$h5", 5}, {"$h6", 6}, {"$h7", 7}, \ --+ {"$h8", 8}, {"$h9", 9}, {"$h10", 10}, {"$h11", 11}, \ --+ {"$h12", 16}, {"$h13", 17}, {"$h14", 18}, {"$h15", 19}, \ --+ {"$o0", 0}, {"$o1", 1}, {"$o2", 2}, {"$o3", 3}, \ --+ {"$o4", 4}, {"$o5", 5}, {"$o6", 6}, {"$o7", 7}, \ --+} --+ --+#define OVERLAPPING_REGISTER_NAMES \ --+{ \ --+ {"$fd0", NDS32_FIRST_FPR_REGNUM + 0, 2}, \ --+ {"$fd1", NDS32_FIRST_FPR_REGNUM + 2, 2}, \ --+ {"$fd2", NDS32_FIRST_FPR_REGNUM + 4, 2}, \ --+ {"$fd3", NDS32_FIRST_FPR_REGNUM + 6, 2}, \ --+ {"$fd4", NDS32_FIRST_FPR_REGNUM + 8, 2}, \ --+ {"$fd5", NDS32_FIRST_FPR_REGNUM + 10, 2}, \ --+ {"$fd6", NDS32_FIRST_FPR_REGNUM + 12, 2}, \ --+ {"$fd7", NDS32_FIRST_FPR_REGNUM + 14, 2}, \ --+ {"$fd8", NDS32_FIRST_FPR_REGNUM + 16, 2}, \ --+ {"$fd9", NDS32_FIRST_FPR_REGNUM + 18, 2}, \ --+ {"$fd10", NDS32_FIRST_FPR_REGNUM + 20, 2}, \ --+ {"$fd11", NDS32_FIRST_FPR_REGNUM + 22, 2}, \ --+ {"$fd12", NDS32_FIRST_FPR_REGNUM + 24, 2}, \ --+ {"$fd13", NDS32_FIRST_FPR_REGNUM + 26, 2}, \ --+ {"$fd14", NDS32_FIRST_FPR_REGNUM + 28, 2}, \ --+ {"$fd15", NDS32_FIRST_FPR_REGNUM + 30, 2}, \ --+ {"$fd16", NDS32_FIRST_FPR_REGNUM + 32, 2}, \ --+ {"$fd17", NDS32_FIRST_FPR_REGNUM + 34, 2}, \ --+ {"$fd18", NDS32_FIRST_FPR_REGNUM + 36, 2}, \ --+ {"$fd19", NDS32_FIRST_FPR_REGNUM + 38, 2}, \ --+ {"$fd20", NDS32_FIRST_FPR_REGNUM + 40, 2}, \ --+ {"$fd21", NDS32_FIRST_FPR_REGNUM + 42, 2}, \ --+ {"$fd22", NDS32_FIRST_FPR_REGNUM + 44, 2}, \ --+ {"$fd23", NDS32_FIRST_FPR_REGNUM + 46, 2}, \ --+ {"$fd24", NDS32_FIRST_FPR_REGNUM + 48, 2}, \ --+ {"$fd25", NDS32_FIRST_FPR_REGNUM + 50, 2}, \ --+ {"$fd26", NDS32_FIRST_FPR_REGNUM + 52, 2}, \ --+ {"$fd27", NDS32_FIRST_FPR_REGNUM + 54, 2}, \ --+ {"$fd28", NDS32_FIRST_FPR_REGNUM + 56, 2}, \ --+ {"$fd29", NDS32_FIRST_FPR_REGNUM + 58, 2}, \ --+ {"$fd30", NDS32_FIRST_FPR_REGNUM + 60, 2}, \ --+ {"$fd31", NDS32_FIRST_FPR_REGNUM + 62, 2}, \ -- } -- -- /* Output normal jump table entry. */ --@@ -896,19 +1710,19 @@ enum reg_class -- do \ -- { \ -- switch (GET_MODE (body)) \ --- { \ --- case QImode: \ --- asm_fprintf (stream, "\t.byte\t.L%d-.L%d\n", value, rel); \ --- break; \ --- case HImode: \ --- asm_fprintf (stream, "\t.short\t.L%d-.L%d\n", value, rel); \ --- break; \ --- case SImode: \ --- asm_fprintf (stream, "\t.word\t.L%d-.L%d\n", value, rel); \ --- break; \ --- default: \ --- gcc_unreachable(); \ --- } \ --+ { \ --+ case QImode: \ --+ asm_fprintf (stream, "\t.byte\t.L%d-.L%d\n", value, rel); \ --+ break; \ --+ case HImode: \ --+ asm_fprintf (stream, "\t.short\t.L%d-.L%d\n", value, rel); \ --+ break; \ --+ case SImode: \ --+ asm_fprintf (stream, "\t.word\t.L%d-.L%d\n", value, rel); \ --+ break; \ --+ default: \ --+ gcc_unreachable(); \ --+ } \ -- } while (0) -- -- /* We have to undef it first because elfos.h formerly define it --@@ -925,10 +1739,10 @@ enum reg_class -- do \ -- { \ -- /* Because our jump table is in text section, \ --- we need to make sure 2-byte alignment after \ --- the jump table for instructions fetch. */ \ --+ we need to make sure 2-byte alignment after \ --+ the jump table for instructions fetch. */ \ -- if (GET_MODE (PATTERN (table)) == QImode) \ --- ASM_OUTPUT_ALIGN (stream, 1); \ --+ ASM_OUTPUT_ALIGN (stream, 1); \ -- asm_fprintf (stream, "\t! Jump Table End\n"); \ -- } while (0) -- --@@ -992,9 +1806,7 @@ enum reg_class -- /* Return the preferred mode for and addr_diff_vec when the mininum -- and maximum offset are known. */ -- #define CASE_VECTOR_SHORTEN_MODE(min_offset, max_offset, body) \ --- ((min_offset < 0 || max_offset >= 0x2000 ) ? SImode \ --- : (max_offset >= 100) ? HImode \ --- : QImode) --+ nds32_case_vector_shorten_mode (min_offset, max_offset, body) -- -- /* Generate pc relative jump table when -fpic or -Os. */ -- #define CASE_VECTOR_PC_RELATIVE (flag_pic || optimize_size) --@@ -1027,6 +1839,11 @@ enum reg_class -- when the condition is true. */ -- #define STORE_FLAG_VALUE 1 -- --+/* A C expression that indicates whether the architecture defines a value for --+ clz or ctz with a zero operand. In nds32 clz for 0 result 32 is defined --+ in ISA spec */ --+#define CLZ_DEFINED_VALUE_AT_ZERO(MODE, VALUE) ((VALUE) = 32, 1) --+ -- /* An alias for the machine mode for pointers. */ -- #define Pmode SImode -- --diff --git a/gcc/config/nds32/nds32.md b/gcc/config/nds32/nds32.md --index 5cdd8b2..557c466 100644 ----- a/gcc/config/nds32/nds32.md --+++ b/gcc/config/nds32/nds32.md --@@ -46,58 +46,144 @@ -- ;; Include DImode/DFmode operations. -- (include "nds32-doubleword.md") -- --+;; Include floating-point patterns. --+(include "nds32-fpu.md") --+ -- ;; Include peephole patterns. -- (include "nds32-peephole2.md") -- -- --+;; ------------------------------------------------------------------------ --+ --+;; CPU pipeline model. --+(define_attr "pipeline_model" "n7,n8,e8,n9,n10,graywolf,n13,panther,simple" --+ (const --+ (cond [(match_test "nds32_cpu_option == CPU_N7") (const_string "n7") --+ (match_test "nds32_cpu_option == CPU_N6 || nds32_cpu_option == CPU_N8") (const_string "n8") --+ (match_test "nds32_cpu_option == CPU_E8") (const_string "e8") --+ (match_test "nds32_cpu_option == CPU_N9") (const_string "n9") --+ (match_test "nds32_cpu_option == CPU_N10") (const_string "n10") --+ (match_test "nds32_cpu_option == CPU_GRAYWOLF") (const_string "graywolf") --+ (match_test "nds32_cpu_option == CPU_N12") (const_string "n13") --+ (match_test "nds32_cpu_option == CPU_N13") (const_string "n13") --+ (match_test "nds32_cpu_option == CPU_PANTHER") (const_string "panther") --+ (match_test "nds32_cpu_option == CPU_SIMPLE") (const_string "simple")] --+ (const_string "n9")))) --+ -- ;; Insn type, it is used to default other attribute values. -- (define_attr "type" --- "unknown,move,load,store,alu,compare,branch,call,misc" --+ "unknown,load,store,load_multiple,store_multiple,alu,alu_shift,pbsad,pbsada,mul,mac,div,branch,mmu,misc,\ --+ falu,fmuls,fmuld,fmacs,fmacd,fdivs,fdivd,fsqrts,fsqrtd,fcmp,fabs,fcpy,fcmov,fmfsr,fmfdr,fmtsr,fmtdr,fload,fstore,\ --+ dalu,dalu64,daluround,dcmp,dclip,dmul,dmac,dinsb,dpack,dbpick,dwext" -- (const_string "unknown")) -- --+;; Insn sub-type --+(define_attr "subtype" --+ "simple,shift,saturation" --+ (const_string "simple")) -- -- ;; Length, in bytes, default is 4-bytes. -- (define_attr "length" "" (const_int 4)) -- --+;; Indicate the amount of micro instructions. --+(define_attr "combo" --+ "0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25" --+ (const_string "1")) --+ --+;; Insn in which feature set, it is used to enable/disable insn alternatives. --+;; v1 : Baseline Instructions --+;; v2 : Baseline Version 2 Instructions --+;; v3m : Baseline Version 3m Instructions --+;; v3 : Baseline Version 3 Instructions --+;; pe1 : Performance Extension Instructions --+;; pe2 : Performance Extension Version 2 Instructions --+;; se : String Extension instructions --+(define_attr "feature" --+ "v1,v2,v3m,v3,pe1,pe2,se,fpu" --+ (const_string "v1")) -- -- ;; Enabled, which is used to enable/disable insn alternatives. -- ;; Note that we use length and TARGET_16_BIT here as criteria. ---;; If the instruction pattern already check TARGET_16_BIT to ---;; determine the length by itself, its enabled attribute should be ---;; always 1 to avoid the conflict with the settings here. ---(define_attr "enabled" "" --- (cond [(and (eq_attr "length" "2") --- (match_test "!TARGET_16_BIT")) --- (const_int 0)] --- (const_int 1))) --+;; If the instruction pattern already check TARGET_16_BIT to determine --+;; the length by itself, its enabled attribute should be customized to --+;; avoid the conflict between length attribute and this default setting. --+(define_attr "enabled" "no,yes" --+ (if_then_else --+ (and (eq_attr "length" "2") --+ (match_test "!TARGET_16_BIT")) --+ (const_string "no") --+ (cond [(eq_attr "feature" "v1") (const_string "yes") --+ (eq_attr "feature" "v2") (if_then_else (match_test "TARGET_ISA_V2 || TARGET_ISA_V3 || TARGET_ISA_V3M") --+ (const_string "yes") --+ (const_string "no")) --+ (eq_attr "feature" "v3") (if_then_else (match_test "TARGET_ISA_V3") --+ (const_string "yes") --+ (const_string "no")) --+ (eq_attr "feature" "v3m") (if_then_else (match_test "TARGET_ISA_V3 || TARGET_ISA_V3M") --+ (const_string "yes") --+ (const_string "no")) --+ (eq_attr "feature" "pe1") (if_then_else (match_test "TARGET_EXT_PERF") --+ (const_string "yes") --+ (const_string "no")) --+ (eq_attr "feature" "pe2") (if_then_else (match_test "TARGET_EXT_PERF2") --+ (const_string "yes") --+ (const_string "no")) --+ (eq_attr "feature" "se") (if_then_else (match_test "TARGET_EXT_STRING") --+ (const_string "yes") --+ (const_string "no")) --+ (eq_attr "feature" "fpu") (if_then_else (match_test "TARGET_FPU_SINGLE || TARGET_FPU_DOUBLE") --+ (const_string "yes") --+ (const_string "no"))] --+ (const_string "yes")))) -- -- -- ;; ---------------------------------------------------------------------------- -- --+(include "nds32-dspext.md") -- -- ;; Move instructions. -- -- ;; For QImode and HImode, the immediate value can be fit in imm20s. -- ;; So there is no need to split rtx for QI and HI patterns. -- ---(define_expand "movqi" --- [(set (match_operand:QI 0 "general_operand" "") --- (match_operand:QI 1 "general_operand" ""))] --+(define_expand "mov" --+ [(set (match_operand:QIHI 0 "general_operand" "") --+ (match_operand:QIHI 1 "general_operand" ""))] -- "" -- { -- /* Need to force register if mem <- !reg. */ -- if (MEM_P (operands[0]) && !REG_P (operands[1])) --- operands[1] = force_reg (QImode, operands[1]); --+ operands[1] = force_reg (mode, operands[1]); --+ --+ if (MEM_P (operands[1]) && optimize > 0) --+ { --+ rtx reg = gen_reg_rtx (SImode); --+ --+ emit_insn (gen_zero_extendsi2 (reg, operands[1])); --+ operands[1] = gen_lowpart (mode, reg); --+ } -- }) -- ---(define_expand "movhi" --- [(set (match_operand:HI 0 "general_operand" "") --- (match_operand:HI 1 "general_operand" ""))] --+(define_expand "movmisalign" --+ [(set (match_operand:SIDI 0 "general_operand" "") --+ (match_operand:SIDI 1 "general_operand" ""))] -- "" -- { --- /* Need to force register if mem <- !reg. */ --+ rtx addr; -- if (MEM_P (operands[0]) && !REG_P (operands[1])) --- operands[1] = force_reg (HImode, operands[1]); --+ operands[1] = force_reg (mode, operands[1]); --+ --+ if (MEM_P (operands[0])) --+ { --+ addr = force_reg (Pmode, XEXP (operands[0], 0)); --+ emit_insn (gen_unaligned_store (addr, operands[1])); --+ } --+ else --+ { --+ addr = force_reg (Pmode, XEXP (operands[1], 0)); --+ emit_insn (gen_unaligned_load (operands[0], addr)); --+ } --+ DONE; -- }) -- -- (define_expand "movsi" --@@ -130,12 +216,33 @@ -- low12_int)); -- DONE; -- } --+ --+ if (REG_P (operands[0]) && SYMBOLIC_CONST_P (operands[1])) --+ { --+ if (TARGET_ICT_MODEL_LARGE --+ && nds32_indirect_call_referenced_p (operands[1])) --+ { --+ nds32_expand_ict_move (operands); --+ DONE; --+ } --+ else if (nds32_tls_referenced_p (operands [1])) --+ { --+ nds32_expand_tls_move (operands); --+ DONE; --+ } --+ else if (flag_pic) --+ { --+ nds32_expand_pic_move (operands); --+ DONE; --+ } --+ } -- }) -- -- (define_insn "*mov" --- [(set (match_operand:QIHISI 0 "nonimmediate_operand" "=r, r, U45, U33, U37, U45, m, l, l, l, d, r, d, r, r, r") --- (match_operand:QIHISI 1 "nds32_move_operand" " r, r, l, l, l, d, r, U45, U33, U37, U45, m, Ip05, Is05, Is20, Ihig"))] --- "" --+ [(set (match_operand:QIHISI 0 "nonimmediate_operand" "=r, r,U45,U33,U37,U45, m, l, l, l, d, d, r, d, r, r, r, *f, *f, r, *f, Q, A") --+ (match_operand:QIHISI 1 "nds32_move_operand" " r, r, l, l, l, d, r,U45,U33,U37,U45,Ufe, m,Ip05, Is05, Is20, Ihig, *f, r, *f, Q, *f, r"))] --+ "register_operand(operands[0], mode) --+ || register_operand(operands[1], mode)" -- { -- switch (which_alternative) -- { --@@ -154,37 +261,54 @@ -- case 8: -- case 9: -- case 10: --- return nds32_output_16bit_load (operands, ); -- case 11: --- return nds32_output_32bit_load (operands, ); --+ return nds32_output_16bit_load (operands, ); -- case 12: --- return "movpi45\t%0, %1"; --+ return nds32_output_32bit_load (operands, ); -- case 13: --- return "movi55\t%0, %1"; --+ return "movpi45\t%0, %1"; -- case 14: --- return "movi\t%0, %1"; --+ return "movi55\t%0, %1"; -- case 15: --+ return "movi\t%0, %1"; --+ case 16: -- return "sethi\t%0, hi20(%1)"; --+ case 17: --+ if (TARGET_FPU_SINGLE) --+ return "fcpyss\t%0, %1, %1"; --+ else --+ return "#"; --+ case 18: --+ return "fmtsr\t%1, %0"; --+ case 19: --+ return "fmfsr\t%0, %1"; --+ case 20: --+ return nds32_output_float_load (operands); --+ case 21: --+ return nds32_output_float_store (operands); --+ case 22: --+ return "mtusr\t%1, %0"; -- default: -- gcc_unreachable (); -- } -- } --- [(set_attr "type" "alu,alu,store,store,store,store,store,load,load,load,load,load,alu,alu,alu,alu") --- (set_attr "length" " 2, 4, 2, 2, 2, 2, 4, 2, 2, 2, 2, 4, 2, 2, 4, 4")]) --+ [(set_attr "type" "alu,alu,store,store,store,store,store,load,load,load,load,load,load,alu,alu,alu,alu,fcpy,fmtsr,fmfsr,fload,fstore,alu") --+ (set_attr "length" " 2, 4, 2, 2, 2, 2, 4, 2, 2, 2, 2, 2, 4, 2, 2, 4, 4, 4, 4, 4, 4, 4, 4") --+ (set_attr "feature" " v1, v1, v1, v1, v1, v1, v1, v1, v1, v1, v1, v3m, v1, v1, v1, v1, v1, fpu, fpu, fpu, fpu, fpu, v1")]) -- -- -- ;; We use nds32_symbolic_operand to limit that only CONST/SYMBOL_REF/LABEL_REF -- ;; are able to match such instruction template. ---(define_insn "*move_addr" --- [(set (match_operand:SI 0 "register_operand" "=l, r") --- (match_operand:SI 1 "nds32_symbolic_operand" " i, i"))] --+(define_insn "move_addr" --+ [(set (match_operand:SI 0 "nds32_general_register_operand" "=l, r") --+ (match_operand:SI 1 "nds32_nonunspec_symbolic_operand" " i, i"))] -- "" -- "la\t%0, %1" --- [(set_attr "type" "move") --+ [(set_attr "type" "alu") -- (set_attr "length" "8")]) -- -- ---(define_insn "*sethi" --+(define_insn "sethi" -- [(set (match_operand:SI 0 "register_operand" "=r") -- (high:SI (match_operand:SI 1 "nds32_symbolic_operand" " i")))] -- "" --@@ -193,7 +317,7 @@ -- (set_attr "length" "4")]) -- -- ---(define_insn "*lo_sum" --+(define_insn "lo_sum" -- [(set (match_operand:SI 0 "register_operand" "=r") -- (lo_sum:SI (match_operand:SI 1 "register_operand" " r") -- (match_operand:SI 2 "nds32_symbolic_operand" " i")))] --@@ -208,8 +332,8 @@ -- ;; Zero extension instructions. -- -- (define_insn "zero_extendsi2" --- [(set (match_operand:SI 0 "register_operand" "=l, r, l, *r") --- (zero_extend:SI (match_operand:QIHI 1 "nonimmediate_operand" " l, r, U33, m")))] --+ [(set (match_operand:SI 0 "register_operand" "=l, r, l, *r") --+ (zero_extend:SI (match_operand:QIHI 1 "nonimmediate_operand" " l, r,U33, m")))] -- "" -- { -- switch (which_alternative) --@@ -245,7 +369,7 @@ -- case 1: -- return "se\t%0, %1"; -- case 2: --- return nds32_output_32bit_load_s (operands, ); --+ return nds32_output_32bit_load_se (operands, ); -- -- default: -- gcc_unreachable (); --@@ -256,25 +380,70 @@ -- -- -- ;; ---------------------------------------------------------------------------- --+(define_expand "extv" --+ [(set (match_operand 0 "register_operand" "") --+ (sign_extract (match_operand 1 "nonimmediate_operand" "") --+ (match_operand 2 "const_int_operand" "") --+ (match_operand 3 "const_int_operand" "")))] --+ "" --+{ --+ enum nds32_expand_result_type result = nds32_expand_extv (operands); --+ switch (result) --+ { --+ case EXPAND_DONE: --+ DONE; --+ break; --+ case EXPAND_FAIL: --+ FAIL; --+ break; --+ case EXPAND_CREATE_TEMPLATE: --+ break; --+ default: --+ gcc_unreachable (); --+ } --+}) --+ --+(define_expand "insv" --+ [(set (zero_extract (match_operand 0 "nonimmediate_operand" "") --+ (match_operand 1 "const_int_operand" "") --+ (match_operand 2 "const_int_operand" "")) --+ (match_operand 3 "register_operand" ""))] --+ "" --+{ --+ enum nds32_expand_result_type result = nds32_expand_insv (operands); --+ switch (result) --+ { --+ case EXPAND_DONE: --+ DONE; --+ break; --+ case EXPAND_FAIL: --+ FAIL; --+ break; --+ case EXPAND_CREATE_TEMPLATE: --+ break; --+ default: --+ gcc_unreachable (); --+ } --+}) -- -- ;; Arithmetic instructions. -- ---(define_insn "add3" --- [(set (match_operand:QIHISI 0 "register_operand" "= d, l, d, l, d, l, k, l, r, r") --- (plus:QIHISI (match_operand:QIHISI 1 "register_operand" "% 0, l, 0, l, 0, l, 0, k, r, r") --- (match_operand:QIHISI 2 "nds32_rimm15s_operand" " In05, In03, Iu05, Iu03, r, l, Is10, Iu06, Is15, r")))] --+(define_insn "addsi3" --+ [(set (match_operand:SI 0 "register_operand" "= d, l, d, l, d,l, k, l, r, r") --+ (plus:SI (match_operand:SI 1 "register_operand" "% 0, l, 0, l, 0,l, 0, k, r, r") --+ (match_operand:SI 2 "nds32_rimm15s_operand" " In05,In03,Iu05,Iu03, r,l,Is10,IU06, Is15, r")))] -- "" -- { -- switch (which_alternative) -- { -- case 0: -- /* addi Rt4,Rt4,-x ==> subi45 Rt4,x --- where 0 <= x <= 31 */ --+ where 0 <= x <= 31 */ -- operands[2] = gen_int_mode (-INTVAL (operands[2]), SImode); -- return "subi45\t%0, %2"; -- case 1: -- /* addi Rt3,Ra3,-x ==> subi333 Rt3,Ra3,x --- where 0 <= x <= 7 */ --+ where 0 <= x <= 7 */ -- operands[2] = gen_int_mode (-INTVAL (operands[2]), SImode); -- return "subi333\t%0, %1, %2"; -- case 2: --@@ -298,19 +467,20 @@ -- gcc_unreachable (); -- } -- } --- [(set_attr "type" "alu,alu,alu,alu,alu,alu,alu,alu,alu,alu") --- (set_attr "length" " 2, 2, 2, 2, 2, 2, 2, 2, 4, 4")]) --- ---(define_insn "sub3" --- [(set (match_operand:QIHISI 0 "register_operand" "=d, l, r, r") --- (minus:QIHISI (match_operand:QIHISI 1 "nds32_rimm15s_operand" " 0, l, Is15, r") --- (match_operand:QIHISI 2 "register_operand" " r, l, r, r")))] --+ [(set_attr "type" "alu,alu,alu,alu,alu,alu,alu,alu,alu,alu") --+ (set_attr "length" " 2, 2, 2, 2, 2, 2, 2, 2, 4, 4") --+ (set_attr "feature" " v1, v1, v1, v1, v1, v1, v2, v1, v1, v1")]) --+ --+(define_insn "subsi3" --+ [(set (match_operand:SI 0 "register_operand" "=d, l, r, r") --+ (minus:SI (match_operand:SI 1 "nds32_rimm15s_operand" " 0, l, Is15, r") --+ (match_operand:SI 2 "register_operand" " r, l, r, r")))] -- "" -- "@ --- sub45\t%0, %2 --- sub333\t%0, %1, %2 --- subri\t%0, %2, %1 --- sub\t%0, %1, %2" --+ sub45\t%0, %2 --+ sub333\t%0, %1, %2 --+ subri\t%0, %2, %1 --+ sub\t%0, %1, %2" -- [(set_attr "type" "alu,alu,alu,alu") -- (set_attr "length" " 2, 2, 4, 4")]) -- --@@ -320,10 +490,10 @@ -- ;; and needs to ensure it is exact_log2 value. -- (define_insn "*add_slli" -- [(set (match_operand:SI 0 "register_operand" "=r") --- (plus:SI (mult:SI (match_operand:SI 1 "register_operand" " r") --+ (plus:SI (mult:SI (match_operand:SI 1 "register_operand" " r") -- (match_operand:SI 2 "immediate_operand" " i")) -- (match_operand:SI 3 "register_operand" " r")))] --- "TARGET_ISA_V3 --+ "TARGET_ISA_V3 && (TARGET_PIPELINE_PANTHER || optimize_size) -- && (exact_log2 (INTVAL (operands[2])) != -1) -- && (exact_log2 (INTVAL (operands[2])) <= 31)" -- { --@@ -333,18 +503,20 @@ -- -- return "add_slli\t%0, %3, %1, %2"; -- } --- [(set_attr "type" "alu") --- (set_attr "length" "4")]) --+ [(set_attr "type" "alu_shift") --+ (set_attr "combo" "2") --+ (set_attr "length" "4")]) -- -- (define_insn "*add_srli" --- [(set (match_operand:SI 0 "register_operand" "= r") --- (plus:SI (lshiftrt:SI (match_operand:SI 1 "register_operand" " r") --- (match_operand:SI 2 "immediate_operand" " Iu05")) --- (match_operand:SI 3 "register_operand" " r")))] --- "TARGET_ISA_V3" --+ [(set (match_operand:SI 0 "register_operand" "= r") --+ (plus:SI (lshiftrt:SI (match_operand:SI 1 "register_operand" " r") --+ (match_operand:SI 2 "nds32_imm5u_operand" " Iu05")) --+ (match_operand:SI 3 "register_operand" " r")))] --+ "TARGET_ISA_V3 && (TARGET_PIPELINE_PANTHER || optimize_size)" -- "add_srli\t%0, %3, %1, %2" --- [(set_attr "type" "alu") --- (set_attr "length" "4")]) --+ [(set_attr "type" "alu_shift") --+ (set_attr "combo" "2") --+ (set_attr "length" "4")]) -- -- -- ;; GCC intends to simplify (minus (reg) (ashift ...)) --@@ -355,7 +527,7 @@ -- (minus:SI (match_operand:SI 1 "register_operand" " r") -- (mult:SI (match_operand:SI 2 "register_operand" " r") -- (match_operand:SI 3 "immediate_operand" " i"))))] --- "TARGET_ISA_V3 --+ "TARGET_ISA_V3 && (TARGET_PIPELINE_PANTHER || optimize_size) -- && (exact_log2 (INTVAL (operands[3])) != -1) -- && (exact_log2 (INTVAL (operands[3])) <= 31)" -- { --@@ -365,32 +537,35 @@ -- -- return "sub_slli\t%0, %1, %2, %3"; -- } --- [(set_attr "type" "alu") --- (set_attr "length" "4")]) --+ [(set_attr "type" "alu_shift") --+ (set_attr "combo" "2") --+ (set_attr "length" "4")]) -- -- (define_insn "*sub_srli" --- [(set (match_operand:SI 0 "register_operand" "= r") --- (minus:SI (match_operand:SI 1 "register_operand" " r") --- (lshiftrt:SI (match_operand:SI 2 "register_operand" " r") --- (match_operand:SI 3 "immediate_operand" " Iu05"))))] --- "TARGET_ISA_V3" --+ [(set (match_operand:SI 0 "register_operand" "= r") --+ (minus:SI (match_operand:SI 1 "register_operand" " r") --+ (lshiftrt:SI (match_operand:SI 2 "register_operand" " r") --+ (match_operand:SI 3 "nds32_imm5u_operand" " Iu05"))))] --+ "TARGET_ISA_V3 && (TARGET_PIPELINE_PANTHER || optimize_size)" -- "sub_srli\t%0, %1, %2, %3" --- [(set_attr "type" "alu") --- (set_attr "length" "4")]) --+ [(set_attr "type" "alu_shift") --+ (set_attr "combo" "2") --+ (set_attr "length" "4")]) -- -- -- ;; Multiplication instructions. -- -- (define_insn "mulsi3" --- [(set (match_operand:SI 0 "register_operand" "=w, r") --+ [(set (match_operand:SI 0 "register_operand" "=l, r") -- (mult:SI (match_operand:SI 1 "register_operand" "%0, r") --- (match_operand:SI 2 "register_operand" " w, r")))] --+ (match_operand:SI 2 "register_operand" " l, r")))] -- "" -- "@ --- mul33\t%0, %2 --- mul\t%0, %1, %2" --- [(set_attr "type" "alu,alu") --- (set_attr "length" " 2, 4")]) --+ mul33\t%0, %2 --+ mul\t%0, %1, %2" --+ [(set_attr "type" "mul,mul") --+ (set_attr "length" " 2, 4") --+ (set_attr "feature" "v3m, v1")]) -- -- (define_insn "mulsidi3" -- [(set (match_operand:DI 0 "register_operand" "=r") --@@ -398,7 +573,7 @@ -- (sign_extend:DI (match_operand:SI 2 "register_operand" " r"))))] -- "TARGET_ISA_V2 || TARGET_ISA_V3" -- "mulsr64\t%0, %1, %2" --- [(set_attr "type" "alu") --+ [(set_attr "type" "mul") -- (set_attr "length" "4")]) -- -- (define_insn "umulsidi3" --@@ -407,7 +582,7 @@ -- (zero_extend:DI (match_operand:SI 2 "register_operand" " r"))))] -- "TARGET_ISA_V2 || TARGET_ISA_V3" -- "mulr64\t%0, %1, %2" --- [(set_attr "type" "alu") --+ [(set_attr "type" "mul") -- (set_attr "length" "4")]) -- -- --@@ -415,32 +590,32 @@ -- -- (define_insn "*maddr32_0" -- [(set (match_operand:SI 0 "register_operand" "=r") --- (plus:SI (match_operand:SI 3 "register_operand" " 0") --- (mult:SI (match_operand:SI 1 "register_operand" " r") --- (match_operand:SI 2 "register_operand" " r"))))] --+ (plus:SI (match_operand:SI 3 "register_operand" " 0") --+ (mult:SI (match_operand:SI 1 "register_operand" " r") --+ (match_operand:SI 2 "register_operand" " r"))))] -- "" -- "maddr32\t%0, %1, %2" --- [(set_attr "type" "alu") --+ [(set_attr "type" "mac") -- (set_attr "length" "4")]) -- -- (define_insn "*maddr32_1" -- [(set (match_operand:SI 0 "register_operand" "=r") --- (plus:SI (mult:SI (match_operand:SI 1 "register_operand" " r") --- (match_operand:SI 2 "register_operand" " r")) --- (match_operand:SI 3 "register_operand" " 0")))] --+ (plus:SI (mult:SI (match_operand:SI 1 "register_operand" " r") --+ (match_operand:SI 2 "register_operand" " r")) --+ (match_operand:SI 3 "register_operand" " 0")))] -- "" -- "maddr32\t%0, %1, %2" --- [(set_attr "type" "alu") --+ [(set_attr "type" "mac") -- (set_attr "length" "4")]) -- -- (define_insn "*msubr32" -- [(set (match_operand:SI 0 "register_operand" "=r") --- (minus:SI (match_operand:SI 3 "register_operand" " 0") --- (mult:SI (match_operand:SI 1 "register_operand" " r") --- (match_operand:SI 2 "register_operand" " r"))))] --+ (minus:SI (match_operand:SI 3 "register_operand" " 0") --+ (mult:SI (match_operand:SI 1 "register_operand" " r") --+ (match_operand:SI 2 "register_operand" " r"))))] -- "" -- "msubr32\t%0, %1, %2" --- [(set_attr "type" "alu") --+ [(set_attr "type" "mac") -- (set_attr "length" "4")]) -- -- --@@ -448,26 +623,46 @@ -- -- (define_insn "divmodsi4" -- [(set (match_operand:SI 0 "register_operand" "=r") --- (div:SI (match_operand:SI 1 "register_operand" " r") --- (match_operand:SI 2 "register_operand" " r"))) --+ (div:SI (match_operand:SI 1 "register_operand" " r") --+ (match_operand:SI 2 "register_operand" " r"))) -- (set (match_operand:SI 3 "register_operand" "=r") --- (mod:SI (match_dup 1) (match_dup 2)))] --+ (mod:SI (match_dup 1) (match_dup 2)))] -- "" -- "divsr\t%0, %3, %1, %2" --- [(set_attr "type" "alu") --+ [(set_attr "type" "div") -- (set_attr "length" "4")]) -- -- (define_insn "udivmodsi4" -- [(set (match_operand:SI 0 "register_operand" "=r") --- (udiv:SI (match_operand:SI 1 "register_operand" " r") --- (match_operand:SI 2 "register_operand" " r"))) --+ (udiv:SI (match_operand:SI 1 "register_operand" " r") --+ (match_operand:SI 2 "register_operand" " r"))) -- (set (match_operand:SI 3 "register_operand" "=r") --- (umod:SI (match_dup 1) (match_dup 2)))] --+ (umod:SI (match_dup 1) (match_dup 2)))] -- "" -- "divr\t%0, %3, %1, %2" --- [(set_attr "type" "alu") --+ [(set_attr "type" "div") --+ (set_attr "length" "4")]) --+ --+;; divsr/divr will keep quotient only when quotient and remainder is the same --+;; register in our ISA spec, it's can reduce 1 register presure if we don't --+;; want remainder. --+(define_insn "divsi4" --+ [(set (match_operand:SI 0 "register_operand" "=r") --+ (div:SI (match_operand:SI 1 "register_operand" " r") --+ (match_operand:SI 2 "register_operand" " r")))] --+ "" --+ "divsr\t%0, %0, %1, %2" --+ [(set_attr "type" "div") -- (set_attr "length" "4")]) -- --+(define_insn "udivsi4" --+ [(set (match_operand:SI 0 "register_operand" "=r") --+ (udiv:SI (match_operand:SI 1 "register_operand" " r") --+ (match_operand:SI 2 "register_operand" " r")))] --+ "" --+ "divr\t%0, %0, %1, %2" --+ [(set_attr "type" "div") --+ (set_attr "length" "4")]) -- -- ;; ---------------------------------------------------------------------------- -- --@@ -488,14 +683,28 @@ -- (set_attr "length" "4")] -- ) -- ---(define_insn "andsi3" --- [(set (match_operand:SI 0 "register_operand" "=w, r, l, l, l, l, l, l, r, r, r, r, r") --- (and:SI (match_operand:SI 1 "register_operand" "%0, r, l, l, l, l, 0, 0, r, r, r, r, r") --- (match_operand:SI 2 "general_operand" " w, r, Izeb, Izeh, Ixls, Ix11, Ibms, Ifex, Izeb, Izeh, Iu15, Ii15, Ic15")))] --+(define_expand "andsi3" --+ [(set (match_operand:SI 0 "register_operand" "") --+ (and:SI (match_operand:SI 1 "register_operand" "") --+ (match_operand:SI 2 "nds32_reg_constant_operand" "")))] --+ "" --+{ --+ if (CONST_INT_P (operands[2]) --+ && !nds32_and_operand (operands[2], SImode)) --+ { --+ nds32_expand_constant (SImode, INTVAL (operands[2]), --+ operands[0], operands[1]); --+ DONE; --+ } --+}) --+ --+(define_insn "*andsi3" --+ [(set (match_operand:SI 0 "register_operand" "=l, r, l, l, l, l, l, l, r, r, r, r, r") --+ (and:SI (match_operand:SI 1 "register_operand" "%0, r, l, l, l, l, 0, 0, r, r, r, r, r") --+ (match_operand:SI 2 "nds32_and_operand" " l, r,Izeb,Izeh,Ixls,Ix11,Ibms,Ifex, Izeb, Izeh, Iu15, Ii15, Ic15")))] -- "" -- { -- HOST_WIDE_INT mask = INTVAL (operands[2]); --- int zero_position; -- -- /* 16-bit andi instructions: -- andi Rt3,Ra3,0xff -> zeb33 Rt3,Ra3 --@@ -520,8 +729,7 @@ -- case 5: -- return "x11b33\t%0, %1"; -- case 6: --- operands[2] = GEN_INT (floor_log2 (mask)); --- return "bmski33\t%0, %2"; --+ return "bmski33\t%0, %B2"; -- case 7: -- operands[2] = GEN_INT (floor_log2 (mask + 1) - 1); -- return "fexti33\t%0, %2"; --@@ -535,47 +743,35 @@ -- operands[2] = GEN_INT (~mask); -- return "bitci\t%0, %1, %2"; -- case 12: --- /* If we reach this alternative, --- it must pass the nds32_can_use_bclr_p() test, --- so that we can guarantee there is only one 0-bit --- within the immediate value. */ --- for (zero_position = 31; zero_position >= 0; zero_position--) --- { --- if ((INTVAL (operands[2]) & (1 << zero_position)) == 0) --- { --- /* Found the 0-bit position. */ --- operands[2] = GEN_INT (zero_position); --- break; --- } --- } --- return "bclr\t%0, %1, %2"; --+ return "bclr\t%0, %1, %b2"; -- -- default: -- gcc_unreachable (); -- } -- } --- [(set_attr "type" "alu,alu,alu,alu,alu,alu,alu,alu,alu,alu,alu,alu,alu") --- (set_attr "length" " 2, 4, 2, 2, 2, 2, 2, 2, 4, 4, 4, 4, 4")]) --+ [(set_attr "type" "alu,alu,alu,alu,alu,alu,alu,alu,alu,alu,alu,alu,alu") --+ (set_attr "length" " 2, 4, 2, 2, 2, 2, 2, 2, 4, 4, 4, 4, 4") --+ (set_attr "feature" "v3m, v1, v1, v1, v1, v1,v3m,v3m, v1, v1, v1, v3,pe1")]) -- -- (define_insn "*and_slli" --- [(set (match_operand:SI 0 "register_operand" "= r") --- (and:SI (ashift:SI (match_operand:SI 1 "register_operand" " r") --- (match_operand:SI 2 "immediate_operand" " Iu05")) --- (match_operand:SI 3 "register_operand" " r")))] --- "TARGET_ISA_V3" --+ [(set (match_operand:SI 0 "register_operand" "= r") --+ (and:SI (ashift:SI (match_operand:SI 1 "register_operand" " r") --+ (match_operand:SI 2 "nds32_imm5u_operand" " Iu05")) --+ (match_operand:SI 3 "register_operand" " r")))] --+ "TARGET_ISA_V3 && (TARGET_PIPELINE_PANTHER || optimize_size)" -- "and_slli\t%0, %3, %1, %2" --- [(set_attr "type" "alu") --- (set_attr "length" "4")]) --+ [(set_attr "type" "alu_shift") --+ (set_attr "length" "4")]) -- -- (define_insn "*and_srli" --- [(set (match_operand:SI 0 "register_operand" "= r") --- (and:SI (lshiftrt:SI (match_operand:SI 1 "register_operand" " r") --- (match_operand:SI 2 "immediate_operand" " Iu05")) --- (match_operand:SI 3 "register_operand" " r")))] --- "TARGET_ISA_V3" --+ [(set (match_operand:SI 0 "register_operand" "= r") --+ (and:SI (lshiftrt:SI (match_operand:SI 1 "register_operand" " r") --+ (match_operand:SI 2 "nds32_imm5u_operand" " Iu05")) --+ (match_operand:SI 3 "register_operand" " r")))] --+ "TARGET_ISA_V3 && (TARGET_PIPELINE_PANTHER || optimize_size)" -- "and_srli\t%0, %3, %1, %2" --- [(set_attr "type" "alu") --- (set_attr "length" "4")]) --+ [(set_attr "type" "alu_shift") --+ (set_attr "length" "4")]) -- -- -- ;; ---------------------------------------------------------------------------- --@@ -584,58 +780,50 @@ -- -- ;; For V3/V3M ISA, we have 'or33' instruction. -- ;; So we can identify 'or Rt3,Rt3,Ra3' case and set its length to be 2. ---(define_insn "iorsi3" --- [(set (match_operand:SI 0 "register_operand" "=w, r, r, r") --- (ior:SI (match_operand:SI 1 "register_operand" "%0, r, r, r") --- (match_operand:SI 2 "general_operand" " w, r, Iu15, Ie15")))] --+ --+(define_expand "iorsi3" --+ [(set (match_operand:SI 0 "register_operand" "") --+ (ior:SI (match_operand:SI 1 "register_operand" "") --+ (match_operand:SI 2 "general_operand" "")))] -- "" -- { --- int one_position; --- --- switch (which_alternative) --- { --- case 0: --- return "or33\t%0, %2"; --- case 1: --- return "or\t%0, %1, %2"; --- case 2: --- return "ori\t%0, %1, %2"; --- case 3: --- /* If we reach this alternative, --- it must pass the nds32_can_use_bset_p() test, --- so that we can guarantee there is only one 1-bit --- within the immediate value. */ --- /* Use exact_log2() to search the 1-bit position. */ --- one_position = exact_log2 (INTVAL (operands[2])); --- operands[2] = GEN_INT (one_position); --- return "bset\t%0, %1, %2"; --+ if (!nds32_ior_operand (operands[2], SImode)) --+ operands[2] = force_reg (SImode, operands[2]); --+}) -- --- default: --- gcc_unreachable (); --- } ---} --- [(set_attr "type" "alu,alu,alu,alu") --- (set_attr "length" " 2, 4, 4, 4")]) --+(define_insn "*iorsi3" --+ [(set (match_operand:SI 0 "register_operand" "=l, r, r, r") --+ (ior:SI (match_operand:SI 1 "register_operand" "%0, r, r, r") --+ (match_operand:SI 2 "nds32_ior_operand" " l, r, Iu15, Ie15")))] --+ "" --+ "@ --+ or33\t%0, %2 --+ or\t%0, %1, %2 --+ ori\t%0, %1, %2 --+ bset\t%0, %1, %B2" --+ [(set_attr "type" "alu,alu,alu,alu") --+ (set_attr "length" " 2, 4, 4, 4") --+ (set_attr "feature" "v3m, v1, v1,pe1")]) -- -- (define_insn "*or_slli" --- [(set (match_operand:SI 0 "register_operand" "= r") --- (ior:SI (ashift:SI (match_operand:SI 1 "register_operand" " r") --- (match_operand:SI 2 "immediate_operand" " Iu05")) --- (match_operand:SI 3 "register_operand" " r")))] --- "TARGET_ISA_V3" --+ [(set (match_operand:SI 0 "register_operand" "= r") --+ (ior:SI (ashift:SI (match_operand:SI 1 "register_operand" " r") --+ (match_operand:SI 2 "nds32_imm5u_operand" " Iu05")) --+ (match_operand:SI 3 "register_operand" " r")))] --+ "TARGET_ISA_V3 && (TARGET_PIPELINE_PANTHER || optimize_size)" -- "or_slli\t%0, %3, %1, %2" --- [(set_attr "type" "alu") --- (set_attr "length" "4")]) --+ [(set_attr "type" "alu_shift") --+ (set_attr "length" "4")]) -- -- (define_insn "*or_srli" --- [(set (match_operand:SI 0 "register_operand" "= r") --- (ior:SI (lshiftrt:SI (match_operand:SI 1 "register_operand" " r") --- (match_operand:SI 2 "immediate_operand" " Iu05")) --- (match_operand:SI 3 "register_operand" " r")))] --- "TARGET_ISA_V3" --+ [(set (match_operand:SI 0 "register_operand" "= r") --+ (ior:SI (lshiftrt:SI (match_operand:SI 1 "register_operand" " r") --+ (match_operand:SI 2 "nds32_imm5u_operand" " Iu05")) --+ (match_operand:SI 3 "register_operand" " r")))] --+ "TARGET_ISA_V3 && (TARGET_PIPELINE_PANTHER || optimize_size)" -- "or_srli\t%0, %3, %1, %2" --- [(set_attr "type" "alu") --- (set_attr "length" "4")]) --+ [(set_attr "type" "alu_shift") --+ (set_attr "length" "4")]) -- -- -- ;; ---------------------------------------------------------------------------- --@@ -644,71 +832,64 @@ -- -- ;; For V3/V3M ISA, we have 'xor33' instruction. -- ;; So we can identify 'xor Rt3,Rt3,Ra3' case and set its length to be 2. ---(define_insn "xorsi3" --- [(set (match_operand:SI 0 "register_operand" "=w, r, r, r") --- (xor:SI (match_operand:SI 1 "register_operand" "%0, r, r, r") --- (match_operand:SI 2 "general_operand" " w, r, Iu15, It15")))] --+ --+(define_expand "xorsi3" --+ [(set (match_operand:SI 0 "register_operand" "") --+ (xor:SI (match_operand:SI 1 "register_operand" "") --+ (match_operand:SI 2 "general_operand" "")))] -- "" -- { --- int one_position; --- --- switch (which_alternative) --- { --- case 0: --- return "xor33\t%0, %2"; --- case 1: --- return "xor\t%0, %1, %2"; --- case 2: --- return "xori\t%0, %1, %2"; --- case 3: --- /* If we reach this alternative, --- it must pass the nds32_can_use_btgl_p() test, --- so that we can guarantee there is only one 1-bit --- within the immediate value. */ --- /* Use exact_log2() to search the 1-bit position. */ --- one_position = exact_log2 (INTVAL (operands[2])); --- operands[2] = GEN_INT (one_position); --- return "btgl\t%0, %1, %2"; --+ if (!nds32_xor_operand (operands[2], SImode)) --+ operands[2] = force_reg (SImode, operands[2]); --+}) -- --- default: --- gcc_unreachable (); --- } ---} --- [(set_attr "type" "alu,alu,alu,alu") --- (set_attr "length" " 2, 4, 4, 4")]) --+(define_insn "*xorsi3" --+ [(set (match_operand:SI 0 "register_operand" "=l, r, r, r") --+ (xor:SI (match_operand:SI 1 "register_operand" "%0, r, r, r") --+ (match_operand:SI 2 "nds32_xor_operand" " l, r, Iu15, It15")))] --+ "" --+ "@ --+ xor33\t%0, %2 --+ xor\t%0, %1, %2 --+ xori\t%0, %1, %2 --+ btgl\t%0, %1, %B2" --+ [(set_attr "type" "alu,alu,alu,alu") --+ (set_attr "length" " 2, 4, 4, 4") --+ (set_attr "feature" "v3m, v1, v1,pe1")]) -- -- (define_insn "*xor_slli" -- [(set (match_operand:SI 0 "register_operand" "= r") -- (xor:SI (ashift:SI (match_operand:SI 1 "register_operand" " r") --- (match_operand:SI 2 "immediate_operand" " Iu05")) --+ (match_operand:SI 2 "nds32_imm5u_operand" " Iu05")) -- (match_operand:SI 3 "register_operand" " r")))] --- "TARGET_ISA_V3" --+ "TARGET_ISA_V3 && (TARGET_PIPELINE_PANTHER || optimize_size)" -- "xor_slli\t%0, %3, %1, %2" --- [(set_attr "type" "alu") --- (set_attr "length" "4")]) --+ [(set_attr "type" "alu_shift") --+ (set_attr "length" "4")]) -- -- (define_insn "*xor_srli" --- [(set (match_operand:SI 0 "register_operand" "= r") --- (xor:SI (lshiftrt:SI (match_operand:SI 1 "register_operand" " r") --- (match_operand:SI 2 "immediate_operand" " Iu05")) --- (match_operand:SI 3 "register_operand" " r")))] --- "TARGET_ISA_V3" --+ [(set (match_operand:SI 0 "register_operand" "= r") --+ (xor:SI (lshiftrt:SI (match_operand:SI 1 "register_operand" " r") --+ (match_operand:SI 2 "nds32_imm5u_operand" " Iu05")) --+ (match_operand:SI 3 "register_operand" " r")))] --+ "TARGET_ISA_V3 && (TARGET_PIPELINE_PANTHER || optimize_size)" -- "xor_srli\t%0, %3, %1, %2" --- [(set_attr "type" "alu") --- (set_attr "length" "4")]) --+ [(set_attr "type" "alu_shift") --+ (set_attr "length" "4")]) -- -- ;; Rotate Right Instructions. -- ---(define_insn "rotrsi3" --- [(set (match_operand:SI 0 "register_operand" "= r, r") --- (rotatert:SI (match_operand:SI 1 "register_operand" " r, r") --- (match_operand:SI 2 "nonmemory_operand" " Iu05, r")))] --+(define_insn "*rotrsi3" --+ [(set (match_operand:SI 0 "register_operand" "= r, r") --+ (rotatert:SI (match_operand:SI 1 "register_operand" " r, r") --+ (match_operand:SI 2 "nds32_rimm5u_operand" " Iu05, r")))] -- "" -- "@ --- rotri\t%0, %1, %2 --- rotr\t%0, %1, %2" --- [(set_attr "type" "alu,alu") --- (set_attr "length" " 4, 4")]) --+ rotri\t%0, %1, %2 --+ rotr\t%0, %1, %2" --+ [(set_attr "type" " alu, alu") --+ (set_attr "subtype" "shift,shift") --+ (set_attr "length" " 4, 4")]) -- -- -- ;; ---------------------------------------------------------------------------- --@@ -720,14 +901,95 @@ -- ;; And for V2 ISA, there is NO 'neg33' instruction. -- ;; The only option is to use 'subri A,B,0' (its semantic is 'A = 0 - B'). -- (define_insn "negsi2" --- [(set (match_operand:SI 0 "register_operand" "=w, r") --- (neg:SI (match_operand:SI 1 "register_operand" " w, r")))] --+ [(set (match_operand:SI 0 "register_operand" "=l, r") --+ (neg:SI (match_operand:SI 1 "register_operand" " l, r")))] -- "" -- "@ -- neg33\t%0, %1 -- subri\t%0, %1, 0" --- [(set_attr "type" "alu,alu") --- (set_attr "length" " 2, 4")]) --+ [(set_attr "type" "alu,alu") --+ (set_attr "length" " 2, 4") --+ (set_attr "feature" "v3m, v1")]) --+ --+(define_expand "negsf2" --+ [(set (match_operand:SF 0 "register_operand" "") --+ (neg:SF (match_operand:SF 1 "register_operand" "")))] --+ "" --+{ --+ if (!TARGET_FPU_SINGLE && !TARGET_EXT_PERF) --+ { --+ rtx new_dst = simplify_gen_subreg (SImode, operands[0], SFmode, 0); --+ rtx new_src = simplify_gen_subreg (SImode, operands[1], SFmode, 0); --+ --+ emit_insn (gen_xorsi3 (new_dst, --+ new_src, --+ gen_int_mode (0x80000000, SImode))); --+ --+ DONE; --+ } --+}) --+ --+(define_expand "negdf2" --+ [(set (match_operand:DF 0 "register_operand" "") --+ (neg:DF (match_operand:DF 1 "register_operand" "")))] --+ "" --+{ --+}) --+ --+(define_insn_and_split "soft_negdf2" --+ [(set (match_operand:DF 0 "register_operand" "") --+ (neg:DF (match_operand:DF 1 "register_operand" "")))] --+ "!TARGET_FPU_DOUBLE" --+ "#" --+ "!TARGET_FPU_DOUBLE" --+ [(const_int 1)] --+{ --+ rtx src = operands[1]; --+ rtx dst = operands[0]; --+ rtx ori_dst = operands[0]; --+ --+ bool need_extra_move_for_dst_p; --+ /* FPU register can't change mode to SI directly, so we need create a --+ tmp register to handle it, and FPU register can't do `xor` or btgl. */ --+ if (HARD_REGISTER_P (src) --+ && TEST_HARD_REG_BIT (reg_class_contents[FP_REGS], REGNO (src))) --+ { --+ rtx tmp = gen_reg_rtx (DFmode); --+ emit_move_insn (tmp, src); --+ src = tmp; --+ } --+ --+ if (HARD_REGISTER_P (dst) --+ && TEST_HARD_REG_BIT (reg_class_contents[FP_REGS], REGNO (dst))) --+ { --+ need_extra_move_for_dst_p = true; --+ rtx tmp = gen_reg_rtx (DFmode); --+ dst = tmp; --+ } --+ --+ rtx dst_high_part = simplify_gen_subreg ( --+ SImode, dst, --+ DFmode, subreg_highpart_offset (SImode, DFmode)); --+ rtx dst_low_part = simplify_gen_subreg ( --+ SImode, dst, --+ DFmode, subreg_lowpart_offset (SImode, DFmode)); --+ rtx src_high_part = simplify_gen_subreg ( --+ SImode, src, --+ DFmode, subreg_highpart_offset (SImode, DFmode)); --+ rtx src_low_part = simplify_gen_subreg ( --+ SImode, src, --+ DFmode, subreg_lowpart_offset (SImode, DFmode)); --+ --+ emit_insn (gen_xorsi3 (dst_high_part, --+ src_high_part, --+ gen_int_mode (0x80000000, SImode))); --+ emit_move_insn (dst_low_part, src_low_part); --+ --+ if (need_extra_move_for_dst_p) --+ emit_move_insn (ori_dst, dst); --+ --+ DONE; --+}) -- -- -- ;; ---------------------------------------------------------------------------- --@@ -737,55 +999,72 @@ -- ;; For V3/V3M ISA, we have 'not33' instruction. -- ;; So we can identify 'not Rt3,Ra3' case and set its length to be 2. -- (define_insn "one_cmplsi2" --- [(set (match_operand:SI 0 "register_operand" "=w, r") --- (not:SI (match_operand:SI 1 "register_operand" " w, r")))] --+ [(set (match_operand:SI 0 "register_operand" "=l, r") --+ (not:SI (match_operand:SI 1 "register_operand" " l, r")))] -- "" -- "@ -- not33\t%0, %1 -- nor\t%0, %1, %1" --- [(set_attr "type" "alu,alu") --- (set_attr "length" " 2, 4")]) --+ [(set_attr "type" "alu,alu") --+ (set_attr "length" " 2, 4") --+ (set_attr "feature" "v3m, v1")]) -- -- -- ;; ---------------------------------------------------------------------------- -- -- ;; Shift instructions. -- ---(define_insn "ashlsi3" --- [(set (match_operand:SI 0 "register_operand" "= l, r, r") --- (ashift:SI (match_operand:SI 1 "register_operand" " l, r, r") --- (match_operand:SI 2 "nonmemory_operand" " Iu03, Iu05, r")))] --+(define_expand "si3" --+ [(set (match_operand:SI 0 "register_operand" "") --+ (shift_rotate:SI (match_operand:SI 1 "register_operand" "") --+ (match_operand:SI 2 "nds32_rimm5u_operand" "")))] -- "" --- "@ --- slli333\t%0, %1, %2 --- slli\t%0, %1, %2 --- sll\t%0, %1, %2" --- [(set_attr "type" "alu,alu,alu") --- (set_attr "length" " 2, 4, 4")]) --+{ --+ if (operands[2] == const0_rtx) --+ { --+ emit_move_insn (operands[0], operands[1]); --+ DONE; --+ } --+}) -- ---(define_insn "ashrsi3" --- [(set (match_operand:SI 0 "register_operand" "= d, r, r") --- (ashiftrt:SI (match_operand:SI 1 "register_operand" " 0, r, r") --- (match_operand:SI 2 "nonmemory_operand" " Iu05, Iu05, r")))] --+(define_insn "*ashlsi3" --+ [(set (match_operand:SI 0 "register_operand" "= l, r, r") --+ (ashift:SI (match_operand:SI 1 "register_operand" " l, r, r") --+ (match_operand:SI 2 "nds32_rimm5u_operand" " Iu03, Iu05, r")))] -- "" -- "@ --- srai45\t%0, %2 --- srai\t%0, %1, %2 --- sra\t%0, %1, %2" --- [(set_attr "type" "alu,alu,alu") --- (set_attr "length" " 2, 4, 4")]) --- ---(define_insn "lshrsi3" --- [(set (match_operand:SI 0 "register_operand" "= d, r, r") --- (lshiftrt:SI (match_operand:SI 1 "register_operand" " 0, r, r") --- (match_operand:SI 2 "nonmemory_operand" " Iu05, Iu05, r")))] --+ slli333\t%0, %1, %2 --+ slli\t%0, %1, %2 --+ sll\t%0, %1, %2" --+ [(set_attr "type" " alu, alu, alu") --+ (set_attr "subtype" "shift,shift,shift") --+ (set_attr "length" " 2, 4, 4")]) --+ --+(define_insn "*ashrsi3" --+ [(set (match_operand:SI 0 "register_operand" "= d, r, r") --+ (ashiftrt:SI (match_operand:SI 1 "register_operand" " 0, r, r") --+ (match_operand:SI 2 "nds32_rimm5u_operand" " Iu05, Iu05, r")))] --+ "" --+ "@ --+ srai45\t%0, %2 --+ srai\t%0, %1, %2 --+ sra\t%0, %1, %2" --+ [(set_attr "type" " alu, alu, alu") --+ (set_attr "subtype" "shift,shift,shift") --+ (set_attr "length" " 2, 4, 4")]) --+ --+(define_insn "*lshrsi3" --+ [(set (match_operand:SI 0 "register_operand" "= d, r, r") --+ (lshiftrt:SI (match_operand:SI 1 "register_operand" " 0, r, r") --+ (match_operand:SI 2 "nds32_rimm5u_operand" " Iu05, Iu05, r")))] -- "" -- "@ --- srli45\t%0, %2 --- srli\t%0, %1, %2 --- srl\t%0, %1, %2" --- [(set_attr "type" "alu,alu,alu") --- (set_attr "length" " 2, 4, 4")]) --+ srli45\t%0, %2 --+ srli\t%0, %1, %2 --+ srl\t%0, %1, %2" --+ [(set_attr "type" " alu, alu, alu") --+ (set_attr "subtype" "shift,shift,shift") --+ (set_attr "length" " 2, 4, 4")]) -- -- -- ;; ---------------------------------------------------------------------------- --@@ -794,148 +1073,65 @@ -- ;; Conditional Move patterns -- ;; ---------------------------------------------------------------------------- -- ---(define_expand "movsicc" --- [(set (match_operand:SI 0 "register_operand" "") --- (if_then_else:SI (match_operand 1 "comparison_operator" "") --- (match_operand:SI 2 "register_operand" "") --- (match_operand:SI 3 "register_operand" "")))] --- "TARGET_CMOV" --+(define_expand "movcc" --+ [(set (match_operand:QIHISI 0 "register_operand" "") --+ (if_then_else:QIHISI (match_operand 1 "nds32_movecc_comparison_operator" "") --+ (match_operand:QIHISI 2 "register_operand" "") --+ (match_operand:QIHISI 3 "register_operand" "")))] --+ "TARGET_CMOV && !optimize_size" -- { --- if ((GET_CODE (operands[1]) == EQ || GET_CODE (operands[1]) == NE) --- && GET_MODE (XEXP (operands[1], 0)) == SImode --- && XEXP (operands[1], 1) == const0_rtx) --- { --- /* If the operands[1] rtx is already (eq X 0) or (ne X 0), --- we have gcc generate original template rtx. */ --- goto create_template; --- } --- else --+ enum nds32_expand_result_type result = nds32_expand_movcc (operands); --+ switch (result) -- { --- /* Since there is only 'slt'(Set when Less Than) instruction for --- comparison in Andes ISA, the major strategy we use here is to --- convert conditional move into 'LT + EQ' or 'LT + NE' rtx combination. --- We design constraints properly so that the reload phase will assist --- to make one source operand to use same register as result operand. --- Then we can use cmovz/cmovn to catch the other source operand --- which has different register. */ --- enum rtx_code code = GET_CODE (operands[1]); --- enum rtx_code new_code = code; --- rtx cmp_op0 = XEXP (operands[1], 0); --- rtx cmp_op1 = XEXP (operands[1], 1); --- rtx tmp; --- int reverse = 0; --- --- /* Main Goal: Use 'LT + EQ' or 'LT + NE' to target "then" part --- Strategy : Reverse condition and swap comparison operands --- --- For example: --- --- a <= b ? P : Q (LE or LEU) --- --> a > b ? Q : P (reverse condition) --- --> b < a ? Q : P (swap comparison operands to achieve 'LT/LTU') --- --- a >= b ? P : Q (GE or GEU) --- --> a < b ? Q : P (reverse condition to achieve 'LT/LTU') --- --- a < b ? P : Q (LT or LTU) --- --> (NO NEED TO CHANGE, it is already 'LT/LTU') --- --- a > b ? P : Q (GT or GTU) --- --> b < a ? P : Q (swap comparison operands to achieve 'LT/LTU') */ --- switch (code) --- { --- case NE: --- /* (a != b ? P : Q) --- can be expressed as --- (a == b ? Q : P) --- so, fall through to reverse condition */ --- case GE: case GEU: case LE: case LEU: --- new_code = reverse_condition (code); --- reverse = 1; --- break; --- case EQ: case GT: case GTU: case LT: case LTU: --- /* no need to reverse condition */ --- break; --- default: --- FAIL; --- } --- --- /* For '>' comparison operator, we swap operands --- so that we can have 'LT/LTU' operator. */ --- if (new_code == GT || new_code == GTU) --- { --- tmp = cmp_op0; --- cmp_op0 = cmp_op1; --- cmp_op1 = tmp; --- --- new_code = swap_condition (new_code); --- } --- --- /* Use a temporary register to store slt/slts result. */ --- tmp = gen_reg_rtx (SImode); --- --- /* Split EQ and NE because we don't have direct comparison of EQ and NE. --- If we don't split it, the conditional move transformation will fail --- when producing (SET A (EQ B C)) or (SET A (NE B C)). */ --- if (new_code == EQ) --- { --- emit_insn (gen_xorsi3 (tmp, cmp_op0, cmp_op1)); --- emit_insn (gen_slt_compare (tmp, tmp, GEN_INT (1))); --- } --- else if (new_code == NE) --- { --- emit_insn (gen_xorsi3 (tmp, cmp_op0, cmp_op1)); --- emit_insn (gen_slt_compare (tmp, GEN_INT (0), tmp)); --- } --- else --- /* This emit_insn will create corresponding 'slt/slts' insturction. */ --- emit_insn (gen_rtx_SET (tmp, gen_rtx_fmt_ee (new_code, SImode, --- cmp_op0, cmp_op1))); --- --- /* Change comparison semantic into (eq X 0) or (ne X 0) behavior --- so that cmovz or cmovn will be matched later. --- --- For reverse condition cases, we want to create a semantic that: --- (eq X 0) --> pick up "else" part --- For normal cases, we want to create a semantic that: --- (ne X 0) --> pick up "then" part --- --- Later we will have cmovz/cmovn instruction pattern to --- match corresponding behavior and output instruction. */ --- operands[1] = gen_rtx_fmt_ee (reverse ? EQ : NE, --- VOIDmode, tmp, const0_rtx); --+ case EXPAND_DONE: --+ DONE; --+ break; --+ case EXPAND_FAIL: --+ FAIL; --+ break; --+ case EXPAND_CREATE_TEMPLATE: --+ break; --+ default: --+ gcc_unreachable (); -- } --- ---create_template: --- do {} while(0); /* dummy line */ -- }) -- ---(define_insn "cmovz" --- [(set (match_operand:SI 0 "register_operand" "=r, r") --- (if_then_else:SI (eq (match_operand:SI 1 "register_operand" " r, r") --+(define_insn "cmovz" --+ [(set (match_operand:QIHISI 0 "register_operand" "=r, r") --+ (if_then_else:QIHISI (eq (match_operand:SI 1 "register_operand" " r, r") -- (const_int 0)) --- (match_operand:SI 2 "register_operand" " r, 0") --- (match_operand:SI 3 "register_operand" " 0, r")))] --+ (match_operand:QIHISI 2 "register_operand" " r, 0") --+ (match_operand:QIHISI 3 "register_operand" " 0, r")))] -- "TARGET_CMOV" -- "@ -- cmovz\t%0, %2, %1 -- cmovn\t%0, %3, %1" --- [(set_attr "type" "move") --+ [(set_attr "type" "alu") -- (set_attr "length" "4")]) -- ---(define_insn "cmovn" --- [(set (match_operand:SI 0 "register_operand" "=r, r") --- (if_then_else:SI (ne (match_operand:SI 1 "register_operand" " r, r") --+(define_insn "cmovn" --+ [(set (match_operand:QIHISI 0 "register_operand" "=r, r") --+ (if_then_else:QIHISI (ne (match_operand:SI 1 "register_operand" " r, r") -- (const_int 0)) --- (match_operand:SI 2 "register_operand" " r, 0") --- (match_operand:SI 3 "register_operand" " 0, r")))] --+ (match_operand:QIHISI 2 "register_operand" " r, 0") --+ (match_operand:QIHISI 3 "register_operand" " 0, r")))] -- "TARGET_CMOV" -- "@ -- cmovn\t%0, %2, %1 -- cmovz\t%0, %3, %1" --- [(set_attr "type" "move") --+ [(set_attr "type" "alu") -- (set_attr "length" "4")]) -- --+;; A hotfix to help RTL combiner to merge a cmovn insn and a zero_extend insn. --+;; It should be removed once after we change the expansion form of the cmovn. --+(define_insn "*cmovn_simplified_" --+ [(set (match_operand:QIHISI 0 "register_operand" "=r") --+ (if_then_else:QIHISI (match_operand:SI 1 "register_operand" "r") --+ (match_operand:QIHISI 2 "register_operand" "r") --+ (match_operand:QIHISI 3 "register_operand" "0")))] --+ "" --+ "cmovn\t%0, %2, %1" --+ [(set_attr "type" "alu")]) -- -- ;; ---------------------------------------------------------------------------- -- ;; Conditional Branch patterns --@@ -950,573 +1146,188 @@ create_template: -- (pc)))] -- "" -- { --- rtx tmp_reg; --- enum rtx_code code; --- --- code = GET_CODE (operands[0]); --- --- /* If operands[2] is (const_int 0), --- we can use beqz,bnez,bgtz,bgez,bltz,or blez instructions. --- So we have gcc generate original template rtx. */ --- if (GET_CODE (operands[2]) == CONST_INT) --- if (INTVAL (operands[2]) == 0) --- if ((code != GTU) --- && (code != GEU) --- && (code != LTU) --- && (code != LEU)) --- goto create_template; --- --- /* For other comparison, NDS32 ISA only has slt (Set-on-Less-Than) --- behavior for the comparison, we might need to generate other --- rtx patterns to achieve same semantic. */ --- switch (code) --+ enum nds32_expand_result_type result = nds32_expand_cbranch (operands); --+ switch (result) -- { --- case GT: --- case GTU: --- if (GET_CODE (operands[2]) == CONST_INT) --- { --- /* GT reg_A, const_int => !(LT reg_A, const_int + 1) */ --- tmp_reg = gen_rtx_REG (SImode, TA_REGNUM); --- --- /* We want to plus 1 into the integer value --- of operands[2] to create 'slt' instruction. --- This caculation is performed on the host machine, --- which may be 64-bit integer. --- So the meaning of caculation result may be --- different from the 32-bit nds32 target. --- --- For example: --- 0x7fffffff + 0x1 -> 0x80000000, --- this value is POSITIVE on 64-bit machine, --- but the expected value on 32-bit nds32 target --- should be NEGATIVE value. --- --- Hence, instead of using GEN_INT(), we use gen_int_mode() to --- explicitly create SImode constant rtx. */ --- operands[2] = gen_int_mode (INTVAL (operands[2]) + 1, SImode); --- --- if (code == GT) --- { --- /* GT, use slts instruction */ --- emit_insn (gen_slts_compare (tmp_reg, operands[1], operands[2])); --- } --- else --- { --- /* GTU, use slt instruction */ --- emit_insn (gen_slt_compare (tmp_reg, operands[1], operands[2])); --- } --- --- PUT_CODE (operands[0], EQ); --- operands[1] = tmp_reg; --- operands[2] = const0_rtx; --- emit_insn (gen_cbranchsi4 (operands[0], operands[1], --- operands[2], operands[3])); --- --- DONE; --- } --- else --- { --- /* GT reg_A, reg_B => LT reg_B, reg_A */ --- tmp_reg = gen_rtx_REG (SImode, TA_REGNUM); --- --- if (code == GT) --- { --- /* GT, use slts instruction */ --- emit_insn (gen_slts_compare (tmp_reg, operands[2], operands[1])); --- } --- else --- { --- /* GTU, use slt instruction */ --- emit_insn (gen_slt_compare (tmp_reg, operands[2], operands[1])); --- } --- --- PUT_CODE (operands[0], NE); --- operands[1] = tmp_reg; --- operands[2] = const0_rtx; --- emit_insn (gen_cbranchsi4 (operands[0], operands[1], --- operands[2], operands[3])); --- --- DONE; --- } --- --- case GE: --- case GEU: --- /* GE reg_A, reg_B => !(LT reg_A, reg_B) */ --- /* GE reg_A, const_int => !(LT reg_A, const_int) */ --- tmp_reg = gen_rtx_REG (SImode, TA_REGNUM); --- --- if (code == GE) --- { --- /* GE, use slts instruction */ --- emit_insn (gen_slts_compare (tmp_reg, operands[1], operands[2])); --- } --- else --- { --- /* GEU, use slt instruction */ --- emit_insn (gen_slt_compare (tmp_reg, operands[1], operands[2])); --- } --- --- PUT_CODE (operands[0], EQ); --- operands[1] = tmp_reg; --- operands[2] = const0_rtx; --- emit_insn (gen_cbranchsi4 (operands[0], operands[1], --- operands[2], operands[3])); --- --+ case EXPAND_DONE: -- DONE; --- --- case LT: --- case LTU: --- /* LT reg_A, reg_B => LT reg_A, reg_B */ --- /* LT reg_A, const_int => LT reg_A, const_int */ --- tmp_reg = gen_rtx_REG (SImode, TA_REGNUM); --- --- if (code == LT) --- { --- /* LT, use slts instruction */ --- emit_insn (gen_slts_compare (tmp_reg, operands[1], operands[2])); --- } --- else --- { --- /* LTU, use slt instruction */ --- emit_insn (gen_slt_compare (tmp_reg, operands[1], operands[2])); --- } --- --- PUT_CODE (operands[0], NE); --- operands[1] = tmp_reg; --- operands[2] = const0_rtx; --- emit_insn (gen_cbranchsi4 (operands[0], operands[1], --- operands[2], operands[3])); --- --- DONE; --- --- case LE: --- case LEU: --- if (GET_CODE (operands[2]) == CONST_INT) --- { --- /* LE reg_A, const_int => LT reg_A, const_int + 1 */ --- tmp_reg = gen_rtx_REG (SImode, TA_REGNUM); --- --- /* Note that (le:SI X INT_MAX) is not the same as (lt:SI X INT_MIN). --- We better have an assert here in case GCC does not properly --- optimize it away. The INT_MAX here is 0x7fffffff for target. */ --- gcc_assert (code != LE || INTVAL (operands[2]) != 0x7fffffff); --- operands[2] = gen_int_mode (INTVAL (operands[2]) + 1, SImode); --- --- if (code == LE) --- { --- /* LE, use slts instruction */ --- emit_insn (gen_slts_compare (tmp_reg, operands[1], operands[2])); --- } --- else --- { --- /* LEU, use slt instruction */ --- emit_insn (gen_slt_compare (tmp_reg, operands[1], operands[2])); --- } --- --- PUT_CODE (operands[0], NE); --- operands[1] = tmp_reg; --- operands[2] = const0_rtx; --- emit_insn (gen_cbranchsi4 (operands[0], operands[1], --- operands[2], operands[3])); --- --- DONE; --- } --- else --- { --- /* LE reg_A, reg_B => !(LT reg_B, reg_A) */ --- tmp_reg = gen_rtx_REG (SImode, TA_REGNUM); --- --- if (code == LE) --- { --- /* LE, use slts instruction */ --- emit_insn (gen_slts_compare (tmp_reg, operands[2], operands[1])); --- } --- else --- { --- /* LEU, use slt instruction */ --- emit_insn (gen_slt_compare (tmp_reg, operands[2], operands[1])); --- } --- --- PUT_CODE (operands[0], EQ); --- operands[1] = tmp_reg; --- operands[2] = const0_rtx; --- emit_insn (gen_cbranchsi4 (operands[0], operands[1], --- operands[2], operands[3])); --- --- DONE; --- } --- --- case EQ: --- case NE: --- /* NDS32 ISA has various form for eq/ne behavior no matter --- what kind of the operand is. --- So just generate original template rtx. */ --- goto create_template; --- --- default: --+ break; --+ case EXPAND_FAIL: -- FAIL; --+ break; --+ case EXPAND_CREATE_TEMPLATE: --+ break; --+ default: --+ gcc_unreachable (); -- } --- ---create_template: --- do {} while(0); /* dummy line */ -- }) -- -- ---(define_insn "*cbranchsi4_equality_zero" --+(define_insn "cbranchsi4_equality_zero" -- [(set (pc) -- (if_then_else (match_operator 0 "nds32_equality_comparison_operator" --- [(match_operand:SI 1 "register_operand" "t, l, r") --+ [(match_operand:SI 1 "register_operand" "t,l, r") -- (const_int 0)]) -- (label_ref (match_operand 2 "" "")) -- (pc)))] -- "" -- { --- enum rtx_code code; --- --- code = GET_CODE (operands[0]); --- --- /* This zero-comparison conditional branch has two forms: --- 32-bit instruction => beqz/bnez imm16s << 1 --- 16-bit instruction => beqzs8/bnezs8/beqz38/bnez38 imm8s << 1 --- --- For 32-bit case, --- we assume it is always reachable. (but check range -65500 ~ 65500) --- --- For 16-bit case, --- it must satisfy { 255 >= (label - pc) >= -256 } condition. --- However, since the $pc for nds32 is at the beginning of the instruction, --- we should leave some length space for current insn. --- So we use range -250 ~ 250. */ --- --- switch (get_attr_length (insn)) --- { --- case 2: --- if (which_alternative == 0) --- { --- /* constraint: t */ --- return (code == EQ) ? "beqzs8\t%2" : "bnezs8\t%2"; --- } --- else if (which_alternative == 1) --- { --- /* constraint: l */ --- return (code == EQ) ? "beqz38\t%1, %2" : "bnez38\t%1, %2"; --- } --- else --- { --- /* constraint: r */ --- /* For which_alternative==2, it should not be here. */ --- gcc_unreachable (); --- } --- case 4: --- /* including constraints: t, l, and r */ --- return (code == EQ) ? "beqz\t%1, %2" : "bnez\t%1, %2"; --- case 6: --- if (which_alternative == 0) --- { --- /* constraint: t */ --- if (code == EQ) --- { --- /* beqzs8 .L0 --- => --- bnezs8 .LCB0 --- j .L0 --- .LCB0: --- */ --- return "bnezs8\t.LCB%=\;j\t%2\n.LCB%=:"; --- } --- else --- { --- /* bnezs8 .L0 --- => --- beqzs8 .LCB0 --- j .L0 --- .LCB0: --- */ --- return "beqzs8\t.LCB%=\;j\t%2\n.LCB%=:"; --- } --- } --- else if (which_alternative == 1) --- { --- /* constraint: l */ --- if (code == EQ) --- { --- /* beqz38 $r0, .L0 --- => --- bnez38 $r0, .LCB0 --- j .L0 --- .LCB0: --- */ --- return "bnez38\t%1, .LCB%=\;j\t%2\n.LCB%=:"; --- } --- else --- { --- /* bnez38 $r0, .L0 --- => --- beqz38 $r0, .LCB0 --- j .L0 --- .LCB0: --- */ --- return "beqz38\t%1, .LCB%=\;j\t%2\n.LCB%=:"; --- } --- } --- else --- { --- /* constraint: r */ --- /* For which_alternative==2, it should not be here. */ --- gcc_unreachable (); --- } --- case 8: --- /* constraint: t, l, r. */ --- if (code == EQ) --- { --- /* beqz $r8, .L0 --- => --- bnez $r8, .LCB0 --- j .L0 --- .LCB0: --- */ --- return "bnez\t%1, .LCB%=\;j\t%2\n.LCB%=:"; --- } --- else --- { --- /* bnez $r8, .L0 --- => --- beqz $r8, .LCB0 --- j .L0 --- .LCB0: --- */ --- return "beqz\t%1, .LCB%=\;j\t%2\n.LCB%=:"; --- } --- default: --- gcc_unreachable (); --- } --+ return nds32_output_cbranchsi4_equality_zero (insn, operands); -- } -- [(set_attr "type" "branch") --- (set_attr "enabled" "1") --+ (set_attr_alternative "enabled" --+ [ --+ ;; Alternative 0 --+ (if_then_else (match_test "TARGET_16_BIT") --+ (const_string "yes") --+ (const_string "no")) --+ ;; Alternative 1 --+ (if_then_else (match_test "TARGET_16_BIT") --+ (const_string "yes") --+ (const_string "no")) --+ ;; Alternative 2 --+ (const_string "yes") --+ ]) -- (set_attr_alternative "length" -- [ -- ;; Alternative 0 --- (if_then_else (and (ge (minus (match_dup 2) (pc)) (const_int -250)) --- (le (minus (match_dup 2) (pc)) (const_int 250))) --- (if_then_else (match_test "TARGET_16_BIT") --- (const_int 2) --- (const_int 4)) --- (if_then_else (and (ge (minus (match_dup 2) (pc)) (const_int -65500)) --- (le (minus (match_dup 2) (pc)) (const_int 65500))) --- (const_int 4) --+ (if_then_else (match_test "!CROSSING_JUMP_P (insn)") --+ (if_then_else (and (ge (minus (match_dup 2) (pc)) (const_int -250)) --+ (le (minus (match_dup 2) (pc)) (const_int 250))) -- (if_then_else (match_test "TARGET_16_BIT") --- (const_int 6) --- (const_int 8)))) --+ (const_int 2) --+ (const_int 4)) --+ (if_then_else (and (ge (minus (match_dup 2) (pc)) (const_int -65500)) --+ (le (minus (match_dup 2) (pc)) (const_int 65500))) --+ (const_int 4) --+ (if_then_else (match_test "TARGET_16_BIT") --+ (const_int 8) --+ (const_int 10)))) --+ (const_int 10)) -- ;; Alternative 1 --- (if_then_else (and (ge (minus (match_dup 2) (pc)) (const_int -250)) --- (le (minus (match_dup 2) (pc)) (const_int 250))) --- (if_then_else (match_test "TARGET_16_BIT") --- (const_int 2) --- (const_int 4)) --+ (if_then_else (match_test "!CROSSING_JUMP_P (insn)") --+ (if_then_else (and (ge (minus (match_dup 2) (pc)) (const_int -250)) --+ (le (minus (match_dup 2) (pc)) (const_int 250))) --+ (if_then_else (match_test "TARGET_16_BIT") --+ (const_int 2) --+ (const_int 4)) --+ (if_then_else (and (ge (minus (match_dup 2) (pc)) (const_int -65500)) --+ (le (minus (match_dup 2) (pc)) (const_int 65500))) --+ (const_int 4) --+ (if_then_else (match_test "TARGET_16_BIT") --+ (const_int 8) --+ (const_int 10)))) --+ (const_int 10)) --+ ;; Alternative 2 --+ (if_then_else (match_test "!CROSSING_JUMP_P (insn)") -- (if_then_else (and (ge (minus (match_dup 2) (pc)) (const_int -65500)) -- (le (minus (match_dup 2) (pc)) (const_int 65500))) -- (const_int 4) --- (if_then_else (match_test "TARGET_16_BIT") --- (const_int 6) --- (const_int 8)))) --- ;; Alternative 2 --- (if_then_else (and (ge (minus (match_dup 2) (pc)) (const_int -65500)) --- (le (minus (match_dup 2) (pc)) (const_int 65500))) --- (const_int 4) --- (const_int 8)) --+ (const_int 10)) --+ (const_int 10)) -- ])]) -- -- -- ;; This pattern is dedicated to V2 ISA, -- ;; because V2 DOES NOT HAVE beqc/bnec instruction. ---(define_insn "*cbranchsi4_equality_reg" --+(define_insn "cbranchsi4_equality_reg" -- [(set (pc) -- (if_then_else (match_operator 0 "nds32_equality_comparison_operator" --- [(match_operand:SI 1 "register_operand" "r") --- (match_operand:SI 2 "nds32_reg_constant_operand" "r")]) --+ [(match_operand:SI 1 "register_operand" "v, r") --+ (match_operand:SI 2 "register_operand" "l, r")]) -- (label_ref (match_operand 3 "" "")) -- (pc)))] -- "TARGET_ISA_V2" -- { --- enum rtx_code code; --- --- code = GET_CODE (operands[0]); --- --- /* This register-comparison conditional branch has one form: --- 32-bit instruction => beq/bne imm14s << 1 --- --- For 32-bit case, --- we assume it is always reachable. (but check range -16350 ~ 16350). */ --- --- switch (code) --- { --- case EQ: --- /* r, r */ --- switch (get_attr_length (insn)) --- { --- case 4: --- return "beq\t%1, %2, %3"; --- case 8: --- /* beq $r0, $r1, .L0 --- => --- bne $r0, $r1, .LCB0 --- j .L0 --- .LCB0: --- */ --- return "bne\t%1, %2, .LCB%=\;j\t%3\n.LCB%=:"; --- default: --- gcc_unreachable (); --- } --- --- case NE: --- /* r, r */ --- switch (get_attr_length (insn)) --- { --- case 4: --- return "bne\t%1, %2, %3"; --- case 8: --- /* bne $r0, $r1, .L0 --- => --- beq $r0, $r1, .LCB0 --- j .L0 --- .LCB0: --- */ --- return "beq\t%1, %2, .LCB%=\;j\t%3\n.LCB%=:"; --- default: --- gcc_unreachable (); --- } --- --- default: --- gcc_unreachable (); --- } --+ return nds32_output_cbranchsi4_equality_reg (insn, operands); -- } -- [(set_attr "type" "branch") --- (set (attr "length") --- (if_then_else (and (ge (minus (match_dup 3) (pc)) (const_int -16350)) --- (le (minus (match_dup 3) (pc)) (const_int 16350))) --- (const_int 4) --- (const_int 8)))]) --+ (set_attr_alternative "enabled" --+ [ --+ ;; Alternative 0 --+ (if_then_else (match_test "TARGET_16_BIT") --+ (const_string "yes") --+ (const_string "no")) --+ ;; Alternative 1 --+ (const_string "yes") --+ ]) --+ (set_attr_alternative "length" --+ [ --+ ;; Alternative 0 --+ (if_then_else (match_test "!CROSSING_JUMP_P (insn)") --+ (if_then_else (and (ge (minus (match_dup 3) (pc)) (const_int -250)) --+ (le (minus (match_dup 3) (pc)) (const_int 250))) --+ (const_int 2) --+ (if_then_else (and (ge (minus (match_dup 3) (pc)) --+ (const_int -16350)) --+ (le (minus (match_dup 3) (pc)) --+ (const_int 16350))) --+ (const_int 4) --+ (const_int 8))) --+ (const_int 8)) --+ ;; Alternative 1 --+ (if_then_else (match_test "!CROSSING_JUMP_P (insn)") --+ (if_then_else (and (ge (minus (match_dup 3) (pc)) (const_int -16350)) --+ (le (minus (match_dup 3) (pc)) (const_int 16350))) --+ (const_int 4) --+ (const_int 10)) --+ (const_int 10)) --+ ])]) -- -- -- ;; This pattern is dedicated to V3/V3M, -- ;; because V3/V3M DO HAVE beqc/bnec instruction. ---(define_insn "*cbranchsi4_equality_reg_or_const_int" --+(define_insn "cbranchsi4_equality_reg_or_const_int" -- [(set (pc) -- (if_then_else (match_operator 0 "nds32_equality_comparison_operator" --- [(match_operand:SI 1 "register_operand" "r, r") --- (match_operand:SI 2 "nds32_reg_constant_operand" "r, Is11")]) --+ [(match_operand:SI 1 "register_operand" "v, r, r") --+ (match_operand:SI 2 "nds32_rimm11s_operand" "l, r, Is11")]) -- (label_ref (match_operand 3 "" "")) -- (pc)))] -- "TARGET_ISA_V3 || TARGET_ISA_V3M" -- { --- enum rtx_code code; --- --- code = GET_CODE (operands[0]); --- --- /* This register-comparison conditional branch has one form: --- 32-bit instruction => beq/bne imm14s << 1 --- 32-bit instruction => beqc/bnec imm8s << 1 --- --- For 32-bit case, we assume it is always reachable. --- (but check range -16350 ~ 16350 and -250 ~ 250). */ --- --- switch (code) --- { --- case EQ: --- if (which_alternative == 0) --- { --- /* r, r */ --- switch (get_attr_length (insn)) --- { --- case 4: --- return "beq\t%1, %2, %3"; --- case 8: --- /* beq $r0, $r1, .L0 --- => --- bne $r0, $r1, .LCB0 --- j .L0 --- .LCB0: --- */ --- return "bne\t%1, %2, .LCB%=\;j\t%3\n.LCB%=:"; --- default: --- gcc_unreachable (); --- } --- } --- else --- { --- /* r, Is11 */ --- switch (get_attr_length (insn)) --- { --- case 4: --- return "beqc\t%1, %2, %3"; --- case 8: --- /* beqc $r0, constant, .L0 --- => --- bnec $r0, constant, .LCB0 --- j .L0 --- .LCB0: --- */ --- return "bnec\t%1, %2, .LCB%=\;j\t%3\n.LCB%=:"; --- default: --- gcc_unreachable (); --- } --- } --- case NE: --- if (which_alternative == 0) --- { --- /* r, r */ --- switch (get_attr_length (insn)) --- { --- case 4: --- return "bne\t%1, %2, %3"; --- case 8: --- /* bne $r0, $r1, .L0 --- => --- beq $r0, $r1, .LCB0 --- j .L0 --- .LCB0: --- */ --- return "beq\t%1, %2, .LCB%=\;j\t%3\n.LCB%=:"; --- default: --- gcc_unreachable (); --- } --- } --- else --- { --- /* r, Is11 */ --- switch (get_attr_length (insn)) --- { --- case 4: --- return "bnec\t%1, %2, %3"; --- case 8: --- /* bnec $r0, constant, .L0 --- => --- beqc $r0, constant, .LCB0 --- j .L0 --- .LCB0: --- */ --- return "beqc\t%1, %2, .LCB%=\;j\t%3\n.LCB%=:"; --- default: --- gcc_unreachable (); --- } --- } --- default: --- gcc_unreachable (); --- } --+ return nds32_output_cbranchsi4_equality_reg_or_const_int (insn, operands); -- } -- [(set_attr "type" "branch") --+ (set_attr_alternative "enabled" --+ [ --+ ;; Alternative 0 --+ (if_then_else (match_test "TARGET_16_BIT") --+ (const_string "yes") --+ (const_string "no")) --+ ;; Alternative 1 --+ (const_string "yes") --+ ;; Alternative 2 --+ (const_string "yes") --+ ]) -- (set_attr_alternative "length" -- [ -- ;; Alternative 0 --- (if_then_else (and (ge (minus (match_dup 3) (pc)) (const_int -16350)) --- (le (minus (match_dup 3) (pc)) (const_int 16350))) --- (const_int 4) --- (const_int 8)) --+ (if_then_else (match_test "!CROSSING_JUMP_P (insn)") --+ (if_then_else (and (ge (minus (match_dup 3) (pc)) (const_int -250)) --+ (le (minus (match_dup 3) (pc)) (const_int 250))) --+ (const_int 2) --+ (if_then_else (and (ge (minus (match_dup 3) (pc)) --+ (const_int -16350)) --+ (le (minus (match_dup 3) (pc)) --+ (const_int 16350))) --+ (const_int 4) --+ (const_int 8))) --+ (const_int 8)) -- ;; Alternative 1 --- (if_then_else (and (ge (minus (match_dup 3) (pc)) (const_int -250)) --- (le (minus (match_dup 3) (pc)) (const_int 250))) --- (const_int 4) --- (const_int 8)) --+ (if_then_else (match_test "!CROSSING_JUMP_P (insn)") --+ (if_then_else (and (ge (minus (match_dup 3) (pc)) (const_int -16350)) --+ (le (minus (match_dup 3) (pc)) (const_int 16350))) --+ (const_int 4) --+ (const_int 10)) --+ (const_int 10)) --+ ;; Alternative 2 --+ (if_then_else (match_test "!CROSSING_JUMP_P (insn)") --+ (if_then_else (and (ge (minus (match_dup 3) (pc)) (const_int -250)) --+ (le (minus (match_dup 3) (pc)) (const_int 250))) --+ (const_int 4) --+ (const_int 10)) --+ (const_int 10)) -- ])]) -- -- --@@ -1529,80 +1340,16 @@ create_template: -- (pc)))] -- "" -- { --- enum rtx_code code; --- --- code = GET_CODE (operands[0]); --- --- /* This zero-greater-less-comparison conditional branch has one form: --- 32-bit instruction => bgtz/bgez/bltz/blez imm16s << 1 --- --- For 32-bit case, we assume it is always reachable. --- (but check range -65500 ~ 65500). */ --- --- if (get_attr_length (insn) == 8) --- { --- /* The branch target is too far to simply use one --- bgtz/bgez/bltz/blez instruction. --- We need to reverse condition and use 'j' to jump to the target. */ --- switch (code) --- { --- case GT: --- /* bgtz $r8, .L0 --- => --- blez $r8, .LCB0 --- j .L0 --- .LCB0: --- */ --- return "blez\t%1, .LCB%=\;j\t%2\n.LCB%=:"; --- case GE: --- /* bgez $r8, .L0 --- => --- bltz $r8, .LCB0 --- j .L0 --- .LCB0: --- */ --- return "bltz\t%1, .LCB%=\;j\t%2\n.LCB%=:"; --- case LT: --- /* bltz $r8, .L0 --- => --- bgez $r8, .LCB0 --- j .L0 --- .LCB0: --- */ --- return "bgez\t%1, .LCB%=\;j\t%2\n.LCB%=:"; --- case LE: --- /* blez $r8, .L0 --- => --- bgtz $r8, .LCB0 --- j .L0 --- .LCB0: --- */ --- return "bgtz\t%1, .LCB%=\;j\t%2\n.LCB%=:"; --- default: --- gcc_unreachable (); --- } --- } --- --- switch (code) --- { --- case GT: --- return "bgtz\t%1, %2"; --- case GE: --- return "bgez\t%1, %2"; --- case LT: --- return "bltz\t%1, %2"; --- case LE: --- return "blez\t%1, %2"; --- default: --- gcc_unreachable (); --- } --+ return nds32_output_cbranchsi4_greater_less_zero (insn, operands); -- } -- [(set_attr "type" "branch") -- (set (attr "length") --- (if_then_else (and (ge (minus (match_dup 2) (pc)) (const_int -65500)) --- (le (minus (match_dup 2) (pc)) (const_int 65500))) --- (const_int 4) --- (const_int 8)))]) --+ (if_then_else (match_test "!CROSSING_JUMP_P (insn)") --+ (if_then_else (and (ge (minus (match_dup 2) (pc)) (const_int -65500)) --+ (le (minus (match_dup 2) (pc)) (const_int 65500))) --+ (const_int 4) --+ (const_int 10)) --+ (const_int 10)))]) -- -- -- (define_expand "cstoresi4" --@@ -1612,237 +1359,85 @@ create_template: -- (match_operand:SI 3 "nonmemory_operand" "")]))] -- "" -- { --- rtx tmp_reg; --- enum rtx_code code; --- --- code = GET_CODE (operands[1]); --- --- switch (code) --+ enum nds32_expand_result_type result = nds32_expand_cstore (operands); --+ switch (result) -- { --- case EQ: --- if (GET_CODE (operands[3]) == CONST_INT) --- { --- /* reg_R = (reg_A == const_int_B) --- --> addi reg_C, reg_A, -const_int_B --- slti reg_R, reg_C, const_int_1 */ --- tmp_reg = gen_reg_rtx (SImode); --- operands[3] = gen_int_mode (-INTVAL (operands[3]), SImode); --- /* If the integer value is not in the range of imm15s, --- we need to force register first because our addsi3 pattern --- only accept nds32_rimm15s_operand predicate. */ --- if (!satisfies_constraint_Is15 (operands[3])) --- operands[3] = force_reg (SImode, operands[3]); --- emit_insn (gen_addsi3 (tmp_reg, operands[2], operands[3])); --- emit_insn (gen_slt_compare (operands[0], tmp_reg, const1_rtx)); --- --- DONE; --- } --- else --- { --- /* reg_R = (reg_A == reg_B) --- --> xor reg_C, reg_A, reg_B --- slti reg_R, reg_C, const_int_1 */ --- tmp_reg = gen_reg_rtx (SImode); --- emit_insn (gen_xorsi3 (tmp_reg, operands[2], operands[3])); --- emit_insn (gen_slt_compare (operands[0], tmp_reg, const1_rtx)); --- --- DONE; --- } --- --- case NE: --- if (GET_CODE (operands[3]) == CONST_INT) --- { --- /* reg_R = (reg_A != const_int_B) --- --> addi reg_C, reg_A, -const_int_B --- slti reg_R, const_int_0, reg_C */ --- tmp_reg = gen_reg_rtx (SImode); --- operands[3] = gen_int_mode (-INTVAL (operands[3]), SImode); --- /* If the integer value is not in the range of imm15s, --- we need to force register first because our addsi3 pattern --- only accept nds32_rimm15s_operand predicate. */ --- if (!satisfies_constraint_Is15 (operands[3])) --- operands[3] = force_reg (SImode, operands[3]); --- emit_insn (gen_addsi3 (tmp_reg, operands[2], operands[3])); --- emit_insn (gen_slt_compare (operands[0], const0_rtx, tmp_reg)); --- --- DONE; --- } --- else --- { --- /* reg_R = (reg_A != reg_B) --- --> xor reg_C, reg_A, reg_B --- slti reg_R, const_int_0, reg_C */ --- tmp_reg = gen_reg_rtx (SImode); --- emit_insn (gen_xorsi3 (tmp_reg, operands[2], operands[3])); --- emit_insn (gen_slt_compare (operands[0], const0_rtx, tmp_reg)); --- --- DONE; --- } --- --- case GT: --- case GTU: --- /* reg_R = (reg_A > reg_B) --> slt reg_R, reg_B, reg_A */ --- /* reg_R = (reg_A > const_int_B) --> slt reg_R, const_int_B, reg_A */ --- if (code == GT) --- { --- /* GT, use slts instruction */ --- emit_insn (gen_slts_compare (operands[0], operands[3], operands[2])); --- } --- else --- { --- /* GTU, use slt instruction */ --- emit_insn (gen_slt_compare (operands[0], operands[3], operands[2])); --- } --- --+ case EXPAND_DONE: -- DONE; --- --- case GE: --- case GEU: --- if (GET_CODE (operands[3]) == CONST_INT) --- { --- /* reg_R = (reg_A >= const_int_B) --- --> movi reg_C, const_int_B - 1 --- slt reg_R, reg_C, reg_A */ --- tmp_reg = gen_reg_rtx (SImode); --- --- emit_insn (gen_movsi (tmp_reg, --- gen_int_mode (INTVAL (operands[3]) - 1, --- SImode))); --- if (code == GE) --- { --- /* GE, use slts instruction */ --- emit_insn (gen_slts_compare (operands[0], tmp_reg, operands[2])); --- } --- else --- { --- /* GEU, use slt instruction */ --- emit_insn (gen_slt_compare (operands[0], tmp_reg, operands[2])); --- } --- --- DONE; --- } --- else --- { --- /* reg_R = (reg_A >= reg_B) --- --> slt reg_R, reg_A, reg_B --- xori reg_R, reg_R, const_int_1 */ --- if (code == GE) --- { --- /* GE, use slts instruction */ --- emit_insn (gen_slts_compare (operands[0], --- operands[2], operands[3])); --- } --- else --- { --- /* GEU, use slt instruction */ --- emit_insn (gen_slt_compare (operands[0], --- operands[2], operands[3])); --- } --- --- /* perform 'not' behavior */ --- emit_insn (gen_xorsi3 (operands[0], operands[0], const1_rtx)); --- --- DONE; --- } --- --- case LT: --- case LTU: --- /* reg_R = (reg_A < reg_B) --> slt reg_R, reg_A, reg_B */ --- /* reg_R = (reg_A < const_int_B) --> slt reg_R, reg_A, const_int_B */ --- if (code == LT) --- { --- /* LT, use slts instruction */ --- emit_insn (gen_slts_compare (operands[0], operands[2], operands[3])); --- } --- else --- { --- /* LTU, use slt instruction */ --- emit_insn (gen_slt_compare (operands[0], operands[2], operands[3])); --- } --- --- DONE; --- --- case LE: --- case LEU: --- if (GET_CODE (operands[3]) == CONST_INT) --- { --- /* reg_R = (reg_A <= const_int_B) --- --> movi reg_C, const_int_B + 1 --- slt reg_R, reg_A, reg_C */ --- tmp_reg = gen_reg_rtx (SImode); --- --- emit_insn (gen_movsi (tmp_reg, --- gen_int_mode (INTVAL (operands[3]) + 1, --- SImode))); --- if (code == LE) --- { --- /* LE, use slts instruction */ --- emit_insn (gen_slts_compare (operands[0], operands[2], tmp_reg)); --- } --- else --- { --- /* LEU, use slt instruction */ --- emit_insn (gen_slt_compare (operands[0], operands[2], tmp_reg)); --- } --- --- DONE; --- } --- else --- { --- /* reg_R = (reg_A <= reg_B) --> slt reg_R, reg_B, reg_A --- xori reg_R, reg_R, const_int_1 */ --- if (code == LE) --- { --- /* LE, use slts instruction */ --- emit_insn (gen_slts_compare (operands[0], --- operands[3], operands[2])); --- } --- else --- { --- /* LEU, use slt instruction */ --- emit_insn (gen_slt_compare (operands[0], --- operands[3], operands[2])); --- } --- --- /* perform 'not' behavior */ --- emit_insn (gen_xorsi3 (operands[0], operands[0], const1_rtx)); --- --- DONE; --- } --- --- --+ break; --+ case EXPAND_FAIL: --+ FAIL; --+ break; --+ case EXPAND_CREATE_TEMPLATE: --+ break; -- default: -- gcc_unreachable (); -- } -- }) -- -- ---(define_insn "slts_compare" --- [(set (match_operand:SI 0 "register_operand" "=t, t, r, r") --- (lt:SI (match_operand:SI 1 "nonmemory_operand" " d, d, r, r") --- (match_operand:SI 2 "nonmemory_operand" " r, Iu05, r, Is15")))] --+(define_expand "slts_compare" --+ [(set (match_operand:SI 0 "register_operand" "") --+ (lt:SI (match_operand:SI 1 "general_operand" "") --+ (match_operand:SI 2 "general_operand" "")))] --+ "" --+{ --+ if (!REG_P (operands[1])) --+ operands[1] = force_reg (SImode, operands[1]); --+ --+ if (!REG_P (operands[2]) && !satisfies_constraint_Is15 (operands[2])) --+ operands[2] = force_reg (SImode, operands[2]); --+}) --+ --+(define_insn "slts_compare_impl" --+ [(set (match_operand:SI 0 "register_operand" "=t, t, r, r") --+ (lt:SI (match_operand:SI 1 "register_operand" " d, d, r, r") --+ (match_operand:SI 2 "nds32_rimm15s_operand" " r,Iu05, r, Is15")))] -- "" -- "@ -- slts45\t%1, %2 -- sltsi45\t%1, %2 -- slts\t%0, %1, %2 -- sltsi\t%0, %1, %2" --- [(set_attr "type" "compare,compare,compare,compare") --- (set_attr "length" " 2, 2, 4, 4")]) --+ [(set_attr "type" "alu, alu, alu, alu") --+ (set_attr "length" " 2, 2, 4, 4")]) --+ --+(define_insn "slt_eq0" --+ [(set (match_operand:SI 0 "register_operand" "=t, r") --+ (eq:SI (match_operand:SI 1 "register_operand" " d, r") --+ (const_int 0)))] --+ "" --+ "@ --+ slti45\t%1, 1 --+ slti\t%0, %1, 1" --+ [(set_attr "type" "alu, alu") --+ (set_attr "length" " 2, 4")]) --+ --+(define_expand "slt_compare" --+ [(set (match_operand:SI 0 "register_operand" "") --+ (ltu:SI (match_operand:SI 1 "general_operand" "") --+ (match_operand:SI 2 "general_operand" "")))] --+ "" --+{ --+ if (!REG_P (operands[1])) --+ operands[1] = force_reg (SImode, operands[1]); -- ---(define_insn "slt_compare" --- [(set (match_operand:SI 0 "register_operand" "=t, t, r, r") --- (ltu:SI (match_operand:SI 1 "nonmemory_operand" " d, d, r, r") --- (match_operand:SI 2 "nonmemory_operand" " r, Iu05, r, Is15")))] --+ if (!REG_P (operands[2]) && !satisfies_constraint_Is15 (operands[2])) --+ operands[2] = force_reg (SImode, operands[2]); --+}) --+ --+(define_insn "slt_compare_impl" --+ [(set (match_operand:SI 0 "register_operand" "=t, t, r, r") --+ (ltu:SI (match_operand:SI 1 "register_operand" " d, d, r, r") --+ (match_operand:SI 2 "nds32_rimm15s_operand" " r,Iu05, r, Is15")))] -- "" -- "@ -- slt45\t%1, %2 -- slti45\t%1, %2 -- slt\t%0, %1, %2 -- slti\t%0, %1, %2" --- [(set_attr "type" "compare,compare,compare,compare") --- (set_attr "length" " 2, 2, 4, 4")]) --- --+ [(set_attr "type" "alu, alu, alu, alu") --+ (set_attr "length" " 2, 2, 4, 4")]) -- -- ;; ---------------------------------------------------------------------------- -- --@@ -1874,12 +1469,14 @@ create_template: -- } -- } -- [(set_attr "type" "branch") --- (set_attr "enabled" "1") --+ (set_attr "enabled" "yes") -- (set (attr "length") --- (if_then_else (and (ge (minus (match_dup 0) (pc)) (const_int -250)) --- (le (minus (match_dup 0) (pc)) (const_int 250))) --- (if_then_else (match_test "TARGET_16_BIT") --- (const_int 2) --+ (if_then_else (match_test "!CROSSING_JUMP_P (insn)") --+ (if_then_else (and (ge (minus (match_dup 0) (pc)) (const_int -250)) --+ (le (minus (match_dup 0) (pc)) (const_int 250))) --+ (if_then_else (match_test "TARGET_16_BIT") --+ (const_int 2) --+ (const_int 4)) -- (const_int 4)) -- (const_int 4)))]) -- --@@ -1887,14 +1484,27 @@ create_template: -- [(set (pc) (match_operand:SI 0 "register_operand" "r, r"))] -- "" -- "@ --- jr5\t%0 --- jr\t%0" --+ jr5\t%0 --+ jr\t%0" -- [(set_attr "type" "branch,branch") -- (set_attr "length" " 2, 4")]) -- --+(define_insn "*cond_indirect_jump" --+ [(cond_exec (ne (match_operand:SI 0 "register_operand" "r") --+ (const_int 0)) --+ (set (pc) (match_operand:SI 1 "register_operand" "0")))] --+ "" --+ "jrnez\t%0" --+ [(set_attr "type" "branch") --+ (set_attr "length" "4")]) --+ --+;; ---------------------------------------------------------------------------- --+ --+;; Normal call patterns. --+ -- ;; Subroutine call instruction returning no value. -- ;; operands[0]: It should be a mem RTX whose address is ---;; the address of the function. --+;; the the address of the function. -- ;; operands[1]: It is the number of bytes of arguments pushed as a const_int. -- ;; operands[2]: It is the number of registers used as operands. -- --@@ -1904,39 +1514,114 @@ create_template: -- (clobber (reg:SI LP_REGNUM)) -- (clobber (reg:SI TA_REGNUM))])] -- "" --- "" --+ { --+ rtx insn; --+ rtx sym = XEXP (operands[0], 0); --+ --+ if (TARGET_ICT_MODEL_LARGE --+ && nds32_indirect_call_referenced_p (sym)) --+ { --+ rtx reg = gen_reg_rtx (Pmode); --+ emit_move_insn (reg, sym); --+ operands[0] = gen_const_mem (Pmode, reg); --+ } --+ --+ if (flag_pic) --+ { --+ insn = emit_call_insn (gen_call_internal --+ (XEXP (operands[0], 0), GEN_INT (0))); --+ use_reg (&CALL_INSN_FUNCTION_USAGE (insn), pic_offset_table_rtx); --+ DONE; --+ } --+ } -- ) -- ---(define_insn "*call_register" --- [(parallel [(call (mem (match_operand:SI 0 "register_operand" "r, r")) --- (match_operand 1)) --- (clobber (reg:SI LP_REGNUM)) --- (clobber (reg:SI TA_REGNUM))])] --- "" --- "@ --- jral5\t%0 --- jral\t%0" --- [(set_attr "type" "branch,branch") --- (set_attr "length" " 2, 4")]) --- ---(define_insn "*call_immediate" --- [(parallel [(call (mem (match_operand:SI 0 "immediate_operand" "i")) --+(define_insn "call_internal" --+ [(parallel [(call (mem (match_operand:SI 0 "nds32_call_address_operand" "r, i")) -- (match_operand 1)) -- (clobber (reg:SI LP_REGNUM)) -- (clobber (reg:SI TA_REGNUM))])] -- "" -- { --- if (TARGET_CMODEL_LARGE) --- return "bal\t%0"; --- else --- return "jal\t%0"; --+ rtx_insn *next_insn = next_active_insn (insn); --+ bool align_p = (!(next_insn && get_attr_length (next_insn) == 2)) --+ && NDS32_ALIGN_P (); --+ switch (which_alternative) --+ { --+ case 0: --+ if (TARGET_16_BIT) --+ { --+ if (align_p) --+ return "jral5\t%0\;.align 2"; --+ else --+ return "jral5\t%0"; --+ } --+ else --+ { --+ if (align_p) --+ return "jral\t%0\;.align 2"; --+ else --+ return "jral\t%0"; --+ } --+ case 1: --+ return nds32_output_call (insn, operands, operands[0], --+ "bal\t%0", "jal\t%0", align_p); --+ default: --+ gcc_unreachable (); --+ } -- } --- [(set_attr "type" "branch") --- (set (attr "length") --- (if_then_else (match_test "TARGET_CMODEL_LARGE") --- (const_int 12) --- (const_int 4)))]) --+ [(set_attr "enabled" "yes") --+ (set_attr "type" "branch") --+ (set_attr_alternative "length" --+ [ --+ ;; Alternative 0 --+ (if_then_else (match_test "TARGET_16_BIT") --+ (const_int 2) --+ (const_int 4)) --+ ;; Alternative 1 --+ (if_then_else (match_test "flag_pic") --+ (const_int 16) --+ (if_then_else (match_test "nds32_long_call_p (operands[0])") --+ (const_int 12) --+ (const_int 4))) --+ ])] --+) -- --+(define_insn "*cond_call_register" --+ [(cond_exec (ne (match_operand:SI 0 "register_operand" "r") --+ (const_int 0)) --+ (parallel [(call (mem (match_operand:SI 1 "register_operand" "0")) --+ (match_operand 2)) --+ (clobber (reg:SI LP_REGNUM)) --+ (clobber (reg:SI TA_REGNUM))]))] --+ "TARGET_ISA_V3" --+ "jralnez\t%0" --+ [(set_attr "type" "branch") --+ (set_attr "length" "4")]) --+ --+(define_insn "*cond_call_immediate" --+ [(cond_exec (match_operator 0 "nds32_conditional_call_comparison_operator" --+ [(match_operand:SI 1 "register_operand" "r") --+ (const_int 0)]) --+ (parallel [(call (mem (match_operand:SI 2 "nds32_symbolic_operand" "i")) --+ (match_operand 3)) --+ (clobber (reg:SI LP_REGNUM)) --+ (clobber (reg:SI TA_REGNUM))]))] --+ "!flag_pic && !TARGET_CMODEL_LARGE --+ && nds32_indirect_call_referenced_p (operands[2])" --+{ --+ switch (GET_CODE (operands[0])) --+ { --+ case LT: --+ return "bltzal\t%1, %2"; --+ case GE: --+ return "bgezal\t%1, %2"; --+ default: --+ gcc_unreachable (); --+ } --+} --+ [(set_attr "type" "branch") --+ (set_attr "length" "4")]) -- -- ;; Subroutine call instruction returning a value. -- ;; operands[0]: It is the hard regiser in which the value is returned. --@@ -1951,49 +1636,152 @@ create_template: -- (clobber (reg:SI LP_REGNUM)) -- (clobber (reg:SI TA_REGNUM))])] -- "" --- "" --+ { --+ rtx insn; --+ rtx sym = XEXP (operands[1], 0); --+ --+ if (TARGET_ICT_MODEL_LARGE --+ && nds32_indirect_call_referenced_p (sym)) --+ { --+ rtx reg = gen_reg_rtx (Pmode); --+ emit_move_insn (reg, sym); --+ operands[1] = gen_const_mem (Pmode, reg); --+ } --+ --+ if (flag_pic) --+ { --+ insn = --+ emit_call_insn (gen_call_value_internal --+ (operands[0], XEXP (operands[1], 0), GEN_INT (0))); --+ use_reg (&CALL_INSN_FUNCTION_USAGE (insn), pic_offset_table_rtx); --+ DONE; --+ } --+ } -- ) -- ---(define_insn "*call_value_register" --+(define_insn "call_value_internal" -- [(parallel [(set (match_operand 0) --- (call (mem (match_operand:SI 1 "register_operand" "r, r")) --+ (call (mem (match_operand:SI 1 "nds32_call_address_operand" "r, i")) -- (match_operand 2))) -- (clobber (reg:SI LP_REGNUM)) -- (clobber (reg:SI TA_REGNUM))])] -- "" --- "@ --- jral5\t%1 --- jral\t%1" --- [(set_attr "type" "branch,branch") --- (set_attr "length" " 2, 4")]) --- ---(define_insn "*call_value_immediate" --- [(parallel [(set (match_operand 0) --- (call (mem (match_operand:SI 1 "immediate_operand" "i")) --- (match_operand 2))) --- (clobber (reg:SI LP_REGNUM)) --- (clobber (reg:SI TA_REGNUM))])] --- "" -- { --- if (TARGET_CMODEL_LARGE) --- return "bal\t%1"; --- else --- return "jal\t%1"; --+ rtx_insn *next_insn = next_active_insn (insn); --+ bool align_p = (!(next_insn && get_attr_length (next_insn) == 2)) --+ && NDS32_ALIGN_P (); --+ switch (which_alternative) --+ { --+ case 0: --+ if (TARGET_16_BIT) --+ { --+ if (align_p) --+ return "jral5\t%1\;.align 2"; --+ else --+ return "jral5\t%1"; --+ } --+ else --+ { --+ if (align_p) --+ return "jral\t%1\;.align 2"; --+ else --+ return "jral\t%1"; --+ } --+ case 1: --+ return nds32_output_call (insn, operands, operands[1], --+ "bal\t%1", "jal\t%1", align_p); --+ default: --+ gcc_unreachable (); --+ } --+} --+ [(set_attr "enabled" "yes") --+ (set_attr "type" "branch") --+ (set_attr_alternative "length" --+ [ --+ ;; Alternative 0 --+ (if_then_else (match_test "TARGET_16_BIT") --+ (const_int 2) --+ (const_int 4)) --+ ;; Alternative 1 --+ (if_then_else (match_test "flag_pic") --+ (const_int 16) --+ (if_then_else (match_test "nds32_long_call_p (operands[1])") --+ (const_int 12) --+ (const_int 4))) --+ ])] --+) --+ --+(define_insn "*cond_call_value_register" --+ [(cond_exec (ne (match_operand:SI 0 "register_operand" "r") --+ (const_int 0)) --+ (parallel [(set (match_operand 1) --+ (call (mem (match_operand:SI 2 "register_operand" "0")) --+ (match_operand 3))) --+ (clobber (reg:SI LP_REGNUM)) --+ (clobber (reg:SI TA_REGNUM))]))] --+ "TARGET_ISA_V3" --+ "jralnez\t%0" --+ [(set_attr "type" "branch") --+ (set_attr "length" "4")]) --+ --+(define_insn "*cond_call_value_immediate" --+ [(cond_exec (match_operator 0 "nds32_conditional_call_comparison_operator" --+ [(match_operand:SI 1 "register_operand" "r") --+ (const_int 0)]) --+ (parallel [(set (match_operand 2) --+ (call (mem (match_operand:SI 3 "nds32_symbolic_operand" "i")) --+ (match_operand 4))) --+ (clobber (reg:SI LP_REGNUM)) --+ (clobber (reg:SI TA_REGNUM))]))] --+ "!flag_pic && !TARGET_CMODEL_LARGE --+ && nds32_indirect_call_referenced_p (operands[3])" --+{ --+ switch (GET_CODE (operands[0])) --+ { --+ case LT: --+ return "bltzal\t%1, %3"; --+ case GE: --+ return "bgezal\t%1, %3"; --+ default: --+ gcc_unreachable (); --+ } -- } -- [(set_attr "type" "branch") --- (set (attr "length") --- (if_then_else (match_test "TARGET_CMODEL_LARGE") --- (const_int 12) --- (const_int 4)))]) --+ (set_attr "length" "4")]) --+ --+;; Call subroutine returning any type. --+ --+(define_expand "untyped_call" --+ [(parallel [(call (match_operand 0 "" "") --+ (const_int 0)) --+ (match_operand 1 "" "") --+ (match_operand 2 "" "")])] --+ "" --+{ --+ int i; --+ --+ emit_call_insn (gen_call (operands[0], const0_rtx)); --+ --+ for (i = 0; i < XVECLEN (operands[2], 0); i++) --+ { --+ rtx set = XVECEXP (operands[2], 0, i); --+ emit_move_insn (SET_DEST (set), SET_SRC (set)); --+ } -- --+ /* The optimizer does not know that the call sets the function value --+ registers we stored in the result block. We avoid problems by --+ claiming that all hard registers are used and clobbered at this --+ point. */ --+ emit_insn (gen_blockage ()); --+ DONE; --+}) -- -- ;; ---------------------------------------------------------------------------- -- -- ;; The sibcall patterns. -- -- ;; sibcall ---;; sibcall_register ---;; sibcall_immediate --+;; sibcall_internal -- -- (define_expand "sibcall" -- [(parallel [(call (match_operand 0 "memory_operand" "") --@@ -2001,41 +1789,60 @@ create_template: -- (clobber (reg:SI TA_REGNUM)) -- (return)])] -- "" --- "" ---) --- ---(define_insn "*sibcall_register" --- [(parallel [(call (mem (match_operand:SI 0 "register_operand" "r, r")) --- (match_operand 1)) --- (clobber (reg:SI TA_REGNUM)) --- (return)])] --- "" --- "@ --- jr5\t%0 --- jr\t%0" --- [(set_attr "type" "branch,branch") --- (set_attr "length" " 2, 4")]) --+{ --+ rtx sym = XEXP (operands[0], 0); --+ --+ if (TARGET_ICT_MODEL_LARGE --+ && nds32_indirect_call_referenced_p (sym)) --+ { --+ rtx reg = gen_reg_rtx (Pmode); --+ emit_move_insn (reg, sym); --+ operands[0] = gen_const_mem (Pmode, reg); --+ } --+}) -- ---(define_insn "*sibcall_immediate" --- [(parallel [(call (mem (match_operand:SI 0 "immediate_operand" "i")) --+(define_insn "sibcall_internal" --+ [(parallel [(call (mem (match_operand:SI 0 "nds32_call_address_operand" "r, i")) -- (match_operand 1)) -- (clobber (reg:SI TA_REGNUM)) -- (return)])] -- "" -- { --- if (TARGET_CMODEL_LARGE) --- return "b\t%0"; --- else --- return "j\t%0"; --+ switch (which_alternative) --+ { --+ case 0: --+ if (TARGET_16_BIT) --+ return "jr5\t%0"; --+ else --+ return "jr\t%0"; --+ case 1: --+ if (nds32_long_call_p (operands[0])) --+ return "b\t%0"; --+ else --+ return "j\t%0"; --+ default: --+ gcc_unreachable (); --+ } -- } --- [(set_attr "type" "branch") --- (set (attr "length") --- (if_then_else (match_test "TARGET_CMODEL_LARGE") --- (const_int 12) --- (const_int 4)))]) --+ [(set_attr "enabled" "yes") --+ (set_attr "type" "branch") --+ (set_attr_alternative "length" --+ [ --+ ;; Alternative 0 --+ (if_then_else (match_test "TARGET_16_BIT") --+ (const_int 2) --+ (const_int 4)) --+ ;; Alternative 1 --+ (if_then_else (match_test "flag_pic") --+ (const_int 16) --+ (if_then_else (match_test "nds32_long_call_p (operands[0])") --+ (const_int 12) --+ (const_int 4))) --+ ])] --+) -- -- ;; sibcall_value ---;; sibcall_value_register --+;; sibcall_value_internal -- ;; sibcall_value_immediate -- -- (define_expand "sibcall_value" --@@ -2045,73 +1852,106 @@ create_template: -- (clobber (reg:SI TA_REGNUM)) -- (return)])] -- "" --- "" ---) --- ---(define_insn "*sibcall_value_register" --- [(parallel [(set (match_operand 0) --- (call (mem (match_operand:SI 1 "register_operand" "r, r")) --- (match_operand 2))) --- (clobber (reg:SI TA_REGNUM)) --- (return)])] --- "" --- "@ --- jr5\t%1 --- jr\t%1" --- [(set_attr "type" "branch,branch") --- (set_attr "length" " 2, 4")]) --+{ --+ rtx sym = XEXP (operands[1], 0); --+ --+ if (TARGET_ICT_MODEL_LARGE --+ && nds32_indirect_call_referenced_p (sym)) --+ { --+ rtx reg = gen_reg_rtx (Pmode); --+ emit_move_insn (reg, sym); --+ operands[1] = gen_const_mem (Pmode, reg); --+ } --+}) -- ---(define_insn "*sibcall_value_immediate" --+(define_insn "sibcall_value_internal" -- [(parallel [(set (match_operand 0) --- (call (mem (match_operand:SI 1 "immediate_operand" "i")) --+ (call (mem (match_operand:SI 1 "nds32_call_address_operand" "r, i")) -- (match_operand 2))) -- (clobber (reg:SI TA_REGNUM)) -- (return)])] -- "" -- { --- if (TARGET_CMODEL_LARGE) --- return "b\t%1"; --- else --- return "j\t%1"; --+ switch (which_alternative) --+ { --+ case 0: --+ if (TARGET_16_BIT) --+ return "jr5\t%1"; --+ else --+ return "jr\t%1"; --+ case 1: --+ if (nds32_long_call_p (operands[1])) --+ return "b\t%1"; --+ else --+ return "j\t%1"; --+ default: --+ gcc_unreachable (); --+ } -- } --- [(set_attr "type" "branch") --- (set (attr "length") --- (if_then_else (match_test "TARGET_CMODEL_LARGE") --- (const_int 12) --- (const_int 4)))]) --- --+ [(set_attr "enabled" "yes") --+ (set_attr "type" "branch") --+ (set_attr_alternative "length" --+ [ --+ ;; Alternative 0 --+ (if_then_else (match_test "TARGET_16_BIT") --+ (const_int 2) --+ (const_int 4)) --+ ;; Alternative 1 --+ (if_then_else (match_test "flag_pic") --+ (const_int 16) --+ (if_then_else (match_test "nds32_long_call_p (operands[1])") --+ (const_int 12) --+ (const_int 4))) --+ ])] --+) -- -- ;; ---------------------------------------------------------------------------- -- ---;; prologue and epilogue. --+;; The prologue and epilogue. -- -- (define_expand "prologue" [(const_int 0)] -- "" -- { -- /* Note that only under V3/V3M ISA, we could use v3push prologue. --- In addition, we do not want to use v3push for isr function --- and variadic function. */ --- if (TARGET_V3PUSH --- && !nds32_isr_function_p (current_function_decl) --- && (cfun->machine->va_args_size == 0)) --+ In addition, we need to check if v3push is indeed available. */ --+ if (NDS32_V3PUSH_AVAILABLE_P) -- nds32_expand_prologue_v3push (); -- else -- nds32_expand_prologue (); --+ --+ /* If cfun->machine->fp_as_gp_p is true, we can generate special --+ directive to guide linker doing fp-as-gp optimization. --+ However, for a naked function, which means --+ it should not have prologue/epilogue, --+ using fp-as-gp still requires saving $fp by push/pop behavior and --+ there is no benefit to use fp-as-gp on such small function. --+ So we need to make sure this function is NOT naked as well. */ --+ if (cfun->machine->fp_as_gp_p && !cfun->machine->naked_p) --+ emit_insn (gen_omit_fp_begin (gen_rtx_REG (SImode, FP_REGNUM))); --+ -- DONE; -- }) -- -- (define_expand "epilogue" [(const_int 0)] -- "" -- { --+ /* If cfun->machine->fp_as_gp_p is true, we can generate special --+ directive to guide linker doing fp-as-gp optimization. --+ However, for a naked function, which means --+ it should not have prologue/epilogue, --+ using fp-as-gp still requires saving $fp by push/pop behavior and --+ there is no benefit to use fp-as-gp on such small function. --+ So we need to make sure this function is NOT naked as well. */ --+ if (cfun->machine->fp_as_gp_p && !cfun->machine->naked_p) --+ emit_insn (gen_omit_fp_end (gen_rtx_REG (SImode, FP_REGNUM))); --+ -- /* Note that only under V3/V3M ISA, we could use v3pop epilogue. --- In addition, we do not want to use v3pop for isr function --- and variadic function. */ --- if (TARGET_V3PUSH --- && !nds32_isr_function_p (current_function_decl) --- && (cfun->machine->va_args_size == 0)) --+ In addition, we need to check if v3push is indeed available. */ --+ if (NDS32_V3PUSH_AVAILABLE_P) -- nds32_expand_epilogue_v3pop (false); -- else -- nds32_expand_epilogue (false); --+ -- DONE; -- }) -- --@@ -2121,15 +1961,11 @@ create_template: -- /* Pass true to indicate that this is sibcall epilogue and -- exit from a function without the final branch back to the -- calling function. */ --- if (TARGET_V3PUSH && !nds32_isr_function_p (current_function_decl)) --- nds32_expand_epilogue_v3pop (true); --- else --- nds32_expand_epilogue (true); --+ nds32_expand_epilogue (true); -- -- DONE; -- }) -- --- -- ;; nop instruction. -- -- (define_insn "nop" --@@ -2142,7 +1978,7 @@ create_template: -- return "nop"; -- } -- [(set_attr "type" "misc") --- (set_attr "enabled" "1") --+ (set_attr "enabled" "yes") -- (set (attr "length") -- (if_then_else (match_test "TARGET_16_BIT") -- (const_int 2) --@@ -2166,12 +2002,11 @@ create_template: -- { -- return nds32_output_stack_push (operands[0]); -- } --- [(set_attr "type" "misc") --- (set_attr "enabled" "1") --+ [(set_attr "type" "store_multiple") --+ (set_attr "combo" "12") --+ (set_attr "enabled" "yes") -- (set (attr "length") --- (if_then_else (match_test "TARGET_V3PUSH --- && !nds32_isr_function_p (cfun->decl) --- && (cfun->machine->va_args_size == 0)") --+ (if_then_else (match_test "NDS32_V3PUSH_AVAILABLE_P") -- (const_int 2) -- (const_int 4)))]) -- --@@ -2188,12 +2023,11 @@ create_template: -- { -- return nds32_output_stack_pop (operands[0]); -- } --- [(set_attr "type" "misc") --- (set_attr "enabled" "1") --+ [(set_attr "type" "load_multiple") --+ (set_attr "combo" "12") --+ (set_attr "enabled" "yes") -- (set (attr "length") --- (if_then_else (match_test "TARGET_V3PUSH --- && !nds32_isr_function_p (cfun->decl) --- && (cfun->machine->va_args_size == 0)") --+ (if_then_else (match_test "NDS32_V3PUSH_AVAILABLE_P") -- (const_int 2) -- (const_int 4)))]) -- --@@ -2205,34 +2039,64 @@ create_template: -- ;; Use this pattern to expand a return instruction -- ;; with simple_return rtx if no epilogue is required. -- (define_expand "return" --- [(simple_return)] --+ [(parallel [(return) --+ (clobber (reg:SI FP_REGNUM))])] -- "nds32_can_use_return_insn ()" --- "" ---) --+{ --+ /* Emit as the simple return. */ --+ if (!cfun->machine->fp_as_gp_p --+ && cfun->machine->naked_p --+ && (cfun->machine->va_args_size == 0)) --+ { --+ emit_jump_insn (gen_return_internal ()); --+ DONE; --+ } --+}) -- -- ;; This pattern is expanded only by the shrink-wrapping optimization -- ;; on paths where the function prologue has not been executed. --+;; However, such optimization may reorder the prologue/epilogue blocks --+;; together with basic blocks within function body. --+;; So we must disable this pattern if we have already decided --+;; to perform fp_as_gp optimization, which requires prologue to be --+;; first block and epilogue to be last block. -- (define_expand "simple_return" -- [(simple_return)] --- "" --+ "!cfun->machine->fp_as_gp_p" -- "" -- ) -- --+(define_insn "*nds32_return" --+ [(parallel [(return) --+ (clobber (reg:SI FP_REGNUM))])] --+ "" --+{ --+ return nds32_output_return (); --+} --+ [(set_attr "type" "branch") --+ (set_attr "enabled" "yes") --+ (set_attr "length" "4")]) --+ -- (define_insn "return_internal" -- [(simple_return)] -- "" -- { --+ if (nds32_isr_function_critical_p (current_function_decl)) --+ return "iret"; --+ -- if (TARGET_16_BIT) -- return "ret5"; -- else -- return "ret"; -- } -- [(set_attr "type" "branch") --- (set_attr "enabled" "1") --+ (set_attr "enabled" "yes") -- (set (attr "length") --- (if_then_else (match_test "TARGET_16_BIT") --- (const_int 2) --- (const_int 4)))]) --+ (if_then_else (match_test "nds32_isr_function_critical_p (current_function_decl)") --+ (const_int 4) --+ (if_then_else (match_test "TARGET_16_BIT") --+ (const_int 2) --+ (const_int 4))))]) -- -- -- ;; ---------------------------------------------------------------------------- --@@ -2267,6 +2131,7 @@ create_template: -- { -- rtx add_tmp; -- rtx reg, test; --+ rtx tmp_reg; -- -- /* Step A: "k <-- (plus (operands[0]) (-operands[1]))". */ -- if (operands[1] != const0_rtx) --@@ -2275,8 +2140,8 @@ create_template: -- add_tmp = gen_int_mode (-INTVAL (operands[1]), SImode); -- -- /* If the integer value is not in the range of imm15s, --- we need to force register first because our addsi3 pattern --- only accept nds32_rimm15s_operand predicate. */ --+ we need to force register first because our addsi3 pattern --+ only accept nds32_rimm15s_operand predicate. */ -- add_tmp = force_reg (SImode, add_tmp); -- -- emit_insn (gen_addsi3 (reg, operands[0], add_tmp)); --@@ -2288,11 +2153,14 @@ create_template: -- emit_jump_insn (gen_cbranchsi4 (test, operands[0], operands[2], -- operands[4])); -- --- operands[5] = gen_reg_rtx (SImode); --- /* Step C, D, E, and F, using another temporary register operands[5]. */ --+ tmp_reg = gen_reg_rtx (SImode); --+ /* Step C, D, E, and F, using another temporary register tmp_reg. */ --+ if (flag_pic) --+ emit_use (pic_offset_table_rtx); --+ -- emit_jump_insn (gen_casesi_internal (operands[0], -- operands[3], --- operands[5])); --+ tmp_reg)); -- DONE; -- }) -- --@@ -2328,17 +2196,34 @@ create_template: -- else -- return nds32_output_casesi (operands); -- } --- [(set_attr "length" "20") --- (set_attr "type" "alu")]) --+ [(set_attr "type" "branch") --+ (set (attr "length") --+ (if_then_else (match_test "flag_pic") --+ (const_int 28) --+ (const_int 20)))]) -- -- ;; ---------------------------------------------------------------------------- -- -- ;; Performance Extension -- --+; If -fwrapv option is issued, GCC expects there will be --+; signed overflow situation. So the ABS(INT_MIN) is still INT_MIN --+; (e.g. ABS(0x80000000)=0x80000000). --+; However, the hardware ABS instruction of nds32 target --+; always performs saturation: abs 0x80000000 -> 0x7fffffff. --+; So that we can only enable abssi2 pattern if flag_wrapv is NOT presented. --+(define_insn "abssi2" --+ [(set (match_operand:SI 0 "register_operand" "=r") --+ (abs:SI (match_operand:SI 1 "register_operand" " r")))] --+ "TARGET_EXT_PERF && TARGET_HW_ABS && !flag_wrapv" --+ "abs\t%0, %1" --+ [(set_attr "type" "alu") --+ (set_attr "length" "4")]) --+ -- (define_insn "clzsi2" -- [(set (match_operand:SI 0 "register_operand" "=r") -- (clz:SI (match_operand:SI 1 "register_operand" " r")))] --- "TARGET_PERF_EXT" --+ "TARGET_EXT_PERF" -- "clz\t%0, %1" -- [(set_attr "type" "alu") -- (set_attr "length" "4")]) --@@ -2347,34 +2232,212 @@ create_template: -- [(set (match_operand:SI 0 "register_operand" "=r") -- (smax:SI (match_operand:SI 1 "register_operand" " r") -- (match_operand:SI 2 "register_operand" " r")))] --- "TARGET_PERF_EXT" --+ "TARGET_EXT_PERF" -- "max\t%0, %1, %2" -- [(set_attr "type" "alu") -- (set_attr "length" "4")]) -- --+(define_expand "uminqi3" --+ [(set (match_operand:QI 0 "register_operand" "") --+ (umin:QI (match_operand:QI 1 "register_operand" "") --+ (match_operand:QI 2 "register_operand" "")))] --+ "TARGET_EXT_PERF" --+{ --+ rtx tmpop[3]; --+ tmpop[0] = gen_reg_rtx (SImode); --+ tmpop[1] = gen_reg_rtx (SImode); --+ tmpop[2] = gen_reg_rtx (SImode); --+ --+ emit_insn (gen_zero_extendqisi2 (tmpop[1], operands[1])); --+ emit_insn (gen_zero_extendqisi2 (tmpop[2], operands[2])); --+ emit_insn (gen_sminsi3 (tmpop[0], tmpop[1], tmpop[2])); --+ convert_move (operands[0], tmpop[0], false); --+ DONE; --+}) --+ --+(define_expand "sminqi3" --+ [(set (match_operand:QI 0 "register_operand" "") --+ (smin:QI (match_operand:QI 1 "register_operand" "") --+ (match_operand:QI 2 "register_operand" "")))] --+ "TARGET_EXT_PERF" --+{ --+ rtx tmpop[3]; --+ tmpop[0] = gen_reg_rtx (SImode); --+ tmpop[1] = gen_reg_rtx (SImode); --+ tmpop[2] = gen_reg_rtx (SImode); --+ --+ emit_insn (gen_extendqisi2 (tmpop[1], operands[1])); --+ emit_insn (gen_extendqisi2 (tmpop[2], operands[2])); --+ emit_insn (gen_sminsi3 (tmpop[0], tmpop[1], tmpop[2])); --+ convert_move (operands[0], tmpop[0], false); --+ DONE; --+}) --+ --+(define_expand "uminhi3" --+ [(set (match_operand:HI 0 "register_operand" "") --+ (umin:HI (match_operand:HI 1 "register_operand" "") --+ (match_operand:HI 2 "register_operand" "")))] --+ "TARGET_EXT_PERF" --+{ --+ rtx tmpop[3]; --+ tmpop[0] = gen_reg_rtx (SImode); --+ tmpop[1] = gen_reg_rtx (SImode); --+ tmpop[2] = gen_reg_rtx (SImode); --+ --+ emit_insn (gen_zero_extendhisi2 (tmpop[1], operands[1])); --+ emit_insn (gen_zero_extendhisi2 (tmpop[2], operands[2])); --+ emit_insn (gen_sminsi3 (tmpop[0], tmpop[1], tmpop[2])); --+ convert_move (operands[0], tmpop[0], false); --+ DONE; --+}) --+ --+(define_expand "sminhi3" --+ [(set (match_operand:HI 0 "register_operand" "") --+ (smin:HI (match_operand:HI 1 "register_operand" "") --+ (match_operand:HI 2 "register_operand" "")))] --+ "TARGET_EXT_PERF" --+{ --+ rtx tmpop[3]; --+ tmpop[0] = gen_reg_rtx (SImode); --+ tmpop[1] = gen_reg_rtx (SImode); --+ tmpop[2] = gen_reg_rtx (SImode); --+ --+ emit_insn (gen_extendhisi2 (tmpop[1], operands[1])); --+ emit_insn (gen_extendhisi2 (tmpop[2], operands[2])); --+ emit_insn (gen_sminsi3 (tmpop[0], tmpop[1], tmpop[2])); --+ convert_move (operands[0], tmpop[0], false); --+ DONE; --+}) --+ -- (define_insn "sminsi3" -- [(set (match_operand:SI 0 "register_operand" "=r") -- (smin:SI (match_operand:SI 1 "register_operand" " r") -- (match_operand:SI 2 "register_operand" " r")))] --- "TARGET_PERF_EXT" --+ "TARGET_EXT_PERF" -- "min\t%0, %1, %2" -- [(set_attr "type" "alu") -- (set_attr "length" "4")]) -- ---(define_insn "*btst" --- [(set (match_operand:SI 0 "register_operand" "= r") --- (zero_extract:SI (match_operand:SI 1 "register_operand" " r") --+(define_insn "btst" --+ [(set (match_operand:SI 0 "register_operand" "= r") --+ (zero_extract:SI (match_operand:SI 1 "register_operand" " r") -- (const_int 1) --- (match_operand:SI 2 "immediate_operand" " Iu05")))] --- "TARGET_PERF_EXT" --+ (match_operand:SI 2 "nds32_imm5u_operand" " Iu05")))] --+ "TARGET_EXT_PERF" -- "btst\t%0, %1, %2" -- [(set_attr "type" "alu") -- (set_attr "length" "4")]) -- --+(define_insn "ave" --+ [(set (match_operand:SI 0 "register_operand" "=r") --+ (truncate:SI --+ (ashiftrt:DI --+ (plus:DI --+ (plus:DI --+ (sign_extend:DI (match_operand:SI 1 "register_operand" "r")) --+ (sign_extend:DI (match_operand:SI 2 "register_operand" "r"))) --+ (const_int 1)) --+ (const_int 1))))] --+ "TARGET_EXT_PERF" --+ "ave\t%0, %1, %2" --+ [(set_attr "type" "alu") --+ (set_attr "length" "4")]) --+ -- ;; ---------------------------------------------------------------------------- -- -- ;; Pseudo NOPs -- --+;; Structural hazards NOP --+(define_insn "nop_res_dep" --+ [(unspec [(match_operand 0 "const_int_operand" "i")] UNSPEC_VOLATILE_RES_DEP)] --+ "" --+ "! structural dependency (%0 cycles)" --+ [(set_attr "length" "0")] --+) --+ --+;; Data hazards NOP --+(define_insn "nop_data_dep" --+ [(unspec [(match_operand 0 "const_int_operand" "i")] UNSPEC_VOLATILE_DATA_DEP)] --+ "" --+ "! data dependency (%0 cycles)" --+ [(set_attr "length" "0")] --+) --+ --+(define_insn "relax_group" --+ [(unspec_volatile [(match_operand:SI 0 "immediate_operand" "i")] UNSPEC_VOLATILE_RELAX_GROUP)] --+ "" --+ ".relax_hint %0" --+ [(set_attr "length" "0")] --+) --+ --+(define_insn "innermost_loop_begin" --+ [(unspec_volatile:SI [(const_int 0)] UNSPEC_VOLATILE_INNERMOST_LOOP_BEGIN)] --+ "" --+ ".innermost_loop_begin" --+ [(set_attr "length" "0")] --+) --+ --+(define_insn "innermost_loop_end" --+ [(unspec_volatile:SI [(const_int 0)] UNSPEC_VOLATILE_INNERMOST_LOOP_END)] --+ "" --+ ".innermost_loop_end" --+ [(set_attr "length" "0")] --+) --+ --+(define_insn "no_ifc_begin" --+ [(unspec_volatile:SI [(const_int 0)] UNSPEC_VOLATILE_NO_IFC_BEGIN)] --+ "" --+ ".no_ifc_begin" --+ [(set_attr "length" "0")] --+) --+ --+(define_insn "no_ifc_end" --+ [(unspec_volatile:SI [(const_int 0)] UNSPEC_VOLATILE_NO_IFC_END)] --+ "" --+ ".no_ifc_end" --+ [(set_attr "length" "0")] --+) --+ --+(define_insn "no_ex9_begin" --+ [(unspec_volatile:SI [(const_int 0)] UNSPEC_VOLATILE_NO_EX9_BEGIN)] --+ "" --+ ".no_ex9_begin" --+ [(set_attr "length" "0")] --+) --+ --+(define_insn "no_ex9_end" --+ [(unspec_volatile:SI [(const_int 0)] UNSPEC_VOLATILE_NO_EX9_END)] --+ "" --+ ".no_ex9_end" --+ [(set_attr "length" "0")] --+) --+ --+(define_insn "hwloop_last_insn" --+ [(unspec_volatile:SI [(const_int 0)] UNSPEC_VOLATILE_HWLOOP_LAST_INSN)] --+ "" --+ "" --+ [(set_attr "length" "0")] --+) --+ --+;; Output .omit_fp_begin for fp-as-gp optimization. --+;; Also we have to set $fp register. --+(define_insn "omit_fp_begin" --+ [(set (match_operand:SI 0 "register_operand" "=x") --+ (unspec_volatile:SI [(const_int 0)] UNSPEC_VOLATILE_OMIT_FP_BEGIN))] --+ "" --+ "! -----\;.omit_fp_begin\;la\t$fp,_FP_BASE_\;! -----" --+ [(set_attr "length" "8")] --+) --+ --+;; Output .omit_fp_end for fp-as-gp optimization. --+;; Claim that we have to use $fp register. --+(define_insn "omit_fp_end" --+ [(unspec_volatile:SI [(match_operand:SI 0 "register_operand" "x")] UNSPEC_VOLATILE_OMIT_FP_END)] --+ "" --+ "! -----\;.omit_fp_end\;! -----" --+ [(set_attr "length" "0")] --+) --+ -- (define_insn "pop25return" -- [(return) -- (unspec_volatile:SI [(reg:SI LP_REGNUM)] UNSPEC_VOLATILE_POP25_RETURN)] --@@ -2383,4 +2446,262 @@ create_template: -- [(set_attr "length" "0")] -- ) -- --+;; Add pc --+(define_insn "add_pc" --+ [(set (match_operand:SI 0 "register_operand" "=r") --+ (plus:SI (match_operand:SI 1 "register_operand" "0") --+ (pc)))] --+ "TARGET_LINUX_ABI || flag_pic" --+ "add5.pc\t%0" --+ [(set_attr "type" "alu") --+ (set_attr "length" "4")] --+) --+ --+(define_expand "bswapsi2" --+ [(set (match_operand:SI 0 "register_operand" "=r") --+ (bswap:SI (match_operand:SI 1 "register_operand" "r")))] --+ "" --+{ --+ emit_insn (gen_unspec_wsbh (operands[0], operands[1])); --+ emit_insn (gen_rotrsi3 (operands[0], operands[0], GEN_INT (16))); --+ DONE; --+}) --+ --+(define_insn "bswaphi2" --+ [(set (match_operand:HI 0 "register_operand" "=r") --+ (bswap:HI (match_operand:HI 1 "register_operand" "r")))] --+ "" --+ "wsbh\t%0, %1" --+ [(set_attr "type" "alu") --+ (set_attr "length" "4")] --+) --+ --+;; Hardware loop --+ --+; operand 0 is the loop count pseudo register --+; operand 1 is the label to jump to at the top of the loop --+(define_expand "doloop_end" --+ [(parallel [(set (pc) (if_then_else --+ (ne (match_operand:SI 0 "" "") --+ (const_int 1)) --+ (label_ref (match_operand 1 "" "")) --+ (pc))) --+ (set (match_dup 0) --+ (plus:SI (match_dup 0) --+ (const_int -1))) --+ (unspec [(const_int 0)] UNSPEC_LOOP_END) --+ (clobber (match_dup 2))])] ; match_scratch --+ "NDS32_HW_LOOP_P ()" --+{ --+ /* The loop optimizer doesn't check the predicates... */ --+ if (GET_MODE (operands[0]) != SImode) --+ FAIL; --+ operands[2] = gen_rtx_SCRATCH (SImode); --+}) --+ --+(define_insn "loop_end" --+ [(set (pc) --+ (if_then_else (ne (match_operand:SI 3 "nonimmediate_operand" "0, 0, *r, 0") --+ (const_int 1)) --+ (label_ref (match_operand 1 "" "")) --+ (pc))) --+ (set (match_operand:SI 0 "nonimmediate_operand" "=r, m, m, *f") --+ (plus:SI (match_dup 3) --+ (const_int -1))) --+ (unspec [(const_int 0)] UNSPEC_LOOP_END) --+ (clobber (match_scratch:SI 2 "=X, &r, &r, &r"))] --+ "NDS32_HW_LOOP_P ()" --+ "#" --+ [(set_attr "length" "12, 12, 12, 12")]) --+ --+(define_split --+ [(set (pc) --+ (if_then_else (ne (match_operand:SI 3 "nonimmediate_operand" "") --+ (const_int 1)) --+ (label_ref (match_operand 1 "" "")) --+ (pc))) --+ (set (match_operand:SI 0 "fpu_reg_or_memory_operand" "") --+ (plus:SI (match_dup 3) --+ (const_int -1))) --+ (unspec [(const_int 0)] UNSPEC_LOOP_END) --+ (clobber (match_scratch:SI 2 ""))] --+ "NDS32_HW_LOOP_P ()" --+ [(set (match_dup 2) (plus:SI (match_dup 3) (const_int -1))) --+ (set (match_dup 0) (match_dup 2)) --+ (set (pc) --+ (if_then_else (ne (match_dup 2) (const_int 0)) --+ (label_ref (match_dup 1)) --+ (pc)))] --+{ --+ if (fpu_reg_or_memory_operand (operands[3], SImode)) --+ { --+ emit_move_insn (operands[2], operands[3]); --+ operands[3] = operands[2]; --+ } --+}) --+ --+(define_insn "mtlbi_hint" --+ [(set (reg:SI LB_REGNUM) --+ (match_operand:SI 0 "nds32_label_operand" "i")) --+ (unspec [(match_operand 1 "const_int_operand" "i")] UNSPEC_LOOP_END)] --+ "NDS32_HW_LOOP_P ()" --+ "mtlbi\t%0" --+ [(set_attr "length" "4")]) --+ --+(define_insn "mtlbi" --+ [(set (reg:SI LB_REGNUM) --+ (match_operand:SI 0 "nds32_label_operand" "i"))] --+ "NDS32_HW_LOOP_P ()" --+ "mtlbi\t%0" --+ [(set_attr "length" "4")]) --+ --+(define_insn "mtlei" --+ [(set (reg:SI LE_REGNUM) --+ (match_operand:SI 0 "nds32_label_operand" "i"))] --+ "NDS32_HW_LOOP_P ()" --+ "mtlei\t%0" --+ [(set_attr "length" "4")]) --+ --+(define_insn "init_lc" --+ [(set (reg:SI LC_REGNUM) --+ (match_operand:SI 0 "register_operand" "r")) --+ (unspec [(match_operand 1 "const_int_operand" "i")] UNSPEC_LOOP_END)] --+ "NDS32_HW_LOOP_P ()" --+ "mtusr\t%0, LC" --+ [(set_attr "length" "4")]) --+ --+; After replace hwloop, use this is pattern to get right CFG --+(define_insn "hwloop_cfg" --+ [(set (pc) --+ (if_then_else (ne (reg:SI LC_REGNUM) --+ (const_int 1)) --+ (match_operand:SI 1 "nds32_label_operand" "i") --+ (pc))) --+ (set (reg:SI LC_REGNUM) --+ (plus:SI (reg:SI LC_REGNUM) --+ (const_int -1))) --+ (use (reg:SI LB_REGNUM)) --+ (use (reg:SI LE_REGNUM)) --+ (use (reg:SI LC_REGNUM)) --+ (unspec [(match_operand 0 "const_int_operand" "i")] UNSPEC_LOOP_END)] --+ "TARGET_HWLOOP" --+ "" --+ [(set_attr "length" "0")]) --+;; ---------------------------------------------------------------------------- --+ --+;; Patterns for exception handling --+ --+(define_expand "eh_return" --+ [(use (match_operand 0 "general_operand"))] --+ "" --+{ --+ emit_insn (gen_nds32_eh_return (operands[0])); --+ DONE; --+}) --+ --+(define_insn_and_split "nds32_eh_return" --+ [(unspec_volatile [(match_operand:SI 0 "register_operand" "r")] UNSPEC_VOLATILE_EH_RETURN)] --+ "" --+ "#" --+ "reload_completed" --+ [(const_int 0)] --+{ --+ rtx place; --+ rtx addr; --+ --+ /* The operands[0] is the handler address. We need to assign it --+ to return address rtx so that we can jump to exception handler --+ when returning from current function. */ --+ --+ if (cfun->machine->lp_size == 0) --+ { --+ /* If $lp is not saved in the stack frame, we can take $lp directly. */ --+ place = gen_rtx_REG (SImode, LP_REGNUM); --+ } --+ else --+ { --+ /* Otherwise, we need to locate the stack slot of return address. --+ The return address is generally saved in [$fp-4] location. --+ However, DSE (dead store elimination) does not detect an alias --+ between [$fp-x] and [$sp+y]. This can result in a store to save --+ $lp introduced by builtin_eh_return() being incorrectly deleted --+ if it is based on $fp. The solution we take here is to compute --+ the offset relative to stack pointer and then use $sp to access --+ location so that the alias can be detected. --+ FIXME: What if the immediate value "offset" is too large to be --+ fit in a single addi instruction? */ --+ HOST_WIDE_INT offset; --+ --+ offset = (cfun->machine->fp_size --+ + cfun->machine->gp_size --+ + cfun->machine->lp_size --+ + cfun->machine->callee_saved_gpr_regs_size --+ + cfun->machine->callee_saved_area_gpr_padding_bytes --+ + cfun->machine->callee_saved_fpr_regs_size --+ + cfun->machine->eh_return_data_regs_size --+ + cfun->machine->local_size --+ + cfun->machine->out_args_size); --+ --+ addr = plus_constant (Pmode, stack_pointer_rtx, offset - 4); --+ place = gen_frame_mem (SImode, addr); --+ } --+ --+ emit_move_insn (place, operands[0]); --+ DONE; --+}) --+ --+;; ---------------------------------------------------------------------------- --+ --+;; Patterns for TLS. --+;; The following two tls patterns don't be expanded directly because the --+;; intermediate value may be spilled into the stack. As a result, it is --+;; hard to analyze the define-use chain in the relax_opt pass. --+ --+ --+;; There is a unspec operand to record RELAX_GROUP number because each --+;; emitted instruction need a relax_hint above it. --+(define_insn "tls_desc" --+ [(set (reg:SI 0) --+ (call (unspec_volatile:SI [(match_operand:SI 0 "nds32_symbolic_operand" "i")] UNSPEC_TLS_DESC) --+ (const_int 1))) --+ (use (unspec [(match_operand:SI 1 "immediate_operand" "i")] UNSPEC_VOLATILE_RELAX_GROUP)) --+ (use (reg:SI GP_REGNUM)) --+ (clobber (reg:SI LP_REGNUM)) --+ (clobber (reg:SI TA_REGNUM))] --+ "" --+ { --+ return nds32_output_tls_desc (operands); --+ } --+ [(set_attr "length" "20") --+ (set_attr "type" "branch")] --+) --+ --+;; There is a unspec operand to record RELAX_GROUP number because each --+;; emitted instruction need a relax_hint above it. --+(define_insn "tls_ie" --+ [(set (match_operand:SI 0 "register_operand" "=r") --+ (unspec:SI [(match_operand:SI 1 "nds32_symbolic_operand" "i")] UNSPEC_TLS_IE)) --+ (use (unspec [(match_operand:SI 2 "immediate_operand" "i")] UNSPEC_VOLATILE_RELAX_GROUP)) --+ (use (reg:SI GP_REGNUM))] --+ "" --+ { --+ return nds32_output_tls_ie (operands); --+ } --+ [(set (attr "length") (if_then_else (match_test "flag_pic") --+ (const_int 12) --+ (const_int 8))) --+ (set_attr "type" "misc")] --+) --+ --+;; The pattern is for some relaxation groups that have to keep addsi3 in 32-bit mode. --+(define_insn "addsi3_32bit" --+ [(set (match_operand:SI 0 "register_operand" "=r") --+ (unspec:SI [(match_operand:SI 1 "register_operand" "%r") --+ (match_operand:SI 2 "register_operand" " r")] UNSPEC_ADD32))] --+ "" --+ "add\t%0, %1, %2"; --+ [(set_attr "type" "alu") --+ (set_attr "length" "4") --+ (set_attr "feature" "v1")]) --+ -- ;; ---------------------------------------------------------------------------- --diff --git a/gcc/config/nds32/nds32.opt b/gcc/config/nds32/nds32.opt --index 938136f..a70ced9 100644 ----- a/gcc/config/nds32/nds32.opt --+++ b/gcc/config/nds32/nds32.opt --@@ -21,14 +21,67 @@ -- HeaderInclude -- config/nds32/nds32-opts.h -- ---mbig-endian ---Target Report RejectNegative Negative(mlittle-endian) Mask(BIG_ENDIAN) --+; --------------------------------------------------------------- --+; The following options are designed for aliasing and compatibility options. --+ --+EB --+Target RejectNegative Alias(mbig-endian) -- Generate code in big-endian mode. -- ---mlittle-endian ---Target Report RejectNegative Negative(mbig-endian) InverseMask(BIG_ENDIAN) --+EL --+Target RejectNegative Alias(mlittle-endian) -- Generate code in little-endian mode. -- --+mfp-as-gp --+Target RejectNegative Alias(mforce-fp-as-gp) --+Force performing fp-as-gp optimization. --+ --+mno-fp-as-gp --+Target RejectNegative Alias(mforbid-fp-as-gp) --+Forbid performing fp-as-gp optimization. --+ --+m16bit --+Target Undocumented Alias(m16-bit) --+Generate 16-bit instructions. --+ --+mcrt-arg=yes --+Target Undocumented Alias(mcrt-arg) --+Obsolete option. Users SHOULD NOT use this option in the command line. --+ --+mreduce-regs --+Target Undocumented Alias(mreduced-regs) --+Use reduced-set registers for register allocation. --+ --+mcache-line-size= --+Target RejectNegative Joined UInteger Undocumented Alias(mcache-block-size=) --+Alias of -mcache-block-size= --+ --+; --------------------------------------------------------------- --+ --+mabi= --+Target RejectNegative Joined Enum(abi_type) Var(nds32_abi) Init(TARGET_DEFAULT_ABI) --+Specify which ABI type to generate code for: 2, 2fp+. --+ --+Enum --+Name(abi_type) Type(enum abi_type) --+Known ABIs (for use with the -mabi= option): --+ --+EnumValue --+Enum(abi_type) String(2) Value(NDS32_ABI_V2) --+ --+EnumValue --+Enum(abi_type) String(2fp+) Value(NDS32_ABI_V2_FP_PLUS) --+ --+mfloat-abi=soft --+Target RejectNegative Alias(mabi=, 2) --+Specify use soft floating point ABI which mean alias to -mabi=2. --+ --+mfloat-abi=hard --+Target RejectNegative Alias(mabi=, 2fp+) --+Specify use soft floating point ABI which mean alias to -mabi=2fp+. --+ --+; --------------------------------------------------------------- --+ -- mreduced-regs -- Target Report RejectNegative Negative(mfull-regs) Mask(REDUCED_REGS) -- Use reduced-set registers for register allocation. --@@ -37,14 +90,148 @@ mfull-regs -- Target Report RejectNegative Negative(mreduced-regs) InverseMask(REDUCED_REGS) -- Use full-set registers for register allocation. -- --+; --------------------------------------------------------------- --+ --+Os1 --+Target --+Optimize for size level 1. This option will disable IFC and EX9 to prevent performance drop. --+ --+Os2 --+Target --+Optimize for size level 2. This option will disable IFC and EX9 for innermost loop to prevent performance drop. --+ --+Os3 --+Target --+Optimize for size level 3 which mean don't care performance. --+ --+malways-align --+Target Mask(ALWAYS_ALIGN) --+Always align function entry, jump target and return address. --+ --+malign-functions --+Target Mask(ALIGN_FUNCTION) --+Align function entry to 4 byte. --+ --+mbig-endian --+Target Undocumented RejectNegative Negative(mlittle-endian) Mask(BIG_ENDIAN) --+Generate code in big-endian mode. --+ --+mlittle-endian --+Target Undocumented RejectNegative Negative(mbig-endian) InverseMask(BIG_ENDIAN) --+Generate code in little-endian mode. --+ --+mforce-fp-as-gp --+Target Undocumented Mask(FORCE_FP_AS_GP) --+Prevent $fp being allocated during register allocation so that compiler is able to force performing fp-as-gp optimization. --+ --+mforbid-fp-as-gp --+Target Undocumented Mask(FORBID_FP_AS_GP) --+Forbid using $fp to access static and global variables. This option strictly forbids fp-as-gp optimization regardless of '-mforce-fp-as-gp'. --+ --+minline-strcpy --+Target Undocumented Mask(INLINE_STRCPY) --+Inlining strcpy function. --+ --+mload-store-opt --+Target Mask(LOAD_STORE_OPT) --+Enable load store optimization. --+ --+mregrename --+Target Mask(REGRENAME_OPT) --+Enable target dependent register rename optimization. --+ --+mgcse --+Target Mask(GCSE_OPT) --+Enable target dependent global CSE optimization. --+ --+mconst-remater --+Target Var(flag_nds32_const_remater_opt) --+Enable target dependent constant remeterialization optimization. --+ --+msoft-fp-arith-comm --+Target Mask(SOFT_FP_ARITH_COMM) --+Enable operand commutative for soft floating point arithmetic optimization. --+ --+msign-conversion --+Target Var(flag_nds32_sign_conversion) --+Enable the sign conversion in Gimple level. --+ --+mscalbn-transform --+Target Var(flag_nds32_scalbn_transform) --+Enable the scalbn transform in Gimple level. --+ --+mlmwsmw-opt --+Target Var(flag_nds32_lmwsmw_opt) --+Enable the load/store multiple optimization. --+ --+mict-model= --+Target Undocumented RejectNegative Joined Enum(nds32_ict_model_type) Var(nds32_ict_model) Init(ICT_MODEL_SMALL) --+Specify the address generation strategy for ICT call's code model. --+ --+Enum --+Name(nds32_ict_model_type) Type(enum nds32_ict_model_type) --+Known cmodel types (for use with the -mict-model= option): --+ --+EnumValue --+Enum(nds32_ict_model_type) String(small) Value(ICT_MODEL_SMALL) --+ --+EnumValue --+Enum(nds32_ict_model_type) String(large) Value(ICT_MODEL_LARGE) --+ --+mlmwsmw-cost= --+Target RejectNegative Joined Enum(lmwsmw_cost_type) Var(flag_lmwsmw_cost) Init(LMWSMW_OPT_AUTO) --+Specify the load/store insn generate to lmw/smw. --+ --+Enum --+Name(lmwsmw_cost_type) Type(enum lmwsmw_cost_type) --+Known lmwsmw cost type (for use with the -mlmwsmw-cost= option): --+ --+EnumValue --+Enum(lmwsmw_cost_type) String(size) Value(LMWSMW_OPT_SIZE) --+ --+EnumValue --+Enum(lmwsmw_cost_type) String(speed) Value(LMWSMW_OPT_SPEED) --+ --+EnumValue --+Enum(lmwsmw_cost_type) String(all) Value(LMWSMW_OPT_ALL) --+ --+EnumValue --+Enum(lmwsmw_cost_type) String(auto) Value(LMWSMW_OPT_AUTO) --+ --+mabi-compatible --+Target Var(flag_nds32_abi_compatible) --+Enable the ABI compatible detection. --+ --+mcprop-acc --+Target Var(flag_nds32_cprop_acc) --+Enable the copy propagation for accumulate style instructions. --+ --+; --------------------------------------------------------------- --+ -- mcmov -- Target Report Mask(CMOV) -- Generate conditional move instructions. -- ---mperf-ext ---Target Report Mask(PERF_EXT) --+mhw-abs --+Target Report Mask(HW_ABS) --+Generate hardware abs instructions. --+ --+mext-perf --+Target Report Mask(EXT_PERF) -- Generate performance extension instructions. -- --+mext-perf2 --+Target Report Mask(EXT_PERF2) --+Generate performance extension version 2 instructions. --+ --+mext-string --+Target Report Mask(EXT_STRING) --+Generate string extension instructions. --+ --+mext-dsp --+Target Report Mask(EXT_DSP) --+Generate DSP extension instructions. --+ -- mv3push -- Target Report Mask(V3PUSH) -- Generate v3 push25/pop25 instructions. --@@ -53,10 +240,22 @@ m16-bit -- Target Report Mask(16_BIT) -- Generate 16-bit instructions. -- --+mrelax-hint --+Target Report Mask(RELAX_HINT) --+Insert relax hint for linker to do relaxation. --+ --+mvh --+Target Report Mask(VH) Condition(!TARGET_LINUX_ABI) --+Enable Virtual Hosting support. --+ -- misr-vector-size= ---Target RejectNegative Joined UInteger Var(nds32_isr_vector_size) Init(NDS32_DEFAULT_ISR_VECTOR_SIZE) --+Target RejectNegative Joined UInteger Var(nds32_isr_vector_size) Init(NDS32_DEFAULT_ISR_VECTOR_SIZE) Condition(!TARGET_LINUX_ABI) -- Specify the size of each interrupt vector, which must be 4 or 16. -- --+misr-secure= --+Target RejectNegative Joined UInteger Var(nds32_isr_secure_level) Init(0) --+Specify the security level of c-isr for the whole file. --+ -- mcache-block-size= -- Target RejectNegative Joined UInteger Var(nds32_cache_block_size) Init(NDS32_DEFAULT_CACHE_BLOCK_SIZE) -- Specify the size of each cache block, which must be a power of 2 between 4 and 512. --@@ -73,32 +272,418 @@ EnumValue -- Enum(nds32_arch_type) String(v2) Value(ARCH_V2) -- -- EnumValue --+Enum(nds32_arch_type) String(v2j) Value(ARCH_V2J) --+ --+EnumValue -- Enum(nds32_arch_type) String(v3) Value(ARCH_V3) -- -- EnumValue --+Enum(nds32_arch_type) String(v3j) Value(ARCH_V3J) --+ --+EnumValue -- Enum(nds32_arch_type) String(v3m) Value(ARCH_V3M) -- ---mcmodel= ---Target RejectNegative Joined Enum(nds32_cmodel_type) Var(nds32_cmodel_option) Init(CMODEL_MEDIUM) ---Specify the address generation strategy for code model. --+EnumValue --+Enum(nds32_arch_type) String(v3m+) Value(ARCH_V3M_PLUS) --+ --+EnumValue --+Enum(nds32_arch_type) String(v3f) Value(ARCH_V3F) --+ --+EnumValue --+Enum(nds32_arch_type) String(v3s) Value(ARCH_V3S) --+ --+mcpu= --+Target RejectNegative Joined Enum(nds32_cpu_type) Var(nds32_cpu_option) Init(CPU_N9) --+Specify the cpu for pipeline model. -- -- Enum ---Name(nds32_cmodel_type) Type(enum nds32_cmodel_type) ---Known cmodel types (for use with the -mcmodel= option): --+Name(nds32_cpu_type) Type(enum nds32_cpu_type) --+Known cpu types (for use with the -mcpu= option): --+ --+EnumValue --+Enum(nds32_cpu_type) String(n6) Value(CPU_N6) --+ --+EnumValue --+Enum(nds32_cpu_type) String(n650) Value(CPU_N6) --+ --+EnumValue --+Enum(nds32_cpu_type) String(n7) Value(CPU_N7) --+ --+EnumValue --+Enum(nds32_cpu_type) String(n705) Value(CPU_N7) --+ --+EnumValue --+Enum(nds32_cpu_type) String(n8) Value(CPU_N8) --+ --+EnumValue --+Enum(nds32_cpu_type) String(n801) Value(CPU_N8) --+ --+EnumValue --+Enum(nds32_cpu_type) String(sn8) Value(CPU_N8) --+ --+EnumValue --+Enum(nds32_cpu_type) String(sn801) Value(CPU_N8) --+ --+EnumValue --+Enum(nds32_cpu_type) String(s8) Value(CPU_N8) --+ --+EnumValue --+Enum(nds32_cpu_type) String(s801) Value(CPU_N8) --+ --+EnumValue --+Enum(nds32_cpu_type) String(e8) Value(CPU_E8) --+ --+EnumValue --+Enum(nds32_cpu_type) String(e801) Value(CPU_E8) --+ --+EnumValue --+Enum(nds32_cpu_type) String(n820) Value(CPU_E8) --+ --+EnumValue --+Enum(nds32_cpu_type) String(s830) Value(CPU_E8) --+ --+EnumValue --+Enum(nds32_cpu_type) String(e830) Value(CPU_E8) --+ --+EnumValue --+Enum(nds32_cpu_type) String(n9) Value(CPU_N9) --+ --+EnumValue --+Enum(nds32_cpu_type) String(n903) Value(CPU_N9) --+ --+EnumValue --+Enum(nds32_cpu_type) String(n903a) Value(CPU_N9) --+ --+EnumValue --+Enum(nds32_cpu_type) String(n968) Value(CPU_N9) --+ --+EnumValue --+Enum(nds32_cpu_type) String(n968a) Value(CPU_N9) --+ --+EnumValue --+Enum(nds32_cpu_type) String(n10) Value(CPU_N10) --+ --+EnumValue --+Enum(nds32_cpu_type) String(n1033) Value(CPU_N10) --+ --+EnumValue --+Enum(nds32_cpu_type) String(n1033a) Value(CPU_N10) --+ --+EnumValue --+Enum(nds32_cpu_type) String(n1033-fpu) Value(CPU_N10) --+ --+EnumValue --+Enum(nds32_cpu_type) String(n1033-spu) Value(CPU_N10) -- -- EnumValue ---Enum(nds32_cmodel_type) String(small) Value(CMODEL_SMALL) --+Enum(nds32_cpu_type) String(n1068) Value(CPU_N10) -- -- EnumValue ---Enum(nds32_cmodel_type) String(medium) Value(CMODEL_MEDIUM) --+Enum(nds32_cpu_type) String(n1068a) Value(CPU_N10) -- -- EnumValue ---Enum(nds32_cmodel_type) String(large) Value(CMODEL_LARGE) --+Enum(nds32_cpu_type) String(n1068-fpu) Value(CPU_N10) --+ --+EnumValue --+Enum(nds32_cpu_type) String(n1068a-fpu) Value(CPU_N10) --+ --+EnumValue --+Enum(nds32_cpu_type) String(n1068-spu) Value(CPU_N10) --+ --+EnumValue --+Enum(nds32_cpu_type) String(n1068a-spu) Value(CPU_N10) --+ --+EnumValue --+Enum(nds32_cpu_type) String(d10) Value(CPU_N10) --+ --+EnumValue --+Enum(nds32_cpu_type) String(d1088) Value(CPU_N10) --+ --+EnumValue --+Enum(nds32_cpu_type) String(d1088-fpu) Value(CPU_N10) --+ --+EnumValue --+Enum(nds32_cpu_type) String(d1088-spu) Value(CPU_N10) --+ --+EnumValue --+Enum(nds32_cpu_type) Undocumented String(graywolf) Value(CPU_GRAYWOLF) --+ --+EnumValue --+Enum(nds32_cpu_type) String(n15) Value(CPU_GRAYWOLF) --+ --+EnumValue --+Enum(nds32_cpu_type) String(d15) Value(CPU_GRAYWOLF) --+ --+EnumValue --+Enum(nds32_cpu_type) String(n15s) Value(CPU_GRAYWOLF) --+ --+EnumValue --+Enum(nds32_cpu_type) String(d15s) Value(CPU_GRAYWOLF) --+ --+EnumValue --+Enum(nds32_cpu_type) String(n15f) Value(CPU_GRAYWOLF) --+ --+EnumValue --+Enum(nds32_cpu_type) String(d15f) Value(CPU_GRAYWOLF) --+ --+EnumValue --+Enum(nds32_cpu_type) String(n12) Value(CPU_N12) --+ --+EnumValue --+Enum(nds32_cpu_type) String(n1213) Value(CPU_N12) --+ --+EnumValue --+Enum(nds32_cpu_type) String(n1233) Value(CPU_N12) --+ --+EnumValue --+Enum(nds32_cpu_type) String(n1233-fpu) Value(CPU_N12) --+ --+EnumValue --+Enum(nds32_cpu_type) String(n1233-spu) Value(CPU_N12) --+ --+EnumValue --+Enum(nds32_cpu_type) String(n13) Value(CPU_N13) --+ --+EnumValue --+Enum(nds32_cpu_type) String(n1337) Value(CPU_N13) --+ --+EnumValue --+Enum(nds32_cpu_type) String(n1337-fpu) Value(CPU_N13) --+ --+EnumValue --+Enum(nds32_cpu_type) String(n1337-spu) Value(CPU_N13) --+ --+EnumValue --+Enum(nds32_cpu_type) Undocumented String(panther) Value(CPU_PANTHER) --+ --+EnumValue --+Enum(nds32_cpu_type) Undocumented String(simple) Value(CPU_SIMPLE) --+ --+mcpu=n15 --+Target RejectNegative Undocumented Alias(mcpu=, graywolf) --+Alias for multi-lib work. --+ --+mcpu=n15f --+Target RejectNegative Undocumented Alias(mcpu=, graywolf) --+Alias for multi-lib work. --+ --+mcpu=n15s --+Target RejectNegative Undocumented Alias(mcpu=, graywolf) --+Alias for multi-lib work. --+ --+mcpu=d15 --+Target RejectNegative Undocumented Alias(mcpu=, graywolf) --+Alias for multi-lib work. --+ --+mcpu=d15s --+Target RejectNegative Undocumented Alias(mcpu=, graywolf) --+Alias for multi-lib work. --+ --+mcpu=d15f --+Target RejectNegative Undocumented Alias(mcpu=, graywolf) --+Alias for multi-lib work. --+ --+mgraywolf --+Target RejectNegative Undocumented Alias(mcpu=, graywolf) --+This alias is only for gcc parallel test. --+ --+mv3m+ --+Target RejectNegative Undocumented Alias(march=, v3m+) --+This alias is only for gcc parallel test. --+ --+mmemory-model= --+Target RejectNegative Joined Enum(nds32_memory_model_type) Var(nds32_memory_model_option) Init(MEMORY_MODEL_FAST) --+Specify the memory model, fast or slow memory. --+ --+Enum --+Name(nds32_memory_model_type) Type(enum nds32_memory_model_type) --+ --+EnumValue --+Enum(nds32_memory_model_type) String(slow) Value(MEMORY_MODEL_SLOW) --+ --+EnumValue --+Enum(nds32_memory_model_type) String(fast) Value(MEMORY_MODEL_FAST) --+ --+mconfig-fpu= --+Target RejectNegative Joined Enum(float_reg_number) Var(nds32_fp_regnum) Init(TARGET_CONFIG_FPU_DEFAULT) --+Specify a fpu configuration value from 0 to 7; 0-3 is as FPU spec says, and 4-7 is corresponding to 0-3. --+ --+Enum --+Name(float_reg_number) Type(enum float_reg_number) --+Known floating-point number of registers (for use with the -mconfig-fpu= option): --+ --+EnumValue --+Enum(float_reg_number) String(0) Value(NDS32_CONFIG_FPU_0) --+ --+EnumValue --+Enum(float_reg_number) String(1) Value(NDS32_CONFIG_FPU_1) --+ --+EnumValue --+Enum(float_reg_number) String(2) Value(NDS32_CONFIG_FPU_2) --+ --+EnumValue --+Enum(float_reg_number) String(3) Value(NDS32_CONFIG_FPU_3) --+ --+EnumValue --+Enum(float_reg_number) String(4) Value(NDS32_CONFIG_FPU_4) --+ --+EnumValue --+Enum(float_reg_number) String(5) Value(NDS32_CONFIG_FPU_5) --+ --+EnumValue --+Enum(float_reg_number) String(6) Value(NDS32_CONFIG_FPU_6) --+ --+EnumValue --+Enum(float_reg_number) String(7) Value(NDS32_CONFIG_FPU_7) --+ --+mconfig-mul= --+Target RejectNegative Joined Enum(nds32_mul_type) Var(nds32_mul_config) Init(MUL_TYPE_FAST_1) --+Specify configuration of instruction mul: fast1, fast2 or slow. The default is fast1. --+ --+Enum --+Name(nds32_mul_type) Type(enum nds32_mul_type) --+ --+EnumValue --+Enum(nds32_mul_type) String(fast) Value(MUL_TYPE_FAST_1) --+ --+EnumValue --+Enum(nds32_mul_type) String(fast1) Value(MUL_TYPE_FAST_1) --+ --+EnumValue --+Enum(nds32_mul_type) String(fast2) Value(MUL_TYPE_FAST_2) --+ --+EnumValue --+Enum(nds32_mul_type) String(slow) Value(MUL_TYPE_SLOW) --+ --+mconfig-register-ports= --+Target RejectNegative Joined Enum(nds32_register_ports) Var(nds32_register_ports_config) Init(REG_PORT_3R2W) --+Specify how many read/write ports for n9/n10 cores. The value should be 3r2w or 2r1w. --+ --+Enum --+Name(nds32_register_ports) Type(enum nds32_register_ports) --+ --+EnumValue --+Enum(nds32_register_ports) String(3r2w) Value(REG_PORT_3R2W) --+ --+EnumValue --+Enum(nds32_register_ports) String(2r1w) Value(REG_PORT_2R1W) --+ --+mreorg-out-of-order --+Target Report Var(flag_reorg_out_of_order) Init(0) --+Allow out-of-order reorganization for multiple issue micro-architectures. --+ --+mifc --+Target Report Mask(IFC) --+Use special directives to guide linker doing ifc optimization. --+ --+mex9 --+Target Report Mask(EX9) --+Use special directives to guide linker doing ex9 optimization. --+ --+mprint-stall-cycles --+Target Report Mask(PRINT_STALLS) --+Print stall cycles due to structural or data dependencies. It should be used with the option '-S'. --+Note that stall cycles are determined by the compiler's pipeline model and it may not be precise. -- -- mctor-dtor -- Target Report -- Enable constructor/destructor feature. -- --+mcrt-arg --+Target Report --+Enable argc/argv passed by simulator. --+ -- mrelax -- Target Report -- Guide linker to relax instructions. --+ --+minnermost-loop --+Target Report Mask(INNERMOST_LOOP) --+Insert the innermost loop directive. --+ --+mext-fpu-fma --+Target Report Mask(EXT_FPU_FMA) --+Generate floating-point multiply-accumulation instructions. --+ --+mext-fpu-sp --+Target Report Mask(FPU_SINGLE) --+Generate single-precision floating-point instructions. --+ --+mext-fpu-dp --+Target Report Mask(FPU_DOUBLE) --+Generate double-precision floating-point instructions. --+ --+mext-zol --+Target Report Mask(HWLOOP) --+Insert the hardware loop directive. --+ --+mforce-no-ext-zol --+Target Undocumented Report Mask(FORCE_NO_HWLOOP) --+Force disable hardware loop, even use -mext-zol. --+ --+mforce-no-ext-dsp --+Target Undocumented Report Mask(FORCE_NO_EXT_DSP) --+Force disable hardware loop, even use -mext-dsp. --+ --+mforce-memcpy-zol --+Target Report Var(flag_force_memcpy_zol) Init(0) --+Force enable hardware loop in memcpy function. --+ --+msched-prolog-epilog --+Target Var(flag_sched_prolog_epilog) Init(1) --+Permit scheduling of a function's prologue and epilogue sequence. --+ --+mret-in-naked-func --+Target Var(flag_ret_in_naked_func) Init(1) --+Generate return instruction in naked function. --+ --+malways-save-lp --+Target Var(flag_always_save_lp) Init(0) --+Always save $lp in the stack. --+ --+munaligned-access --+Target Report Var(flag_unaligned_access) Init(0) --+Enable unaligned word and halfword accesses to packed data. --+ --+; --------------------------------------------------------------- --+; The following options are designed for compatibility issue. --+; Hopefully these obsolete options will be removed one day. --+ --+mg --+Target Undocumented Warn(%qs is deprecated and has no effect) --+Obsolete option. Users SHOULD NOT use this option in the command line. --+ --+mdx-regs --+Target Undocumented Warn(%qs is deprecated and has no effect) --+Obsolete option. Users SHOULD NOT use this option in the command line. --+ --+mexpand-isr --+Target Undocumented Warn(%qs is deprecated and has no effect) --+Obsolete option. Users SHOULD NOT use this option in the command line. --+ --+mcrt-cpp=yes --+Target Undocumented Warn(%qs is deprecated and has no effect, use -mctor-dtor instead) --+Obsolete option. Users SHOULD NOT use this option in the command line. --+ --+mcrt-exit=yes --+Target Undocumented Warn(%qs is deprecated and has no effect, use -mctor-dtor instead) --+Obsolete option. Users SHOULD NOT use this option in the command line. --+ --+mlib= --+Target RejectNegative Joined Undocumented Warn(%qs is deprecated and has no effect) --+Obsolete option. Users SHOULD NOT use this option in the command line. --+ --+; --------------------------------------------------------------- --+; The following options are designed for compatibility issue. --+; Hopefully these obsolete options will be removed one day. --+ --+mace --+Target RejectNegative --+Compile with Andes ACE. --+ --+mace-s2s= --+Target Joined RejectNegative --+Argument for pass to Andes's ACE source-to-source translator. --+ --+ --+; --------------------------------------------------------------- --diff --git a/gcc/config/nds32/nds32_init.inc b/gcc/config/nds32/nds32_init.inc --new file mode 100644 --index 0000000..1084ad0 ----- /dev/null --+++ b/gcc/config/nds32/nds32_init.inc --@@ -0,0 +1,43 @@ --+/* --+ * nds32_init.inc --+ * --+ * NDS32 architecture startup assembler header file --+ * --+ */ --+ --+.macro nds32_init --+ --+ ! Initialize GP for data access --+ la $gp, _SDA_BASE_ --+ --+#if defined(__NDS32_EXT_EX9__) --+ ! Check HW for EX9 --+ mfsr $r0, $MSC_CFG --+ li $r1, (1 << 24) --+ and $r2, $r0, $r1 --+ beqz $r2, 1f --+ --+ ! Initialize the table base of EX9 instruction --+ la $r0, _ITB_BASE_ --+ mtusr $r0, $ITB --+1: --+#endif --+ --+#if defined(__NDS32_EXT_FPU_DP__) || defined(__NDS32_EXT_FPU_SP__) --+ ! Enable FPU --+ mfsr $r0, $FUCOP_CTL --+ ori $r0, $r0, #0x1 --+ mtsr $r0, $FUCOP_CTL --+ dsb --+ --+ ! Enable denormalized flush-to-Zero mode --+ fmfcsr $r0 --+ ori $r0,$r0,#0x1000 --+ fmtcsr $r0 --+ dsb --+#endif --+ --+ ! Initialize default stack pointer --+ la $sp, _stack --+ --+.endm --diff --git a/gcc/config/nds32/nds32_intrinsic.h b/gcc/config/nds32/nds32_intrinsic.h --index 3e868dc..fef727b 100644 ----- a/gcc/config/nds32/nds32_intrinsic.h --+++ b/gcc/config/nds32/nds32_intrinsic.h --@@ -26,12 +26,1383 @@ -- #ifndef _NDS32_INTRINSIC_H -- #define _NDS32_INTRINSIC_H -- --+typedef signed char int8x4_t __attribute ((vector_size(4))); --+typedef short int16x2_t __attribute ((vector_size(4))); --+typedef int int32x2_t __attribute__((vector_size(8))); --+typedef unsigned char uint8x4_t __attribute__ ((vector_size (4))); --+typedef unsigned short uint16x2_t __attribute__ ((vector_size (4))); --+typedef unsigned int uint32x2_t __attribute__((vector_size(8))); --+ --+/* General instrinsic register names. */ -- enum nds32_intrinsic_registers -- { --- __NDS32_REG_PSW__ = 1024, --+ __NDS32_REG_CPU_VER__ = 1024, --+ __NDS32_REG_ICM_CFG__, --+ __NDS32_REG_DCM_CFG__, --+ __NDS32_REG_MMU_CFG__, --+ __NDS32_REG_MSC_CFG__, --+ __NDS32_REG_MSC_CFG2__, --+ __NDS32_REG_CORE_ID__, --+ __NDS32_REG_FUCOP_EXIST__, --+ --+ __NDS32_REG_PSW__, -- __NDS32_REG_IPSW__, --+ __NDS32_REG_P_IPSW__, --+ __NDS32_REG_IVB__, --+ __NDS32_REG_EVA__, --+ __NDS32_REG_P_EVA__, -- __NDS32_REG_ITYPE__, --- __NDS32_REG_IPC__ --+ __NDS32_REG_P_ITYPE__, --+ --+ __NDS32_REG_MERR__, --+ __NDS32_REG_IPC__, --+ __NDS32_REG_P_IPC__, --+ __NDS32_REG_OIPC__, --+ __NDS32_REG_P_P0__, --+ __NDS32_REG_P_P1__, --+ --+ __NDS32_REG_INT_MASK__, --+ __NDS32_REG_INT_MASK2__, --+ __NDS32_REG_INT_MASK3__, --+ __NDS32_REG_INT_PEND__, --+ __NDS32_REG_INT_PEND2__, --+ __NDS32_REG_INT_PEND3__, --+ __NDS32_REG_SP_USR__, --+ __NDS32_REG_SP_PRIV__, --+ __NDS32_REG_INT_PRI__, --+ __NDS32_REG_INT_PRI2__, --+ __NDS32_REG_INT_PRI3__, --+ __NDS32_REG_INT_PRI4__, --+ __NDS32_REG_INT_CTRL__, --+ __NDS32_REG_INT_TRIGGER__, --+ __NDS32_REG_INT_TRIGGER2__, --+ __NDS32_REG_INT_GPR_PUSH_DIS__, --+ --+ __NDS32_REG_MMU_CTL__, --+ __NDS32_REG_L1_PPTB__, --+ __NDS32_REG_TLB_VPN__, --+ __NDS32_REG_TLB_DATA__, --+ __NDS32_REG_TLB_MISC__, --+ __NDS32_REG_VLPT_IDX__, --+ __NDS32_REG_ILMB__, --+ __NDS32_REG_DLMB__, --+ --+ __NDS32_REG_CACHE_CTL__, --+ __NDS32_REG_HSMP_SADDR__, --+ __NDS32_REG_HSMP_EADDR__, --+ __NDS32_REG_SDZ_CTL__, --+ __NDS32_REG_N12MISC_CTL__, --+ __NDS32_REG_MISC_CTL__, --+ __NDS32_REG_ECC_MISC__, --+ --+ __NDS32_REG_BPC0__, --+ __NDS32_REG_BPC1__, --+ __NDS32_REG_BPC2__, --+ __NDS32_REG_BPC3__, --+ __NDS32_REG_BPC4__, --+ __NDS32_REG_BPC5__, --+ __NDS32_REG_BPC6__, --+ __NDS32_REG_BPC7__, --+ --+ __NDS32_REG_BPA0__, --+ __NDS32_REG_BPA1__, --+ __NDS32_REG_BPA2__, --+ __NDS32_REG_BPA3__, --+ __NDS32_REG_BPA4__, --+ __NDS32_REG_BPA5__, --+ __NDS32_REG_BPA6__, --+ __NDS32_REG_BPA7__, --+ --+ __NDS32_REG_BPAM0__, --+ __NDS32_REG_BPAM1__, --+ __NDS32_REG_BPAM2__, --+ __NDS32_REG_BPAM3__, --+ __NDS32_REG_BPAM4__, --+ __NDS32_REG_BPAM5__, --+ __NDS32_REG_BPAM6__, --+ __NDS32_REG_BPAM7__, --+ --+ __NDS32_REG_BPV0__, --+ __NDS32_REG_BPV1__, --+ __NDS32_REG_BPV2__, --+ __NDS32_REG_BPV3__, --+ __NDS32_REG_BPV4__, --+ __NDS32_REG_BPV5__, --+ __NDS32_REG_BPV6__, --+ __NDS32_REG_BPV7__, --+ --+ __NDS32_REG_BPCID0__, --+ __NDS32_REG_BPCID1__, --+ __NDS32_REG_BPCID2__, --+ __NDS32_REG_BPCID3__, --+ __NDS32_REG_BPCID4__, --+ __NDS32_REG_BPCID5__, --+ __NDS32_REG_BPCID6__, --+ __NDS32_REG_BPCID7__, --+ --+ __NDS32_REG_EDM_CFG__, --+ __NDS32_REG_EDMSW__, --+ __NDS32_REG_EDM_CTL__, --+ __NDS32_REG_EDM_DTR__, --+ __NDS32_REG_BPMTC__, --+ __NDS32_REG_DIMBR__, --+ --+ __NDS32_REG_TECR0__, --+ __NDS32_REG_TECR1__, --+ __NDS32_REG_PFMC0__, --+ __NDS32_REG_PFMC1__, --+ __NDS32_REG_PFMC2__, --+ __NDS32_REG_PFM_CTL__, --+ __NDS32_REG_PFT_CTL__, --+ __NDS32_REG_HSP_CTL__, --+ __NDS32_REG_SP_BOUND__, --+ __NDS32_REG_SP_BOUND_PRIV__, --+ __NDS32_REG_SP_BASE__, --+ __NDS32_REG_SP_BASE_PRIV__, --+ __NDS32_REG_FUCOP_CTL__, --+ __NDS32_REG_PRUSR_ACC_CTL__, --+ --+ __NDS32_REG_DMA_CFG__, --+ __NDS32_REG_DMA_GCSW__, --+ __NDS32_REG_DMA_CHNSEL__, --+ __NDS32_REG_DMA_ACT__, --+ __NDS32_REG_DMA_SETUP__, --+ __NDS32_REG_DMA_ISADDR__, --+ __NDS32_REG_DMA_ESADDR__, --+ __NDS32_REG_DMA_TCNT__, --+ __NDS32_REG_DMA_STATUS__, --+ __NDS32_REG_DMA_2DSET__, --+ __NDS32_REG_DMA_2DSCTL__, --+ __NDS32_REG_DMA_RCNT__, --+ __NDS32_REG_DMA_HSTATUS__, --+ --+ __NDS32_REG_PC__, --+ __NDS32_REG_SP_USR1__, --+ __NDS32_REG_SP_USR2__, --+ __NDS32_REG_SP_USR3__, --+ __NDS32_REG_SP_PRIV1__, --+ __NDS32_REG_SP_PRIV2__, --+ __NDS32_REG_SP_PRIV3__, --+ __NDS32_REG_BG_REGION__, --+ __NDS32_REG_SFCR__, --+ __NDS32_REG_SIGN__, --+ __NDS32_REG_ISIGN__, --+ __NDS32_REG_P_ISIGN__, --+ __NDS32_REG_IFC_LP__, --+ __NDS32_REG_ITB__ -- }; -- --+/* The cctl subtype for intrinsic. */ --+enum nds32_cctl_valck --+{ --+ __NDS32_CCTL_L1D_VA_FILLCK__, --+ __NDS32_CCTL_L1D_VA_ULCK__, --+ __NDS32_CCTL_L1I_VA_FILLCK__, --+ __NDS32_CCTL_L1I_VA_ULCK__ --+}; --+ --+enum nds32_cctl_idxwbinv --+{ --+ __NDS32_CCTL_L1D_IX_WBINVAL__, --+ __NDS32_CCTL_L1D_IX_INVAL__, --+ __NDS32_CCTL_L1D_IX_WB__, --+ __NDS32_CCTL_L1I_IX_INVAL__ --+}; --+ --+enum nds32_cctl_vawbinv --+{ --+ __NDS32_CCTL_L1D_VA_INVAL__, --+ __NDS32_CCTL_L1D_VA_WB__, --+ __NDS32_CCTL_L1D_VA_WBINVAL__, --+ __NDS32_CCTL_L1I_VA_INVAL__ --+}; --+ --+enum nds32_cctl_idxread --+{ --+ __NDS32_CCTL_L1D_IX_RTAG__, --+ __NDS32_CCTL_L1D_IX_RWD__, --+ __NDS32_CCTL_L1I_IX_RTAG__, --+ __NDS32_CCTL_L1I_IX_RWD__ --+}; --+ --+enum nds32_cctl_idxwrite --+{ --+ __NDS32_CCTL_L1D_IX_WTAG__, --+ __NDS32_CCTL_L1D_IX_WWD__, --+ __NDS32_CCTL_L1I_IX_WTAG__, --+ __NDS32_CCTL_L1I_IX_WWD__ --+}; --+ --+enum nds32_dpref --+{ --+ __NDS32_DPREF_SRD__, --+ __NDS32_DPREF_MRD__, --+ __NDS32_DPREF_SWR__, --+ __NDS32_DPREF_MWR__, --+ __NDS32_DPREF_PTE__, --+ __NDS32_DPREF_CLWR__ --+}; --+ --+/* ------------------------------------------------------------------------ */ --+ --+/* Define interrupt number for intrinsic function. */ --+#define NDS32_INT_H0 0 --+#define NDS32_INT_H1 1 --+#define NDS32_INT_H2 2 --+#define NDS32_INT_H3 3 --+#define NDS32_INT_H4 4 --+#define NDS32_INT_H5 5 --+#define NDS32_INT_H6 6 --+#define NDS32_INT_H7 7 --+#define NDS32_INT_H8 8 --+#define NDS32_INT_H9 9 --+#define NDS32_INT_H10 10 --+#define NDS32_INT_H11 11 --+#define NDS32_INT_H12 12 --+#define NDS32_INT_H13 13 --+#define NDS32_INT_H14 14 --+#define NDS32_INT_H15 15 --+#define NDS32_INT_H16 16 --+#define NDS32_INT_H17 17 --+#define NDS32_INT_H18 18 --+#define NDS32_INT_H19 19 --+#define NDS32_INT_H20 20 --+#define NDS32_INT_H21 21 --+#define NDS32_INT_H22 22 --+#define NDS32_INT_H23 23 --+#define NDS32_INT_H24 24 --+#define NDS32_INT_H25 25 --+#define NDS32_INT_H26 26 --+#define NDS32_INT_H27 27 --+#define NDS32_INT_H28 28 --+#define NDS32_INT_H29 29 --+#define NDS32_INT_H30 30 --+#define NDS32_INT_H31 31 --+#define NDS32_INT_H32 32 --+#define NDS32_INT_H33 33 --+#define NDS32_INT_H34 34 --+#define NDS32_INT_H35 35 --+#define NDS32_INT_H36 36 --+#define NDS32_INT_H37 37 --+#define NDS32_INT_H38 38 --+#define NDS32_INT_H39 39 --+#define NDS32_INT_H40 40 --+#define NDS32_INT_H41 41 --+#define NDS32_INT_H42 42 --+#define NDS32_INT_H43 43 --+#define NDS32_INT_H44 44 --+#define NDS32_INT_H45 45 --+#define NDS32_INT_H46 46 --+#define NDS32_INT_H47 47 --+#define NDS32_INT_H48 48 --+#define NDS32_INT_H49 49 --+#define NDS32_INT_H50 50 --+#define NDS32_INT_H51 51 --+#define NDS32_INT_H52 52 --+#define NDS32_INT_H53 53 --+#define NDS32_INT_H54 54 --+#define NDS32_INT_H55 55 --+#define NDS32_INT_H56 56 --+#define NDS32_INT_H57 57 --+#define NDS32_INT_H58 58 --+#define NDS32_INT_H59 59 --+#define NDS32_INT_H60 60 --+#define NDS32_INT_H61 61 --+#define NDS32_INT_H62 62 --+#define NDS32_INT_H63 63 --+#define NDS32_INT_SWI 64 --+#define NDS32_INT_ALZ 65 --+#define NDS32_INT_IDIVZE 66 --+#define NDS32_INT_DSSIM 67 --+ --+/* ------------------------------------------------------------------------ */ --+ --+/* Define intrinsic register name macro for compatibility. */ --+#define NDS32_SR_CPU_VER __NDS32_REG_CPU_VER__ --+#define NDS32_SR_ICM_CFG __NDS32_REG_ICM_CFG__ --+#define NDS32_SR_DCM_CFG __NDS32_REG_DCM_CFG__ --+#define NDS32_SR_MMU_CFG __NDS32_REG_MMU_CFG__ --+#define NDS32_SR_MSC_CFG __NDS32_REG_MSC_CFG__ --+#define NDS32_SR_MSC_CFG2 __NDS32_REG_MSC_CFG2__ --+#define NDS32_SR_CORE_ID __NDS32_REG_CORE_ID__ --+#define NDS32_SR_FUCOP_EXIST __NDS32_REG_FUCOP_EXIST__ --+#define NDS32_SR_PSW __NDS32_REG_PSW__ --+#define NDS32_SR_IPSW __NDS32_REG_IPSW__ --+#define NDS32_SR_P_IPSW __NDS32_REG_P_IPSW__ --+#define NDS32_SR_IVB __NDS32_REG_IVB__ --+#define NDS32_SR_EVA __NDS32_REG_EVA__ --+#define NDS32_SR_P_EVA __NDS32_REG_P_EVA__ --+#define NDS32_SR_ITYPE __NDS32_REG_ITYPE__ --+#define NDS32_SR_P_ITYPE __NDS32_REG_P_ITYPE__ --+#define NDS32_SR_MERR __NDS32_REG_MERR__ --+#define NDS32_SR_IPC __NDS32_REG_IPC__ --+#define NDS32_SR_P_IPC __NDS32_REG_P_IPC__ --+#define NDS32_SR_OIPC __NDS32_REG_OIPC__ --+#define NDS32_SR_P_P0 __NDS32_REG_P_P0__ --+#define NDS32_SR_P_P1 __NDS32_REG_P_P1__ --+#define NDS32_SR_INT_MASK __NDS32_REG_INT_MASK__ --+#define NDS32_SR_INT_MASK2 __NDS32_REG_INT_MASK2__ --+#define NDS32_SR_INT_MASK3 __NDS32_REG_INT_MASK3__ --+#define NDS32_SR_INT_PEND __NDS32_REG_INT_PEND__ --+#define NDS32_SR_INT_PEND2 __NDS32_REG_INT_PEND2__ --+#define NDS32_SR_INT_PEND3 __NDS32_REG_INT_PEND3__ --+#define NDS32_SR_SP_USR __NDS32_REG_SP_USR__ --+#define NDS32_SR_SP_PRIV __NDS32_REG_SP_PRIV__ --+#define NDS32_SR_INT_PRI __NDS32_REG_INT_PRI__ --+#define NDS32_SR_INT_PRI2 __NDS32_REG_INT_PRI2__ --+#define NDS32_SR_INT_PRI3 __NDS32_REG_INT_PRI3__ --+#define NDS32_SR_INT_PRI4 __NDS32_REG_INT_PRI4__ --+#define NDS32_SR_INT_CTRL __NDS32_REG_INT_CTRL__ --+#define NDS32_SR_INT_TRIGGER __NDS32_REG_INT_TRIGGER__ --+#define NDS32_SR_INT_TRIGGER2 __NDS32_REG_INT_TRIGGER2__ --+#define NDS32_SR_INT_GPR_PUSH_DIS __NDS32_REG_INT_GPR_PUSH_DIS__ --+#define NDS32_SR_MMU_CTL __NDS32_REG_MMU_CTL__ --+#define NDS32_SR_L1_PPTB __NDS32_REG_L1_PPTB__ --+#define NDS32_SR_TLB_VPN __NDS32_REG_TLB_VPN__ --+#define NDS32_SR_TLB_DATA __NDS32_REG_TLB_DATA__ --+#define NDS32_SR_TLB_MISC __NDS32_REG_TLB_MISC__ --+#define NDS32_SR_VLPT_IDX __NDS32_REG_VLPT_IDX__ --+#define NDS32_SR_ILMB __NDS32_REG_ILMB__ --+#define NDS32_SR_DLMB __NDS32_REG_DLMB__ --+#define NDS32_SR_CACHE_CTL __NDS32_REG_CACHE_CTL__ --+#define NDS32_SR_HSMP_SADDR __NDS32_REG_HSMP_SADDR__ --+#define NDS32_SR_HSMP_EADDR __NDS32_REG_HSMP_EADDR__ --+#define NDS32_SR_SDZ_CTL __NDS32_REG_SDZ_CTL__ --+#define NDS32_SR_N12MISC_CTL __NDS32_REG_N12MISC_CTL__ --+#define NDS32_SR_MISC_CTL __NDS32_REG_MISC_CTL__ --+#define NDS32_SR_ECC_MISC __NDS32_REG_ECC_MISC__ --+#define NDS32_SR_BPC0 __NDS32_REG_BPC0__ --+#define NDS32_SR_BPC1 __NDS32_REG_BPC1__ --+#define NDS32_SR_BPC2 __NDS32_REG_BPC2__ --+#define NDS32_SR_BPC3 __NDS32_REG_BPC3__ --+#define NDS32_SR_BPC4 __NDS32_REG_BPC4__ --+#define NDS32_SR_BPC5 __NDS32_REG_BPC5__ --+#define NDS32_SR_BPC6 __NDS32_REG_BPC6__ --+#define NDS32_SR_BPC7 __NDS32_REG_BPC7__ --+#define NDS32_SR_BPA0 __NDS32_REG_BPA0__ --+#define NDS32_SR_BPA1 __NDS32_REG_BPA1__ --+#define NDS32_SR_BPA2 __NDS32_REG_BPA2__ --+#define NDS32_SR_BPA3 __NDS32_REG_BPA3__ --+#define NDS32_SR_BPA4 __NDS32_REG_BPA4__ --+#define NDS32_SR_BPA5 __NDS32_REG_BPA5__ --+#define NDS32_SR_BPA6 __NDS32_REG_BPA6__ --+#define NDS32_SR_BPA7 __NDS32_REG_BPA7__ --+#define NDS32_SR_BPAM0 __NDS32_REG_BPAM0__ --+#define NDS32_SR_BPAM1 __NDS32_REG_BPAM1__ --+#define NDS32_SR_BPAM2 __NDS32_REG_BPAM2__ --+#define NDS32_SR_BPAM3 __NDS32_REG_BPAM3__ --+#define NDS32_SR_BPAM4 __NDS32_REG_BPAM4__ --+#define NDS32_SR_BPAM5 __NDS32_REG_BPAM5__ --+#define NDS32_SR_BPAM6 __NDS32_REG_BPAM6__ --+#define NDS32_SR_BPAM7 __NDS32_REG_BPAM7__ --+#define NDS32_SR_BPV0 __NDS32_REG_BPV0__ --+#define NDS32_SR_BPV1 __NDS32_REG_BPV1__ --+#define NDS32_SR_BPV2 __NDS32_REG_BPV2__ --+#define NDS32_SR_BPV3 __NDS32_REG_BPV3__ --+#define NDS32_SR_BPV4 __NDS32_REG_BPV4__ --+#define NDS32_SR_BPV5 __NDS32_REG_BPV5__ --+#define NDS32_SR_BPV6 __NDS32_REG_BPV6__ --+#define NDS32_SR_BPV7 __NDS32_REG_BPV7__ --+#define NDS32_SR_BPCID0 __NDS32_REG_BPCID0__ --+#define NDS32_SR_BPCID1 __NDS32_REG_BPCID1__ --+#define NDS32_SR_BPCID2 __NDS32_REG_BPCID2__ --+#define NDS32_SR_BPCID3 __NDS32_REG_BPCID3__ --+#define NDS32_SR_BPCID4 __NDS32_REG_BPCID4__ --+#define NDS32_SR_BPCID5 __NDS32_REG_BPCID5__ --+#define NDS32_SR_BPCID6 __NDS32_REG_BPCID6__ --+#define NDS32_SR_BPCID7 __NDS32_REG_BPCID7__ --+#define NDS32_SR_EDM_CFG __NDS32_REG_EDM_CFG__ --+#define NDS32_SR_EDMSW __NDS32_REG_EDMSW__ --+#define NDS32_SR_EDM_CTL __NDS32_REG_EDM_CTL__ --+#define NDS32_SR_EDM_DTR __NDS32_REG_EDM_DTR__ --+#define NDS32_SR_BPMTC __NDS32_REG_BPMTC__ --+#define NDS32_SR_DIMBR __NDS32_REG_DIMBR__ --+#define NDS32_SR_TECR0 __NDS32_REG_TECR0__ --+#define NDS32_SR_TECR1 __NDS32_REG_TECR1__ --+#define NDS32_SR_PFMC0 __NDS32_REG_PFMC0__ --+#define NDS32_SR_PFMC1 __NDS32_REG_PFMC1__ --+#define NDS32_SR_PFMC2 __NDS32_REG_PFMC2__ --+#define NDS32_SR_PFM_CTL __NDS32_REG_PFM_CTL__ --+#define NDS32_SR_HSP_CTL __NDS32_REG_HSP_CTL__ --+#define NDS32_SR_SP_BOUND __NDS32_REG_SP_BOUND__ --+#define NDS32_SR_SP_BOUND_PRIV __NDS32_REG_SP_BOUND_PRIV__ --+#define NDS32_SR_SP_BASE __NDS32_REG_SP_BASE__ --+#define NDS32_SR_SP_BASE_PRIV __NDS32_REG_SP_BASE_PRIV__ --+#define NDS32_SR_FUCOP_CTL __NDS32_REG_FUCOP_CTL__ --+#define NDS32_SR_PRUSR_ACC_CTL __NDS32_REG_PRUSR_ACC_CTL__ --+#define NDS32_SR_DMA_CFG __NDS32_REG_DMA_CFG__ --+#define NDS32_SR_DMA_GCSW __NDS32_REG_DMA_GCSW__ --+#define NDS32_SR_DMA_CHNSEL __NDS32_REG_DMA_CHNSEL__ --+#define NDS32_SR_DMA_ACT __NDS32_REG_DMA_ACT__ --+#define NDS32_SR_DMA_SETUP __NDS32_REG_DMA_SETUP__ --+#define NDS32_SR_DMA_ISADDR __NDS32_REG_DMA_ISADDR__ --+#define NDS32_SR_DMA_ESADDR __NDS32_REG_DMA_ESADDR__ --+#define NDS32_SR_DMA_TCNT __NDS32_REG_DMA_TCNT__ --+#define NDS32_SR_DMA_STATUS __NDS32_REG_DMA_STATUS__ --+#define NDS32_SR_DMA_2DSET __NDS32_REG_DMA_2DSET__ --+#define NDS32_SR_DMA_2DSCTL __NDS32_REG_DMA_2DSCTL__ --+#define NDS32_SR_DMA_RCNT __NDS32_REG_DMA_RCNT__ --+#define NDS32_SR_DMA_HSTATUS __NDS32_REG_DMA_HSTATUS__ --+#define NDS32_SR_SP_USR1 __NDS32_REG_SP_USR1__ --+#define NDS32_SR_SP_USR2 __NDS32_REG_SP_USR2__ --+#define NDS32_SR_SP_USR3 __NDS32_REG_SP_USR3__ --+#define NDS32_SR_SP_PRIV1 __NDS32_REG_SP_PRIV1__ --+#define NDS32_SR_SP_PRIV2 __NDS32_REG_SP_PRIV2__ --+#define NDS32_SR_SP_PRIV3 __NDS32_REG_SP_PRIV3__ --+#define NDS32_SR_BG_REGION __NDS32_REG_BG_REGION__ --+#define NDS32_SR_SFCR __NDS32_REG_SFCR__ --+#define NDS32_SR_SIGN __NDS32_REG_SIGN__ --+#define NDS32_SR_ISIGN __NDS32_REG_ISIGN__ --+#define NDS32_SR_P_ISIGN __NDS32_REG_P_ISIGN__ --+ --+#define NDS32_USR_PC __NDS32_REG_PC__ --+#define NDS32_USR_DMA_CFG __NDS32_REG_DMA_CFG__ --+#define NDS32_USR_DMA_GCSW __NDS32_REG_DMA_GCSW__ --+#define NDS32_USR_DMA_CHNSEL __NDS32_REG_DMA_CHNSEL__ --+#define NDS32_USR_DMA_ACT __NDS32_REG_DMA_ACT__ --+#define NDS32_USR_DMA_SETUP __NDS32_REG_DMA_SETUP__ --+#define NDS32_USR_DMA_ISADDR __NDS32_REG_DMA_ISADDR__ --+#define NDS32_USR_DMA_ESADDR __NDS32_REG_DMA_ESADDR__ --+#define NDS32_USR_DMA_TCNT __NDS32_REG_DMA_TCNT__ --+#define NDS32_USR_DMA_STATUS __NDS32_REG_DMA_STATUS__ --+#define NDS32_USR_DMA_2DSET __NDS32_REG_DMA_2DSET__ --+#define NDS32_USR_DMA_2DSCTL __NDS32_REG_DMA_2DSCTL__ --+#define NDS32_USR_PFMC0 __NDS32_REG_PFMC0__ --+#define NDS32_USR_PFMC1 __NDS32_REG_PFMC1__ --+#define NDS32_USR_PFMC2 __NDS32_REG_PFMC2__ --+#define NDS32_USR_PFM_CTL __NDS32_REG_PFM_CTL__ --+#define NDS32_USR_IFC_LP __NDS32_REG_IFC_LP__ --+#define NDS32_USR_ITB __NDS32_REG_ITB__ --+ --+#define NDS32_CCTL_L1D_VA_FILLCK __NDS32_CCTL_L1D_VA_FILLCK__ --+#define NDS32_CCTL_L1D_VA_ULCK __NDS32_CCTL_L1D_VA_ULCK__ --+#define NDS32_CCTL_L1I_VA_FILLCK __NDS32_CCTL_L1I_VA_FILLCK__ --+#define NDS32_CCTL_L1I_VA_ULCK __NDS32_CCTL_L1I_VA_ULCK__ --+ --+#define NDS32_CCTL_L1D_IX_WBINVAL __NDS32_CCTL_L1D_IX_WBINVAL__ --+#define NDS32_CCTL_L1D_IX_INVAL __NDS32_CCTL_L1D_IX_INVAL__ --+#define NDS32_CCTL_L1D_IX_WB __NDS32_CCTL_L1D_IX_WB__ --+#define NDS32_CCTL_L1I_IX_INVAL __NDS32_CCTL_L1I_IX_INVAL__ --+ --+#define NDS32_CCTL_L1D_VA_INVAL __NDS32_CCTL_L1D_VA_INVAL__ --+#define NDS32_CCTL_L1D_VA_WB __NDS32_CCTL_L1D_VA_WB__ --+#define NDS32_CCTL_L1D_VA_WBINVAL __NDS32_CCTL_L1D_VA_WBINVAL__ --+#define NDS32_CCTL_L1I_VA_INVAL __NDS32_CCTL_L1I_VA_INVAL__ --+ --+#define NDS32_CCTL_L1D_IX_RTAG __NDS32_CCTL_L1D_IX_RTAG__ --+#define NDS32_CCTL_L1D_IX_RWD __NDS32_CCTL_L1D_IX_RWD__ --+#define NDS32_CCTL_L1I_IX_RTAG __NDS32_CCTL_L1I_IX_RTAG__ --+#define NDS32_CCTL_L1I_IX_RWD __NDS32_CCTL_L1I_IX_RWD__ --+ --+#define NDS32_CCTL_L1D_IX_WTAG __NDS32_CCTL_L1D_IX_WTAG__ --+#define NDS32_CCTL_L1D_IX_WWD __NDS32_CCTL_L1D_IX_WWD__ --+#define NDS32_CCTL_L1I_IX_WTAG __NDS32_CCTL_L1I_IX_WTAG__ --+#define NDS32_CCTL_L1I_IX_WWD __NDS32_CCTL_L1I_IX_WWD__ --+ --+#define NDS32_DPREF_SRD __NDS32_DPREF_SRD__ --+#define NDS32_DPREF_MRD __NDS32_DPREF_MRD__ --+#define NDS32_DPREF_SWR __NDS32_DPREF_SWR__ --+#define NDS32_DPREF_MWR __NDS32_DPREF_MWR__ --+#define NDS32_DPREF_PTE __NDS32_DPREF_PTE__ --+#define NDS32_DPREF_CLWR __NDS32_DPREF_CLWR__ --+ --+/* ------------------------------------------------------------------------ */ --+ --+/* Define user friendly macro. */ --+#define SIGNATURE_BEGIN __nds32__signature_begin () --+#define SIGNATURE_END __nds32__signature_end () --+ --+/* Map __nds32__xxx() to __builtin_xxx() functions for compatibility. */ --+#define __nds32__llw(a) \ --+ (__builtin_nds32_llw ((a))) --+#define __nds32__lwup(a) \ --+ (__builtin_nds32_lwup ((a))) --+#define __nds32__lbup(a) \ --+ (__builtin_nds32_lbup ((a))) --+#define __nds32__scw(a, b) \ --+ (__builtin_nds32_scw ((a), (b))) --+#define __nds32__swup(a, b) \ --+ (__builtin_nds32_swup ((a), (b))) --+#define __nds32__sbup(a, b) \ --+ (__builtin_nds32_sbup ((a), (b))) --+ --+#define __nds32__mfsr(srname) \ --+ (__builtin_nds32_mfsr ((srname))) --+#define __nds32__mfusr(usrname) \ --+ (__builtin_nds32_mfusr ((usrname))) --+#define __nds32__mtsr(val, srname) \ --+ (__builtin_nds32_mtsr ((val), (srname))) --+#define __nds32__mtsr_isb(val, srname) \ --+ (__builtin_nds32_mtsr_isb ((val), (srname))) --+#define __nds32__mtsr_dsb(val, srname) \ --+ (__builtin_nds32_mtsr_dsb ((val), (srname))) --+#define __nds32__mtusr(val, usrname) \ --+ (__builtin_nds32_mtusr ((val), (usrname))) --+ --+#define __nds32__break(swid) \ --+ (__builtin_nds32_break(swid)) --+#define __nds32__cctlva_lck(subtype, va) \ --+ (__builtin_nds32_cctl_va_lck ((subtype), (va))) --+#define __nds32__cctlidx_wbinval(subtype, idx) \ --+ (__builtin_nds32_cctl_idx_wbinval ((subtype), (idx))) --+#define __nds32__cctlva_wbinval_alvl(subtype, va) \ --+ (__builtin_nds32_cctl_va_wbinval_la ((subtype), (va))) --+#define __nds32__cctlva_wbinval_one_lvl(subtype, va) \ --+ (__builtin_nds32_cctl_va_wbinval_l1 ((subtype), (va))) --+#define __nds32__cctlidx_read(subtype, idx) \ --+ (__builtin_nds32_cctl_idx_read ((subtype), (idx))) --+#define __nds32__cctlidx_write(subtype, b, idxw) \ --+ (__builtin_nds32_cctl_idx_write ((subtype), (b), (idxw))) --+#define __nds32__cctl_l1d_invalall() \ --+ (__builtin_nds32_cctl_l1d_invalall()) --+#define __nds32__cctl_l1d_wball_alvl() \ --+ (__builtin_nds32_cctl_l1d_wball_alvl()) --+#define __nds32__cctl_l1d_wball_one_lvl() \ --+ (__builtin_nds32_cctl_l1d_wball_one_lvl()) --+ --+#define __nds32__dsb() \ --+ (__builtin_nds32_dsb()) --+#define __nds32__isb() \ --+ (__builtin_nds32_isb()) --+#define __nds32__msync_store() \ --+ (__builtin_nds32_msync_store()) --+#define __nds32__msync_all() \ --+ (__builtin_nds32_msync_all()) --+#define __nds32__nop() \ --+ (__builtin_nds32_nop()) --+ --+#define __nds32__standby_wait_done() \ --+ (__builtin_nds32_standby_wait_done()) --+#define __nds32__standby_no_wake_grant() \ --+ (__builtin_nds32_standby_no_wake_grant()) --+#define __nds32__standby_wake_grant() \ --+ (__builtin_nds32_standby_wake_grant()) --+#define __nds32__schedule_barrier() \ --+ (__builtin_nds32_schedule_barrier()) --+#define __nds32__setend_big() \ --+ (__builtin_nds32_setend_big()) --+#define __nds32__setend_little() \ --+ (__builtin_nds32_setend_little()) --+#define __nds32__setgie_en() \ --+ (__builtin_nds32_setgie_en()) --+#define __nds32__setgie_dis() \ --+ (__builtin_nds32_setgie_dis()) --+ --+#define __nds32__jr_itoff(a) \ --+ (__builtin_nds32_jr_itoff ((a))) --+#define __nds32__jr_toff(a) \ --+ (__builtin_nds32_jr_toff ((a))) --+#define __nds32__jral_iton(a) \ --+ (__builtin_nds32_jral_iton ((a))) --+#define __nds32__jral_ton(a) \ --+ (__builtin_nds32_jral_ton ((a))) --+#define __nds32__ret_itoff(a) \ --+ (__builtin_nds32_ret_itoff ((a))) --+#define __nds32__ret_toff(a) \ --+ (__builtin_nds32_ret_toff ((a))) --+#define __nds32__svs(a, b) \ --+ (__builtin_nds32_svs ((a), (b))) --+#define __nds32__sva(a, b) \ --+ (__builtin_nds32_sva ((a), (b))) --+#define __nds32__dpref_qw(a, b, subtype) \ --+ (__builtin_nds32_dpref_qw ((a), (b), (subtype))) --+#define __nds32__dpref_hw(a, b, subtype) \ --+ (__builtin_nds32_dpref_hw ((a), (b), (subtype))) --+#define __nds32__dpref_w(a, b, subtype) \ --+ (__builtin_nds32_dpref_w ((a), (b), (subtype))) --+#define __nds32__dpref_dw(a, b, subtype) \ --+ (__builtin_nds32_dpref_dw ((a), (b), (subtype))) --+ --+#define __nds32__teqz(a, swid) \ --+ (__builtin_nds32_teqz ((a), (swid))) --+#define __nds32__tnez(a, swid) \ --+ ( __builtin_nds32_tnez ((a), (swid))) --+#define __nds32__trap(swid) \ --+ (__builtin_nds32_trap ((swid))) --+#define __nds32__isync(a) \ --+ (__builtin_nds32_isync ((a))) --+#define __nds32__rotr(val, ror) \ --+ (__builtin_nds32_rotr ((val), (ror))) --+#define __nds32__wsbh(a) \ --+ (__builtin_nds32_wsbh ((a))) --+#define __nds32__syscall(a) \ --+ (__builtin_nds32_syscall ((a))) --+#define __nds32__return_address() \ --+ (__builtin_nds32_return_address()) --+#define __nds32__get_current_sp() \ --+ (__builtin_nds32_get_current_sp()) --+#define __nds32__set_current_sp(a) \ --+ (__builtin_nds32_set_current_sp ((a))) --+#define __nds32__abs(a) \ --+ (__builtin_nds32_pe_abs ((a))) --+#define __nds32__ave(a, b) \ --+ (__builtin_nds32_pe_ave ((a), (b))) --+#define __nds32__bclr(a, pos) \ --+ (__builtin_nds32_pe_bclr ((a), (pos))) --+#define __nds32__bset(a, pos) \ --+ (__builtin_nds32_pe_bset ((a), (pos))) --+#define __nds32__btgl(a, pos) \ --+ (__builtin_nds32_pe_btgl ((a), (pos))) --+#define __nds32__btst(a, pos) \ --+ (__builtin_nds32_pe_btst ((a), (pos))) --+ --+#define __nds32__clip(a, imm) \ --+ (__builtin_nds32_pe_clip ((a), (imm))) --+#define __nds32__clips(a, imm) \ --+ (__builtin_nds32_pe_clips ((a), (imm))) --+#define __nds32__clz(a) \ --+ (__builtin_nds32_pe_clz ((a))) --+#define __nds32__clo(a) \ --+ (__builtin_nds32_pe_clo ((a))) --+#define __nds32__bse(r, a, b) \ --+ (__builtin_nds32_pe2_bse ((r), (a), (b))) --+#define __nds32__bsp(r, a, b) \ --+ (__builtin_nds32_pe2_bsp ((r), (a), (b))) --+#define __nds32__pbsad(a, b) \ --+ (__builtin_nds32_pe2_pbsad ((a), (b))) --+#define __nds32__pbsada(acc, a, b) \ --+ (__builtin_nds32_pe2_pbsada ((acc), (a), (b))) --+ --+#define __nds32__ffb(a, b) \ --+ (__builtin_nds32_se_ffb ((a), (b))) --+#define __nds32__ffmism(a, b) \ --+ (__builtin_nds32_se_ffmism ((a), (b))) --+#define __nds32__flmism(a, b) \ --+ (__builtin_nds32_se_flmism ((a), (b))) --+#define __nds32__fcpynsd(a, b) \ --+ (__builtin_nds32_fcpynsd ((a), (b))) --+#define __nds32__fcpynss(a, b) \ --+ (__builtin_nds32_fcpynss ((a), (b))) --+#define __nds32__fcpysd(a, b) \ --+ (__builtin_nds32_fcpysd ((a), (b))) --+#define __nds32__fcpyss(a, b) \ --+ (__builtin_nds32_fcpyss ((a), (b))) --+#define __nds32__fmfcsr() \ --+ (__builtin_nds32_fmfcsr()) --+#define __nds32__fmtcsr(fpcsr) \ --+ (__builtin_nds32_fmtcsr ((fpcsr))) --+#define __nds32__fmfcfg() \ --+ (__builtin_nds32_fmfcfg()) --+ --+#define __nds32__tlbop_trd(a) \ --+ (__builtin_nds32_tlbop_trd ((a))) --+#define __nds32__tlbop_twr(a) \ --+ (__builtin_nds32_tlbop_twr ((a))) --+#define __nds32__tlbop_rwr(a) \ --+ (__builtin_nds32_tlbop_rwr ((a))) --+#define __nds32__tlbop_rwlk(a) \ --+ (__builtin_nds32_tlbop_rwlk ((a))) --+#define __nds32__tlbop_unlk(a) \ --+ (__builtin_nds32_tlbop_unlk ((a))) --+#define __nds32__tlbop_pb(a) \ --+ (__builtin_nds32_tlbop_pb ((a))) --+#define __nds32__tlbop_inv(a) \ --+ (__builtin_nds32_tlbop_inv ((a))) --+#define __nds32__tlbop_flua() \ --+(__builtin_nds32_tlbop_flua()) --+ --+#define __nds32__kaddw(a, b) \ --+ (__builtin_nds32_kaddw ((a), (b))) --+#define __nds32__kaddh(a, b) \ --+ (__builtin_nds32_kaddh ((a), (b))) --+#define __nds32__ksubw(a, b) \ --+ (__builtin_nds32_ksubw ((a), (b))) --+#define __nds32__ksubh(a, b) \ --+ (__builtin_nds32_ksubh ((a), (b))) --+#define __nds32__kdmbb(a, b) \ --+ (__builtin_nds32_kdmbb ((a), (b))) --+#define __nds32__v_kdmbb(a, b) \ --+ (__builtin_nds32_v_kdmbb ((a), (b))) --+#define __nds32__kdmbt(a, b) \ --+ (__builtin_nds32_kdmbt ((a), (b))) --+#define __nds32__v_kdmbt(a, b) \ --+ (__builtin_nds32_v_kdmbt ((a), (b))) --+#define __nds32__kdmtb(a, b) \ --+ (__builtin_nds32_kdmtb ((a), (b))) --+#define __nds32__v_kdmtb(a, b) \ --+ (__builtin_nds32_v_kdmtb ((a), (b))) --+#define __nds32__kdmtt(a, b) \ --+ (__builtin_nds32_kdmtt ((a), (b))) --+#define __nds32__v_kdmtt(a, b) \ --+ (__builtin_nds32_v_kdmtt ((a), (b))) --+#define __nds32__khmbb(a, b) \ --+ (__builtin_nds32_khmbb ((a), (b))) --+#define __nds32__v_khmbb(a, b) \ --+ (__builtin_nds32_v_khmbb ((a), (b))) --+#define __nds32__khmbt(a, b) \ --+ (__builtin_nds32_khmbt ((a), (b))) --+#define __nds32__v_khmbt(a, b) \ --+ (__builtin_nds32_v_khmbt ((a), (b))) --+#define __nds32__khmtb(a, b) \ --+ (__builtin_nds32_khmtb ((a), (b))) --+#define __nds32__v_khmtb(a, b) \ --+ (__builtin_nds32_v_khmtb ((a), (b))) --+#define __nds32__khmtt(a, b) \ --+ (__builtin_nds32_khmtt ((a), (b))) --+#define __nds32__v_khmtt(a, b) \ --+ (__builtin_nds32_v_khmtt ((a), (b))) --+#define __nds32__kslraw(a, b) \ --+ (__builtin_nds32_kslraw ((a), (b))) --+#define __nds32__kslraw_u(a, b) \ --+ (__builtin_nds32_kslraw_u ((a), (b))) --+ --+#define __nds32__rdov() \ --+ (__builtin_nds32_rdov()) --+#define __nds32__clrov() \ --+ (__builtin_nds32_clrov()) --+#define __nds32__gie_dis() \ --+ (__builtin_nds32_gie_dis()) --+#define __nds32__gie_en() \ --+ (__builtin_nds32_gie_en()) --+#define __nds32__enable_int(a) \ --+ (__builtin_nds32_enable_int ((a))) --+#define __nds32__disable_int(a) \ --+ (__builtin_nds32_disable_int ((a))) --+#define __nds32__set_pending_swint() \ --+ (__builtin_nds32_set_pending_swint()) --+#define __nds32__clr_pending_swint() \ --+ (__builtin_nds32_clr_pending_swint()) --+#define __nds32__clr_pending_hwint(a) \ --+ (__builtin_nds32_clr_pending_hwint(a)) --+#define __nds32__get_all_pending_int() \ --+ (__builtin_nds32_get_all_pending_int()) --+#define __nds32__get_pending_int(a) \ --+ (__builtin_nds32_get_pending_int ((a))) --+#define __nds32__set_int_priority(a, b) \ --+ (__builtin_nds32_set_int_priority ((a), (b))) --+#define __nds32__get_int_priority(a) \ --+ (__builtin_nds32_get_int_priority ((a))) --+#define __nds32__set_trig_type_level(a) \ --+ (__builtin_nds32_set_trig_level(a)) --+#define __nds32__set_trig_type_edge(a) \ --+ (__builtin_nds32_set_trig_edge(a)) --+#define __nds32__get_trig_type(a) \ --+ (__builtin_nds32_get_trig_type ((a))) --+ --+#define __nds32__get_unaligned_hw(a) \ --+ (__builtin_nds32_unaligned_load_hw ((a))) --+#define __nds32__get_unaligned_w(a) \ --+ (__builtin_nds32_unaligned_load_w ((a))) --+#define __nds32__get_unaligned_dw(a) \ --+ (__builtin_nds32_unaligned_load_dw ((a))) --+#define __nds32__put_unaligned_hw(a, data) \ --+ (__builtin_nds32_unaligned_store_hw ((a), (data))) --+#define __nds32__put_unaligned_w(a, data) \ --+ (__builtin_nds32_unaligned_store_w ((a), (data))) --+#define __nds32__put_unaligned_dw(a, data) \ --+ (__builtin_nds32_unaligned_store_dw ((a), (data))) --+ --+#define __nds32__signature_begin() \ --+ (__builtin_nds32_signature_begin ()) --+#define __nds32__signature_end() \ --+ (__builtin_nds32_signature_end ()) --+ --+#define __nds32__add16(a, b) \ --+ (__builtin_nds32_add16 ((a), (b))) --+#define __nds32__v_uadd16(a, b) \ --+ (__builtin_nds32_v_uadd16 ((a), (b))) --+#define __nds32__v_sadd16(a, b) \ --+ (__builtin_nds32_v_sadd16 ((a), (b))) --+#define __nds32__radd16(a, b) \ --+ (__builtin_nds32_radd16 ((a), (b))) --+#define __nds32__v_radd16(a, b) \ --+ (__builtin_nds32_v_radd16 ((a), (b))) --+#define __nds32__uradd16(a, b) \ --+ (__builtin_nds32_uradd16 ((a), (b))) --+#define __nds32__v_uradd16(a, b) \ --+ (__builtin_nds32_v_uradd16 ((a), (b))) --+#define __nds32__kadd16(a, b) \ --+ (__builtin_nds32_kadd16 ((a), (b))) --+#define __nds32__v_kadd16(a, b) \ --+ (__builtin_nds32_v_kadd16 ((a), (b))) --+#define __nds32__ukadd16(a, b) \ --+ (__builtin_nds32_ukadd16 ((a), (b))) --+#define __nds32__v_ukadd16(a, b) \ --+ (__builtin_nds32_v_ukadd16 ((a), (b))) --+#define __nds32__sub16(a, b) \ --+ (__builtin_nds32_sub16 ((a), (b))) --+#define __nds32__v_usub16(a, b) \ --+ (__builtin_nds32_v_usub16 ((a), (b))) --+#define __nds32__v_ssub16(a, b) \ --+ (__builtin_nds32_v_ssub16 ((a), (b))) --+#define __nds32__rsub16(a, b) \ --+ (__builtin_nds32_rsub16 ((a), (b))) --+#define __nds32__v_rsub16(a, b) \ --+ (__builtin_nds32_v_rsub16 ((a), (b))) --+#define __nds32__ursub16(a, b) \ --+ (__builtin_nds32_ursub16 ((a), (b))) --+#define __nds32__v_ursub16(a, b) \ --+ (__builtin_nds32_v_ursub16 ((a), (b))) --+#define __nds32__ksub16(a, b) \ --+ (__builtin_nds32_ksub16 ((a), (b))) --+#define __nds32__v_ksub16(a, b) \ --+ (__builtin_nds32_v_ksub16 ((a), (b))) --+#define __nds32__uksub16(a, b) \ --+ (__builtin_nds32_uksub16 ((a), (b))) --+#define __nds32__v_uksub16(a, b) \ --+ (__builtin_nds32_v_uksub16 ((a), (b))) --+#define __nds32__cras16(a, b) \ --+ (__builtin_nds32_cras16 ((a), (b))) --+#define __nds32__v_ucras16(a, b) \ --+ (__builtin_nds32_v_ucras16 ((a), (b))) --+#define __nds32__v_scras16(a, b) \ --+ (__builtin_nds32_v_scras16 ((a), (b))) --+#define __nds32__rcras16(a, b) \ --+ (__builtin_nds32_rcras16 ((a), (b))) --+#define __nds32__v_rcras16(a, b) \ --+ (__builtin_nds32_v_rcras16 ((a), (b))) --+#define __nds32__urcras16(a, b) \ --+ (__builtin_nds32_urcras16 ((a), (b))) --+#define __nds32__v_urcras16(a, b) \ --+ (__builtin_nds32_v_urcras16 ((a), (b))) --+#define __nds32__kcras16(a, b) \ --+ (__builtin_nds32_kcras16 ((a), (b))) --+#define __nds32__v_kcras16(a, b) \ --+ (__builtin_nds32_v_kcras16 ((a), (b))) --+#define __nds32__ukcras16(a, b) \ --+ (__builtin_nds32_ukcras16 ((a), (b))) --+#define __nds32__v_ukcras16(a, b) \ --+ (__builtin_nds32_v_ukcras16 ((a), (b))) --+#define __nds32__crsa16(a, b) \ --+ (__builtin_nds32_crsa16 ((a), (b))) --+#define __nds32__v_ucrsa16(a, b) \ --+ (__builtin_nds32_v_ucrsa16 ((a), (b))) --+#define __nds32__v_scrsa16(a, b) \ --+ (__builtin_nds32_v_scrsa16 ((a), (b))) --+#define __nds32__rcrsa16(a, b) \ --+ (__builtin_nds32_rcrsa16 ((a), (b))) --+#define __nds32__v_rcrsa16(a, b) \ --+ (__builtin_nds32_v_rcrsa16 ((a), (b))) --+#define __nds32__urcrsa16(a, b) \ --+ (__builtin_nds32_urcrsa16 ((a), (b))) --+#define __nds32__v_urcrsa16(a, b) \ --+ (__builtin_nds32_v_urcrsa16 ((a), (b))) --+#define __nds32__kcrsa16(a, b) \ --+ (__builtin_nds32_kcrsa16 ((a), (b))) --+#define __nds32__v_kcrsa16(a, b) \ --+ (__builtin_nds32_v_kcrsa16 ((a), (b))) --+#define __nds32__ukcrsa16(a, b) \ --+ (__builtin_nds32_ukcrsa16 ((a), (b))) --+#define __nds32__v_ukcrsa16(a, b) \ --+ (__builtin_nds32_v_ukcrsa16 ((a), (b))) --+ --+#define __nds32__add8(a, b) \ --+ (__builtin_nds32_add8 ((a), (b))) --+#define __nds32__v_uadd8(a, b) \ --+ (__builtin_nds32_v_uadd8 ((a), (b))) --+#define __nds32__v_sadd8(a, b) \ --+ (__builtin_nds32_v_sadd8 ((a), (b))) --+#define __nds32__radd8(a, b) \ --+ (__builtin_nds32_radd8 ((a), (b))) --+#define __nds32__v_radd8(a, b) \ --+ (__builtin_nds32_v_radd8 ((a), (b))) --+#define __nds32__uradd8(a, b) \ --+ (__builtin_nds32_uradd8 ((a), (b))) --+#define __nds32__v_uradd8(a, b) \ --+ (__builtin_nds32_v_uradd8 ((a), (b))) --+#define __nds32__kadd8(a, b) \ --+ (__builtin_nds32_kadd8 ((a), (b))) --+#define __nds32__v_kadd8(a, b) \ --+ (__builtin_nds32_v_kadd8 ((a), (b))) --+#define __nds32__ukadd8(a, b) \ --+ (__builtin_nds32_ukadd8 ((a), (b))) --+#define __nds32__v_ukadd8(a, b) \ --+ (__builtin_nds32_v_ukadd8 ((a), (b))) --+#define __nds32__sub8(a, b) \ --+ (__builtin_nds32_sub8 ((a), (b))) --+#define __nds32__v_usub8(a, b) \ --+ (__builtin_nds32_v_usub8 ((a), (b))) --+#define __nds32__v_ssub8(a, b) \ --+ (__builtin_nds32_v_ssub8 ((a), (b))) --+#define __nds32__rsub8(a, b) \ --+ (__builtin_nds32_rsub8 ((a), (b))) --+#define __nds32__v_rsub8(a, b) \ --+ (__builtin_nds32_v_rsub8 ((a), (b))) --+#define __nds32__ursub8(a, b) \ --+ (__builtin_nds32_ursub8 ((a), (b))) --+#define __nds32__v_ursub8(a, b) \ --+ (__builtin_nds32_v_ursub8 ((a), (b))) --+#define __nds32__ksub8(a, b) \ --+ (__builtin_nds32_ksub8 ((a), (b))) --+#define __nds32__v_ksub8(a, b) \ --+ (__builtin_nds32_v_ksub8 ((a), (b))) --+#define __nds32__uksub8(a, b) \ --+ (__builtin_nds32_uksub8 ((a), (b))) --+#define __nds32__v_uksub8(a, b) \ --+ (__builtin_nds32_v_uksub8 ((a), (b))) --+ --+#define __nds32__sra16(a, b) \ --+ (__builtin_nds32_sra16 ((a), (b))) --+#define __nds32__v_sra16(a, b) \ --+ (__builtin_nds32_v_sra16 ((a), (b))) --+#define __nds32__sra16_u(a, b) \ --+ (__builtin_nds32_sra16_u ((a), (b))) --+#define __nds32__v_sra16_u(a, b) \ --+ (__builtin_nds32_v_sra16_u ((a), (b))) --+#define __nds32__srl16(a, b) \ --+ (__builtin_nds32_srl16 ((a), (b))) --+#define __nds32__v_srl16(a, b) \ --+ (__builtin_nds32_v_srl16 ((a), (b))) --+#define __nds32__srl16_u(a, b) \ --+ (__builtin_nds32_srl16_u ((a), (b))) --+#define __nds32__v_srl16_u(a, b) \ --+ (__builtin_nds32_v_srl16_u ((a), (b))) --+#define __nds32__sll16(a, b) \ --+ (__builtin_nds32_sll16 ((a), (b))) --+#define __nds32__v_sll16(a, b) \ --+ (__builtin_nds32_v_sll16 ((a), (b))) --+#define __nds32__ksll16(a, b) \ --+ (__builtin_nds32_ksll16 ((a), (b))) --+#define __nds32__v_ksll16(a, b) \ --+ (__builtin_nds32_v_ksll16 ((a), (b))) --+#define __nds32__kslra16(a, b) \ --+ (__builtin_nds32_kslra16 ((a), (b))) --+#define __nds32__v_kslra16(a, b) \ --+ (__builtin_nds32_v_kslra16 ((a), (b))) --+#define __nds32__kslra16_u(a, b) \ --+ (__builtin_nds32_kslra16_u ((a), (b))) --+#define __nds32__v_kslra16_u(a, b) \ --+ (__builtin_nds32_v_kslra16_u ((a), (b))) --+ --+#define __nds32__cmpeq16(a, b) \ --+ (__builtin_nds32_cmpeq16 ((a), (b))) --+#define __nds32__v_scmpeq16(a, b) \ --+ (__builtin_nds32_v_scmpeq16 ((a), (b))) --+#define __nds32__v_ucmpeq16(a, b) \ --+ (__builtin_nds32_v_ucmpeq16 ((a), (b))) --+#define __nds32__scmplt16(a, b) \ --+ (__builtin_nds32_scmplt16 ((a), (b))) --+#define __nds32__v_scmplt16(a, b) \ --+ (__builtin_nds32_v_scmplt16 ((a), (b))) --+#define __nds32__scmple16(a, b) \ --+ (__builtin_nds32_scmple16 ((a), (b))) --+#define __nds32__v_scmple16(a, b) \ --+ (__builtin_nds32_v_scmple16 ((a), (b))) --+#define __nds32__ucmplt16(a, b) \ --+ (__builtin_nds32_ucmplt16 ((a), (b))) --+#define __nds32__v_ucmplt16(a, b) \ --+ (__builtin_nds32_v_ucmplt16 ((a), (b))) --+#define __nds32__ucmple16(a, b) \ --+ (__builtin_nds32_ucmple16 ((a), (b))) --+#define __nds32__v_ucmple16(a, b) \ --+ (__builtin_nds32_v_ucmple16 ((a), (b))) --+ --+#define __nds32__cmpeq8(a, b) \ --+ (__builtin_nds32_cmpeq8 ((a), (b))) --+#define __nds32__v_scmpeq8(a, b) \ --+ (__builtin_nds32_v_scmpeq8 ((a), (b))) --+#define __nds32__v_ucmpeq8(a, b) \ --+ (__builtin_nds32_v_ucmpeq8 ((a), (b))) --+#define __nds32__scmplt8(a, b) \ --+ (__builtin_nds32_scmplt8 ((a), (b))) --+#define __nds32__v_scmplt8(a, b) \ --+ (__builtin_nds32_v_scmplt8 ((a), (b))) --+#define __nds32__scmple8(a, b) \ --+ (__builtin_nds32_scmple8 ((a), (b))) --+#define __nds32__v_scmple8(a, b) \ --+ (__builtin_nds32_v_scmple8 ((a), (b))) --+#define __nds32__ucmplt8(a, b) \ --+ (__builtin_nds32_ucmplt8 ((a), (b))) --+#define __nds32__v_ucmplt8(a, b) \ --+ (__builtin_nds32_v_ucmplt8 ((a), (b))) --+#define __nds32__ucmple8(a, b) \ --+ (__builtin_nds32_ucmple8 ((a), (b))) --+#define __nds32__v_ucmple8(a, b) \ --+ (__builtin_nds32_v_ucmple8 ((a), (b))) --+ --+#define __nds32__smin16(a, b) \ --+ (__builtin_nds32_smin16 ((a), (b))) --+#define __nds32__v_smin16(a, b) \ --+ (__builtin_nds32_v_smin16 ((a), (b))) --+#define __nds32__umin16(a, b) \ --+ (__builtin_nds32_umin16 ((a), (b))) --+#define __nds32__v_umin16(a, b) \ --+ (__builtin_nds32_v_umin16 ((a), (b))) --+#define __nds32__smax16(a, b) \ --+ (__builtin_nds32_smax16 ((a), (b))) --+#define __nds32__v_smax16(a, b) \ --+ (__builtin_nds32_v_smax16 ((a), (b))) --+#define __nds32__umax16(a, b) \ --+ (__builtin_nds32_umax16 ((a), (b))) --+#define __nds32__v_umax16(a, b) \ --+ (__builtin_nds32_v_umax16 ((a), (b))) --+#define __nds32__sclip16(a, b) \ --+ (__builtin_nds32_sclip16 ((a), (b))) --+#define __nds32__v_sclip16(a, b) \ --+ (__builtin_nds32_v_sclip16 ((a), (b))) --+#define __nds32__uclip16(a, b) \ --+ (__builtin_nds32_uclip16 ((a), (b))) --+#define __nds32__v_uclip16(a, b) \ --+ (__builtin_nds32_v_uclip16 ((a), (b))) --+#define __nds32__khm16(a, b) \ --+ (__builtin_nds32_khm16 ((a), (b))) --+#define __nds32__v_khm16(a, b) \ --+ (__builtin_nds32_v_khm16 ((a), (b))) --+#define __nds32__khmx16(a, b) \ --+ (__builtin_nds32_khmx16 ((a), (b))) --+#define __nds32__v_khmx16(a, b) \ --+ (__builtin_nds32_v_khmx16 ((a), (b))) --+#define __nds32__kabs16(a) \ --+ (__builtin_nds32_kabs16 ((a))) --+#define __nds32__v_kabs16(a) \ --+ (__builtin_nds32_v_kabs16 ((a))) --+ --+#define __nds32__smin8(a, b) \ --+ (__builtin_nds32_smin8 ((a), (b))) --+#define __nds32__v_smin8(a, b) \ --+ (__builtin_nds32_v_smin8 ((a), (b))) --+#define __nds32__umin8(a, b) \ --+ (__builtin_nds32_umin8 ((a), (b))) --+#define __nds32__v_umin8(a, b) \ --+ (__builtin_nds32_v_umin8 ((a), (b))) --+#define __nds32__smax8(a, b) \ --+ (__builtin_nds32_smax8 ((a), (b))) --+#define __nds32__v_smax8(a, b) \ --+ (__builtin_nds32_v_smax8 ((a), (b))) --+#define __nds32__umax8(a, b) \ --+ (__builtin_nds32_umax8 ((a), (b))) --+#define __nds32__v_umax8(a, b) \ --+ (__builtin_nds32_v_umax8 ((a), (b))) --+#define __nds32__kabs8(a) \ --+ (__builtin_nds32_kabs8 ((a))) --+#define __nds32__v_kabs8(a) \ --+ (__builtin_nds32_v_kabs8 ((a))) --+ --+#define __nds32__sunpkd810(a) \ --+ (__builtin_nds32_sunpkd810 ((a))) --+#define __nds32__v_sunpkd810(a) \ --+ (__builtin_nds32_v_sunpkd810 ((a))) --+#define __nds32__sunpkd820(a) \ --+ (__builtin_nds32_sunpkd820 ((a))) --+#define __nds32__v_sunpkd820(a) \ --+ (__builtin_nds32_v_sunpkd820 ((a))) --+#define __nds32__sunpkd830(a) \ --+ (__builtin_nds32_sunpkd830 ((a))) --+#define __nds32__v_sunpkd830(a) \ --+ (__builtin_nds32_v_sunpkd830 ((a))) --+#define __nds32__sunpkd831(a) \ --+ (__builtin_nds32_sunpkd831 ((a))) --+#define __nds32__v_sunpkd831(a) \ --+ (__builtin_nds32_v_sunpkd831 ((a))) --+#define __nds32__zunpkd810(a) \ --+ (__builtin_nds32_zunpkd810 ((a))) --+#define __nds32__v_zunpkd810(a) \ --+ (__builtin_nds32_v_zunpkd810 ((a))) --+#define __nds32__zunpkd820(a) \ --+ (__builtin_nds32_zunpkd820 ((a))) --+#define __nds32__v_zunpkd820(a) \ --+ (__builtin_nds32_v_zunpkd820 ((a))) --+#define __nds32__zunpkd830(a) \ --+ (__builtin_nds32_zunpkd830 ((a))) --+#define __nds32__v_zunpkd830(a) \ --+ (__builtin_nds32_v_zunpkd830 ((a))) --+#define __nds32__zunpkd831(a) \ --+ (__builtin_nds32_zunpkd831 ((a))) --+#define __nds32__v_zunpkd831(a) \ --+ (__builtin_nds32_v_zunpkd831 ((a))) --+ --+#define __nds32__raddw(a, b) \ --+ (__builtin_nds32_raddw ((a), (b))) --+#define __nds32__uraddw(a, b) \ --+ (__builtin_nds32_uraddw ((a), (b))) --+#define __nds32__rsubw(a, b) \ --+ (__builtin_nds32_rsubw ((a), (b))) --+#define __nds32__ursubw(a, b) \ --+ (__builtin_nds32_ursubw ((a), (b))) --+ --+#define __nds32__sra_u(a, b) \ --+ (__builtin_nds32_sra_u ((a), (b))) --+#define __nds32__ksll(a, b) \ --+ (__builtin_nds32_ksll ((a), (b))) --+#define __nds32__pkbb16(a, b) \ --+ (__builtin_nds32_pkbb16 ((a), (b))) --+#define __nds32__v_pkbb16(a, b) \ --+ (__builtin_nds32_v_pkbb16 ((a), (b))) --+#define __nds32__pkbt16(a, b) \ --+ (__builtin_nds32_pkbt16 ((a), (b))) --+#define __nds32__v_pkbt16(a, b) \ --+ (__builtin_nds32_v_pkbt16 ((a), (b))) --+#define __nds32__pktb16(a, b) \ --+ (__builtin_nds32_pktb16 ((a), (b))) --+#define __nds32__v_pktb16(a, b) \ --+ (__builtin_nds32_v_pktb16 ((a), (b))) --+#define __nds32__pktt16(a, b) \ --+ (__builtin_nds32_pktt16 ((a), (b))) --+#define __nds32__v_pktt16(a, b) \ --+ (__builtin_nds32_v_pktt16 ((a), (b))) --+ --+#define __nds32__smmul(a, b) \ --+ (__builtin_nds32_smmul ((a), (b))) --+#define __nds32__smmul_u(a, b) \ --+ (__builtin_nds32_smmul_u ((a), (b))) --+#define __nds32__kmmac(r, a, b) \ --+ (__builtin_nds32_kmmac ((r), (a), (b))) --+#define __nds32__kmmac_u(r, a, b) \ --+ (__builtin_nds32_kmmac_u ((r), (a), (b))) --+#define __nds32__kmmsb(r, a, b) \ --+ (__builtin_nds32_kmmsb ((r), (a), (b))) --+#define __nds32__kmmsb_u(r, a, b) \ --+ (__builtin_nds32_kmmsb_u ((r), (a), (b))) --+#define __nds32__kwmmul(a, b) \ --+ (__builtin_nds32_kwmmul ((a), (b))) --+#define __nds32__kwmmul_u(a, b) \ --+ (__builtin_nds32_kwmmul_u ((a), (b))) --+ --+#define __nds32__smmwb(a, b) \ --+ (__builtin_nds32_smmwb ((a), (b))) --+#define __nds32__v_smmwb(a, b) \ --+ (__builtin_nds32_v_smmwb ((a), (b))) --+#define __nds32__smmwb_u(a, b) \ --+ (__builtin_nds32_smmwb_u ((a), (b))) --+#define __nds32__v_smmwb_u(a, b) \ --+ (__builtin_nds32_v_smmwb_u ((a), (b))) --+#define __nds32__smmwt(a, b) \ --+ (__builtin_nds32_smmwt ((a), (b))) --+#define __nds32__v_smmwt(a, b) \ --+ (__builtin_nds32_v_smmwt ((a), (b))) --+#define __nds32__smmwt_u(a, b) \ --+ (__builtin_nds32_smmwt_u ((a), (b))) --+#define __nds32__v_smmwt_u(a, b) \ --+ (__builtin_nds32_v_smmwt_u ((a), (b))) --+#define __nds32__kmmawb(r, a, b) \ --+ (__builtin_nds32_kmmawb ((r), (a), (b))) --+#define __nds32__v_kmmawb(r, a, b) \ --+ (__builtin_nds32_v_kmmawb ((r), (a), (b))) --+#define __nds32__kmmawb_u(r, a, b) \ --+ (__builtin_nds32_kmmawb_u ((r), (a), (b))) --+#define __nds32__v_kmmawb_u(r, a, b) \ --+ (__builtin_nds32_v_kmmawb_u ((r), (a), (b))) --+#define __nds32__kmmawt(r, a, b) \ --+ (__builtin_nds32_kmmawt ((r), (a), (b))) --+#define __nds32__v_kmmawt(r, a, b) \ --+ (__builtin_nds32_v_kmmawt ((r), (a), (b))) --+#define __nds32__kmmawt_u(r, a, b) \ --+ (__builtin_nds32_kmmawt_u ((r), (a), (b))) --+#define __nds32__v_kmmawt_u(r, a, b) \ --+ (__builtin_nds32_v_kmmawt_u ((r), (a), (b))) --+ --+#define __nds32__smbb(a, b) \ --+ (__builtin_nds32_smbb ((a), (b))) --+#define __nds32__v_smbb(a, b) \ --+ (__builtin_nds32_v_smbb ((a), (b))) --+#define __nds32__smbt(a, b) \ --+ (__builtin_nds32_smbt ((a), (b))) --+#define __nds32__v_smbt(a, b) \ --+ (__builtin_nds32_v_smbt ((a), (b))) --+#define __nds32__smtt(a, b) \ --+ (__builtin_nds32_smtt ((a), (b))) --+#define __nds32__v_smtt(a, b) \ --+ (__builtin_nds32_v_smtt ((a), (b))) --+#define __nds32__kmda(a, b) \ --+ (__builtin_nds32_kmda ((a), (b))) --+#define __nds32__v_kmda(a, b) \ --+ (__builtin_nds32_v_kmda ((a), (b))) --+#define __nds32__kmxda(a, b) \ --+ (__builtin_nds32_kmxda ((a), (b))) --+#define __nds32__v_kmxda(a, b) \ --+ (__builtin_nds32_v_kmxda ((a), (b))) --+#define __nds32__smds(a, b) \ --+ (__builtin_nds32_smds ((a), (b))) --+#define __nds32__v_smds(a, b) \ --+ (__builtin_nds32_v_smds ((a), (b))) --+#define __nds32__smdrs(a, b) \ --+ (__builtin_nds32_smdrs ((a), (b))) --+#define __nds32__v_smdrs(a, b) \ --+ (__builtin_nds32_v_smdrs ((a), (b))) --+#define __nds32__smxds(a, b) \ --+ (__builtin_nds32_smxds ((a), (b))) --+#define __nds32__v_smxds(a, b) \ --+ (__builtin_nds32_v_smxds ((a), (b))) --+#define __nds32__kmabb(r, a, b) \ --+ (__builtin_nds32_kmabb ((r), (a), (b))) --+#define __nds32__v_kmabb(r, a, b) \ --+ (__builtin_nds32_v_kmabb ((r), (a), (b))) --+#define __nds32__kmabt(r, a, b) \ --+ (__builtin_nds32_kmabt ((r), (a), (b))) --+#define __nds32__v_kmabt(r, a, b) \ --+ (__builtin_nds32_v_kmabt ((r), (a), (b))) --+#define __nds32__kmatt(r, a, b) \ --+ (__builtin_nds32_kmatt ((r), (a), (b))) --+#define __nds32__v_kmatt(r, a, b) \ --+ (__builtin_nds32_v_kmatt ((r), (a), (b))) --+#define __nds32__kmada(r, a, b) \ --+ (__builtin_nds32_kmada ((r), (a), (b))) --+#define __nds32__v_kmada(r, a, b) \ --+ (__builtin_nds32_v_kmada ((r), (a), (b))) --+#define __nds32__kmaxda(r, a, b) \ --+ (__builtin_nds32_kmaxda ((r), (a), (b))) --+#define __nds32__v_kmaxda(r, a, b) \ --+ (__builtin_nds32_v_kmaxda ((r), (a), (b))) --+#define __nds32__kmads(r, a, b) \ --+ (__builtin_nds32_kmads ((r), (a), (b))) --+#define __nds32__v_kmads(r, a, b) \ --+ (__builtin_nds32_v_kmads ((r), (a), (b))) --+#define __nds32__kmadrs(r, a, b) \ --+ (__builtin_nds32_kmadrs ((r), (a), (b))) --+#define __nds32__v_kmadrs(r, a, b) \ --+ (__builtin_nds32_v_kmadrs ((r), (a), (b))) --+#define __nds32__kmaxds(r, a, b) \ --+ (__builtin_nds32_kmaxds ((r), (a), (b))) --+#define __nds32__v_kmaxds(r, a, b) \ --+ (__builtin_nds32_v_kmaxds ((r), (a), (b))) --+#define __nds32__kmsda(r, a, b) \ --+ (__builtin_nds32_kmsda ((r), (a), (b))) --+#define __nds32__v_kmsda(r, a, b) \ --+ (__builtin_nds32_v_kmsda ((r), (a), (b))) --+#define __nds32__kmsxda(r, a, b) \ --+ (__builtin_nds32_kmsxda ((r), (a), (b))) --+#define __nds32__v_kmsxda(r, a, b) \ --+ (__builtin_nds32_v_kmsxda ((r), (a), (b))) --+ --+#define __nds32__smal(a, b) \ --+ (__builtin_nds32_smal ((a), (b))) --+#define __nds32__v_smal(a, b) \ --+ (__builtin_nds32_v_smal ((a), (b))) --+ --+#define __nds32__bitrev(a, b) \ --+ (__builtin_nds32_bitrev ((a), (b))) --+#define __nds32__wext(a, b) \ --+ (__builtin_nds32_wext ((a), (b))) --+#define __nds32__bpick(r, a, b) \ --+ (__builtin_nds32_bpick ((r), (a), (b))) --+#define __nds32__insb(r, a, b) \ --+ (__builtin_nds32_insb ((r), (a), (b))) --+ --+#define __nds32__sadd64(a, b) \ --+ (__builtin_nds32_sadd64 ((a), (b))) --+#define __nds32__uadd64(a, b) \ --+ (__builtin_nds32_uadd64 ((a), (b))) --+#define __nds32__radd64(a, b) \ --+ (__builtin_nds32_radd64 ((a), (b))) --+#define __nds32__uradd64(a, b) \ --+ (__builtin_nds32_uradd64 ((a), (b))) --+#define __nds32__kadd64(a, b) \ --+ (__builtin_nds32_kadd64 ((a), (b))) --+#define __nds32__ukadd64(a, b) \ --+ (__builtin_nds32_ukadd64 ((a), (b))) --+#define __nds32__ssub64(a, b) \ --+ (__builtin_nds32_ssub64 ((a), (b))) --+#define __nds32__usub64(a, b) \ --+ (__builtin_nds32_usub64 ((a), (b))) --+#define __nds32__rsub64(a, b) \ --+ (__builtin_nds32_rsub64 ((a), (b))) --+#define __nds32__ursub64(a, b) \ --+ (__builtin_nds32_ursub64 ((a), (b))) --+#define __nds32__ksub64(a, b) \ --+ (__builtin_nds32_ksub64 ((a), (b))) --+#define __nds32__uksub64(a, b) \ --+ (__builtin_nds32_uksub64 ((a), (b))) --+ --+#define __nds32__smar64(r, a, b) \ --+ (__builtin_nds32_smar64 ((r), (a), (b))) --+#define __nds32__smsr64(r, a, b) \ --+ (__builtin_nds32_smsr64 ((r), (a), (b))) --+#define __nds32__umar64(r, a, b) \ --+ (__builtin_nds32_umar64 ((r), (a), (b))) --+#define __nds32__umsr64(r, a, b) \ --+ (__builtin_nds32_umsr64 ((r), (a), (b))) --+#define __nds32__kmar64(r, a, b) \ --+ (__builtin_nds32_kmar64 ((r), (a), (b))) --+#define __nds32__kmsr64(r, a, b) \ --+ (__builtin_nds32_kmsr64 ((r), (a), (b))) --+#define __nds32__ukmar64(r, a, b) \ --+ (__builtin_nds32_ukmar64 ((r), (a), (b))) --+#define __nds32__ukmsr64(r, a, b) \ --+ (__builtin_nds32_ukmsr64 ((r), (a), (b))) --+ --+#define __nds32__smalbb(r, a, b) \ --+ (__builtin_nds32_smalbb ((r), (a), (b))) --+#define __nds32__v_smalbb(r, a, b) \ --+ (__builtin_nds32_v_smalbb ((r), (a), (b))) --+#define __nds32__smalbt(r, a, b) \ --+ (__builtin_nds32_smalbt ((r), (a), (b))) --+#define __nds32__v_smalbt(r, a, b) \ --+ (__builtin_nds32_v_smalbt ((r), (a), (b))) --+#define __nds32__smaltt(r, a, b) \ --+ (__builtin_nds32_smaltt ((r), (a), (b))) --+#define __nds32__v_smaltt(r, a, b) \ --+ (__builtin_nds32_v_smaltt ((r), (a), (b))) --+#define __nds32__smalda(r, a, b) \ --+ (__builtin_nds32_smalda ((r), (a), (b))) --+#define __nds32__v_smalda(r, a, b) \ --+ (__builtin_nds32_v_smalda ((r), (a), (b))) --+#define __nds32__smalxda(r, a, b) \ --+ (__builtin_nds32_smalxda ((r), (a), (b))) --+#define __nds32__v_smalxda(r, a, b) \ --+ (__builtin_nds32_v_smalxda ((r), (a), (b))) --+#define __nds32__smalds(r, a, b) \ --+ (__builtin_nds32_smalds ((r), (a), (b))) --+#define __nds32__v_smalds(r, a, b) \ --+ (__builtin_nds32_v_smalds ((r), (a), (b))) --+#define __nds32__smaldrs(r, a, b) \ --+ (__builtin_nds32_smaldrs ((r), (a), (b))) --+#define __nds32__v_smaldrs(r, a, b) \ --+ (__builtin_nds32_v_smaldrs ((r), (a), (b))) --+#define __nds32__smalxds(r, a, b) \ --+ (__builtin_nds32_smalxds ((r), (a), (b))) --+#define __nds32__v_smalxds(r, a, b) \ --+ (__builtin_nds32_v_smalxds ((r), (a), (b))) --+#define __nds32__smslda(r, a, b) \ --+ (__builtin_nds32_smslda ((r), (a), (b))) --+#define __nds32__v_smslda(r, a, b) \ --+ (__builtin_nds32_v_smslda ((r), (a), (b))) --+#define __nds32__smslxda(r, a, b) \ --+ (__builtin_nds32_smslxda ((r), (a), (b))) --+#define __nds32__v_smslxda(r, a, b) \ --+ (__builtin_nds32_v_smslxda ((r), (a), (b))) --+ --+#define __nds32__smul16(a, b) \ --+ (__builtin_nds32_smul16 ((a), (b))) --+#define __nds32__v_smul16(a, b) \ --+ (__builtin_nds32_v_smul16 ((a), (b))) --+#define __nds32__smulx16(a, b) \ --+ (__builtin_nds32_smulx16 ((a), (b))) --+#define __nds32__v_smulx16(a, b) \ --+ (__builtin_nds32_v_smulx16 ((a), (b))) --+#define __nds32__umul16(a, b) \ --+ (__builtin_nds32_umul16 ((a), (b))) --+#define __nds32__v_umul16(a, b) \ --+ (__builtin_nds32_v_umul16 ((a), (b))) --+#define __nds32__umulx16(a, b) \ --+ (__builtin_nds32_umulx16 ((a), (b))) --+#define __nds32__v_umulx16(a, b) \ --+ (__builtin_nds32_v_umulx16 ((a), (b))) --+ --+#define __nds32__uclip32(a, imm) \ --+ (__builtin_nds32_uclip32 ((a), (imm))) --+#define __nds32__sclip32(a, imm) \ --+ (__builtin_nds32_sclip32 ((a), (imm))) --+#define __nds32__kabs(a) \ --+ (__builtin_nds32_kabs ((a))) --+ --+#define __nds32__no_ext_zol() \ --+ (__builtin_nds32_no_ext_zol()) --+ --+#define __nds32__unaligned_feature() \ --+ (__builtin_nds32_unaligned_feature()) --+#define __nds32__enable_unaligned() \ --+ (__builtin_nds32_enable_unaligned()) --+#define __nds32__disable_unaligned() \ --+ (__builtin_nds32_disable_unaligned()) --+ --+#define __nds32__get_unaligned_u16x2(a) \ --+ (__builtin_nds32_get_unaligned_u16x2 ((a))) --+#define __nds32__get_unaligned_s16x2(a) \ --+ (__builtin_nds32_get_unaligned_s16x2 ((a))) --+#define __nds32__get_unaligned_u8x4(a) \ --+ (__builtin_nds32_get_unaligned_u8x4 ((a))) --+#define __nds32__get_unaligned_s8x4(a) \ --+ (__builtin_nds32_get_unaligned_s8x4 ((a))) --+ --+#define __nds32__put_unaligned_u16x2(a, data) \ --+ (__builtin_nds32_put_unaligned_u16x2 ((a), (data))) --+#define __nds32__put_unaligned_s16x2(a, data) \ --+ (__builtin_nds32_put_unaligned_s16x2 ((a), (data))) --+#define __nds32__put_unaligned_u8x4(a, data) \ --+ (__builtin_nds32_put_unaligned_u8x4 ((a), (data))) --+#define __nds32__put_unaligned_s8x4(a, data) \ --+ (__builtin_nds32_put_unaligned_s8x4 ((a), (data))) --+ --+#define NDS32ATTR_SIGNATURE __attribute__((signature)) --+ -- #endif /* nds32_intrinsic.h */ --diff --git a/gcc/config/nds32/nds32_isr.h b/gcc/config/nds32/nds32_isr.h --new file mode 100644 --index 0000000..6fabd3e ----- /dev/null --+++ b/gcc/config/nds32/nds32_isr.h --@@ -0,0 +1,526 @@ --+/* Intrinsic definitions of Andes NDS32 cpu for GNU compiler --+ Copyright (C) 2012-2016 Free Software Foundation, Inc. --+ Contributed by Andes Technology Corporation. --+ --+ This file is part of GCC. --+ --+ GCC is free software; you can redistribute it and/or modify it --+ under the terms of the GNU General Public License as published --+ by the Free Software Foundation; either version 3, or (at your --+ option) any later version. --+ --+ GCC is distributed in the hope that it will be useful, but WITHOUT --+ ANY WARRANTY; without even the implied warranty of MERCHANTABILITY --+ or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public --+ License for more details. --+ --+ Under Section 7 of GPL version 3, you are granted additional --+ permissions described in the GCC Runtime Library Exception, version --+ 3.1, as published by the Free Software Foundation. --+ --+ You should have received a copy of the GNU General Public License and --+ a copy of the GCC Runtime Library Exception along with this program; --+ see the files COPYING3 and COPYING.RUNTIME respectively. If not, see --+ . */ --+ --+#ifndef _NDS32_ISR_H --+#define _NDS32_ISR_H --+ --+/* Attribute of a interrupt or exception handler: --+ --+ NDS32_READY_NESTED: This handler is interruptible if user re-enable GIE bit. --+ NDS32_NESTED : This handler is interruptible. This is not suitable --+ exception handler. --+ NDS32_NOT_NESTED : This handler is NOT interruptible. Users have to do --+ some work if nested is wanted --+ NDS32_CRITICAL : This handler is critical ISR, which means it is small --+ and efficient. */ --+#define NDS32_READY_NESTED 0 --+#define NDS32_NESTED 1 --+#define NDS32_NOT_NESTED 2 --+#define NDS32_CRITICAL 3 --+ --+/* Attribute of a interrupt or exception handler: --+ --+ NDS32_SAVE_ALL_REGS : Save all registers in a table. --+ NDS32_SAVE_PARTIAL_REGS: Save partial registers. */ --+#define NDS32_SAVE_CALLER_REGS 0 --+#define NDS32_SAVE_ALL_REGS 1 --+ --+/* There are two version of Register table for interrupt and exception handler, --+ one for 16-register CPU the other for 32-register CPU. These structures are --+ used for context switching or system call handling. The address of this --+ data can be get from the input argument of the handler functions. --+ --+ For system call handling, r0 to r5 are used to pass arguments. If more --+ arguments are used they are put into the stack and its starting address is --+ in sp. Return value of system call can be put into r0 and r1 upon exit from --+ system call handler. System call ID is in a system register and it can be --+ fetched via intrinsic function. For more information please read ABI and --+ other related documents. --+ --+ For context switching, at least 2 values need to saved in kernel. One is --+ IPC and the other is the stack address of current task. Use intrinsic --+ function to get IPC and the input argument of the handler functions + 8 to --+ get stack address of current task. To do context switching, you replace --+ new_sp with the stack address of new task and replace IPC system register --+ with IPC of new task, then, just return from handler. The context switching --+ will happen. */ --+ --+/* Register table for exception handler; 32-register version. */ --+typedef struct --+{ --+ int r0; --+ int r1; --+ int r2; --+ int r3; --+ int r4; --+ int r5; --+ int r6; --+ int r7; --+ int r8; --+ int r9; --+ int r10; --+ int r11; --+ int r12; --+ int r13; --+ int r14; --+ int r15; --+ int r16; --+ int r17; --+ int r18; --+ int r19; --+ int r20; --+ int r21; --+ int r22; --+ int r23; --+ int r24; --+ int r25; --+ int r26; --+ int r27; --+ int fp; --+ int gp; --+ int lp; --+ int sp; --+} NDS32_GPR32; --+ --+/* Register table for exception handler; 16-register version. */ --+typedef struct --+{ --+ int r0; --+ int r1; --+ int r2; --+ int r3; --+ int r4; --+ int r5; --+ int r6; --+ int r7; --+ int r8; --+ int r9; --+ int r10; --+ int r15; --+ int fp; --+ int gp; --+ int lp; --+ int sp; --+} NDS32_GPR16; --+ --+ --+/* Use NDS32_REG32_TAB or NDS32_REG16_TAB in your program to --+ access register table. */ --+typedef struct --+{ --+ union --+ { --+ int reg_a[32] ; --+ NDS32_GPR32 reg_s ; --+ } u ; --+} NDS32_REG32_TAB; --+ --+typedef struct --+{ --+ union --+ { --+ int reg_a[16] ; --+ NDS32_GPR16 reg_s ; --+ } u ; --+} NDS32_REG16_TAB; --+ --+typedef struct --+{ --+ int d0lo; --+ int d0hi; --+ int d1lo; --+ int d1hi; --+} NDS32_DX_TAB; --+ --+typedef struct --+{ --+#ifdef __NDS32_EB__ --+ float fsr0; --+ float fsr1; --+ float fsr2; --+ float fsr3; --+ float fsr4; --+ float fsr5; --+ float fsr6; --+ float fsr7; --+#else --+ float fsr1; --+ float fsr0; --+ float fsr3; --+ float fsr2; --+ float fsr5; --+ float fsr4; --+ float fsr7; --+ float fsr6; --+#endif --+} NDS32_FSR8; --+ --+typedef struct --+{ --+ double dsr0; --+ double dsr1; --+ double dsr2; --+ double dsr3; --+} NDS32_DSR4; --+ --+typedef struct --+{ --+#ifdef __NDS32_EB__ --+ float fsr0; --+ float fsr1; --+ float fsr2; --+ float fsr3; --+ float fsr4; --+ float fsr5; --+ float fsr6; --+ float fsr7; --+ float fsr8; --+ float fsr9; --+ float fsr10; --+ float fsr11; --+ float fsr12; --+ float fsr13; --+ float fsr14; --+ float fsr15; --+#else --+ float fsr1; --+ float fsr0; --+ float fsr3; --+ float fsr2; --+ float fsr5; --+ float fsr4; --+ float fsr7; --+ float fsr6; --+ float fsr9; --+ float fsr8; --+ float fsr11; --+ float fsr10; --+ float fsr13; --+ float fsr12; --+ float fsr15; --+ float fsr14; --+#endif --+} NDS32_FSR16; --+ --+typedef struct --+{ --+ double dsr0; --+ double dsr1; --+ double dsr2; --+ double dsr3; --+ double dsr4; --+ double dsr5; --+ double dsr6; --+ double dsr7; --+} NDS32_DSR8; --+ --+typedef struct --+{ --+#ifdef __NDS32_EB__ --+ float fsr0; --+ float fsr1; --+ float fsr2; --+ float fsr3; --+ float fsr4; --+ float fsr5; --+ float fsr6; --+ float fsr7; --+ float fsr8; --+ float fsr9; --+ float fsr10; --+ float fsr11; --+ float fsr12; --+ float fsr13; --+ float fsr14; --+ float fsr15; --+ float fsr16; --+ float fsr17; --+ float fsr18; --+ float fsr19; --+ float fsr20; --+ float fsr21; --+ float fsr22; --+ float fsr23; --+ float fsr24; --+ float fsr25; --+ float fsr26; --+ float fsr27; --+ float fsr28; --+ float fsr29; --+ float fsr30; --+ float fsr31; --+#else --+ float fsr1; --+ float fsr0; --+ float fsr3; --+ float fsr2; --+ float fsr5; --+ float fsr4; --+ float fsr7; --+ float fsr6; --+ float fsr9; --+ float fsr8; --+ float fsr11; --+ float fsr10; --+ float fsr13; --+ float fsr12; --+ float fsr15; --+ float fsr14; --+ float fsr17; --+ float fsr16; --+ float fsr19; --+ float fsr18; --+ float fsr21; --+ float fsr20; --+ float fsr23; --+ float fsr22; --+ float fsr25; --+ float fsr24; --+ float fsr27; --+ float fsr26; --+ float fsr29; --+ float fsr28; --+ float fsr31; --+ float fsr30; --+#endif --+} NDS32_FSR32; --+ --+typedef struct --+{ --+ double dsr0; --+ double dsr1; --+ double dsr2; --+ double dsr3; --+ double dsr4; --+ double dsr5; --+ double dsr6; --+ double dsr7; --+ double dsr8; --+ double dsr9; --+ double dsr10; --+ double dsr11; --+ double dsr12; --+ double dsr13; --+ double dsr14; --+ double dsr15; --+} NDS32_DSR16; --+ --+typedef struct --+{ --+ double dsr0; --+ double dsr1; --+ double dsr2; --+ double dsr3; --+ double dsr4; --+ double dsr5; --+ double dsr6; --+ double dsr7; --+ double dsr8; --+ double dsr9; --+ double dsr10; --+ double dsr11; --+ double dsr12; --+ double dsr13; --+ double dsr14; --+ double dsr15; --+ double dsr16; --+ double dsr17; --+ double dsr18; --+ double dsr19; --+ double dsr20; --+ double dsr21; --+ double dsr22; --+ double dsr23; --+ double dsr24; --+ double dsr25; --+ double dsr26; --+ double dsr27; --+ double dsr28; --+ double dsr29; --+ double dsr30; --+ double dsr31; --+} NDS32_DSR32; --+ --+typedef struct --+{ --+ union --+ { --+ NDS32_FSR8 fsr_s ; --+ NDS32_DSR4 dsr_s ; --+ } u ; --+} NDS32_FPU8_TAB; --+ --+typedef struct --+{ --+ union --+ { --+ NDS32_FSR16 fsr_s ; --+ NDS32_DSR8 dsr_s ; --+ } u ; --+} NDS32_FPU16_TAB; --+ --+typedef struct --+{ --+ union --+ { --+ NDS32_FSR32 fsr_s ; --+ NDS32_DSR16 dsr_s ; --+ } u ; --+} NDS32_FPU32_TAB; --+ --+typedef struct --+{ --+ union --+ { --+ NDS32_FSR32 fsr_s ; --+ NDS32_DSR32 dsr_s ; --+ } u ; --+} NDS32_FPU64_TAB; --+ --+typedef struct --+{ --+ int ipc; --+ int ipsw; --+#if defined(NDS32_EXT_FPU_CONFIG_0) --+ NDS32_FPU8_TAB fpr; --+#elif defined(NDS32_EXT_FPU_CONFIG_1) --+ NDS32_FPU16_TAB fpr; --+#elif defined(NDS32_EXT_FPU_CONFIG_2) --+ NDS32_FPU32_TAB fpr; --+#elif defined(NDS32_EXT_FPU_CONFIG_3) --+ NDS32_FPU64_TAB fpr; --+#endif --+#if __NDS32_DX_REGS__ --+ NDS32_DX_TAB dxr; --+#endif --+#if __NDS32_EXT_IFC__ --+ int ifc_lp; --+ int filler; --+#endif --+#if __NDS32_REDUCED_REGS__ || __NDS32_REDUCE_REGS --+ NDS32_REG16_TAB gpr; --+#else --+ NDS32_REG32_TAB gpr; --+#endif --+} NDS32_CONTEXT; --+ --+/* Predefined Vector Definition. --+ --+ For IVIC Mode: 9 to 14 are for hardware interrupt --+ and 15 is for software interrupt. --+ For EVIC Mode: 9 to 72 are for hardware interrupt --+ and software interrupt can be routed to any one of them. --+ --+ You may want to define your hardware interrupts in the following way --+ for easy maintainance. --+ --+ IVIC mode: --+ #define MY_HW_IVIC_TIMER NDS32_VECTOR_INTERRUPT_HW0 + 1 --+ #define MY_HW_IVIC_USB NDS32_VECTOR_INTERRUPT_HW0 + 3 --+ EVIC mode: --+ #define MY_HW_EVIC_DMA NDS32_VECTOR_INTERRUPT_HW0 + 2 --+ #define MY_HW_EVIC_SWI NDS32_VECTOR_INTERRUPT_HW0 + 10 */ --+#define NDS32_VECTOR_RESET 0 --+#define NDS32_VECTOR_TLB_FILL 1 --+#define NDS32_VECTOR_PTE_NOT_PRESENT 2 --+#define NDS32_VECTOR_TLB_MISC 3 --+#define NDS32_VECTOR_TLB_VLPT_MISS 4 --+#define NDS32_VECTOR_MACHINE_ERROR 5 --+#define NDS32_VECTOR_DEBUG_RELATED 6 --+#define NDS32_VECTOR_GENERAL_EXCEPTION 7 --+#define NDS32_VECTOR_SYSCALL 8 --+#define NDS32_VECTOR_INTERRUPT_HW0 9 --+#define NDS32_VECTOR_INTERRUPT_HW1 10 --+#define NDS32_VECTOR_INTERRUPT_HW2 11 --+#define NDS32_VECTOR_INTERRUPT_HW3 12 --+#define NDS32_VECTOR_INTERRUPT_HW4 13 --+#define NDS32_VECTOR_INTERRUPT_HW5 14 --+#define NDS32_VECTOR_INTERRUPT_HW6 15 --+#define NDS32_VECTOR_SWI 15 /* THIS IS FOR IVIC MODE ONLY */ --+#define NDS32_VECTOR_INTERRUPT_HW7 16 --+#define NDS32_VECTOR_INTERRUPT_HW8 17 --+#define NDS32_VECTOR_INTERRUPT_HW9 18 --+#define NDS32_VECTOR_INTERRUPT_HW10 19 --+#define NDS32_VECTOR_INTERRUPT_HW11 20 --+#define NDS32_VECTOR_INTERRUPT_HW12 21 --+#define NDS32_VECTOR_INTERRUPT_HW13 22 --+#define NDS32_VECTOR_INTERRUPT_HW14 23 --+#define NDS32_VECTOR_INTERRUPT_HW15 24 --+#define NDS32_VECTOR_INTERRUPT_HW16 25 --+#define NDS32_VECTOR_INTERRUPT_HW17 26 --+#define NDS32_VECTOR_INTERRUPT_HW18 27 --+#define NDS32_VECTOR_INTERRUPT_HW19 28 --+#define NDS32_VECTOR_INTERRUPT_HW20 29 --+#define NDS32_VECTOR_INTERRUPT_HW21 30 --+#define NDS32_VECTOR_INTERRUPT_HW22 31 --+#define NDS32_VECTOR_INTERRUPT_HW23 32 --+#define NDS32_VECTOR_INTERRUPT_HW24 33 --+#define NDS32_VECTOR_INTERRUPT_HW25 34 --+#define NDS32_VECTOR_INTERRUPT_HW26 35 --+#define NDS32_VECTOR_INTERRUPT_HW27 36 --+#define NDS32_VECTOR_INTERRUPT_HW28 37 --+#define NDS32_VECTOR_INTERRUPT_HW29 38 --+#define NDS32_VECTOR_INTERRUPT_HW30 39 --+#define NDS32_VECTOR_INTERRUPT_HW31 40 --+#define NDS32_VECTOR_INTERRUPT_HW32 41 --+#define NDS32_VECTOR_INTERRUPT_HW33 42 --+#define NDS32_VECTOR_INTERRUPT_HW34 43 --+#define NDS32_VECTOR_INTERRUPT_HW35 44 --+#define NDS32_VECTOR_INTERRUPT_HW36 45 --+#define NDS32_VECTOR_INTERRUPT_HW37 46 --+#define NDS32_VECTOR_INTERRUPT_HW38 47 --+#define NDS32_VECTOR_INTERRUPT_HW39 48 --+#define NDS32_VECTOR_INTERRUPT_HW40 49 --+#define NDS32_VECTOR_INTERRUPT_HW41 50 --+#define NDS32_VECTOR_INTERRUPT_HW42 51 --+#define NDS32_VECTOR_INTERRUPT_HW43 52 --+#define NDS32_VECTOR_INTERRUPT_HW44 53 --+#define NDS32_VECTOR_INTERRUPT_HW45 54 --+#define NDS32_VECTOR_INTERRUPT_HW46 55 --+#define NDS32_VECTOR_INTERRUPT_HW47 56 --+#define NDS32_VECTOR_INTERRUPT_HW48 57 --+#define NDS32_VECTOR_INTERRUPT_HW49 58 --+#define NDS32_VECTOR_INTERRUPT_HW50 59 --+#define NDS32_VECTOR_INTERRUPT_HW51 60 --+#define NDS32_VECTOR_INTERRUPT_HW52 61 --+#define NDS32_VECTOR_INTERRUPT_HW53 62 --+#define NDS32_VECTOR_INTERRUPT_HW54 63 --+#define NDS32_VECTOR_INTERRUPT_HW55 64 --+#define NDS32_VECTOR_INTERRUPT_HW56 65 --+#define NDS32_VECTOR_INTERRUPT_HW57 66 --+#define NDS32_VECTOR_INTERRUPT_HW58 67 --+#define NDS32_VECTOR_INTERRUPT_HW59 68 --+#define NDS32_VECTOR_INTERRUPT_HW60 69 --+#define NDS32_VECTOR_INTERRUPT_HW61 70 --+#define NDS32_VECTOR_INTERRUPT_HW62 71 --+#define NDS32_VECTOR_INTERRUPT_HW63 72 --+ --+#define NDS32ATTR_RESET(option) __attribute__((reset(option))) --+#define NDS32ATTR_EXCEPT(type) __attribute__((exception(type))) --+#define NDS32ATTR_EXCEPTION(type) __attribute__((exception(type))) --+#define NDS32ATTR_INTERRUPT(type) __attribute__((interrupt(type))) --+#define NDS32ATTR_ISR(type) __attribute__((interrupt(type))) --+ --+#endif /* nds32_isr.h */ --diff --git a/gcc/config/nds32/pipelines.md b/gcc/config/nds32/pipelines.md --index f7e2fa8..6cd854d 100644 ----- a/gcc/config/nds32/pipelines.md --+++ b/gcc/config/nds32/pipelines.md --@@ -18,12 +18,65 @@ -- ;; along with GCC; see the file COPYING3. If not see -- ;; . -- ---(define_automaton "nds32_machine") --+;; ------------------------------------------------------------------------ --+;; Include N7 pipeline settings. --+;; ------------------------------------------------------------------------ --+(include "nds32-n7.md") --+ --+ --+;; ------------------------------------------------------------------------ --+;; Include N8 pipeline settings. --+;; ------------------------------------------------------------------------ --+(include "nds32-n8.md") --+ --+ --+;; ------------------------------------------------------------------------ --+;; Include E8 pipeline settings. --+;; ------------------------------------------------------------------------ --+(include "nds32-e8.md") --+ --+ --+;; ------------------------------------------------------------------------ --+;; Include N9/N10 pipeline settings. --+;; ------------------------------------------------------------------------ --+(include "nds32-n9-3r2w.md") --+(include "nds32-n9-2r1w.md") --+ --+ --+;; ------------------------------------------------------------------------ --+;; Include N10 pipeline settings. --+;; ------------------------------------------------------------------------ --+(include "nds32-n10.md") --+ --+ --+;; ------------------------------------------------------------------------ --+;; Include Graywolf pipeline settings. --+;; ------------------------------------------------------------------------ --+(include "nds32-graywolf.md") --+ --+ --+;; ------------------------------------------------------------------------ --+;; Include N12/N13 pipeline settings. --+;; ------------------------------------------------------------------------ --+(include "nds32-n13.md") --+ --+ --+;; ------------------------------------------------------------------------ --+;; Include Panther pipeline settings. --+;; ------------------------------------------------------------------------ --+(include "nds32-panther.md") --+ --+ --+;; ------------------------------------------------------------------------ --+;; Define simple pipeline settings. --+;; ------------------------------------------------------------------------ --+ --+(define_automaton "nds32_simple_machine") -- ---(define_cpu_unit "general_unit" "nds32_machine") --+(define_cpu_unit "simple_unit" "nds32_simple_machine") -- -- (define_insn_reservation "simple_insn" 1 --- (eq_attr "type" "unknown,load,store,move,alu,compare,branch,call,misc") --- "general_unit") --+ (eq_attr "pipeline_model" "simple") --+ "simple_unit") -- -- ;; ------------------------------------------------------------------------ --diff --git a/gcc/config/nds32/predicates.md b/gcc/config/nds32/predicates.md --index 05a039d..71a3615 100644 ----- a/gcc/config/nds32/predicates.md --+++ b/gcc/config/nds32/predicates.md --@@ -24,25 +24,93 @@ -- (define_predicate "nds32_greater_less_comparison_operator" -- (match_code "gt,ge,lt,le")) -- --+(define_predicate "nds32_float_comparison_operator" --+ (match_code "eq,ne,le,lt,ge,gt,ordered,unordered,ungt,unge,unlt,unle")) --+ --+(define_predicate "nds32_movecc_comparison_operator" --+ (match_code "eq,ne,le,leu,ge,geu")) --+ -- (define_special_predicate "nds32_logical_binary_operator" -- (match_code "and,ior,xor")) -- --+(define_special_predicate "nds32_conditional_call_comparison_operator" --+ (match_code "lt,ge")) --+ --+(define_special_predicate "nds32_have_33_inst_operator" --+ (match_code "mult,and,ior,xor")) --+ -- (define_predicate "nds32_symbolic_operand" --- (match_code "const,symbol_ref,label_ref")) --+ (and (match_code "const,symbol_ref,label_ref") --+ (match_test "!(TARGET_ICT_MODEL_LARGE --+ && nds32_indirect_call_referenced_p (op))"))) --+ --+(define_predicate "nds32_nonunspec_symbolic_operand" --+ (and (match_code "const,symbol_ref,label_ref") --+ (match_test "!flag_pic && nds32_const_unspec_p (op) --+ && !(TARGET_ICT_MODEL_LARGE --+ && nds32_indirect_call_referenced_p (op))"))) --+ --+(define_predicate "nds32_label_operand" --+ (match_code "label_ref")) -- -- (define_predicate "nds32_reg_constant_operand" --- (ior (match_operand 0 "register_operand") --- (match_operand 0 "const_int_operand"))) --+ (match_code "reg,const_int")) -- -- (define_predicate "nds32_rimm15s_operand" -- (ior (match_operand 0 "register_operand") -- (and (match_operand 0 "const_int_operand") -- (match_test "satisfies_constraint_Is15 (op)")))) -- --+(define_predicate "nds32_rimm11s_operand" --+ (ior (match_operand 0 "register_operand") --+ (and (match_operand 0 "const_int_operand") --+ (match_test "satisfies_constraint_Is11 (op)")))) --+ --+(define_predicate "nds32_imm_0_1_operand" --+ (and (match_operand 0 "const_int_operand") --+ (ior (match_test "satisfies_constraint_Iv00 (op)") --+ (match_test "satisfies_constraint_Iv01 (op)")))) --+ --+(define_predicate "nds32_imm_1_2_operand" --+ (and (match_operand 0 "const_int_operand") --+ (ior (match_test "satisfies_constraint_Iv01 (op)") --+ (match_test "satisfies_constraint_Iv02 (op)")))) --+ --+(define_predicate "nds32_imm_1_2_4_8_operand" --+ (and (match_operand 0 "const_int_operand") --+ (ior (ior (match_test "satisfies_constraint_Iv01 (op)") --+ (match_test "satisfies_constraint_Iv02 (op)")) --+ (ior (match_test "satisfies_constraint_Iv04 (op)") --+ (match_test "satisfies_constraint_Iv08 (op)"))))) --+ --+(define_predicate "nds32_imm2u_operand" --+ (and (match_operand 0 "const_int_operand") --+ (match_test "satisfies_constraint_Iu02 (op)"))) --+ --+(define_predicate "nds32_imm4u_operand" --+ (and (match_operand 0 "const_int_operand") --+ (match_test "satisfies_constraint_Iu04 (op)"))) --+ -- (define_predicate "nds32_imm5u_operand" -- (and (match_operand 0 "const_int_operand") -- (match_test "satisfies_constraint_Iu05 (op)"))) -- --+(define_predicate "nds32_imm6u_operand" --+ (and (match_operand 0 "const_int_operand") --+ (match_test "satisfies_constraint_Iu06 (op)"))) --+ --+(define_predicate "nds32_rimm4u_operand" --+ (ior (match_operand 0 "register_operand") --+ (match_operand 0 "nds32_imm4u_operand"))) --+ --+(define_predicate "nds32_rimm5u_operand" --+ (ior (match_operand 0 "register_operand") --+ (match_operand 0 "nds32_imm5u_operand"))) --+ --+(define_predicate "nds32_rimm6u_operand" --+ (ior (match_operand 0 "register_operand") --+ (match_operand 0 "nds32_imm6u_operand"))) --+ -- (define_predicate "nds32_move_operand" -- (and (match_operand 0 "general_operand") -- (not (match_code "high,const,symbol_ref,label_ref"))) --@@ -57,12 +125,121 @@ -- return true; -- }) -- --+(define_predicate "nds32_vmove_operand" --+ (and (match_operand 0 "general_operand") --+ (not (match_code "high,const,symbol_ref,label_ref"))) --+{ --+ /* If the constant op does NOT satisfy Is20 nor Ihig, --+ we can not perform move behavior by a single instruction. */ --+ if (GET_CODE (op) == CONST_VECTOR --+ && !satisfies_constraint_CVs2 (op) --+ && !satisfies_constraint_CVhi (op)) --+ return false; --+ --+ return true; --+}) --+ --+(define_predicate "nds32_and_operand" --+ (match_code "reg,const_int") --+{ --+ return (REG_P (op) && GET_MODE (op) == mode) --+ || satisfies_constraint_Izeb (op) --+ || satisfies_constraint_Izeh (op) --+ || satisfies_constraint_Ixls (op) --+ || satisfies_constraint_Ix11 (op) --+ || satisfies_constraint_Ibms (op) --+ || satisfies_constraint_Ifex (op) --+ || satisfies_constraint_Iu15 (op) --+ || satisfies_constraint_Ii15 (op) --+ || satisfies_constraint_Ic15 (op); --+}) --+ --+(define_predicate "nds32_ior_operand" --+ (match_code "reg,const_int") --+{ --+ return (REG_P (op) && GET_MODE (op) == mode) --+ || satisfies_constraint_Iu15 (op) --+ || satisfies_constraint_Ie15 (op); --+}) --+ --+(define_predicate "nds32_xor_operand" --+ (match_code "reg,const_int") --+{ --+ return (REG_P (op) && GET_MODE (op) == mode) --+ || GET_CODE (op) == SUBREG --+ || satisfies_constraint_Iu15 (op) --+ || satisfies_constraint_It15 (op); --+}) --+ --+(define_predicate "nds32_general_register_operand" --+ (match_code "reg,subreg") --+{ --+ if (GET_CODE (op) == SUBREG) --+ op = SUBREG_REG (op); --+ --+ return (REG_P (op) --+ && (REGNO (op) >= FIRST_PSEUDO_REGISTER --+ || REGNO (op) <= NDS32_LAST_GPR_REGNUM)); --+}) --+ --+(define_predicate "nds32_fpu_register_operand" --+ (match_code "reg,subreg") --+{ --+ if (GET_CODE (op) == SUBREG) --+ op = SUBREG_REG (op); --+ --+ return (REG_P (op) --+ && NDS32_IS_FPR_REGNUM (REGNO (op))); --+}) --+ --+(define_predicate "fpu_reg_or_memory_operand" --+ (ior (match_operand 0 "nds32_fpu_register_operand") --+ (match_operand 0 "memory_operand"))) --+ --+(define_predicate "nds32_call_address_operand" --+ (ior (match_operand 0 "nds32_symbolic_operand") --+ (match_operand 0 "nds32_general_register_operand"))) --+ --+(define_predicate "nds32_insv_operand" --+ (match_code "const_int") --+{ --+ return INTVAL (op) == 0 --+ || INTVAL (op) == 8 --+ || INTVAL (op) == 16 --+ || INTVAL (op) == 24; --+}) --+ --+(define_predicate "nds32_lmw_smw_base_operand" --+ (and (match_code "mem") --+ (match_test "nds32_valid_smw_lwm_base_p (op)"))) --+ --+(define_predicate "float_even_register_operand" --+ (and (match_code "reg") --+ (and (match_test "REGNO (op) >= NDS32_FIRST_FPR_REGNUM") --+ (match_test "REGNO (op) <= NDS32_LAST_FPR_REGNUM") --+ (match_test "(REGNO (op) & 1) == 0")))) --+ --+(define_predicate "float_odd_register_operand" --+ (and (match_code "reg") --+ (and (match_test "REGNO (op) >= NDS32_FIRST_FPR_REGNUM") --+ (match_test "REGNO (op) <= NDS32_LAST_FPR_REGNUM") --+ (match_test "(REGNO (op) & 1) != 0")))) --+ -- (define_special_predicate "nds32_load_multiple_operation" -- (match_code "parallel") -- { -- /* To verify 'load' operation, pass 'true' for the second argument. -- See the implementation in nds32.c for details. */ --- return nds32_valid_multiple_load_store (op, true); --+ return nds32_valid_multiple_load_store_p (op, true, false); --+}) --+ --+(define_special_predicate "nds32_load_multiple_and_update_address_operation" --+ (match_code "parallel") --+{ --+ /* To verify 'load' operation, pass 'true' for the second argument. --+ to verify 'update address' operation, pass 'true' for the third argument --+ See the implementation in nds32.c for details. */ --+ return nds32_valid_multiple_load_store_p (op, true, true); -- }) -- -- (define_special_predicate "nds32_store_multiple_operation" --@@ -70,7 +247,16 @@ -- { -- /* To verify 'store' operation, pass 'false' for the second argument. -- See the implementation in nds32.c for details. */ --- return nds32_valid_multiple_load_store (op, false); --+ return nds32_valid_multiple_load_store_p (op, false, false); --+}) --+ --+(define_special_predicate "nds32_store_multiple_and_update_address_operation" --+ (match_code "parallel") --+{ --+ /* To verify 'store' operation, pass 'false' for the second argument, --+ to verify 'update address' operation, pass 'true' for the third argument --+ See the implementation in nds32.c for details. */ --+ return nds32_valid_multiple_load_store_p (op, false, true); -- }) -- -- (define_special_predicate "nds32_stack_push_operation" --diff --git a/gcc/config/nds32/t-elf b/gcc/config/nds32/t-elf --new file mode 100644 --index 0000000..a63a310 ----- /dev/null --+++ b/gcc/config/nds32/t-elf --@@ -0,0 +1,42 @@ --+# The multilib settings of Andes NDS32 cpu for GNU compiler --+# Copyright (C) 2012-2016 Free Software Foundation, Inc. --+# Contributed by Andes Technology Corporation. --+# --+# This file is part of GCC. --+# --+# GCC is free software; you can redistribute it and/or modify it --+# under the terms of the GNU General Public License as published --+# by the Free Software Foundation; either version 3, or (at your --+# option) any later version. --+# --+# GCC is distributed in the hope that it will be useful, but WITHOUT --+# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY --+# or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public --+# License for more details. --+# --+# You should have received a copy of the GNU General Public License --+# along with GCC; see the file COPYING3. If not see --+# . --+ --+# We also define a macro MULTILIB_DEFAULTS in nds32.h that tells the --+# driver program which options are defaults for this target and thus --+# do not need to be handled specially. --+MULTILIB_OPTIONS += mcmodel=small/mcmodel=medium/mcmodel=large mvh --+ --+ifneq ($(filter graywolf,$(TM_MULTILIB_CONFIG)),) --+MULTILIB_OPTIONS += mcpu=graywolf --+endif --+ --+ifneq ($(filter dsp,$(TM_MULTILIB_CONFIG)),) --+MULTILIB_OPTIONS += mext-dsp --+endif --+ --+ifneq ($(filter zol,$(TM_MULTILIB_CONFIG)),) --+MULTILIB_OPTIONS += mext-zol --+endif --+ --+ifneq ($(filter v3m+,$(TM_MULTILIB_CONFIG)),) --+MULTILIB_OPTIONS += march=v3m+ --+endif --+ --+# ------------------------------------------------------------------------ --diff --git a/gcc/config/nds32/t-mlibs b/gcc/config/nds32/t-linux --similarity index 94% --rename from gcc/config/nds32/t-mlibs --rename to gcc/config/nds32/t-linux --index 5cb13f7..a4d8ab3 100644 ----- a/gcc/config/nds32/t-mlibs --+++ b/gcc/config/nds32/t-linux --@@ -21,6 +21,6 @@ -- # We also define a macro MULTILIB_DEFAULTS in nds32.h that tells the -- # driver program which options are defaults for this target and thus -- # do not need to be handled specially. ---MULTILIB_OPTIONS = mcmodel=small/mcmodel=medium/mcmodel=large --+MULTILIB_OPTIONS += -- -- # ------------------------------------------------------------------------ --diff --git a/gcc/config/nds32/t-nds32 b/gcc/config/nds32/t-nds32 --index cf3aea6..e34b844 100644 ----- a/gcc/config/nds32/t-nds32 --+++ b/gcc/config/nds32/t-nds32 --@@ -1,51 +1,294 @@ ---# General rules that all nds32/ targets must have. --+# Dependency rules rule of Andes NDS32 cpu for GNU compiler -- # Copyright (C) 2012-2016 Free Software Foundation, Inc. -- # Contributed by Andes Technology Corporation. -- # -- # This file is part of GCC. -- # ---# GCC is free software; you can redistribute it and/or modify ---# it under the terms of the GNU General Public License as published by ---# the Free Software Foundation; either version 3, or (at your option) ---# any later version. --+# GCC is free software; you can redistribute it and/or modify it --+# under the terms of the GNU General Public License as published --+# by the Free Software Foundation; either version 3, or (at your --+# option) any later version. -- # ---# GCC is distributed in the hope that it will be useful, ---# but WITHOUT ANY WARRANTY; without even the implied warranty of ---# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ---# GNU General Public License for more details. --+# GCC is distributed in the hope that it will be useful, but WITHOUT --+# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY --+# or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public --+# License for more details. -- # -- # You should have received a copy of the GNU General Public License -- # along with GCC; see the file COPYING3. If not see -- # . -- ---nds32-cost.o: $(srcdir)/config/nds32/nds32-cost.c --- $(COMPILE) $< --- $(POSTCOMPILE) -- ---nds32-intrinsic.o: $(srcdir)/config/nds32/nds32-intrinsic.c --- $(COMPILE) $< --- $(POSTCOMPILE) --+nds32-md-auxiliary.o: $(srcdir)/config/nds32/nds32-md-auxiliary.c \ --+ $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) \ --+ $(RTL_H) $(TREE_H) $(HASH_TABLE_H) $(OBSTACK_H) $(REGS_H) hard-reg-set.h \ --+ insn-config.h conditions.h output.h dumpfile.h \ --+ $(INSN_ATTR_H) $(FLAGS_H) reload.h $(FUNCTION_H) \ --+ $(EXPR_H) $(OPTABS_H) $(RECOG_H) $(CGRAPH_H) \ --+ $(GGC_H) except.h $(C_PRAGMA_H) $(TM_P_H) \ --+ $(TARGET_H) $(TARGET_DEF_H) debug.h langhooks.h $(DF_H) \ --+ intl.h libfuncs.h $(PARAMS_H) $(OPTS_H) --+ $(COMPILER) -c $(ALL_COMPILERFLAGS) $(ALL_CPPFLAGS) $(INCLUDES) \ --+ $(srcdir)/config/nds32/nds32-md-auxiliary.c -- ---nds32-isr.o: $(srcdir)/config/nds32/nds32-isr.c --- $(COMPILE) $< --- $(POSTCOMPILE) --+nds32-memory-manipulation.o: $(srcdir)/config/nds32/nds32-memory-manipulation.c \ --+ $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) \ --+ $(RTL_H) $(TREE_H) $(HASH_TABLE_H) $(OBSTACK_H) $(REGS_H) hard-reg-set.h \ --+ insn-config.h conditions.h output.h dumpfile.h \ --+ $(INSN_ATTR_H) $(FLAGS_H) reload.h $(FUNCTION_H) \ --+ $(EXPR_H) $(OPTABS_H) $(RECOG_H) $(CGRAPH_H) \ --+ $(GGC_H) except.h $(C_PRAGMA_H) $(TM_P_H) \ --+ $(TARGET_H) $(TARGET_DEF_H) debug.h langhooks.h $(DF_H) \ --+ intl.h libfuncs.h $(PARAMS_H) $(OPTS_H) --+ $(COMPILER) -c $(ALL_COMPILERFLAGS) $(ALL_CPPFLAGS) $(INCLUDES) \ --+ $(srcdir)/config/nds32/nds32-memory-manipulation.c -- ---nds32-md-auxiliary.o: $(srcdir)/config/nds32/nds32-md-auxiliary.c --- $(COMPILE) $< --- $(POSTCOMPILE) --+nds32-predicates.o: $(srcdir)/config/nds32/nds32-predicates.c \ --+ $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) \ --+ $(RTL_H) $(TREE_H) $(HASH_TABLE_H) $(OBSTACK_H) $(REGS_H) hard-reg-set.h \ --+ insn-config.h conditions.h output.h dumpfile.h \ --+ $(INSN_ATTR_H) $(FLAGS_H) reload.h $(FUNCTION_H) \ --+ $(EXPR_H) $(OPTABS_H) $(RECOG_H) $(CGRAPH_H) \ --+ $(GGC_H) except.h $(C_PRAGMA_H) $(TM_P_H) \ --+ $(TARGET_H) $(TARGET_DEF_H) debug.h langhooks.h $(DF_H) \ --+ intl.h libfuncs.h $(PARAMS_H) $(OPTS_H) --+ $(COMPILER) -c $(ALL_COMPILERFLAGS) $(ALL_CPPFLAGS) $(INCLUDES) \ --+ $(srcdir)/config/nds32/nds32-predicates.c -- ---nds32-pipelines-auxiliary.o: $(srcdir)/config/nds32/nds32-pipelines-auxiliary.c --- $(COMPILE) $< --- $(POSTCOMPILE) --+nds32-intrinsic.o: $(srcdir)/config/nds32/nds32-intrinsic.c \ --+ $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) \ --+ $(RTL_H) $(TREE_H) $(HASH_TABLE_H) $(OBSTACK_H) $(REGS_H) hard-reg-set.h \ --+ insn-config.h conditions.h output.h dumpfile.h \ --+ $(INSN_ATTR_H) $(FLAGS_H) reload.h $(FUNCTION_H) \ --+ $(EXPR_H) $(OPTABS_H) $(RECOG_H) $(CGRAPH_H) \ --+ $(GGC_H) except.h $(C_PRAGMA_H) $(TM_P_H) \ --+ $(TARGET_H) $(TARGET_DEF_H) debug.h langhooks.h $(DF_H) \ --+ intl.h libfuncs.h $(PARAMS_H) $(OPTS_H) --+ $(COMPILER) -c $(ALL_COMPILERFLAGS) $(ALL_CPPFLAGS) $(INCLUDES) \ --+ $(srcdir)/config/nds32/nds32-intrinsic.c -- ---nds32-predicates.o: $(srcdir)/config/nds32/nds32-predicates.c --- $(COMPILE) $< --- $(POSTCOMPILE) --+nds32-pipelines-auxiliary.o: \ --+ $(srcdir)/config/nds32/nds32-pipelines-auxiliary.c \ --+ $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) \ --+ $(RTL_H) $(TREE_H) $(HASH_TABLE_H) $(OBSTACK_H) $(REGS_H) hard-reg-set.h \ --+ insn-config.h conditions.h output.h dumpfile.h \ --+ $(INSN_ATTR_H) $(FLAGS_H) reload.h $(FUNCTION_H) \ --+ $(EXPR_H) $(OPTABS_H) $(RECOG_H) $(CGRAPH_H) \ --+ $(GGC_H) except.h $(C_PRAGMA_H) $(TM_P_H) \ --+ $(TARGET_H) $(TARGET_DEF_H) debug.h langhooks.h $(DF_H) \ --+ intl.h libfuncs.h $(PARAMS_H) $(OPTS_H) --+ $(COMPILER) -c $(ALL_COMPILERFLAGS) $(ALL_CPPFLAGS) $(INCLUDES) \ --+ $(srcdir)/config/nds32/nds32-pipelines-auxiliary.c -- ---nds32-memory-manipulation.o: $(srcdir)/config/nds32/nds32-memory-manipulation.c --- $(COMPILE) $< --- $(POSTCOMPILE) --+nds32-isr.o: \ --+ $(srcdir)/config/nds32/nds32-isr.c \ --+ $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) \ --+ $(RTL_H) $(TREE_H) $(HASH_TABLE_H) $(OBSTACK_H) $(REGS_H) hard-reg-set.h \ --+ insn-config.h conditions.h output.h dumpfile.h \ --+ $(INSN_ATTR_H) $(FLAGS_H) reload.h $(FUNCTION_H) \ --+ $(EXPR_H) $(OPTABS_H) $(RECOG_H) $(CGRAPH_H) \ --+ $(GGC_H) except.h $(C_PRAGMA_H) $(TM_P_H) \ --+ $(TARGET_H) $(TARGET_DEF_H) debug.h langhooks.h $(DF_H) \ --+ intl.h libfuncs.h $(PARAMS_H) $(OPTS_H) --+ $(COMPILER) -c $(ALL_COMPILERFLAGS) $(ALL_CPPFLAGS) $(INCLUDES) \ --+ $(srcdir)/config/nds32/nds32-isr.c -- ---nds32-fp-as-gp.o: $(srcdir)/config/nds32/nds32-fp-as-gp.c --- $(COMPILE) $< --- $(POSTCOMPILE) --+nds32-cost.o: \ --+ $(srcdir)/config/nds32/nds32-cost.c \ --+ $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) \ --+ $(RTL_H) $(TREE_H) $(HASH_TABLE_H) $(OBSTACK_H) $(REGS_H) hard-reg-set.h \ --+ insn-config.h conditions.h output.h dumpfile.h \ --+ $(INSN_ATTR_H) $(FLAGS_H) reload.h $(FUNCTION_H) \ --+ $(EXPR_H) $(OPTABS_H) $(RECOG_H) $(CGRAPH_H) \ --+ $(GGC_H) except.h $(C_PRAGMA_H) $(TM_P_H) \ --+ $(TARGET_H) $(TARGET_DEF_H) debug.h langhooks.h $(DF_H) \ --+ intl.h libfuncs.h $(PARAMS_H) $(OPTS_H) --+ $(COMPILER) -c $(ALL_COMPILERFLAGS) $(ALL_CPPFLAGS) $(INCLUDES) \ --+ $(srcdir)/config/nds32/nds32-cost.c --+ --+nds32-fp-as-gp.o: \ --+ $(srcdir)/config/nds32/nds32-fp-as-gp.c \ --+ $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) \ --+ $(RTL_H) $(TREE_H) $(HASH_TABLE_H) $(OBSTACK_H) $(REGS_H) hard-reg-set.h \ --+ insn-config.h conditions.h output.h dumpfile.h \ --+ $(INSN_ATTR_H) $(FLAGS_H) reload.h $(FUNCTION_H) \ --+ $(EXPR_H) $(OPTABS_H) $(RECOG_H) $(CGRAPH_H) \ --+ $(GGC_H) except.h $(C_PRAGMA_H) $(TM_P_H) \ --+ $(TARGET_H) $(TARGET_DEF_H) debug.h langhooks.h $(DF_H) \ --+ intl.h libfuncs.h $(PARAMS_H) $(OPTS_H) --+ $(COMPILER) -c $(ALL_COMPILERFLAGS) $(ALL_CPPFLAGS) $(INCLUDES) \ --+ $(srcdir)/config/nds32/nds32-fp-as-gp.c --+ --+nds32-load-store-opt.o: \ --+ $(srcdir)/config/nds32/nds32-load-store-opt.c \ --+ $(srcdir)/config/nds32/nds32-load-store-opt.h \ --+ $(srcdir)/config/nds32/nds32-reg-utils.h \ --+ $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) \ --+ $(RTL_H) $(TREE_H) $(HASH_TABLE_H) $(OBSTACK_H) $(REGS_H) hard-reg-set.h \ --+ insn-config.h conditions.h output.h dumpfile.h \ --+ $(INSN_ATTR_H) $(FLAGS_H) reload.h $(FUNCTION_H) \ --+ $(EXPR_H) $(OPTABS_H) $(RECOG_H) $(CGRAPH_H) \ --+ $(GGC_H) except.h $(C_PRAGMA_H) $(TM_P_H) \ --+ $(TARGET_H) $(TARGET_DEF_H) debug.h langhooks.h $(DF_H) \ --+ intl.h libfuncs.h $(PARAMS_H) $(OPTS_H) --+ $(COMPILER) -c $(ALL_COMPILERFLAGS) $(ALL_CPPFLAGS) $(INCLUDES) \ --+ $(srcdir)/config/nds32/nds32-load-store-opt.c --+ --+nds32-soft-fp-comm.o: \ --+ $(srcdir)/config/nds32/nds32-soft-fp-comm.c \ --+ $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) \ --+ $(RTL_H) $(TREE_H) $(HASH_TABLE_H) $(OBSTACK_H) $(REGS_H) hard-reg-set.h \ --+ insn-config.h conditions.h output.h dumpfile.h \ --+ $(INSN_ATTR_H) $(FLAGS_H) reload.h $(FUNCTION_H) \ --+ $(EXPR_H) $(OPTABS_H) $(RECOG_H) $(CGRAPH_H) \ --+ $(GGC_H) except.h $(C_PRAGMA_H) $(TM_P_H) \ --+ $(TARGET_H) $(TARGET_DEF_H) debug.h langhooks.h $(DF_H) \ --+ intl.h libfuncs.h $(PARAMS_H) $(OPTS_H) --+ $(COMPILER) -c $(ALL_COMPILERFLAGS) $(ALL_CPPFLAGS) $(INCLUDES) \ --+ $(srcdir)/config/nds32/nds32-soft-fp-comm.c --+ --+nds32-regrename.o: \ --+ $(srcdir)/config/nds32/nds32-regrename.c \ --+ $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) \ --+ $(RTL_H) $(TREE_H) $(HASH_TABLE_H) $(OBSTACK_H) $(REGS_H) hard-reg-set.h \ --+ insn-config.h conditions.h output.h dumpfile.h \ --+ $(INSN_ATTR_H) $(FLAGS_H) reload.h $(FUNCTION_H) \ --+ $(EXPR_H) $(OPTABS_H) $(RECOG_H) $(CGRAPH_H) \ --+ $(GGC_H) except.h $(C_PRAGMA_H) $(TM_P_H) \ --+ $(TARGET_H) $(TARGET_DEF_H) debug.h langhooks.h $(DF_H) \ --+ intl.h libfuncs.h $(PARAMS_H) $(OPTS_H) --+ $(COMPILER) -c $(ALL_COMPILERFLAGS) $(ALL_CPPFLAGS) $(INCLUDES) \ --+ $(srcdir)/config/nds32/nds32-regrename.c --+ --+nds32-gcse.o: \ --+ $(srcdir)/config/nds32/nds32-gcse.c \ --+ $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) \ --+ $(RTL_H) $(TREE_H) $(HASH_TABLE_H) $(OBSTACK_H) $(REGS_H) hard-reg-set.h \ --+ insn-config.h conditions.h output.h dumpfile.h \ --+ $(INSN_ATTR_H) $(FLAGS_H) reload.h $(FUNCTION_H) \ --+ $(EXPR_H) $(OPTABS_H) $(RECOG_H) $(CGRAPH_H) \ --+ $(GGC_H) except.h $(C_PRAGMA_H) $(TM_P_H) \ --+ $(TARGET_H) $(TARGET_DEF_H) debug.h langhooks.h $(DF_H) \ --+ intl.h libfuncs.h $(PARAMS_H) $(OPTS_H) --+ $(COMPILER) -c $(ALL_COMPILERFLAGS) $(ALL_CPPFLAGS) $(INCLUDES) \ --+ $(srcdir)/config/nds32/nds32-gcse.c --+ --+nds32-relax-opt.o: \ --+ $(srcdir)/config/nds32/nds32-relax-opt.c \ --+ $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) \ --+ $(RTL_H) $(TREE_H) $(HASH_TABLE_H) $(OBSTACK_H) $(REGS_H) hard-reg-set.h \ --+ insn-config.h conditions.h output.h dumpfile.h \ --+ $(INSN_ATTR_H) $(FLAGS_H) reload.h $(FUNCTION_H) \ --+ $(EXPR_H) $(OPTABS_H) $(RECOG_H) $(CGRAPH_H) \ --+ $(GGC_H) except.h $(C_PRAGMA_H) $(TM_P_H) \ --+ $(TARGET_H) $(TARGET_DEF_H) debug.h langhooks.h $(DF_H) \ --+ intl.h libfuncs.h $(PARAMS_H) $(OPTS_H) --+ $(COMPILER) -c $(ALL_COMPILERFLAGS) $(ALL_CPPFLAGS) $(INCLUDES) \ --+ $(srcdir)/config/nds32/nds32-relax-opt.c --+ --+nds32-cprop-acc.o: \ --+ $(srcdir)/config/nds32/nds32-cprop-acc.c \ --+ $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) \ --+ $(RTL_H) $(TREE_H) $(HASH_TABLE_H) $(OBSTACK_H) $(REGS_H) hard-reg-set.h \ --+ insn-config.h conditions.h output.h dumpfile.h \ --+ $(INSN_ATTR_H) $(FLAGS_H) reload.h $(FUNCTION_H) \ --+ $(EXPR_H) $(OPTABS_H) $(RECOG_H) $(CGRAPH_H) \ --+ $(GGC_H) except.h $(C_PRAGMA_H) $(TM_P_H) \ --+ $(TARGET_H) $(TARGET_DEF_H) debug.h langhooks.h $(DF_H) \ --+ intl.h libfuncs.h $(PARAMS_H) $(OPTS_H) --+ $(COMPILER) -c $(ALL_COMPILERFLAGS) $(ALL_CPPFLAGS) $(INCLUDES) \ --+ $(srcdir)/config/nds32/nds32-cprop-acc.c --+ --+nds32-sign-conversion.o: \ --+ $(srcdir)/config/nds32/nds32-sign-conversion.c \ --+ $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) \ --+ $(GIMPLE_H) $(RTL_H) $(TREE_H) $(HASH_TABLE_H) $(OBSTACK_H) $(REGS_H) hard-reg-set.h \ --+ insn-config.h conditions.h output.h dumpfile.h \ --+ $(INSN_ATTR_H) $(FLAGS_H) reload.h $(FUNCTION_H) \ --+ $(EXPR_H) $(OPTABS_H) $(RECOG_H) $(CGRAPH_H) \ --+ $(GGC_H) except.h $(C_PRAGMA_H) $(TM_P_H) \ --+ $(TARGET_H) $(TARGET_DEF_H) debug.h langhooks.h $(DF_H) \ --+ intl.h libfuncs.h $(PARAMS_H) $(OPTS_H) --+ $(COMPILER) -c $(ALL_COMPILERFLAGS) $(ALL_CPPFLAGS) $(INCLUDES) \ --+ $(srcdir)/config/nds32/nds32-sign-conversion.c --+ --+nds32-scalbn-transform.o: \ --+ $(srcdir)/config/nds32/nds32-scalbn-transform.c \ --+ $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) \ --+ $(GIMPLE_H) $(RTL_H) $(TREE_H) $(HASH_TABLE_H) $(OBSTACK_H) $(REGS_H) hard-reg-set.h \ --+ insn-config.h conditions.h output.h dumpfile.h \ --+ $(INSN_ATTR_H) $(FLAGS_H) reload.h $(FUNCTION_H) \ --+ $(EXPR_H) $(OPTABS_H) $(RECOG_H) $(CGRAPH_H) \ --+ $(GGC_H) except.h $(C_PRAGMA_H) $(TM_P_H) \ --+ $(TARGET_H) $(TARGET_DEF_H) debug.h langhooks.h $(DF_H) \ --+ intl.h libfuncs.h $(PARAMS_H) $(OPTS_H) --+ $(COMPILER) -c $(ALL_COMPILERFLAGS) $(ALL_CPPFLAGS) $(INCLUDES) \ --+ $(srcdir)/config/nds32/nds32-scalbn-transform.c --+ --+nds32-abi-compatible.o: \ --+ $(srcdir)/config/nds32/nds32-abi-compatible.c \ --+ $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) \ --+ $(GIMPLE_H) $(RTL_H) $(TREE_H) $(HASH_TABLE_H) $(OBSTACK_H) $(REGS_H) hard-reg-set.h \ --+ insn-config.h conditions.h output.h dumpfile.h \ --+ $(INSN_ATTR_H) $(FLAGS_H) reload.h $(FUNCTION_H) \ --+ $(EXPR_H) $(OPTABS_H) $(RECOG_H) $(CGRAPH_H) \ --+ $(GGC_H) except.h $(C_PRAGMA_H) $(TM_P_H) \ --+ $(TARGET_H) $(TARGET_DEF_H) debug.h langhooks.h $(DF_H) \ --+ intl.h libfuncs.h $(PARAMS_H) $(OPTS_H) --+ $(COMPILER) -c $(ALL_COMPILERFLAGS) $(ALL_CPPFLAGS) $(INCLUDES) \ --+ $(srcdir)/config/nds32/nds32-abi-compatible.c --+ --+nds32-lmwsmw.o: \ --+ $(srcdir)/config/nds32/nds32-lmwsmw.c \ --+ $(srcdir)/config/nds32/nds32-load-store-opt.h \ --+ $(srcdir)/config/nds32/nds32-reg-utils.h \ --+ $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) \ --+ $(RTL_H) $(TREE_H) $(HASH_TABLE_H) $(OBSTACK_H) $(REGS_H) hard-reg-set.h \ --+ insn-config.h conditions.h output.h dumpfile.h \ --+ $(INSN_ATTR_H) $(FLAGS_H) reload.h $(FUNCTION_H) \ --+ $(EXPR_H) $(OPTABS_H) $(RECOG_H) $(CGRAPH_H) \ --+ $(GGC_H) except.h $(C_PRAGMA_H) $(TM_P_H) \ --+ $(TARGET_H) $(TARGET_DEF_H) debug.h langhooks.h $(DF_H) \ --+ intl.h libfuncs.h $(PARAMS_H) $(OPTS_H) --+ $(COMPILER) -c $(ALL_COMPILERFLAGS) $(ALL_CPPFLAGS) $(INCLUDES) \ --+ $(srcdir)/config/nds32/nds32-lmwsmw.c --+ --+nds32-reg-utils.o: \ --+ $(srcdir)/config/nds32/nds32-reg-utils.c \ --+ $(srcdir)/config/nds32/nds32-reg-utils.h \ --+ $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) \ --+ $(RTL_H) $(TREE_H) $(HASH_TABLE_H) $(OBSTACK_H) $(REGS_H) hard-reg-set.h \ --+ insn-config.h conditions.h output.h dumpfile.h \ --+ $(INSN_ATTR_H) $(FLAGS_H) reload.h $(FUNCTION_H) \ --+ $(EXPR_H) $(OPTABS_H) $(RECOG_H) $(CGRAPH_H) \ --+ $(GGC_H) except.h $(C_PRAGMA_H) $(TM_P_H) \ --+ $(TARGET_H) $(TARGET_DEF_H) debug.h langhooks.h $(DF_H) \ --+ intl.h libfuncs.h $(PARAMS_H) $(OPTS_H) --+ $(COMPILER) -c $(ALL_COMPILERFLAGS) $(ALL_CPPFLAGS) $(INCLUDES) \ --+ $(srcdir)/config/nds32/nds32-reg-utils.c --+ --+nds32-const-remater.o: \ --+ $(srcdir)/config/nds32/nds32-const-remater.c \ --+ $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) \ --+ $(RTL_H) $(TREE_H) $(HASH_TABLE_H) $(OBSTACK_H) $(REGS_H) hard-reg-set.h \ --+ insn-config.h conditions.h output.h dumpfile.h \ --+ $(INSN_ATTR_H) $(FLAGS_H) reload.h $(FUNCTION_H) \ --+ $(EXPR_H) $(OPTABS_H) $(RECOG_H) $(CGRAPH_H) \ --+ $(GGC_H) except.h $(C_PRAGMA_H) $(TM_P_H) \ --+ $(TARGET_H) $(TARGET_DEF_H) debug.h langhooks.h $(DF_H) \ --+ intl.h libfuncs.h $(PARAMS_H) $(OPTS_H) --+ $(COMPILER) -c $(ALL_COMPILERFLAGS) $(ALL_CPPFLAGS) $(INCLUDES) \ --+ $(srcdir)/config/nds32/nds32-const-remater.c --+ --+nds32-utils.o: \ --+ $(srcdir)/config/nds32/nds32-utils.c \ --+ $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) \ --+ $(RTL_H) $(TREE_H) $(HASH_TABLE_H) $(OBSTACK_H) $(REGS_H) hard-reg-set.h \ --+ insn-config.h conditions.h output.h dumpfile.h \ --+ $(INSN_ATTR_H) $(FLAGS_H) reload.h $(FUNCTION_H) \ --+ $(EXPR_H) $(OPTABS_H) $(RECOG_H) $(CGRAPH_H) \ --+ $(GGC_H) except.h $(C_PRAGMA_H) $(TM_P_H) \ --+ $(TARGET_H) $(TARGET_DEF_H) debug.h langhooks.h $(DF_H) \ --+ intl.h libfuncs.h $(PARAMS_H) $(OPTS_H) --+ $(COMPILER) -c $(ALL_COMPILERFLAGS) $(ALL_CPPFLAGS) $(INCLUDES) \ --+ $(srcdir)/config/nds32/nds32-utils.c --diff --git a/gcc/configure b/gcc/configure --index 954673c..ca21885 100755 ----- a/gcc/configure --+++ b/gcc/configure --@@ -27327,7 +27327,7 @@ esac -- # version to the per-target configury. -- case "$cpu_type" in -- aarch64 | alpha | arm | avr | bfin | cris | i386 | m32c | m68k | microblaze \ --- | mips | nios2 | pa | rs6000 | score | sparc | spu | tilegx | tilepro \ --+ | mips | nds32 | nios2 | pa | rs6000 | score | sparc | spu | tilegx | tilepro \ -- | visium | xstormy16 | xtensa) -- insn="nop" -- ;; --diff --git a/gcc/configure.ac b/gcc/configure.ac --index 4c65d44..d7a5efc 100644 ----- a/gcc/configure.ac --+++ b/gcc/configure.ac --@@ -4667,7 +4667,7 @@ esac -- # version to the per-target configury. -- case "$cpu_type" in -- aarch64 | alpha | arm | avr | bfin | cris | i386 | m32c | m68k | microblaze \ --- | mips | nios2 | pa | rs6000 | score | sparc | spu | tilegx | tilepro \ --+ | mips | nds32 | nios2 | pa | rs6000 | score | sparc | spu | tilegx | tilepro \ -- | visium | xstormy16 | xtensa) -- insn="nop" -- ;; --diff --git a/gcc/doc/extend.texi b/gcc/doc/extend.texi --index ee2715d..37fa3b5 100644 ----- a/gcc/doc/extend.texi --+++ b/gcc/doc/extend.texi --@@ -13587,38 +13587,33 @@ builtin is exact. -- -- These built-in functions are available for the NDS32 target: -- ---@deftypefn {Built-in Function} void __builtin_nds32_isync (int *@var{addr}) --+@table @code --+@item void __builtin_nds32_isync (int *@var{addr}) -- Insert an ISYNC instruction into the instruction stream where -- @var{addr} is an instruction address for serialization. ---@end deftypefn -- ---@deftypefn {Built-in Function} void __builtin_nds32_isb (void) --+@item void __builtin_nds32_isb (void) -- Insert an ISB instruction into the instruction stream. ---@end deftypefn -- ---@deftypefn {Built-in Function} int __builtin_nds32_mfsr (int @var{sr}) --+@item int __builtin_nds32_mfsr (int @var{sr}) -- Return the content of a system register which is mapped by @var{sr}. ---@end deftypefn -- ---@deftypefn {Built-in Function} int __builtin_nds32_mfusr (int @var{usr}) --+@item int __builtin_nds32_mfusr (int @var{usr}) -- Return the content of a user space register which is mapped by @var{usr}. ---@end deftypefn -- ---@deftypefn {Built-in Function} void __builtin_nds32_mtsr (int @var{value}, int @var{sr}) --+@item void __builtin_nds32_mtsr (int @var{value}, int @var{sr}) -- Move the @var{value} to a system register which is mapped by @var{sr}. ---@end deftypefn -- ---@deftypefn {Built-in Function} void __builtin_nds32_mtusr (int @var{value}, int @var{usr}) --+@item void __builtin_nds32_mtusr (int @var{value}, int @var{usr}) -- Move the @var{value} to a user space register which is mapped by @var{usr}. ---@end deftypefn -- ---@deftypefn {Built-in Function} void __builtin_nds32_setgie_en (void) --+@item void __builtin_nds32_setgie_en (void) -- Enable global interrupt. ---@end deftypefn -- ---@deftypefn {Built-in Function} void __builtin_nds32_setgie_dis (void) --+@item void __builtin_nds32_setgie_dis (void) -- Disable global interrupt. ---@end deftypefn --+ --+@end table -- -- @node picoChip Built-in Functions -- @subsection picoChip Built-in Functions --diff --git a/gcc/doc/install.texi b/gcc/doc/install.texi --index b60b53a..fc23722 100644 ----- a/gcc/doc/install.texi --+++ b/gcc/doc/install.texi --@@ -2109,7 +2109,7 @@ supported since version 4.7.2 and is the default in 4.8.0 and newer. -- -- @item --with-nds32-lib=@var{library} -- Specifies that @var{library} setting is used for building @file{libgcc.a}. ---Currently, the valid @var{library} is @samp{newlib} or @samp{mculib}. --+Currently, the valid @var{library} are 'newlib' or 'mculib'. -- This option is only supported for the NDS32 target. -- -- @item --with-build-time-tools=@var{dir} --diff --git a/gcc/doc/invoke.texi b/gcc/doc/invoke.texi --index 2ed9285..75e0042 100644 ----- a/gcc/doc/invoke.texi --+++ b/gcc/doc/invoke.texi --@@ -904,13 +904,19 @@ Objective-C and Objective-C++ Dialects}. -- -mreduced-regs -mfull-regs @gol -- -mcmov -mno-cmov @gol -- -mperf-ext -mno-perf-ext @gol --+-mperf2-ext -mno-perf2-ext @gol --+-mstring-ext -mno-string-ext @gol -- -mv3push -mno-v3push @gol -- -m16bit -mno-16bit @gol --+-mgp-direct -mno-gp-direct @gol -- -misr-vector-size=@var{num} @gol -- -mcache-block-size=@var{num} @gol -- -march=@var{arch} @gol ----mcmodel=@var{code-model} @gol ----mctor-dtor -mrelax} --+-mcpu=@var{cpu} @gol --+-mmemory-model=@var{cpu} @gol --+-mconfig-register-ports=@var{ports} @gol --+-mforce-fp-as-gp -mforbid-fp-as-gp @gol --+-mex9 -mctor-dtor -mrelax} -- -- @emph{Nios II Options} -- @gccoptlist{-G @var{num} -mgpopt=@var{option} -mgpopt -mno-gpopt @gol --@@ -5006,7 +5012,7 @@ example, warn if an unsigned variable is compared against zero with -- @opindex Wbad-function-cast -- @opindex Wno-bad-function-cast -- Warn when a function call is cast to a non-matching type. ---For example, warn if a call to a function returning an integer type --+For example, warn if a call to a function returning an integer type -- is cast to a pointer type. -- -- @item -Wc90-c99-compat @r{(C and Objective-C only)} --@@ -19089,6 +19095,22 @@ Generate performance extension instructions. -- @opindex mno-perf-ext -- Do not generate performance extension instructions. -- --+@item -mperf2-ext --+@opindex mperf2-ext --+Generate performance extension version 2 instructions. --+ --+@item -mno-perf2-ext --+@opindex mno-perf2-ext --+Do not generate performance extension version 2 instructions. --+ --+@item -mstring-ext --+@opindex mstring-ext --+Generate string extension instructions. --+ --+@item -mno-string-ext --+@opindex mno-string-ext --+Do not generate string extension instructions. --+ -- @item -mv3push -- @opindex mv3push -- Generate v3 push25/pop25 instructions. --@@ -19105,6 +19127,14 @@ Generate 16-bit instructions. -- @opindex mno-16-bit -- Do not generate 16-bit instructions. -- --+@item -mgp-direct --+@opindex mgp-direct --+Generate GP base instructions directly. --+ --+@item -mno-gp-direct --+@opindex mno-gp-direct --+Do no generate GP base instructions directly. --+ -- @item -misr-vector-size=@var{num} -- @opindex misr-vector-size -- Specify the size of each interrupt vector, which must be 4 or 16. --@@ -19118,20 +19148,33 @@ which must be a power of 2 between 4 and 512. -- @opindex march -- Specify the name of the target architecture. -- ---@item -mcmodel=@var{code-model} ---@opindex mcmodel ---Set the code model to one of ---@table @asis ---@item @samp{small} ---All the data and read-only data segments must be within 512KB addressing space. ---The text segment must be within 16MB addressing space. ---@item @samp{medium} ---The data segment must be within 512KB while the read-only data segment can be ---within 4GB addressing space. The text segment should be still within 16MB ---addressing space. ---@item @samp{large} ---All the text and data segments can be within 4GB addressing space. ---@end table --+@item -mcpu=@var{cpu} --+@opindex mcpu --+Specify the cpu for pipeline model. --+ --+@item -mmemory-model=@var{cpu} --+@opindex mmemory-model --+Specify fast or slow memory model. --+ --+@item -mconfig-register-ports=@var{ports} --+@opindex mconfig-register-ports --+Specify how many read/write ports for n9/n10 cores. --+The value should be 3r2w or 2r1w. --+ --+@item -mforce-fp-as-gp --+@opindex mforce-fp-as-gp --+Prevent $fp being allocated during register allocation so that compiler --+is able to force performing fp-as-gp optimization. --+ --+@item -mforbid-fp-as-gp --+@opindex mforbid-fp-as-gp --+Forbid using $fp to access static and global variables. --+This option strictly forbids fp-as-gp optimization --+regardless of @option{-mforce-fp-as-gp}. --+ --+@item -mex9 --+@opindex mex9 --+Use special directives to guide linker doing ex9 optimization. -- -- @item -mctor-dtor -- @opindex mctor-dtor --@@ -19159,55 +19202,15 @@ Put global and static objects less than or equal to @var{num} bytes -- into the small data or BSS sections instead of the normal data or BSS -- sections. The default value of @var{num} is 8. -- ---@item -mgpopt=@var{option} -- @item -mgpopt -- @itemx -mno-gpopt -- @opindex mgpopt -- @opindex mno-gpopt ---Generate (do not generate) GP-relative accesses. The following ---@var{option} names are recognized: --- ---@table @samp --- ---@item none ---Do not generate GP-relative accesses. --- ---@item local ---Generate GP-relative accesses for small data objects that are not ---external, weak, or uninitialized common symbols. ---Also use GP-relative addressing for objects that ---have been explicitly placed in a small data section via a @code{section} ---attribute. --- ---@item global ---As for @samp{local}, but also generate GP-relative accesses for ---small data objects that are external, weak, or common. If you use this option, ---you must ensure that all parts of your program (including libraries) are ---compiled with the same @option{-G} setting. --- ---@item data ---Generate GP-relative accesses for all data objects in the program. If you ---use this option, the entire data and BSS segments ---of your program must fit in 64K of memory and you must use an appropriate ---linker script to allocate them within the addressable range of the ---global pointer. --- ---@item all ---Generate GP-relative addresses for function pointers as well as data ---pointers. If you use this option, the entire text, data, and BSS segments ---of your program must fit in 64K of memory and you must use an appropriate ---linker script to allocate them within the addressable range of the ---global pointer. --- ---@end table --- ---@option{-mgpopt} is equivalent to @option{-mgpopt=local}, and ---@option{-mno-gpopt} is equivalent to @option{-mgpopt=none}. --- ---The default is @option{-mgpopt} except when @option{-fpic} or ---@option{-fPIC} is specified to generate position-independent code. ---Note that the Nios II ABI does not permit GP-relative accesses from ---shared libraries. --+Generate (do not generate) GP-relative accesses for objects in the --+small data or BSS sections. The default is @option{-mgpopt} except --+when @option{-fpic} or @option{-fPIC} is specified to generate --+position-independent code. Note that the Nios II ABI does not permit --+GP-relative accesses from shared libraries. -- -- You may need to specify @option{-mno-gpopt} explicitly when building -- programs that include large amounts of small data, including large --diff --git a/gcc/gcc.c b/gcc/gcc.c --index 0f042b0..5c43f33 100644 ----- a/gcc/gcc.c --+++ b/gcc/gcc.c --@@ -1288,7 +1288,7 @@ static const struct compiler default_compilers[] = -- {".zip", "#Java", 0, 0, 0}, {".jar", "#Java", 0, 0, 0}, -- {".go", "#Go", 0, 1, 0}, -- /* Next come the entries for C. */ --- {".c", "@c", 0, 0, 1}, --+ {".c", "@nds32_c", 0, 0, 1}, -- {"@c", -- /* cc1 has an integrated ISO C preprocessor. We should invoke the -- external preprocessor if -save-temps is given. */ --@@ -1303,6 +1303,38 @@ static const struct compiler default_compilers[] = -- %{!save-temps*:%{!traditional-cpp:%{!no-integrated-cpp:\ -- cc1 %(cpp_unique_options) %(cc1_options)}}}\ -- %{!fsyntax-only:%(invoke_as)}}}}", 0, 0, 1}, --+ {"@nds32_c", --+ /* cc1 has an integrated ISO C preprocessor. We should invoke the --+ external preprocessor if -save-temps is given. */ --+ "%{E|M|MM:%(trad_capable_cpp) %(cpp_options) %(cpp_debug_options)}\ --+ %{mace:\ --+ %{!E:%{!M:%{!MM:\ --+ %{traditional:\ --+%eGNU C no longer supports -traditional without -E}\ --+ %{save-temps*|traditional-cpp|no-integrated-cpp:%(trad_capable_cpp) \ --+ %(cpp_options) -o %{save-temps*:%b.i} %{!save-temps*:%g.i} \n\ --+ cs2 %{mace-s2s*} %{save-temps*:%b.i} %{!save-temps*:%g.i} \ --+ -o %{save-temps*:%b.ace.i} %{!save-temps*:%g.ace.i} --\n\ --+ cc1 -fpreprocessed %{save-temps*:%b.ace.i} %{!save-temps*:%g.ace.i} \ --+ %(cc1_options)}\ --+ %{!save-temps*:%{!traditional-cpp:%{!no-integrated-cpp:\ --+ %(trad_capable_cpp) %(cpp_options) -o %u.i\n}}}\ --+ %{!save-temps*:%{!traditional-cpp:%{!no-integrated-cpp:\ --+ cs2 %{mace-s2s*} %U.i -o %u.ace.i --\n}}}\ --+ %{!save-temps*:%{!traditional-cpp:%{!no-integrated-cpp:\ --+ cc1 -fpreprocessed %U.ace.i %(cc1_options)}}}\ --+ %{!fsyntax-only:%(invoke_as)}}}}}\ --+ %{!mace:\ --+ %{!E:%{!M:%{!MM:\ --+ %{traditional:\ --+%eGNU C no longer supports -traditional without -E}\ --+ %{save-temps*|traditional-cpp|no-integrated-cpp:%(trad_capable_cpp) \ --+ %(cpp_options) -o %{save-temps*:%b.i} %{!save-temps*:%g.i} \n\ --+ cc1 -fpreprocessed %{save-temps*:%b.i} %{!save-temps*:%g.i} \ --+ %(cc1_options)}\ --+ %{!save-temps*:%{!traditional-cpp:%{!no-integrated-cpp:\ --+ cc1 %(cpp_unique_options) %(cc1_options)}}}\ --+ %{!fsyntax-only:%(invoke_as)}}}}}", 0, 0, 1}, -- {"-", -- "%{!E:%e-E or -x required when input is from standard input}\ -- %(trad_capable_cpp) %(cpp_options) %(cpp_debug_options)", 0, 0, 0}, --diff --git a/gcc/loop-unroll.c b/gcc/loop-unroll.c --index 4d26e2f..60f934c 100644 ----- a/gcc/loop-unroll.c --+++ b/gcc/loop-unroll.c --@@ -1132,7 +1132,9 @@ decide_unroll_stupid (struct loop *loop, int flags) -- of mispredicts. -- TODO: this heuristic needs tunning; call inside the loop body -- is also relatively good reason to not unroll. */ --- if (num_loop_branches (loop) > 1) --+ unsigned branch_count = PARAM_VALUE (PARAM_MAX_LOOP_UNROLL_BRANCH); --+ --+ if (num_loop_branches (loop) > branch_count) -- { -- if (dump_file) -- fprintf (dump_file, ";; Not unrolling, contains branches\n"); --diff --git a/gcc/opt-read.awk b/gcc/opt-read.awk --index b304ccb..2e6e8df 100644 ----- a/gcc/opt-read.awk --+++ b/gcc/opt-read.awk --@@ -99,6 +99,7 @@ BEGIN { -- val_flags = "0" -- val_flags = val_flags \ -- test_flag("Canonical", props, "| CL_ENUM_CANONICAL") \ --+ test_flag("Undocumented", props, "| CL_UNDOCUMENTED") \ -- test_flag("DriverOnly", props, "| CL_ENUM_DRIVER_ONLY") -- enum_data[enum_name] = enum_data[enum_name] \ -- " { " quote string quote ", " value ", " val_flags \ --diff --git a/gcc/opts.c b/gcc/opts.c --index 0f9431a..da75332 100644 ----- a/gcc/opts.c --+++ b/gcc/opts.c --@@ -1271,6 +1271,10 @@ print_filtered_help (unsigned int include_flags, -- { -- unsigned int len = strlen (cl_enums[i].values[j].arg); -- --+ /* Skip the undocument enum value */ --+ if (cl_enums[i].values[j].flags & CL_UNDOCUMENTED) --+ continue; --+ -- if (pos > 4 && pos + 1 + len <= columns) -- { -- printf (" %s", cl_enums[i].values[j].arg); --diff --git a/gcc/params.def b/gcc/params.def --index dbff305..44847b3 100644 ----- a/gcc/params.def --+++ b/gcc/params.def --@@ -297,6 +297,11 @@ DEFPARAM(PARAM_MAX_UNROLL_TIMES, -- "max-unroll-times", -- "The maximum number of unrollings of a single loop.", -- 8, 0, 0) --+/* Maximum number of loop unroll loop branch count. */ --+DEFPARAM (PARAM_MAX_LOOP_UNROLL_BRANCH, --+ "max-unroll-loop-branch", --+ "Maximum number of loop branch count", --+ 1, 1, 20) -- /* The maximum number of insns of a peeled loop. */ -- DEFPARAM(PARAM_MAX_PEELED_INSNS, -- "max-peeled-insns", --diff --git a/gcc/testsuite/g++.dg/init/array15.C b/gcc/testsuite/g++.dg/init/array15.C --index 17160d0..280fe69 100644 ----- a/gcc/testsuite/g++.dg/init/array15.C --+++ b/gcc/testsuite/g++.dg/init/array15.C --@@ -1,4 +1,6 @@ -- // { dg-do run } --+// { dg-require-effective-target nds32_full_addr_space { target nds32*-*-elf* } } --+// { dg-options "-mcmodel=large" { target nds32*-*-elf* } } -- -- // Copyright (C) 2004 Free Software Foundation, Inc. -- // Contributed by Nathan Sidwell 8 Dec 2004 --diff --git a/gcc/testsuite/g++.dg/init/array16.C b/gcc/testsuite/g++.dg/init/array16.C --index 188d1a8..83c0d47 100644 ----- a/gcc/testsuite/g++.dg/init/array16.C --+++ b/gcc/testsuite/g++.dg/init/array16.C --@@ -2,6 +2,7 @@ -- // have "compile" for some targets and "run" for others. -- // { dg-do run { target { ! mmix-*-* } } } -- // { dg-options "-mstructure-size-boundary=8" { target arm*-*-* } } --+// { dg-skip-if "" { nds32_gp_direct } } -- -- // Copyright (C) 2004 Free Software Foundation, Inc. -- // Contributed by Nathan Sidwell 8 Dec 2004 --diff --git a/gcc/testsuite/g++.dg/torture/type-generic-1.C b/gcc/testsuite/g++.dg/torture/type-generic-1.C --index 4d82592..5ae789c 100644 ----- a/gcc/testsuite/g++.dg/torture/type-generic-1.C --+++ b/gcc/testsuite/g++.dg/torture/type-generic-1.C --@@ -4,6 +4,7 @@ -- /* { dg-do run } */ -- /* { dg-add-options ieee } */ -- /* { dg-skip-if "No Inf/NaN support" { spu-*-* } } */ --+/* { dg-skip-if "No Denormmalized support" { nds32_ext_fpu } } */ -- -- #include "../../gcc.dg/tg-tests.h" -- --diff --git a/gcc/testsuite/gcc.c-torture/compile/limits-fndefn.c b/gcc/testsuite/gcc.c-torture/compile/limits-fndefn.c --index 228c5d9..d2d3e51 100644 ----- a/gcc/testsuite/gcc.c-torture/compile/limits-fndefn.c --+++ b/gcc/testsuite/gcc.c-torture/compile/limits-fndefn.c --@@ -1,4 +1,5 @@ -- /* { dg-skip-if "too complex for avr" { avr-*-* } { "*" } { "" } } */ --+/* { dg-skip-if "lto may cause internal compiler error on cygwin with gcc-4.9" { nds32*-*-* } { "*" } { "" } } */ -- /* { dg-skip-if "ptxas times out" { nvptx-*-* } { "*" } { "" } } */ -- /* { dg-timeout-factor 4.0 } */ -- #define LIM1(x) x##0, x##1, x##2, x##3, x##4, x##5, x##6, x##7, x##8, x##9, --diff --git a/gcc/testsuite/gcc.c-torture/execute/20010122-1.c b/gcc/testsuite/gcc.c-torture/execute/20010122-1.c --index 4eeb8c7..6cd02bc 100644 ----- a/gcc/testsuite/gcc.c-torture/execute/20010122-1.c --+++ b/gcc/testsuite/gcc.c-torture/execute/20010122-1.c --@@ -1,4 +1,5 @@ -- /* { dg-skip-if "requires frame pointers" { *-*-* } "-fomit-frame-pointer" "" } */ --+/* { dg-additional-options "-malways-save-lp" { target nds32*-*-* } } */ -- /* { dg-require-effective-target return_address } */ -- -- extern void exit (int); --diff --git a/gcc/testsuite/gcc.c-torture/execute/920501-8.x b/gcc/testsuite/gcc.c-torture/execute/920501-8.x --new file mode 100644 --index 0000000..96f05bc ----- /dev/null --+++ b/gcc/testsuite/gcc.c-torture/execute/920501-8.x --@@ -0,0 +1,11 @@ --+# Please see Andes Bugzilla #11005 for the details. --+if { [istarget "nds32*-*-*"] } { --+ # The nds32 mculib toolchains require --+ # "-u_printf_float" and "-u_scanf_float" options --+ # to fully support printf and scanf functionality. --+ # These options are supposed to be harmless to newlib toolchain. --+ set additional_flags "-u_printf_float -u_scanf_float" --+} --+ --+return 0 --+ --diff --git a/gcc/testsuite/gcc.c-torture/execute/930513-1.x b/gcc/testsuite/gcc.c-torture/execute/930513-1.x --new file mode 100644 --index 0000000..96f05bc ----- /dev/null --+++ b/gcc/testsuite/gcc.c-torture/execute/930513-1.x --@@ -0,0 +1,11 @@ --+# Please see Andes Bugzilla #11005 for the details. --+if { [istarget "nds32*-*-*"] } { --+ # The nds32 mculib toolchains require --+ # "-u_printf_float" and "-u_scanf_float" options --+ # to fully support printf and scanf functionality. --+ # These options are supposed to be harmless to newlib toolchain. --+ set additional_flags "-u_printf_float -u_scanf_float" --+} --+ --+return 0 --+ --diff --git a/gcc/testsuite/gcc.c-torture/execute/ieee/ieee.exp b/gcc/testsuite/gcc.c-torture/execute/ieee/ieee.exp --index 009984e..19cfcca 100644 ----- a/gcc/testsuite/gcc.c-torture/execute/ieee/ieee.exp --+++ b/gcc/testsuite/gcc.c-torture/execute/ieee/ieee.exp --@@ -30,6 +30,10 @@ load_lib c-torture.exp -- # Disable tests on machines with no hardware support for IEEE arithmetic. -- if { [istarget "vax-*-*"] || [ istarget "powerpc-*-*spe"] || [istarget "pdp11-*-*"] } { return } -- --+# Since we cannot use dg-skip-if or dg-require-effective-target for individual --+# test case under ieee category, we disable all ieee tests on nds32 fpu toolchains. --+if { [istarget "nds32*-*-*"] && [check_effective_target_nds32_ext_fpu] } { return } --+ -- if $tracelevel then { -- strace $tracelevel -- } --diff --git a/gcc/testsuite/gcc.c-torture/execute/pr60822.c b/gcc/testsuite/gcc.c-torture/execute/pr60822.c --index dcd2447..a305df3 100644 ----- a/gcc/testsuite/gcc.c-torture/execute/pr60822.c --+++ b/gcc/testsuite/gcc.c-torture/execute/pr60822.c --@@ -1,4 +1,5 @@ -- /* { dg-require-effective-target int32plus } */ --+/* { dg-additional-options "-mcmodel=large" { target nds32*-*-elf* } } */ -- struct X { -- char fill0[800000]; -- int a; --diff --git a/gcc/testsuite/gcc.c-torture/execute/struct-ret-1.x b/gcc/testsuite/gcc.c-torture/execute/struct-ret-1.x --new file mode 100644 --index 0000000..96f05bc ----- /dev/null --+++ b/gcc/testsuite/gcc.c-torture/execute/struct-ret-1.x --@@ -0,0 +1,11 @@ --+# Please see Andes Bugzilla #11005 for the details. --+if { [istarget "nds32*-*-*"] } { --+ # The nds32 mculib toolchains require --+ # "-u_printf_float" and "-u_scanf_float" options --+ # to fully support printf and scanf functionality. --+ # These options are supposed to be harmless to newlib toolchain. --+ set additional_flags "-u_printf_float -u_scanf_float" --+} --+ --+return 0 --+ --diff --git a/gcc/testsuite/gcc.dg/constructor-1.c b/gcc/testsuite/gcc.dg/constructor-1.c --index 73e9fc3..827987e 100644 ----- a/gcc/testsuite/gcc.dg/constructor-1.c --+++ b/gcc/testsuite/gcc.dg/constructor-1.c --@@ -1,6 +1,7 @@ -- /* { dg-do run } */ -- /* { dg-options "-O2" } */ -- /* { dg-skip-if "" { ! global_constructor } { "*" } { "" } } */ --+/* { dg-options "-O2 -mctor-dtor" { target { nds32*-*-* } } } */ -- -- /* The ipa-split pass pulls the body of the if(!x) block -- into a separate function to make foo a better inlining --diff --git a/gcc/testsuite/gcc.dg/graphite/interchange-0.c b/gcc/testsuite/gcc.dg/graphite/interchange-0.c --index d56be46..b83535c 100644 ----- a/gcc/testsuite/gcc.dg/graphite/interchange-0.c --+++ b/gcc/testsuite/gcc.dg/graphite/interchange-0.c --@@ -1,4 +1,5 @@ -- /* { dg-require-effective-target size32plus } */ --+/* { dg-additional-options "-mcmodel=large" { target nds32*-*-elf* } } */ -- -- #define DEBUG 0 -- --diff --git a/gcc/testsuite/gcc.dg/graphite/interchange-1.c b/gcc/testsuite/gcc.dg/graphite/interchange-1.c --index b65d486..2d77f0e 100644 ----- a/gcc/testsuite/gcc.dg/graphite/interchange-1.c --+++ b/gcc/testsuite/gcc.dg/graphite/interchange-1.c --@@ -1,4 +1,6 @@ -- /* { dg-require-effective-target size32plus } */ --+/* { dg-require-effective-target nds32_full_addr_space { target nds32*-*-elf* } } */ --+/* { dg-additional-options "-mcmodel=large" { target nds32*-*-elf* } } */ -- -- /* Formerly known as ltrans-1.c */ -- --diff --git a/gcc/testsuite/gcc.dg/graphite/interchange-10.c b/gcc/testsuite/gcc.dg/graphite/interchange-10.c --index a955644..2021de2 100644 ----- a/gcc/testsuite/gcc.dg/graphite/interchange-10.c --+++ b/gcc/testsuite/gcc.dg/graphite/interchange-10.c --@@ -1,4 +1,6 @@ -- /* { dg-require-effective-target size32plus } */ --+/* { dg-require-effective-target nds32_full_addr_space { target nds32*-*-elf* } } */ --+/* { dg-additional-options "-mcmodel=large" { target nds32*-*-elf* } } */ -- -- #define DEBUG 0 -- #if DEBUG --diff --git a/gcc/testsuite/gcc.dg/graphite/interchange-11.c b/gcc/testsuite/gcc.dg/graphite/interchange-11.c --index 6102822..5abb316 100644 ----- a/gcc/testsuite/gcc.dg/graphite/interchange-11.c --+++ b/gcc/testsuite/gcc.dg/graphite/interchange-11.c --@@ -1,4 +1,6 @@ -- /* { dg-require-effective-target size32plus } */ --+/* { dg-require-effective-target nds32_full_addr_space { target nds32*-*-elf* } } */ --+/* { dg-additional-options "-mcmodel=large" { target nds32*-*-elf* } } */ -- -- #define DEBUG 0 -- #if DEBUG --diff --git a/gcc/testsuite/gcc.dg/graphite/interchange-15.c b/gcc/testsuite/gcc.dg/graphite/interchange-15.c --index 7410f29..1f71f06 100644 ----- a/gcc/testsuite/gcc.dg/graphite/interchange-15.c --+++ b/gcc/testsuite/gcc.dg/graphite/interchange-15.c --@@ -1,4 +1,6 @@ -- /* { dg-require-effective-target size32plus } */ --+/* { dg-require-effective-target nds32_full_addr_space { target nds32*-*-elf* } } */ --+/* { dg-additional-options "-mcmodel=large" { target nds32*-*-elf* } } */ -- -- #define DEBUG 0 -- #if DEBUG --diff --git a/gcc/testsuite/gcc.dg/graphite/interchange-2.c b/gcc/testsuite/gcc.dg/graphite/interchange-2.c --index 936ee00..0041649 100644 ----- a/gcc/testsuite/gcc.dg/graphite/interchange-2.c --+++ b/gcc/testsuite/gcc.dg/graphite/interchange-2.c --@@ -1,4 +1,6 @@ -- /* { dg-require-effective-target size32plus } */ --+/* { dg-require-effective-target nds32_full_addr_space { target nds32*-*-elf* } } */ --+/* { dg-additional-options "-mcmodel=large" { target nds32*-*-elf* } } */ -- -- /* Formerly known as ltrans-2.c */ -- --diff --git a/gcc/testsuite/gcc.dg/graphite/interchange-3.c b/gcc/testsuite/gcc.dg/graphite/interchange-3.c --index 4aec824..6635529 100644 ----- a/gcc/testsuite/gcc.dg/graphite/interchange-3.c --+++ b/gcc/testsuite/gcc.dg/graphite/interchange-3.c --@@ -1,4 +1,6 @@ -- /* { dg-require-effective-target size32plus } */ --+/* { dg-require-effective-target nds32_full_addr_space { target nds32*-*-elf* } } */ --+/* { dg-additional-options "-mcmodel=large" { target nds32*-*-elf* } } */ -- -- /* Formerly known as ltrans-3.c */ -- --diff --git a/gcc/testsuite/gcc.dg/graphite/interchange-4.c b/gcc/testsuite/gcc.dg/graphite/interchange-4.c --index 463ecb5..359f0ac 100644 ----- a/gcc/testsuite/gcc.dg/graphite/interchange-4.c --+++ b/gcc/testsuite/gcc.dg/graphite/interchange-4.c --@@ -1,4 +1,6 @@ -- /* { dg-require-effective-target size32plus } */ --+/* { dg-require-effective-target nds32_full_addr_space { target nds32*-*-elf* } } */ --+/* { dg-additional-options "-mcmodel=large" { target nds32*-*-elf* } } */ -- -- /* Formerly known as ltrans-4.c */ -- --diff --git a/gcc/testsuite/gcc.dg/graphite/interchange-5.c b/gcc/testsuite/gcc.dg/graphite/interchange-5.c --index e5aaa64..892257e 100644 ----- a/gcc/testsuite/gcc.dg/graphite/interchange-5.c --+++ b/gcc/testsuite/gcc.dg/graphite/interchange-5.c --@@ -1,4 +1,5 @@ -- /* { dg-require-effective-target size32plus } */ --+/* { dg-additional-options "-mcmodel=large" { target nds32*-*-elf* } } */ -- -- /* Formerly known as ltrans-5.c */ -- --diff --git a/gcc/testsuite/gcc.dg/graphite/interchange-mvt.c b/gcc/testsuite/gcc.dg/graphite/interchange-mvt.c --index c6543ec..51c6ee5 100644 ----- a/gcc/testsuite/gcc.dg/graphite/interchange-mvt.c --+++ b/gcc/testsuite/gcc.dg/graphite/interchange-mvt.c --@@ -1,4 +1,6 @@ -- /* { dg-require-effective-target size32plus } */ --+/* { dg-require-effective-target nds32_full_addr_space { target nds32*-*-elf* } } */ --+/* { dg-additional-options "-mcmodel=large" { target nds32*-*-elf* } } */ -- -- #define DEBUG 0 -- #if DEBUG --diff --git a/gcc/testsuite/gcc.dg/graphite/pr46185.c b/gcc/testsuite/gcc.dg/graphite/pr46185.c --index 36d46a4..738c9a8 100644 ----- a/gcc/testsuite/gcc.dg/graphite/pr46185.c --+++ b/gcc/testsuite/gcc.dg/graphite/pr46185.c --@@ -1,5 +1,7 @@ -- /* { dg-do run } */ --+/* { dg-require-effective-target nds32_full_addr_space { target nds32*-*-elf* } } */ -- /* { dg-options "-O2 -floop-interchange -ffast-math -fno-ipa-cp" } */ --+/* { dg-additional-options "-mcmodel=large" { target nds32*-*-elf* } } */ -- -- #define DEBUG 0 -- #if DEBUG --diff --git a/gcc/testsuite/gcc.dg/graphite/uns-interchange-15.c b/gcc/testsuite/gcc.dg/graphite/uns-interchange-15.c --index fe2669f..dd77aa3 100644 ----- a/gcc/testsuite/gcc.dg/graphite/uns-interchange-15.c --+++ b/gcc/testsuite/gcc.dg/graphite/uns-interchange-15.c --@@ -1,4 +1,6 @@ -- /* { dg-require-effective-target size32plus } */ --+/* { dg-require-effective-target nds32_full_addr_space { target nds32*-*-elf* } } */ --+/* { dg-additional-options "-mcmodel=large" { target nds32*-*-elf* } } */ -- -- #define DEBUG 0 -- #if DEBUG --diff --git a/gcc/testsuite/gcc.dg/graphite/uns-interchange-mvt.c b/gcc/testsuite/gcc.dg/graphite/uns-interchange-mvt.c --index 211c9ab..c7defb4 100644 ----- a/gcc/testsuite/gcc.dg/graphite/uns-interchange-mvt.c --+++ b/gcc/testsuite/gcc.dg/graphite/uns-interchange-mvt.c --@@ -1,4 +1,6 @@ -- /* { dg-require-effective-target size32plus } */ --+/* { dg-require-effective-target nds32_full_addr_space { target nds32*-*-elf* } } */ --+/* { dg-additional-options "-mcmodel=large" { target nds32*-*-elf* } } */ -- -- #define DEBUG 0 -- #if DEBUG --diff --git a/gcc/testsuite/gcc.dg/initpri1.c b/gcc/testsuite/gcc.dg/initpri1.c --index 794ea2b..10b3a24 100644 ----- a/gcc/testsuite/gcc.dg/initpri1.c --+++ b/gcc/testsuite/gcc.dg/initpri1.c --@@ -1,4 +1,5 @@ -- /* { dg-do run { target init_priority } } */ --+/* { dg-options "-mctor-dtor" { target { nds32*-*-* } } } */ -- -- extern void abort (); -- --diff --git a/gcc/testsuite/gcc.dg/initpri2.c b/gcc/testsuite/gcc.dg/initpri2.c --index fa9fda0..1418411 100644 ----- a/gcc/testsuite/gcc.dg/initpri2.c --+++ b/gcc/testsuite/gcc.dg/initpri2.c --@@ -1,4 +1,5 @@ -- /* { dg-do compile { target init_priority } } */ --+/* { dg-options "-mctor-dtor" { target { nds32*-*-* } } } */ -- -- /* Priorities must be in the range [0, 65535]. */ -- void c1() --diff --git a/gcc/testsuite/gcc.dg/initpri3.c b/gcc/testsuite/gcc.dg/initpri3.c --index 1633da0..e1b8cf6 100644 ----- a/gcc/testsuite/gcc.dg/initpri3.c --+++ b/gcc/testsuite/gcc.dg/initpri3.c --@@ -1,6 +1,7 @@ -- /* { dg-do run { target init_priority } } */ -- /* { dg-require-effective-target lto } */ -- /* { dg-options "-flto -O3" } */ --+/* { dg-options "-flto -O3 -mctor-dtor" { target { nds32*-*-* } } } */ -- -- extern void abort (); -- --diff --git a/gcc/testsuite/gcc.dg/ipa/ipa-sra-1.c b/gcc/testsuite/gcc.dg/ipa/ipa-sra-1.c --index 4db904b..2290d8b 100644 ----- a/gcc/testsuite/gcc.dg/ipa/ipa-sra-1.c --+++ b/gcc/testsuite/gcc.dg/ipa/ipa-sra-1.c --@@ -1,5 +1,6 @@ -- /* { dg-do run } */ -- /* { dg-options "-O2 -fipa-sra -fdump-tree-eipa_sra-details" } */ --+/* { dg-additional-options "-u_printf_float -u_scanf_float" { target nds32*-*-* } } */ -- -- struct bovid -- { --diff --git a/gcc/testsuite/gcc.dg/lower-subreg-1.c b/gcc/testsuite/gcc.dg/lower-subreg-1.c --index 47057fe..25439b1 100644 ----- a/gcc/testsuite/gcc.dg/lower-subreg-1.c --+++ b/gcc/testsuite/gcc.dg/lower-subreg-1.c --@@ -1,4 +1,4 @@ ---/* { dg-do compile { target { ! { mips64 || { aarch64*-*-* arm*-*-* ia64-*-* sparc*-*-* spu-*-* tilegx-*-* } } } } } */ --+/* { dg-do compile { target { ! { mips64 || { aarch64*-*-* arm*-*-* ia64-*-* sparc*-*-* spu-*-* tilegx-*-* nds32*-*-* } } } } } */ -- /* { dg-options "-O -fdump-rtl-subreg1" } */ -- /* { dg-additional-options "-mno-stv" { target ia32 } } */ -- /* { dg-skip-if "" { { i?86-*-* x86_64-*-* } && x32 } { "*" } { "" } } */ --diff --git a/gcc/testsuite/gcc.dg/pr28796-2.c b/gcc/testsuite/gcc.dg/pr28796-2.c --index f56a5d4..fff71bc 100644 ----- a/gcc/testsuite/gcc.dg/pr28796-2.c --+++ b/gcc/testsuite/gcc.dg/pr28796-2.c --@@ -2,6 +2,7 @@ -- /* { dg-options "-O2 -funsafe-math-optimizations -fno-finite-math-only -DUNSAFE" } */ -- /* { dg-add-options ieee } */ -- /* { dg-skip-if "No Inf/NaN support" { spu-*-* } } */ --+/* { dg-skip-if "No Denormmalized support" { nds32_ext_fpu } } */ -- -- #include "tg-tests.h" -- --diff --git a/gcc/testsuite/gcc.dg/sibcall-10.c b/gcc/testsuite/gcc.dg/sibcall-10.c --index d98b43a..bb0e24c 100644 ----- a/gcc/testsuite/gcc.dg/sibcall-10.c --+++ b/gcc/testsuite/gcc.dg/sibcall-10.c --@@ -5,7 +5,7 @@ -- Copyright (C) 2002 Free Software Foundation Inc. -- Contributed by Hans-Peter Nilsson */ -- ---/* { dg-do run { xfail { { cris-*-* crisv32-*-* h8300-*-* hppa*64*-*-* m32r-*-* mcore-*-* mn10300-*-* msp430*-*-* nds32*-*-* xstormy16-*-* v850*-*-* vax-*-* xtensa*-*-* } || { arm*-*-* && { ! arm32 } } } } } */ --+/* { dg-do run { xfail { { cris-*-* crisv32-*-* h8300-*-* hppa*64*-*-* m32r-*-* mcore-*-* mn10300-*-* msp430*-*-* xstormy16-*-* v850*-*-* vax-*-* xtensa*-*-* } || { arm*-*-* && { ! arm32 } } } } } */ -- /* -mlongcall disables sibcall patterns. */ -- /* { dg-skip-if "" { powerpc*-*-* } { "-mlongcall" } { "" } } */ -- /* { dg-options "-O2 -foptimize-sibling-calls" } */ --diff --git a/gcc/testsuite/gcc.dg/sibcall-3.c b/gcc/testsuite/gcc.dg/sibcall-3.c --index eafe8dd..f188a18 100644 ----- a/gcc/testsuite/gcc.dg/sibcall-3.c --+++ b/gcc/testsuite/gcc.dg/sibcall-3.c --@@ -5,7 +5,7 @@ -- Copyright (C) 2002 Free Software Foundation Inc. -- Contributed by Hans-Peter Nilsson */ -- ---/* { dg-do run { xfail { { cris-*-* crisv32-*-* h8300-*-* hppa*64*-*-* m32r-*-* mcore-*-* mn10300-*-* msp430*-*-* nds32*-*-* xstormy16-*-* v850*-*-* vax-*-* xtensa*-*-* } || { arm*-*-* && { ! arm32 } } } } } */ --+/* { dg-do run { xfail { { cris-*-* crisv32-*-* h8300-*-* hppa*64*-*-* m32r-*-* mcore-*-* mn10300-*-* msp430*-*-* xstormy16-*-* v850*-*-* vax-*-* xtensa*-*-* } || { arm*-*-* && { ! arm32 } } } } } */ -- /* -mlongcall disables sibcall patterns. */ -- /* { dg-skip-if "" { powerpc*-*-* } { "-mlongcall" } { "" } } */ -- /* { dg-options "-O2 -foptimize-sibling-calls" } */ --diff --git a/gcc/testsuite/gcc.dg/sibcall-4.c b/gcc/testsuite/gcc.dg/sibcall-4.c --index 1e039c6..a8c844a 100644 ----- a/gcc/testsuite/gcc.dg/sibcall-4.c --+++ b/gcc/testsuite/gcc.dg/sibcall-4.c --@@ -5,7 +5,7 @@ -- Copyright (C) 2002 Free Software Foundation Inc. -- Contributed by Hans-Peter Nilsson */ -- ---/* { dg-do run { xfail { { cris-*-* crisv32-*-* h8300-*-* hppa*64*-*-* m32r-*-* mcore-*-* mn10300-*-* msp430*-*-* nds32*-*-* xstormy16-*-* v850*-*-* vax-*-* xtensa*-*-* } || { arm*-*-* && { ! arm32 } } } } } */ --+/* { dg-do run { xfail { { cris-*-* crisv32-*-* h8300-*-* hppa*64*-*-* m32r-*-* mcore-*-* mn10300-*-* msp430*-*-* xstormy16-*-* v850*-*-* vax-*-* xtensa*-*-* } || { arm*-*-* && { ! arm32 } } } } } */ -- /* -mlongcall disables sibcall patterns. */ -- /* { dg-skip-if "" { powerpc*-*-* } { "-mlongcall" } { "" } } */ -- /* { dg-options "-O2 -foptimize-sibling-calls" } */ --diff --git a/gcc/testsuite/gcc.dg/sibcall-9.c b/gcc/testsuite/gcc.dg/sibcall-9.c --index 34e7053..71c3251 100644 ----- a/gcc/testsuite/gcc.dg/sibcall-9.c --+++ b/gcc/testsuite/gcc.dg/sibcall-9.c --@@ -5,7 +5,7 @@ -- Copyright (C) 2002 Free Software Foundation Inc. -- Contributed by Hans-Peter Nilsson */ -- ---/* { dg-do run { xfail { { cris-*-* crisv32-*-* h8300-*-* hppa*64*-*-* m32r-*-* mcore-*-* mn10300-*-* msp430*-*-* nds32*-*-* nvptx-*-* xstormy16-*-* v850*-*-* vax-*-* xtensa*-*-* } || { arm*-*-* && { ! arm32 } } } } } */ --+/* { dg-do run { xfail { { cris-*-* crisv32-*-* h8300-*-* hppa*64*-*-* m32r-*-* mcore-*-* mn10300-*-* msp430*-*-* nvptx-*-* xstormy16-*-* v850*-*-* vax-*-* xtensa*-*-* } || { arm*-*-* && { ! arm32 } } } } } */ -- /* -mlongcall disables sibcall patterns. */ -- /* { dg-skip-if "" { powerpc*-*-* } { "-mlongcall" } { "" } } */ -- /* { dg-options "-O2 -foptimize-sibling-calls" } */ --diff --git a/gcc/testsuite/gcc.dg/stack-usage-1.c b/gcc/testsuite/gcc.dg/stack-usage-1.c --index 7864c6a..c768ca2 100644 ----- a/gcc/testsuite/gcc.dg/stack-usage-1.c --+++ b/gcc/testsuite/gcc.dg/stack-usage-1.c --@@ -2,6 +2,7 @@ -- /* { dg-options "-fstack-usage" } */ -- /* nvptx doesn't have a reg allocator, and hence no stack usage data. */ -- /* { dg-skip-if "" { nvptx-*-* } { "*" } { "" } } */ --+/* { dg-options "-fstack-usage -fno-omit-frame-pointer" { target { nds32*-*-* } } } */ -- -- /* This is aimed at testing basic support for -fstack-usage in the back-ends. -- See the SPARC back-end for example (grep flag_stack_usage_info in sparc.c). --diff --git a/gcc/testsuite/gcc.dg/torture/type-generic-1.c b/gcc/testsuite/gcc.dg/torture/type-generic-1.c --index 3897818..6815e8b 100644 ----- a/gcc/testsuite/gcc.dg/torture/type-generic-1.c --+++ b/gcc/testsuite/gcc.dg/torture/type-generic-1.c --@@ -3,6 +3,7 @@ -- -- /* { dg-do run } */ -- /* { dg-skip-if "No Inf/NaN support" { spu-*-* } } */ --+/* { dg-skip-if "No Denormmalized support" { nds32_ext_fpu } } */ -- /* { dg-options "-DUNSAFE" { target tic6x*-*-* visium-*-* } } */ -- /* { dg-add-options ieee } */ -- --diff --git a/gcc/testsuite/gcc.dg/tree-ssa/ssa-dom-cse-2.c b/gcc/testsuite/gcc.dg/tree-ssa/ssa-dom-cse-2.c --index 1a4bfe6..78c948a 100644 ----- a/gcc/testsuite/gcc.dg/tree-ssa/ssa-dom-cse-2.c --+++ b/gcc/testsuite/gcc.dg/tree-ssa/ssa-dom-cse-2.c --@@ -25,4 +25,4 @@ foo () -- but the loop reads only one element at a time, and DOM cannot resolve these. -- The same happens on powerpc depending on the SIMD support available. */ -- ---/* { dg-final { scan-tree-dump "return 28;" "optimized" { xfail { { alpha*-*-* hppa*64*-*-* powerpc64*-*-* } || { sparc*-*-* && lp64 } } } } } */ --+/* { dg-final { scan-tree-dump "return 28;" "optimized" { xfail { { alpha*-*-* hppa*64*-*-* powerpc64*-*-* nds32*-*-*} || { sparc*-*-* && lp64 } } } } } */ --diff --git a/gcc/testsuite/gcc.dg/tree-ssa/vrp88.c b/gcc/testsuite/gcc.dg/tree-ssa/vrp88.c --index f70b311..8a1081c 100644 ----- a/gcc/testsuite/gcc.dg/tree-ssa/vrp88.c --+++ b/gcc/testsuite/gcc.dg/tree-ssa/vrp88.c --@@ -33,6 +33,6 @@ bitmap_single_bit_set_p (const_bitmap a) -- } -- -- /* Verify that VRP simplified an "if" statement. */ ---/* { dg-final { scan-tree-dump "Folded into: if.*" "vrp1"} } */ --+/* { dg-final { scan-tree-dump "Folded into: if.*" "vrp1" { xfail *-*-* } } } */ -- -- --diff --git a/gcc/testsuite/gcc.target/nds32/basic-main.c b/gcc/testsuite/gcc.target/nds32/basic-main.c --index 6fdbc35..7341fb5 100644 ----- a/gcc/testsuite/gcc.target/nds32/basic-main.c --+++ b/gcc/testsuite/gcc.target/nds32/basic-main.c --@@ -1,9 +1,10 @@ -- /* This is a basic main function test program. */ -- ---/* { dg-do run } */ ---/* { dg-options "-O0" } */ --+/* { dg-do run } */ --+/* { dg-options "-O0" } */ -- ---int main(void) --+int --+main (void) -- { -- return 0; -- } --diff --git a/gcc/testsuite/gcc.target/nds32/builtin-PE1-abs.c b/gcc/testsuite/gcc.target/nds32/builtin-PE1-abs.c --new file mode 100644 --index 0000000..8cadcfd ----- /dev/null --+++ b/gcc/testsuite/gcc.target/nds32/builtin-PE1-abs.c --@@ -0,0 +1,20 @@ --+/* This is a test program for abs instruction. */ --+ --+/* { dg-do run } */ --+/* { dg-options "-O1" } */ --+/* { dg-require-effective-target nds32_ext_perf } */ --+ --+#include --+#include --+ --+int --+main () --+{ --+ int a = -4; --+ int abs = __nds32__abs (a); --+ --+ if (abs != 4) --+ abort (); --+ else --+ exit (0); --+} --diff --git a/gcc/testsuite/gcc.target/nds32/builtin-PE1-ave.c b/gcc/testsuite/gcc.target/nds32/builtin-PE1-ave.c --new file mode 100644 --index 0000000..d2c87db ----- /dev/null --+++ b/gcc/testsuite/gcc.target/nds32/builtin-PE1-ave.c --@@ -0,0 +1,21 @@ --+/* This is a test program for ave instruction. */ --+ --+/* { dg-do run } */ --+/* { dg-options "-O1" } */ --+/* { dg-require-effective-target nds32_ext_perf } */ --+ --+#include --+#include --+ --+int --+main () --+{ --+ int a = 4; --+ int b = 2; --+ int ave = __nds32__ave (a, b); --+ --+ if (ave != 3) --+ abort (); --+ else --+ exit (0); --+} --diff --git a/gcc/testsuite/gcc.target/nds32/builtin-PE1-bclr.c b/gcc/testsuite/gcc.target/nds32/builtin-PE1-bclr.c --new file mode 100644 --index 0000000..0e6c1e0 ----- /dev/null --+++ b/gcc/testsuite/gcc.target/nds32/builtin-PE1-bclr.c --@@ -0,0 +1,20 @@ --+/* This is a test program for bclr instruction. */ --+ --+/* { dg-do run } */ --+/* { dg-options "-O1" } */ --+/* { dg-require-effective-target nds32_ext_perf } */ --+ --+#include --+#include --+ --+int --+main () --+{ --+ int a = 1; --+ int c = __nds32__bclr (a, 0); --+ --+ if (c != 0) --+ abort (); --+ else --+ exit (0); --+} --diff --git a/gcc/testsuite/gcc.target/nds32/builtin-PE1-bset.c b/gcc/testsuite/gcc.target/nds32/builtin-PE1-bset.c --new file mode 100644 --index 0000000..1bd8513 ----- /dev/null --+++ b/gcc/testsuite/gcc.target/nds32/builtin-PE1-bset.c --@@ -0,0 +1,20 @@ --+/* This is a test program for bset instruction. */ --+ --+/* { dg-do run } */ --+/* { dg-options "-O1" } */ --+/* { dg-require-effective-target nds32_ext_perf } */ --+ --+#include --+#include --+ --+int --+main () --+{ --+ int c = 0; --+ c = __nds32__bset (c, 0); --+ --+ if (c != 1) --+ abort (); --+ else --+ exit (0); --+} --diff --git a/gcc/testsuite/gcc.target/nds32/builtin-PE1-btgl.c b/gcc/testsuite/gcc.target/nds32/builtin-PE1-btgl.c --new file mode 100644 --index 0000000..a1dbc00 ----- /dev/null --+++ b/gcc/testsuite/gcc.target/nds32/builtin-PE1-btgl.c --@@ -0,0 +1,20 @@ --+/* This is a test program for btgl instruction. */ --+ --+/* { dg-do run } */ --+/* { dg-options "-O1" } */ --+/* { dg-require-effective-target nds32_ext_perf } */ --+ --+#include --+#include --+ --+int --+main () --+{ --+ int a = 1; --+ int c = __nds32__btgl (1, 0); --+ --+ if (c != 0) --+ abort (); --+ else --+ exit (0); --+} --diff --git a/gcc/testsuite/gcc.target/nds32/builtin-PE1-btst.c b/gcc/testsuite/gcc.target/nds32/builtin-PE1-btst.c --new file mode 100644 --index 0000000..c001f94 ----- /dev/null --+++ b/gcc/testsuite/gcc.target/nds32/builtin-PE1-btst.c --@@ -0,0 +1,20 @@ --+/* This is a test program for btst instruction. */ --+ --+/* { dg-do run } */ --+/* { dg-options "-O1" } */ --+/* { dg-require-effective-target nds32_ext_perf } */ --+ --+#include --+#include --+ --+int --+main () --+{ --+ int c = 1; --+ c = __nds32__btst (c, 0); --+ --+ if (c != 1) --+ abort (); --+ else --+ exit (0); --+} --diff --git a/gcc/testsuite/gcc.target/nds32/builtin-PE1-clip.c b/gcc/testsuite/gcc.target/nds32/builtin-PE1-clip.c --new file mode 100644 --index 0000000..d63b298 ----- /dev/null --+++ b/gcc/testsuite/gcc.target/nds32/builtin-PE1-clip.c --@@ -0,0 +1,20 @@ --+/* This is a test program for clip instruction. */ --+ --+/* { dg-do run } */ --+/* { dg-options "-O1" } */ --+/* { dg-require-effective-target nds32_ext_perf } */ --+ --+#include --+#include --+ --+int --+main () --+{ --+ int c = 33; --+ c = __nds32__clip (c, 5); --+ --+ if (c != 31) --+ abort (); --+ else --+ exit (0); --+} --diff --git a/gcc/testsuite/gcc.target/nds32/builtin-PE1-clips.c b/gcc/testsuite/gcc.target/nds32/builtin-PE1-clips.c --new file mode 100644 --index 0000000..3e3f663 ----- /dev/null --+++ b/gcc/testsuite/gcc.target/nds32/builtin-PE1-clips.c --@@ -0,0 +1,20 @@ --+/* This is a test program for clips instruction. */ --+ --+/* { dg-do run } */ --+/* { dg-options "-O1" } */ --+/* { dg-require-effective-target nds32_ext_perf } */ --+ --+#include --+#include --+ --+int --+main () --+{ --+ int a = -33; --+ int c = __nds32__clips (a, 5); --+ --+ if (c != -32) --+ abort (); --+ else --+ exit (0); --+} --diff --git a/gcc/testsuite/gcc.target/nds32/builtin-PE1-clo.c b/gcc/testsuite/gcc.target/nds32/builtin-PE1-clo.c --new file mode 100644 --index 0000000..d672a33 ----- /dev/null --+++ b/gcc/testsuite/gcc.target/nds32/builtin-PE1-clo.c --@@ -0,0 +1,20 @@ --+/* This is a test program for clo instruction. */ --+ --+/* { dg-do run } */ --+/* { dg-options "-O1" } */ --+/* { dg-require-effective-target nds32_ext_perf } */ --+ --+#include --+#include --+ --+int --+main () --+{ --+ int c = 0xFFFF0000; --+ c = __nds32__clo (c); --+ --+ if (c != 16) --+ abort (); --+ else --+ exit (0); --+} --diff --git a/gcc/testsuite/gcc.target/nds32/builtin-PE1-clz.c b/gcc/testsuite/gcc.target/nds32/builtin-PE1-clz.c --new file mode 100644 --index 0000000..17e6318 ----- /dev/null --+++ b/gcc/testsuite/gcc.target/nds32/builtin-PE1-clz.c --@@ -0,0 +1,20 @@ --+/* This is a test program for clz instruction. */ --+ --+/* { dg-do run } */ --+/* { dg-options "-O1" } */ --+/* { dg-require-effective-target nds32_ext_perf } */ --+ --+#include --+#include --+ --+int --+main () --+{ --+ int c = 0x0000FFFF; --+ c = __nds32__clz (c); --+ --+ if (c != 16) --+ abort (); --+ else --+ exit (0); --+} --diff --git a/gcc/testsuite/gcc.target/nds32/builtin-PE2-bse.c b/gcc/testsuite/gcc.target/nds32/builtin-PE2-bse.c --new file mode 100644 --index 0000000..c769fea ----- /dev/null --+++ b/gcc/testsuite/gcc.target/nds32/builtin-PE2-bse.c --@@ -0,0 +1,28 @@ --+/* This is a test program for bse instruction. */ --+ --+/* { dg-do run } */ --+/* { dg-options "-O1" } */ --+/* { dg-require-effective-target nds32_ext_perf2 } */ --+ --+#include --+#include --+ --+int --+main () --+{ --+ unsigned int a = 0xF0F0F0F0; --+ unsigned int b = 0x00000300; --+ unsigned int r = 0; --+ --+ unsigned int verify_b = 0x00000300; --+ unsigned int verify_r = 0; --+ --+ __nds32__bse (&r, a, &b); --+ a = 0xF0F0F0F0; --+ asm volatile ("bse %0, %2, %1": "+&r" (verify_r), "+&r" (verify_b) : "r" (a)); --+ --+ if ((verify_b == b) && (verify_r == r)) --+ exit (0); --+ else --+ abort (); --+} --diff --git a/gcc/testsuite/gcc.target/nds32/builtin-PE2-bsp.c b/gcc/testsuite/gcc.target/nds32/builtin-PE2-bsp.c --new file mode 100644 --index 0000000..d798719 ----- /dev/null --+++ b/gcc/testsuite/gcc.target/nds32/builtin-PE2-bsp.c --@@ -0,0 +1,26 @@ --+/* This is a test program for bsp instruction. */ --+ --+/* { dg-do run } */ --+/* { dg-options "-O1" } */ --+/* { dg-require-effective-target nds32_ext_perf2 } */ --+ --+#include --+#include --+ --+int --+main () --+{ --+ unsigned int a = 0x0000000F; --+ unsigned int b = 0x00000300; --+ unsigned int r = 0; --+ unsigned int verify_b = 0x00000300; --+ unsigned int verify_r = 0; --+ --+ __nds32__bsp (&r, a, &b); --+ asm volatile ("bsp %0, %2, %1": "+&r" (verify_r), "+&r" (verify_b) : "r" (a)); --+ --+ if ((verify_b == b) && (verify_r == r)) --+ exit (0); --+ else --+ abort (); --+} --diff --git a/gcc/testsuite/gcc.target/nds32/builtin-PE2-pbsad.c b/gcc/testsuite/gcc.target/nds32/builtin-PE2-pbsad.c --new file mode 100644 --index 0000000..bc4fe42 ----- /dev/null --+++ b/gcc/testsuite/gcc.target/nds32/builtin-PE2-pbsad.c --@@ -0,0 +1,21 @@ --+/* This is a test program for pbsad instruction. */ --+ --+/* { dg-do run } */ --+/* { dg-options "-O1" } */ --+/* { dg-require-effective-target nds32_ext_perf2 } */ --+ --+#include --+#include --+ --+int --+main () --+{ --+ unsigned int a = 0x09070605; --+ unsigned int b = 0x04020301; --+ unsigned int r = __nds32__pbsad (a, b); --+ --+ if (r != 17) --+ abort (); --+ else --+ exit (0); --+} --diff --git a/gcc/testsuite/gcc.target/nds32/builtin-PE2-pbsada.c b/gcc/testsuite/gcc.target/nds32/builtin-PE2-pbsada.c --new file mode 100644 --index 0000000..6ed1b08 ----- /dev/null --+++ b/gcc/testsuite/gcc.target/nds32/builtin-PE2-pbsada.c --@@ -0,0 +1,23 @@ --+/* This is a test program for pbsada instruction. */ --+ --+/* { dg-do run } */ --+/* { dg-options "-O1" } */ --+/* { dg-require-effective-target nds32_ext_perf2 } */ --+ --+#include --+#include --+ --+int --+main () --+{ --+ unsigned int a = 0x09070605; --+ unsigned int b = 0x04020301; --+ unsigned int r = 1; --+ --+ r = __nds32__pbsada(r, a, b); --+ --+ if (r != 18) --+ abort (); --+ else --+ exit (0); --+} --diff --git a/gcc/testsuite/gcc.target/nds32/builtin-dsp-add16.c b/gcc/testsuite/gcc.target/nds32/builtin-dsp-add16.c --new file mode 100644 --index 0000000..0eec324 ----- /dev/null --+++ b/gcc/testsuite/gcc.target/nds32/builtin-dsp-add16.c --@@ -0,0 +1,49 @@ --+/* This is a test program for add16 instruction. */ --+ --+/* { dg-do run } */ --+ --+#include --+#include --+ --+#ifdef __NDS32_EXT_DSP__ --+static __attribute__ ((noinline)) --+unsigned int add16 (unsigned int ra, unsigned int rb) --+{ --+ return __nds32__add16 (ra, rb); --+} --+ --+static __attribute__ ((noinline)) --+uint16x2_t v_uadd16 (uint16x2_t ra, uint16x2_t rb) --+{ --+ return __nds32__v_uadd16 (ra, rb); --+} --+ --+static __attribute__ ((noinline)) --+int16x2_t v_sadd16 (int16x2_t ra, int16x2_t rb) --+{ --+ return __nds32__v_sadd16 (ra, rb); --+} --+ --+int --+main () --+{ --+ unsigned int a = add16 (0x0001f000, 0x00011000); --+ uint16x2_t v_ua = v_uadd16 ((uint16x2_t) {0xf000, 0xf000}, --+ (uint16x2_t) {0x1000, 0x2000}); --+ int16x2_t v_sa = v_sadd16 ((int16x2_t) {0xf777, 0xf111}, --+ (int16x2_t) {0x1000, 0x2000}); --+ --+ if (a != 0x00020000) --+ abort (); --+ else if (v_ua[0] != 0x0000 --+ || v_ua[1] != 0x1000) --+ abort (); --+ else if (v_sa[0] != 0x0777 --+ || v_sa[1] != 0x1111) --+ abort (); --+ else --+ exit (0); --+} --+#else --+int main(){return 0;} --+#endif --diff --git a/gcc/testsuite/gcc.target/nds32/builtin-dsp-add64.c b/gcc/testsuite/gcc.target/nds32/builtin-dsp-add64.c --new file mode 100644 --index 0000000..b761b7f ----- /dev/null --+++ b/gcc/testsuite/gcc.target/nds32/builtin-dsp-add64.c --@@ -0,0 +1,36 @@ --+/* This is a test program for add64 instruction. */ --+ --+/* { dg-do run } */ --+ --+#include --+#include --+ --+#ifdef __NDS32_EXT_DSP__ --+static __attribute__ ((noinline)) --+long long sadd64 (long long ra, long long rb) --+{ --+ return __nds32__sadd64 (ra, rb); --+} --+ --+static __attribute__ ((noinline)) --+unsigned long long uadd64 (unsigned long long ra, unsigned long long rb) --+{ --+ return __nds32__uadd64 (ra, rb); --+} --+ --+int --+main () --+{ --+ long long sa = sadd64 (0x1122334400000000ll, 0x55667788ll); --+ unsigned long long ua = uadd64 (0xffff00000000ull, 0x55667788ull); --+ --+ if (sa != 0x1122334455667788ll) --+ abort (); --+ else if (ua != 0xffff55667788ull) --+ abort (); --+ else --+ exit (0); --+} --+#else --+int main(){return 0;} --+#endif --diff --git a/gcc/testsuite/gcc.target/nds32/builtin-dsp-add8.c b/gcc/testsuite/gcc.target/nds32/builtin-dsp-add8.c --new file mode 100644 --index 0000000..77e686c ----- /dev/null --+++ b/gcc/testsuite/gcc.target/nds32/builtin-dsp-add8.c --@@ -0,0 +1,53 @@ --+/* This is a test program for add8 instruction. */ --+ --+/* { dg-do run } */ --+ --+#include --+#include --+ --+#ifdef __NDS32_EXT_DSP__ --+static __attribute__ ((noinline)) --+unsigned int add8 (unsigned int ra, unsigned int rb) --+{ --+ return __nds32__add8 (ra, rb); --+} --+ --+static __attribute__ ((noinline)) --+uint8x4_t v_uadd8 (uint8x4_t ra, uint8x4_t rb) --+{ --+ return __nds32__v_uadd8 (ra, rb); --+} --+ --+static __attribute__ ((noinline)) --+int8x4_t v_sadd8 (int8x4_t ra, int8x4_t rb) --+{ --+ return __nds32__v_sadd8 (ra, rb); --+} --+ --+int --+main () --+{ --+ unsigned int a = add8 (0x11223344, 0x55667788); --+ uint8x4_t v_ua = v_uadd8 ((uint8x4_t) {0xff, 0xee, 0xdd, 0xcc}, --+ (uint8x4_t) {0x1, 0xee, 0xdd, 0xcc}); --+ int8x4_t v_sa = v_sadd8 ((int8x4_t) {0x80, 0x7f, 0xbb, 0xaa}, --+ (int8x4_t) {0x80, 0x7f, 0xbb, 0xaa}); --+ --+ if (a != 0x6688aacc) --+ abort (); --+ else if (v_ua[0] != 0 --+ || v_ua[1] != 0xdc --+ || v_ua[2] != 0xba --+ || v_ua[3] != 0x98) --+ abort (); --+ else if (v_sa[0] != 0 --+ || v_sa[1] != (char) 0xfe --+ || v_sa[2] != 0x76 --+ || v_sa[3] != 0x54) --+ abort (); --+ else --+ exit (0); --+} --+#else --+int main(){return 0;} --+#endif --diff --git a/gcc/testsuite/gcc.target/nds32/builtin-dsp-bitrev.c b/gcc/testsuite/gcc.target/nds32/builtin-dsp-bitrev.c --new file mode 100644 --index 0000000..2c8c297 ----- /dev/null --+++ b/gcc/testsuite/gcc.target/nds32/builtin-dsp-bitrev.c --@@ -0,0 +1,27 @@ --+/* This is a test program for bitrev instruction. */ --+ --+/* { dg-do run } */ --+ --+#include --+#include --+ --+#ifdef __NDS32_EXT_DSP__ --+static __attribute__ ((noinline)) --+unsigned int bitrev (unsigned int ra, unsigned int rb) --+{ --+ return __nds32__bitrev (ra, rb); --+} --+ --+int --+main () --+{ --+ unsigned int a = bitrev (0xd, 1); --+ --+ if (a != 0x2) --+ abort (); --+ else --+ exit (0); --+} --+#else --+int main(){return 0;} --+#endif --diff --git a/gcc/testsuite/gcc.target/nds32/builtin-dsp-bpick.c b/gcc/testsuite/gcc.target/nds32/builtin-dsp-bpick.c --new file mode 100644 --index 0000000..78893cb ----- /dev/null --+++ b/gcc/testsuite/gcc.target/nds32/builtin-dsp-bpick.c --@@ -0,0 +1,27 @@ --+/* This is a test program for bpick instruction. */ --+ --+/* { dg-do run } */ --+ --+#include --+#include --+ --+#ifdef __NDS32_EXT_DSP__ --+static __attribute__ ((noinline)) --+unsigned int bpick (unsigned int ra, unsigned int rb, unsigned int rc) --+{ --+ return __nds32__bpick (ra, rb, rc); --+} --+ --+int --+main () --+{ --+ unsigned int a = bpick (0x11223344, 0x11332244, 0); --+ --+ if (a != 0x11332244) --+ abort (); --+ else --+ exit (0); --+} --+#else --+int main(){return 0;} --+#endif --diff --git a/gcc/testsuite/gcc.target/nds32/builtin-dsp-cmpeq16.c b/gcc/testsuite/gcc.target/nds32/builtin-dsp-cmpeq16.c --new file mode 100644 --index 0000000..c37abf4 ----- /dev/null --+++ b/gcc/testsuite/gcc.target/nds32/builtin-dsp-cmpeq16.c --@@ -0,0 +1,49 @@ --+/* This is a test program for cmpeq16 instruction. */ --+ --+/* { dg-do run } */ --+ --+#include --+#include --+ --+#ifdef __NDS32_EXT_DSP__ --+static __attribute__ ((noinline)) --+unsigned int cmpeq16 (unsigned int ra, unsigned int rb) --+{ --+ return __nds32__cmpeq16 (ra, rb); --+} --+ --+static __attribute__ ((noinline)) --+uint16x2_t v_scmpeq16 (int16x2_t ra, int16x2_t rb) --+{ --+ return __nds32__v_scmpeq16 (ra, rb); --+} --+ --+static __attribute__ ((noinline)) --+uint16x2_t v_ucmpeq16 (uint16x2_t ra, uint16x2_t rb) --+{ --+ return __nds32__v_ucmpeq16 (ra, rb); --+} --+ --+int --+main () --+{ --+ unsigned int a = cmpeq16 (0xffff0000, 0xffff0001); --+ uint16x2_t v_sa = v_scmpeq16 ((int16x2_t) {0x7fff, 0x8000}, --+ (int16x2_t) {0x8000, 0x8000}); --+ uint16x2_t v_ua = v_ucmpeq16 ((uint16x2_t) {0x7fff, 0x8000}, --+ (uint16x2_t) {0x8000, 0x8000}); --+ --+ if (a != 0xffff0000) --+ abort (); --+ else if (v_sa[0] != 0 --+ || v_sa[1] != 0xffff) --+ abort (); --+ else if (v_ua[0] != 0 --+ || v_ua[1] != 0xffff) --+ abort (); --+ else --+ exit (0); --+} --+#else --+int main(){return 0;} --+#endif --diff --git a/gcc/testsuite/gcc.target/nds32/builtin-dsp-cmpeq8.c b/gcc/testsuite/gcc.target/nds32/builtin-dsp-cmpeq8.c --new file mode 100644 --index 0000000..a692dac ----- /dev/null --+++ b/gcc/testsuite/gcc.target/nds32/builtin-dsp-cmpeq8.c --@@ -0,0 +1,53 @@ --+/* This is a test program for cmpeq8 instruction. */ --+ --+/* { dg-do run } */ --+ --+#include --+#include --+ --+#ifdef __NDS32_EXT_DSP__ --+static __attribute__ ((noinline)) --+unsigned int cmpeq8 (unsigned int ra, unsigned int rb) --+{ --+ return __nds32__cmpeq8 (ra, rb); --+} --+ --+static __attribute__ ((noinline)) --+uint8x4_t v_scmpeq8 (int8x4_t ra, int8x4_t rb) --+{ --+ return __nds32__v_scmpeq8 (ra, rb); --+} --+ --+static __attribute__ ((noinline)) --+uint8x4_t v_ucmpeq8 (uint8x4_t ra, uint8x4_t rb) --+{ --+ return __nds32__v_ucmpeq8 (ra, rb); --+} --+ --+int --+main () --+{ --+ unsigned int a = cmpeq8 (0xffff0000, 0xffff0101); --+ uint8x4_t v_sa = v_scmpeq8 ((int8x4_t) { 0x7f, 0x7f, 0x01, 0x01}, --+ (int8x4_t) { 0x7f, 0x7f, 0x00, 0x00}); --+ uint8x4_t v_ua = v_ucmpeq8 ((uint8x4_t) { 0x7f, 0x7f, 0x01, 0x01}, --+ (uint8x4_t) { 0x7f, 0x7f, 0x00, 0x00}); --+ --+ if (a != 0xffff0000) --+ abort (); --+ else if (v_sa[0] != 0xff --+ || v_sa[1] != 0xff --+ || v_sa[2] != 0 --+ || v_sa[3] != 0) --+ abort (); --+ else if (v_ua[0] != 0xff --+ || v_ua[1] != 0xff --+ || v_ua[2] != 0 --+ || v_ua[3] != 0) --+ abort (); --+ else --+ exit (0); --+} --+#else --+int main(){return 0;} --+#endif --diff --git a/gcc/testsuite/gcc.target/nds32/builtin-dsp-cras16.c b/gcc/testsuite/gcc.target/nds32/builtin-dsp-cras16.c --new file mode 100644 --index 0000000..7d6da46 ----- /dev/null --+++ b/gcc/testsuite/gcc.target/nds32/builtin-dsp-cras16.c --@@ -0,0 +1,58 @@ --+/* This is a test program for cras16 instruction. */ --+ --+/* { dg-do run } */ --+ --+#include --+#include --+ --+#ifdef __NDS32_EXT_DSP__ --+static __attribute__ ((noinline)) --+unsigned int cras16 (unsigned int ra, unsigned int rb) --+{ --+ return __nds32__cras16 (ra, rb); --+} --+ --+static __attribute__ ((noinline)) --+uint16x2_t v_ucras16 (uint16x2_t ra, uint16x2_t rb) --+{ --+ return __nds32__v_ucras16 (ra, rb); --+} --+ --+static __attribute__ ((noinline)) --+int16x2_t v_scras16 (int16x2_t ra, int16x2_t rb) --+{ --+ return __nds32__v_scras16 (ra, rb); --+} --+ --+int --+main () --+{ --+ --+#ifdef __NDS32_EL__ --+ uint16x2_t v_ua_p = {1, 0}; --+ int16x2_t v_sa_p = {0x1000, 0x111}; --+#else --+ uint16x2_t v_ua_p = {0x2469, 0xe000}; --+ int16x2_t v_sa_p = {0x3000, 0xe111}; --+#endif --+ --+ unsigned int a = cras16 (0x0001f000, 0x0001f000); --+ uint16x2_t v_ua = v_ucras16 ((uint16x2_t) {0x1235, 0xf000}, --+ (uint16x2_t) {0x1000, 0x1234}); --+ int16x2_t v_sa = v_scras16 ((int16x2_t) {0x2000, 0xf111}, --+ (int16x2_t) {0x1000, 0x1000}); --+ --+ if (a != 0xf001efff) --+ abort (); --+ else if (v_ua[0] != v_ua_p[0] --+ || v_ua[1] != v_ua_p[1]) --+ abort (); --+ else if (v_sa[0] != v_sa_p[0] --+ || v_sa[1] != v_sa_p[1]) --+ abort (); --+ else --+ exit (0); --+} --+#else --+int main(){return 0;} --+#endif --diff --git a/gcc/testsuite/gcc.target/nds32/builtin-dsp-crsa16.c b/gcc/testsuite/gcc.target/nds32/builtin-dsp-crsa16.c --new file mode 100644 --index 0000000..de99c3a ----- /dev/null --+++ b/gcc/testsuite/gcc.target/nds32/builtin-dsp-crsa16.c --@@ -0,0 +1,57 @@ --+/* This is a test program for crsa16 instruction. */ --+ --+/* { dg-do run } */ --+ --+#include --+#include --+ --+#ifdef __NDS32_EXT_DSP__ --+static __attribute__ ((noinline)) --+unsigned int crsa16 (unsigned int ra, unsigned int rb) --+{ --+ return __nds32__crsa16 (ra, rb); --+} --+ --+static __attribute__ ((noinline)) --+uint16x2_t v_ucrsa16 (uint16x2_t ra, uint16x2_t rb) --+{ --+ return __nds32__v_ucrsa16 (ra, rb); --+} --+ --+static __attribute__ ((noinline)) --+int16x2_t v_scrsa16 (int16x2_t ra, int16x2_t rb) --+{ --+ return __nds32__v_scrsa16 (ra, rb); --+} --+ --+int --+main () --+{ --+#ifdef __NDS32_EL__ --+ uint16x2_t v_ua_p = {0x2469, 0xe000}; --+ int16x2_t v_sa_p = {0x3000, 0x110}; --+#else --+ uint16x2_t v_ua_p = {1, 0}; --+ int16x2_t v_sa_p = {0x1000, 0x112}; --+#endif --+ --+ unsigned int a = crsa16 (0x0001f000, 0x0001f000); --+ uint16x2_t v_ua = v_ucrsa16 ((uint16x2_t) {0x1235, 0xf000}, --+ (uint16x2_t) {0x1000, 0x1234}); --+ int16x2_t v_sa = v_scrsa16 ((int16x2_t) {0x2000, 0x0111}, --+ (int16x2_t) {0x0001, 0x1000}); --+ --+ if (a != 0x1001f001) --+ abort (); --+ else if (v_ua[0] != v_ua_p[0] --+ || v_ua[1] != v_ua_p[1]) --+ abort (); --+ else if (v_sa[0] != v_sa_p[0] --+ || v_sa[1] != v_sa_p[1]) --+ abort (); --+ else --+ exit (0); --+} --+#else --+int main(){return 0;} --+#endif --diff --git a/gcc/testsuite/gcc.target/nds32/builtin-dsp-insb.c b/gcc/testsuite/gcc.target/nds32/builtin-dsp-insb.c --new file mode 100644 --index 0000000..ebd0348 ----- /dev/null --+++ b/gcc/testsuite/gcc.target/nds32/builtin-dsp-insb.c --@@ -0,0 +1,27 @@ --+/* This is a test program for insb instruction. */ --+ --+/* { dg-do run } */ --+ --+#include --+#include --+ --+#ifdef __NDS32_EXT_DSP__ --+static __attribute__ ((noinline)) --+unsigned int insb (unsigned int ra, unsigned int rb) --+{ --+ return __nds32__insb (ra, rb, 1); --+} --+ --+int --+main () --+{ --+ unsigned int a = insb (0x11220044, 0x33); --+ --+ if (a != 0x11223344) --+ abort (); --+ else --+ exit (0); --+} --+#else --+int main(){return 0;} --+#endif --diff --git a/gcc/testsuite/gcc.target/nds32/builtin-dsp-pkbb16.c b/gcc/testsuite/gcc.target/nds32/builtin-dsp-pkbb16.c --new file mode 100644 --index 0000000..23d92e9 ----- /dev/null --+++ b/gcc/testsuite/gcc.target/nds32/builtin-dsp-pkbb16.c --@@ -0,0 +1,44 @@ --+/* This is a test program for pkbb16 instruction. */ --+ --+/* { dg-do run } */ --+ --+#include --+#include --+ --+#ifdef __NDS32_EXT_DSP__ --+static __attribute__ ((noinline)) --+unsigned int pkbb16 (unsigned int ra, unsigned int rb) --+{ --+ return __nds32__pkbb16 (ra, rb); --+} --+ --+static __attribute__ ((noinline)) --+uint16x2_t v_pkbb16 (uint16x2_t ra, uint16x2_t rb) --+{ --+ return __nds32__v_pkbb16 (ra, rb); --+} --+ --+int --+main () --+{ --+#ifdef __NDS32_EL__ --+ uint16x2_t va_p = {0xcccc, 0xaaaa}; --+#else --+ uint16x2_t va_p = {0xbbbb, 0xdddd}; --+#endif --+ --+ unsigned int a = pkbb16 (0x11223344, 0x55667788); --+ uint16x2_t va = v_pkbb16 ((uint16x2_t) {0xaaaa, 0xbbbb}, --+ (uint16x2_t) {0xcccc, 0xdddd}); --+ --+ if (a != 0x33447788) --+ abort (); --+ else if (va[0] != va_p[0] --+ || va[1] != va_p[1]) --+ abort (); --+ else --+ exit (0); --+} --+#else --+int main(){return 0;} --+#endif --diff --git a/gcc/testsuite/gcc.target/nds32/builtin-dsp-pkbt16.c b/gcc/testsuite/gcc.target/nds32/builtin-dsp-pkbt16.c --new file mode 100644 --index 0000000..6c34420 ----- /dev/null --+++ b/gcc/testsuite/gcc.target/nds32/builtin-dsp-pkbt16.c --@@ -0,0 +1,44 @@ --+/* This is a test program for pkbt16 instruction. */ --+ --+/* { dg-do run } */ --+ --+#include --+#include --+ --+#ifdef __NDS32_EXT_DSP__ --+static __attribute__ ((noinline)) --+unsigned int pkbt16 (unsigned int ra, unsigned int rb) --+{ --+ return __nds32__pkbt16 (ra, rb); --+} --+ --+static __attribute__ ((noinline)) --+uint16x2_t v_pkbt16 (uint16x2_t ra, uint16x2_t rb) --+{ --+ return __nds32__v_pkbt16 (ra, rb); --+} --+ --+int --+main () --+{ --+#ifdef __NDS32_EL__ --+ uint16x2_t va_p = {0xdddd, 0xaaaa}; --+#else --+ uint16x2_t va_p = {0xbbbb, 0xcccc}; --+#endif --+ --+ unsigned int a = pkbt16 (0x11223344, 0x55667788); --+ uint16x2_t va = v_pkbt16 ((uint16x2_t) {0xaaaa, 0xbbbb}, --+ (uint16x2_t) {0xcccc, 0xdddd}); --+ --+ if (a != 0x33445566) --+ abort (); --+ else if (va[0] != va_p[0] --+ || va[1] != va_p[1]) --+ abort (); --+ else --+ exit (0); --+} --+#else --+int main(){return 0;} --+#endif --diff --git a/gcc/testsuite/gcc.target/nds32/builtin-dsp-pktb16.c b/gcc/testsuite/gcc.target/nds32/builtin-dsp-pktb16.c --new file mode 100644 --index 0000000..0aab5df ----- /dev/null --+++ b/gcc/testsuite/gcc.target/nds32/builtin-dsp-pktb16.c --@@ -0,0 +1,44 @@ --+/* This is a test program for pktb16 instruction. */ --+ --+/* { dg-do run } */ --+ --+#include --+#include --+ --+#ifdef __NDS32_EXT_DSP__ --+static __attribute__ ((noinline)) --+unsigned int pktb16 (unsigned int ra, unsigned int rb) --+{ --+ return __nds32__pktb16 (ra, rb); --+} --+ --+static __attribute__ ((noinline)) --+uint16x2_t v_pktb16 (uint16x2_t ra, uint16x2_t rb) --+{ --+ return __nds32__v_pktb16 (ra, rb); --+} --+ --+int --+main () --+{ --+#ifdef __NDS32_EL__ --+ uint16x2_t va_p = {0xcccc, 0xbbbb}; --+#else --+ uint16x2_t va_p = {0xaaaa, 0xdddd}; --+#endif --+ --+ unsigned int a = pktb16 (0x11223344, 0x55667788); --+ uint16x2_t va = v_pktb16 ((uint16x2_t) {0xaaaa, 0xbbbb}, --+ (uint16x2_t) {0xcccc, 0xdddd}); --+ --+ if (a != 0x11227788) --+ abort (); --+ else if (va[0] != va_p[0] --+ || va[1] != va_p[1]) --+ abort (); --+ else --+ exit (0); --+} --+#else --+int main(){return 0;} --+#endif --diff --git a/gcc/testsuite/gcc.target/nds32/builtin-dsp-pktt16.c b/gcc/testsuite/gcc.target/nds32/builtin-dsp-pktt16.c --new file mode 100644 --index 0000000..745cde5 ----- /dev/null --+++ b/gcc/testsuite/gcc.target/nds32/builtin-dsp-pktt16.c --@@ -0,0 +1,44 @@ --+/* This is a test program for pktt16 instruction. */ --+ --+/* { dg-do run } */ --+ --+#include --+#include --+ --+#ifdef __NDS32_EXT_DSP__ --+static __attribute__ ((noinline)) --+unsigned int pktt16 (unsigned int ra, unsigned int rb) --+{ --+ return __nds32__pktt16 (ra, rb); --+} --+ --+static __attribute__ ((noinline)) --+uint16x2_t v_pktt16 (uint16x2_t ra, uint16x2_t rb) --+{ --+ return __nds32__v_pktt16 (ra, rb); --+} --+ --+int --+main () --+{ --+#ifdef __NDS32_EL__ --+ uint16x2_t va_p = {0xdddd, 0xbbbb}; --+#else --+ uint16x2_t va_p = {0xaaaa, 0xcccc}; --+#endif --+ --+ unsigned int a = pktt16 (0x11223344, 0x55667788); --+ uint16x2_t va = v_pktt16 ((uint16x2_t) {0xaaaa, 0xbbbb}, --+ (uint16x2_t) {0xcccc, 0xdddd}); --+ --+ if (a != 0x11225566) --+ abort (); --+ else if (va[0] != va_p[0] --+ || va[1] != va_p[1]) --+ abort (); --+ else --+ exit (0); --+} --+#else --+int main(){return 0;} --+#endif --diff --git a/gcc/testsuite/gcc.target/nds32/builtin-dsp-radd16.c b/gcc/testsuite/gcc.target/nds32/builtin-dsp-radd16.c --new file mode 100644 --index 0000000..5271b41 ----- /dev/null --+++ b/gcc/testsuite/gcc.target/nds32/builtin-dsp-radd16.c --@@ -0,0 +1,38 @@ --+/* This is a test program for radd16 instruction. */ --+ --+/* { dg-do run } */ --+ --+#include --+#include --+ --+#ifdef __NDS32_EXT_DSP__ --+static __attribute__ ((noinline)) --+unsigned int radd16 (unsigned int ra, unsigned int rb) --+{ --+ return __nds32__radd16 (ra, rb); --+} --+ --+static __attribute__ ((noinline)) --+int16x2_t v_radd16 (int16x2_t ra, int16x2_t rb) --+{ --+ return __nds32__v_radd16 (ra, rb); --+} --+ --+int --+main () --+{ --+ unsigned int a = radd16 (0x7fff7fff, 0x7fff7fff); --+ int16x2_t va = v_radd16 ((int16x2_t) {0x8000, 0x4000}, --+ (int16x2_t) {0x8000, 0x8000}); --+ --+ if (a != 0x7fff7fff) --+ abort (); --+ else if (va[0] != (short) 0x8000 --+ || va[1] != (short) 0xe000) --+ abort (); --+ else --+ exit (0); --+} --+#else --+int main(){return 0;} --+#endif --diff --git a/gcc/testsuite/gcc.target/nds32/builtin-dsp-radd64.c b/gcc/testsuite/gcc.target/nds32/builtin-dsp-radd64.c --new file mode 100644 --index 0000000..3e82ff5 ----- /dev/null --+++ b/gcc/testsuite/gcc.target/nds32/builtin-dsp-radd64.c --@@ -0,0 +1,27 @@ --+/* This is a test program for radd64 instruction. */ --+ --+/* { dg-do run } */ --+ --+#include --+#include --+ --+#ifdef __NDS32_EXT_DSP__ --+static __attribute__ ((noinline)) --+long long radd64 (long long ra, long long rb) --+{ --+ return __nds32__radd64 (ra, rb); --+} --+ --+int --+main () --+{ --+ long long a = radd64 (0xf000000000000000ll, 0xf000000000000000ll); --+ --+ if (a != 0xf000000000000000ll) --+ abort (); --+ else --+ exit (0); --+} --+#else --+int main(){return 0;} --+#endif --diff --git a/gcc/testsuite/gcc.target/nds32/builtin-dsp-radd8.c b/gcc/testsuite/gcc.target/nds32/builtin-dsp-radd8.c --new file mode 100644 --index 0000000..10735a1 ----- /dev/null --+++ b/gcc/testsuite/gcc.target/nds32/builtin-dsp-radd8.c --@@ -0,0 +1,40 @@ --+/* This is a test program for radd8 instruction. */ --+ --+/* { dg-do run } */ --+ --+#include --+#include --+ --+#ifdef __NDS32_EXT_DSP__ --+static __attribute__ ((noinline)) --+unsigned int radd8 (unsigned int ra, unsigned int rb) --+{ --+ return __nds32__radd8 (ra, rb); --+} --+ --+static __attribute__ ((noinline)) --+int8x4_t v_radd8 (int8x4_t ra, int8x4_t rb) --+{ --+ return __nds32__v_radd8 (ra, rb); --+} --+ --+int --+main () --+{ --+ unsigned int a = radd8 (0x11223344, 0x55667788); --+ int8x4_t va = v_radd8 ((int8x4_t) {0x7f, 0x80, 0x80, 0xaa}, --+ (int8x4_t) {0x7f, 0x80, 0x40, 0xaa}); --+ --+ if (a != 0x334455e6) --+ abort (); --+ else if (va[0] != 0x7f --+ || va[1] != (char) 0x80 --+ || va[2] != (char) 0xe0 --+ || va[3] != (char) 0xaa) --+ abort (); --+ else --+ exit (0); --+} --+#else --+int main(){return 0;} --+#endif --diff --git a/gcc/testsuite/gcc.target/nds32/builtin-dsp-raddw.c b/gcc/testsuite/gcc.target/nds32/builtin-dsp-raddw.c --new file mode 100644 --index 0000000..190a477 ----- /dev/null --+++ b/gcc/testsuite/gcc.target/nds32/builtin-dsp-raddw.c --@@ -0,0 +1,27 @@ --+/* This is a test program for raddw instruction. */ --+ --+/* { dg-do run } */ --+ --+#include --+#include --+ --+#ifdef __NDS32_EXT_DSP__ --+static __attribute__ ((noinline)) --+int raddw (int ra, int rb) --+{ --+ return __nds32__raddw (ra, rb); --+} --+ --+int --+main () --+{ --+ int a = raddw (0x80000000, 0x80000000); --+ --+ if (a != 0x80000000) --+ abort (); --+ else --+ exit (0); --+} --+#else --+int main(){return 0;} --+#endif --diff --git a/gcc/testsuite/gcc.target/nds32/builtin-dsp-rcras16.c b/gcc/testsuite/gcc.target/nds32/builtin-dsp-rcras16.c --new file mode 100644 --index 0000000..2a2288a ----- /dev/null --+++ b/gcc/testsuite/gcc.target/nds32/builtin-dsp-rcras16.c --@@ -0,0 +1,44 @@ --+/* This is a test program for rcras16 instruction. */ --+ --+/* { dg-do run } */ --+ --+#include --+#include --+ --+#ifdef __NDS32_EXT_DSP__ --+static __attribute__ ((noinline)) --+unsigned int rcras16 (unsigned int ra, unsigned int rb) --+{ --+ return __nds32__rcras16 (ra, rb); --+} --+ --+static __attribute__ ((noinline)) --+int16x2_t v_rcras16 (int16x2_t ra, int16x2_t rb) --+{ --+ return __nds32__v_rcras16 (ra, rb); --+} --+ --+int --+main () --+{ --+#ifdef __NDS32_EL__ --+ int16x2_t va_p = {0x7fff, 0x8000}; --+#else --+ int16x2_t va_p = {0xffff, 0}; --+#endif --+ --+ unsigned int a = rcras16 (0x0fff0000, 0x00000fff); --+ int16x2_t va = v_rcras16 ((int16x2_t) {0x7fff, 0x8000}, --+ (int16x2_t) {0x8000, 0x8000}); --+ --+ if (a != 0x0fff0000) --+ abort (); --+ else if (va[0] != va_p[0] --+ || va[1] != va_p[1]) --+ abort (); --+ else --+ exit (0); --+} --+#else --+int main(){return 0;} --+#endif --diff --git a/gcc/testsuite/gcc.target/nds32/builtin-dsp-rcrsa16.c b/gcc/testsuite/gcc.target/nds32/builtin-dsp-rcrsa16.c --new file mode 100644 --index 0000000..ebcc0f6 ----- /dev/null --+++ b/gcc/testsuite/gcc.target/nds32/builtin-dsp-rcrsa16.c --@@ -0,0 +1,44 @@ --+/* This is a test program for rcrsa16 instruction. */ --+ --+/* { dg-do run } */ --+ --+#include --+#include --+ --+#ifdef __NDS32_EXT_DSP__ --+static __attribute__ ((noinline)) --+unsigned int rcrsa16 (unsigned int ra, unsigned int rb) --+{ --+ return __nds32__rcrsa16 (ra, rb); --+} --+ --+static __attribute__ ((noinline)) --+int16x2_t v_rcrsa16 (int16x2_t ra, int16x2_t rb) --+{ --+ return __nds32__v_rcrsa16 (ra, rb); --+} --+ --+int --+main () --+{ --+#ifdef __NDS32_EL__ --+ int16x2_t va_p = {0x8000, 0x8000}; --+#else --+ int16x2_t va_p = {0, 0xffff}; --+#endif --+ --+ unsigned int a = rcrsa16 (0x7fff7fff, 0x7fff8000); --+ int16x2_t va = v_rcrsa16 ((int16x2_t) {0x8000, 0x8000}, --+ (int16x2_t) {0x7fff, 0x8000}); --+ --+ if (a != 0x7fff7fff) --+ abort (); --+ else if (va[0] != va_p [0] --+ || va[1] != va_p [1]) --+ abort (); --+ else --+ exit (0); --+} --+#else --+int main(){return 0;} --+#endif --diff --git a/gcc/testsuite/gcc.target/nds32/builtin-dsp-rsub16.c b/gcc/testsuite/gcc.target/nds32/builtin-dsp-rsub16.c --new file mode 100644 --index 0000000..f9fcc86 ----- /dev/null --+++ b/gcc/testsuite/gcc.target/nds32/builtin-dsp-rsub16.c --@@ -0,0 +1,38 @@ --+/* This is a test program for rsub16 instruction. */ --+ --+/* { dg-do run } */ --+ --+#include --+#include --+ --+#ifdef __NDS32_EXT_DSP__ --+static __attribute__ ((noinline)) --+unsigned int rsub16 (unsigned int ra, unsigned int rb) --+{ --+ return __nds32__rsub16 (ra, rb); --+} --+ --+static __attribute__ ((noinline)) --+int16x2_t v_rsub16 (int16x2_t ra, int16x2_t rb) --+{ --+ return __nds32__v_rsub16 (ra, rb); --+} --+ --+int --+main () --+{ --+ unsigned int a = rsub16 (0x7fff7fff, 0x80008000); --+ int16x2_t va = v_rsub16 ((int16x2_t) {0x8000, 0x8000}, --+ (int16x2_t) {0x7fff, 0x4000}); --+ --+ if (a != 0x7fff7fff) --+ abort (); --+ else if (va[0] != (short) 0x8000 --+ || va[1] != (short) 0xa000) --+ abort (); --+ else --+ exit (0); --+} --+#else --+int main(){return 0;} --+#endif --diff --git a/gcc/testsuite/gcc.target/nds32/builtin-dsp-rsub64.c b/gcc/testsuite/gcc.target/nds32/builtin-dsp-rsub64.c --new file mode 100644 --index 0000000..227eba7 ----- /dev/null --+++ b/gcc/testsuite/gcc.target/nds32/builtin-dsp-rsub64.c --@@ -0,0 +1,27 @@ --+/* This is a test program for rsub64 instruction. */ --+ --+/* { dg-do run } */ --+ --+#include --+#include --+ --+#ifdef __NDS32_EXT_DSP__ --+static __attribute__ ((noinline)) --+long long rsub64 (long long ra, long long rb) --+{ --+ return __nds32__rsub64 (ra, rb); --+} --+ --+int --+main () --+{ --+ long long a = rsub64 (0xe, 0xf); --+ --+ if (a != 0xffffffffffffffff) --+ abort (); --+ else --+ exit (0); --+} --+#else --+int main(){return 0;} --+#endif --diff --git a/gcc/testsuite/gcc.target/nds32/builtin-dsp-rsub8.c b/gcc/testsuite/gcc.target/nds32/builtin-dsp-rsub8.c --new file mode 100644 --index 0000000..0f1dddc ----- /dev/null --+++ b/gcc/testsuite/gcc.target/nds32/builtin-dsp-rsub8.c --@@ -0,0 +1,40 @@ --+/* This is a test program for rsub8 instruction. */ --+ --+/* { dg-do run } */ --+ --+#include --+#include --+ --+#ifdef __NDS32_EXT_DSP__ --+static __attribute__ ((noinline)) --+unsigned int rsub8 (unsigned int ra, unsigned int rb) --+{ --+ return __nds32__rsub8 (ra, rb); --+} --+ --+static __attribute__ ((noinline)) --+int8x4_t v_rsub8 (int8x4_t ra, int8x4_t rb) --+{ --+ return __nds32__v_rsub8 (ra, rb); --+} --+ --+int --+main () --+{ --+ unsigned int a = rsub8 (0x55667788, 0x11223344); --+ int8x4_t va = v_rsub8 ((int8x4_t) {0x7f, 0x80, 0x80, 0xaa}, --+ (int8x4_t) {0x80, 0x7f, 0x40, 0xaa}); --+ --+ if (a != 0x222222a2) --+ abort (); --+ else if (va[0] != 0x7f --+ || va[1] != (char) 0x80 --+ || va[2] != (char) 0xa0 --+ || va[3] != 0) --+ abort (); --+ else --+ exit (0); --+} --+#else --+int main(){return 0;} --+#endif --diff --git a/gcc/testsuite/gcc.target/nds32/builtin-dsp-rsubw.c b/gcc/testsuite/gcc.target/nds32/builtin-dsp-rsubw.c --new file mode 100644 --index 0000000..b70a229 ----- /dev/null --+++ b/gcc/testsuite/gcc.target/nds32/builtin-dsp-rsubw.c --@@ -0,0 +1,27 @@ --+/* This is a test program for rsubw instruction. */ --+ --+/* { dg-do run } */ --+ --+#include --+#include --+ --+#ifdef __NDS32_EXT_DSP__ --+static __attribute__ ((noinline)) --+int rsubw (int ra, int rb) --+{ --+ return __nds32__rsubw (ra, rb); --+} --+ --+int --+main () --+{ --+ int a = rsubw (0x80000000, 0x7fffffff); --+ --+ if (a != 0x80000000) --+ abort (); --+ else --+ exit (0); --+} --+#else --+int main(){return 0;} --+#endif --diff --git a/gcc/testsuite/gcc.target/nds32/builtin-dsp-scmple16.c b/gcc/testsuite/gcc.target/nds32/builtin-dsp-scmple16.c --new file mode 100644 --index 0000000..95251d6 ----- /dev/null --+++ b/gcc/testsuite/gcc.target/nds32/builtin-dsp-scmple16.c --@@ -0,0 +1,37 @@ --+/* This is a test program for scmple16 instruction. */ --+ --+/* { dg-do run } */ --+ --+#include --+#include --+ --+#ifdef __NDS32_EXT_DSP__ --+static __attribute__ ((noinline)) --+unsigned int scmple16 (unsigned int ra, unsigned int rb) --+{ --+ return __nds32__scmple16 (ra, rb); --+} --+ --+static __attribute__ ((noinline)) --+uint16x2_t v_scmple16 (int16x2_t ra, int16x2_t rb) --+{ --+ return __nds32__v_scmple16 (ra, rb); --+} --+ --+int --+main () --+{ --+ unsigned int a = scmple16 (0xfffe0001, 0xffff0000); --+ uint16x2_t va = v_scmple16 ((int16x2_t) {0x7fff, 0x7ffe}, --+ (int16x2_t) {0x7ffe, 0x7fff}); --+ if (a != 0xffff0000) --+ abort (); --+ else if (va[0] != 0 --+ || va[1] != 0xffff) --+ abort (); --+ else --+ exit (0); --+} --+#else --+int main(){return 0;} --+#endif --diff --git a/gcc/testsuite/gcc.target/nds32/builtin-dsp-scmple8.c b/gcc/testsuite/gcc.target/nds32/builtin-dsp-scmple8.c --new file mode 100644 --index 0000000..6c0033d ----- /dev/null --+++ b/gcc/testsuite/gcc.target/nds32/builtin-dsp-scmple8.c --@@ -0,0 +1,40 @@ --+/* This is a test program for scmple8 instruction. */ --+ --+/* { dg-do run } */ --+ --+#include --+#include --+ --+#ifdef __NDS32_EXT_DSP__ --+static __attribute__ ((noinline)) --+unsigned int scmple8 (unsigned int ra, unsigned int rb) --+{ --+ return __nds32__scmple8 (ra, rb); --+} --+ --+static __attribute__ ((noinline)) --+uint8x4_t v_scmple8 (int8x4_t ra, int8x4_t rb) --+{ --+ return __nds32__v_scmple8 (ra, rb); --+} --+ --+int --+main () --+{ --+ unsigned int a = scmple8 (0xfefe0101, 0xffff0000); --+ uint8x4_t va = v_scmple8 ((int8x4_t) {0x7e, 0x7e, 0x01, 0x01}, --+ (int8x4_t) {0x7f, 0x7f, 0x00, 0x00}); --+ --+ if (a != 0xffff0000) --+ abort (); --+ else if (va[0] != 0xff --+ || va[1] != 0xff --+ || va[2] != 0 --+ || va[3] != 0) --+ abort (); --+ else --+ exit (0); --+} --+#else --+int main(){return 0;} --+#endif --diff --git a/gcc/testsuite/gcc.target/nds32/builtin-dsp-scmplt16.c b/gcc/testsuite/gcc.target/nds32/builtin-dsp-scmplt16.c --new file mode 100644 --index 0000000..5797711 ----- /dev/null --+++ b/gcc/testsuite/gcc.target/nds32/builtin-dsp-scmplt16.c --@@ -0,0 +1,38 @@ --+/* This is a test program for scmplt16 instruction. */ --+ --+/* { dg-do run } */ --+ --+#include --+#include --+ --+#ifdef __NDS32_EXT_DSP__ --+static __attribute__ ((noinline)) --+unsigned int scmplt16 (unsigned int ra, unsigned int rb) --+{ --+ return __nds32__scmplt16 (ra, rb); --+} --+ --+static __attribute__ ((noinline)) --+uint16x2_t v_scmplt16 (int16x2_t ra, int16x2_t rb) --+{ --+ return __nds32__v_scmplt16 (ra, rb); --+} --+ --+int --+main () --+{ --+ unsigned int a = scmplt16 (0xfffe0001, 0xffff0000); --+ uint16x2_t va = v_scmplt16 ((int16x2_t) {0x7fff, 0x7ffe}, --+ (int16x2_t) {0x7ffe, 0x7fff}); --+ --+ if (a != 0xffff0000) --+ abort (); --+ else if (va[0] != 0 --+ || va[1] != 0xffff) --+ abort (); --+ else --+ exit (0); --+} --+#else --+int main(){return 0;} --+#endif --diff --git a/gcc/testsuite/gcc.target/nds32/builtin-dsp-scmplt8.c b/gcc/testsuite/gcc.target/nds32/builtin-dsp-scmplt8.c --new file mode 100644 --index 0000000..3e52006 ----- /dev/null --+++ b/gcc/testsuite/gcc.target/nds32/builtin-dsp-scmplt8.c --@@ -0,0 +1,40 @@ --+/* This is a test program for scmplt8 instruction. */ --+ --+/* { dg-do run } */ --+ --+#include --+#include --+ --+#ifdef __NDS32_EXT_DSP__ --+static __attribute__ ((noinline)) --+unsigned int scmplt8 (unsigned int ra, unsigned int rb) --+{ --+ return __nds32__scmplt8 (ra, rb); --+} --+ --+static __attribute__ ((noinline)) --+uint8x4_t v_scmplt8 (int8x4_t ra, int8x4_t rb) --+{ --+ return __nds32__v_scmplt8 (ra, rb); --+} --+ --+int --+main () --+{ --+ unsigned int a = scmplt8 (0xfefe0101, 0xffff0000); --+ uint8x4_t va = v_scmplt8 ((int8x4_t) {0x7e, 0x7e, 0x01, 0x01}, --+ (int8x4_t) {0x7f, 0x7f, 0x00, 0x00}); --+ --+ if (a != 0xffff0000) --+ abort (); --+ else if (va[0] != 0xff --+ || va[1] != 0xff --+ || va[2] != 0 --+ || va[3] != 0) --+ abort (); --+ else --+ exit (0); --+} --+#else --+int main(){return 0;} --+#endif --diff --git a/gcc/testsuite/gcc.target/nds32/builtin-dsp-sll16.c b/gcc/testsuite/gcc.target/nds32/builtin-dsp-sll16.c --new file mode 100644 --index 0000000..5ab9506 ----- /dev/null --+++ b/gcc/testsuite/gcc.target/nds32/builtin-dsp-sll16.c --@@ -0,0 +1,37 @@ --+/* This is a test program for sll16 instruction. */ --+ --+/* { dg-do run } */ --+ --+#include --+#include --+ --+#ifdef __NDS32_EXT_DSP__ --+static __attribute__ ((noinline)) --+unsigned int sll16 (unsigned int ra, unsigned int rb) --+{ --+ return __nds32__sll16 (ra, rb); --+} --+ --+static __attribute__ ((noinline)) --+uint16x2_t v_sll16 (uint16x2_t ra, unsigned int rb) --+{ --+ return __nds32__v_sll16 (ra, rb); --+} --+ --+int --+main () --+{ --+ unsigned int a = sll16 (0x0f00f000, 4); --+ uint16x2_t va = v_sll16 ((uint16x2_t) {0x7fff, 0x8000}, 4); --+ --+ if (a != 0xf0000000) --+ abort (); --+ else if (va[0] != 0xfff0 --+ || va[1] != 0) --+ abort (); --+ else --+ exit (0); --+} --+#else --+int main(){return 0;} --+#endif --diff --git a/gcc/testsuite/gcc.target/nds32/builtin-dsp-smal.c b/gcc/testsuite/gcc.target/nds32/builtin-dsp-smal.c --new file mode 100644 --index 0000000..f7e54b7 ----- /dev/null --+++ b/gcc/testsuite/gcc.target/nds32/builtin-dsp-smal.c --@@ -0,0 +1,36 @@ --+/* This is a test program for smal instruction. */ --+ --+/* { dg-do run } */ --+ --+#include --+#include --+ --+#ifdef __NDS32_EXT_DSP__ --+static __attribute__ ((noinline)) --+long long smal (long long ra, unsigned int rb) --+{ --+ return __nds32__smal (ra, rb); --+} --+ --+static __attribute__ ((noinline)) --+long long v_smal (long long ra, int16x2_t rb) --+{ --+ return __nds32__v_smal (ra, rb); --+} --+ --+int --+main () --+{ --+ long long a = smal (0xfffff0000ll, 0x0001ffff); --+ long long va = v_smal (0xffffff0000ll, --+ (int16x2_t) {0x0002, 0xffff}); --+ if (a != 0xffffeffffll) --+ abort (); --+ else if (va != 0xfffffefffell) --+ abort (); --+ else --+ exit (0); --+} --+#else --+int main(){return 0;} --+#endif --diff --git a/gcc/testsuite/gcc.target/nds32/builtin-dsp-smalbb.c b/gcc/testsuite/gcc.target/nds32/builtin-dsp-smalbb.c --new file mode 100644 --index 0000000..c39a889 ----- /dev/null --+++ b/gcc/testsuite/gcc.target/nds32/builtin-dsp-smalbb.c --@@ -0,0 +1,45 @@ --+/* This is a test program for smalbb instruction. */ --+ --+/* { dg-do run } */ --+ --+#include --+#include --+ --+#ifdef __NDS32_EXT_DSP__ --+static __attribute__ ((noinline)) --+long long smalbb (long long t, unsigned int a, unsigned int b) --+{ --+ return __nds32__smalbb (t, a, b); --+} --+ --+static __attribute__ ((noinline)) --+long long v_smalbb (long long t, int16x2_t a, int16x2_t b) --+{ --+ return __nds32__v_smalbb (t, a, b); --+} --+ --+ --+int --+main () --+{ --+#ifdef __NDS32_EL__ --+ long long a_p = 0x12345679075ca9d3ll; --+ long long va_p = 0x12345679075ca9d3ll; --+#else --+ long long a_p = 0x12345679075ca9d3ll; --+ long long va_p = 0x12345678ffffffffll; --+#endif --+ --+ long long a = smalbb (0x12345678ffffffffll,0x00006789, 0x00001234); --+ long long va = v_smalbb (0x12345678ffffffffll, (int16x2_t) {0x6789, 0}, --+ (int16x2_t) {0x1234, 0}); --+ if (a != a_p) --+ abort (); --+ else if (va != va_p) --+ abort (); --+ else --+ exit (0); --+} --+#else --+int main(){return 0;} --+#endif --diff --git a/gcc/testsuite/gcc.target/nds32/builtin-dsp-smalbt.c b/gcc/testsuite/gcc.target/nds32/builtin-dsp-smalbt.c --new file mode 100644 --index 0000000..06577fd ----- /dev/null --+++ b/gcc/testsuite/gcc.target/nds32/builtin-dsp-smalbt.c --@@ -0,0 +1,45 @@ --+/* This is a test program for smalbt instruction. */ --+ --+/* { dg-do run } */ --+ --+#include --+#include --+ --+#ifdef __NDS32_EXT_DSP__ --+static __attribute__ ((noinline)) --+long long smalbt (long long t, unsigned int a, unsigned int b) --+{ --+ return __nds32__smalbt (t, a, b); --+} --+ --+static __attribute__ ((noinline)) --+long long v_smalbt (long long t, int16x2_t a, int16x2_t b) --+{ --+ return __nds32__v_smalbt (t, a, b); --+} --+ --+ --+int --+main () --+{ --+#ifdef __NDS32_EL__ --+ long long a_p = 0x12345679075ca9d3ll; --+ long long va_p = 0x12345679075ca9d3ll; --+#else --+ long long a_p = 0x12345679075ca9d3ll; --+ long long va_p = 0x12345678ffffffffll; --+#endif --+ --+ long long a = smalbt (0x12345678ffffffffll, 0x00006789, 0x12340000); --+ long long va = v_smalbt (0x12345678ffffffffll, (int16x2_t) {0x6789, 0}, --+ (int16x2_t) {0, 0x1234}); --+ if (a != a_p) --+ abort (); --+ else if (va != va_p) --+ abort (); --+ else --+ exit (0); --+} --+#else --+int main(){return 0;} --+#endif --diff --git a/gcc/testsuite/gcc.target/nds32/builtin-dsp-smalda.c b/gcc/testsuite/gcc.target/nds32/builtin-dsp-smalda.c --new file mode 100644 --index 0000000..33b4b3f ----- /dev/null --+++ b/gcc/testsuite/gcc.target/nds32/builtin-dsp-smalda.c --@@ -0,0 +1,38 @@ --+/* This is a test program for smalda instruction. */ --+ --+/* { dg-do run } */ --+ --+#include --+#include --+ --+#ifdef __NDS32_EXT_DSP__ --+static __attribute__ ((noinline)) --+long long smalda (long long t, unsigned int a, unsigned int b) --+{ --+ return __nds32__smalda (t, a, b); --+} --+ --+static __attribute__ ((noinline)) --+long long v_smalda (long long t, int16x2_t a, int16x2_t b) --+{ --+ return __nds32__v_smalda (t, a, b); --+} --+ --+ --+int --+main () --+{ --+ long long a = smalda (0x12345678ffffffffll, 0x67890000, 0x12340000); --+ long long va = v_smalda (0x12345678ffffffffll, (int16x2_t) {0, 0x6789}, --+ (int16x2_t) {0, 0x1234}); --+ --+ if (a != 0x12345679075CA9D3ll) --+ abort (); --+ else if (va != 0x12345679075CA9D3ll) --+ abort (); --+ else --+ exit (0); --+} --+#else --+int main(){return 0;} --+#endif --diff --git a/gcc/testsuite/gcc.target/nds32/builtin-dsp-smaldrs.c b/gcc/testsuite/gcc.target/nds32/builtin-dsp-smaldrs.c --new file mode 100644 --index 0000000..48255b1 ----- /dev/null --+++ b/gcc/testsuite/gcc.target/nds32/builtin-dsp-smaldrs.c --@@ -0,0 +1,46 @@ --+/* This is a test program for smaldrs instruction. */ --+ --+/* { dg-do run } */ --+ --+#include --+#include --+ --+#ifdef __NDS32_EXT_DSP__ --+static __attribute__ ((noinline)) --+long long smaldrs (long long t, unsigned int a, unsigned int b) --+{ --+ return __nds32__smaldrs (t, a, b); --+} --+ --+static __attribute__ ((noinline)) --+long long v_smaldrs (long long t, int16x2_t a, int16x2_t b) --+{ --+ return __nds32__v_smaldrs (t, a, b); --+} --+ --+ --+int --+main () --+{ --+#ifdef __NDS32_EL__ --+ long long a_p = 0x12345678ffffaaaall; --+ long long va_p = 0x12345678ffffaaaall; --+#else --+ long long a_p = 0x12345678ffffaaaall; --+ long long va_p = 0x1234567900005554ll; --+#endif --+ --+ long long a = smaldrs (0x12345678ffffffffll, 0x67890001, 0x00011234); --+ long long va = v_smaldrs (0x12345678ffffffffll, (int16x2_t) {0x0001, 0x6789}, --+ (int16x2_t) {0x1234, 0x0001}); --+ --+ if (a != a_p) --+ abort (); --+ else if (va != va_p) --+ abort (); --+ else --+ exit (0); --+} --+#else --+int main(){return 0;} --+#endif --diff --git a/gcc/testsuite/gcc.target/nds32/builtin-dsp-smalds.c b/gcc/testsuite/gcc.target/nds32/builtin-dsp-smalds.c --new file mode 100644 --index 0000000..5a89ea6 ----- /dev/null --+++ b/gcc/testsuite/gcc.target/nds32/builtin-dsp-smalds.c --@@ -0,0 +1,46 @@ --+/* This is a test program for smalds instruction. */ --+ --+/* { dg-do run } */ --+ --+#include --+#include --+ --+#ifdef __NDS32_EXT_DSP__ --+static __attribute__ ((noinline)) --+long long smalds (long long t, unsigned int a, unsigned int b) --+{ --+ return __nds32__smalds (t, a, b); --+} --+ --+static __attribute__ ((noinline)) --+long long v_smalds (long long t, int16x2_t a, int16x2_t b) --+{ --+ return __nds32__v_smalds (t, a, b); --+} --+ --+ --+int --+main () --+{ --+#ifdef __NDS32_EL__ --+ long long a_p = 0x12345678ffffaaaall; --+ long long va_p = 0x12345678ffffaaaall; --+#else --+ long long a_p = 0x12345678ffffaaaall; --+ long long va_p = 0x1234567900005554ll; --+#endif --+ --+ long long a = smalds (0x12345678ffffffffll, 0x12340001, 0x00016789); --+ long long va = v_smalds (0x12345678ffffffffll, (int16x2_t) {0x0001, 0x1234}, --+ (int16x2_t) {0x6789, 0x0001}); --+ --+ if (a != a_p) --+ abort (); --+ else if (va != va_p) --+ abort (); --+ else --+ exit (0); --+} --+#else --+int main(){return 0;} --+#endif --diff --git a/gcc/testsuite/gcc.target/nds32/builtin-dsp-smaltt.c b/gcc/testsuite/gcc.target/nds32/builtin-dsp-smaltt.c --new file mode 100644 --index 0000000..709607a ----- /dev/null --+++ b/gcc/testsuite/gcc.target/nds32/builtin-dsp-smaltt.c --@@ -0,0 +1,46 @@ --+/* This is a test program for smaltt instruction. */ --+ --+/* { dg-do run } */ --+ --+#include --+#include --+ --+#ifdef __NDS32_EXT_DSP__ --+static __attribute__ ((noinline)) --+long long smaltt (long long t, unsigned int a, unsigned int b) --+{ --+ return __nds32__smaltt (t, a, b); --+} --+ --+static __attribute__ ((noinline)) --+long long v_smaltt (long long t, int16x2_t a, int16x2_t b) --+{ --+ return __nds32__v_smaltt (t, a, b); --+} --+ --+ --+int --+main () --+{ --+#ifdef __NDS32_EL__ --+ long long a_p = 0x12345679075ca9d3ll; --+ long long va_p = 0x12345679075ca9d3ll; --+#else --+ long long a_p = 0x12345679075ca9d3ll; --+ long long va_p = 0x12345678ffffffffll; --+#endif --+ --+ long long a = smaltt (0x12345678ffffffffll, 0x67890000, 0x12340000); --+ long long va = v_smaltt (0x12345678ffffffffll, (int16x2_t) {0, 0x6789}, --+ (int16x2_t) {0, 0x1234}); --+ --+ if (a != a_p) --+ abort (); --+ else if (va != va_p) --+ abort (); --+ else --+ exit (0); --+} --+#else --+int main(){return 0;} --+#endif --diff --git a/gcc/testsuite/gcc.target/nds32/builtin-dsp-smalxda.c b/gcc/testsuite/gcc.target/nds32/builtin-dsp-smalxda.c --new file mode 100644 --index 0000000..0f90250 ----- /dev/null --+++ b/gcc/testsuite/gcc.target/nds32/builtin-dsp-smalxda.c --@@ -0,0 +1,38 @@ --+/* This is a test program for smalxda instruction. */ --+ --+/* { dg-do run } */ --+ --+#include --+#include --+ --+#ifdef __NDS32_EXT_DSP__ --+static __attribute__ ((noinline)) --+long long smalxda (long long t, unsigned int a, unsigned int b) --+{ --+ return __nds32__smalxda (t, a, b); --+} --+ --+static __attribute__ ((noinline)) --+long long v_smalxda (long long t, int16x2_t a, int16x2_t b) --+{ --+ return __nds32__v_smalxda (t, a, b); --+} --+ --+ --+int --+main () --+{ --+ long long a = smalxda (0x12345678ffffffffll, 0x67890000, 0x00001234); --+ long long va = v_smalxda (0x12345678ffffffffll, (int16x2_t) {0, 0x6789}, --+ (int16x2_t) {0x1234, 0}); --+ --+ if (a != 0x12345679075CA9D3) --+ abort (); --+ else if (va != 0x12345679075CA9D3) --+ abort (); --+ else --+ exit (0); --+} --+#else --+int main(){return 0;} --+#endif --diff --git a/gcc/testsuite/gcc.target/nds32/builtin-dsp-smalxds.c b/gcc/testsuite/gcc.target/nds32/builtin-dsp-smalxds.c --new file mode 100644 --index 0000000..ee2e098 ----- /dev/null --+++ b/gcc/testsuite/gcc.target/nds32/builtin-dsp-smalxds.c --@@ -0,0 +1,46 @@ --+/* This is a test program for smalxds instruction. */ --+ --+/* { dg-do run } */ --+ --+#include --+#include --+ --+#ifdef __NDS32_EXT_DSP__ --+static __attribute__ ((noinline)) --+long long smalxds (long long t, unsigned int a, unsigned int b) --+{ --+ return __nds32__smalxds (t, a, b); --+} --+ --+static __attribute__ ((noinline)) --+long long v_smalxds (long long t, int16x2_t a, int16x2_t b) --+{ --+ return __nds32__v_smalxds (t, a, b); --+} --+ --+ --+int --+main () --+{ --+#ifdef __NDS32_EL__ --+ long long a_p = 0x12345678ffffaaaall; --+ long long va_p = 0x12345678ffffaaaall; --+#else --+ long long a_p = 0x12345678ffffaaaall; --+ long long va_p = 0x1234567900005554ll; --+#endif --+ --+ long long a = smalxds (0x12345678ffffffffll, 0x12340001, 0x67890001); --+ long long va = v_smalxds (0x12345678ffffffffll, (int16x2_t) {0x0001, 0x1234}, --+ (int16x2_t) {0x0001, 0x6789}); --+ --+ if (a != a_p) --+ abort (); --+ else if (va != va_p) --+ abort (); --+ else --+ exit (0); --+} --+#else --+int main(){return 0;} --+#endif --diff --git a/gcc/testsuite/gcc.target/nds32/builtin-dsp-smar64.c b/gcc/testsuite/gcc.target/nds32/builtin-dsp-smar64.c --new file mode 100644 --index 0000000..59c6f1f ----- /dev/null --+++ b/gcc/testsuite/gcc.target/nds32/builtin-dsp-smar64.c --@@ -0,0 +1,27 @@ --+/* This is a test program for smar64 instruction. */ --+ --+/* { dg-do run } */ --+ --+#include --+#include --+ --+#ifdef __NDS32_EXT_DSP__ --+static __attribute__ ((noinline)) --+long long smar64 (long long t, int a, int b) --+{ --+ return __nds32__smar64 (t, a, b); --+} --+ --+int --+main () --+{ --+ long long a = smar64 (0xf000000000000000ll, 0x12345678, 0x23); --+ --+ if (a != 0xf00000027d27d268ll) --+ abort (); --+ else --+ exit (0); --+} --+#else --+int main(){return 0;} --+#endif --diff --git a/gcc/testsuite/gcc.target/nds32/builtin-dsp-smax16.c b/gcc/testsuite/gcc.target/nds32/builtin-dsp-smax16.c --new file mode 100644 --index 0000000..72bf957 ----- /dev/null --+++ b/gcc/testsuite/gcc.target/nds32/builtin-dsp-smax16.c --@@ -0,0 +1,37 @@ --+/* This is a test program for smax16 instruction. */ --+ --+/* { dg-do run } */ --+ --+#include --+#include --+ --+#ifdef __NDS32_EXT_DSP__ --+static __attribute__ ((noinline)) --+unsigned int smax16 (unsigned int ra, unsigned int rb) --+{ --+ return __nds32__smax16 (ra, rb); --+} --+ --+static __attribute__ ((noinline)) --+int16x2_t v_smax16 (int16x2_t ra, int16x2_t rb) --+{ --+ return __nds32__v_smax16 (ra, rb); --+} --+ --+int --+main () --+{ --+ unsigned int a = smax16 (0xfffe0001, 0xffff0000); --+ int16x2_t va = v_smax16 ((int16x2_t) {0x7fff, 0}, --+ (int16x2_t) {0x7ffe, 1}); --+ if (a != 0xffff0001) --+ abort (); --+ else if (va[0] != 0x7fff --+ || va[1] != 1) --+ abort (); --+ else --+ exit (0); --+} --+#else --+int main(){return 0;} --+#endif --diff --git a/gcc/testsuite/gcc.target/nds32/builtin-dsp-smax8.c b/gcc/testsuite/gcc.target/nds32/builtin-dsp-smax8.c --new file mode 100644 --index 0000000..128bf19 ----- /dev/null --+++ b/gcc/testsuite/gcc.target/nds32/builtin-dsp-smax8.c --@@ -0,0 +1,41 @@ --+/* This is a test program for smax8 instruction. */ --+ --+/* { dg-do run } */ --+ --+#include --+#include --+ --+#ifdef __NDS32_EXT_DSP__ --+static __attribute__ ((noinline)) --+unsigned int smax8 (unsigned int ra, unsigned int rb) --+{ --+ return __nds32__smax8 (ra, rb); --+} --+ --+static __attribute__ ((noinline)) --+int8x4_t v_smax8 (int8x4_t ra, int8x4_t rb) --+{ --+ return __nds32__v_smax8 (ra, rb); --+} --+ --+ --+int --+main () --+{ --+ unsigned int a = smax8 (0xffff0000, 0xfefe0001); --+ int8x4_t va = v_smax8 ((int8x4_t) {0x7f, 0x7f, 0x01, 0x01}, --+ (int8x4_t) {0x7e, 0x7e, 0x00, 0x00}); --+ --+ if (a != 0xffff0001) --+ abort (); --+ else if (va[0] != 0x7f --+ || va[1] != 0x7f --+ || va[2] != 1 --+ || va[3] != 1) --+ abort (); --+ else --+ exit (0); --+} --+#else --+int main(){return 0;} --+#endif --diff --git a/gcc/testsuite/gcc.target/nds32/builtin-dsp-smbb.c b/gcc/testsuite/gcc.target/nds32/builtin-dsp-smbb.c --new file mode 100644 --index 0000000..25759bd ----- /dev/null --+++ b/gcc/testsuite/gcc.target/nds32/builtin-dsp-smbb.c --@@ -0,0 +1,44 @@ --+/* This is a test program for smbb instruction. */ --+ --+/* { dg-do run } */ --+ --+#include --+#include --+ --+#ifdef __NDS32_EXT_DSP__ --+static __attribute__ ((noinline)) --+int smbb (unsigned int ra, unsigned int rb) --+{ --+ return __nds32__smbb (ra, rb); --+} --+ --+static __attribute__ ((noinline)) --+int v_smbb (int16x2_t ra, int16x2_t rb) --+{ --+ return __nds32__v_smbb (ra, rb); --+} --+ --+int --+main () --+{ --+#ifdef __NDS32_EL__ --+ int va_p = 1; --+#else --+ int va_p = 2; --+#endif --+ --+ int a = smbb (0x80000002, 0x80000001); --+ --+ int va = v_smbb ((int16x2_t) {0xffff, 0x0002}, --+ (int16x2_t) {0xffff, 0x0001}); --+ --+ if (a != 2) --+ abort (); --+ else if (va != va_p) --+ abort (); --+ else --+ exit (0); --+} --+#else --+int main(){return 0;} --+#endif --diff --git a/gcc/testsuite/gcc.target/nds32/builtin-dsp-smbt.c b/gcc/testsuite/gcc.target/nds32/builtin-dsp-smbt.c --new file mode 100644 --index 0000000..7ed2c22 ----- /dev/null --+++ b/gcc/testsuite/gcc.target/nds32/builtin-dsp-smbt.c --@@ -0,0 +1,44 @@ --+/* This is a test program for smbt instruction. */ --+ --+/* { dg-do run } */ --+ --+#include --+#include --+ --+#ifdef __NDS32_EXT_DSP__ --+static __attribute__ ((noinline)) --+int smbt (unsigned int ra, unsigned int rb) --+{ --+ return __nds32__smbt (ra, rb); --+} --+ --+static __attribute__ ((noinline)) --+int v_smbt (int16x2_t ra, int16x2_t rb) --+{ --+ return __nds32__v_smbt (ra, rb); --+} --+ --+int --+main () --+{ --+#ifdef __NDS32_EL__ --+ int va_p = 0xffffffff; --+#else --+ int va_p = 0xfffffffe; --+#endif --+ --+ int a = smbt (0x80000002, 0x80000001); --+ --+ int va = v_smbt ((int16x2_t) {0xffff, 0x0002}, --+ (int16x2_t) {0xffff, 0x0001}); --+ --+ if (a != 0xffff0000) --+ abort (); --+ else if (va != va_p) --+ abort (); --+ else --+ exit (0); --+} --+#else --+int main(){return 0;} --+#endif --diff --git a/gcc/testsuite/gcc.target/nds32/builtin-dsp-smdrs.c b/gcc/testsuite/gcc.target/nds32/builtin-dsp-smdrs.c --new file mode 100644 --index 0000000..4224b04 ----- /dev/null --+++ b/gcc/testsuite/gcc.target/nds32/builtin-dsp-smdrs.c --@@ -0,0 +1,43 @@ --+/* This is a test program for smdrs instruction. */ --+ --+/* { dg-do run } */ --+ --+#include --+#include --+ --+#ifdef __NDS32_EXT_DSP__ --+static __attribute__ ((noinline)) --+int smdrs (unsigned int ra, unsigned int rb) --+{ --+ return __nds32__smdrs (ra, rb); --+} --+ --+static __attribute__ ((noinline)) --+int v_smdrs (int16x2_t ra, int16x2_t rb) --+{ --+ return __nds32__v_smdrs (ra, rb); --+} --+ --+int --+main () --+{ --+#ifdef __NDS32_EL__ --+ int va_p = 0xffffffff; --+#else --+ int va_p = 1; --+#endif --+ --+ int a = smdrs (0x80000002, 0x80000001); --+ int va = v_smdrs ((int16x2_t) {0xffff, 0x0002}, --+ (int16x2_t) {0xffff, 0x0001}); --+ --+ if (a != 0xc0000002) --+ abort (); --+ else if (va != va_p) --+ abort (); --+ else --+ exit (0); --+} --+#else --+int main(){return 0;} --+#endif --diff --git a/gcc/testsuite/gcc.target/nds32/builtin-dsp-smds.c b/gcc/testsuite/gcc.target/nds32/builtin-dsp-smds.c --new file mode 100644 --index 0000000..9875efb ----- /dev/null --+++ b/gcc/testsuite/gcc.target/nds32/builtin-dsp-smds.c --@@ -0,0 +1,43 @@ --+/* This is a test program for smds instruction. */ --+ --+/* { dg-do run } */ --+ --+#include --+#include --+ --+#ifdef __NDS32_EXT_DSP__ --+static __attribute__ ((noinline)) --+int smds (unsigned int ra, unsigned int rb) --+{ --+ return __nds32__smds (ra, rb); --+} --+ --+static __attribute__ ((noinline)) --+int v_smds (int16x2_t ra, int16x2_t rb) --+{ --+ return __nds32__v_smds (ra, rb); --+} --+ --+int --+main () --+{ --+#ifdef __NDS32_EL__ --+ int va_p = 1; --+#else --+ int va_p = 0xffffffff; --+#endif --+ --+ int a = smds (0x80000002, 0x80000001); --+ int va = v_smds ((int16x2_t) {0xffff, 0x0002}, --+ (int16x2_t) {0xffff, 0x0001}); --+ --+ if (a != 0x3ffffffe) --+ abort (); --+ else if (va != va_p) --+ abort (); --+ else --+ exit (0); --+} --+#else --+int main(){return 0;} --+#endif --diff --git a/gcc/testsuite/gcc.target/nds32/builtin-dsp-smin16.c b/gcc/testsuite/gcc.target/nds32/builtin-dsp-smin16.c --new file mode 100644 --index 0000000..60deb4b ----- /dev/null --+++ b/gcc/testsuite/gcc.target/nds32/builtin-dsp-smin16.c --@@ -0,0 +1,37 @@ --+/* This is a test program for smin16 instruction. */ --+ --+/* { dg-do run } */ --+ --+#include --+#include --+ --+#ifdef __NDS32_EXT_DSP__ --+static __attribute__ ((noinline)) --+unsigned int smin16 (unsigned int ra, unsigned int rb) --+{ --+ return __nds32__smin16 (ra, rb); --+} --+ --+static __attribute__ ((noinline)) --+int16x2_t v_smin16 (int16x2_t ra, int16x2_t rb) --+{ --+ return __nds32__v_smin16 (ra, rb); --+} --+ --+int --+main () --+{ --+ unsigned int a = smin16 (0xfffe0001, 0xffff0000); --+ int16x2_t v_sa = v_smin16 ((int16x2_t) {0x7fff, 0}, --+ (int16x2_t) {0x7ffe, 1}); --+ if (a != 0xfffe0000) --+ abort (); --+ else if (v_sa[0] != 0x7ffe --+ || v_sa[1] != 0) --+ abort (); --+ else --+ exit (0); --+} --+#else --+int main(){return 0;} --+#endif --diff --git a/gcc/testsuite/gcc.target/nds32/builtin-dsp-smmul.c b/gcc/testsuite/gcc.target/nds32/builtin-dsp-smmul.c --new file mode 100644 --index 0000000..5735efa ----- /dev/null --+++ b/gcc/testsuite/gcc.target/nds32/builtin-dsp-smmul.c --@@ -0,0 +1,27 @@ --+/* This is a test program for smmul instruction. */ --+ --+/* { dg-do run } */ --+ --+#include --+#include --+ --+#ifdef __NDS32_EXT_DSP__ --+static __attribute__ ((noinline)) --+int smmul (int ra, int rb) --+{ --+ return __nds32__smmul (ra, rb); --+} --+ --+int --+main () --+{ --+ int a = smmul (0x80000000, 0x80000000); --+ --+ if (a != 0x40000000) --+ abort (); --+ else --+ exit (0); --+} --+#else --+int main(){return 0;} --+#endif --diff --git a/gcc/testsuite/gcc.target/nds32/builtin-dsp-smmulu.c b/gcc/testsuite/gcc.target/nds32/builtin-dsp-smmulu.c --new file mode 100644 --index 0000000..fbe0b15 ----- /dev/null --+++ b/gcc/testsuite/gcc.target/nds32/builtin-dsp-smmulu.c --@@ -0,0 +1,27 @@ --+/* This is a test program for smmul.u instruction. */ --+ --+/* { dg-do run } */ --+ --+#include --+#include --+ --+#ifdef __NDS32_EXT_DSP__ --+static __attribute__ ((noinline)) --+int smmul_u (int ra, int rb) --+{ --+ return __nds32__smmul_u (ra, rb); --+} --+ --+int --+main () --+{ --+ int a = smmul_u (0x80000002, 0x80000001); --+ --+ if (a != 0x3fffffff) --+ abort (); --+ else --+ exit (0); --+} --+#else --+int main(){return 0;} --+#endif --diff --git a/gcc/testsuite/gcc.target/nds32/builtin-dsp-smmwb.c b/gcc/testsuite/gcc.target/nds32/builtin-dsp-smmwb.c --new file mode 100644 --index 0000000..9160b9a ----- /dev/null --+++ b/gcc/testsuite/gcc.target/nds32/builtin-dsp-smmwb.c --@@ -0,0 +1,43 @@ --+/* This is a test program for smmwb instruction. */ --+ --+/* { dg-do run } */ --+ --+#include --+#include --+ --+#ifdef __NDS32_EXT_DSP__ --+static __attribute__ ((noinline)) --+int smmwb (int ra, unsigned int rb) --+{ --+ return __nds32__smmwb (ra, rb); --+} --+ --+static __attribute__ ((noinline)) --+int v_smmwb (int ra, int16x2_t rb) --+{ --+ return __nds32__v_smmwb (ra, rb); --+} --+ --+int --+main () --+{ --+#ifdef __NDS32_EL__ --+ int va_p = 0; --+#else --+ int va_p = 0xffffffff; --+#endif --+ --+ int a = smmwb (0x80000002, 0x80000001); --+ --+ int va = v_smmwb (0xffff0002, (int16x2_t) {0xffff, 0x0001}); --+ --+ if (a != 0xffff8000) --+ abort (); --+ else if (va != va_p) --+ abort (); --+ else --+ exit (0); --+} --+#else --+int main(){return 0;} --+#endif --diff --git a/gcc/testsuite/gcc.target/nds32/builtin-dsp-smmwbu.c b/gcc/testsuite/gcc.target/nds32/builtin-dsp-smmwbu.c --new file mode 100644 --index 0000000..46ebed2 ----- /dev/null --+++ b/gcc/testsuite/gcc.target/nds32/builtin-dsp-smmwbu.c --@@ -0,0 +1,43 @@ --+/* This is a test program for smmwb.u instruction. */ --+ --+/* { dg-do run } */ --+ --+#include --+#include --+ --+#ifdef __NDS32_EXT_DSP__ --+static __attribute__ ((noinline)) --+int smmwb_u (int ra, unsigned int rb) --+{ --+ return __nds32__smmwb_u (ra, rb); --+} --+ --+static __attribute__ ((noinline)) --+int v_smmwb_u (int ra, int16x2_t rb) --+{ --+ return __nds32__v_smmwb_u (ra, rb); --+} --+ --+int --+main () --+{ --+#ifdef __NDS32_EL__ --+ int va_p = 1; --+#else --+ int va_p = 0xffffffff; --+#endif --+ --+ int a = smmwb_u (0x80000002, 0x80000001); --+ --+ int va = v_smmwb_u (0xffff0002, (int16x2_t) {0xffff, 0x0001}); --+ --+ if (a != 0xffff8000) --+ abort (); --+ else if (va != va_p) --+ abort (); --+ else --+ exit (0); --+} --+#else --+int main(){return 0;} --+#endif --diff --git a/gcc/testsuite/gcc.target/nds32/builtin-dsp-smmwt.c b/gcc/testsuite/gcc.target/nds32/builtin-dsp-smmwt.c --new file mode 100644 --index 0000000..45d4792 ----- /dev/null --+++ b/gcc/testsuite/gcc.target/nds32/builtin-dsp-smmwt.c --@@ -0,0 +1,43 @@ --+/* This is a test program for smmwt instruction. */ --+ --+/* { dg-do run } */ --+ --+#include --+#include --+ --+#ifdef __NDS32_EXT_DSP__ --+static __attribute__ ((noinline)) --+int smmwt (int ra, unsigned int rb) --+{ --+ return __nds32__smmwt (ra, rb); --+} --+ --+static __attribute__ ((noinline)) --+int v_smmwt (int ra, int16x2_t rb) --+{ --+ return __nds32__v_smmwt (ra, rb); --+} --+ --+int --+main () --+{ --+#ifdef __NDS32_EL__ --+ int va_p = 0xffffffff; --+#else --+ int va_p = 0; --+#endif --+ --+ int a = smmwt (0x80000002, 0x80000001); --+ --+ int va = v_smmwt (0xffff0002, (int16x2_t) {0xffff, 0x0001}); --+ --+ if (a != 0x3fffffff) --+ abort (); --+ else if (va != va_p) --+ abort (); --+ else --+ exit (0); --+} --+#else --+int main(){return 0;} --+#endif --diff --git a/gcc/testsuite/gcc.target/nds32/builtin-dsp-smmwtu.c b/gcc/testsuite/gcc.target/nds32/builtin-dsp-smmwtu.c --new file mode 100644 --index 0000000..3b4b487 ----- /dev/null --+++ b/gcc/testsuite/gcc.target/nds32/builtin-dsp-smmwtu.c --@@ -0,0 +1,43 @@ --+/* This is a test program for smmwt.u instruction. */ --+ --+/* { dg-do run } */ --+ --+#include --+#include --+ --+#ifdef __NDS32_EXT_DSP__ --+static __attribute__ ((noinline)) --+int smmwt_u (int ra, unsigned int rb) --+{ --+ return __nds32__smmwt_u (ra, rb); --+} --+ --+static __attribute__ ((noinline)) --+int v_smmwt_u (int ra, int16x2_t rb) --+{ --+ return __nds32__v_smmwt_u (ra, rb); --+} --+ --+int --+main () --+{ --+#ifdef __NDS32_EL__ --+ int va_p = 0xffffffff; --+#else --+ int va_p = 1; --+#endif --+ --+ int a = smmwt_u (0x80000002, 0x80000001); --+ --+ int va = v_smmwt_u (0xffff0002, (int16x2_t) {0xffff, 0x0001}); --+ --+ if (a != 0x3fffffff) --+ abort (); --+ else if (va != va_p) --+ abort (); --+ else --+ exit (0); --+} --+#else --+int main(){return 0;} --+#endif --diff --git a/gcc/testsuite/gcc.target/nds32/builtin-dsp-smslda.c b/gcc/testsuite/gcc.target/nds32/builtin-dsp-smslda.c --new file mode 100644 --index 0000000..be2ac27 ----- /dev/null --+++ b/gcc/testsuite/gcc.target/nds32/builtin-dsp-smslda.c --@@ -0,0 +1,37 @@ --+/* This is a test program for smslda instruction. */ --+ --+/* { dg-do run } */ --+ --+#include --+#include --+ --+#ifdef __NDS32_EXT_DSP__ --+static __attribute__ ((noinline)) --+long long smslda (long long rt, unsigned int ra, unsigned int rb) --+{ --+ return __nds32__smslda (rt, ra, rb); --+} --+ --+static __attribute__ ((noinline)) --+long long v_smslda (long long rt, int16x2_t ra, int16x2_t rb) --+{ --+ return __nds32__v_smslda (rt, ra, rb); --+} --+ --+int --+main () --+{ --+ long long a = smslda (0xff0000000000ll, 0xffffffff, 0x2); --+ long long va = v_smslda (0x100000000ll, --+ (int16x2_t) {0xf000, 0}, (int16x2_t) {0, 3}); --+ --+ if (a != 0xff0000000002ll) --+ abort (); --+ else if (va != 0x100000000ll) --+ abort (); --+ else --+ exit (0); --+} --+#else --+int main(){return 0;} --+#endif --diff --git a/gcc/testsuite/gcc.target/nds32/builtin-dsp-smslxda.c b/gcc/testsuite/gcc.target/nds32/builtin-dsp-smslxda.c --new file mode 100644 --index 0000000..f276a2e ----- /dev/null --+++ b/gcc/testsuite/gcc.target/nds32/builtin-dsp-smslxda.c --@@ -0,0 +1,37 @@ --+/* This is a test program for smslxda instruction. */ --+ --+/* { dg-do run } */ --+ --+#include --+#include --+ --+#ifdef __NDS32_EXT_DSP__ --+static __attribute__ ((noinline)) --+long long smslxda (long long rt, unsigned int ra, unsigned int rb) --+{ --+ return __nds32__smslxda (rt, ra, rb); --+} --+ --+static __attribute__ ((noinline)) --+long long v_smslxda (long long rt, int16x2_t ra, int16x2_t rb) --+{ --+ return __nds32__v_smslxda (rt, ra, rb); --+} --+ --+int --+main () --+{ --+ long long a = smslxda (0xff0000000000ll, 0xffffffff, 0x2); --+ long long va = v_smslxda (0x100000000ll, --+ (int16x2_t) {0xf000, 0}, (int16x2_t) {0, 3}); --+ --+ if (a != 0xff0000000002ll) --+ abort (); --+ else if (va != 0x100003000ll) --+ abort (); --+ else --+ exit (0); --+} --+#else --+int main(){return 0;} --+#endif --diff --git a/gcc/testsuite/gcc.target/nds32/builtin-dsp-smsr64.c b/gcc/testsuite/gcc.target/nds32/builtin-dsp-smsr64.c --new file mode 100644 --index 0000000..64a84e9 ----- /dev/null --+++ b/gcc/testsuite/gcc.target/nds32/builtin-dsp-smsr64.c --@@ -0,0 +1,27 @@ --+/* This is a test program for smsr64 instruction. */ --+ --+/* { dg-do run } */ --+ --+#include --+#include --+ --+#ifdef __NDS32_EXT_DSP__ --+static __attribute__ ((noinline)) --+long long smsr64 (long long t, int a, int b) --+{ --+ return __nds32__smsr64 (t, a, b); --+} --+ --+int --+main () --+{ --+ long long a = smsr64 (0x5000000300000000ll, 0x12345678, 0x23); --+ --+ if (a != 0x5000000082D82D98ll) --+ abort (); --+ else --+ exit (0); --+} --+#else --+int main(){return 0;} --+#endif --diff --git a/gcc/testsuite/gcc.target/nds32/builtin-dsp-smtt.c b/gcc/testsuite/gcc.target/nds32/builtin-dsp-smtt.c --new file mode 100644 --index 0000000..bfb30f2 ----- /dev/null --+++ b/gcc/testsuite/gcc.target/nds32/builtin-dsp-smtt.c --@@ -0,0 +1,44 @@ --+/* This is a test program for smtt instruction. */ --+ --+/* { dg-do run } */ --+ --+#include --+#include --+ --+#ifdef __NDS32_EXT_DSP__ --+static __attribute__ ((noinline)) --+int smtt (unsigned int ra, unsigned int rb) --+{ --+ return __nds32__smtt (ra, rb); --+} --+ --+static __attribute__ ((noinline)) --+int v_smtt (int16x2_t ra, int16x2_t rb) --+{ --+ return __nds32__v_smtt (ra, rb); --+} --+ --+int --+main () --+{ --+#ifdef __NDS32_EL__ --+ int va_p = 2; --+#else --+ int va_p = 1; --+#endif --+ --+ int a = smtt (0x80000002, 0x80000001); --+ --+ int va = v_smtt ((int16x2_t) {0xffff, 0x0002}, --+ (int16x2_t) {0xffff, 0x0001}); --+ --+ if (a != 0x40000000) --+ abort (); --+ else if (va != va_p) --+ abort (); --+ else --+ exit (0); --+} --+#else --+int main(){return 0;} --+#endif --diff --git a/gcc/testsuite/gcc.target/nds32/builtin-dsp-smul16.c b/gcc/testsuite/gcc.target/nds32/builtin-dsp-smul16.c --new file mode 100644 --index 0000000..bb3fad4 ----- /dev/null --+++ b/gcc/testsuite/gcc.target/nds32/builtin-dsp-smul16.c --@@ -0,0 +1,38 @@ --+/* This is a test program for smul16 instruction. */ --+ --+/* { dg-do run } */ --+ --+#include --+#include --+ --+#ifdef __NDS32_EXT_DSP__ --+static __attribute__ ((noinline)) --+unsigned long long smul16 (unsigned int ra, unsigned int rb) --+{ --+ return __nds32__smul16 (ra, rb); --+} --+ --+static __attribute__ ((noinline)) --+int32x2_t v_smul16 (int16x2_t ra, int16x2_t rb) --+{ --+ return __nds32__v_smul16 (ra, rb); --+} --+ --+int --+main () --+{ --+ unsigned long long a = smul16 (0xffff0000, 0x0001ffff); --+ int32x2_t va = v_smul16 ((int16x2_t) {0xffff, 0}, --+ (int16x2_t) {0x0001, 0xffff}); --+ --+ if (a != 0xffffffff00000000) --+ abort (); --+ else if (va[0] != 0xffffffff --+ || va[1] != 0) --+ abort (); --+ else --+ exit (0); --+} --+#else --+int main(){return 0;} --+#endif --diff --git a/gcc/testsuite/gcc.target/nds32/builtin-dsp-smulx16.c b/gcc/testsuite/gcc.target/nds32/builtin-dsp-smulx16.c --new file mode 100644 --index 0000000..0e65a2a ----- /dev/null --+++ b/gcc/testsuite/gcc.target/nds32/builtin-dsp-smulx16.c --@@ -0,0 +1,37 @@ --+/* This is a test program for smulx16 instruction. */ --+ --+/* { dg-do run } */ --+ --+#include --+#include --+ --+#ifdef __NDS32_EXT_DSP__ --+static __attribute__ ((noinline)) --+unsigned long long smulx16 (unsigned int ra, unsigned int rb) --+{ --+ return __nds32__smulx16 (ra, rb); --+} --+ --+static __attribute__ ((noinline)) --+int32x2_t v_smulx16 (int16x2_t ra, int16x2_t rb) --+{ --+ return __nds32__v_smulx16 (ra, rb); --+} --+ --+int --+main () --+{ --+ unsigned long long a = smulx16 (0xffff0000, 0xffff0001); --+ int32x2_t va = v_smulx16 ((int16x2_t) {0xffff, 0xffff}, --+ (int16x2_t) {1, 0}); --+ if (a != 0xffffffff00000000) --+ abort (); --+ else if (va[0] != 0 --+ || va[1] != 0xffffffff) --+ abort (); --+ else --+ exit (0); --+} --+#else --+int main(){return 0;} --+#endif --diff --git a/gcc/testsuite/gcc.target/nds32/builtin-dsp-smxds.c b/gcc/testsuite/gcc.target/nds32/builtin-dsp-smxds.c --new file mode 100644 --index 0000000..e429aa3 ----- /dev/null --+++ b/gcc/testsuite/gcc.target/nds32/builtin-dsp-smxds.c --@@ -0,0 +1,45 @@ --+/* This is a test program for smxds instruction. */ --+ --+/* { dg-do run } */ --+ --+#include --+#include --+ --+#ifdef __NDS32_EXT_DSP__ --+static __attribute__ ((noinline)) --+int smxds (unsigned int ra, unsigned int rb) --+{ --+ return __nds32__smxds (ra, rb); --+} --+ --+static __attribute__ ((noinline)) --+int v_smxds (int16x2_t ra, int16x2_t rb) --+{ --+ return __nds32__v_smxds (ra, rb); --+} --+ --+int --+main () --+{ --+#ifdef __NDS32_EL__ --+ int a_p = 0x8000; --+ int va_p = 0xffffffff; --+#else --+ int a_p = 0x8000; --+ int va_p = 1; --+#endif --+ --+ int a = smxds (0x80000002, 0x80000001); --+ int va = v_smxds ((int16x2_t) {0xffff, 0x0002}, --+ (int16x2_t) {0xffff, 0x0001}); --+ --+ if (a != a_p) --+ abort (); --+ else if (va != va_p) --+ abort (); --+ else --+ exit (0); --+} --+#else --+int main(){return 0;} --+#endif --diff --git a/gcc/testsuite/gcc.target/nds32/builtin-dsp-sra16.c b/gcc/testsuite/gcc.target/nds32/builtin-dsp-sra16.c --new file mode 100644 --index 0000000..7d85032 ----- /dev/null --+++ b/gcc/testsuite/gcc.target/nds32/builtin-dsp-sra16.c --@@ -0,0 +1,37 @@ --+/* This is a test program for sra16 instruction. */ --+ --+/* { dg-do run } */ --+ --+#include --+#include --+ --+#ifdef __NDS32_EXT_DSP__ --+static __attribute__ ((noinline)) --+unsigned int sra16 (unsigned int ra, unsigned int rb) --+{ --+ return __nds32__sra16 (ra, rb); --+} --+ --+static __attribute__ ((noinline)) --+int16x2_t v_sra16 (int16x2_t ra, unsigned int rb) --+{ --+ return __nds32__v_sra16 (ra, rb); --+} --+ --+int --+main () --+{ --+ unsigned int a = sra16 (0x0ffff000, 4); --+ int16x2_t va = v_sra16 ((int16x2_t) {0x7fff, 0x8000}, 4); --+ --+ if (a != 0x00ffff00) --+ abort (); --+ else if (va[0] != 0x7ff --+ || va[1] != (short) 0xf800) --+ abort (); --+ else --+ exit (0); --+} --+#else --+int main(){return 0;} --+#endif --diff --git a/gcc/testsuite/gcc.target/nds32/builtin-dsp-sra16u.c b/gcc/testsuite/gcc.target/nds32/builtin-dsp-sra16u.c --new file mode 100644 --index 0000000..5bc127c ----- /dev/null --+++ b/gcc/testsuite/gcc.target/nds32/builtin-dsp-sra16u.c --@@ -0,0 +1,37 @@ --+/* This is a test program for sra16.u instruction. */ --+ --+/* { dg-do run } */ --+ --+#include --+#include --+ --+#ifdef __NDS32_EXT_DSP__ --+static __attribute__ ((noinline)) --+unsigned int sra16u (unsigned int ra, unsigned int rb) --+{ --+ return __nds32__sra16_u (ra, rb); --+} --+ --+static __attribute__ ((noinline)) --+int16x2_t v_sra16u (int16x2_t ra, unsigned int rb) --+{ --+ return __nds32__v_sra16_u (ra, rb); --+} --+ --+int --+main () --+{ --+ unsigned int a = sra16u (0x0ffff000, 4); --+ int16x2_t va = v_sra16u ((int16x2_t) {0x7fff, 0x8000}, 4); --+ --+ if (a != 0x100ff00) --+ abort (); --+ else if (va[0] != 0x800 --+ || va[1] != (short) 0xf800) --+ abort (); --+ else --+ exit (0); --+} --+#else --+int main(){return 0;} --+#endif --diff --git a/gcc/testsuite/gcc.target/nds32/builtin-dsp-srai16.c b/gcc/testsuite/gcc.target/nds32/builtin-dsp-srai16.c --new file mode 100644 --index 0000000..f3c6e16 ----- /dev/null --+++ b/gcc/testsuite/gcc.target/nds32/builtin-dsp-srai16.c --@@ -0,0 +1,39 @@ --+/* This is a test program for srai16 instruction. */ --+ --+/* { dg-do run } */ --+ --+#include --+#include --+ --+#ifdef __NDS32_EXT_DSP__ --+static __attribute__ ((noinline)) --+unsigned int srai16 (unsigned int ra) --+{ --+ return __nds32__sra16 (ra, 4); --+} --+ --+static __attribute__ ((noinline)) --+int16x2_t v_srai16 (int16x2_t ra) --+{ --+ return __nds32__v_sra16 (ra, 4); --+} --+ --+int --+main () --+{ --+ unsigned int a = srai16 (0x0ffff000); --+ --+ int16x2_t aa; --+ int16x2_t va = v_srai16 ((int16x2_t) {0x7fff, 0x8000}); --+ --+ if (a != 0x00ffff00) --+ abort (); --+ else if (va[0] != 0x7ff --+ || va[1] != (short) 0xf800) --+ abort (); --+ else --+ exit (0); --+} --+#else --+int main(){return 0;} --+#endif --diff --git a/gcc/testsuite/gcc.target/nds32/builtin-dsp-srai16u.c b/gcc/testsuite/gcc.target/nds32/builtin-dsp-srai16u.c --new file mode 100644 --index 0000000..380bd2e ----- /dev/null --+++ b/gcc/testsuite/gcc.target/nds32/builtin-dsp-srai16u.c --@@ -0,0 +1,37 @@ --+/* This is a test program for srai16.u instruction. */ --+ --+/* { dg-do run } */ --+ --+#include --+#include --+ --+#ifdef __NDS32_EXT_DSP__ --+static __attribute__ ((noinline)) --+unsigned int srai16u (unsigned int ra) --+{ --+ return __nds32__sra16_u (ra, 4); --+} --+ --+static __attribute__ ((noinline)) --+int16x2_t v_srai16u (int16x2_t ra) --+{ --+ return __nds32__v_sra16_u (ra, 4); --+} --+ --+int --+main () --+{ --+ unsigned int a = srai16u (0x0ffff000); --+ int16x2_t va = v_srai16u ((int16x2_t) {0x7fff, 0x8000}); --+ --+ if (a != 0x100ff00) --+ abort (); --+ else if (va[0] != 0x800 --+ || va[1] != (short) 0xf800) --+ abort (); --+ else --+ exit (0); --+} --+#else --+int main(){return 0;} --+#endif --diff --git a/gcc/testsuite/gcc.target/nds32/builtin-dsp-sraiu.c b/gcc/testsuite/gcc.target/nds32/builtin-dsp-sraiu.c --new file mode 100644 --index 0000000..4090762 ----- /dev/null --+++ b/gcc/testsuite/gcc.target/nds32/builtin-dsp-sraiu.c --@@ -0,0 +1,27 @@ --+/* This is a test program for srai.u instruction. */ --+ --+/* { dg-do run } */ --+ --+#include --+#include --+ --+#ifdef __NDS32_EXT_DSP__ --+static __attribute__ ((noinline)) --+int sraiu (int ra) --+{ --+ return __nds32__sra_u (ra, 8); --+} --+ --+int --+main () --+{ --+ int a = sraiu (0xf00ff); --+ --+ if (a != 0xf01) --+ abort (); --+ else --+ exit (0); --+} --+#else --+int main(){return 0;} --+#endif --diff --git a/gcc/testsuite/gcc.target/nds32/builtin-dsp-srau.c b/gcc/testsuite/gcc.target/nds32/builtin-dsp-srau.c --new file mode 100644 --index 0000000..e3a3137 ----- /dev/null --+++ b/gcc/testsuite/gcc.target/nds32/builtin-dsp-srau.c --@@ -0,0 +1,27 @@ --+/* This is a test program for sra.u instruction. */ --+ --+/* { dg-do run } */ --+ --+#include --+#include --+ --+#ifdef __NDS32_EXT_DSP__ --+static __attribute__ ((noinline)) --+int srau (int ra, unsigned int rb) --+{ --+ return __nds32__sra_u (ra, rb); --+} --+ --+int --+main () --+{ --+ int a = srau (0xf00ff, 8); --+ --+ if (a != 0xf01) --+ abort (); --+ else --+ exit (0); --+} --+#else --+int main(){return 0;} --+#endif --diff --git a/gcc/testsuite/gcc.target/nds32/builtin-dsp-srl16.c b/gcc/testsuite/gcc.target/nds32/builtin-dsp-srl16.c --new file mode 100644 --index 0000000..8aa9c59 ----- /dev/null --+++ b/gcc/testsuite/gcc.target/nds32/builtin-dsp-srl16.c --@@ -0,0 +1,37 @@ --+/* This is a test program for srl16 instruction. */ --+ --+/* { dg-do run } */ --+ --+#include --+#include --+ --+#ifdef __NDS32_EXT_DSP__ --+static __attribute__ ((noinline)) --+unsigned int srl16 (unsigned int ra, unsigned int rb) --+{ --+ return __nds32__srl16 (ra, rb); --+} --+ --+static __attribute__ ((noinline)) --+uint16x2_t v_srl16 (uint16x2_t ra, unsigned int rb) --+{ --+ return __nds32__v_srl16 (ra, rb); --+} --+ --+int --+main () --+{ --+ unsigned int a = srl16 (0x0f00f000, 4); --+ uint16x2_t va = v_srl16 ((uint16x2_t) {0x7fff, 0x8000}, 4); --+ --+ if (a != 0xf00f00) --+ abort (); --+ else if (va[0] != 0x7ff --+ || va[1] != 0x0800) --+ abort (); --+ else --+ exit (0); --+} --+#else --+int main(){return 0;} --+#endif --diff --git a/gcc/testsuite/gcc.target/nds32/builtin-dsp-srl16u.c b/gcc/testsuite/gcc.target/nds32/builtin-dsp-srl16u.c --new file mode 100644 --index 0000000..3f4ac5b ----- /dev/null --+++ b/gcc/testsuite/gcc.target/nds32/builtin-dsp-srl16u.c --@@ -0,0 +1,37 @@ --+/* This is a test program for srl16.u instruction. */ --+ --+/* { dg-do run } */ --+ --+#include --+#include --+ --+#ifdef __NDS32_EXT_DSP__ --+static __attribute__ ((noinline)) --+unsigned int srl16_u (unsigned int ra, unsigned int rb) --+{ --+ return __nds32__srl16_u (ra, rb); --+} --+ --+static __attribute__ ((noinline)) --+uint16x2_t v_srl16_u (uint16x2_t ra, unsigned int rb) --+{ --+ return __nds32__v_srl16_u (ra, rb); --+} --+ --+int --+main () --+{ --+ unsigned int a = srl16_u (0x0f00f000, 4); --+ uint16x2_t va = v_srl16_u ((uint16x2_t) {0x7fff, 0x8000}, 4); --+ --+ if (a != 0xf00f00) --+ abort (); --+ else if (va[0] != 0x800 --+ || va[1] != 0x800) --+ abort (); --+ else --+ exit (0); --+} --+#else --+int main(){return 0;} --+#endif --diff --git a/gcc/testsuite/gcc.target/nds32/builtin-dsp-srli16.c b/gcc/testsuite/gcc.target/nds32/builtin-dsp-srli16.c --new file mode 100644 --index 0000000..200bf8c ----- /dev/null --+++ b/gcc/testsuite/gcc.target/nds32/builtin-dsp-srli16.c --@@ -0,0 +1,37 @@ --+/* This is a test program for srli16 instruction. */ --+ --+/* { dg-do run } */ --+ --+#include --+#include --+ --+#ifdef __NDS32_EXT_DSP__ --+static __attribute__ ((noinline)) --+unsigned int srli16 (unsigned int ra) --+{ --+ return __nds32__srl16 (ra, 4); --+} --+ --+static __attribute__ ((noinline)) --+uint16x2_t v_srli16 (uint16x2_t ra) --+{ --+ return __nds32__v_srl16 (ra, 4); --+} --+ --+int --+main () --+{ --+ unsigned int a = srli16 (0x0f00f000); --+ uint16x2_t va = v_srli16 ((uint16x2_t) {0x7fff, 0x8000}); --+ --+ if (a != 0xf00f00) --+ abort (); --+ else if (va[0] != 0x7ff --+ || va[1] != 0x0800) --+ abort (); --+ else --+ exit (0); --+} --+#else --+int main(){return 0;} --+#endif --diff --git a/gcc/testsuite/gcc.target/nds32/builtin-dsp-srli16u.c b/gcc/testsuite/gcc.target/nds32/builtin-dsp-srli16u.c --new file mode 100644 --index 0000000..808319b ----- /dev/null --+++ b/gcc/testsuite/gcc.target/nds32/builtin-dsp-srli16u.c --@@ -0,0 +1,37 @@ --+/* This is a test program for sril16.u instruction. */ --+ --+/* { dg-do run } */ --+ --+#include --+#include --+ --+#ifdef __NDS32_EXT_DSP__ --+static __attribute__ ((noinline)) --+unsigned int srli16_u (unsigned int ra) --+{ --+ return __nds32__srl16_u (ra, 4); --+} --+ --+static __attribute__ ((noinline)) --+uint16x2_t v_srli16_u (uint16x2_t ra) --+{ --+ return __nds32__v_srl16_u (ra, 4); --+} --+ --+int --+main () --+{ --+ unsigned int a = srli16_u (0x0f00f000); --+ uint16x2_t va = v_srli16_u ((uint16x2_t) {0x7fff, 0x8000}); --+ --+ if (a != 0xf00f00) --+ abort (); --+ else if (va[0] != 0x800 --+ || va[1] != 0x800) --+ abort (); --+ else --+ exit (0); --+} --+#else --+int main(){return 0;} --+#endif --diff --git a/gcc/testsuite/gcc.target/nds32/builtin-dsp-sub16.c b/gcc/testsuite/gcc.target/nds32/builtin-dsp-sub16.c --new file mode 100644 --index 0000000..eff5f92 ----- /dev/null --+++ b/gcc/testsuite/gcc.target/nds32/builtin-dsp-sub16.c --@@ -0,0 +1,49 @@ --+/* This is a test program for sub16 instruction. */ --+ --+/* { dg-do run } */ --+ --+#include --+#include --+ --+#ifdef __NDS32_EXT_DSP__ --+static __attribute__ ((noinline)) --+unsigned int sub16 (unsigned int ra, unsigned int rb) --+{ --+ return __nds32__sub16 (ra, rb); --+} --+ --+static __attribute__ ((noinline)) --+uint16x2_t v_usub16 (uint16x2_t ra, uint16x2_t rb) --+{ --+ return __nds32__v_usub16 (ra, rb); --+} --+ --+static __attribute__ ((noinline)) --+int16x2_t v_ssub16 (int16x2_t ra, int16x2_t rb) --+{ --+ return __nds32__v_ssub16 (ra, rb); --+} --+ --+int --+main () --+{ --+ unsigned int a = sub16 (0x00010000, 0x00010001); --+ uint16x2_t v_ua = v_usub16 ((uint16x2_t) {0x1000, 0x0001}, --+ (uint16x2_t) {0xf000, 0x0000}); --+ int16x2_t v_sa = v_ssub16 ((int16x2_t) {0x7777, 0x2111}, --+ (int16x2_t) {0x1000, 0x2000}); --+ --+ if (a != 0x0000ffff) --+ abort (); --+ else if (v_ua[0] != 0x2000 --+ || v_ua[1] != 0x0001) --+ abort (); --+ else if (v_sa[0] != 0x6777 --+ || v_sa[1] != 0x0111) --+ abort (); --+ else --+ exit (0); --+} --+#else --+int main(){return 0;} --+#endif --diff --git a/gcc/testsuite/gcc.target/nds32/builtin-dsp-sub64.c b/gcc/testsuite/gcc.target/nds32/builtin-dsp-sub64.c --new file mode 100644 --index 0000000..efdd879 ----- /dev/null --+++ b/gcc/testsuite/gcc.target/nds32/builtin-dsp-sub64.c --@@ -0,0 +1,36 @@ --+/* This is a test program for sub64 instruction. */ --+ --+/* { dg-do run } */ --+ --+#include --+#include --+ --+#ifdef __NDS32_EXT_DSP__ --+static __attribute__ ((noinline)) --+long long ssub64 (long long ra, long long rb) --+{ --+ return __nds32__ssub64 (ra, rb); --+} --+ --+static __attribute__ ((noinline)) --+unsigned long long usub64 (unsigned long long ra, unsigned long long rb) --+{ --+ return __nds32__usub64 (ra, rb); --+} --+ --+int --+main () --+{ --+ long long sa = ssub64 (0x100000000ll, 0xffffffffll); --+ unsigned long long ua = usub64 (0xf00000000ull, 0x1111ull); --+ --+ if (sa != 1ll) --+ abort (); --+ else if (ua != 0xeffffeeefull) --+ abort (); --+ else --+ exit (0); --+} --+#else --+int main(){return 0;} --+#endif --diff --git a/gcc/testsuite/gcc.target/nds32/builtin-dsp-sub8.c b/gcc/testsuite/gcc.target/nds32/builtin-dsp-sub8.c --new file mode 100644 --index 0000000..b21f8a5 ----- /dev/null --+++ b/gcc/testsuite/gcc.target/nds32/builtin-dsp-sub8.c --@@ -0,0 +1,53 @@ --+/* This is a test program for sub8 instruction. */ --+ --+/* { dg-do run } */ --+ --+#include --+#include --+ --+#ifdef __NDS32_EXT_DSP__ --+static __attribute__ ((noinline)) --+unsigned int sub8 (unsigned int ra, unsigned int rb) --+{ --+ return __nds32__sub8 (ra, rb); --+} --+ --+static __attribute__ ((noinline)) --+uint8x4_t v_usub8 (uint8x4_t ra, uint8x4_t rb) --+{ --+ return __nds32__v_usub8 (ra, rb); --+} --+ --+static __attribute__ ((noinline)) --+int8x4_t v_ssub8 (int8x4_t ra, int8x4_t rb) --+{ --+ return __nds32__v_ssub8 (ra, rb); --+} --+ --+int --+main () --+{ --+ unsigned int a = sub8 (0x55667788, 0x11223344); --+ uint8x4_t v_ua = v_usub8 ((uint8x4_t) {0xff, 0xee, 0xee, 0xcc}, --+ (uint8x4_t) {0x1, 0xee, 0xdd, 0xdd}); --+ int8x4_t v_sa = v_ssub8 ((int8x4_t) {0x81, 0x0, 0xdd, 0xaa}, --+ (int8x4_t) {0x80, 0x1, 0xcc, 0xaa}); --+ --+ if (a != 0x44444444) --+ abort (); --+ else if (v_ua[0] != 0xfe --+ || v_ua[1] != 0 --+ || v_ua[2] != 0x11 --+ || v_ua[3] != 0xef) --+ abort (); --+ else if (v_sa[0] != 1 --+ || v_sa[1] != (char) 0xff --+ || v_sa[2] != 0x11 --+ || v_sa[3] != 0) --+ abort (); --+ else --+ exit (0); --+} --+#else --+int main(){return 0;} --+#endif --diff --git a/gcc/testsuite/gcc.target/nds32/builtin-dsp-sunpkd810.c b/gcc/testsuite/gcc.target/nds32/builtin-dsp-sunpkd810.c --new file mode 100644 --index 0000000..29fff3a ----- /dev/null --+++ b/gcc/testsuite/gcc.target/nds32/builtin-dsp-sunpkd810.c --@@ -0,0 +1,43 @@ --+/* This is a test program for sunpkd810 instruction. */ --+ --+/* { dg-do run } */ --+ --+#include --+#include --+ --+#ifdef __NDS32_EXT_DSP__ --+static __attribute__ ((noinline)) --+unsigned int sunpkd810 (unsigned int a) --+{ --+ return __nds32__sunpkd810 (a); --+} --+ --+static __attribute__ ((noinline)) --+int16x2_t v_sunpkd810 (int8x4_t a) --+{ --+ return __nds32__v_sunpkd810 (a); --+} --+ --+int --+main () --+{ --+#ifdef __NDS32_EL__ --+ int16x2_t va_p = {0xfff8, 0x56}; --+#else --+ int16x2_t va_p = {0, 0}; --+#endif --+ --+ unsigned int a = sunpkd810 (0x000056f8); --+ int16x2_t va = v_sunpkd810 ((int8x4_t) {0xf8, 0x56, 0, 0}); --+ --+ if (a != 0x0056fff8) --+ abort (); --+ else if (va[0] != va_p[0] --+ || va[1] != va_p[1]) --+ abort (); --+ else --+ exit (0); --+} --+#else --+int main(){return 0;} --+#endif --diff --git a/gcc/testsuite/gcc.target/nds32/builtin-dsp-sunpkd820.c b/gcc/testsuite/gcc.target/nds32/builtin-dsp-sunpkd820.c --new file mode 100644 --index 0000000..43f969a ----- /dev/null --+++ b/gcc/testsuite/gcc.target/nds32/builtin-dsp-sunpkd820.c --@@ -0,0 +1,43 @@ --+/* This is a test program for sunpkd820 instruction. */ --+ --+/* { dg-do run } */ --+ --+#include --+#include --+ --+#ifdef __NDS32_EXT_DSP__ --+static __attribute__ ((noinline)) --+unsigned int sunpkd820 (unsigned int a) --+{ --+ return __nds32__sunpkd820 (a); --+} --+ --+static __attribute__ ((noinline)) --+int16x2_t v_sunpkd820 (int8x4_t a) --+{ --+ return __nds32__v_sunpkd820 (a); --+} --+ --+int --+main () --+{ --+#ifdef __NDS32_EL__ --+ int16x2_t va_p = {0xfff8, 0x34}; --+#else --+ int16x2_t va_p = {0, 0}; --+#endif --+ --+ unsigned int a = sunpkd820 (0x003400f8); --+ int16x2_t va = v_sunpkd820 ((int8x4_t) {0xf8, 0, 0x34, 0}); --+ --+ if (a != 0x0034fff8) --+ abort (); --+ else if (va[0] != va_p[0] --+ || va[1] != va_p[1]) --+ abort (); --+ else --+ exit (0); --+} --+#else --+int main(){return 0;} --+#endif --diff --git a/gcc/testsuite/gcc.target/nds32/builtin-dsp-sunpkd830.c b/gcc/testsuite/gcc.target/nds32/builtin-dsp-sunpkd830.c --new file mode 100644 --index 0000000..76540b5 ----- /dev/null --+++ b/gcc/testsuite/gcc.target/nds32/builtin-dsp-sunpkd830.c --@@ -0,0 +1,37 @@ --+/* This is a test program for sunpkd830 instruction. */ --+ --+/* { dg-do run } */ --+ --+#include --+#include --+ --+#ifdef __NDS32_EXT_DSP__ --+static __attribute__ ((noinline)) --+unsigned int sunpkd830 (unsigned int a) --+{ --+ return __nds32__sunpkd830 (a); --+} --+ --+static __attribute__ ((noinline)) --+int16x2_t v_sunpkd830 (int8x4_t a) --+{ --+ return __nds32__v_sunpkd830 (a); --+} --+ --+int --+main () --+{ --+ unsigned int a = sunpkd830 (0x120000f8); --+ int16x2_t va = v_sunpkd830 ((int8x4_t) {0xf8, 0x00, 0, 0x12}); --+ --+ if (a != 0x0012fff8) --+ abort (); --+ else if (va[0] != (short) 0xfff8 --+ || va[1] != 0x0012) --+ abort (); --+ else --+ exit (0); --+} --+#else --+int main(){return 0;} --+#endif --diff --git a/gcc/testsuite/gcc.target/nds32/builtin-dsp-sunpkd831.c b/gcc/testsuite/gcc.target/nds32/builtin-dsp-sunpkd831.c --new file mode 100644 --index 0000000..05149e6 ----- /dev/null --+++ b/gcc/testsuite/gcc.target/nds32/builtin-dsp-sunpkd831.c --@@ -0,0 +1,43 @@ --+/* This is a test program for sunpkd831 instruction. */ --+ --+/* { dg-do run } */ --+ --+#include --+#include --+ --+#ifdef __NDS32_EXT_DSP__ --+static __attribute__ ((noinline)) --+unsigned int sunpkd831 (unsigned int a) --+{ --+ return __nds32__sunpkd831 (a); --+} --+ --+static __attribute__ ((noinline)) --+int16x2_t v_sunpkd831 (int8x4_t a) --+{ --+ return __nds32__v_sunpkd831 (a); --+} --+ --+int --+main () --+{ --+#ifdef __NDS32_EL__ --+ int16x2_t va_p = {0xfff8, 0x12}; --+#else --+ int16x2_t va_p = {0, 0}; --+#endif --+ --+ unsigned int a = sunpkd831 (0x1200f800); --+ int16x2_t va = v_sunpkd831 ((int8x4_t) {0, 0xf8, 0, 0x12}); --+ --+ if (a != 0x0012fff8) --+ abort (); --+ else if (va[0] != va_p[0] --+ || va[1] != va_p[1]) --+ abort (); --+ else --+ exit (0); --+} --+#else --+int main(){return 0;} --+#endif --diff --git a/gcc/testsuite/gcc.target/nds32/builtin-dsp-ucmple16.c b/gcc/testsuite/gcc.target/nds32/builtin-dsp-ucmple16.c --new file mode 100644 --index 0000000..17b5344 ----- /dev/null --+++ b/gcc/testsuite/gcc.target/nds32/builtin-dsp-ucmple16.c --@@ -0,0 +1,37 @@ --+/* This is a test program for ucmple16 instruction. */ --+ --+/* { dg-do run } */ --+ --+#include --+#include --+ --+#ifdef __NDS32_EXT_DSP__ --+static __attribute__ ((noinline)) --+unsigned int ucmple16 (unsigned int ra, unsigned int rb) --+{ --+ return __nds32__ucmple16 (ra, rb); --+} --+ --+static __attribute__ ((noinline)) --+uint16x2_t v_ucmple16 (uint16x2_t ra, uint16x2_t rb) --+{ --+ return __nds32__v_ucmple16 (ra, rb); --+} --+ --+int --+main () --+{ --+ unsigned int a = ucmple16 (0xfffe0001, 0xffff0000); --+ uint16x2_t va = v_ucmple16 ((uint16x2_t) {0x7fff, 0x7ffe}, --+ (uint16x2_t) {0x7ffe, 0x7fff}); --+ if (a != 0xffff0000) --+ abort (); --+ else if (va[0] != 0 --+ || va[1] != 0xffff) --+ abort (); --+ else --+ exit (0); --+} --+#else --+int main(){return 0;} --+#endif --diff --git a/gcc/testsuite/gcc.target/nds32/builtin-dsp-ucmple8.c b/gcc/testsuite/gcc.target/nds32/builtin-dsp-ucmple8.c --new file mode 100644 --index 0000000..561b500 ----- /dev/null --+++ b/gcc/testsuite/gcc.target/nds32/builtin-dsp-ucmple8.c --@@ -0,0 +1,40 @@ --+/* This is a test program for ucmple8 instruction. */ --+ --+/* { dg-do run } */ --+ --+#include --+#include --+ --+#ifdef __NDS32_EXT_DSP__ --+static __attribute__ ((noinline)) --+unsigned int ucmple8 (unsigned int ra, unsigned int rb) --+{ --+ return __nds32__ucmple8 (ra, rb); --+} --+ --+static __attribute__ ((noinline)) --+uint8x4_t v_ucmple8 (uint8x4_t ra, uint8x4_t rb) --+{ --+ return __nds32__v_ucmple8 (ra, rb); --+} --+ --+int --+main () --+{ --+ unsigned int a = ucmple8 (0xfefe0101, 0xffff0000); --+ uint8x4_t va = v_ucmple8 ((uint8x4_t) {0x7e, 0x7e, 0x01, 0x01}, --+ (uint8x4_t) {0x7f, 0x7f, 0x00, 0x00}); --+ --+ if (a != 0xffff0000) --+ abort (); --+ else if (va[0] != 0xff --+ || va[1] != 0xff --+ || va[2] != 0 --+ || va[3] != 0) --+ abort (); --+ else --+ exit (0); --+} --+#else --+int main(){return 0;} --+#endif --diff --git a/gcc/testsuite/gcc.target/nds32/builtin-dsp-ucmplt16.c b/gcc/testsuite/gcc.target/nds32/builtin-dsp-ucmplt16.c --new file mode 100644 --index 0000000..820ce1e ----- /dev/null --+++ b/gcc/testsuite/gcc.target/nds32/builtin-dsp-ucmplt16.c --@@ -0,0 +1,37 @@ --+/* This is a test program for ucmplt16 instruction. */ --+ --+/* { dg-do run } */ --+ --+#include --+#include --+ --+#ifdef __NDS32_EXT_DSP__ --+static __attribute__ ((noinline)) --+unsigned int ucmplt16 (unsigned int ra, unsigned int rb) --+{ --+ return __nds32__ucmplt16 (ra, rb); --+} --+ --+static __attribute__ ((noinline)) --+uint16x2_t v_ucmplt16 (uint16x2_t ra, uint16x2_t rb) --+{ --+ return __nds32__v_ucmplt16 (ra, rb); --+} --+ --+int --+main () --+{ --+ unsigned int a = ucmplt16 (0xfffe0001, 0xffff0000); --+ uint16x2_t va = v_ucmplt16 ((uint16x2_t) {0x7fff, 0x7ffe}, --+ (uint16x2_t) {0x7ffe, 0x7fff}); --+ if (a != 0xffff0000) --+ abort (); --+ else if (va[0] != 0 --+ || va[1] != 0xffff) --+ abort (); --+ else --+ exit (0); --+} --+#else --+int main(){return 0;} --+#endif --diff --git a/gcc/testsuite/gcc.target/nds32/builtin-dsp-ucmplt8.c b/gcc/testsuite/gcc.target/nds32/builtin-dsp-ucmplt8.c --new file mode 100644 --index 0000000..8001586 ----- /dev/null --+++ b/gcc/testsuite/gcc.target/nds32/builtin-dsp-ucmplt8.c --@@ -0,0 +1,40 @@ --+/* This is a test program for ucmplt8 instruction. */ --+ --+/* { dg-do run } */ --+ --+#include --+#include --+ --+#ifdef __NDS32_EXT_DSP__ --+static __attribute__ ((noinline)) --+unsigned int ucmplt8 (unsigned int ra, unsigned int rb) --+{ --+ return __nds32__ucmplt8 (ra, rb); --+} --+ --+static __attribute__ ((noinline)) --+uint8x4_t v_ucmplt8 (uint8x4_t ra, uint8x4_t rb) --+{ --+ return __nds32__v_ucmplt8 (ra, rb); --+} --+ --+int --+main () --+{ --+ unsigned int a = ucmplt8 (0xfefe0101, 0xffff0000); --+ uint8x4_t va = v_ucmplt8 ((uint8x4_t) {0x7e, 0x7e, 0x01, 0x01}, --+ (uint8x4_t) {0x7f, 0x7f, 0x00, 0x00}); --+ --+ if (a != 0xffff0000) --+ abort (); --+ else if (va[0] != 0xff --+ || va[1] != 0xff --+ || va[2] != 0 --+ || va[3] != 0) --+ abort (); --+ else --+ exit (0); --+} --+#else --+int main(){return 0;} --+#endif --diff --git a/gcc/testsuite/gcc.target/nds32/builtin-dsp-umar64.c b/gcc/testsuite/gcc.target/nds32/builtin-dsp-umar64.c --new file mode 100644 --index 0000000..ac32ae1 ----- /dev/null --+++ b/gcc/testsuite/gcc.target/nds32/builtin-dsp-umar64.c --@@ -0,0 +1,27 @@ --+/* This is a test program for umar64 instruction. */ --+ --+/* { dg-do run } */ --+ --+#include --+#include --+ --+#ifdef __NDS32_EXT_DSP__ --+static __attribute__ ((noinline)) --+unsigned long long umar64 (unsigned long long t,unsigned int a,unsigned int b) --+{ --+ return __nds32__umar64 (t, a, b); --+} --+ --+int --+main () --+{ --+ unsigned long long a = umar64 (0xf000000000000000ull, 0x12345678, 0x23); --+ --+ if (a != 0xf00000027d27d268ull) --+ abort (); --+ else --+ exit (0); --+} --+#else --+int main(){return 0;} --+#endif --diff --git a/gcc/testsuite/gcc.target/nds32/builtin-dsp-umax16.c b/gcc/testsuite/gcc.target/nds32/builtin-dsp-umax16.c --new file mode 100644 --index 0000000..99a43d2 ----- /dev/null --+++ b/gcc/testsuite/gcc.target/nds32/builtin-dsp-umax16.c --@@ -0,0 +1,37 @@ --+/* This is a test program for umax16 instruction. */ --+ --+/* { dg-do run } */ --+ --+#include --+#include --+ --+#ifdef __NDS32_EXT_DSP__ --+static __attribute__ ((noinline)) --+unsigned int umax16 (unsigned int ra, unsigned int rb) --+{ --+ return __nds32__umax16 (ra, rb); --+} --+ --+static __attribute__ ((noinline)) --+uint16x2_t v_umax16 (uint16x2_t ra, uint16x2_t rb) --+{ --+ return __nds32__v_umax16 (ra, rb); --+} --+ --+int --+main () --+{ --+ unsigned int a = umax16 (0xfffe0001, 0xffff0000); --+ uint16x2_t va = v_umax16 ((uint16x2_t) {0xffff, 0}, --+ (uint16x2_t) {0xfffe, 1}); --+ if (a != 0xffff0001) --+ abort (); --+ else if (va[0] != 0xffff --+ || va[1] != 1) --+ abort (); --+ else --+ exit (0); --+} --+#else --+int main(){return 0;} --+#endif --diff --git a/gcc/testsuite/gcc.target/nds32/builtin-dsp-umax8.c b/gcc/testsuite/gcc.target/nds32/builtin-dsp-umax8.c --new file mode 100644 --index 0000000..23904b2 ----- /dev/null --+++ b/gcc/testsuite/gcc.target/nds32/builtin-dsp-umax8.c --@@ -0,0 +1,41 @@ --+/* This is a test program for umax8 instruction. */ --+ --+/* { dg-do run } */ --+ --+#include --+#include --+ --+#ifdef __NDS32_EXT_DSP__ --+static __attribute__ ((noinline)) --+unsigned int umax8 (unsigned int ra, unsigned int rb) --+{ --+ return __nds32__umax8 (ra, rb); --+} --+ --+static __attribute__ ((noinline)) --+uint8x4_t v_umax8 (uint8x4_t ra, uint8x4_t rb) --+{ --+ return __nds32__v_umax8 (ra, rb); --+} --+ --+ --+int --+main () --+{ --+ unsigned int a = umax8 (0xffff0000, 0xfffe0001); --+ uint8x4_t va = v_umax8 ((uint8x4_t) {0xff, 0xff, 0x01, 0x01}, --+ (uint8x4_t) {0xfe, 0xfe, 0x00, 0x00}); --+ --+ if (a != 0xffff0001) --+ abort (); --+ else if (va[0] != 0xff --+ || va[1] != 0xff --+ || va[2] != 1 --+ || va[3] != 1) --+ abort (); --+ else --+ exit (0); --+} --+#else --+int main(){return 0;} --+#endif --diff --git a/gcc/testsuite/gcc.target/nds32/builtin-dsp-umin16.c b/gcc/testsuite/gcc.target/nds32/builtin-dsp-umin16.c --new file mode 100644 --index 0000000..eec7058 ----- /dev/null --+++ b/gcc/testsuite/gcc.target/nds32/builtin-dsp-umin16.c --@@ -0,0 +1,37 @@ --+/* This is a test program for umin16 instruction. */ --+ --+/* { dg-do run } */ --+ --+#include --+#include --+ --+#ifdef __NDS32_EXT_DSP__ --+static __attribute__ ((noinline)) --+unsigned int umin16 (unsigned int ra, unsigned int rb) --+{ --+ return __nds32__umin16 (ra, rb); --+} --+ --+static __attribute__ ((noinline)) --+uint16x2_t v_umin16 (uint16x2_t ra, uint16x2_t rb) --+{ --+ return __nds32__v_umin16 (ra, rb); --+} --+ --+int --+main () --+{ --+ unsigned int a = umin16 (0xfffe0001, 0xffff0000); --+ uint16x2_t va = v_umin16 ((uint16x2_t) {0x7fff, 0}, --+ (uint16x2_t) {0x7ffe, 1}); --+ if (a != 0xfffe0000) --+ abort (); --+ else if (va[0] != 0x7ffe --+ || va[1] != 0) --+ abort (); --+ else --+ exit (0); --+} --+#else --+int main(){return 0;} --+#endif --diff --git a/gcc/testsuite/gcc.target/nds32/builtin-dsp-umsr64.c b/gcc/testsuite/gcc.target/nds32/builtin-dsp-umsr64.c --new file mode 100644 --index 0000000..3fb20bf ----- /dev/null --+++ b/gcc/testsuite/gcc.target/nds32/builtin-dsp-umsr64.c --@@ -0,0 +1,27 @@ --+/* This is a test program for umsr64 instruction. */ --+ --+/* { dg-do run } */ --+ --+#include --+#include --+ --+#ifdef __NDS32_EXT_DSP__ --+static __attribute__ ((noinline)) --+unsigned long long umsr64 (unsigned long long t, unsigned int a, unsigned int b) --+{ --+ return __nds32__umsr64 (t, a, b); --+} --+ --+int --+main () --+{ --+ unsigned long long a = umsr64 (0x5000000300000000ull, 0x12345678, 0x23); --+ --+ if (a != 0x5000000082D82D98ull) --+ abort (); --+ else --+ exit (0); --+} --+#else --+int main(){return 0;} --+#endif --diff --git a/gcc/testsuite/gcc.target/nds32/builtin-dsp-umul16.c b/gcc/testsuite/gcc.target/nds32/builtin-dsp-umul16.c --new file mode 100644 --index 0000000..ddfb6be ----- /dev/null --+++ b/gcc/testsuite/gcc.target/nds32/builtin-dsp-umul16.c --@@ -0,0 +1,37 @@ --+/* This is a test program for umul16 instruction. */ --+ --+/* { dg-do run } */ --+ --+#include --+#include --+ --+#ifdef __NDS32_EXT_DSP__ --+static __attribute__ ((noinline)) --+unsigned long long umul16 (unsigned int ra, unsigned int rb) --+{ --+ return __nds32__umul16 (ra, rb); --+} --+ --+static __attribute__ ((noinline)) --+uint32x2_t v_umul16 (uint16x2_t ra, uint16x2_t rb) --+{ --+ return __nds32__v_umul16 (ra, rb); --+} --+ --+int --+main () --+{ --+ unsigned long long a = umul16 (0xffff0000, 0x0001ffff); --+ uint32x2_t va = v_umul16 ((uint16x2_t) {0xffff, 0}, --+ (uint16x2_t) {0x0001, 0xffff}); --+ if (a != 0xffff00000000) --+ abort (); --+ else if (va[0] != 0xffff --+ || va[1] != 0) --+ abort (); --+ else --+ exit (0); --+} --+#else --+int main(){return 0;} --+#endif --diff --git a/gcc/testsuite/gcc.target/nds32/builtin-dsp-umulx16.c b/gcc/testsuite/gcc.target/nds32/builtin-dsp-umulx16.c --new file mode 100644 --index 0000000..c57d304 ----- /dev/null --+++ b/gcc/testsuite/gcc.target/nds32/builtin-dsp-umulx16.c --@@ -0,0 +1,37 @@ --+/* This is a test program for umulx16 instruction. */ --+ --+/* { dg-do run } */ --+ --+#include --+#include --+ --+#ifdef __NDS32_EXT_DSP__ --+static __attribute__ ((noinline)) --+unsigned long long umulx16 (unsigned int ra, unsigned int rb) --+{ --+ return __nds32__umulx16 (ra, rb); --+} --+ --+static __attribute__ ((noinline)) --+uint32x2_t v_umulx16 (uint16x2_t ra, uint16x2_t rb) --+{ --+ return __nds32__v_umulx16 (ra, rb); --+} --+ --+int --+main () --+{ --+ unsigned long long a = umulx16 (0xffff0000, 0xffff0001); --+ uint32x2_t va = v_umulx16 ((uint16x2_t) {0xffff, 0xffff}, --+ (uint16x2_t) {1, 0}); --+ if (a != 0xffff00000000) --+ abort (); --+ else if (va[0] != 0 --+ || va[1] != 0xffff) --+ abort (); --+ else --+ exit (0); --+} --+#else --+int main(){return 0;} --+#endif --diff --git a/gcc/testsuite/gcc.target/nds32/builtin-dsp-uradd16.c b/gcc/testsuite/gcc.target/nds32/builtin-dsp-uradd16.c --new file mode 100644 --index 0000000..82c7be7 ----- /dev/null --+++ b/gcc/testsuite/gcc.target/nds32/builtin-dsp-uradd16.c --@@ -0,0 +1,38 @@ --+/* This is a test program for uradd16 instruction. */ --+ --+/* { dg-do run } */ --+ --+#include --+#include --+ --+#ifdef __NDS32_EXT_DSP__ --+static __attribute__ ((noinline)) --+unsigned int uradd16 (unsigned int ra, unsigned int rb) --+{ --+ return __nds32__uradd16 (ra, rb); --+} --+ --+static __attribute__ ((noinline)) --+uint16x2_t v_uradd16 (uint16x2_t ra, uint16x2_t rb) --+{ --+ return __nds32__v_uradd16 (ra, rb); --+} --+ --+int --+main () --+{ --+ unsigned int a = uradd16 (0x7fff7fff, 0x7fff7fff); --+ uint16x2_t va = v_uradd16 ((uint16x2_t) {0x8000, 0x4000}, --+ (uint16x2_t) {0x8000, 0x8000}); --+ --+ if (a != 0x7fff7fff) --+ abort (); --+ else if (va[0] != 0x8000 --+ || va[1] != 0x6000) --+ abort (); --+ else --+ exit (0); --+} --+#else --+int main(){return 0;} --+#endif --diff --git a/gcc/testsuite/gcc.target/nds32/builtin-dsp-uradd64.c b/gcc/testsuite/gcc.target/nds32/builtin-dsp-uradd64.c --new file mode 100644 --index 0000000..51ee961 ----- /dev/null --+++ b/gcc/testsuite/gcc.target/nds32/builtin-dsp-uradd64.c --@@ -0,0 +1,27 @@ --+/* This is a test program for uradd64 instruction. */ --+ --+/* { dg-do run } */ --+ --+#include --+#include --+ --+#ifdef __NDS32_EXT_DSP__ --+static __attribute__ ((noinline)) --+unsigned long long uradd64 (unsigned long long ra, unsigned long long rb) --+{ --+ return __nds32__uradd64 (ra, rb); --+} --+ --+int --+main () --+{ --+ unsigned long long a = uradd64 (0xf000000000000000ull, 0xf000000000000000ull); --+ --+ if (a != 0xf000000000000000ull) --+ abort (); --+ else --+ exit (0); --+} --+#else --+int main(){return 0;} --+#endif --diff --git a/gcc/testsuite/gcc.target/nds32/builtin-dsp-uradd8.c b/gcc/testsuite/gcc.target/nds32/builtin-dsp-uradd8.c --new file mode 100644 --index 0000000..d4f91d6 ----- /dev/null --+++ b/gcc/testsuite/gcc.target/nds32/builtin-dsp-uradd8.c --@@ -0,0 +1,40 @@ --+/* This is a test program for uradd8 instruction. */ --+ --+/* { dg-do run } */ --+ --+#include --+#include --+ --+#ifdef __NDS32_EXT_DSP__ --+static __attribute__ ((noinline)) --+unsigned int uradd8 (unsigned int ra, unsigned int rb) --+{ --+ return __nds32__uradd8 (ra, rb); --+} --+ --+static __attribute__ ((noinline)) --+uint8x4_t v_uradd8 (uint8x4_t ra, uint8x4_t rb) --+{ --+ return __nds32__v_uradd8 (ra, rb); --+} --+ --+int --+main () --+{ --+ unsigned int a = uradd8 (0x11223344, 0x55667788); --+ uint8x4_t va = v_uradd8 ((uint8x4_t) {0x7f, 0x80, 0x40, 0xaa}, --+ (uint8x4_t) {0x7f, 0x80, 0x80, 0xaa}); --+ --+ if (a != 0x33445566) --+ abort (); --+ else if (va[0] != 0x7f --+ || va[1] != 0x80 --+ || va[2] != 0x60 --+ || va[3] != 0xaa) --+ abort (); --+ else --+ exit (0); --+} --+#else --+int main(){return 0;} --+#endif --diff --git a/gcc/testsuite/gcc.target/nds32/builtin-dsp-uraddw.c b/gcc/testsuite/gcc.target/nds32/builtin-dsp-uraddw.c --new file mode 100644 --index 0000000..9fc76b0 ----- /dev/null --+++ b/gcc/testsuite/gcc.target/nds32/builtin-dsp-uraddw.c --@@ -0,0 +1,27 @@ --+/* This is a test program for uraddw instruction. */ --+ --+/* { dg-do run } */ --+ --+#include --+#include --+ --+#ifdef __NDS32_EXT_DSP__ --+static __attribute__ ((noinline)) --+unsigned int uraddw (unsigned int ra, unsigned int rb) --+{ --+ return __nds32__uraddw (ra, rb); --+} --+ --+unsigned int --+main () --+{ --+ unsigned int a = uraddw (0x80000000, 0x80000000); --+ --+ if (a != 0x80000000) --+ abort (); --+ else --+ exit (0); --+} --+#else --+int main(){return 0;} --+#endif --diff --git a/gcc/testsuite/gcc.target/nds32/builtin-dsp-urcras16.c b/gcc/testsuite/gcc.target/nds32/builtin-dsp-urcras16.c --new file mode 100644 --index 0000000..1330374 ----- /dev/null --+++ b/gcc/testsuite/gcc.target/nds32/builtin-dsp-urcras16.c --@@ -0,0 +1,44 @@ --+/* This is a test program for urcras16 instruction. */ --+ --+/* { dg-do run } */ --+ --+#include --+#include --+ --+#ifdef __NDS32_EXT_DSP__ --+static __attribute__ ((noinline)) --+unsigned int urcras16 (unsigned int ra, unsigned int rb) --+{ --+ return __nds32__urcras16 (ra, rb); --+} --+ --+static __attribute__ ((noinline)) --+uint16x2_t v_urcras16 (uint16x2_t ra, uint16x2_t rb) --+{ --+ return __nds32__v_urcras16 (ra, rb); --+} --+ --+int --+main () --+{ --+#ifdef __NDS32_EL__ --+ uint16x2_t va_p = {0xffff, 0x8000}; --+#else --+ uint16x2_t va_p = {0x7fff, 0}; --+#endif --+ --+ unsigned int a = urcras16 (0x7fff7fff, 0x80007fff); --+ uint16x2_t va = v_urcras16 ((uint16x2_t) {0x7fff, 0x8000}, --+ (uint16x2_t) {0x8000, 0x8000}); --+ --+ if (a != 0x7fffffff) --+ abort (); --+ else if (va[0] != va_p[0] --+ || va[1] != va_p[1]) --+ abort (); --+ else --+ exit (0); --+} --+#else --+int main(){return 0;} --+#endif --diff --git a/gcc/testsuite/gcc.target/nds32/builtin-dsp-urcrsa16.c b/gcc/testsuite/gcc.target/nds32/builtin-dsp-urcrsa16.c --new file mode 100644 --index 0000000..806fa7a ----- /dev/null --+++ b/gcc/testsuite/gcc.target/nds32/builtin-dsp-urcrsa16.c --@@ -0,0 +1,44 @@ --+/* This is a test program for urcrsa16 instruction. */ --+ --+/* { dg-do run } */ --+ --+#include --+#include --+ --+#ifdef __NDS32_EXT_DSP__ --+static __attribute__ ((noinline)) --+unsigned int urcrsa16 (unsigned int ra, unsigned int rb) --+{ --+ return __nds32__urcrsa16 (ra, rb); --+} --+ --+static __attribute__ ((noinline)) --+uint16x2_t v_urcrsa16 (uint16x2_t ra, uint16x2_t rb) --+{ --+ return __nds32__v_urcrsa16 (ra, rb); --+} --+ --+int --+main () --+{ --+#ifdef __NDS32_EL__ --+ uint16x2_t va_p = {0x8000, 0xffff}; --+#else --+ uint16x2_t va_p = {0, 0x7fff}; --+#endif --+ --+ unsigned int a = urcrsa16 (0x7fff7fff, 0x7fff8000); --+ uint16x2_t va = v_urcrsa16 ((uint16x2_t) {0x8000, 0x7fff}, --+ (uint16x2_t) {0x8000, 0x8000}); --+ --+ if (a != 0xffff7fff) --+ abort (); --+ else if (va[0] != va_p[0] --+ || va[1] != va_p[1]) --+ abort (); --+ else --+ exit (0); --+} --+#else --+int main(){return 0;} --+#endif --diff --git a/gcc/testsuite/gcc.target/nds32/builtin-dsp-ursub16.c b/gcc/testsuite/gcc.target/nds32/builtin-dsp-ursub16.c --new file mode 100644 --index 0000000..9e87234 ----- /dev/null --+++ b/gcc/testsuite/gcc.target/nds32/builtin-dsp-ursub16.c --@@ -0,0 +1,38 @@ --+/* This is a test program for ursub16 instruction. */ --+ --+/* { dg-do run } */ --+ --+#include --+#include --+ --+#ifdef __NDS32_EXT_DSP__ --+static __attribute__ ((noinline)) --+unsigned int ursub16 (unsigned int ra, unsigned int rb) --+{ --+ return __nds32__ursub16 (ra, rb); --+} --+ --+static __attribute__ ((noinline)) --+uint16x2_t v_ursub16 (uint16x2_t ra, uint16x2_t rb) --+{ --+ return __nds32__v_ursub16 (ra, rb); --+} --+ --+int --+main () --+{ --+ unsigned int a = ursub16 (0x7fff7fff, 0x80008000); --+ uint16x2_t va = v_ursub16 ((uint16x2_t) {0x8000, 0x8000}, --+ (uint16x2_t) {0x7fff, 0x4000}); --+ --+ if (a != 0xffffffff) --+ abort (); --+ else if (va[0] != 0 --+ || va[1] != 0x2000) --+ abort (); --+ else --+ exit (0); --+} --+#else --+int main(){return 0;} --+#endif --diff --git a/gcc/testsuite/gcc.target/nds32/builtin-dsp-ursub64.c b/gcc/testsuite/gcc.target/nds32/builtin-dsp-ursub64.c --new file mode 100644 --index 0000000..e1f7b15 ----- /dev/null --+++ b/gcc/testsuite/gcc.target/nds32/builtin-dsp-ursub64.c --@@ -0,0 +1,27 @@ --+/* This is a test program for ursub64 instruction. */ --+ --+/* { dg-do run } */ --+ --+#include --+#include --+ --+#ifdef __NDS32_EXT_DSP__ --+static __attribute__ ((noinline)) --+unsigned long long ursub64 (unsigned long long ra, unsigned long long rb) --+{ --+ return __nds32__ursub64 (ra, rb); --+} --+ --+int --+main () --+{ --+ unsigned long long a = ursub64 (0xeull, 0xfull); --+ --+ if (a != 0xffffffffffffffffull) --+ abort (); --+ else --+ exit (0); --+} --+#else --+int main(){return 0;} --+#endif --diff --git a/gcc/testsuite/gcc.target/nds32/builtin-dsp-ursub8.c b/gcc/testsuite/gcc.target/nds32/builtin-dsp-ursub8.c --new file mode 100644 --index 0000000..f5e3ff6 ----- /dev/null --+++ b/gcc/testsuite/gcc.target/nds32/builtin-dsp-ursub8.c --@@ -0,0 +1,40 @@ --+/* This is a test program for ursub8 instruction. */ --+ --+/* { dg-do run } */ --+ --+#include --+#include --+ --+#ifdef __NDS32_EXT_DSP__ --+static __attribute__ ((noinline)) --+unsigned int ursub8 (unsigned int ra, unsigned int rb) --+{ --+ return __nds32__ursub8 (ra, rb); --+} --+ --+static __attribute__ ((noinline)) --+uint8x4_t v_ursub8 (uint8x4_t ra, uint8x4_t rb) --+{ --+ return __nds32__v_ursub8 (ra, rb); --+} --+ --+int --+main () --+{ --+ unsigned int a = ursub8 (0x55667788, 0x11223344); --+ uint8x4_t va = v_ursub8 ((uint8x4_t) {0x7f, 0x80, 0x80, 0xaa}, --+ (uint8x4_t) {0x80, 0x7f, 0x40, 0xaa}); --+ --+ if (a != 0x22222222) --+ abort (); --+ else if (va[0] != 0xff --+ || va[1] != 0 --+ || va[2] != 0x20 --+ || va[3] != 0) --+ abort (); --+ else --+ exit (0); --+} --+#else --+int main(){return 0;} --+#endif --diff --git a/gcc/testsuite/gcc.target/nds32/builtin-dsp-ursubw.c b/gcc/testsuite/gcc.target/nds32/builtin-dsp-ursubw.c --new file mode 100644 --index 0000000..b12afb0 ----- /dev/null --+++ b/gcc/testsuite/gcc.target/nds32/builtin-dsp-ursubw.c --@@ -0,0 +1,27 @@ --+/* This is a test program for ursubw instruction. */ --+ --+/* { dg-do run } */ --+ --+#include --+#include --+ --+#ifdef __NDS32_EXT_DSP__ --+static __attribute__ ((noinline)) --+unsigned int ursubw (unsigned int ra,unsigned int rb) --+{ --+ return __nds32__ursubw (ra, rb); --+} --+ --+int --+main () --+{ --+ unsigned int a = ursubw (0x80000000, 0x40000000); --+ --+ if (a != 0x20000000) --+ abort (); --+ else --+ exit (0); --+} --+#else --+int main(){return 0;} --+#endif --diff --git a/gcc/testsuite/gcc.target/nds32/builtin-dsp-wext.c b/gcc/testsuite/gcc.target/nds32/builtin-dsp-wext.c --new file mode 100644 --index 0000000..d86fb8f ----- /dev/null --+++ b/gcc/testsuite/gcc.target/nds32/builtin-dsp-wext.c --@@ -0,0 +1,27 @@ --+/* This is a test program for wext instruction. */ --+ --+/* { dg-do run } */ --+ --+#include --+#include --+ --+#ifdef __NDS32_EXT_DSP__ --+static __attribute__ ((noinline)) --+unsigned int wext (long long ra, unsigned int rb) --+{ --+ return __nds32__wext (ra, rb); --+} --+ --+int --+main () --+{ --+ unsigned int a = wext (0x1234ffff0000ll, 16); --+ --+ if (a != 0x1234ffff) --+ abort (); --+ else --+ exit (0); --+} --+#else --+int main(){return 0;} --+#endif --diff --git a/gcc/testsuite/gcc.target/nds32/builtin-dsp-wexti.c b/gcc/testsuite/gcc.target/nds32/builtin-dsp-wexti.c --new file mode 100644 --index 0000000..8f09423 ----- /dev/null --+++ b/gcc/testsuite/gcc.target/nds32/builtin-dsp-wexti.c --@@ -0,0 +1,27 @@ --+/* This is a test program for wexti instruction. */ --+ --+/* { dg-do run } */ --+ --+#include --+#include --+ --+#ifdef __NDS32_EXT_DSP__ --+static __attribute__ ((noinline)) --+unsigned int wexti (long long ra) --+{ --+ return __nds32__wext (ra, 16); --+} --+ --+int --+main () --+{ --+ unsigned int a = wexti (0x1234ffff0000ll); --+ --+ if (a != 0x1234ffff) --+ abort (); --+ else --+ exit (0); --+} --+#else --+int main(){return 0;} --+#endif --diff --git a/gcc/testsuite/gcc.target/nds32/builtin-dsp-zunpkd810.c b/gcc/testsuite/gcc.target/nds32/builtin-dsp-zunpkd810.c --new file mode 100644 --index 0000000..7b3aebb ----- /dev/null --+++ b/gcc/testsuite/gcc.target/nds32/builtin-dsp-zunpkd810.c --@@ -0,0 +1,43 @@ --+/* This is a test program for zunpkd810 instruction. */ --+ --+/* { dg-do run } */ --+ --+#include --+#include --+ --+#ifdef __NDS32_EXT_DSP__ --+static __attribute__ ((noinline)) --+unsigned int zunpkd810 (unsigned int a) --+{ --+ return __nds32__zunpkd810 (a); --+} --+ --+static __attribute__ ((noinline)) --+uint16x2_t v_zunpkd810 (uint8x4_t a) --+{ --+ return __nds32__v_zunpkd810 (a); --+} --+ --+int --+main () --+{ --+#ifdef __NDS32_EL__ --+ int16x2_t va_p = {0xf8, 0x56}; --+#else --+ int16x2_t va_p = {0, 0}; --+#endif --+ --+ unsigned int a = zunpkd810 (0x000056f8); --+ uint16x2_t va = v_zunpkd810 ((uint8x4_t) {0xf8, 0x56, 0, 0}); --+ --+ if (a != 0x005600f8) --+ abort (); --+ else if (va[0] != va_p[0] --+ || va[1] != va_p[1]) --+ abort (); --+ else --+ exit (0); --+} --+#else --+int main(){return 0;} --+#endif --diff --git a/gcc/testsuite/gcc.target/nds32/builtin-dsp-zunpkd820.c b/gcc/testsuite/gcc.target/nds32/builtin-dsp-zunpkd820.c --new file mode 100644 --index 0000000..dc37a3d ----- /dev/null --+++ b/gcc/testsuite/gcc.target/nds32/builtin-dsp-zunpkd820.c --@@ -0,0 +1,43 @@ --+/* This is a test program for zunpkd820 instruction. */ --+ --+/* { dg-do run } */ --+ --+#include --+#include --+ --+#ifdef __NDS32_EXT_DSP__ --+static __attribute__ ((noinline)) --+unsigned int zunpkd820 (unsigned int a) --+{ --+ return __nds32__zunpkd820 (a); --+} --+ --+static __attribute__ ((noinline)) --+uint16x2_t v_zunpkd820 (uint8x4_t a) --+{ --+ return __nds32__v_zunpkd820 (a); --+} --+ --+int --+main () --+{ --+#ifdef __NDS32_EL__ --+ int16x2_t va_p = {0xf8, 0x34}; --+#else --+ int16x2_t va_p = {0, 0}; --+#endif --+ --+ unsigned int a = zunpkd820 (0x003400f8); --+ uint16x2_t va = v_zunpkd820 ((uint8x4_t) {0xf8, 0, 0x34, 0}); --+ --+ if (a != 0x003400f8) --+ abort (); --+ else if (va[0] != va_p[0] --+ || va[1] != va_p[1]) --+ abort (); --+ else --+ exit (0); --+} --+#else --+int main(){return 0;} --+#endif --diff --git a/gcc/testsuite/gcc.target/nds32/builtin-dsp-zunpkd830.c b/gcc/testsuite/gcc.target/nds32/builtin-dsp-zunpkd830.c --new file mode 100644 --index 0000000..8f5a224 ----- /dev/null --+++ b/gcc/testsuite/gcc.target/nds32/builtin-dsp-zunpkd830.c --@@ -0,0 +1,37 @@ --+/* This is a test program for zunpkd830 instruction. */ --+ --+/* { dg-do run } */ --+ --+#include --+#include --+ --+#ifdef __NDS32_EXT_DSP__ --+static __attribute__ ((noinline)) --+unsigned int zunpkd830 (unsigned int a) --+{ --+ return __nds32__zunpkd830 (a); --+} --+ --+static __attribute__ ((noinline)) --+uint16x2_t v_zunpkd830 (uint8x4_t a) --+{ --+ return __nds32__v_zunpkd830 (a); --+} --+ --+int --+main () --+{ --+ unsigned int a = zunpkd830 (0x120000f8); --+ uint16x2_t va = v_zunpkd830 ((uint8x4_t) { 0xf8, 0x00, 0, 0x12}); --+ --+ if (a != 0x001200f8) --+ abort (); --+ else if (va[0] != 0x00f8 --+ || va[1] != 0x0012) --+ abort (); --+ else --+ exit (0); --+} --+#else --+int main(){return 0;} --+#endif --diff --git a/gcc/testsuite/gcc.target/nds32/builtin-dsp-zunpkd831.c b/gcc/testsuite/gcc.target/nds32/builtin-dsp-zunpkd831.c --new file mode 100644 --index 0000000..6878cd3 ----- /dev/null --+++ b/gcc/testsuite/gcc.target/nds32/builtin-dsp-zunpkd831.c --@@ -0,0 +1,43 @@ --+/* This is a test program for zunpkd831 instruction. */ --+ --+/* { dg-do run } */ --+ --+#include --+#include --+ --+#ifdef __NDS32_EXT_DSP__ --+static __attribute__ ((noinline)) --+unsigned int zunpkd831 (unsigned int a) --+{ --+ return __nds32__zunpkd831 (a); --+} --+ --+static __attribute__ ((noinline)) --+uint16x2_t v_zunpkd831 (uint8x4_t a) --+{ --+ return __nds32__v_zunpkd831 (a); --+} --+ --+int --+main () --+{ --+#ifdef __NDS32_EL__ --+ int16x2_t va_p = {0xf8, 0x12}; --+#else --+ int16x2_t va_p = {0, 0}; --+#endif --+ --+ unsigned int a = zunpkd831 (0x1200f800); --+ uint16x2_t va = v_zunpkd831 ((uint8x4_t) {0, 0xf8, 0, 0x12}); --+ --+ if (a != 0x001200f8) --+ abort (); --+ else if (va[0] != va_p[0] --+ || va[1] != va_p[1]) --+ abort (); --+ else --+ exit (0); --+} --+#else --+int main(){return 0;} --+#endif --diff --git a/gcc/testsuite/gcc.target/nds32/builtin-fpu-fcpyd.c b/gcc/testsuite/gcc.target/nds32/builtin-fpu-fcpyd.c --new file mode 100644 --index 0000000..4ee7e5e ----- /dev/null --+++ b/gcc/testsuite/gcc.target/nds32/builtin-fpu-fcpyd.c --@@ -0,0 +1,21 @@ --+/* This is a test program for fcpysd instruction. */ --+ --+/* { dg-do run } */ --+/* { dg-options "-O1" } */ --+/* { dg-require-effective-target nds32_ext_fpu_dp } */ --+ --+#include --+#include --+ --+int --+main () --+{ --+ double da = -1.5; --+ double db = 1.3; --+ double dr = __nds32__fcpysd (da, db); --+ --+ if (dr != 1.5) --+ abort (); --+ else --+ exit (0); --+} --diff --git a/gcc/testsuite/gcc.target/nds32/builtin-fpu-fcpynd.c b/gcc/testsuite/gcc.target/nds32/builtin-fpu-fcpynd.c --new file mode 100644 --index 0000000..804410b ----- /dev/null --+++ b/gcc/testsuite/gcc.target/nds32/builtin-fpu-fcpynd.c --@@ -0,0 +1,21 @@ --+/* This is a test program for fcpynsd instruction. */ --+ --+/* { dg-do run } */ --+/* { dg-options "-O1" } */ --+/* { dg-require-effective-target nds32_ext_fpu_dp } */ --+ --+#include --+#include --+ --+int --+main () --+{ --+ double da = -1.5; --+ double db = -1.3; --+ double dr = __nds32__fcpynsd (da, db); --+ --+ if (dr != 1.5) --+ abort (); --+ else --+ exit (0); --+} --diff --git a/gcc/testsuite/gcc.target/nds32/builtin-fpu-fcpyns.c b/gcc/testsuite/gcc.target/nds32/builtin-fpu-fcpyns.c --new file mode 100644 --index 0000000..0d86734 ----- /dev/null --+++ b/gcc/testsuite/gcc.target/nds32/builtin-fpu-fcpyns.c --@@ -0,0 +1,21 @@ --+/* This is a test program for fcpynss instruction. */ --+ --+/* { dg-do run } */ --+/* { dg-options "-O1" } */ --+/* { dg-require-effective-target nds32_ext_fpu_sp } */ --+ --+#include --+#include --+ --+int --+main () --+{ --+ float a = -1.5; --+ float b = -1.3; --+ float r = __nds32__fcpynss (a, b); --+ --+ if (r != 1.5) --+ abort (); --+ else --+ exit (0); --+} --diff --git a/gcc/testsuite/gcc.target/nds32/builtin-fpu-fcpys.c b/gcc/testsuite/gcc.target/nds32/builtin-fpu-fcpys.c --new file mode 100644 --index 0000000..4bccf57 ----- /dev/null --+++ b/gcc/testsuite/gcc.target/nds32/builtin-fpu-fcpys.c --@@ -0,0 +1,21 @@ --+/* This is a test program for fcpyss instruction. */ --+ --+/* { dg-do run } */ --+/* { dg-options "-O1" } */ --+/* { dg-require-effective-target nds32_ext_fpu_sp } */ --+ --+#include --+#include --+ --+int --+main () --+{ --+ float a = -1.5; --+ float b = 1.3; --+ float r = __nds32__fcpyss (a, b); --+ --+ if (r != 1.5) --+ abort (); --+ else --+ exit (0); --+} --diff --git a/gcc/testsuite/gcc.target/nds32/builtin-fpu-fmfcfg.c b/gcc/testsuite/gcc.target/nds32/builtin-fpu-fmfcfg.c --new file mode 100644 --index 0000000..83e65ed ----- /dev/null --+++ b/gcc/testsuite/gcc.target/nds32/builtin-fpu-fmfcfg.c --@@ -0,0 +1,23 @@ --+/* This is a test program for fmfcfg instruction. */ --+ --+/* { dg-do run } */ --+/* { dg-options "-O1" } */ --+/* { dg-require-effective-target nds32_ext_fpu } */ --+ --+#include --+#include --+ --+int --+main () --+{ --+ unsigned int intrinsic_fmfcfg = -1; --+ unsigned int inline_assemble_fmfcfg = -2; --+ --+ intrinsic_fmfcfg = __nds32__fmfcfg (); --+ __asm volatile ("fmfcfg %0" : "=r" (inline_assemble_fmfcfg)); --+ --+ if (intrinsic_fmfcfg == inline_assemble_fmfcfg) --+ exit (0); --+ else --+ abort (); --+} --diff --git a/gcc/testsuite/gcc.target/nds32/builtin-fpu-fpcsr.c b/gcc/testsuite/gcc.target/nds32/builtin-fpu-fpcsr.c --new file mode 100644 --index 0000000..787b430 ----- /dev/null --+++ b/gcc/testsuite/gcc.target/nds32/builtin-fpu-fpcsr.c --@@ -0,0 +1,35 @@ --+/* This is a test program for fmtcsr/fmfcsr instruction. */ --+ --+/* { dg-do run } */ --+/* { dg-options "-O1" } */ --+/* { dg-require-effective-target nds32_ext_fpu } */ --+ --+#include --+#include --+ --+int --+main () --+{ --+ unsigned int fpcsr; --+ unsigned int real_fpcsr; --+ --+ /* Keep real fpcsr value. */ --+ real_fpcsr = __nds32__fmfcsr (); --+ --+ /* write fpcsr */ --+ fpcsr = 3; --+ __nds32__fmtcsr (fpcsr); --+ --+ /* read fpcsr */ --+ fpcsr = 0; --+ fpcsr = __nds32__fmfcsr (); --+ fpcsr = fpcsr & 0x00001fff; --+ --+ /* Recover fpcsr value. */ --+ __nds32__fmtcsr (real_fpcsr); --+ --+ if (fpcsr == 3) --+ exit (0); --+ else --+ abort (); --+} --diff --git a/gcc/testsuite/gcc.target/nds32/builtin-get-lp.c b/gcc/testsuite/gcc.target/nds32/builtin-get-lp.c --new file mode 100644 --index 0000000..80b4921 ----- /dev/null --+++ b/gcc/testsuite/gcc.target/nds32/builtin-get-lp.c --@@ -0,0 +1,22 @@ --+/* Verify the return address with builtin function. */ --+ --+/* { dg-do run } */ --+/* { dg-options "-O1" } */ --+ --+#include --+#include --+ --+int main() --+{ --+ unsigned int intrinsic_lp = -1; --+ unsigned int inline_assemble_lp = -2; --+ --+ intrinsic_lp = __nds32__return_address (); --+ --+ __asm volatile ("mov55 %0, $lp" : "=r" (inline_assemble_lp)); --+ --+ if (intrinsic_lp != inline_assemble_lp) --+ abort (); --+ else --+ exit (0); --+} --diff --git a/gcc/testsuite/gcc.target/nds32/builtin-isb.c b/gcc/testsuite/gcc.target/nds32/builtin-isb.c --deleted file mode 100644 --index e65061b..0000000 ----- a/gcc/testsuite/gcc.target/nds32/builtin-isb.c --+++ /dev/null --@@ -1,11 +0,0 @@ ---/* Verify that we generate isb instruction with builtin function. */ --- ---/* { dg-do compile } */ ---/* { dg-options "-O0" } */ ---/* { dg-final { scan-assembler "\\tisb" } } */ --- ---void ---test (void) ---{ --- __builtin_nds32_isb (); ---} --diff --git a/gcc/testsuite/gcc.target/nds32/builtin-isync.c b/gcc/testsuite/gcc.target/nds32/builtin-isync.c --deleted file mode 100644 --index 3160e4a..0000000 ----- a/gcc/testsuite/gcc.target/nds32/builtin-isync.c --+++ /dev/null --@@ -1,12 +0,0 @@ ---/* Verify that we generate isync instruction with builtin function. */ --- ---/* { dg-do compile } */ ---/* { dg-options "-O0" } */ ---/* { dg-final { scan-assembler "\\tisync" } } */ --- ---void ---test (void) ---{ --- int *addr = (int *) 0x53000000; --- __builtin_nds32_isync (addr); ---} --diff --git a/gcc/testsuite/gcc.target/nds32/builtin-mfsr-mtsr.c b/gcc/testsuite/gcc.target/nds32/builtin-mfsr-mtsr.c --deleted file mode 100644 --index db4c558..0000000 ----- a/gcc/testsuite/gcc.target/nds32/builtin-mfsr-mtsr.c --+++ /dev/null --@@ -1,17 +0,0 @@ ---/* Verify that we generate mfsr/mtsr instruction with builtin function. */ --- ---/* { dg-do compile } */ ---/* { dg-options "-O0" } */ ---/* { dg-final { scan-assembler "\\tmfsr" } } */ ---/* { dg-final { scan-assembler "\\tmtsr" } } */ --- ---#include --- ---void ---test (void) ---{ --- int ipsw_value; --- --- ipsw_value = __builtin_nds32_mfsr (__NDS32_REG_IPSW__); --- __builtin_nds32_mtsr (ipsw_value, __NDS32_REG_IPSW__); ---} --diff --git a/gcc/testsuite/gcc.target/nds32/builtin-mfusr-mtusr.c b/gcc/testsuite/gcc.target/nds32/builtin-mfusr-mtusr.c --deleted file mode 100644 --index 3cfaab9..0000000 ----- a/gcc/testsuite/gcc.target/nds32/builtin-mfusr-mtusr.c --+++ /dev/null --@@ -1,17 +0,0 @@ ---/* Verify that we generate mfusr/mtusr instruction with builtin function. */ --- ---/* { dg-do compile } */ ---/* { dg-options "-O0" } */ ---/* { dg-final { scan-assembler "\\tmfusr" } } */ ---/* { dg-final { scan-assembler "\\tmtusr" } } */ --- ---#include --- ---void ---test (void) ---{ --- int itype_value; --- --- itype_value = __builtin_nds32_mfusr (__NDS32_REG_ITYPE__); --- __builtin_nds32_mtusr (itype_value, __NDS32_REG_ITYPE__); ---} --diff --git a/gcc/testsuite/gcc.target/nds32/builtin-rotr.c b/gcc/testsuite/gcc.target/nds32/builtin-rotr.c --new file mode 100644 --index 0000000..a295cb2 ----- /dev/null --+++ b/gcc/testsuite/gcc.target/nds32/builtin-rotr.c --@@ -0,0 +1,19 @@ --+/* This is a test program for rotr instruction. */ --+ --+/* { dg-do run } */ --+/* { dg-options "-O0" } */ --+ --+#include --+#include --+ --+int --+main () --+{ --+ unsigned int a = 1; --+ a = __nds32__rotr (a, 30); --+ --+ if (a != 4) --+ abort (); --+ else --+ exit (0); --+} --diff --git a/gcc/testsuite/gcc.target/nds32/builtin-setgie-dis.c b/gcc/testsuite/gcc.target/nds32/builtin-setgie-dis.c --deleted file mode 100644 --index 2dceed9..0000000 ----- a/gcc/testsuite/gcc.target/nds32/builtin-setgie-dis.c --+++ /dev/null --@@ -1,11 +0,0 @@ ---/* Verify that we generate setgie.d instruction with builtin function. */ --- ---/* { dg-do compile } */ ---/* { dg-options "-O0" } */ ---/* { dg-final { scan-assembler "\\tsetgie.d" } } */ --- ---void ---test (void) ---{ --- __builtin_nds32_setgie_dis (); ---} --diff --git a/gcc/testsuite/gcc.target/nds32/builtin-setgie-en.c b/gcc/testsuite/gcc.target/nds32/builtin-setgie-en.c --deleted file mode 100644 --index 8928870..0000000 ----- a/gcc/testsuite/gcc.target/nds32/builtin-setgie-en.c --+++ /dev/null --@@ -1,11 +0,0 @@ ---/* Verify that we generate setgie.e instruction with builtin function. */ --- ---/* { dg-do compile } */ ---/* { dg-options "-O0" } */ ---/* { dg-final { scan-assembler "\\tsetgie.e" } } */ --- ---void ---test (void) ---{ --- __builtin_nds32_setgie_en (); ---} --diff --git a/gcc/testsuite/gcc.target/nds32/builtin-setgie_mtsr_mfsr.c b/gcc/testsuite/gcc.target/nds32/builtin-setgie_mtsr_mfsr.c --new file mode 100644 --index 0000000..b353909 ----- /dev/null --+++ b/gcc/testsuite/gcc.target/nds32/builtin-setgie_mtsr_mfsr.c --@@ -0,0 +1,43 @@ --+/* This is a test program for checking gie with --+ mtsr/mfsr instruction. */ --+ --+/* { dg-do run } */ --+/* { dg-options "-O0" } */ --+ --+#include --+#include --+ --+int --+main () --+{ --+ unsigned int psw; --+ unsigned int gie; --+ unsigned int pfm_ctl; --+ unsigned int real_psw; --+ --+ /* Keep PSW value. */ --+ real_psw = __nds32__mfsr (NDS32_SR_PSW); --+ --+ __nds32__setgie_en (); --+ __nds32__dsb(); /* This is needed for waiting pipeline. */ --+ psw = __nds32__mfsr (NDS32_SR_PSW); --+ --+ gie = psw & 0x00000001; --+ --+ if (gie != 1) --+ abort (); --+ --+ psw = psw & 0xFFFFFFFE; --+ __nds32__mtsr (psw, NDS32_SR_PSW); --+ __nds32__dsb(); /* This is needed for waiting pipeline. */ --+ psw = __nds32__mfsr (NDS32_SR_PSW); --+ gie = psw & 0x00000001; --+ --+ /* Recover PSW value. */ --+ __nds32__mtsr (real_psw, NDS32_SR_PSW); --+ --+ if (gie != 0) --+ abort (); --+ else --+ exit (0); --+} --diff --git a/gcc/testsuite/gcc.target/nds32/builtin-sp.c b/gcc/testsuite/gcc.target/nds32/builtin-sp.c --new file mode 100644 --index 0000000..2e5499d ----- /dev/null --+++ b/gcc/testsuite/gcc.target/nds32/builtin-sp.c --@@ -0,0 +1,33 @@ --+/* This is a test program for sp intrinsic usage. --+ Because we want to use frame pointer to access local variable, --+ we need to use -fno-omit-frame-pointer to make sure the existence --+ of frame pointer. */ --+ --+/* { dg-do run } */ --+/* { dg-options "-O0 -fno-omit-frame-pointer" } */ --+ --+#include --+#include --+ --+int --+main () --+{ --+ unsigned int old_sp, new_sp; --+ --+ old_sp = __nds32__get_current_sp (); --+ new_sp = old_sp - 4; --+ __nds32__set_current_sp (new_sp); --+ new_sp = __nds32__get_current_sp (); --+ --+ if (new_sp != (old_sp - 4)) --+ abort (); --+ --+ new_sp = new_sp + 4; --+ __nds32__set_current_sp (new_sp); --+ new_sp = __nds32__get_current_sp (); --+ --+ if (new_sp != old_sp) --+ abort (); --+ else --+ exit (0); --+} --diff --git a/gcc/testsuite/gcc.target/nds32/builtin-string-ffb.c b/gcc/testsuite/gcc.target/nds32/builtin-string-ffb.c --new file mode 100644 --index 0000000..cf02434 ----- /dev/null --+++ b/gcc/testsuite/gcc.target/nds32/builtin-string-ffb.c --@@ -0,0 +1,28 @@ --+/* This is a test program for ffb instruction. */ --+ --+/* { dg-do run } */ --+/* { dg-options "-O1" } */ --+/* { dg-require-effective-target nds32_ext_string } */ --+ --+#include --+#include --+ --+int --+main () --+{ --+ unsigned int a = 0x1b2a3d4c; --+ unsigned int b = 0x0000003d; --+ int r; --+ --+ r = __nds32__ffb (a, b); --+ --+#ifdef __NDS32_EL__ --+ if (r != -3) --+ abort (); --+#else --+ if (r != -2) --+ abort (); --+#endif --+ --+ exit (0); --+} --diff --git a/gcc/testsuite/gcc.target/nds32/builtin-string-ffmism.c b/gcc/testsuite/gcc.target/nds32/builtin-string-ffmism.c --new file mode 100644 --index 0000000..b2fb008 ----- /dev/null --+++ b/gcc/testsuite/gcc.target/nds32/builtin-string-ffmism.c --@@ -0,0 +1,28 @@ --+/* This is a test program for ffmism instruction. */ --+ --+/* { dg-do run } */ --+/* { dg-options "-O1" } */ --+/* { dg-require-effective-target nds32_ext_string } */ --+ --+#include --+#include --+ --+int --+main () --+{ --+ unsigned int a = 0x1b2a3d4c; --+ unsigned int b = 0x112a334c; --+ int r; --+ --+ r = __nds32__ffmism (a, b); --+ --+#ifdef __NDS32_EL__ --+ if (r != -3) --+ abort (); --+#else --+ if (r != -4) --+ abort (); --+#endif --+ --+ exit (0); --+} --diff --git a/gcc/testsuite/gcc.target/nds32/builtin-string-flmism.c b/gcc/testsuite/gcc.target/nds32/builtin-string-flmism.c --new file mode 100644 --index 0000000..105fce5 ----- /dev/null --+++ b/gcc/testsuite/gcc.target/nds32/builtin-string-flmism.c --@@ -0,0 +1,28 @@ --+/* This is a test program for flmism instruction. */ --+ --+/* { dg-do run } */ --+/* { dg-options "-O1" } */ --+/* { dg-require-effective-target nds32_ext_string } */ --+ --+#include --+#include --+ --+int --+main () --+{ --+ unsigned int a = 0x1b2a3d4c; --+ unsigned int b = 0x112a334c; --+ int r; --+ --+ r = __nds32__flmism (a, b); --+ --+#ifdef __NDS32_EL__ --+ if (r != -1) --+ abort (); --+#else --+ if (r != -2) --+ abort (); --+#endif --+ --+ exit (0); --+} --diff --git a/gcc/testsuite/gcc.target/nds32/builtin-unaligned-s16x2.c b/gcc/testsuite/gcc.target/nds32/builtin-unaligned-s16x2.c --new file mode 100644 --index 0000000..5a2e8b7 ----- /dev/null --+++ b/gcc/testsuite/gcc.target/nds32/builtin-unaligned-s16x2.c --@@ -0,0 +1,36 @@ --+/* This is a test program for smbb instruction. */ --+ --+/* { dg-do run } */ --+ --+#include --+#include --+ --+#ifdef __NDS32_EXT_DSP__ --+int --+main (void) --+{ --+ char data[] = {0x55,0x66,0x77,0x88}; --+ short* short_data = (short*)& data[1]; --+ int16x2_t test_short = {0x1111, 0xaaaa}; --+ int16x2_t vecdata = __nds32__get_unaligned_s16x2 (short_data); --+ --+#ifdef __NDS32_EL__ --+ if (vecdata[0] != 0x7766) --+ abort (); --+#else --+ if (vecdata[0] != 0x6677) --+ abort (); --+#endif --+ --+ __nds32__put_unaligned_s16x2 (short_data, test_short); --+ vecdata = __nds32__get_unaligned_s16x2 (short_data); --+ --+ if (vecdata[0] != 0x1111 --+ & vecdata[1] != 0xaaaa) --+ abort (); --+ else --+ exit (0); --+} --+#else --+int main(){return 0;} --+#endif --diff --git a/gcc/testsuite/gcc.target/nds32/builtin-unaligned-s8x4.c b/gcc/testsuite/gcc.target/nds32/builtin-unaligned-s8x4.c --new file mode 100644 --index 0000000..f6cb4c9 ----- /dev/null --+++ b/gcc/testsuite/gcc.target/nds32/builtin-unaligned-s8x4.c --@@ -0,0 +1,36 @@ --+/* This is a test program for smbb instruction. */ --+ --+/* { dg-do run } */ --+ --+#include --+#include --+ --+#ifdef __NDS32_EXT_DSP__ --+int --+main (void) --+{ --+ char data[] = {0x55,0x66,0x77,0x88}; --+ char* char_data = (char*)& data[1]; --+ int8x4_t test_char = {0x11, 0x22, 0xaa, 0xbb}; --+ int8x4_t vecdata = __nds32__get_unaligned_s8x4 (char_data); --+ --+#ifdef __NDS32_EL__ --+ if (vecdata[0] != 0x66) --+ abort (); --+#else --+ if (vecdata[0] != 0x66) --+ abort (); --+#endif --+ --+ __nds32__put_unaligned_s8x4 (char_data, test_char); --+ vecdata = __nds32__get_unaligned_s8x4 (char_data); --+ --+ if (vecdata[0] != 0x11 --+ & vecdata[3] != 0xaa) --+ abort (); --+ else --+ exit (0); --+} --+#else --+int main(){return 0;} --+#endif --diff --git a/gcc/testsuite/gcc.target/nds32/builtin-unaligned-u16x2.c b/gcc/testsuite/gcc.target/nds32/builtin-unaligned-u16x2.c --new file mode 100644 --index 0000000..63ebd40 ----- /dev/null --+++ b/gcc/testsuite/gcc.target/nds32/builtin-unaligned-u16x2.c --@@ -0,0 +1,36 @@ --+/* This is a test program for smbb instruction. */ --+ --+/* { dg-do run } */ --+ --+#include --+#include --+ --+#ifdef __NDS32_EXT_DSP__ --+int --+main (void) --+{ --+ unsigned char data[] = {0x55,0x66,0x77,0x88}; --+ unsigned short* short_data = (unsigned short*)& data[1]; --+ uint16x2_t test_short = {0x1111, 0xaaaa}; --+ uint16x2_t vecdata = __nds32__get_unaligned_u16x2 (short_data); --+ --+#ifdef __NDS32_EL__ --+ if (vecdata[0] != 0x7766) --+ abort (); --+#else --+ if (vecdata[0] != 0x6677) --+ abort (); --+#endif --+ --+ __nds32__put_unaligned_u16x2 (short_data, test_short); --+ vecdata = __nds32__get_unaligned_u16x2 (short_data); --+ --+ if (vecdata[0] != 0x1111 --+ & vecdata[1] != 0xaaaa) --+ abort (); --+ else --+ exit (0); --+} --+#else --+int main(){return 0;} --+#endif --diff --git a/gcc/testsuite/gcc.target/nds32/builtin-unaligned-u8x4.c b/gcc/testsuite/gcc.target/nds32/builtin-unaligned-u8x4.c --new file mode 100644 --index 0000000..7b48274 ----- /dev/null --+++ b/gcc/testsuite/gcc.target/nds32/builtin-unaligned-u8x4.c --@@ -0,0 +1,36 @@ --+/* This is a test program for smbb instruction. */ --+ --+/* { dg-do run } */ --+ --+#include --+#include --+ --+#ifdef __NDS32_EXT_DSP__ --+int --+main (void) --+{ --+ char data[] = {0x55,0x66,0x77,0x88}; --+ unsigned char* char_data = (char*)& data[1]; --+ uint8x4_t test_char = {0x11, 0x22, 0xaa, 0xbb}; --+ uint8x4_t vecdata = __nds32__get_unaligned_u8x4 (char_data); --+ --+#ifdef __NDS32_EL__ --+ if (vecdata[0] != 0x66) --+ abort (); --+#else --+ if (vecdata[0] != 0x66) --+ abort (); --+#endif --+ --+ __nds32__put_unaligned_u8x4 (char_data, test_char); --+ vecdata = __nds32__get_unaligned_u8x4 (char_data); --+ --+ if (vecdata[0] != 0x11 --+ & vecdata[3] != 0xaa) --+ abort (); --+ else --+ exit (0); --+} --+#else --+int main(){return 0;} --+#endif --diff --git a/gcc/testsuite/gcc.target/nds32/builtin-unaligned_dw.c b/gcc/testsuite/gcc.target/nds32/builtin-unaligned_dw.c --new file mode 100644 --index 0000000..42640b4 ----- /dev/null --+++ b/gcc/testsuite/gcc.target/nds32/builtin-unaligned_dw.c --@@ -0,0 +1,31 @@ --+/* This is a test program for unaligned double word access. */ --+ --+/* { dg-do run } */ --+/* { dg-options "-O0 -std=c99" } */ --+ --+#include --+#include --+ --+int --+main () --+{ --+ unsigned char data[] = {0x55, 0x66, 0x77, 0x88, 0xAA, --+ 0xBB, 0xCC, 0xDD, 0xEE, 0xFF}; --+ unsigned long long* long_long_data = (unsigned long long*) & data[1]; --+ unsigned long long test_long_long = 0x1122334455667788LL; --+ --+#ifdef __NDS32_EL__ --+ if (__nds32__get_unaligned_dw (long_long_data) != 0xEEDDCCBBAA887766LL) --+ abort (); --+#else --+ if (__nds32__get_unaligned_dw (long_long_data) != 0x667788AABBCCDDEELL) --+ abort (); --+#endif --+ --+ __nds32__put_unaligned_dw (long_long_data, test_long_long); --+ --+ if (__nds32__get_unaligned_dw (long_long_data) != 0x1122334455667788LL) --+ abort (); --+ else --+ exit (0); --+} --diff --git a/gcc/testsuite/gcc.target/nds32/builtin-unaligned_hw.c b/gcc/testsuite/gcc.target/nds32/builtin-unaligned_hw.c --new file mode 100644 --index 0000000..f9e1ceb ----- /dev/null --+++ b/gcc/testsuite/gcc.target/nds32/builtin-unaligned_hw.c --@@ -0,0 +1,30 @@ --+/* This is a test program for unaligned half word access. */ --+ --+/* { dg-do run } */ --+/* { dg-options "-O0" } */ --+ --+#include --+#include --+ --+int --+main () --+{ --+ unsigned char data[] = {0x55,0x66,0x77,0x88}; --+ unsigned short* short_data = (unsigned short*)& data[1]; --+ unsigned short test_short = 0x5566; --+ --+#ifdef __NDS32_EL__ --+ if (__nds32__get_unaligned_hw (short_data) != 0x7766) --+ abort (); --+#else --+ if (__nds32__get_unaligned_hw (short_data) != 0x6677) --+ abort (); --+#endif --+ --+ __nds32__put_unaligned_hw (short_data, test_short); --+ --+ if (__nds32__get_unaligned_hw (short_data) != 0x5566) --+ abort (); --+ else --+ exit (0); --+} --diff --git a/gcc/testsuite/gcc.target/nds32/builtin-unaligned_w.c b/gcc/testsuite/gcc.target/nds32/builtin-unaligned_w.c --new file mode 100644 --index 0000000..40d8711 ----- /dev/null --+++ b/gcc/testsuite/gcc.target/nds32/builtin-unaligned_w.c --@@ -0,0 +1,30 @@ --+/* This is a test program for unaligned word access. */ --+ --+/* { dg-do run } */ --+/* { dg-options "-O0 -std=c99" } */ --+ --+#include --+#include --+ --+int --+main () --+{ --+ unsigned char data[] = {0x55,0x66,0x77,0x88,0xAA,0xBB,0xCC,0xDD}; --+ unsigned int* int_data = (unsigned int*)& data[1]; --+ unsigned int test_int = 0x55667788; --+ --+#ifdef __NDS32_EL__ --+ if (__nds32__get_unaligned_w (int_data) != 0xAA887766) --+ abort (); --+#else --+ if (__nds32__get_unaligned_w (int_data) != 0x667788AA) --+ abort (); --+#endif --+ --+ __nds32__put_unaligned_w (int_data, test_int); --+ --+ if (__nds32__get_unaligned_w (int_data) != 0x55667788) --+ abort (); --+ else --+ exit (0); --+} --diff --git a/gcc/testsuite/gcc.target/nds32/builtin-wsbh.c b/gcc/testsuite/gcc.target/nds32/builtin-wsbh.c --new file mode 100644 --index 0000000..1cee2ed ----- /dev/null --+++ b/gcc/testsuite/gcc.target/nds32/builtin-wsbh.c --@@ -0,0 +1,21 @@ --+/* This is a test program for wsbh instruction. */ --+ --+/* { dg-do run } */ --+/* { dg-options "-O0" } */ --+ --+#include --+#include --+ --+int --+main () --+{ --+ unsigned int a = 0x03020100; --+ unsigned int b; --+ --+ b = __nds32__wsbh (a); --+ --+ if (b != 0x02030001) --+ abort (); --+ else --+ exit (0); --+} --diff --git a/gcc/testsuite/gcc.target/nds32/compile/builtin-all-pending.c b/gcc/testsuite/gcc.target/nds32/compile/builtin-all-pending.c --new file mode 100644 --index 0000000..0e57831 ----- /dev/null --+++ b/gcc/testsuite/gcc.target/nds32/compile/builtin-all-pending.c --@@ -0,0 +1,11 @@ --+/* { dg-do compile } */ --+/* { dg-options "-O1" } */ --+ --+#include --+ --+int --+main (void) --+{ --+ int a = __nds32__get_all_pending_int (); --+ return a; --+} --diff --git a/gcc/testsuite/gcc.target/nds32/compile/builtin-cctl.c b/gcc/testsuite/gcc.target/nds32/compile/builtin-cctl.c --new file mode 100644 --index 0000000..2af55f5 ----- /dev/null --+++ b/gcc/testsuite/gcc.target/nds32/compile/builtin-cctl.c --@@ -0,0 +1,29 @@ --+/* Verify that we generate cache control instruction with builtin function. */ --+ --+/* { dg-do compile } */ --+/* { dg-options "-O0" } */ --+/* { dg-final { scan-assembler "L1D_VA_INVAL" } } */ --+/* { dg-final { scan-assembler "L1D_VA_INVAL" } } */ --+/* { dg-final { scan-assembler "L1D_INVALALL" } } */ --+/* { dg-final { scan-assembler "L1D_IX_WWD" } } */ --+/* { dg-final { scan-assembler "L1D_IX_RWD" } } */ --+/* { dg-final { scan-assembler "PFM_CTL" } } */ --+/* { dg-final { scan-assembler "PFM_CTL" } } */ --+ --+#include --+ --+void --+test (void) --+{ --+ unsigned int va = 0; --+ --+ __nds32__cctlva_lck (NDS32_CCTL_L1D_VA_FILLCK, &va); --+ __nds32__cctlidx_wbinval (NDS32_CCTL_L1D_IX_WBINVAL, va); --+ __nds32__cctlva_wbinval_alvl (NDS32_CCTL_L1D_VA_INVAL, &va); --+ __nds32__cctlva_wbinval_one_lvl (NDS32_CCTL_L1D_VA_INVAL, &va); --+ __nds32__cctl_l1d_invalall (); --+ __nds32__cctlidx_write (NDS32_CCTL_L1D_IX_WWD, va, 1); --+ __nds32__cctlidx_read (NDS32_CCTL_L1D_IX_RWD, 1); --+ __nds32__mtusr (0, NDS32_USR_PFM_CTL); --+ __nds32__mfusr (NDS32_USR_PFM_CTL); --+} --diff --git a/gcc/testsuite/gcc.target/nds32/compile/builtin-clr-pending-hw.c b/gcc/testsuite/gcc.target/nds32/compile/builtin-clr-pending-hw.c --new file mode 100644 --index 0000000..fce90e9 ----- /dev/null --+++ b/gcc/testsuite/gcc.target/nds32/compile/builtin-clr-pending-hw.c --@@ -0,0 +1,16 @@ --+/* { dg-do compile } */ --+/* { dg-options "-O1" } */ --+ --+#include --+ --+void --+main (void) --+{ --+ __nds32__clr_pending_hwint (NDS32_INT_H0); --+ __nds32__clr_pending_hwint (NDS32_INT_H1); --+ __nds32__clr_pending_hwint (NDS32_INT_H2); --+ --+ __nds32__clr_pending_hwint (NDS32_INT_H15); --+ __nds32__clr_pending_hwint (NDS32_INT_H16); --+ __nds32__clr_pending_hwint (NDS32_INT_H31); --+} --diff --git a/gcc/testsuite/gcc.target/nds32/compile/builtin-clr-pending.c b/gcc/testsuite/gcc.target/nds32/compile/builtin-clr-pending.c --new file mode 100644 --index 0000000..08e1dd0 ----- /dev/null --+++ b/gcc/testsuite/gcc.target/nds32/compile/builtin-clr-pending.c --@@ -0,0 +1,10 @@ --+/* { dg-do compile } */ --+/* { dg-options "-O1" } */ --+ --+#include --+ --+void --+main (void) --+{ --+ __nds32__clr_pending_swint (); --+} --diff --git a/gcc/testsuite/gcc.target/nds32/compile/builtin-disable.c b/gcc/testsuite/gcc.target/nds32/compile/builtin-disable.c --new file mode 100644 --index 0000000..a3a1f44 ----- /dev/null --+++ b/gcc/testsuite/gcc.target/nds32/compile/builtin-disable.c --@@ -0,0 +1,13 @@ --+/* { dg-do compile } */ --+/* { dg-options "-O1" } */ --+ --+#include --+ --+void --+main (void) --+{ --+ __nds32__disable_int (NDS32_INT_H15); --+ __nds32__disable_int (NDS32_INT_H16); --+ __nds32__disable_int (NDS32_INT_H31); --+ __nds32__disable_int (NDS32_INT_SWI); --+} --diff --git a/gcc/testsuite/gcc.target/nds32/compile/builtin-dpref.c b/gcc/testsuite/gcc.target/nds32/compile/builtin-dpref.c --new file mode 100644 --index 0000000..38cf822 ----- /dev/null --+++ b/gcc/testsuite/gcc.target/nds32/compile/builtin-dpref.c --@@ -0,0 +1,24 @@ --+/* Verify that we generate data prefetch instruction with builtin function. */ --+ --+/* { dg-do compile } */ --+/* { dg-options "-O0" } */ --+/* { dg-final { scan-assembler "dpref\\tSRD" } } */ --+/* { dg-final { scan-assembler "dpref\\tSRD" } } */ --+/* { dg-final { scan-assembler "dpref\\tSRD" } } */ --+/* { dg-final { scan-assembler "dpref\\tSRD" } } */ --+ --+#include --+ --+void --+test (void) --+{ --+ unsigned char dpref_q = 0; --+ unsigned short dpref_h = 0; --+ unsigned int dpref_w = 0; --+ unsigned long long dpref_dw = 0; --+ --+ __nds32__dpref_qw (&dpref_q, 0, NDS32_DPREF_SRD); --+ __nds32__dpref_hw (&dpref_h, 0, NDS32_DPREF_SRD); --+ __nds32__dpref_w (&dpref_w, 0, NDS32_DPREF_SRD); --+ __nds32__dpref_dw (&dpref_dw, 0, NDS32_DPREF_SRD); --+} --diff --git a/gcc/testsuite/gcc.target/nds32/compile/builtin-enable.c b/gcc/testsuite/gcc.target/nds32/compile/builtin-enable.c --new file mode 100644 --index 0000000..e18ed7a ----- /dev/null --+++ b/gcc/testsuite/gcc.target/nds32/compile/builtin-enable.c --@@ -0,0 +1,13 @@ --+/* { dg-do compile } */ --+/* { dg-options "-O1" } */ --+ --+#include --+ --+void --+main (void) --+{ --+ __nds32__enable_int (NDS32_INT_H15); --+ __nds32__enable_int (NDS32_INT_H16); --+ __nds32__enable_int (NDS32_INT_H31); --+ __nds32__enable_int (NDS32_INT_SWI); --+} --diff --git a/gcc/testsuite/gcc.target/nds32/compile/builtin-get-pending-int.c b/gcc/testsuite/gcc.target/nds32/compile/builtin-get-pending-int.c --new file mode 100644 --index 0000000..4ced0a5 ----- /dev/null --+++ b/gcc/testsuite/gcc.target/nds32/compile/builtin-get-pending-int.c --@@ -0,0 +1,14 @@ --+/* { dg-do compile } */ --+/* { dg-options "-O1" } */ --+ --+#include --+ --+int --+main (void) --+{ --+ int a = __nds32__get_pending_int (NDS32_INT_H15); --+ int b = __nds32__get_pending_int (NDS32_INT_SWI); --+ int c = __nds32__get_pending_int (NDS32_INT_H16); --+ --+ return a + b + c; --+} --diff --git a/gcc/testsuite/gcc.target/nds32/compile/builtin-get-trig.c b/gcc/testsuite/gcc.target/nds32/compile/builtin-get-trig.c --new file mode 100644 --index 0000000..a394a60 ----- /dev/null --+++ b/gcc/testsuite/gcc.target/nds32/compile/builtin-get-trig.c --@@ -0,0 +1,14 @@ --+/* { dg-do compile } */ --+/* { dg-options "-O1" } */ --+ --+#include --+ --+int --+main (void) --+{ --+ int a = __nds32__get_trig_type (NDS32_INT_H0); --+ int b = __nds32__get_trig_type (NDS32_INT_H15); --+ int c = __nds32__get_trig_type (NDS32_INT_H16); --+ int d = __nds32__get_trig_type (NDS32_INT_H31); --+ return a + b + c + d; --+} --diff --git a/gcc/testsuite/gcc.target/nds32/compile/builtin-isb.c b/gcc/testsuite/gcc.target/nds32/compile/builtin-isb.c --new file mode 100644 --index 0000000..c699966 ----- /dev/null --+++ b/gcc/testsuite/gcc.target/nds32/compile/builtin-isb.c --@@ -0,0 +1,13 @@ --+/* Verify that we generate isb instruction with builtin function. */ --+ --+/* { dg-do compile } */ --+/* { dg-options "-O0" } */ --+/* { dg-final { scan-assembler "\\tisb" } } */ --+ --+#include --+ --+void --+test (void) --+{ --+ __nds32__isb (); --+} --diff --git a/gcc/testsuite/gcc.target/nds32/compile/builtin-isync.c b/gcc/testsuite/gcc.target/nds32/compile/builtin-isync.c --new file mode 100644 --index 0000000..0c312e4 ----- /dev/null --+++ b/gcc/testsuite/gcc.target/nds32/compile/builtin-isync.c --@@ -0,0 +1,14 @@ --+/* Verify that we generate isync instruction with builtin function. */ --+ --+/* { dg-do compile } */ --+/* { dg-options "-O0" } */ --+/* { dg-final { scan-assembler "\\tisync" } } */ --+ --+#include --+ --+void --+test (void) --+{ --+ int *addr = (int *) 0x53000000; --+ __nds32__isync (addr); --+} --diff --git a/gcc/testsuite/gcc.target/nds32/compile/builtin-load-store.c b/gcc/testsuite/gcc.target/nds32/compile/builtin-load-store.c --new file mode 100644 --index 0000000..fc15716 ----- /dev/null --+++ b/gcc/testsuite/gcc.target/nds32/compile/builtin-load-store.c --@@ -0,0 +1,25 @@ --+/* Verify that we generate llw/lwup/scw/swup instruction --+ with builtin function. */ --+ --+/* { dg-do compile } */ --+/* { dg-require-effective-target nds32_no_v3m } */ --+/* { dg-options "-O0" } */ --+/* { dg-final { scan-assembler "\\tllw" } } */ --+/* { dg-final { scan-assembler "\\tlwup" } } */ --+/* { dg-final { scan-assembler "\\tscw" } } */ --+/* { dg-final { scan-assembler "\\tswup" } } */ --+ --+#include --+ --+void --+test (void) --+{ --+ int a = 0; --+ int b = 0; --+ unsigned int cc = 0; --+ --+ __nds32__llw (&a); --+ cc = __nds32__lwup (&a); --+ __nds32__scw (&a, b); --+ __nds32__swup (&a, b); --+} --diff --git a/gcc/testsuite/gcc.target/nds32/compile/builtin-lto.c b/gcc/testsuite/gcc.target/nds32/compile/builtin-lto.c --new file mode 100644 --index 0000000..fbebcb6 ----- /dev/null --+++ b/gcc/testsuite/gcc.target/nds32/compile/builtin-lto.c --@@ -0,0 +1,28 @@ --+/* Verify that we use -flto option to generate instructions --+ with builtin function. */ --+ --+/* { dg-do compile } */ --+/* { dg-options "-O0 -flto" } */ --+/* { dg-final { scan-assembler "\\tdsb" } } */ --+/* { dg-final { scan-assembler "\\tisb" } } */ --+/* { dg-final { scan-assembler "\\tmsync\\tall" } } */ --+/* { dg-final { scan-assembler "\\tmsync\\tstore" } } */ --+/* { dg-final { scan-assembler "\\tnop" } } */ --+/* { dg-final { scan-assembler "\\tstandby\\tno_wake_grant" } } */ --+/* { dg-final { scan-assembler "\\tstandby\\twake_grant" } } */ --+/* { dg-final { scan-assembler "\\tstandby\\twait_done" } } */ --+ --+#include --+ --+void --+test (void) --+{ --+ __nds32__dsb (); --+ __nds32__isb (); --+ __nds32__msync_all (); --+ __nds32__msync_store (); --+ __nds32__nop (); --+ __nds32__standby_no_wake_grant (); --+ __nds32__standby_wake_grant (); --+ __nds32__standby_wait_done (); --+} --diff --git a/gcc/testsuite/gcc.target/nds32/compile/builtin-machine-sva.c b/gcc/testsuite/gcc.target/nds32/compile/builtin-machine-sva.c --new file mode 100644 --index 0000000..f927c72 ----- /dev/null --+++ b/gcc/testsuite/gcc.target/nds32/compile/builtin-machine-sva.c --@@ -0,0 +1,16 @@ --+/* Verify that we generate sva instruction with builtin function. */ --+ --+/* { dg-do compile } */ --+/* { dg-options "-O0" } */ --+/* { dg-final { scan-assembler "\\tsva" } } */ --+ --+#include --+ --+void --+test (void) --+{ --+ int a, b; --+ char c; --+ --+ c = __nds32__sva (a, b); --+} --diff --git a/gcc/testsuite/gcc.target/nds32/compile/builtin-machine-svs.c b/gcc/testsuite/gcc.target/nds32/compile/builtin-machine-svs.c --new file mode 100644 --index 0000000..f998491 ----- /dev/null --+++ b/gcc/testsuite/gcc.target/nds32/compile/builtin-machine-svs.c --@@ -0,0 +1,16 @@ --+/* Verify that we generate svs instruction with builtin function. */ --+ --+/* { dg-do compile } */ --+/* { dg-options "-O0" } */ --+/* { dg-final { scan-assembler "\\tsvs" } } */ --+ --+#include --+ --+void --+test (void) --+{ --+ int a, b; --+ char c; --+ --+ c = __nds32__svs (a, b); --+} --diff --git a/gcc/testsuite/gcc.target/nds32/compile/builtin-mfsr-mtsr.c b/gcc/testsuite/gcc.target/nds32/compile/builtin-mfsr-mtsr.c --new file mode 100644 --index 0000000..f069507 ----- /dev/null --+++ b/gcc/testsuite/gcc.target/nds32/compile/builtin-mfsr-mtsr.c --@@ -0,0 +1,17 @@ --+/* Verify that we generate mfsr/mtsr instruction with builtin function. */ --+ --+/* { dg-do compile } */ --+/* { dg-options "-O0" } */ --+/* { dg-final { scan-assembler "\\tmfsr" } } */ --+/* { dg-final { scan-assembler "\\tmtsr" } } */ --+ --+#include --+ --+void --+test (void) --+{ --+ int ipsw_value; --+ --+ ipsw_value = __nds32__mfsr (__NDS32_REG_IPSW__); --+ __nds32__mtsr (ipsw_value, __NDS32_REG_IPSW__); --+} --diff --git a/gcc/testsuite/gcc.target/nds32/compile/builtin-mfusr-mtusr.c b/gcc/testsuite/gcc.target/nds32/compile/builtin-mfusr-mtusr.c --new file mode 100644 --index 0000000..d6d069b ----- /dev/null --+++ b/gcc/testsuite/gcc.target/nds32/compile/builtin-mfusr-mtusr.c --@@ -0,0 +1,17 @@ --+/* Verify that we generate mfusr/mtusr instruction with builtin function. */ --+ --+/* { dg-do compile } */ --+/* { dg-options "-O0" } */ --+/* { dg-final { scan-assembler "\\tmfusr" } } */ --+/* { dg-final { scan-assembler "\\tmtusr" } } */ --+ --+#include --+ --+void --+test (void) --+{ --+ int itype_value; --+ --+ itype_value = __nds32__mfusr (__NDS32_REG_ITYPE__); --+ __nds32__mtusr (itype_value, __NDS32_REG_ITYPE__); --+} --diff --git a/gcc/testsuite/gcc.target/nds32/compile/builtin-misc.c b/gcc/testsuite/gcc.target/nds32/compile/builtin-misc.c --new file mode 100644 --index 0000000..a11f6d9 ----- /dev/null --+++ b/gcc/testsuite/gcc.target/nds32/compile/builtin-misc.c --@@ -0,0 +1,39 @@ --+/* Verify that we generate other instructions with builtin function. */ --+ --+/* { dg-do compile } */ --+/* { dg-options "-O0" } */ --+/* { dg-final { scan-assembler "\\tbreak" } } */ --+/* { dg-final { scan-assembler "\\tdsb" } } */ --+/* { dg-final { scan-assembler "\\tisb" } } */ --+/* { dg-final { scan-assembler "\\tisync" } } */ --+/* { dg-final { scan-assembler "\\tmsync\\tall" } } */ --+/* { dg-final { scan-assembler "\\tmsync\\tstore" } } */ --+/* { dg-final { scan-assembler "\\tnop" } } */ --+/* { dg-final { scan-assembler "\\tstandby\\tno_wake_grant" } } */ --+/* { dg-final { scan-assembler "\\tstandby\\twake_grant" } } */ --+/* { dg-final { scan-assembler "\\tstandby\\twait_done" } } */ --+/* { dg-final { scan-assembler "\\tteqz" } } */ --+/* { dg-final { scan-assembler "\\ttnez" } } */ --+/* { dg-final { scan-assembler "\\ttrap" } } */ --+ --+#include --+ --+void --+test (void) --+{ --+ int a = 0; --+ --+ __nds32__break (2); --+ __nds32__dsb (); --+ __nds32__isb (); --+ __nds32__isync (&a); --+ __nds32__msync_all (); --+ __nds32__msync_store (); --+ __nds32__nop (); --+ __nds32__standby_no_wake_grant (); --+ __nds32__standby_wake_grant (); --+ __nds32__standby_wait_done (); --+ __nds32__teqz (a, 2); --+ __nds32__tnez (a, 2); --+ __nds32__trap (2); --+} --diff --git a/gcc/testsuite/gcc.target/nds32/compile/builtin-mtsr-dsb.c b/gcc/testsuite/gcc.target/nds32/compile/builtin-mtsr-dsb.c --new file mode 100644 --index 0000000..226d627 ----- /dev/null --+++ b/gcc/testsuite/gcc.target/nds32/compile/builtin-mtsr-dsb.c --@@ -0,0 +1,14 @@ --+/* Verify that we generate mtsr and dsb instruction with builtin function. */ --+ --+/* { dg-do compile } */ --+/* { dg-options "-O0" } */ --+/* { dg-final { scan-assembler "\\tmtsr" } } */ --+/* { dg-final { scan-assembler "\\tdsb" } } */ --+ --+#include --+ --+void --+main (void) --+{ --+ __nds32__mtsr_dsb (1, NDS32_SR_ILMB); --+} --diff --git a/gcc/testsuite/gcc.target/nds32/compile/builtin-mtsr-isb.c b/gcc/testsuite/gcc.target/nds32/compile/builtin-mtsr-isb.c --new file mode 100644 --index 0000000..e8b1f98 ----- /dev/null --+++ b/gcc/testsuite/gcc.target/nds32/compile/builtin-mtsr-isb.c --@@ -0,0 +1,14 @@ --+/* Verify that we generate mtsr and isb instruction with builtin function. */ --+ --+/* { dg-do compile } */ --+/* { dg-options "-O0" } */ --+/* { dg-final { scan-assembler "\\tmtsr" } } */ --+/* { dg-final { scan-assembler "\\tisb" } } */ --+ --+#include --+ --+void --+main (void) --+{ --+ __nds32__mtsr_isb (1, NDS32_SR_ILMB); --+} --diff --git a/gcc/testsuite/gcc.target/nds32/compile/builtin-priority.c b/gcc/testsuite/gcc.target/nds32/compile/builtin-priority.c --new file mode 100644 --index 0000000..c2ec6f6 ----- /dev/null --+++ b/gcc/testsuite/gcc.target/nds32/compile/builtin-priority.c --@@ -0,0 +1,18 @@ --+/* { dg-do compile } */ --+/* { dg-options "-O1" } */ --+ --+#include --+ --+int --+main (void) --+{ --+ __nds32__set_int_priority (NDS32_INT_H0, 0); --+ __nds32__set_int_priority (NDS32_INT_H15, 3); --+ __nds32__set_int_priority (NDS32_INT_H31, 3); --+ --+ int a = __nds32__get_int_priority (NDS32_INT_H0); --+ int b = __nds32__get_int_priority (NDS32_INT_H15); --+ int c = __nds32__get_int_priority (NDS32_INT_H31); --+ --+ return a + b + c; --+} --diff --git a/gcc/testsuite/gcc.target/nds32/compile/builtin-set-pending.c b/gcc/testsuite/gcc.target/nds32/compile/builtin-set-pending.c --new file mode 100644 --index 0000000..f10b83d ----- /dev/null --+++ b/gcc/testsuite/gcc.target/nds32/compile/builtin-set-pending.c --@@ -0,0 +1,10 @@ --+/* { dg-do compile } */ --+/* { dg-options "-O1" } */ --+ --+#include --+ --+int --+main (void) --+{ --+ __nds32__set_pending_swint (); --+} --diff --git a/gcc/testsuite/gcc.target/nds32/compile/builtin-set-trig-edge.c b/gcc/testsuite/gcc.target/nds32/compile/builtin-set-trig-edge.c --new file mode 100644 --index 0000000..bd8178c ----- /dev/null --+++ b/gcc/testsuite/gcc.target/nds32/compile/builtin-set-trig-edge.c --@@ -0,0 +1,13 @@ --+/* { dg-do compile } */ --+/* { dg-options "-O1" } */ --+ --+#include --+ --+void --+main (void) --+{ --+ __nds32__set_trig_type_edge (NDS32_INT_H0); --+ __nds32__set_trig_type_edge (NDS32_INT_H15); --+ __nds32__set_trig_type_edge (NDS32_INT_H16); --+ __nds32__set_trig_type_edge (NDS32_INT_H31); --+} --diff --git a/gcc/testsuite/gcc.target/nds32/compile/builtin-set-trig-level.c b/gcc/testsuite/gcc.target/nds32/compile/builtin-set-trig-level.c --new file mode 100644 --index 0000000..1780543 ----- /dev/null --+++ b/gcc/testsuite/gcc.target/nds32/compile/builtin-set-trig-level.c --@@ -0,0 +1,13 @@ --+/* { dg-do compile } */ --+/* { dg-options "-O1" } */ --+ --+#include --+ --+void --+main (void) --+{ --+ __nds32__set_trig_type_level (NDS32_INT_H0); --+ __nds32__set_trig_type_level (NDS32_INT_H15); --+ __nds32__set_trig_type_level (NDS32_INT_H16); --+ __nds32__set_trig_type_level (NDS32_INT_H31); --+} --diff --git a/gcc/testsuite/gcc.target/nds32/compile/builtin-setgie-dis.c b/gcc/testsuite/gcc.target/nds32/compile/builtin-setgie-dis.c --new file mode 100644 --index 0000000..e143d3f ----- /dev/null --+++ b/gcc/testsuite/gcc.target/nds32/compile/builtin-setgie-dis.c --@@ -0,0 +1,13 @@ --+/* Verify that we generate setgie.d instruction with builtin function. */ --+ --+/* { dg-do compile } */ --+/* { dg-options "-O0" } */ --+/* { dg-final { scan-assembler "\\tsetgie.d" } } */ --+ --+#include --+ --+void --+test (void) --+{ --+ __nds32__setgie_dis (); --+} --diff --git a/gcc/testsuite/gcc.target/nds32/compile/builtin-setgie-en.c b/gcc/testsuite/gcc.target/nds32/compile/builtin-setgie-en.c --new file mode 100644 --index 0000000..ed95782 ----- /dev/null --+++ b/gcc/testsuite/gcc.target/nds32/compile/builtin-setgie-en.c --@@ -0,0 +1,13 @@ --+/* Verify that we generate setgie.e instruction with builtin function. */ --+ --+/* { dg-do compile */ --+/* { dg-options "-O0" } */ --+/* { dg-final { scan-assembler "\\tsetgie.e" } } */ --+ --+#include --+ --+void --+test (void) --+{ --+ __nds32__setgie_en (); --+} --diff --git a/gcc/testsuite/gcc.target/nds32/compile/builtin-stura-add16.c b/gcc/testsuite/gcc.target/nds32/compile/builtin-stura-add16.c --new file mode 100644 --index 0000000..49fca46 ----- /dev/null --+++ b/gcc/testsuite/gcc.target/nds32/compile/builtin-stura-add16.c --@@ -0,0 +1,22 @@ --+/* { dg-do compile } */ --+/* { dg-options "-mext-dsp" } */ --+/* { dg-final { scan-assembler "kadd16" } } */ --+/* { dg-final { scan-assembler "kadd16" } } */ --+/* { dg-final { scan-assembler "ukadd16" } } */ --+/* { dg-final { scan-assembler "ukadd16" } } */ --+ --+#include --+ --+void --+test (void) --+{ --+ unsigned int r, a, b; --+ int16x2_t vr, va, vb; --+ uint16x2_t v_ur, v_ua, v_ub; --+ --+ r = __nds32__kadd16 (a, b); --+ vr = __nds32__v_kadd16 (va, vb); --+ --+ r = __nds32__ukadd16 (a, b); --+ v_ur = __nds32__v_ukadd16 (v_ua, v_ub); --+} --diff --git a/gcc/testsuite/gcc.target/nds32/compile/builtin-stura-add64.c b/gcc/testsuite/gcc.target/nds32/compile/builtin-stura-add64.c --new file mode 100644 --index 0000000..1f33a42 ----- /dev/null --+++ b/gcc/testsuite/gcc.target/nds32/compile/builtin-stura-add64.c --@@ -0,0 +1,17 @@ --+/* { dg-do compile } */ --+/* { dg-options "-mext-dsp" } */ --+/* { dg-final { scan-assembler "kadd64" } } */ --+/* { dg-final { scan-assembler "ukadd64" } } */ --+ --+#include --+ --+void --+test (void) --+{ --+ long long r, a, b; --+ unsigned long long ur, ua, ub; --+ --+ r = __nds32__kadd64 (a, b); --+ ur = __nds32__ukadd64 (ua, ub); --+ --+} --diff --git a/gcc/testsuite/gcc.target/nds32/compile/builtin-stura-add8.c b/gcc/testsuite/gcc.target/nds32/compile/builtin-stura-add8.c --new file mode 100644 --index 0000000..1f2d226 ----- /dev/null --+++ b/gcc/testsuite/gcc.target/nds32/compile/builtin-stura-add8.c --@@ -0,0 +1,22 @@ --+/* { dg-do compile } */ --+/* { dg-options "-mext-dsp" } */ --+/* { dg-final { scan-assembler "kadd8" } } */ --+/* { dg-final { scan-assembler "kadd8" } } */ --+/* { dg-final { scan-assembler "ukadd8" } } */ --+/* { dg-final { scan-assembler "ukadd8" } } */ --+ --+#include --+ --+void --+test (void) --+{ --+ unsigned int r, a, b; --+ int8x4_t vr, va, vb; --+ uint8x4_t v_ur, v_ua, v_ub; --+ --+ r = __nds32__kadd8 (a, b); --+ vr = __nds32__v_kadd8 (va, vb); --+ --+ r = __nds32__ukadd8 (a, b); --+ v_ur = __nds32__v_ukadd8 (v_ua, v_ub); --+} --diff --git a/gcc/testsuite/gcc.target/nds32/compile/builtin-stura-cras16.c b/gcc/testsuite/gcc.target/nds32/compile/builtin-stura-cras16.c --new file mode 100644 --index 0000000..89c7e6d ----- /dev/null --+++ b/gcc/testsuite/gcc.target/nds32/compile/builtin-stura-cras16.c --@@ -0,0 +1,22 @@ --+/* { dg-do compile } */ --+/* { dg-options "-mext-dsp" } */ --+/* { dg-final { scan-assembler "kcras16" } } */ --+/* { dg-final { scan-assembler "kcras16" } } */ --+/* { dg-final { scan-assembler "ukcras16" } } */ --+/* { dg-final { scan-assembler "ukcras16" } } */ --+ --+#include --+ --+void --+test (void) --+{ --+ unsigned int r, a, b; --+ int16x2_t vr, va, vb; --+ uint16x2_t v_ur, v_ua, v_ub; --+ --+ r = __nds32__kcras16 (a, b); --+ vr = __nds32__v_kcras16 (va, vb); --+ --+ r = __nds32__ukcras16 (a, b); --+ v_ur = __nds32__v_ukcras16 (v_ua, v_ub); --+} --diff --git a/gcc/testsuite/gcc.target/nds32/compile/builtin-stura-crsa16.c b/gcc/testsuite/gcc.target/nds32/compile/builtin-stura-crsa16.c --new file mode 100644 --index 0000000..beaa69a ----- /dev/null --+++ b/gcc/testsuite/gcc.target/nds32/compile/builtin-stura-crsa16.c --@@ -0,0 +1,22 @@ --+/* { dg-do compile } */ --+/* { dg-options "-mext-dsp" } */ --+/* { dg-final { scan-assembler "kcrsa16" } } */ --+/* { dg-final { scan-assembler "kcrsa16" } } */ --+/* { dg-final { scan-assembler "ukcrsa16" } } */ --+/* { dg-final { scan-assembler "ukcrsa16" } } */ --+ --+#include --+ --+void --+test (void) --+{ --+ unsigned int r, a, b; --+ int16x2_t vr, va, vb; --+ uint16x2_t v_ur, v_ua, v_ub; --+ --+ r = __nds32__kcrsa16 (a, b); --+ vr = __nds32__v_kcrsa16 (va, vb); --+ --+ r = __nds32__ukcrsa16 (a, b); --+ v_ur = __nds32__v_ukcrsa16 (v_ua, v_ub); --+} --diff --git a/gcc/testsuite/gcc.target/nds32/compile/builtin-stura-kabs8.c b/gcc/testsuite/gcc.target/nds32/compile/builtin-stura-kabs8.c --new file mode 100644 --index 0000000..de2e3c3 ----- /dev/null --+++ b/gcc/testsuite/gcc.target/nds32/compile/builtin-stura-kabs8.c --@@ -0,0 +1,16 @@ --+/* { dg-do compile } */ --+/* { dg-options "-mext-dsp" } */ --+/* { dg-final { scan-assembler "kabs8" } } */ --+/* { dg-final { scan-assembler "kabs8" } } */ --+ --+#include --+ --+void --+test (void) --+{ --+ unsigned int r, a; --+ int8x4_t vr, va; --+ --+ r = __nds32__kabs8 (a); --+ vr = __nds32__v_kabs8 (va); --+} --diff --git a/gcc/testsuite/gcc.target/nds32/compile/builtin-stura-ksll.c b/gcc/testsuite/gcc.target/nds32/compile/builtin-stura-ksll.c --new file mode 100644 --index 0000000..316b10c ----- /dev/null --+++ b/gcc/testsuite/gcc.target/nds32/compile/builtin-stura-ksll.c --@@ -0,0 +1,16 @@ --+/* { dg-do compile } */ --+/* { dg-options "-mext-dsp" } */ --+/* { dg-final { scan-assembler "ksll" } } */ --+/* { dg-final { scan-assembler "kslli" } } */ --+ --+#include --+ --+void --+test (void) --+{ --+ int r, a; --+ unsigned int b; --+ --+ r = __nds32__ksll (a, b); --+ r = __nds32__ksll (a, 0); --+} --diff --git a/gcc/testsuite/gcc.target/nds32/compile/builtin-stura-ksll16.c b/gcc/testsuite/gcc.target/nds32/compile/builtin-stura-ksll16.c --new file mode 100644 --index 0000000..be9a08e ----- /dev/null --+++ b/gcc/testsuite/gcc.target/nds32/compile/builtin-stura-ksll16.c --@@ -0,0 +1,21 @@ --+/* { dg-do compile } */ --+/* { dg-options "-mext-dsp" } */ --+/* { dg-final { scan-assembler "ksll16" } } */ --+/* { dg-final { scan-assembler "ksll16" } } */ --+/* { dg-final { scan-assembler "kslli16" } } */ --+/* { dg-final { scan-assembler "kslli16" } } */ --+ --+#include --+ --+void --+test (void) --+{ --+ unsigned int r, a, b; --+ int16x2_t vr, va; --+ --+ r = __nds32__ksll16 (a, b); --+ vr = __nds32__v_ksll16 (va, b); --+ --+ r = __nds32__ksll16 (a, 0); --+ vr = __nds32__v_ksll16 (va, 0); --+} --diff --git a/gcc/testsuite/gcc.target/nds32/compile/builtin-stura-kslrawu.c b/gcc/testsuite/gcc.target/nds32/compile/builtin-stura-kslrawu.c --new file mode 100644 --index 0000000..4eb03e5 ----- /dev/null --+++ b/gcc/testsuite/gcc.target/nds32/compile/builtin-stura-kslrawu.c --@@ -0,0 +1,14 @@ --+/* { dg-do compile } */ --+/* { dg-options "-mext-dsp" } */ --+/* { dg-final { scan-assembler "kslraw.u" } } */ --+ --+#include --+ --+void --+test (void) --+{ --+ int r, a; --+ unsigned int b; --+ --+ r = __nds32__kslraw_u (a, b); --+} --diff --git a/gcc/testsuite/gcc.target/nds32/compile/builtin-stura-mar64.c b/gcc/testsuite/gcc.target/nds32/compile/builtin-stura-mar64.c --new file mode 100644 --index 0000000..79a3eb3 ----- /dev/null --+++ b/gcc/testsuite/gcc.target/nds32/compile/builtin-stura-mar64.c --@@ -0,0 +1,16 @@ --+/* { dg-do compile } */ --+/* { dg-options "-mext-dsp" } */ --+/* { dg-final { scan-assembler "kmar64" } } */ --+/* { dg-final { scan-assembler "ukmar64" } } */ --+ --+#include --+ --+void --+test (void) --+{ --+ long long r, a, b; --+ unsigned long long ur, ua, ub; --+ --+ r = __nds32__kmar64 (r, a, b); --+ ur = __nds32__ukmar64 (ur, ua, ub); --+} --diff --git a/gcc/testsuite/gcc.target/nds32/compile/builtin-stura-misc16.c b/gcc/testsuite/gcc.target/nds32/compile/builtin-stura-misc16.c --new file mode 100644 --index 0000000..272e922 ----- /dev/null --+++ b/gcc/testsuite/gcc.target/nds32/compile/builtin-stura-misc16.c --@@ -0,0 +1,36 @@ --+/* { dg-do compile } */ --+/* { dg-options "-mext-dsp" } */ --+/* { dg-final { scan-assembler "sclip16" } } */ --+/* { dg-final { scan-assembler "sclip16" } } */ --+/* { dg-final { scan-assembler "uclip16" } } */ --+/* { dg-final { scan-assembler "uclip16" } } */ --+/* { dg-final { scan-assembler "khm16" } } */ --+/* { dg-final { scan-assembler "khm16" } } */ --+/* { dg-final { scan-assembler "khmx16" } } */ --+/* { dg-final { scan-assembler "khmx16" } } */ --+/* { dg-final { scan-assembler "kabs16" } } */ --+/* { dg-final { scan-assembler "kabs16" } } */ --+ --+#include --+ --+void --+test (void) --+{ --+ unsigned int r, a, b; --+ int16x2_t vr, va, vb; --+ --+ r = __nds32__sclip16 (a, 0); --+ vr = __nds32__v_sclip16 (va, 0); --+ --+ r = __nds32__uclip16 (a, 0); --+ vr = __nds32__v_uclip16 (va, 0); --+ --+ r = __nds32__khm16 (a, b); --+ vr = __nds32__v_khm16 (va, vb); --+ --+ r = __nds32__khmx16 (a, b); --+ vr = __nds32__v_khmx16 (va, vb); --+ --+ r = __nds32__kabs16 (a); --+ vr = __nds32__v_kabs16 (va); --+} --diff --git a/gcc/testsuite/gcc.target/nds32/compile/builtin-stura-msr64.c b/gcc/testsuite/gcc.target/nds32/compile/builtin-stura-msr64.c --new file mode 100644 --index 0000000..2ad64fa ----- /dev/null --+++ b/gcc/testsuite/gcc.target/nds32/compile/builtin-stura-msr64.c --@@ -0,0 +1,16 @@ --+/* { dg-do compile } */ --+/* { dg-options "-mext-dsp" } */ --+/* { dg-final { scan-assembler "kmsr64" } } */ --+/* { dg-final { scan-assembler "ukmsr64" } } */ --+ --+#include --+ --+void --+test (void) --+{ --+ long long r, a, b; --+ unsigned long long ur, ua, ub; --+ --+ r = __nds32__kmsr64 (r, a, b); --+ ur = __nds32__ukmsr64 (ur, ua, ub); --+} --diff --git a/gcc/testsuite/gcc.target/nds32/compile/builtin-stura-msw16.c b/gcc/testsuite/gcc.target/nds32/compile/builtin-stura-msw16.c --new file mode 100644 --index 0000000..d7ccecb ----- /dev/null --+++ b/gcc/testsuite/gcc.target/nds32/compile/builtin-stura-msw16.c --@@ -0,0 +1,32 @@ --+/* { dg-do compile } */ --+/* { dg-options "-mext-dsp" } */ --+/* { dg-final { scan-assembler "kmmawb" } } */ --+/* { dg-final { scan-assembler "kmmawb" } } */ --+/* { dg-final { scan-assembler "kmmawb.u" } } */ --+/* { dg-final { scan-assembler "kmmawb.u" } } */ --+/* { dg-final { scan-assembler "kmmawt" } } */ --+/* { dg-final { scan-assembler "kmmawt" } } */ --+/* { dg-final { scan-assembler "kmmawt.u" } } */ --+/* { dg-final { scan-assembler "kmmawt.u" } } */ --+ --+#include --+ --+void --+test (void) --+{ --+ int r, a; --+ unsigned int b; --+ int16x2_t vb; --+ --+ r = __nds32__kmmawb (r, a, b); --+ r = __nds32__v_kmmawb (r, a, vb); --+ --+ r = __nds32__kmmawb_u (r, a, b); --+ r = __nds32__v_kmmawb_u (r, a, vb); --+ --+ r = __nds32__kmmawt (r, a, b); --+ r = __nds32__v_kmmawt (r, a, vb); --+ --+ r = __nds32__kmmawt_u (r, a, b); --+ r = __nds32__v_kmmawt_u (r, a, vb); --+} --diff --git a/gcc/testsuite/gcc.target/nds32/compile/builtin-stura-msw32.c b/gcc/testsuite/gcc.target/nds32/compile/builtin-stura-msw32.c --new file mode 100644 --index 0000000..64d8d4a ----- /dev/null --+++ b/gcc/testsuite/gcc.target/nds32/compile/builtin-stura-msw32.c --@@ -0,0 +1,24 @@ --+/* { dg-do compile } */ --+/* { dg-options "-mext-dsp" } */ --+/* { dg-final { scan-assembler "kmmac" } } */ --+/* { dg-final { scan-assembler "kmmac.u" } } */ --+/* { dg-final { scan-assembler "kmmsb" } } */ --+/* { dg-final { scan-assembler "kmmsb.u" } } */ --+/* { dg-final { scan-assembler "kwmmul" } } */ --+/* { dg-final { scan-assembler "kwmmul.u" } } */ --+ --+#include --+ --+void --+test (void) --+{ --+ int r, a, b; --+ r = __nds32__kmmac (r, a, b); --+ r = __nds32__kmmac_u (r, a, b); --+ --+ r = __nds32__kmmsb (r, a, b); --+ r = __nds32__kmmsb_u (r, a, b); --+ --+ r = __nds32__kwmmul (a, b); --+ r = __nds32__kwmmul_u (a, b); --+} --diff --git a/gcc/testsuite/gcc.target/nds32/compile/builtin-stura-smul16x32.c b/gcc/testsuite/gcc.target/nds32/compile/builtin-stura-smul16x32.c --new file mode 100644 --index 0000000..0d2b87f ----- /dev/null --+++ b/gcc/testsuite/gcc.target/nds32/compile/builtin-stura-smul16x32.c --@@ -0,0 +1,72 @@ --+/* { dg-do compile } */ --+/* { dg-options "-mext-dsp" } */ --+/* { dg-final { scan-assembler "kmda" } } */ --+/* { dg-final { scan-assembler "kmda" } } */ --+/* { dg-final { scan-assembler "kmxda" } } */ --+/* { dg-final { scan-assembler "kmxda" } } */ --+/* { dg-final { scan-assembler "kmabb" } } */ --+/* { dg-final { scan-assembler "kmabb" } } */ --+/* { dg-final { scan-assembler "kmabt" } } */ --+/* { dg-final { scan-assembler "kmabt" } } */ --+/* { dg-final { scan-assembler "kmatt" } } */ --+/* { dg-final { scan-assembler "kmatt" } } */ --+/* { dg-final { scan-assembler "kmada" } } */ --+/* { dg-final { scan-assembler "kmada" } } */ --+/* { dg-final { scan-assembler "kmaxda" } } */ --+/* { dg-final { scan-assembler "kmaxda" } } */ --+/* { dg-final { scan-assembler "kmads" } } */ --+/* { dg-final { scan-assembler "kmads" } } */ --+/* { dg-final { scan-assembler "kmadrs" } } */ --+/* { dg-final { scan-assembler "kmadrs" } } */ --+/* { dg-final { scan-assembler "kmaxds" } } */ --+/* { dg-final { scan-assembler "kmaxds" } } */ --+/* { dg-final { scan-assembler "kmsda" } } */ --+/* { dg-final { scan-assembler "kmsda" } } */ --+/* { dg-final { scan-assembler "kmsxda" } } */ --+/* { dg-final { scan-assembler "kmsxda" } } */ --+ --+#include --+ --+void --+test (void) --+{ --+ int r; --+ unsigned int a, b; --+ int16x2_t va, vb; --+ --+ r = __nds32__kmda (a, b); --+ r = __nds32__v_kmda (va, vb); --+ --+ r = __nds32__kmxda (a, b); --+ r = __nds32__v_kmxda (va, vb); --+ --+ r = __nds32__kmabb (r, a, b); --+ r = __nds32__v_kmabb (r, va, vb); --+ --+ r = __nds32__kmabt (r, a, b); --+ r = __nds32__v_kmabt (r, va, vb); --+ --+ r = __nds32__kmatt (r, a, b); --+ r = __nds32__v_kmatt (r, va, vb); --+ --+ r = __nds32__kmada (r, a, b); --+ r = __nds32__v_kmada (r, va, vb); --+ --+ r = __nds32__kmaxda (r, a, b); --+ r = __nds32__v_kmaxda (r, va, vb); --+ --+ r = __nds32__kmads (r, a, b); --+ r = __nds32__v_kmads (r, va, vb); --+ --+ r = __nds32__kmadrs (r, a, b); --+ r = __nds32__v_kmadrs (r, va, vb); --+ --+ r = __nds32__kmaxds (r, a, b); --+ r = __nds32__v_kmaxds (r, va, vb); --+ --+ r = __nds32__kmsda (r, a, b); --+ r = __nds32__v_kmsda (r, va, vb); --+ --+ r = __nds32__kmsxda (r, a, b); --+ r = __nds32__v_kmsxda (r, va, vb); --+} --diff --git a/gcc/testsuite/gcc.target/nds32/compile/builtin-stura-sub16.c b/gcc/testsuite/gcc.target/nds32/compile/builtin-stura-sub16.c --new file mode 100644 --index 0000000..ecea7bb ----- /dev/null --+++ b/gcc/testsuite/gcc.target/nds32/compile/builtin-stura-sub16.c --@@ -0,0 +1,22 @@ --+/* { dg-do compile } */ --+/* { dg-options "-mext-dsp" } */ --+/* { dg-final { scan-assembler "ksub16" } } */ --+/* { dg-final { scan-assembler "ksub16" } } */ --+/* { dg-final { scan-assembler "uksub16" } } */ --+/* { dg-final { scan-assembler "uksub16" } } */ --+ --+#include --+ --+void --+test (void) --+{ --+ unsigned int r, a, b; --+ int16x2_t vr, va, vb; --+ uint16x2_t v_ur, v_ua, v_ub; --+ --+ r = __nds32__ksub16 (a, b); --+ vr = __nds32__v_ksub16 (va, vb); --+ --+ r = __nds32__uksub16 (a, b); --+ v_ur = __nds32__v_uksub16 (v_ua, v_ub); --+} --diff --git a/gcc/testsuite/gcc.target/nds32/compile/builtin-stura-sub64.c b/gcc/testsuite/gcc.target/nds32/compile/builtin-stura-sub64.c --new file mode 100644 --index 0000000..fae30e9 ----- /dev/null --+++ b/gcc/testsuite/gcc.target/nds32/compile/builtin-stura-sub64.c --@@ -0,0 +1,17 @@ --+/* { dg-do compile } */ --+/* { dg-options "-mext-dsp" } */ --+/* { dg-final { scan-assembler "ksub64" } } */ --+/* { dg-final { scan-assembler "uksub64" } } */ --+ --+#include --+ --+void --+test (void) --+{ --+ long long r, a, b; --+ unsigned long long ur, ua, ub; --+ --+ r = __nds32__ksub64 (a, b); --+ ur = __nds32__uksub64 (ua, ub); --+ --+} --diff --git a/gcc/testsuite/gcc.target/nds32/compile/builtin-stura-sub8.c b/gcc/testsuite/gcc.target/nds32/compile/builtin-stura-sub8.c --new file mode 100644 --index 0000000..5e343e9 ----- /dev/null --+++ b/gcc/testsuite/gcc.target/nds32/compile/builtin-stura-sub8.c --@@ -0,0 +1,22 @@ --+/* { dg-do compile } */ --+/* { dg-options "-mext-dsp" } */ --+/* { dg-final { scan-assembler "ksub8" } } */ --+/* { dg-final { scan-assembler "ksub8" } } */ --+/* { dg-final { scan-assembler "uksub8" } } */ --+/* { dg-final { scan-assembler "uksub8" } } */ --+ --+#include --+ --+void --+test (void) --+{ --+ unsigned int r, a, b; --+ int8x4_t vr, va, vb; --+ uint8x4_t v_ur, v_ua, v_ub; --+ --+ r = __nds32__ksub8 (a, b); --+ vr = __nds32__v_ksub8 (va, vb); --+ --+ r = __nds32__uksub8 (a, b); --+ v_ur = __nds32__v_uksub8 (v_ua, v_ub); --+} --diff --git a/gcc/testsuite/gcc.target/nds32/compile/builtin-unaligned-feature.c b/gcc/testsuite/gcc.target/nds32/compile/builtin-unaligned-feature.c --new file mode 100644 --index 0000000..6199109 ----- /dev/null --+++ b/gcc/testsuite/gcc.target/nds32/compile/builtin-unaligned-feature.c --@@ -0,0 +1,13 @@ --+/* { dg-do compile } */ --+/* { dg-options "-O1" } */ --+ --+#include --+ --+int --+main () --+{ --+ unsigned unalign = __nds32__unaligned_feature (); --+ __nds32__enable_unaligned (); --+ __nds32__disable_unaligned (); --+ return unalign; --+} --diff --git a/gcc/testsuite/gcc.target/nds32/compile/dsp-add-sub.c b/gcc/testsuite/gcc.target/nds32/compile/dsp-add-sub.c --new file mode 100644 --index 0000000..704610e ----- /dev/null --+++ b/gcc/testsuite/gcc.target/nds32/compile/dsp-add-sub.c --@@ -0,0 +1,47 @@ --+/* { dg-do compile } */ --+/* { dg-options "-O2 -mext-dsp" } */ --+/* { dg-final { scan-assembler "add8" } } */ --+/* { dg-final { scan-assembler "add16" } } */ --+/* { dg-final { scan-assembler "add64" } } */ --+/* { dg-final { scan-assembler "sub8" } } */ --+/* { dg-final { scan-assembler "sub16" } } */ --+/* { dg-final { scan-assembler "sub64" } } */ --+ --+typedef signed char v4qi __attribute__ ((vector_size (4))); --+typedef short v2hi __attribute__ ((vector_size (4))); --+ --+v4qi __attribute__ ((noinline)) --+add8 (v4qi a, v4qi b) --+{ --+ return a + b; --+} --+ --+v4qi __attribute__ ((noinline)) --+sub8 (v4qi a, v4qi b) --+{ --+ return a - b; --+} --+ --+v2hi __attribute__ ((noinline)) --+add16 (v2hi a, v2hi b) --+{ --+ return a + b; --+} --+ --+v2hi __attribute__ ((noinline)) --+sub16 (v2hi a, v2hi b) --+{ --+ return a - b; --+} --+ --+long long --+add64 (long long a, long long b) --+{ --+ return a + b; --+} --+ --+long long --+sub64 (long long a, long long b) --+{ --+ return a - b; --+} --diff --git a/gcc/testsuite/gcc.target/nds32/compile/dsp-bpick.c b/gcc/testsuite/gcc.target/nds32/compile/dsp-bpick.c --new file mode 100644 --index 0000000..5f9d7de ----- /dev/null --+++ b/gcc/testsuite/gcc.target/nds32/compile/dsp-bpick.c --@@ -0,0 +1,8 @@ --+/* { dg-do compile } */ --+/* { dg-options "-O2 -mext-dsp" } */ --+/* { dg-final { scan-assembler "bpick" } } */ --+ --+int bpick(int a, int b, int mask) --+{ --+ return (a & mask) | (b & ~mask); --+} --diff --git a/gcc/testsuite/gcc.target/nds32/compile/dsp-mmul.c b/gcc/testsuite/gcc.target/nds32/compile/dsp-mmul.c --new file mode 100644 --index 0000000..5c9cdeb ----- /dev/null --+++ b/gcc/testsuite/gcc.target/nds32/compile/dsp-mmul.c --@@ -0,0 +1,12 @@ --+/* { dg-do compile } */ --+/* { dg-options "-O2 -mext-dsp" } */ --+/* { dg-final { scan-assembler "smmul" } } */ --+ --+typedef signed char v4qi __attribute__ ((vector_size (4))); --+typedef short v2hi __attribute__ ((vector_size (4))); --+ --+int smmul(int a, int b) --+{ --+ long long tmp = (long long)a * b; --+ return (int)((tmp >> 32) & 0xffffffffll); --+} --diff --git a/gcc/testsuite/gcc.target/nds32/compile/dsp-mulhisi.c b/gcc/testsuite/gcc.target/nds32/compile/dsp-mulhisi.c --new file mode 100644 --index 0000000..856530b ----- /dev/null --+++ b/gcc/testsuite/gcc.target/nds32/compile/dsp-mulhisi.c --@@ -0,0 +1,23 @@ --+/* { dg-do compile } */ --+/* { dg-options "-O2 -mext-dsp" } */ --+/* { dg-final { scan-assembler "smbb" } } */ --+/* { dg-final { scan-assembler "smbt" } } */ --+/* { dg-final { scan-assembler "smtt" } } */ --+ --+typedef signed char v4qi __attribute__ ((vector_size (4))); --+typedef short v2hi __attribute__ ((vector_size (4))); --+ --+int smbb(v2hi a, v2hi b) --+{ --+ return a[0] * b[0]; --+} --+ --+int smbt(v2hi a, v2hi b) --+{ --+ return a[0] * b[1]; --+} --+ --+int smtt(v2hi a, v2hi b) --+{ --+ return a[1] * b[1]; --+} --diff --git a/gcc/testsuite/gcc.target/nds32/compile/dsp-raddsub.c b/gcc/testsuite/gcc.target/nds32/compile/dsp-raddsub.c --new file mode 100644 --index 0000000..4817637 ----- /dev/null --+++ b/gcc/testsuite/gcc.target/nds32/compile/dsp-raddsub.c --@@ -0,0 +1,26 @@ --+/* { dg-do compile } */ --+/* { dg-options "-O2 -mext-dsp" } */ --+/* { dg-final { scan-assembler "raddw" } } */ --+/* { dg-final { scan-assembler "rsubw" } } */ --+/* { dg-final { scan-assembler "uraddw" } } */ --+/* { dg-final { scan-assembler "ursubw" } } */ --+ --+int raddw(int a, int b) --+{ --+ return (a + b) >> 1; --+} --+ --+int rsubw(int a, int b) --+{ --+ return (a - b) >> 1; --+} --+ --+unsigned uraddw(unsigned a, unsigned b) --+{ --+ return (a + b) >> 1; --+} --+ --+unsigned ursubw(unsigned a, unsigned b) --+{ --+ return (a - b) >> 1; --+} --diff --git a/gcc/testsuite/gcc.target/nds32/compile/dsp-smals.c b/gcc/testsuite/gcc.target/nds32/compile/dsp-smals.c --new file mode 100644 --index 0000000..f1dc684 ----- /dev/null --+++ b/gcc/testsuite/gcc.target/nds32/compile/dsp-smals.c --@@ -0,0 +1,30 @@ --+/* { dg-do compile } */ --+/* { dg-options "-O2 -mext-dsp" } */ --+/* { dg-final { scan-assembler "smalbb" } } */ --+/* { dg-final { scan-assembler "smalbt" } } */ --+/* { dg-final { scan-assembler "smaltt" } } */ --+/* { dg-final { scan-assembler "smal" } } */ --+ --+typedef signed char v4qi __attribute__ ((vector_size (4))); --+typedef short v2hi __attribute__ ((vector_size (4))); --+ --+ --+long long smalbb(long long acc, v2hi a, v2hi b) --+{ --+ return acc + a[0] * b[0]; --+} --+ --+long long smalbt(long long acc, v2hi a, v2hi b) --+{ --+ return acc + a[1] * b[0]; --+} --+ --+long long smaltt(long long acc, v2hi a, v2hi b) --+{ --+ return acc + a[1] * b[1]; --+} --+ --+long long smal(v2hi a, long long b) --+{ --+ return b + (long long)(a[0] * a[1]); --+} --diff --git a/gcc/testsuite/gcc.target/nds32/compile/dsp-smalxda.c b/gcc/testsuite/gcc.target/nds32/compile/dsp-smalxda.c --new file mode 100644 --index 0000000..2fe606b ----- /dev/null --+++ b/gcc/testsuite/gcc.target/nds32/compile/dsp-smalxda.c --@@ -0,0 +1,17 @@ --+/* { dg-do compile } */ --+/* { dg-options "-O2 -mext-dsp" } */ --+/* { dg-final { scan-assembler "smalxda" } } */ --+/* { dg-final { scan-assembler "smalxds" } } */ --+ --+typedef signed char v4qi __attribute__ ((vector_size (4))); --+typedef short v2hi __attribute__ ((vector_size (4))); --+ --+long long smalxda(long long acc, v2hi a, v2hi b) --+{ --+ return acc + (a[0] * b[1] + a[1] * b[0]); --+} --+ --+long long smalxds(long long acc, v2hi a, v2hi b) --+{ --+ return acc + (a[1] * b[0] - a[0] * b[1]); --+} --diff --git a/gcc/testsuite/gcc.target/nds32/compile/dsp-unpkd.c b/gcc/testsuite/gcc.target/nds32/compile/dsp-unpkd.c --new file mode 100644 --index 0000000..2de7107 ----- /dev/null --+++ b/gcc/testsuite/gcc.target/nds32/compile/dsp-unpkd.c --@@ -0,0 +1,79 @@ --+/* { dg-do compile } */ --+/* { dg-options "-O2 -mext-dsp" } */ --+/* { dg-final { scan-assembler "sunpkd810" } } */ --+/* { dg-final { scan-assembler "sunpkd820" } } */ --+/* { dg-final { scan-assembler "sunpkd830" } } */ --+/* { dg-final { scan-assembler "sunpkd831" } } */ --+/* { dg-final { scan-assembler "zunpkd810" } } */ --+/* { dg-final { scan-assembler "zunpkd820" } } */ --+/* { dg-final { scan-assembler "zunpkd830" } } */ --+/* { dg-final { scan-assembler "zunpkd831" } } */ --+ --+typedef signed char v4qi __attribute__ ((vector_size (4))); --+typedef short v2hi __attribute__ ((vector_size (4))); --+typedef unsigned char uv4qi __attribute__ ((vector_size (4))); --+typedef unsigned short uv2hi __attribute__ ((vector_size (4))); --+ --+v2hi sunpkd810(v4qi v) --+{ --+ v2hi ret; --+ ret[0] = v[0]; --+ ret[1] = v[1]; --+ return ret; --+} --+ --+v2hi sunpkd820(v4qi v) --+{ --+ v2hi ret; --+ ret[0] = v[0]; --+ ret[1] = v[2]; --+ return ret; --+} --+ --+v2hi sunpkd830(v4qi v) --+{ --+ v2hi ret; --+ ret[0] = v[0]; --+ ret[1] = v[3]; --+ return ret; --+} --+ --+v2hi sunpkd831(v4qi v) --+{ --+ v2hi ret; --+ ret[0] = v[1]; --+ ret[1] = v[3]; --+ return ret; --+} --+ --+uv2hi zunpkd810(uv4qi v) --+{ --+ uv2hi ret; --+ ret[0] = v[0]; --+ ret[1] = v[1]; --+ return ret; --+} --+ --+uv2hi zunpkd820(uv4qi v) --+{ --+ uv2hi ret; --+ ret[0] = v[0]; --+ ret[1] = v[2]; --+ return ret; --+} --+ --+uv2hi zunpkd830(uv4qi v) --+{ --+ uv2hi ret; --+ ret[0] = v[0]; --+ ret[1] = v[3]; --+ return ret; --+} --+ --+uv2hi zunpkd831(uv4qi v) --+{ --+ uv2hi ret; --+ ret[0] = v[1]; --+ ret[1] = v[3]; --+ return ret; --+} --diff --git a/gcc/testsuite/gcc.target/nds32/compile/scalbn-transform-1.c b/gcc/testsuite/gcc.target/nds32/compile/scalbn-transform-1.c --new file mode 100644 --index 0000000..d456fa5 ----- /dev/null --+++ b/gcc/testsuite/gcc.target/nds32/compile/scalbn-transform-1.c --@@ -0,0 +1,21 @@ --+/* Verify scalbn transform pass for normal case. */ --+ --+/* { dg-do compile } */ --+/* { dg-options "-O2 -fdump-tree-all -lm" } */ --+/* { dg-require-effective-target nds32_soft_fp } */ --+ --+float test_scalbnf (float x) --+{ --+ return x * 128; --+} --+ --+double test_scalbn (double x) --+{ --+ return x * 256; --+} --+ --+/* { dg-final { scan-tree-dump "(_\[0-9\]+) = __builtin_scalbnf \\(x_\[0-9\]+\\(D\\), 7\\);\\s*_\[0-9\]+ = \\(float\\) \\1;" "scalbn_transform" } } */ --+/* { dg-final { scan-tree-dump "(_\[0-9\]+) = __builtin_scalbn \\(x_\[0-9\]+\\(D\\), 8\\);\\s*_\[0-9\]+ = \\(double\\) \\1;" "scalbn_transform" } } */ --+/* { dg-final { scan-tree-dump-not " \\* 1.28e\\+2" "scalbn_transform" } } */ --+/* { dg-final { scan-tree-dump-not " \\* 2.56e\\+2" "scalbn_transform" } } */ --+/* { dg-final { cleanup-tree-dump "*" } } */ --diff --git a/gcc/testsuite/gcc.target/nds32/compile/scalbn-transform-2.c b/gcc/testsuite/gcc.target/nds32/compile/scalbn-transform-2.c --new file mode 100644 --index 0000000..480cf23 ----- /dev/null --+++ b/gcc/testsuite/gcc.target/nds32/compile/scalbn-transform-2.c --@@ -0,0 +1,14 @@ --+/* Verify scalbn transform pass for negative number case. */ --+ --+/* { dg-do compile } */ --+/* { dg-options "-O2 -fdump-tree-all" } */ --+/* { dg-require-effective-target nds32_soft_fp } */ --+ --+double test_neg_scalbn (double x) --+{ --+ return x * -8; --+} --+ --+/* { dg-final { scan-tree-dump "(_\[0-9\]+) = __builtin_scalbn \\(x_\[0-9\]+\\(D\\), 3\\);\\s*_\[0-9\]+ = -\\1;" "scalbn_transform" } } */ --+/* { dg-final { scan-tree-dump-not " \\* -8.0e\\+0" "scalbn_transform" } } */ --+/* { dg-final { cleanup-tree-dump "*" } } */ --diff --git a/gcc/testsuite/gcc.target/nds32/compile/scalbn-transform-3.c b/gcc/testsuite/gcc.target/nds32/compile/scalbn-transform-3.c --new file mode 100644 --index 0000000..256f31a ----- /dev/null --+++ b/gcc/testsuite/gcc.target/nds32/compile/scalbn-transform-3.c --@@ -0,0 +1,14 @@ --+/* Verify scalbn transform pass for negative-exponent case. */ --+ --+/* { dg-do compile } */ --+/* { dg-options "-O2 -fdump-tree-all" } */ --+/* { dg-require-effective-target nds32_soft_fp } */ --+ --+double test_neg_exp_scalbnf (double x) --+{ --+ return x * 0.0625; --+} --+ --+/* { dg-final { scan-tree-dump "(_\[0-9\]+) = __builtin_scalbn \\(x_\[0-9\]+\\(D\\), -4\\);\\s*_\[0-9\]+ = \\(double\\) \\1;" "scalbn_transform" } } */ --+/* { dg-final { scan-tree-dump-not " \\* 6.25e\\-2" "scalbn_transform" } } */ --+/* { dg-final { cleanup-tree-dump "*" } } */ --diff --git a/gcc/testsuite/gcc.target/nds32/compile/scalbn-transform-4.c b/gcc/testsuite/gcc.target/nds32/compile/scalbn-transform-4.c --new file mode 100644 --index 0000000..b6ba596 ----- /dev/null --+++ b/gcc/testsuite/gcc.target/nds32/compile/scalbn-transform-4.c --@@ -0,0 +1,52 @@ --+/* Verify scalbn transform pass for cases that can't be optimized. */ --+ --+/* { dg-do compile } */ --+/* { dg-options "-O2 -fdump-tree-all" } */ --+/* { dg-require-effective-target nds32_soft_fp } */ --+ --+#include "math.h" --+ --+double test_filter_condition_1 (double x) --+{ --+ return x * 0; --+} --+ --+double test_filter_condition_2 (double x) --+{ --+ return x * -0; --+} --+ --+double test_filter_condition_3 (double x) --+{ --+ return x * 485; --+} --+ --+double test_filter_condition_4 (double x) --+{ --+ return x * -85; --+} --+ --+double test_filter_condition_5 (double x) --+{ --+ return x * 0.12; --+} --+ --+double test_filter_condition_6 (double x) --+{ --+ return x * -INFINITY; --+} --+ --+double test_filter_condition_7 (double x) --+{ --+ return x * NAN; --+} --+ --+/* { dg-final { scan-tree-dump-times "x_\[0-9\]+\\(D\\) \\* 0.0" 2 "scalbn_transform" } } */ --+/* { dg-final { scan-tree-dump " \\* 4.85e\\+2" "scalbn_transform" } } */ --+/* { dg-final { scan-tree-dump " \\* -8.5e\\+1" "scalbn_transform" } } */ --+/* { dg-final { scan-tree-dump " \\* 1.19999" "scalbn_transform" } } */ --+/* { dg-final { scan-tree-dump " \\* -Inf" "scalbn_transform" } } */ --+/* { dg-final { scan-tree-dump " \\* Nan" "scalbn_transform" } } */ --+/* { dg-final { scan-tree-dump-not "__builtin_scalbn" "scalbn_transform" } } */ --+/* { dg-final { scan-tree-dump-times "No multiplication stmt is transformed" 7 "scalbn_transform" } } */ --+/* { dg-final { cleanup-tree-dump "*" } } */ --diff --git a/gcc/testsuite/gcc.target/nds32/compile/scalbn-transform-5.c b/gcc/testsuite/gcc.target/nds32/compile/scalbn-transform-5.c --new file mode 100644 --index 0000000..874170e ----- /dev/null --+++ b/gcc/testsuite/gcc.target/nds32/compile/scalbn-transform-5.c --@@ -0,0 +1,20 @@ --+/* Verify scalbn transform pass for bug 11424 case. */ --+ --+/* { dg-do compile } */ --+/* { dg-options "-O2 -fdump-tree-all" } */ --+/* { dg-require-effective-target nds32_soft_fp } */ --+ --+typedef float float32_t; --+float32_t test_case (float32_t *pIn) --+{ --+ float32_t in; --+ in = *pIn++; --+ in = (in * 128); --+ in += in > 0.0f ? 0.5f : -0.5f; --+ --+ return in; --+} --+ --+/* { dg-final { scan-tree-dump "(_\[0-9\]+) = __builtin_scalbnf \\(in_\[0-9\]+, 7\\);\\s*in_\[0-9\]+ = \\(float32_t\\) \\1;" "scalbn_transform" } } */ --+/* { dg-final { scan-tree-dump-not "in_\[0-9\]+ = in_\[0-9\]+ \\* 1.28e\\+2" "scalbn_transform" } } */ --+/* { dg-final { cleanup-tree-dump "*" } } */ --diff --git a/gcc/testsuite/gcc.target/nds32/dsp-v2hi-packing00.c b/gcc/testsuite/gcc.target/nds32/dsp-v2hi-packing00.c --new file mode 100644 --index 0000000..d1c61b7 ----- /dev/null --+++ b/gcc/testsuite/gcc.target/nds32/dsp-v2hi-packing00.c --@@ -0,0 +1,127 @@ --+/* { dg-do run } */ --+ --+#include --+ --+int16x2_t packing01(int16x2_t x, int16x2_t y) __attribute__ ((noinline)); --+int16x2_t packing01(int16x2_t x, int16x2_t y) --+{ --+ int16x2_t ret; --+ ret[0] = x[0]; --+ ret[1] = y[1]; --+ return ret; --+} --+ --+int16x2_t packing10(int16x2_t x, int16x2_t y) __attribute__ ((noinline)); --+int16x2_t packing10(int16x2_t x, int16x2_t y) --+{ --+ int16x2_t ret; --+ ret[0] = x[1]; --+ ret[1] = y[0]; --+ return ret; --+} --+ --+int16x2_t packing00(int16x2_t x, int16x2_t y) __attribute__ ((noinline)); --+int16x2_t packing00(int16x2_t x, int16x2_t y) --+{ --+ int16x2_t ret; --+ ret[0] = x[0]; --+ ret[1] = y[0]; --+ return ret; --+} --+ --+int16x2_t packing0cv0(int16x2_t x) __attribute__ ((noinline)); --+int16x2_t packing0cv0(int16x2_t x) --+{ --+ int16x2_t ret = {0, 0}; --+ ret[0] = x[0]; --+ return ret; --+} --+ --+int16x2_t packingcv00(int16x2_t x) __attribute__ ((noinline)); --+int16x2_t packingcv00(int16x2_t x) --+{ --+ int16x2_t ret = {0, 0}; --+ ret[1] = x[0]; --+ return ret; --+} --+ --+int16x2_t packing11(int16x2_t x, int16x2_t y) __attribute__ ((noinline)); --+int16x2_t packing11(int16x2_t x, int16x2_t y) --+{ --+ int16x2_t ret; --+ ret[0] = x[1]; --+ ret[1] = y[1]; --+ return ret; --+} --+int16x2_t packing1cv0(int16x2_t x) __attribute__ ((noinline)); --+int16x2_t packing1cv0(int16x2_t x) --+{ --+ int16x2_t ret = {0, 0}; --+ ret[0] = x[1]; --+ return ret; --+} --+ --+int16x2_t packingcv01(int16x2_t x) __attribute__ ((noinline)); --+int16x2_t packingcv01(int16x2_t x) --+{ --+ int16x2_t ret = {0, 0}; --+ ret[1] = x[1]; --+ return ret; --+} --+ --+int main() { --+ int16x2_t a = {0x11, 0x22}; --+ int16x2_t b = {0x33, 0x44}; --+ --+ int16x2_t ret00, ret01, ret10, ret11; --+ int16x2_t ret0cv0, retcv00, ret1cv0, retcv01; --+ ret00 = packing00 (a, b); --+ --+ if (ret00[0] != 0x11 --+ || ret00[1] != 0x33) --+ return 1; --+ --+ ret0cv0 = packing0cv0 (a); --+ --+ if (ret0cv0[0] != 0x11 --+ || ret0cv0[1] != 0) --+ return 1; --+ --+ retcv00 = packingcv00 (a); --+ --+ if (retcv00[0] != 0 --+ || retcv00[1] != 0x11) --+ return 1; --+ --+ ret11 = packing11 (a, b); --+ --+ if (ret11[0] != 0x22 --+ || ret11[1] != 0x44) --+ return 1; --+ --+ ret1cv0 = packing1cv0 (a); --+ --+ if (ret1cv0[0] != 0x22 --+ || ret1cv0[1] != 0) --+ return 1; --+ --+ retcv01 = packingcv01 (a); --+ --+ if (retcv01[0] != 0 --+ || retcv01[1] != 0x22) --+ return 1; --+ --+ ret01 = packing01 (a, b); --+ --+ if (ret01[0] != 0x11 --+ || ret01[1] != 0x44) --+ return 1; --+ --+ ret10 = packing10 (a, b); --+ --+ if (ret10[0] != 0x22 --+ || ret10[1] != 0x33) --+ return 1; --+ --+ return 0; --+} --diff --git a/gcc/testsuite/gcc.target/nds32/nds32.exp b/gcc/testsuite/gcc.target/nds32/nds32.exp --index 1c245f6..2f5a150 100644 ----- a/gcc/testsuite/gcc.target/nds32/nds32.exp --+++ b/gcc/testsuite/gcc.target/nds32/nds32.exp --@@ -38,8 +38,10 @@ if ![info exists DEFAULT_CFLAGS] then { -- dg-init -- -- # Main loop. ---dg-runtest [lsort [glob -nocomplain $srcdir/$subdir/*.\[cS\]]] \ --+dg-runtest [lsort [glob -nocomplain $srcdir/$subdir/compile/*.\[cS\]]] \ -- "" $DEFAULT_CFLAGS --+gcc-dg-runtest [lsort [glob -nocomplain $srcdir/$subdir/*.\[cS\]]] \ --+ "" "" -- -- # All done. -- dg-finish --diff --git a/gcc/testsuite/lib/target-supports.exp b/gcc/testsuite/lib/target-supports.exp --index f0f5ac4..5a9b57d 100644 ----- a/gcc/testsuite/lib/target-supports.exp --+++ b/gcc/testsuite/lib/target-supports.exp --@@ -487,6 +487,10 @@ proc check_effective_target_trampolines { } { -- || [istarget hppa64-hp-hpux11.23] } { -- return 0; -- } --+ if { [istarget nds32*-*-*] --+ && [check_effective_target_nds32_reduced_regs] } { --+ return 0; --+ } -- return 1 -- } -- --@@ -500,7 +504,7 @@ proc check_effective_target_keeps_null_pointer_checks { } { -- if [target_info exists keeps_null_pointer_checks] { -- return 1 -- } --- if { [istarget avr-*-*] } { --+ if { [istarget avr-*-*] || [istarget nds32*-*-elf] } { -- return 1; -- } -- return 0 --@@ -3597,6 +3601,125 @@ proc check_effective_target_arm_prefer_ldrd_strd { } { -- } "-O2 -mthumb" ] -- } -- --+# If board info says it only has 16M addressing space, return 0. --+# Otherwise, return 1. --+proc check_effective_target_nds32_full_addr_space { } { --+ if [board_info target exists addr16m] { --+ return 0 --+ } --+ return 1; --+} --+ --+# Return 1 if gp direct is enable by default. --+proc check_effective_target_nds32_gp_direct { } { --+ return [check_no_compiler_messages gp_direct object { --+ #ifdef __NDS32_GP_DIRECT__ --+ int dummy; --+ #else --+ #error no GP_DIRECT --+ #endif --+ }] --+} --+ --+# Return 1 if this is a nds32 target supporting -mext-perf. --+proc check_effective_target_nds32_ext_perf { } { --+ return [check_no_compiler_messages ext_perf object { --+ #ifdef __NDS32_EXT_PERF__ --+ int dummy; --+ #else --+ #error no EXT_PERF --+ #endif --+ }] --+} --+ --+# Return 1 if this is a nds32 target supporting -mext-perf2. --+proc check_effective_target_nds32_ext_perf2 { } { --+ return [check_no_compiler_messages ext_perf2 object { --+ #ifdef __NDS32_EXT_PERF2__ --+ int dummy; --+ #else --+ #error no EXT_PERF2 --+ #endif --+ }] --+} --+ --+# Return 1 if this is a nds32 target supporting -mext-string. --+proc check_effective_target_nds32_ext_string { } { --+ return [check_no_compiler_messages ext_string object { --+ #ifdef __NDS32_EXT_STRING__ --+ int dummy; --+ #else --+ #error no EXT_STRING --+ #endif --+ }] --+} --+ --+# Return 1 if this is a nds32 target supporting -mext-fpu-sp or -mext-fpu-dp. --+proc check_effective_target_nds32_ext_fpu { } { --+ return [check_no_compiler_messages ext_fpu object { --+ #if defined(__NDS32_EXT_FPU_SP__) || defined(__NDS32_EXT_FPU_DP__) --+ int dummy; --+ #else --+ #error no support FPU --+ #endif --+ }] --+} --+ --+# Return 1 if this is a nds32 target not supporting -mext-fpu-sp or -mext-fpu-dp. --+proc check_effective_target_nds32_soft_fp { } { --+ return [check_no_compiler_messages soft_fp object { --+ #if defined(__NDS32_EXT_FPU_SP__) || defined(__NDS32_EXT_FPU_DP__) --+ #error Hard FP --+ #else --+ int dummy; --+ #endif --+ }] --+} --+ --+# Return 1 if this is a nds32 target supporting -mext-fpu-sp. --+proc check_effective_target_nds32_ext_fpu_sp { } { --+ return [check_no_compiler_messages ext_fpu_sp object { --+ #ifdef __NDS32_EXT_FPU_SP__ --+ int dummy; --+ #else --+ #error no EXT_FPU_SP --+ #endif --+ }] --+} --+ --+# Return 1 if this is a nds32 target supporting -mext-fpu-dp. --+proc check_effective_target_nds32_ext_fpu_dp { } { --+ return [check_no_compiler_messages ext_fpu_dp object { --+ #ifdef __NDS32_EXT_FPU_DP__ --+ int dummy; --+ #else --+ #error no EXT_FPU_DP --+ #endif --+ }] --+} --+ --+# Return 1 if this is a nds32 target supporting -mreduced-regs. --+proc check_effective_target_nds32_reduced_regs { } { --+ return [check_no_compiler_messages reduced_regs object { --+ #ifdef __NDS32_REDUCED_REGS__ --+ int dummy; --+ #else --+ #error no REDUCED_REGS --+ #endif --+ }] --+} --+ --+# Return 1 if this is a nds32 target not supporting v3m ISA. --+proc check_effective_target_nds32_no_v3m { } { --+ return [check_no_compiler_messages no_v3m object { --+ #if !defined(__NDS32_BASELINE_V3M__) --+ int dummy; --+ #else --+ #error Support V3M ISA --+ #endif --+ }] --+} --+ -- # Return 1 if this is a PowerPC target supporting -meabi. -- -- proc check_effective_target_powerpc_eabi_ok { } { --@@ -6897,6 +7020,7 @@ proc check_effective_target_logical_op_short_circuit {} { -- || [istarget avr*-*-*] -- || [istarget crisv32-*-*] || [istarget cris-*-*] -- || [istarget mmix-*-*] --+ || [istarget nds32*-*-*] -- || [istarget s390*-*-*] -- || [istarget powerpc*-*-*] -- || [istarget nios2*-*-*] --diff --git a/gcc/tree-vrp.c b/gcc/tree-vrp.c --index 154df21..acd1a52 100644 ----- a/gcc/tree-vrp.c --+++ b/gcc/tree-vrp.c --@@ -9518,6 +9518,7 @@ simplify_cond_using_ranges (gcond *stmt) -- used for the comparison directly if we just massage the constant in the -- comparison. */ -- if (TREE_CODE (op0) == SSA_NAME --+ && has_single_use (op0) -- && TREE_CODE (op1) == INTEGER_CST) -- { -- gimple *def_stmt = SSA_NAME_DEF_STMT (op0); --diff --git a/libgcc/config.host b/libgcc/config.host --index 124f2ce..107ccb1 100644 ----- a/libgcc/config.host --+++ b/libgcc/config.host --@@ -946,6 +946,23 @@ msp430*-*-elf) -- tmake_file="$tm_file t-crtstuff t-fdpbit msp430/t-msp430" -- extra_parts="$extra_parts libmul_none.a libmul_16.a libmul_32.a libmul_f5.a" -- ;; --+nds32*-linux*) --+ # Basic makefile fragment and extra_parts for crt stuff. --+ # We also append c-isr library implementation. --+ tmake_file="${tmake_file} t-slibgcc-libgcc" --+ tmake_file="${tmake_file} nds32/t-nds32-glibc nds32/t-crtstuff t-softfp-sfdf t-softfp" --+ # The header file of defining MD_FALLBACK_FRAME_STATE_FOR. --+ md_unwind_header=nds32/linux-unwind.h --+ # Append library definition makefile fragment according to --with-nds32-lib=X setting. --+ case "${with_nds32_lib}" in --+ "" | glibc | uclibc ) --+ ;; --+ *) --+ echo "Cannot accept --with-nds32-lib=$with_nds32_lib, available values are: glibc uclibc" 1>&2 --+ exit 1 --+ ;; --+ esac --+ ;; -- nds32*-elf*) -- # Basic makefile fragment and extra_parts for crt stuff. -- # We also append c-isr library implementation. --@@ -959,9 +976,19 @@ nds32*-elf*) -- tmake_file="${tmake_file} nds32/t-nds32-newlib t-softfp-sfdf t-softfp" -- ;; -- mculib) --- # Append library definition makefile fragment t-nds32-mculib. --+ case "${with_arch}" in --+ "" | v2 | v2j | v3 | v3j | v3m) --+ # Append library definition makefile fragment t-nds32-mculib-generic. -- # The software floating point library is included in mculib. --- tmake_file="${tmake_file} nds32/t-nds32-mculib" --+ tmake_file="${tmake_file} nds32/t-nds32-mculib-generic" --+ ;; --+ v3f | v3s) --+ # Append library definition makefile fragment t-nds32-mculib-softfp. --+ # Append mculib do not support ABI2FP_PLUS, --+ # so using'soft-fp' software floating point make rule fragment provided by gcc. --+ tmake_file="${tmake_file} nds32/t-nds32-mculib-softfp t-softfp-sfdf t-softfp" --+ ;; --+ esac -- ;; -- *) -- echo "Cannot accept --with-nds32-lib=$with_nds32_lib, available values are: newlib mculib" 1>&2 --diff --git a/libgcc/config/nds32/crtzero.S b/libgcc/config/nds32/crtzero.S --deleted file mode 100644 --index 9898525..0000000 ----- a/libgcc/config/nds32/crtzero.S --+++ /dev/null --@@ -1,103 +0,0 @@ ---/* The startup code sample of Andes NDS32 cpu for GNU compiler --- Copyright (C) 2012-2016 Free Software Foundation, Inc. --- Contributed by Andes Technology Corporation. --- --- This file is part of GCC. --- --- GCC is free software; you can redistribute it and/or modify it --- under the terms of the GNU General Public License as published --- by the Free Software Foundation; either version 3, or (at your --- option) any later version. --- --- GCC is distributed in the hope that it will be useful, but WITHOUT --- ANY WARRANTY; without even the implied warranty of MERCHANTABILITY --- or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public --- License for more details. --- --- Under Section 7 of GPL version 3, you are granted additional --- permissions described in the GCC Runtime Library Exception, version --- 3.1, as published by the Free Software Foundation. --- --- You should have received a copy of the GNU General Public License and --- a copy of the GCC Runtime Library Exception along with this program; --- see the files COPYING3 and COPYING.RUNTIME respectively. If not, see --- . */ --- ---!!============================================================================== ---!! ---!! crtzero.S ---!! ---!! This is JUST A SAMPLE of nds32 startup code !! ---!! You can refer this content and implement ---!! the actual one in newlib/mculib. ---!! ---!!============================================================================== --- ---!!------------------------------------------------------------------------------ ---!! Jump to start up code ---!!------------------------------------------------------------------------------ --- .section .nds32_init, "ax" --- j _start --- ---!!------------------------------------------------------------------------------ ---!! Startup code implementation ---!!------------------------------------------------------------------------------ --- .section .text --- .global _start --- .weak _SDA_BASE_ --- .weak _FP_BASE_ --- .align 2 --- .func _start --- .type _start, @function ---_start: ---.L_fp_gp_lp_init: --- la $fp, _FP_BASE_ ! init $fp --- la $gp, _SDA_BASE_ ! init $gp for small data access --- movi $lp, 0 ! init $lp --- ---.L_stack_init: --- la $sp, _stack ! init $sp --- movi $r0, -8 ! align $sp to 8-byte (use 0xfffffff8) --- and $sp, $sp, $r0 ! align $sp to 8-byte (filter out lower 3-bit) --- ---.L_bss_init: --- ! clear BSS, this process can be 4 time faster if data is 4 byte aligned --- ! if so, use swi.p instead of sbi.p --- ! the related stuff are defined in linker script --- la $r0, _edata ! get the starting addr of bss --- la $r2, _end ! get ending addr of bss --- beq $r0, $r2, .L_call_main ! if no bss just do nothing --- movi $r1, 0 ! should be cleared to 0 ---.L_clear_bss: --- sbi.p $r1, [$r0], 1 ! Set 0 to bss --- bne $r0, $r2, .L_clear_bss ! Still bytes left to set --- ---!.L_stack_heap_check: ---! la $r0, _end ! init heap_end ---! s.w $r0, heap_end ! save it --- --- ---!.L_init_argc_argv: ---! ! argc/argv initialization if necessary; default implementation is in crt1.o ---! la $r9, _arg_init ! load address of _arg_init? ---! beqz $r9, .L4 ! has _arg_init? no, go check main() ---! addi $sp, $sp, -512 ! allocate space for command line + arguments ---! move $r6, $sp ! r6 = buffer addr of cmd line ---! move $r0, $r6 ! r0 = buffer addr of cmd line ---! syscall 6002 ! get cmd line ---! move $r0, $r6 ! r0 = buffer addr of cmd line ---! addi $r1, $r6, 256 ! r1 = argv ---! jral $r9 ! init argc/argv ---! addi $r1, $r6, 256 ! r1 = argv --- ---.L_call_main: --- ! call main() if main() is provided --- la $r15, main ! load address of main --- jral $r15 ! call main --- ---.L_terminate_program: --- syscall 0x1 ! use syscall 0x1 to terminate program --- .size _start, .-_start --- .end --- ---!! ------------------------------------------------------------------------ --diff --git a/libgcc/config/nds32/initfini.c b/libgcc/config/nds32/initfini.c --index 0aa33f5..34406f0 100644 ----- a/libgcc/config/nds32/initfini.c --+++ b/libgcc/config/nds32/initfini.c --@@ -25,6 +25,10 @@ -- see the files COPYING3 and COPYING.RUNTIME respectively. If not, see -- . */ -- --+#include --+/* Need header file for `struct object' type. */ --+#include "../libgcc/unwind-dw2-fde.h" --+ -- /* Declare a pointer to void function type. */ -- typedef void (*func_ptr) (void); -- --@@ -42,11 +46,59 @@ typedef void (*func_ptr) (void); -- refer to only the __CTOR_END__ symbol in crtfini.o and the __DTOR_LIST__ -- symbol in crtinit.o, where they are defined. */ -- ---static func_ptr __CTOR_LIST__[1] __attribute__ ((section (".ctors"))) --- = { (func_ptr) (-1) }; --+static func_ptr __CTOR_LIST__[1] __attribute__ ((section (".ctors"), used)) --+ = { (func_ptr) 0 }; --+ --+static func_ptr __DTOR_LIST__[1] __attribute__ ((section (".dtors"), used)) --+ = { (func_ptr) 0 }; --+ --+ --+#ifdef SUPPORT_UNWINDING_DWARF2 --+/* Preparation of exception handling with dwar2 mechanism registration. */ -- ---static func_ptr __DTOR_LIST__[1] __attribute__ ((section (".dtors"))) --- = { (func_ptr) (-1) }; --+asm ("\n\ --+ .section .eh_frame,\"aw\",@progbits\n\ --+ .global __EH_FRAME_BEGIN__\n\ --+ .type __EH_FRAME_BEGIN__, @object\n\ --+ .align 2\n\ --+__EH_FRAME_BEGIN__:\n\ --+ ! Beginning location of eh_frame section\n\ --+ .previous\n\ --+"); --+ --+extern func_ptr __EH_FRAME_BEGIN__[]; --+ --+ --+/* Note that the following two functions are going to be chained into --+ constructor and destructor list, repectively. So these two declarations --+ must be placed after __CTOR_LIST__ and __DTOR_LIST. */ --+extern void __nds32_register_eh(void) __attribute__((constructor, used)); --+extern void __nds32_deregister_eh(void) __attribute__((destructor, used)); --+ --+/* Register the exception handling table as the first constructor. */ --+void --+__nds32_register_eh (void) --+{ --+ static struct object object; --+ if (__register_frame_info) --+ __register_frame_info (__EH_FRAME_BEGIN__, &object); --+} --+ --+/* Unregister the exception handling table as a deconstructor. */ --+void --+__nds32_deregister_eh (void) --+{ --+ static int completed = 0; --+ --+ if (completed) --+ return; --+ --+ if (__deregister_frame_info) --+ __deregister_frame_info (__EH_FRAME_BEGIN__); --+ --+ completed = 1; --+} --+#endif -- -- /* Run all the global destructors on exit from the program. */ -- --@@ -63,7 +115,7 @@ static func_ptr __DTOR_LIST__[1] __attribute__ ((section (".dtors"))) -- same particular root executable or shared library file. */ -- -- static void __do_global_dtors (void) ---asm ("__do_global_dtors") __attribute__ ((section (".text"))); --+asm ("__do_global_dtors") __attribute__ ((section (".text"), used)); -- -- static void -- __do_global_dtors (void) --@@ -116,23 +168,37 @@ void *__dso_handle = 0; -- last, these words naturally end up at the very ends of the two lists -- contained in these two sections. */ -- ---static func_ptr __CTOR_END__[1] __attribute__ ((section (".ctors"))) --+static func_ptr __CTOR_END__[1] __attribute__ ((section (".ctors"), used)) -- = { (func_ptr) 0 }; -- ---static func_ptr __DTOR_END__[1] __attribute__ ((section (".dtors"))) --+static func_ptr __DTOR_END__[1] __attribute__ ((section (".dtors"), used)) -- = { (func_ptr) 0 }; -- --+#ifdef SUPPORT_UNWINDING_DWARF2 --+/* ZERO terminator in .eh_frame section. */ --+asm ("\n\ --+ .section .eh_frame,\"aw\",@progbits\n\ --+ .global __EH_FRAME_END__\n\ --+ .type __EH_FRAME_END__, @object\n\ --+ .align 2\n\ --+__EH_FRAME_END__:\n\ --+ ! End location of eh_frame section with ZERO terminator\n\ --+ .word 0\n\ --+ .previous\n\ --+"); --+#endif --+ -- /* Run all global constructors for the program. -- Note that they are run in reverse order. */ -- -- static void __do_global_ctors (void) ---asm ("__do_global_ctors") __attribute__ ((section (".text"))); --+asm ("__do_global_ctors") __attribute__ ((section (".text"), used)); -- -- static void -- __do_global_ctors (void) -- { -- func_ptr *p; --- for (p = __CTOR_END__ - 1; *p != (func_ptr) -1; p--) --+ for (p = __CTOR_END__ - 1; *p; p--) -- (*p) (); -- } -- --diff --git a/libgcc/config/nds32/isr-library/adj_intr_lvl.inc b/libgcc/config/nds32/isr-library/adj_intr_lvl.inc --index 3e978b4..a519df8 100644 ----- a/libgcc/config/nds32/isr-library/adj_intr_lvl.inc --+++ b/libgcc/config/nds32/isr-library/adj_intr_lvl.inc --@@ -26,13 +26,26 @@ -- .macro ADJ_INTR_LVL -- #if defined(NDS32_NESTED) /* Nested handler. */ -- mfsr $r3, $PSW --+ /* By substracting 1 from $PSW, we can lower PSW.INTL --+ and enable GIE simultaneously. */ -- addi $r3, $r3, #-0x1 --+ #if __NDS32_EXT_ZOL__ || __NDS32_EXT_DSP__ --+ ori $r3, $r3, 0x2000 /* Set PSW.AEN(b'13) */ --+ #endif -- mtsr $r3, $PSW -- #elif defined(NDS32_NESTED_READY) /* Nested ready handler. */ -- /* Save ipc and ipsw and lower INT level. */ -- mfsr $r3, $PSW -- addi $r3, $r3, #-0x2 --+ #if __NDS32_EXT_ZOL__ || __NDS32_EXT_DSP__ --+ ori $r3, $r3, 0x2000 /* Set PSW.AEN(b'13) */ --+ #endif -- mtsr $r3, $PSW -- #else /* Not nested handler. */ --+ #if __NDS32_EXT_ZOL__ || __NDS32_EXT_DSP__ --+ mfsr $r3, $PSW --+ ori $r3, $r3, 0x2000 /* Set PSW.AEN(b'13) */ --+ mtsr $r3, $PSW --+ #endif -- #endif -- .endm --diff --git a/libgcc/config/nds32/isr-library/excp_isr.S b/libgcc/config/nds32/isr-library/excp_isr.S --index 6179a98..f1a3b59 100644 ----- a/libgcc/config/nds32/isr-library/excp_isr.S --+++ b/libgcc/config/nds32/isr-library/excp_isr.S --@@ -23,6 +23,7 @@ -- see the files COPYING3 and COPYING.RUNTIME respectively. If not, see -- . */ -- --+#include "save_usr_regs.inc" -- #include "save_mac_regs.inc" -- #include "save_fpu_regs.inc" -- #include "save_fpu_regs_00.inc" --@@ -32,35 +33,33 @@ -- #include "save_all.inc" -- #include "save_partial.inc" -- #include "adj_intr_lvl.inc" ---#include "restore_mac_regs.inc" -- #include "restore_fpu_regs_00.inc" -- #include "restore_fpu_regs_01.inc" -- #include "restore_fpu_regs_02.inc" -- #include "restore_fpu_regs_03.inc" -- #include "restore_fpu_regs.inc" --+#include "restore_mac_regs.inc" --+#include "restore_usr_regs.inc" -- #include "restore_all.inc" -- #include "restore_partial.inc" --+ -- .section .nds32_isr, "ax" /* Put it in the section of 1st level handler. */ -- .align 1 ---/* --- First Level Handlers --- 1. First Level Handlers are invokded in vector section via jump instruction --- with specific names for different configurations. --- 2. Naming Format: _nds32_e_SR_NT for exception handlers. --- _nds32_i_SR_NT for interrupt handlers. --- 2.1 All upper case letters are replaced with specific lower case letters encodings. --- 2.2 SR: Saved Registers --- sa: Save All regs (context) --- ps: Partial Save (all caller-saved regs) --- 2.3 NT: Nested Type --- ns: nested --- nn: not nested --- nr: nested ready ---*/ --- ---/* --- This is original 16-byte vector size version. ---*/ --+ --+/* First Level Handlers --+ 1. First Level Handlers are invokded in vector section via jump instruction --+ with specific names for different configurations. --+ 2. Naming Format: _nds32_e_SR_NT for exception handlers. --+ _nds32_i_SR_NT for interrupt handlers. --+ 2.1 All upper case letters are replaced with specific lower case letters encodings. --+ 2.2 SR -- Saved Registers --+ sa: Save All regs (context) --+ ps: Partial Save (all caller-saved regs) --+ 2.3 NT -- Nested Type --+ ns: nested --+ nn: not nested --+ nr: nested ready */ --+ -- #ifdef NDS32_SAVE_ALL_REGS -- #if defined(NDS32_NESTED) -- .globl _nds32_e_sa_ns --@@ -91,21 +90,26 @@ _nds32_e_ps_nn: -- #endif /* endif for Nest Type */ -- #endif /* not NDS32_SAVE_ALL_REGS */ -- ---/* --- This is 16-byte vector size version. --- The vector id was restored into $r0 in vector by compiler. ---*/ --+ --+/* For 4-byte vector size version, the vector id is --+ extracted from $ITYPE and is set into $r0 by library. --+ For 16-byte vector size version, the vector id --+ is set into $r0 in vector section by compiler. */ --+ --+/* Save used registers. */ -- #ifdef NDS32_SAVE_ALL_REGS -- SAVE_ALL -- #else -- SAVE_PARTIAL -- #endif --+ -- /* Prepare to call 2nd level handler. */ -- la $r2, _nds32_jmptbl_00 -- lw $r2, [$r2 + $r0 << #2] -- ADJ_INTR_LVL /* Adjust INTR level. $r3 is clobbered. */ -- jral $r2 --- /* Restore used registers. */ --+ --+/* Restore used registers. */ -- #ifdef NDS32_SAVE_ALL_REGS -- RESTORE_ALL -- #else --@@ -113,6 +117,7 @@ _nds32_e_ps_nn: -- #endif -- iret -- --+ -- #ifdef NDS32_SAVE_ALL_REGS -- #if defined(NDS32_NESTED) -- .size _nds32_e_sa_ns, .-_nds32_e_sa_ns --diff --git a/libgcc/config/nds32/isr-library/excp_isr_4b.S b/libgcc/config/nds32/isr-library/excp_isr_4b.S --deleted file mode 100644 --index af70c7a..0000000 ----- a/libgcc/config/nds32/isr-library/excp_isr_4b.S --+++ /dev/null --@@ -1,133 +0,0 @@ ---/* c-isr library stuff of Andes NDS32 cpu for GNU compiler --- Copyright (C) 2012-2016 Free Software Foundation, Inc. --- Contributed by Andes Technology Corporation. --- --- This file is part of GCC. --- --- GCC is free software; you can redistribute it and/or modify it --- under the terms of the GNU General Public License as published --- by the Free Software Foundation; either version 3, or (at your --- option) any later version. --- --- GCC is distributed in the hope that it will be useful, but WITHOUT --- ANY WARRANTY; without even the implied warranty of MERCHANTABILITY --- or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public --- License for more details. --- --- Under Section 7 of GPL version 3, you are granted additional --- permissions described in the GCC Runtime Library Exception, version --- 3.1, as published by the Free Software Foundation. --- --- You should have received a copy of the GNU General Public License and --- a copy of the GCC Runtime Library Exception along with this program; --- see the files COPYING3 and COPYING.RUNTIME respectively. If not, see --- . */ --- ---#include "save_mac_regs.inc" ---#include "save_fpu_regs.inc" ---#include "save_fpu_regs_00.inc" ---#include "save_fpu_regs_01.inc" ---#include "save_fpu_regs_02.inc" ---#include "save_fpu_regs_03.inc" ---#include "save_all.inc" ---#include "save_partial.inc" ---#include "adj_intr_lvl.inc" ---#include "restore_mac_regs.inc" ---#include "restore_fpu_regs_00.inc" ---#include "restore_fpu_regs_01.inc" ---#include "restore_fpu_regs_02.inc" ---#include "restore_fpu_regs_03.inc" ---#include "restore_fpu_regs.inc" ---#include "restore_all.inc" ---#include "restore_partial.inc" --- .section .nds32_isr, "ax" /* Put it in the section of 1st level handler. */ --- .align 1 ---/* --- First Level Handlers --- 1. First Level Handlers are invokded in vector section via jump instruction --- with specific names for different configurations. --- 2. Naming Format: _nds32_e_SR_NT for exception handlers. --- _nds32_i_SR_NT for interrupt handlers. --- 2.1 All upper case letters are replaced with specific lower case letters encodings. --- 2.2 SR: Saved Registers --- sa: Save All regs (context) --- ps: Partial Save (all caller-saved regs) --- 2.3 NT: Nested Type --- ns: nested --- nn: not nested --- nr: nested ready ---*/ --- ---/* --- This is 4-byte vector size version. --- The "_4b" postfix was added for 4-byte version symbol. ---*/ ---#ifdef NDS32_SAVE_ALL_REGS ---#if defined(NDS32_NESTED) --- .globl _nds32_e_sa_ns_4b --- .type _nds32_e_sa_ns_4b, @function ---_nds32_e_sa_ns_4b: ---#elif defined(NDS32_NESTED_READY) --- .globl _nds32_e_sa_nr_4b --- .type _nds32_e_sa_nr_4b, @function ---_nds32_e_sa_nr_4b: ---#else /* Not nested handler. */ --- .globl _nds32_e_sa_nn_4b --- .type _nds32_e_sa_nn_4b, @function ---_nds32_e_sa_nn_4b: ---#endif /* endif for Nest Type */ ---#else /* not NDS32_SAVE_ALL_REGS */ ---#if defined(NDS32_NESTED) --- .globl _nds32_e_ps_ns_4b --- .type _nds32_e_ps_ns_4b, @function ---_nds32_e_ps_ns_4b: ---#elif defined(NDS32_NESTED_READY) --- .globl _nds32_e_ps_nr_4b --- .type _nds32_e_ps_nr_4b, @function ---_nds32_e_ps_nr_4b: ---#else /* Not nested handler. */ --- .globl _nds32_e_ps_nn_4b --- .type _nds32_e_ps_nn_4b, @function ---_nds32_e_ps_nn_4b: ---#endif /* endif for Nest Type */ ---#endif /* not NDS32_SAVE_ALL_REGS */ --- ---/* --- This is 4-byte vector size version. --- The vector id was restored into $lp in vector by compiler. ---*/ ---#ifdef NDS32_SAVE_ALL_REGS --- SAVE_ALL_4B ---#else --- SAVE_PARTIAL_4B ---#endif --- /* Prepare to call 2nd level handler. */ --- la $r2, _nds32_jmptbl_00 --- lw $r2, [$r2 + $r0 << #2] --- ADJ_INTR_LVL /* Adjust INTR level. $r3 is clobbered. */ --- jral $r2 --- /* Restore used registers. */ ---#ifdef NDS32_SAVE_ALL_REGS --- RESTORE_ALL ---#else --- RESTORE_PARTIAL ---#endif --- iret --- ---#ifdef NDS32_SAVE_ALL_REGS ---#if defined(NDS32_NESTED) --- .size _nds32_e_sa_ns_4b, .-_nds32_e_sa_ns_4b ---#elif defined(NDS32_NESTED_READY) --- .size _nds32_e_sa_nr_4b, .-_nds32_e_sa_nr_4b ---#else /* Not nested handler. */ --- .size _nds32_e_sa_nn_4b, .-_nds32_e_sa_nn_4b ---#endif /* endif for Nest Type */ ---#else /* not NDS32_SAVE_ALL_REGS */ ---#if defined(NDS32_NESTED) --- .size _nds32_e_ps_ns_4b, .-_nds32_e_ps_ns_4b ---#elif defined(NDS32_NESTED_READY) --- .size _nds32_e_ps_nr_4b, .-_nds32_e_ps_nr_4b ---#else /* Not nested handler. */ --- .size _nds32_e_ps_nn_4b, .-_nds32_e_ps_nn_4b ---#endif /* endif for Nest Type */ ---#endif /* not NDS32_SAVE_ALL_REGS */ --diff --git a/libgcc/config/nds32/isr-library/intr_isr.S b/libgcc/config/nds32/isr-library/intr_isr.S --index c55da1c..90c5c25 100644 ----- a/libgcc/config/nds32/isr-library/intr_isr.S --+++ b/libgcc/config/nds32/isr-library/intr_isr.S --@@ -23,6 +23,7 @@ -- see the files COPYING3 and COPYING.RUNTIME respectively. If not, see -- . */ -- --+#include "save_usr_regs.inc" -- #include "save_mac_regs.inc" -- #include "save_fpu_regs.inc" -- #include "save_fpu_regs_00.inc" --@@ -32,35 +33,33 @@ -- #include "save_all.inc" -- #include "save_partial.inc" -- #include "adj_intr_lvl.inc" ---#include "restore_mac_regs.inc" -- #include "restore_fpu_regs_00.inc" -- #include "restore_fpu_regs_01.inc" -- #include "restore_fpu_regs_02.inc" -- #include "restore_fpu_regs_03.inc" -- #include "restore_fpu_regs.inc" --+#include "restore_mac_regs.inc" --+#include "restore_usr_regs.inc" -- #include "restore_all.inc" -- #include "restore_partial.inc" --+ -- .section .nds32_isr, "ax" /* Put it in the section of 1st level handler. */ -- .align 1 ---/* --- First Level Handlers --- 1. First Level Handlers are invokded in vector section via jump instruction --- with specific names for different configurations. --- 2. Naming Format: _nds32_e_SR_NT for exception handlers. --- _nds32_i_SR_NT for interrupt handlers. --- 2.1 All upper case letters are replaced with specific lower case letters encodings. --- 2.2 SR: Saved Registers --- sa: Save All regs (context) --- ps: Partial Save (all caller-saved regs) --- 2.3 NT: Nested Type --- ns: nested --- nn: not nested --- nr: nested ready ---*/ --- ---/* --- This is original 16-byte vector size version. ---*/ --+ --+/* First Level Handlers --+ 1. First Level Handlers are invokded in vector section via jump instruction --+ with specific names for different configurations. --+ 2. Naming Format: _nds32_e_SR_NT for exception handlers. --+ _nds32_i_SR_NT for interrupt handlers. --+ 2.1 All upper case letters are replaced with specific lower case letters encodings. --+ 2.2 SR -- Saved Registers --+ sa: Save All regs (context) --+ ps: Partial Save (all caller-saved regs) --+ 2.3 NT -- Nested Type --+ ns: nested --+ nn: not nested --+ nr: nested ready */ --+ -- #ifdef NDS32_SAVE_ALL_REGS -- #if defined(NDS32_NESTED) -- .globl _nds32_i_sa_ns --@@ -91,21 +90,36 @@ _nds32_i_ps_nn: -- #endif /* endif for Nest Type */ -- #endif /* not NDS32_SAVE_ALL_REGS */ -- ---/* --- This is 16-byte vector size version. --- The vector id was restored into $r0 in vector by compiler. ---*/ --+ --+/* For 4-byte vector size version, the vector id is --+ extracted from $ITYPE and is set into $r0 by library. --+ For 16-byte vector size version, the vector id --+ is set into $r0 in vector section by compiler. */ --+ --+/* Save used registers first. */ -- #ifdef NDS32_SAVE_ALL_REGS -- SAVE_ALL -- #else -- SAVE_PARTIAL -- #endif --- /* Prepare to call 2nd level handler. */ --+ --+/* According to vector size, we need to have different implementation. */ --+#if __NDS32_ISR_VECTOR_SIZE_4__ --+ /* Prepare to call 2nd level handler. */ --+ la $r2, _nds32_jmptbl_00 --+ lw $r2, [$r2 + $r0 << #2] --+ addi $r0, $r0, #-9 /* Make interrput vector id zero-based. */ --+ ADJ_INTR_LVL /* Adjust INTR level. $r3 is clobbered. */ --+ jral $r2 --+#else /* not __NDS32_ISR_VECTOR_SIZE_4__ */ --+ /* Prepare to call 2nd level handler. */ -- la $r2, _nds32_jmptbl_09 /* For zero-based vcetor id. */ -- lw $r2, [$r2 + $r0 << #2] -- ADJ_INTR_LVL /* Adjust INTR level. $r3 is clobbered. */ -- jral $r2 --- /* Restore used registers. */ --+#endif /* not __NDS32_ISR_VECTOR_SIZE_4__ */ --+ --+/* Restore used registers. */ -- #ifdef NDS32_SAVE_ALL_REGS -- RESTORE_ALL -- #else --@@ -113,6 +127,7 @@ _nds32_i_ps_nn: -- #endif -- iret -- --+ -- #ifdef NDS32_SAVE_ALL_REGS -- #if defined(NDS32_NESTED) -- .size _nds32_i_sa_ns, .-_nds32_i_sa_ns --diff --git a/libgcc/config/nds32/isr-library/intr_isr_4b.S b/libgcc/config/nds32/isr-library/intr_isr_4b.S --deleted file mode 100644 --index d82c007..0000000 ----- a/libgcc/config/nds32/isr-library/intr_isr_4b.S --+++ /dev/null --@@ -1,134 +0,0 @@ ---/* c-isr library stuff of Andes NDS32 cpu for GNU compiler --- Copyright (C) 2012-2016 Free Software Foundation, Inc. --- Contributed by Andes Technology Corporation. --- --- This file is part of GCC. --- --- GCC is free software; you can redistribute it and/or modify it --- under the terms of the GNU General Public License as published --- by the Free Software Foundation; either version 3, or (at your --- option) any later version. --- --- GCC is distributed in the hope that it will be useful, but WITHOUT --- ANY WARRANTY; without even the implied warranty of MERCHANTABILITY --- or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public --- License for more details. --- --- Under Section 7 of GPL version 3, you are granted additional --- permissions described in the GCC Runtime Library Exception, version --- 3.1, as published by the Free Software Foundation. --- --- You should have received a copy of the GNU General Public License and --- a copy of the GCC Runtime Library Exception along with this program; --- see the files COPYING3 and COPYING.RUNTIME respectively. If not, see --- . */ --- ---#include "save_mac_regs.inc" ---#include "save_fpu_regs.inc" ---#include "save_fpu_regs_00.inc" ---#include "save_fpu_regs_01.inc" ---#include "save_fpu_regs_02.inc" ---#include "save_fpu_regs_03.inc" ---#include "save_all.inc" ---#include "save_partial.inc" ---#include "adj_intr_lvl.inc" ---#include "restore_mac_regs.inc" ---#include "restore_fpu_regs_00.inc" ---#include "restore_fpu_regs_01.inc" ---#include "restore_fpu_regs_02.inc" ---#include "restore_fpu_regs_03.inc" ---#include "restore_fpu_regs.inc" ---#include "restore_all.inc" ---#include "restore_partial.inc" --- .section .nds32_isr, "ax" /* Put it in the section of 1st level handler. */ --- .align 1 ---/* --- First Level Handlers --- 1. First Level Handlers are invokded in vector section via jump instruction --- with specific names for different configurations. --- 2. Naming Format: _nds32_e_SR_NT for exception handlers. --- _nds32_i_SR_NT for interrupt handlers. --- 2.1 All upper case letters are replaced with specific lower case letters encodings. --- 2.2 SR: Saved Registers --- sa: Save All regs (context) --- ps: Partial Save (all caller-saved regs) --- 2.3 NT: Nested Type --- ns: nested --- nn: not nested --- nr: nested ready ---*/ --- ---/* --- This is 4-byte vector size version. --- The "_4b" postfix was added for 4-byte version symbol. ---*/ ---#ifdef NDS32_SAVE_ALL_REGS ---#if defined(NDS32_NESTED) --- .globl _nds32_i_sa_ns_4b --- .type _nds32_i_sa_ns_4b, @function ---_nds32_i_sa_ns_4b: ---#elif defined(NDS32_NESTED_READY) --- .globl _nds32_i_sa_nr_4b --- .type _nds32_i_sa_nr_4b, @function ---_nds32_i_sa_nr_4b: ---#else /* Not nested handler. */ --- .globl _nds32_i_sa_nn_4b --- .type _nds32_i_sa_nn_4b, @function ---_nds32_i_sa_nn_4b: ---#endif /* endif for Nest Type */ ---#else /* not NDS32_SAVE_ALL_REGS */ ---#if defined(NDS32_NESTED) --- .globl _nds32_i_ps_ns_4b --- .type _nds32_i_ps_ns_4b, @function ---_nds32_i_ps_ns_4b: ---#elif defined(NDS32_NESTED_READY) --- .globl _nds32_i_ps_nr_4b --- .type _nds32_i_ps_nr_4b, @function ---_nds32_i_ps_nr_4b: ---#else /* Not nested handler. */ --- .globl _nds32_i_ps_nn_4b --- .type _nds32_i_ps_nn_4b, @function ---_nds32_i_ps_nn_4b: ---#endif /* endif for Nest Type */ ---#endif /* not NDS32_SAVE_ALL_REGS */ --- ---/* --- This is 4-byte vector size version. --- The vector id was restored into $lp in vector by compiler. ---*/ ---#ifdef NDS32_SAVE_ALL_REGS --- SAVE_ALL_4B ---#else --- SAVE_PARTIAL_4B ---#endif --- /* Prepare to call 2nd level handler. */ --- la $r2, _nds32_jmptbl_00 --- lw $r2, [$r2 + $r0 << #2] --- addi $r0, $r0, #-9 /* Make interrput vector id zero-based. */ --- ADJ_INTR_LVL /* Adjust INTR level. $r3 is clobbered. */ --- jral $r2 --- /* Restore used registers. */ ---#ifdef NDS32_SAVE_ALL_REGS --- RESTORE_ALL ---#else --- RESTORE_PARTIAL ---#endif --- iret --- ---#ifdef NDS32_SAVE_ALL_REGS ---#if defined(NDS32_NESTED) --- .size _nds32_i_sa_ns_4b, .-_nds32_i_sa_ns_4b ---#elif defined(NDS32_NESTED_READY) --- .size _nds32_i_sa_nr_4b, .-_nds32_i_sa_nr_4b ---#else /* Not nested handler. */ --- .size _nds32_i_sa_nn_4b, .-_nds32_i_sa_nn_4b ---#endif /* endif for Nest Type */ ---#else /* not NDS32_SAVE_ALL_REGS */ ---#if defined(NDS32_NESTED) --- .size _nds32_i_ps_ns_4b, .-_nds32_i_ps_ns_4b ---#elif defined(NDS32_NESTED_READY) --- .size _nds32_i_ps_nr_4b, .-_nds32_i_ps_nr_4b ---#else /* Not nested handler. */ --- .size _nds32_i_ps_nn_4b, .-_nds32_i_ps_nn_4b ---#endif /* endif for Nest Type */ ---#endif /* not NDS32_SAVE_ALL_REGS */ --diff --git a/libgcc/config/nds32/isr-library/reset.S b/libgcc/config/nds32/isr-library/reset.S --index 961d731..8b9ccf5 100644 ----- a/libgcc/config/nds32/isr-library/reset.S --+++ b/libgcc/config/nds32/isr-library/reset.S --@@ -26,22 +26,18 @@ -- .section .nds32_isr, "ax" /* Put it in the section of 1st level handler. */ -- .align 1 -- .weak _SDA_BASE_ /* For reset handler only. */ --- .weak _FP_BASE_ /* For reset handler only. */ -- .weak _nds32_init_mem /* User defined memory initialization function. */ -- .globl _start -- .globl _nds32_reset -- .type _nds32_reset, @function -- _nds32_reset: -- _start: ---#ifdef NDS32_EXT_EX9 --- .no_ex9_begin ---#endif -- /* Handle NMI and warm boot if any of them exists. */ -- beqz $sp, 1f /* Reset, NMI or warm boot? */ -- /* Either NMI or warm boot; save all regs. */ -- -- /* Preserve registers for context-switching. */ ---#ifdef __NDS32_REDUCED_REGS__ --+#if __NDS32_REDUCED_REGS__ || __NDS32_REDUCE_REGS -- /* For 16-reg mode. */ -- smw.adm $r0, [$sp], $r10, #0x0 -- smw.adm $r15, [$sp], $r15, #0xf --@@ -49,10 +45,9 @@ _start: -- /* For 32-reg mode. */ -- smw.adm $r0, [$sp], $r27, #0xf -- #endif ---#ifdef NDS32_EXT_IFC --+#if __NDS32_EXT_IFC__ -- mfusr $r1, $IFC_LP --- smw.adm $r1, [$sp], $r2, #0x0 /* Save extra $r2 to keep --- stack 8-byte alignment. */ --+ smw.adm $r1, [$sp], $r2, #0x0 /* Save extra $r2 to keep stack 8-byte alignment. */ -- #endif -- -- la $gp, _SDA_BASE_ /* Init GP for small data access. */ --@@ -71,12 +66,11 @@ _start: -- bnez $r0, 1f /* If fail to resume, do cold boot. */ -- -- /* Restore registers for context-switching. */ ---#ifdef NDS32_EXT_IFC --- lmw.bim $r1, [$sp], $r2, #0x0 /* Restore extra $r2 to keep --- stack 8-byte alignment. */ --+#if __NDS32_EXT_IFC__ --+ lmw.bim $r1, [$sp], $r2, #0x0 /* Restore extra $r2 to keep stack 8-byte alignment. */ -- mtusr $r1, $IFC_LP -- #endif ---#ifdef __NDS32_REDUCED_REGS__ --+#if __NDS32_REDUCED_REGS__ || __NDS32_REDUCE_REGS -- /* For 16-reg mode. */ -- lmw.bim $r15, [$sp], $r15, #0xf -- lmw.bim $r0, [$sp], $r10, #0x0 --@@ -88,6 +82,17 @@ _start: -- -- -- 1: /* Cold boot. */ --+#if __NDS32_ISR_VECTOR_SIZE_4__ --+ /* With vector ID feature for v3 architecture, default vector size is 4-byte. */ --+ /* Set IVB.ESZ = 0 (vector table entry size = 4 bytes) */ --+ mfsr $r0, $IVB --+ li $r1, #0xc000 --+ or $r0, $r0, $r1 --+ xor $r0, $r0, $r1 --+ mtsr $r0, $IVB --+ dsb --+#else --+ /* There is no vector ID feature, so the vector size must be 16-byte. */ -- /* Set IVB.ESZ = 1 (vector table entry size = 16 bytes) */ -- mfsr $r0, $IVB -- li $r1, #0xffff3fff --@@ -95,36 +100,54 @@ _start: -- ori $r0, $r0, #0x4000 -- mtsr $r0, $IVB -- dsb --+#endif -- -- la $gp, _SDA_BASE_ /* Init $gp. */ --- la $fp, _FP_BASE_ /* Init $fp. */ -- la $sp, _stack /* Init $sp. */ ---#ifdef NDS32_EXT_EX9 ---/* --- * Initialize the table base of EX9 instruction --- * ex9 generation needs to disable before the ITB is set --- */ --- mfsr $r0, $MSC_CFG /* Check if HW support of EX9. */ --+ --+#if __NDS32_EXT_EX9__ --+.L_init_itb: --+ /* Initialization for Instruction Table Base (ITB). --+ The symbol _ITB_BASE_ is determined by Linker. --+ Set $ITB only if MSC_CFG.EIT (cr4.b'24) is set. */ --+ mfsr $r0, $MSC_CFG -- srli $r0, $r0, 24 -- andi $r0, $r0, 0x1 --- beqz $r0, 4f /* Zero means HW does not support EX9. */ --- la $r0, _ITB_BASE_ /* Init $ITB. */ --+ beqz $r0, 4f /* Fall through ? */ --+ la $r0, _ITB_BASE_ -- mtusr $r0, $ITB --- .no_ex9_end -- 4: -- #endif --- la $r15, _nds32_init_mem /* Call DRAM init. _nds32_init_mem --- may written by C language. */ --+ --+#if __NDS32_EXT_FPU_SP__ || __NDS32_EXT_FPU_DP__ --+.L_init_fpu: --+ /* Initialize FPU --+ Set FUCOP_CTL.CP0EN (fucpr.b'0). */ --+ mfsr $r0, $FUCOP_CTL --+ ori $r0, $r0, 0x1 --+ mtsr $r0, $FUCOP_CTL --+ dsb --+ /* According to [bugzilla #9425], set flush-to-zero mode. --+ That is, set $FPCSR.DNZ(b'12) = 1. */ --+ FMFCSR $r0 --+ ori $r0, $r0, 0x1000 --+ FMTCSR $r0 --+ dsb --+#endif --+ --+ /* Call DRAM init. _nds32_init_mem may written by C language. */ --+ la $r15, _nds32_init_mem -- beqz $r15, 6f -- jral $r15 -- 6: -- l.w $r15, _nds32_jmptbl_00 /* Load reset handler. */ -- jral $r15 ---/* Reset handler() should never return in a RTOS or non-OS system. --- In case it does return, an exception will be generated. --- This exception will be caught either by default break handler or by EDM. --- Default break handle may just do an infinite loop. --- EDM will notify GDB and GDB will regain control when the ID is 0x7fff. */ --+ --+ /* Reset handler() should never return in a RTOS or non-OS system. --+ In case it does return, an exception will be generated. --+ This exception will be caught either by default break handler or by EDM. --+ Default break handle may just do an infinite loop. --+ EDM will notify GDB and GDB will regain control when the ID is 0x7fff. */ -- 5: -- break #0x7fff -- .size _nds32_reset, .-_nds32_reset --diff --git a/libgcc/config/nds32/isr-library/reset_4b.S b/libgcc/config/nds32/isr-library/reset_4b.S --deleted file mode 100644 --index 792e655..0000000 ----- a/libgcc/config/nds32/isr-library/reset_4b.S --+++ /dev/null --@@ -1,131 +0,0 @@ ---/* c-isr library stuff of Andes NDS32 cpu for GNU compiler --- Copyright (C) 2012-2016 Free Software Foundation, Inc. --- Contributed by Andes Technology Corporation. --- --- This file is part of GCC. --- --- GCC is free software; you can redistribute it and/or modify it --- under the terms of the GNU General Public License as published --- by the Free Software Foundation; either version 3, or (at your --- option) any later version. --- --- GCC is distributed in the hope that it will be useful, but WITHOUT --- ANY WARRANTY; without even the implied warranty of MERCHANTABILITY --- or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public --- License for more details. --- --- Under Section 7 of GPL version 3, you are granted additional --- permissions described in the GCC Runtime Library Exception, version --- 3.1, as published by the Free Software Foundation. --- --- You should have received a copy of the GNU General Public License and --- a copy of the GCC Runtime Library Exception along with this program; --- see the files COPYING3 and COPYING.RUNTIME respectively. If not, see --- . */ --- --- .section .nds32_isr, "ax" /* Put it in the section of 1st level handler. */ --- .align 1 --- .weak _SDA_BASE_ /* For reset handler only. */ --- .weak _FP_BASE_ /* For reset handler only. */ --- .weak _nds32_init_mem /* User defined memory initialization function. */ --- .globl _start --- .globl _nds32_reset_4b --- .type _nds32_reset_4b, @function ---_nds32_reset_4b: ---_start: ---#ifdef NDS32_EXT_EX9 --- .no_ex9_begin ---#endif --- /* Handle NMI and warm boot if any of them exists. */ --- beqz $sp, 1f /* Reset, NMI or warm boot? */ --- /* Either NMI or warm boot; save all regs. */ --- --- /* Preserve registers for context-switching. */ ---#ifdef __NDS32_REDUCED_REGS__ --- /* For 16-reg mode. */ --- smw.adm $r0, [$sp], $r10, #0x0 --- smw.adm $r15, [$sp], $r15, #0xf ---#else --- /* For 32-reg mode. */ --- smw.adm $r0, [$sp], $r27, #0xf ---#endif ---#ifdef NDS32_EXT_IFC --- mfusr $r1, $IFC_LP --- smw.adm $r1, [$sp], $r2, #0x0 /* Save extra $r2 to keep --- stack 8-byte alignment. */ ---#endif --- --- la $gp, _SDA_BASE_ /* Init GP for small data access. */ --- move $r0, $sp /* Init parameter. */ --- mfsr $r1, $ITYPE /* Check ITYPE for NMI or warm boot. */ --- andi $r1, $r1, #0xf --- addi $r1, $r1, #-1 --- beqz $r1, 2f /* Warm boot if true. */ --- l.w $r15, _nds32_nmih /* Load NMI handler. */ --- j 3f ---2: --- l.w $r15, _nds32_wrh /* Load warm boot handler. */ ---3: --- beqz $r15, 1f /* If no handler, do cold boot. */ --- jral $r15 /* Call handler. */ --- bnez $r0, 1f /* If fail to resume, do cold boot. */ --- --- /* Restore registers for context-switching. */ ---#ifdef NDS32_EXT_IFC --- lmw.bim $r1, [$sp], $r2, #0x0 /* Restore extra $r2 to keep --- stack 8-byte alignment. */ --- mtusr $r1, $IFC_LP ---#endif ---#ifdef __NDS32_REDUCED_REGS__ --- /* For 16-reg mode. */ --- lmw.bim $r15, [$sp], $r15, #0xf --- lmw.bim $r0, [$sp], $r10, #0x0 ---#else --- /* For 32-reg mode. */ --- lmw.bim $r0, [$sp], $r27, #0xf ---#endif --- iret /* Resume operation. */ --- --- ---1: /* Cold boot. */ --- /* With vector ID feature, set default vector size to 4B. */ --- /* Set IVB.ESZ = 0 (vector table entry size = 4 bytes) */ --- mfsr $r0, $IVB --- li $r1, #0xc000 --- or $r0, $r0, $r1 --- xor $r0, $r0, $r1 --- mtsr $r0, $IVB --- dsb --- --- la $gp, _SDA_BASE_ /* Init $gp. */ --- la $fp, _FP_BASE_ /* Init $fp. */ --- la $sp, _stack /* Init $sp. */ ---#ifdef NDS32_EXT_EX9 ---/* --- * Initialize the table base of EX9 instruction --- * ex9 generation needs to disable before the ITB is set --- */ --- mfsr $r0, $MSC_CFG /* Check if HW support of EX9. */ --- srli $r0, $r0, 24 --- andi $r0, $r0, 0x1 --- beqz $r0, 4f /* Zero means HW does not support EX9. */ --- la $r0, _ITB_BASE_ /* Init $ITB. */ --- mtusr $r0, $ITB --- .no_ex9_end ---4: ---#endif --- la $r15, _nds32_init_mem /* Call DRAM init. _nds32_init_mem --- may written by C language. */ --- beqz $r15, 6f --- jral $r15 ---6: --- l.w $r15, _nds32_jmptbl_00 /* Load reset handler. */ --- jral $r15 ---/* Reset handler() should never return in a RTOS or non-OS system. --- In case it does return, an exception will be generated. --- This exception will be caught either by default break handler or by EDM. --- Default break handle may just do an infinite loop. --- EDM will notify GDB and GDB will regain control when the ID is 0x7fff. */ ---5: --- break #0x7fff --- .size _nds32_reset_4b, .-_nds32_reset_4b --diff --git a/libgcc/config/nds32/isr-library/restore_all.inc b/libgcc/config/nds32/isr-library/restore_all.inc --index c25b46e..96f87ec 100644 ----- a/libgcc/config/nds32/isr-library/restore_all.inc --+++ b/libgcc/config/nds32/isr-library/restore_all.inc --@@ -31,15 +31,11 @@ -- mtsr $r2, $IPSW -- RESTORE_FPU_REGS -- RESTORE_MAC_REGS ---#ifdef NDS32_EXT_IFC --- lmw.bim $r1, [$sp], $r2, #0x0 /* Restore extra $r2 to keep --- stack 8-byte alignment. */ --- mtusr $r1, $IFC_LP ---#endif ---#ifdef __NDS32_REDUCED_REGS__ --+ RESTORE_USR_REGS --+#if __NDS32_REDUCED_REGS__ || __NDS32_REDUCE_REGS -- lmw.bim $r0, [$sp], $r10, #0x0 /* Restore all regs. */ -- lmw.bim $r15, [$sp], $r15, #0xf ---#else /* not __NDS32_REDUCED_REGS__ */ --+#else -- lmw.bim $r0, [$sp], $r27, #0xf /* Restore all regs. */ -- #endif -- .endm --diff --git a/libgcc/config/nds32/isr-library/restore_mac_regs.inc b/libgcc/config/nds32/isr-library/restore_mac_regs.inc --index 0ffc980..a15024c 100644 ----- a/libgcc/config/nds32/isr-library/restore_mac_regs.inc --+++ b/libgcc/config/nds32/isr-library/restore_mac_regs.inc --@@ -24,7 +24,7 @@ -- . */ -- -- .macro RESTORE_MAC_REGS ---#ifdef NDS32_DX_REGS --+#if __NDS32_DX_REGS__ -- lmw.bim $r1, [$sp], $r4, #0x0 -- mtusr $r1, $d0.lo -- mtusr $r2, $d0.hi --diff --git a/libgcc/config/nds32/isr-library/restore_partial.inc b/libgcc/config/nds32/isr-library/restore_partial.inc --index 70d5421..c07d30e 100644 ----- a/libgcc/config/nds32/isr-library/restore_partial.inc --+++ b/libgcc/config/nds32/isr-library/restore_partial.inc --@@ -31,15 +31,11 @@ -- mtsr $r1, $IPC /* Set IPC. */ -- mtsr $r2, $IPSW /* Set IPSW. */ -- #endif --- RESTORE_FPU_REGS --- RESTORE_MAC_REGS ---#ifdef NDS32_EXT_IFC --- lmw.bim $r1, [$sp], $r2, #0x0 /* Restore extra $r2 to keep --- stack 8-byte alignment. */ --- mtusr $r1, $IFC_LP ---#endif --+ RESTORE_FPU_REGS --+ RESTORE_MAC_REGS --+ RESTORE_USR_REGS -- lmw.bim $r0, [$sp], $r5, #0x0 /* Restore all regs. */ ---#ifdef __NDS32_REDUCED_REGS__ --+#if __NDS32_REDUCED_REGS__ || __NDS32_REDUCE_REGS -- lmw.bim $r15, [$sp], $r15, #0x2 -- #else -- lmw.bim $r15, [$sp], $r27, #0x2 /* Restore all regs. */ --diff --git a/libgcc/config/nds32/isr-library/vec_vid03_4b.S b/libgcc/config/nds32/isr-library/restore_usr_regs.inc --similarity index 72% --rename from libgcc/config/nds32/isr-library/vec_vid03_4b.S --rename to libgcc/config/nds32/isr-library/restore_usr_regs.inc --index cd30906..c8f6e4a 100644 ----- a/libgcc/config/nds32/isr-library/vec_vid03_4b.S --+++ b/libgcc/config/nds32/isr-library/restore_usr_regs.inc --@@ -23,12 +23,20 @@ -- see the files COPYING3 and COPYING.RUNTIME respectively. If not, see -- . */ -- --- .section .nds32_vector.03, "ax" --- .vec_size 4 --- .align 2 --- .weak _nds32_vector_03_4b --- .type _nds32_vector_03_4b, @function ---_nds32_vector_03_4b: ---1: --- j 1b --- .size _nds32_vector_03_4b, .-_nds32_vector_03_4b --+.macro RESTORE_USR_REGS --+#if __NDS32_EXT_IFC__ && (__NDS32_EXT_ZOL__ || __NDS32_EXT_DSP__) --+ lmw.bim $r1, [$sp], $r4, #0x0 --+ mtusr $r1, $IFC_LP --+ mtusr $r2, $LB --+ mtusr $r3, $LE --+ mtusr $r4, $LC --+#elif __NDS32_EXT_IFC__ --+ lmw.bim $r1, [$sp], $r2, #0x0 --+ mtusr $r1, $IFC_LP --+#elif __NDS32_EXT_ZOL__ || __NDS32_EXT_DSP__ --+ lmw.bim $r1, [$sp], $r4, #0x0 --+ mtusr $r1, $LB --+ mtusr $r2, $LE --+ mtusr $r3, $LC --+#endif --+.endm --diff --git a/libgcc/config/nds32/isr-library/save_all.inc b/libgcc/config/nds32/isr-library/save_all.inc --index 20eb29d..c926664 100644 ----- a/libgcc/config/nds32/isr-library/save_all.inc --+++ b/libgcc/config/nds32/isr-library/save_all.inc --@@ -23,45 +23,42 @@ -- see the files COPYING3 and COPYING.RUNTIME respectively. If not, see -- . */ -- ---.macro SAVE_ALL_4B ---#ifdef __NDS32_REDUCED_REGS__ --+#if __NDS32_ISR_VECTOR_SIZE_4__ --+ --+/* If vector size is 4-byte, we have to save registers --+ in the macro implementation. */ --+.macro SAVE_ALL --+#if __NDS32_REDUCED_REGS__ || __NDS32_REDUCE_REGS -- smw.adm $r15, [$sp], $r15, #0xf -- smw.adm $r0, [$sp], $r10, #0x0 ---#else /* not __NDS32_REDUCED_REGS__ */ --+#else -- smw.adm $r0, [$sp], $r27, #0xf ---#endif /* not __NDS32_REDUCED_REGS__ */ ---#ifdef NDS32_EXT_IFC --- mfusr $r1, $IFC_LP --- smw.adm $r1, [$sp], $r2, #0x0 /* Save extra $r2 to keep --- stack 8-byte alignment. */ -- #endif --- SAVE_MAC_REGS --- SAVE_FPU_REGS --+ SAVE_USR_REGS --+ SAVE_MAC_REGS --+ SAVE_FPU_REGS -- mfsr $r1, $IPC /* Get IPC. */ -- mfsr $r2, $IPSW /* Get IPSW. */ -- smw.adm $r1, [$sp], $r2, #0x0 /* Push IPC, IPSW. */ -- move $r1, $sp /* $r1 is ptr to NDS32_CONTEXT. */ -- mfsr $r0, $ITYPE /* Get VID to $r0. */ -- srli $r0, $r0, #5 ---#ifdef __NDS32_ISA_V2__ -- andi $r0, $r0, #127 ---#else --- fexti33 $r0, #6 ---#endif -- .endm -- --+#else /* not __NDS32_ISR_VECTOR_SIZE_4__ */ --+ --+/* If vector size is 16-byte, some works can be done in --+ the vector section generated by compiler, so that we --+ can implement less in the macro. */ -- .macro SAVE_ALL ---/* SAVE_REG_TBL code has been moved to --- vector table generated by compiler. */ ---#ifdef NDS32_EXT_IFC --- mfusr $r1, $IFC_LP --- smw.adm $r1, [$sp], $r2, #0x0 /* Save extra $r2 to keep --- stack 8-byte alignment. */ ---#endif --- SAVE_MAC_REGS --- SAVE_FPU_REGS --+ SAVE_USR_REGS --+ SAVE_MAC_REGS --+ SAVE_FPU_REGS -- mfsr $r1, $IPC /* Get IPC. */ -- mfsr $r2, $IPSW /* Get IPSW. */ -- smw.adm $r1, [$sp], $r2, #0x0 /* Push IPC, IPSW. */ -- move $r1, $sp /* $r1 is ptr to NDS32_CONTEXT. */ -- .endm --+ --+#endif /* not __NDS32_ISR_VECTOR_SIZE_4__ */ --diff --git a/libgcc/config/nds32/isr-library/save_mac_regs.inc b/libgcc/config/nds32/isr-library/save_mac_regs.inc --index ddb5e77..2d79d70 100644 ----- a/libgcc/config/nds32/isr-library/save_mac_regs.inc --+++ b/libgcc/config/nds32/isr-library/save_mac_regs.inc --@@ -24,7 +24,7 @@ -- . */ -- -- .macro SAVE_MAC_REGS ---#ifdef NDS32_DX_REGS --+#if __NDS32_DX_REGS__ -- mfusr $r1, $d0.lo -- mfusr $r2, $d0.hi -- mfusr $r3, $d1.lo --diff --git a/libgcc/config/nds32/isr-library/save_partial.inc b/libgcc/config/nds32/isr-library/save_partial.inc --index ee514c4..0c6d481 100644 ----- a/libgcc/config/nds32/isr-library/save_partial.inc --+++ b/libgcc/config/nds32/isr-library/save_partial.inc --@@ -23,20 +23,20 @@ -- see the files COPYING3 and COPYING.RUNTIME respectively. If not, see -- . */ -- ---.macro SAVE_PARTIAL_4B ---#ifdef __NDS32_REDUCED_REGS__ --+#if __NDS32_ISR_VECTOR_SIZE_4__ --+ --+/* If vector size is 4-byte, we have to save registers --+ in the macro implementation. */ --+.macro SAVE_PARTIAL --+#if __NDS32_REDUCED_REGS__ || __NDS32_REDUCE_REGS -- smw.adm $r15, [$sp], $r15, #0x2 ---#else /* not __NDS32_REDUCED_REGS__ */ --+#else -- smw.adm $r15, [$sp], $r27, #0x2 ---#endif /* not __NDS32_REDUCED_REGS__ */ --- smw.adm $r0, [$sp], $r5, #0x0 ---#ifdef NDS32_EXT_IFC --- mfusr $r1, $IFC_LP --- smw.adm $r1, [$sp], $r2, #0x0 /* Save extra $r2 to keep --- stack 8-byte alignment. */ -- #endif --- SAVE_MAC_REGS --- SAVE_FPU_REGS --+ smw.adm $r0, [$sp], $r5, #0x0 --+ SAVE_USR_REGS --+ SAVE_MAC_REGS --+ SAVE_FPU_REGS -- #if defined(NDS32_NESTED) || defined(NDS32_NESTED_READY) -- mfsr $r1, $IPC /* Get IPC. */ -- mfsr $r2, $IPSW /* Get IPSW. */ --@@ -44,26 +44,24 @@ -- #endif -- mfsr $r0, $ITYPE /* Get VID to $r0. */ -- srli $r0, $r0, #5 ---#ifdef __NDS32_ISA_V2__ -- andi $r0, $r0, #127 ---#else --- fexti33 $r0, #6 ---#endif -- .endm -- --+#else /* not __NDS32_ISR_VECTOR_SIZE_4__ */ --+ --+/* If vector size is 16-byte, some works can be done in --+ the vector section generated by compiler, so that we --+ can implement less in the macro. */ --+ -- .macro SAVE_PARTIAL ---/* SAVE_CALLER_REGS code has been moved to --- vector table generated by compiler. */ ---#ifdef NDS32_EXT_IFC --- mfusr $r1, $IFC_LP --- smw.adm $r1, [$sp], $r2, #0x0 /* Save extra $r2 to keep --- stack 8-byte alignment. */ ---#endif --- SAVE_MAC_REGS --- SAVE_FPU_REGS --+ SAVE_USR_REGS --+ SAVE_MAC_REGS --+ SAVE_FPU_REGS -- #if defined(NDS32_NESTED) || defined(NDS32_NESTED_READY) -- mfsr $r1, $IPC /* Get IPC. */ -- mfsr $r2, $IPSW /* Get IPSW. */ -- smw.adm $r1, [$sp], $r2, #0x0 /* Push IPC, IPSW. */ -- #endif -- .endm --+ --+#endif /* not __NDS32_ISR_VECTOR_SIZE_4__ */ --diff --git a/libgcc/config/nds32/isr-library/vec_vid00_4b.S b/libgcc/config/nds32/isr-library/save_usr_regs.inc --similarity index 61% --rename from libgcc/config/nds32/isr-library/vec_vid00_4b.S --rename to libgcc/config/nds32/isr-library/save_usr_regs.inc --index e1a37b4..b6807d7 100644 ----- a/libgcc/config/nds32/isr-library/vec_vid00_4b.S --+++ b/libgcc/config/nds32/isr-library/save_usr_regs.inc --@@ -23,12 +23,22 @@ -- see the files COPYING3 and COPYING.RUNTIME respectively. If not, see -- . */ -- --- .section .nds32_vector.00, "ax" --- .vec_size 4 --- .align 2 --- .weak _nds32_vector_00_4b --- .type _nds32_vector_00_4b, @function ---_nds32_vector_00_4b: ---1: --- j 1b --- .size _nds32_vector_00_4b, .-_nds32_vector_00_4b --+.macro SAVE_USR_REGS --+/* Store User Special Registers according to supported ISA extension --+ !!! WATCH OUT !!! Take care of 8-byte alignment issue. */ --+#if __NDS32_EXT_IFC__ && (__NDS32_EXT_ZOL__ || __NDS32_EXT_DSP__) --+ mfusr $r1, $IFC_LP --+ mfusr $r2, $LB --+ mfusr $r3, $LE --+ mfusr $r4, $LC --+ smw.adm $r1, [$sp], $r4, #0x0 /* Save even. Ok! */ --+#elif __NDS32_EXT_IFC__ --+ mfusr $r1, $IFC_LP --+ smw.adm $r1, [$sp], $r2, #0x0 /* Save extra $r2 to keep stack 8-byte aligned. */ --+#elif (__NDS32_EXT_ZOL__ || __NDS32_EXT_DSP__) --+ mfusr $r1, $LB --+ mfusr $r2, $LE --+ mfusr $r3, $LC --+ smw.adm $r1, [$sp], $r4, #0x0 /* Save extra $r4 to keep stack 8-byte aligned. */ --+#endif --+.endm --diff --git a/libgcc/config/nds32/isr-library/vec_vid00.S b/libgcc/config/nds32/isr-library/vec_vid00.S --index ccdbd19..f02e92c 100644 ----- a/libgcc/config/nds32/isr-library/vec_vid00.S --+++ b/libgcc/config/nds32/isr-library/vec_vid00.S --@@ -24,8 +24,15 @@ -- . */ -- -- .section .nds32_vector.00, "ax" --+#if __NDS32_ISR_VECTOR_SIZE_4__ --+ /* The vector size is default 4-byte for v3 architecture. */ --+ .vec_size 4 --+ .align 2 --+#else --+ /* The vector size is default 16-byte for other architectures. */ -- .vec_size 16 -- .align 4 --+#endif -- .weak _nds32_vector_00 -- .type _nds32_vector_00, @function -- _nds32_vector_00: --diff --git a/libgcc/config/nds32/isr-library/vec_vid01.S b/libgcc/config/nds32/isr-library/vec_vid01.S --index ed5a88e..542fcf8 100644 ----- a/libgcc/config/nds32/isr-library/vec_vid01.S --+++ b/libgcc/config/nds32/isr-library/vec_vid01.S --@@ -24,8 +24,15 @@ -- . */ -- -- .section .nds32_vector.01, "ax" --+#if __NDS32_ISR_VECTOR_SIZE_4__ --+ /* The vector size is default 4-byte for v3 architecture. */ --+ .vec_size 4 --+ .align 2 --+#else --+ /* The vector size is default 16-byte for other architectures. */ -- .vec_size 16 -- .align 4 --+#endif -- .weak _nds32_vector_01 -- .type _nds32_vector_01, @function -- _nds32_vector_01: --diff --git a/libgcc/config/nds32/isr-library/vec_vid01_4b.S b/libgcc/config/nds32/isr-library/vec_vid01_4b.S --deleted file mode 100644 --index 239bd75..0000000 ----- a/libgcc/config/nds32/isr-library/vec_vid01_4b.S --+++ /dev/null --@@ -1,34 +0,0 @@ ---/* c-isr library stuff of Andes NDS32 cpu for GNU compiler --- Copyright (C) 2012-2016 Free Software Foundation, Inc. --- Contributed by Andes Technology Corporation. --- --- This file is part of GCC. --- --- GCC is free software; you can redistribute it and/or modify it --- under the terms of the GNU General Public License as published --- by the Free Software Foundation; either version 3, or (at your --- option) any later version. --- --- GCC is distributed in the hope that it will be useful, but WITHOUT --- ANY WARRANTY; without even the implied warranty of MERCHANTABILITY --- or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public --- License for more details. --- --- Under Section 7 of GPL version 3, you are granted additional --- permissions described in the GCC Runtime Library Exception, version --- 3.1, as published by the Free Software Foundation. --- --- You should have received a copy of the GNU General Public License and --- a copy of the GCC Runtime Library Exception along with this program; --- see the files COPYING3 and COPYING.RUNTIME respectively. If not, see --- . */ --- --- .section .nds32_vector.01, "ax" --- .vec_size 4 --- .align 2 --- .weak _nds32_vector_01_4b --- .type _nds32_vector_01_4b, @function ---_nds32_vector_01_4b: ---1: --- j 1b --- .size _nds32_vector_01_4b, .-_nds32_vector_01_4b --diff --git a/libgcc/config/nds32/isr-library/vec_vid02.S b/libgcc/config/nds32/isr-library/vec_vid02.S --index 1a95a57..72b8b56 100644 ----- a/libgcc/config/nds32/isr-library/vec_vid02.S --+++ b/libgcc/config/nds32/isr-library/vec_vid02.S --@@ -24,8 +24,15 @@ -- . */ -- -- .section .nds32_vector.02, "ax" --+#if __NDS32_ISR_VECTOR_SIZE_4__ --+ /* The vector size is default 4-byte for v3 architecture. */ --+ .vec_size 4 --+ .align 2 --+#else --+ /* The vector size is default 16-byte for other architectures. */ -- .vec_size 16 -- .align 4 --+#endif -- .weak _nds32_vector_02 -- .type _nds32_vector_02, @function -- _nds32_vector_02: --diff --git a/libgcc/config/nds32/isr-library/vec_vid02_4b.S b/libgcc/config/nds32/isr-library/vec_vid02_4b.S --deleted file mode 100644 --index c532e62..0000000 ----- a/libgcc/config/nds32/isr-library/vec_vid02_4b.S --+++ /dev/null --@@ -1,34 +0,0 @@ ---/* c-isr library stuff of Andes NDS32 cpu for GNU compiler --- Copyright (C) 2012-2016 Free Software Foundation, Inc. --- Contributed by Andes Technology Corporation. --- --- This file is part of GCC. --- --- GCC is free software; you can redistribute it and/or modify it --- under the terms of the GNU General Public License as published --- by the Free Software Foundation; either version 3, or (at your --- option) any later version. --- --- GCC is distributed in the hope that it will be useful, but WITHOUT --- ANY WARRANTY; without even the implied warranty of MERCHANTABILITY --- or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public --- License for more details. --- --- Under Section 7 of GPL version 3, you are granted additional --- permissions described in the GCC Runtime Library Exception, version --- 3.1, as published by the Free Software Foundation. --- --- You should have received a copy of the GNU General Public License and --- a copy of the GCC Runtime Library Exception along with this program; --- see the files COPYING3 and COPYING.RUNTIME respectively. If not, see --- . */ --- --- .section .nds32_vector.02, "ax" --- .vec_size 4 --- .align 2 --- .weak _nds32_vector_02_4b --- .type _nds32_vector_02_4b, @function ---_nds32_vector_02_4b: ---1: --- j 1b --- .size _nds32_vector_02_4b, .-_nds32_vector_02_4b --diff --git a/libgcc/config/nds32/isr-library/vec_vid03.S b/libgcc/config/nds32/isr-library/vec_vid03.S --index 9bc572a..b0f8a60 100644 ----- a/libgcc/config/nds32/isr-library/vec_vid03.S --+++ b/libgcc/config/nds32/isr-library/vec_vid03.S --@@ -24,8 +24,15 @@ -- . */ -- -- .section .nds32_vector.03, "ax" --+#if __NDS32_ISR_VECTOR_SIZE_4__ --+ /* The vector size is default 4-byte for v3 architecture. */ --+ .vec_size 4 --+ .align 2 --+#else --+ /* The vector size is default 16-byte for other architectures. */ -- .vec_size 16 -- .align 4 --+#endif -- .weak _nds32_vector_03 -- .type _nds32_vector_03, @function -- _nds32_vector_03: --diff --git a/libgcc/config/nds32/isr-library/vec_vid04.S b/libgcc/config/nds32/isr-library/vec_vid04.S --index e8d4e10..d76ef73 100644 ----- a/libgcc/config/nds32/isr-library/vec_vid04.S --+++ b/libgcc/config/nds32/isr-library/vec_vid04.S --@@ -24,8 +24,15 @@ -- . */ -- -- .section .nds32_vector.04, "ax" --+#if __NDS32_ISR_VECTOR_SIZE_4__ --+ /* The vector size is default 4-byte for v3 architecture. */ --+ .vec_size 4 --+ .align 2 --+#else --+ /* The vector size is default 16-byte for other architectures. */ -- .vec_size 16 -- .align 4 --+#endif -- .weak _nds32_vector_04 -- .type _nds32_vector_04, @function -- _nds32_vector_04: --diff --git a/libgcc/config/nds32/isr-library/vec_vid04_4b.S b/libgcc/config/nds32/isr-library/vec_vid04_4b.S --deleted file mode 100644 --index 21fc77e..0000000 ----- a/libgcc/config/nds32/isr-library/vec_vid04_4b.S --+++ /dev/null --@@ -1,34 +0,0 @@ ---/* c-isr library stuff of Andes NDS32 cpu for GNU compiler --- Copyright (C) 2012-2016 Free Software Foundation, Inc. --- Contributed by Andes Technology Corporation. --- --- This file is part of GCC. --- --- GCC is free software; you can redistribute it and/or modify it --- under the terms of the GNU General Public License as published --- by the Free Software Foundation; either version 3, or (at your --- option) any later version. --- --- GCC is distributed in the hope that it will be useful, but WITHOUT --- ANY WARRANTY; without even the implied warranty of MERCHANTABILITY --- or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public --- License for more details. --- --- Under Section 7 of GPL version 3, you are granted additional --- permissions described in the GCC Runtime Library Exception, version --- 3.1, as published by the Free Software Foundation. --- --- You should have received a copy of the GNU General Public License and --- a copy of the GCC Runtime Library Exception along with this program; --- see the files COPYING3 and COPYING.RUNTIME respectively. If not, see --- . */ --- --- .section .nds32_vector.04, "ax" --- .vec_size 4 --- .align 2 --- .weak _nds32_vector_04_4b --- .type _nds32_vector_04_4b, @function ---_nds32_vector_04_4b: ---1: --- j 1b --- .size _nds32_vector_04_4b, .-_nds32_vector_04_4b --diff --git a/libgcc/config/nds32/isr-library/vec_vid05.S b/libgcc/config/nds32/isr-library/vec_vid05.S --index 1621a9d..ed5a5bb 100644 ----- a/libgcc/config/nds32/isr-library/vec_vid05.S --+++ b/libgcc/config/nds32/isr-library/vec_vid05.S --@@ -24,8 +24,15 @@ -- . */ -- -- .section .nds32_vector.05, "ax" --+#if __NDS32_ISR_VECTOR_SIZE_4__ --+ /* The vector size is default 4-byte for v3 architecture. */ --+ .vec_size 4 --+ .align 2 --+#else --+ /* The vector size is default 16-byte for other architectures. */ -- .vec_size 16 -- .align 4 --+#endif -- .weak _nds32_vector_05 -- .type _nds32_vector_05, @function -- _nds32_vector_05: --diff --git a/libgcc/config/nds32/isr-library/vec_vid05_4b.S b/libgcc/config/nds32/isr-library/vec_vid05_4b.S --deleted file mode 100644 --index b86fe19..0000000 ----- a/libgcc/config/nds32/isr-library/vec_vid05_4b.S --+++ /dev/null --@@ -1,34 +0,0 @@ ---/* c-isr library stuff of Andes NDS32 cpu for GNU compiler --- Copyright (C) 2012-2016 Free Software Foundation, Inc. --- Contributed by Andes Technology Corporation. --- --- This file is part of GCC. --- --- GCC is free software; you can redistribute it and/or modify it --- under the terms of the GNU General Public License as published --- by the Free Software Foundation; either version 3, or (at your --- option) any later version. --- --- GCC is distributed in the hope that it will be useful, but WITHOUT --- ANY WARRANTY; without even the implied warranty of MERCHANTABILITY --- or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public --- License for more details. --- --- Under Section 7 of GPL version 3, you are granted additional --- permissions described in the GCC Runtime Library Exception, version --- 3.1, as published by the Free Software Foundation. --- --- You should have received a copy of the GNU General Public License and --- a copy of the GCC Runtime Library Exception along with this program; --- see the files COPYING3 and COPYING.RUNTIME respectively. If not, see --- . */ --- --- .section .nds32_vector.05, "ax" --- .vec_size 4 --- .align 2 --- .weak _nds32_vector_05_4b --- .type _nds32_vector_05_4b, @function ---_nds32_vector_05_4b: ---1: --- j 1b --- .size _nds32_vector_05_4b, .-_nds32_vector_05_4b --diff --git a/libgcc/config/nds32/isr-library/vec_vid06.S b/libgcc/config/nds32/isr-library/vec_vid06.S --index 934f0b1..834c7de 100644 ----- a/libgcc/config/nds32/isr-library/vec_vid06.S --+++ b/libgcc/config/nds32/isr-library/vec_vid06.S --@@ -24,8 +24,15 @@ -- . */ -- -- .section .nds32_vector.06, "ax" --+#if __NDS32_ISR_VECTOR_SIZE_4__ --+ /* The vector size is default 4-byte for v3 architecture. */ --+ .vec_size 4 --+ .align 2 --+#else --+ /* The vector size is default 16-byte for other architectures. */ -- .vec_size 16 -- .align 4 --+#endif -- .weak _nds32_vector_06 -- .type _nds32_vector_06, @function -- _nds32_vector_06: --diff --git a/libgcc/config/nds32/isr-library/vec_vid06_4b.S b/libgcc/config/nds32/isr-library/vec_vid06_4b.S --deleted file mode 100644 --index 3624cfd..0000000 ----- a/libgcc/config/nds32/isr-library/vec_vid06_4b.S --+++ /dev/null --@@ -1,34 +0,0 @@ ---/* c-isr library stuff of Andes NDS32 cpu for GNU compiler --- Copyright (C) 2012-2016 Free Software Foundation, Inc. --- Contributed by Andes Technology Corporation. --- --- This file is part of GCC. --- --- GCC is free software; you can redistribute it and/or modify it --- under the terms of the GNU General Public License as published --- by the Free Software Foundation; either version 3, or (at your --- option) any later version. --- --- GCC is distributed in the hope that it will be useful, but WITHOUT --- ANY WARRANTY; without even the implied warranty of MERCHANTABILITY --- or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public --- License for more details. --- --- Under Section 7 of GPL version 3, you are granted additional --- permissions described in the GCC Runtime Library Exception, version --- 3.1, as published by the Free Software Foundation. --- --- You should have received a copy of the GNU General Public License and --- a copy of the GCC Runtime Library Exception along with this program; --- see the files COPYING3 and COPYING.RUNTIME respectively. If not, see --- . */ --- --- .section .nds32_vector.06, "ax" --- .vec_size 4 --- .align 2 --- .weak _nds32_vector_06_4b --- .type _nds32_vector_06_4b, @function ---_nds32_vector_06_4b: ---1: --- j 1b --- .size _nds32_vector_06_4b, .-_nds32_vector_06_4b --diff --git a/libgcc/config/nds32/isr-library/vec_vid07.S b/libgcc/config/nds32/isr-library/vec_vid07.S --index 0b0484d..cb3b33a 100644 ----- a/libgcc/config/nds32/isr-library/vec_vid07.S --+++ b/libgcc/config/nds32/isr-library/vec_vid07.S --@@ -24,8 +24,15 @@ -- . */ -- -- .section .nds32_vector.07, "ax" --+#if __NDS32_ISR_VECTOR_SIZE_4__ --+ /* The vector size is default 4-byte for v3 architecture. */ --+ .vec_size 4 --+ .align 2 --+#else --+ /* The vector size is default 16-byte for other architectures. */ -- .vec_size 16 -- .align 4 --+#endif -- .weak _nds32_vector_07 -- .type _nds32_vector_07, @function -- _nds32_vector_07: --diff --git a/libgcc/config/nds32/isr-library/vec_vid07_4b.S b/libgcc/config/nds32/isr-library/vec_vid07_4b.S --deleted file mode 100644 --index 997ca75..0000000 ----- a/libgcc/config/nds32/isr-library/vec_vid07_4b.S --+++ /dev/null --@@ -1,34 +0,0 @@ ---/* c-isr library stuff of Andes NDS32 cpu for GNU compiler --- Copyright (C) 2012-2016 Free Software Foundation, Inc. --- Contributed by Andes Technology Corporation. --- --- This file is part of GCC. --- --- GCC is free software; you can redistribute it and/or modify it --- under the terms of the GNU General Public License as published --- by the Free Software Foundation; either version 3, or (at your --- option) any later version. --- --- GCC is distributed in the hope that it will be useful, but WITHOUT --- ANY WARRANTY; without even the implied warranty of MERCHANTABILITY --- or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public --- License for more details. --- --- Under Section 7 of GPL version 3, you are granted additional --- permissions described in the GCC Runtime Library Exception, version --- 3.1, as published by the Free Software Foundation. --- --- You should have received a copy of the GNU General Public License and --- a copy of the GCC Runtime Library Exception along with this program; --- see the files COPYING3 and COPYING.RUNTIME respectively. If not, see --- . */ --- --- .section .nds32_vector.07, "ax" --- .vec_size 4 --- .align 2 --- .weak _nds32_vector_07_4b --- .type _nds32_vector_07_4b, @function ---_nds32_vector_07_4b: ---1: --- j 1b --- .size _nds32_vector_07_4b, .-_nds32_vector_07_4b --diff --git a/libgcc/config/nds32/isr-library/vec_vid08.S b/libgcc/config/nds32/isr-library/vec_vid08.S --index 2a30375..b4ae947 100644 ----- a/libgcc/config/nds32/isr-library/vec_vid08.S --+++ b/libgcc/config/nds32/isr-library/vec_vid08.S --@@ -24,8 +24,15 @@ -- . */ -- -- .section .nds32_vector.08, "ax" --+#if __NDS32_ISR_VECTOR_SIZE_4__ --+ /* The vector size is default 4-byte for v3 architecture. */ --+ .vec_size 4 --+ .align 2 --+#else --+ /* The vector size is default 16-byte for other architectures. */ -- .vec_size 16 -- .align 4 --+#endif -- .weak _nds32_vector_08 -- .type _nds32_vector_08, @function -- _nds32_vector_08: --diff --git a/libgcc/config/nds32/isr-library/vec_vid08_4b.S b/libgcc/config/nds32/isr-library/vec_vid08_4b.S --deleted file mode 100644 --index 83546d1..0000000 ----- a/libgcc/config/nds32/isr-library/vec_vid08_4b.S --+++ /dev/null --@@ -1,34 +0,0 @@ ---/* c-isr library stuff of Andes NDS32 cpu for GNU compiler --- Copyright (C) 2012-2016 Free Software Foundation, Inc. --- Contributed by Andes Technology Corporation. --- --- This file is part of GCC. --- --- GCC is free software; you can redistribute it and/or modify it --- under the terms of the GNU General Public License as published --- by the Free Software Foundation; either version 3, or (at your --- option) any later version. --- --- GCC is distributed in the hope that it will be useful, but WITHOUT --- ANY WARRANTY; without even the implied warranty of MERCHANTABILITY --- or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public --- License for more details. --- --- Under Section 7 of GPL version 3, you are granted additional --- permissions described in the GCC Runtime Library Exception, version --- 3.1, as published by the Free Software Foundation. --- --- You should have received a copy of the GNU General Public License and --- a copy of the GCC Runtime Library Exception along with this program; --- see the files COPYING3 and COPYING.RUNTIME respectively. If not, see --- . */ --- --- .section .nds32_vector.08, "ax" --- .vec_size 4 --- .align 2 --- .weak _nds32_vector_08_4b --- .type _nds32_vector_08_4b, @function ---_nds32_vector_08_4b: ---1: --- j 1b --- .size _nds32_vector_08_4b, .-_nds32_vector_08_4b --diff --git a/libgcc/config/nds32/isr-library/vec_vid09.S b/libgcc/config/nds32/isr-library/vec_vid09.S --index 9aeaf78..47fa5c1 100644 ----- a/libgcc/config/nds32/isr-library/vec_vid09.S --+++ b/libgcc/config/nds32/isr-library/vec_vid09.S --@@ -24,8 +24,15 @@ -- . */ -- -- .section .nds32_vector.09, "ax" --+#if __NDS32_ISR_VECTOR_SIZE_4__ --+ /* The vector size is default 4-byte for v3 architecture. */ --+ .vec_size 4 --+ .align 2 --+#else --+ /* The vector size is default 16-byte for other architectures. */ -- .vec_size 16 -- .align 4 --+#endif -- .weak _nds32_vector_09 -- .type _nds32_vector_09, @function -- _nds32_vector_09: --diff --git a/libgcc/config/nds32/isr-library/vec_vid09_4b.S b/libgcc/config/nds32/isr-library/vec_vid09_4b.S --deleted file mode 100644 --index 2d1944f..0000000 ----- a/libgcc/config/nds32/isr-library/vec_vid09_4b.S --+++ /dev/null --@@ -1,34 +0,0 @@ ---/* c-isr library stuff of Andes NDS32 cpu for GNU compiler --- Copyright (C) 2012-2016 Free Software Foundation, Inc. --- Contributed by Andes Technology Corporation. --- --- This file is part of GCC. --- --- GCC is free software; you can redistribute it and/or modify it --- under the terms of the GNU General Public License as published --- by the Free Software Foundation; either version 3, or (at your --- option) any later version. --- --- GCC is distributed in the hope that it will be useful, but WITHOUT --- ANY WARRANTY; without even the implied warranty of MERCHANTABILITY --- or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public --- License for more details. --- --- Under Section 7 of GPL version 3, you are granted additional --- permissions described in the GCC Runtime Library Exception, version --- 3.1, as published by the Free Software Foundation. --- --- You should have received a copy of the GNU General Public License and --- a copy of the GCC Runtime Library Exception along with this program; --- see the files COPYING3 and COPYING.RUNTIME respectively. If not, see --- . */ --- --- .section .nds32_vector.09, "ax" --- .vec_size 4 --- .align 2 --- .weak _nds32_vector_09_4b --- .type _nds32_vector_09_4b, @function ---_nds32_vector_09_4b: ---1: --- j 1b --- .size _nds32_vector_09_4b, .-_nds32_vector_09_4b --diff --git a/libgcc/config/nds32/isr-library/vec_vid10.S b/libgcc/config/nds32/isr-library/vec_vid10.S --index 411edd7..6bf2c7c 100644 ----- a/libgcc/config/nds32/isr-library/vec_vid10.S --+++ b/libgcc/config/nds32/isr-library/vec_vid10.S --@@ -24,8 +24,15 @@ -- . */ -- -- .section .nds32_vector.10, "ax" --+#if __NDS32_ISR_VECTOR_SIZE_4__ --+ /* The vector size is default 4-byte for v3 architecture. */ --+ .vec_size 4 --+ .align 2 --+#else --+ /* The vector size is default 16-byte for other architectures. */ -- .vec_size 16 -- .align 4 --+#endif -- .weak _nds32_vector_10 -- .type _nds32_vector_10, @function -- _nds32_vector_10: --diff --git a/libgcc/config/nds32/isr-library/vec_vid10_4b.S b/libgcc/config/nds32/isr-library/vec_vid10_4b.S --deleted file mode 100644 --index 04761ab..0000000 ----- a/libgcc/config/nds32/isr-library/vec_vid10_4b.S --+++ /dev/null --@@ -1,34 +0,0 @@ ---/* c-isr library stuff of Andes NDS32 cpu for GNU compiler --- Copyright (C) 2012-2016 Free Software Foundation, Inc. --- Contributed by Andes Technology Corporation. --- --- This file is part of GCC. --- --- GCC is free software; you can redistribute it and/or modify it --- under the terms of the GNU General Public License as published --- by the Free Software Foundation; either version 3, or (at your --- option) any later version. --- --- GCC is distributed in the hope that it will be useful, but WITHOUT --- ANY WARRANTY; without even the implied warranty of MERCHANTABILITY --- or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public --- License for more details. --- --- Under Section 7 of GPL version 3, you are granted additional --- permissions described in the GCC Runtime Library Exception, version --- 3.1, as published by the Free Software Foundation. --- --- You should have received a copy of the GNU General Public License and --- a copy of the GCC Runtime Library Exception along with this program; --- see the files COPYING3 and COPYING.RUNTIME respectively. If not, see --- . */ --- --- .section .nds32_vector.10, "ax" --- .vec_size 4 --- .align 2 --- .weak _nds32_vector_10_4b --- .type _nds32_vector_10_4b, @function ---_nds32_vector_10_4b: ---1: --- j 1b --- .size _nds32_vector_10_4b, .-_nds32_vector_10_4b --diff --git a/libgcc/config/nds32/isr-library/vec_vid11.S b/libgcc/config/nds32/isr-library/vec_vid11.S --index 8de45a4..86975ea 100644 ----- a/libgcc/config/nds32/isr-library/vec_vid11.S --+++ b/libgcc/config/nds32/isr-library/vec_vid11.S --@@ -24,8 +24,15 @@ -- . */ -- -- .section .nds32_vector.11, "ax" --+#if __NDS32_ISR_VECTOR_SIZE_4__ --+ /* The vector size is default 4-byte for v3 architecture. */ --+ .vec_size 4 --+ .align 2 --+#else --+ /* The vector size is default 16-byte for other architectures. */ -- .vec_size 16 -- .align 4 --+#endif -- .weak _nds32_vector_11 -- .type _nds32_vector_11, @function -- _nds32_vector_11: --diff --git a/libgcc/config/nds32/isr-library/vec_vid11_4b.S b/libgcc/config/nds32/isr-library/vec_vid11_4b.S --deleted file mode 100644 --index 328c1e6..0000000 ----- a/libgcc/config/nds32/isr-library/vec_vid11_4b.S --+++ /dev/null --@@ -1,34 +0,0 @@ ---/* c-isr library stuff of Andes NDS32 cpu for GNU compiler --- Copyright (C) 2012-2016 Free Software Foundation, Inc. --- Contributed by Andes Technology Corporation. --- --- This file is part of GCC. --- --- GCC is free software; you can redistribute it and/or modify it --- under the terms of the GNU General Public License as published --- by the Free Software Foundation; either version 3, or (at your --- option) any later version. --- --- GCC is distributed in the hope that it will be useful, but WITHOUT --- ANY WARRANTY; without even the implied warranty of MERCHANTABILITY --- or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public --- License for more details. --- --- Under Section 7 of GPL version 3, you are granted additional --- permissions described in the GCC Runtime Library Exception, version --- 3.1, as published by the Free Software Foundation. --- --- You should have received a copy of the GNU General Public License and --- a copy of the GCC Runtime Library Exception along with this program; --- see the files COPYING3 and COPYING.RUNTIME respectively. If not, see --- . */ --- --- .section .nds32_vector.11, "ax" --- .vec_size 4 --- .align 2 --- .weak _nds32_vector_11_4b --- .type _nds32_vector_11_4b, @function ---_nds32_vector_11_4b: ---1: --- j 1b --- .size _nds32_vector_11_4b, .-_nds32_vector_11_4b --diff --git a/libgcc/config/nds32/isr-library/vec_vid12.S b/libgcc/config/nds32/isr-library/vec_vid12.S --index ff5c6df..07cb7de 100644 ----- a/libgcc/config/nds32/isr-library/vec_vid12.S --+++ b/libgcc/config/nds32/isr-library/vec_vid12.S --@@ -24,8 +24,15 @@ -- . */ -- -- .section .nds32_vector.12, "ax" --+#if __NDS32_ISR_VECTOR_SIZE_4__ --+ /* The vector size is default 4-byte for v3 architecture. */ --+ .vec_size 4 --+ .align 2 --+#else --+ /* The vector size is default 16-byte for other architectures. */ -- .vec_size 16 -- .align 4 --+#endif -- .weak _nds32_vector_12 -- .type _nds32_vector_12, @function -- _nds32_vector_12: --diff --git a/libgcc/config/nds32/isr-library/vec_vid12_4b.S b/libgcc/config/nds32/isr-library/vec_vid12_4b.S --deleted file mode 100644 --index 52b7d23..0000000 ----- a/libgcc/config/nds32/isr-library/vec_vid12_4b.S --+++ /dev/null --@@ -1,34 +0,0 @@ ---/* c-isr library stuff of Andes NDS32 cpu for GNU compiler --- Copyright (C) 2012-2016 Free Software Foundation, Inc. --- Contributed by Andes Technology Corporation. --- --- This file is part of GCC. --- --- GCC is free software; you can redistribute it and/or modify it --- under the terms of the GNU General Public License as published --- by the Free Software Foundation; either version 3, or (at your --- option) any later version. --- --- GCC is distributed in the hope that it will be useful, but WITHOUT --- ANY WARRANTY; without even the implied warranty of MERCHANTABILITY --- or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public --- License for more details. --- --- Under Section 7 of GPL version 3, you are granted additional --- permissions described in the GCC Runtime Library Exception, version --- 3.1, as published by the Free Software Foundation. --- --- You should have received a copy of the GNU General Public License and --- a copy of the GCC Runtime Library Exception along with this program; --- see the files COPYING3 and COPYING.RUNTIME respectively. If not, see --- . */ --- --- .section .nds32_vector.12, "ax" --- .vec_size 4 --- .align 2 --- .weak _nds32_vector_12_4b --- .type _nds32_vector_12_4b, @function ---_nds32_vector_12_4b: ---1: --- j 1b --- .size _nds32_vector_12_4b, .-_nds32_vector_12_4b --diff --git a/libgcc/config/nds32/isr-library/vec_vid13.S b/libgcc/config/nds32/isr-library/vec_vid13.S --index 66014c3..5ac1a83 100644 ----- a/libgcc/config/nds32/isr-library/vec_vid13.S --+++ b/libgcc/config/nds32/isr-library/vec_vid13.S --@@ -24,8 +24,15 @@ -- . */ -- -- .section .nds32_vector.13, "ax" --+#if __NDS32_ISR_VECTOR_SIZE_4__ --+ /* The vector size is default 4-byte for v3 architecture. */ --+ .vec_size 4 --+ .align 2 --+#else --+ /* The vector size is default 16-byte for other architectures. */ -- .vec_size 16 -- .align 4 --+#endif -- .weak _nds32_vector_13 -- .type _nds32_vector_13, @function -- _nds32_vector_13: --diff --git a/libgcc/config/nds32/isr-library/vec_vid13_4b.S b/libgcc/config/nds32/isr-library/vec_vid13_4b.S --deleted file mode 100644 --index 59029ad..0000000 ----- a/libgcc/config/nds32/isr-library/vec_vid13_4b.S --+++ /dev/null --@@ -1,34 +0,0 @@ ---/* c-isr library stuff of Andes NDS32 cpu for GNU compiler --- Copyright (C) 2012-2016 Free Software Foundation, Inc. --- Contributed by Andes Technology Corporation. --- --- This file is part of GCC. --- --- GCC is free software; you can redistribute it and/or modify it --- under the terms of the GNU General Public License as published --- by the Free Software Foundation; either version 3, or (at your --- option) any later version. --- --- GCC is distributed in the hope that it will be useful, but WITHOUT --- ANY WARRANTY; without even the implied warranty of MERCHANTABILITY --- or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public --- License for more details. --- --- Under Section 7 of GPL version 3, you are granted additional --- permissions described in the GCC Runtime Library Exception, version --- 3.1, as published by the Free Software Foundation. --- --- You should have received a copy of the GNU General Public License and --- a copy of the GCC Runtime Library Exception along with this program; --- see the files COPYING3 and COPYING.RUNTIME respectively. If not, see --- . */ --- --- .section .nds32_vector.13, "ax" --- .vec_size 4 --- .align 2 --- .weak _nds32_vector_13_4b --- .type _nds32_vector_13_4b, @function ---_nds32_vector_13_4b: ---1: --- j 1b --- .size _nds32_vector_13_4b, .-_nds32_vector_13_4b --diff --git a/libgcc/config/nds32/isr-library/vec_vid14.S b/libgcc/config/nds32/isr-library/vec_vid14.S --index ca6f66f..5116f2f 100644 ----- a/libgcc/config/nds32/isr-library/vec_vid14.S --+++ b/libgcc/config/nds32/isr-library/vec_vid14.S --@@ -24,8 +24,15 @@ -- . */ -- -- .section .nds32_vector.14, "ax" --+#if __NDS32_ISR_VECTOR_SIZE_4__ --+ /* The vector size is default 4-byte for v3 architecture. */ --+ .vec_size 4 --+ .align 2 --+#else --+ /* The vector size is default 16-byte for other architectures. */ -- .vec_size 16 -- .align 4 --+#endif -- .weak _nds32_vector_14 -- .type _nds32_vector_14, @function -- _nds32_vector_14: --diff --git a/libgcc/config/nds32/isr-library/vec_vid14_4b.S b/libgcc/config/nds32/isr-library/vec_vid14_4b.S --deleted file mode 100644 --index 0d2afe4..0000000 ----- a/libgcc/config/nds32/isr-library/vec_vid14_4b.S --+++ /dev/null --@@ -1,34 +0,0 @@ ---/* c-isr library stuff of Andes NDS32 cpu for GNU compiler --- Copyright (C) 2012-2016 Free Software Foundation, Inc. --- Contributed by Andes Technology Corporation. --- --- This file is part of GCC. --- --- GCC is free software; you can redistribute it and/or modify it --- under the terms of the GNU General Public License as published --- by the Free Software Foundation; either version 3, or (at your --- option) any later version. --- --- GCC is distributed in the hope that it will be useful, but WITHOUT --- ANY WARRANTY; without even the implied warranty of MERCHANTABILITY --- or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public --- License for more details. --- --- Under Section 7 of GPL version 3, you are granted additional --- permissions described in the GCC Runtime Library Exception, version --- 3.1, as published by the Free Software Foundation. --- --- You should have received a copy of the GNU General Public License and --- a copy of the GCC Runtime Library Exception along with this program; --- see the files COPYING3 and COPYING.RUNTIME respectively. If not, see --- . */ --- --- .section .nds32_vector.14, "ax" --- .vec_size 4 --- .align 2 --- .weak _nds32_vector_14_4b --- .type _nds32_vector_14_4b, @function ---_nds32_vector_14_4b: ---1: --- j 1b --- .size _nds32_vector_14_4b, .-_nds32_vector_14_4b --diff --git a/libgcc/config/nds32/isr-library/vec_vid15.S b/libgcc/config/nds32/isr-library/vec_vid15.S --index c94b42a..03449c0 100644 ----- a/libgcc/config/nds32/isr-library/vec_vid15.S --+++ b/libgcc/config/nds32/isr-library/vec_vid15.S --@@ -24,8 +24,15 @@ -- . */ -- -- .section .nds32_vector.15, "ax" --+#if __NDS32_ISR_VECTOR_SIZE_4__ --+ /* The vector size is default 4-byte for v3 architecture. */ --+ .vec_size 4 --+ .align 2 --+#else --+ /* The vector size is default 16-byte for other architectures. */ -- .vec_size 16 -- .align 4 --+#endif -- .weak _nds32_vector_15 -- .type _nds32_vector_15, @function -- _nds32_vector_15: --diff --git a/libgcc/config/nds32/isr-library/vec_vid15_4b.S b/libgcc/config/nds32/isr-library/vec_vid15_4b.S --deleted file mode 100644 --index 60799d7..0000000 ----- a/libgcc/config/nds32/isr-library/vec_vid15_4b.S --+++ /dev/null --@@ -1,34 +0,0 @@ ---/* c-isr library stuff of Andes NDS32 cpu for GNU compiler --- Copyright (C) 2012-2016 Free Software Foundation, Inc. --- Contributed by Andes Technology Corporation. --- --- This file is part of GCC. --- --- GCC is free software; you can redistribute it and/or modify it --- under the terms of the GNU General Public License as published --- by the Free Software Foundation; either version 3, or (at your --- option) any later version. --- --- GCC is distributed in the hope that it will be useful, but WITHOUT --- ANY WARRANTY; without even the implied warranty of MERCHANTABILITY --- or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public --- License for more details. --- --- Under Section 7 of GPL version 3, you are granted additional --- permissions described in the GCC Runtime Library Exception, version --- 3.1, as published by the Free Software Foundation. --- --- You should have received a copy of the GNU General Public License and --- a copy of the GCC Runtime Library Exception along with this program; --- see the files COPYING3 and COPYING.RUNTIME respectively. If not, see --- . */ --- --- .section .nds32_vector.15, "ax" --- .vec_size 4 --- .align 2 --- .weak _nds32_vector_15_4b --- .type _nds32_vector_15_4b, @function ---_nds32_vector_15_4b: ---1: --- j 1b --- .size _nds32_vector_15_4b, .-_nds32_vector_15_4b --diff --git a/libgcc/config/nds32/isr-library/vec_vid16.S b/libgcc/config/nds32/isr-library/vec_vid16.S --index f19454d..b01d673 100644 ----- a/libgcc/config/nds32/isr-library/vec_vid16.S --+++ b/libgcc/config/nds32/isr-library/vec_vid16.S --@@ -24,8 +24,15 @@ -- . */ -- -- .section .nds32_vector.16, "ax" --+#if __NDS32_ISR_VECTOR_SIZE_4__ --+ /* The vector size is default 4-byte for v3 architecture. */ --+ .vec_size 4 --+ .align 2 --+#else --+ /* The vector size is default 16-byte for other architectures. */ -- .vec_size 16 -- .align 4 --+#endif -- .weak _nds32_vector_16 -- .type _nds32_vector_16, @function -- _nds32_vector_16: --diff --git a/libgcc/config/nds32/isr-library/vec_vid16_4b.S b/libgcc/config/nds32/isr-library/vec_vid16_4b.S --deleted file mode 100644 --index 6791204..0000000 ----- a/libgcc/config/nds32/isr-library/vec_vid16_4b.S --+++ /dev/null --@@ -1,34 +0,0 @@ ---/* c-isr library stuff of Andes NDS32 cpu for GNU compiler --- Copyright (C) 2012-2016 Free Software Foundation, Inc. --- Contributed by Andes Technology Corporation. --- --- This file is part of GCC. --- --- GCC is free software; you can redistribute it and/or modify it --- under the terms of the GNU General Public License as published --- by the Free Software Foundation; either version 3, or (at your --- option) any later version. --- --- GCC is distributed in the hope that it will be useful, but WITHOUT --- ANY WARRANTY; without even the implied warranty of MERCHANTABILITY --- or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public --- License for more details. --- --- Under Section 7 of GPL version 3, you are granted additional --- permissions described in the GCC Runtime Library Exception, version --- 3.1, as published by the Free Software Foundation. --- --- You should have received a copy of the GNU General Public License and --- a copy of the GCC Runtime Library Exception along with this program; --- see the files COPYING3 and COPYING.RUNTIME respectively. If not, see --- . */ --- --- .section .nds32_vector.16, "ax" --- .vec_size 4 --- .align 2 --- .weak _nds32_vector_16_4b --- .type _nds32_vector_16_4b, @function ---_nds32_vector_16_4b: ---1: --- j 1b --- .size _nds32_vector_16_4b, .-_nds32_vector_16_4b --diff --git a/libgcc/config/nds32/isr-library/vec_vid17.S b/libgcc/config/nds32/isr-library/vec_vid17.S --index 486a0aa..c6ed785 100644 ----- a/libgcc/config/nds32/isr-library/vec_vid17.S --+++ b/libgcc/config/nds32/isr-library/vec_vid17.S --@@ -24,8 +24,15 @@ -- . */ -- -- .section .nds32_vector.17, "ax" --+#if __NDS32_ISR_VECTOR_SIZE_4__ --+ /* The vector size is default 4-byte for v3 architecture. */ --+ .vec_size 4 --+ .align 2 --+#else --+ /* The vector size is default 16-byte for other architectures. */ -- .vec_size 16 -- .align 4 --+#endif -- .weak _nds32_vector_17 -- .type _nds32_vector_17, @function -- _nds32_vector_17: --diff --git a/libgcc/config/nds32/isr-library/vec_vid17_4b.S b/libgcc/config/nds32/isr-library/vec_vid17_4b.S --deleted file mode 100644 --index 04f4285..0000000 ----- a/libgcc/config/nds32/isr-library/vec_vid17_4b.S --+++ /dev/null --@@ -1,34 +0,0 @@ ---/* c-isr library stuff of Andes NDS32 cpu for GNU compiler --- Copyright (C) 2012-2016 Free Software Foundation, Inc. --- Contributed by Andes Technology Corporation. --- --- This file is part of GCC. --- --- GCC is free software; you can redistribute it and/or modify it --- under the terms of the GNU General Public License as published --- by the Free Software Foundation; either version 3, or (at your --- option) any later version. --- --- GCC is distributed in the hope that it will be useful, but WITHOUT --- ANY WARRANTY; without even the implied warranty of MERCHANTABILITY --- or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public --- License for more details. --- --- Under Section 7 of GPL version 3, you are granted additional --- permissions described in the GCC Runtime Library Exception, version --- 3.1, as published by the Free Software Foundation. --- --- You should have received a copy of the GNU General Public License and --- a copy of the GCC Runtime Library Exception along with this program; --- see the files COPYING3 and COPYING.RUNTIME respectively. If not, see --- . */ --- --- .section .nds32_vector.17, "ax" --- .vec_size 4 --- .align 2 --- .weak _nds32_vector_17_4b --- .type _nds32_vector_17_4b, @function ---_nds32_vector_17_4b: ---1: --- j 1b --- .size _nds32_vector_17_4b, .-_nds32_vector_17_4b --diff --git a/libgcc/config/nds32/isr-library/vec_vid18.S b/libgcc/config/nds32/isr-library/vec_vid18.S --index 137511f..e0e7b7e 100644 ----- a/libgcc/config/nds32/isr-library/vec_vid18.S --+++ b/libgcc/config/nds32/isr-library/vec_vid18.S --@@ -24,8 +24,15 @@ -- . */ -- -- .section .nds32_vector.18, "ax" --+#if __NDS32_ISR_VECTOR_SIZE_4__ --+ /* The vector size is default 4-byte for v3 architecture. */ --+ .vec_size 4 --+ .align 2 --+#else --+ /* The vector size is default 16-byte for other architectures. */ -- .vec_size 16 -- .align 4 --+#endif -- .weak _nds32_vector_18 -- .type _nds32_vector_18, @function -- _nds32_vector_18: --diff --git a/libgcc/config/nds32/isr-library/vec_vid18_4b.S b/libgcc/config/nds32/isr-library/vec_vid18_4b.S --deleted file mode 100644 --index 4d80192..0000000 ----- a/libgcc/config/nds32/isr-library/vec_vid18_4b.S --+++ /dev/null --@@ -1,34 +0,0 @@ ---/* c-isr library stuff of Andes NDS32 cpu for GNU compiler --- Copyright (C) 2012-2016 Free Software Foundation, Inc. --- Contributed by Andes Technology Corporation. --- --- This file is part of GCC. --- --- GCC is free software; you can redistribute it and/or modify it --- under the terms of the GNU General Public License as published --- by the Free Software Foundation; either version 3, or (at your --- option) any later version. --- --- GCC is distributed in the hope that it will be useful, but WITHOUT --- ANY WARRANTY; without even the implied warranty of MERCHANTABILITY --- or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public --- License for more details. --- --- Under Section 7 of GPL version 3, you are granted additional --- permissions described in the GCC Runtime Library Exception, version --- 3.1, as published by the Free Software Foundation. --- --- You should have received a copy of the GNU General Public License and --- a copy of the GCC Runtime Library Exception along with this program; --- see the files COPYING3 and COPYING.RUNTIME respectively. If not, see --- . */ --- --- .section .nds32_vector.18, "ax" --- .vec_size 4 --- .align 2 --- .weak _nds32_vector_18_4b --- .type _nds32_vector_18_4b, @function ---_nds32_vector_18_4b: ---1: --- j 1b --- .size _nds32_vector_18_4b, .-_nds32_vector_18_4b --diff --git a/libgcc/config/nds32/isr-library/vec_vid19.S b/libgcc/config/nds32/isr-library/vec_vid19.S --index 791e135..ef7075f 100644 ----- a/libgcc/config/nds32/isr-library/vec_vid19.S --+++ b/libgcc/config/nds32/isr-library/vec_vid19.S --@@ -24,8 +24,15 @@ -- . */ -- -- .section .nds32_vector.19, "ax" --+#if __NDS32_ISR_VECTOR_SIZE_4__ --+ /* The vector size is default 4-byte for v3 architecture. */ --+ .vec_size 4 --+ .align 2 --+#else --+ /* The vector size is default 16-byte for other architectures. */ -- .vec_size 16 -- .align 4 --+#endif -- .weak _nds32_vector_19 -- .type _nds32_vector_19, @function -- _nds32_vector_19: --diff --git a/libgcc/config/nds32/isr-library/vec_vid19_4b.S b/libgcc/config/nds32/isr-library/vec_vid19_4b.S --deleted file mode 100644 --index 87d4c7c..0000000 ----- a/libgcc/config/nds32/isr-library/vec_vid19_4b.S --+++ /dev/null --@@ -1,34 +0,0 @@ ---/* c-isr library stuff of Andes NDS32 cpu for GNU compiler --- Copyright (C) 2012-2016 Free Software Foundation, Inc. --- Contributed by Andes Technology Corporation. --- --- This file is part of GCC. --- --- GCC is free software; you can redistribute it and/or modify it --- under the terms of the GNU General Public License as published --- by the Free Software Foundation; either version 3, or (at your --- option) any later version. --- --- GCC is distributed in the hope that it will be useful, but WITHOUT --- ANY WARRANTY; without even the implied warranty of MERCHANTABILITY --- or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public --- License for more details. --- --- Under Section 7 of GPL version 3, you are granted additional --- permissions described in the GCC Runtime Library Exception, version --- 3.1, as published by the Free Software Foundation. --- --- You should have received a copy of the GNU General Public License and --- a copy of the GCC Runtime Library Exception along with this program; --- see the files COPYING3 and COPYING.RUNTIME respectively. If not, see --- . */ --- --- .section .nds32_vector.19, "ax" --- .vec_size 4 --- .align 2 --- .weak _nds32_vector_19_4b --- .type _nds32_vector_19_4b, @function ---_nds32_vector_19_4b: ---1: --- j 1b --- .size _nds32_vector_19_4b, .-_nds32_vector_19_4b --diff --git a/libgcc/config/nds32/isr-library/vec_vid20.S b/libgcc/config/nds32/isr-library/vec_vid20.S --index e7ab0e3..99bcf01 100644 ----- a/libgcc/config/nds32/isr-library/vec_vid20.S --+++ b/libgcc/config/nds32/isr-library/vec_vid20.S --@@ -24,8 +24,15 @@ -- . */ -- -- .section .nds32_vector.20, "ax" --+#if __NDS32_ISR_VECTOR_SIZE_4__ --+ /* The vector size is default 4-byte for v3 architecture. */ --+ .vec_size 4 --+ .align 2 --+#else --+ /* The vector size is default 16-byte for other architectures. */ -- .vec_size 16 -- .align 4 --+#endif -- .weak _nds32_vector_20 -- .type _nds32_vector_20, @function -- _nds32_vector_20: --diff --git a/libgcc/config/nds32/isr-library/vec_vid20_4b.S b/libgcc/config/nds32/isr-library/vec_vid20_4b.S --deleted file mode 100644 --index 308385a..0000000 ----- a/libgcc/config/nds32/isr-library/vec_vid20_4b.S --+++ /dev/null --@@ -1,34 +0,0 @@ ---/* c-isr library stuff of Andes NDS32 cpu for GNU compiler --- Copyright (C) 2012-2016 Free Software Foundation, Inc. --- Contributed by Andes Technology Corporation. --- --- This file is part of GCC. --- --- GCC is free software; you can redistribute it and/or modify it --- under the terms of the GNU General Public License as published --- by the Free Software Foundation; either version 3, or (at your --- option) any later version. --- --- GCC is distributed in the hope that it will be useful, but WITHOUT --- ANY WARRANTY; without even the implied warranty of MERCHANTABILITY --- or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public --- License for more details. --- --- Under Section 7 of GPL version 3, you are granted additional --- permissions described in the GCC Runtime Library Exception, version --- 3.1, as published by the Free Software Foundation. --- --- You should have received a copy of the GNU General Public License and --- a copy of the GCC Runtime Library Exception along with this program; --- see the files COPYING3 and COPYING.RUNTIME respectively. If not, see --- . */ --- --- .section .nds32_vector.20, "ax" --- .vec_size 4 --- .align 2 --- .weak _nds32_vector_20_4b --- .type _nds32_vector_20_4b, @function ---_nds32_vector_20_4b: ---1: --- j 1b --- .size _nds32_vector_20_4b, .-_nds32_vector_20_4b --diff --git a/libgcc/config/nds32/isr-library/vec_vid21.S b/libgcc/config/nds32/isr-library/vec_vid21.S --index 315ae56..8c66bef 100644 ----- a/libgcc/config/nds32/isr-library/vec_vid21.S --+++ b/libgcc/config/nds32/isr-library/vec_vid21.S --@@ -24,8 +24,15 @@ -- . */ -- -- .section .nds32_vector.21, "ax" --+#if __NDS32_ISR_VECTOR_SIZE_4__ --+ /* The vector size is default 4-byte for v3 architecture. */ --+ .vec_size 4 --+ .align 2 --+#else --+ /* The vector size is default 16-byte for other architectures. */ -- .vec_size 16 -- .align 4 --+#endif -- .weak _nds32_vector_21 -- .type _nds32_vector_21, @function -- _nds32_vector_21: --diff --git a/libgcc/config/nds32/isr-library/vec_vid21_4b.S b/libgcc/config/nds32/isr-library/vec_vid21_4b.S --deleted file mode 100644 --index 16cf02a..0000000 ----- a/libgcc/config/nds32/isr-library/vec_vid21_4b.S --+++ /dev/null --@@ -1,34 +0,0 @@ ---/* c-isr library stuff of Andes NDS32 cpu for GNU compiler --- Copyright (C) 2012-2016 Free Software Foundation, Inc. --- Contributed by Andes Technology Corporation. --- --- This file is part of GCC. --- --- GCC is free software; you can redistribute it and/or modify it --- under the terms of the GNU General Public License as published --- by the Free Software Foundation; either version 3, or (at your --- option) any later version. --- --- GCC is distributed in the hope that it will be useful, but WITHOUT --- ANY WARRANTY; without even the implied warranty of MERCHANTABILITY --- or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public --- License for more details. --- --- Under Section 7 of GPL version 3, you are granted additional --- permissions described in the GCC Runtime Library Exception, version --- 3.1, as published by the Free Software Foundation. --- --- You should have received a copy of the GNU General Public License and --- a copy of the GCC Runtime Library Exception along with this program; --- see the files COPYING3 and COPYING.RUNTIME respectively. If not, see --- . */ --- --- .section .nds32_vector.21, "ax" --- .vec_size 4 --- .align 2 --- .weak _nds32_vector_21_4b --- .type _nds32_vector_21_4b, @function ---_nds32_vector_21_4b: ---1: --- j 1b --- .size _nds32_vector_21_4b, .-_nds32_vector_21_4b --diff --git a/libgcc/config/nds32/isr-library/vec_vid22.S b/libgcc/config/nds32/isr-library/vec_vid22.S --index 6f9de85..5c442ce 100644 ----- a/libgcc/config/nds32/isr-library/vec_vid22.S --+++ b/libgcc/config/nds32/isr-library/vec_vid22.S --@@ -24,8 +24,15 @@ -- . */ -- -- .section .nds32_vector.22, "ax" --+#if __NDS32_ISR_VECTOR_SIZE_4__ --+ /* The vector size is default 4-byte for v3 architecture. */ --+ .vec_size 4 --+ .align 2 --+#else --+ /* The vector size is default 16-byte for other architectures. */ -- .vec_size 16 -- .align 4 --+#endif -- .weak _nds32_vector_22 -- .type _nds32_vector_22, @function -- _nds32_vector_22: --diff --git a/libgcc/config/nds32/isr-library/vec_vid22_4b.S b/libgcc/config/nds32/isr-library/vec_vid22_4b.S --deleted file mode 100644 --index 587ee7f..0000000 ----- a/libgcc/config/nds32/isr-library/vec_vid22_4b.S --+++ /dev/null --@@ -1,34 +0,0 @@ ---/* c-isr library stuff of Andes NDS32 cpu for GNU compiler --- Copyright (C) 2012-2016 Free Software Foundation, Inc. --- Contributed by Andes Technology Corporation. --- --- This file is part of GCC. --- --- GCC is free software; you can redistribute it and/or modify it --- under the terms of the GNU General Public License as published --- by the Free Software Foundation; either version 3, or (at your --- option) any later version. --- --- GCC is distributed in the hope that it will be useful, but WITHOUT --- ANY WARRANTY; without even the implied warranty of MERCHANTABILITY --- or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public --- License for more details. --- --- Under Section 7 of GPL version 3, you are granted additional --- permissions described in the GCC Runtime Library Exception, version --- 3.1, as published by the Free Software Foundation. --- --- You should have received a copy of the GNU General Public License and --- a copy of the GCC Runtime Library Exception along with this program; --- see the files COPYING3 and COPYING.RUNTIME respectively. If not, see --- . */ --- --- .section .nds32_vector.22, "ax" --- .vec_size 4 --- .align 2 --- .weak _nds32_vector_22_4b --- .type _nds32_vector_22_4b, @function ---_nds32_vector_22_4b: ---1: --- j 1b --- .size _nds32_vector_22_4b, .-_nds32_vector_22_4b --diff --git a/libgcc/config/nds32/isr-library/vec_vid23.S b/libgcc/config/nds32/isr-library/vec_vid23.S --index 956b585..c5d73df 100644 ----- a/libgcc/config/nds32/isr-library/vec_vid23.S --+++ b/libgcc/config/nds32/isr-library/vec_vid23.S --@@ -24,8 +24,15 @@ -- . */ -- -- .section .nds32_vector.23, "ax" --+#if __NDS32_ISR_VECTOR_SIZE_4__ --+ /* The vector size is default 4-byte for v3 architecture. */ --+ .vec_size 4 --+ .align 2 --+#else --+ /* The vector size is default 16-byte for other architectures. */ -- .vec_size 16 -- .align 4 --+#endif -- .weak _nds32_vector_23 -- .type _nds32_vector_23, @function -- _nds32_vector_23: --diff --git a/libgcc/config/nds32/isr-library/vec_vid23_4b.S b/libgcc/config/nds32/isr-library/vec_vid23_4b.S --deleted file mode 100644 --index 5e4b643..0000000 ----- a/libgcc/config/nds32/isr-library/vec_vid23_4b.S --+++ /dev/null --@@ -1,34 +0,0 @@ ---/* c-isr library stuff of Andes NDS32 cpu for GNU compiler --- Copyright (C) 2012-2016 Free Software Foundation, Inc. --- Contributed by Andes Technology Corporation. --- --- This file is part of GCC. --- --- GCC is free software; you can redistribute it and/or modify it --- under the terms of the GNU General Public License as published --- by the Free Software Foundation; either version 3, or (at your --- option) any later version. --- --- GCC is distributed in the hope that it will be useful, but WITHOUT --- ANY WARRANTY; without even the implied warranty of MERCHANTABILITY --- or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public --- License for more details. --- --- Under Section 7 of GPL version 3, you are granted additional --- permissions described in the GCC Runtime Library Exception, version --- 3.1, as published by the Free Software Foundation. --- --- You should have received a copy of the GNU General Public License and --- a copy of the GCC Runtime Library Exception along with this program; --- see the files COPYING3 and COPYING.RUNTIME respectively. If not, see --- . */ --- --- .section .nds32_vector.23, "ax" --- .vec_size 4 --- .align 2 --- .weak _nds32_vector_23_4b --- .type _nds32_vector_23_4b, @function ---_nds32_vector_23_4b: ---1: --- j 1b --- .size _nds32_vector_23_4b, .-_nds32_vector_23_4b --diff --git a/libgcc/config/nds32/isr-library/vec_vid24.S b/libgcc/config/nds32/isr-library/vec_vid24.S --index 57086e9..fe7dada 100644 ----- a/libgcc/config/nds32/isr-library/vec_vid24.S --+++ b/libgcc/config/nds32/isr-library/vec_vid24.S --@@ -24,8 +24,15 @@ -- . */ -- -- .section .nds32_vector.24, "ax" --+#if __NDS32_ISR_VECTOR_SIZE_4__ --+ /* The vector size is default 4-byte for v3 architecture. */ --+ .vec_size 4 --+ .align 2 --+#else --+ /* The vector size is default 16-byte for other architectures. */ -- .vec_size 16 -- .align 4 --+#endif -- .weak _nds32_vector_24 -- .type _nds32_vector_24, @function -- _nds32_vector_24: --diff --git a/libgcc/config/nds32/isr-library/vec_vid24_4b.S b/libgcc/config/nds32/isr-library/vec_vid24_4b.S --deleted file mode 100644 --index 43495f9..0000000 ----- a/libgcc/config/nds32/isr-library/vec_vid24_4b.S --+++ /dev/null --@@ -1,34 +0,0 @@ ---/* c-isr library stuff of Andes NDS32 cpu for GNU compiler --- Copyright (C) 2012-2016 Free Software Foundation, Inc. --- Contributed by Andes Technology Corporation. --- --- This file is part of GCC. --- --- GCC is free software; you can redistribute it and/or modify it --- under the terms of the GNU General Public License as published --- by the Free Software Foundation; either version 3, or (at your --- option) any later version. --- --- GCC is distributed in the hope that it will be useful, but WITHOUT --- ANY WARRANTY; without even the implied warranty of MERCHANTABILITY --- or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public --- License for more details. --- --- Under Section 7 of GPL version 3, you are granted additional --- permissions described in the GCC Runtime Library Exception, version --- 3.1, as published by the Free Software Foundation. --- --- You should have received a copy of the GNU General Public License and --- a copy of the GCC Runtime Library Exception along with this program; --- see the files COPYING3 and COPYING.RUNTIME respectively. If not, see --- . */ --- --- .section .nds32_vector.24, "ax" --- .vec_size 4 --- .align 2 --- .weak _nds32_vector_24_4b --- .type _nds32_vector_24_4b, @function ---_nds32_vector_24_4b: ---1: --- j 1b --- .size _nds32_vector_24_4b, .-_nds32_vector_24_4b --diff --git a/libgcc/config/nds32/isr-library/vec_vid25.S b/libgcc/config/nds32/isr-library/vec_vid25.S --index 61fa526..ada24e4 100644 ----- a/libgcc/config/nds32/isr-library/vec_vid25.S --+++ b/libgcc/config/nds32/isr-library/vec_vid25.S --@@ -24,8 +24,15 @@ -- . */ -- -- .section .nds32_vector.25, "ax" --+#if __NDS32_ISR_VECTOR_SIZE_4__ --+ /* The vector size is default 4-byte for v3 architecture. */ --+ .vec_size 4 --+ .align 2 --+#else --+ /* The vector size is default 16-byte for other architectures. */ -- .vec_size 16 -- .align 4 --+#endif -- .weak _nds32_vector_25 -- .type _nds32_vector_25, @function -- _nds32_vector_25: --diff --git a/libgcc/config/nds32/isr-library/vec_vid25_4b.S b/libgcc/config/nds32/isr-library/vec_vid25_4b.S --deleted file mode 100644 --index 1ce6cf3..0000000 ----- a/libgcc/config/nds32/isr-library/vec_vid25_4b.S --+++ /dev/null --@@ -1,34 +0,0 @@ ---/* c-isr library stuff of Andes NDS32 cpu for GNU compiler --- Copyright (C) 2012-2016 Free Software Foundation, Inc. --- Contributed by Andes Technology Corporation. --- --- This file is part of GCC. --- --- GCC is free software; you can redistribute it and/or modify it --- under the terms of the GNU General Public License as published --- by the Free Software Foundation; either version 3, or (at your --- option) any later version. --- --- GCC is distributed in the hope that it will be useful, but WITHOUT --- ANY WARRANTY; without even the implied warranty of MERCHANTABILITY --- or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public --- License for more details. --- --- Under Section 7 of GPL version 3, you are granted additional --- permissions described in the GCC Runtime Library Exception, version --- 3.1, as published by the Free Software Foundation. --- --- You should have received a copy of the GNU General Public License and --- a copy of the GCC Runtime Library Exception along with this program; --- see the files COPYING3 and COPYING.RUNTIME respectively. If not, see --- . */ --- --- .section .nds32_vector.25, "ax" --- .vec_size 4 --- .align 2 --- .weak _nds32_vector_25_4b --- .type _nds32_vector_25_4b, @function ---_nds32_vector_25_4b: ---1: --- j 1b --- .size _nds32_vector_25_4b, .-_nds32_vector_25_4b --diff --git a/libgcc/config/nds32/isr-library/vec_vid26.S b/libgcc/config/nds32/isr-library/vec_vid26.S --index 3d9191d..1f97945 100644 ----- a/libgcc/config/nds32/isr-library/vec_vid26.S --+++ b/libgcc/config/nds32/isr-library/vec_vid26.S --@@ -24,8 +24,15 @@ -- . */ -- -- .section .nds32_vector.26, "ax" --+#if __NDS32_ISR_VECTOR_SIZE_4__ --+ /* The vector size is default 4-byte for v3 architecture. */ --+ .vec_size 4 --+ .align 2 --+#else --+ /* The vector size is default 16-byte for other architectures. */ -- .vec_size 16 -- .align 4 --+#endif -- .weak _nds32_vector_26 -- .type _nds32_vector_26, @function -- _nds32_vector_26: --diff --git a/libgcc/config/nds32/isr-library/vec_vid26_4b.S b/libgcc/config/nds32/isr-library/vec_vid26_4b.S --deleted file mode 100644 --index 5803247..0000000 ----- a/libgcc/config/nds32/isr-library/vec_vid26_4b.S --+++ /dev/null --@@ -1,34 +0,0 @@ ---/* c-isr library stuff of Andes NDS32 cpu for GNU compiler --- Copyright (C) 2012-2016 Free Software Foundation, Inc. --- Contributed by Andes Technology Corporation. --- --- This file is part of GCC. --- --- GCC is free software; you can redistribute it and/or modify it --- under the terms of the GNU General Public License as published --- by the Free Software Foundation; either version 3, or (at your --- option) any later version. --- --- GCC is distributed in the hope that it will be useful, but WITHOUT --- ANY WARRANTY; without even the implied warranty of MERCHANTABILITY --- or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public --- License for more details. --- --- Under Section 7 of GPL version 3, you are granted additional --- permissions described in the GCC Runtime Library Exception, version --- 3.1, as published by the Free Software Foundation. --- --- You should have received a copy of the GNU General Public License and --- a copy of the GCC Runtime Library Exception along with this program; --- see the files COPYING3 and COPYING.RUNTIME respectively. If not, see --- . */ --- --- .section .nds32_vector.26, "ax" --- .vec_size 4 --- .align 2 --- .weak _nds32_vector_26_4b --- .type _nds32_vector_26_4b, @function ---_nds32_vector_26_4b: ---1: --- j 1b --- .size _nds32_vector_26_4b, .-_nds32_vector_26_4b --diff --git a/libgcc/config/nds32/isr-library/vec_vid27.S b/libgcc/config/nds32/isr-library/vec_vid27.S --index ff12cfb..f440a8b 100644 ----- a/libgcc/config/nds32/isr-library/vec_vid27.S --+++ b/libgcc/config/nds32/isr-library/vec_vid27.S --@@ -24,8 +24,15 @@ -- . */ -- -- .section .nds32_vector.27, "ax" --+#if __NDS32_ISR_VECTOR_SIZE_4__ --+ /* The vector size is default 4-byte for v3 architecture. */ --+ .vec_size 4 --+ .align 2 --+#else --+ /* The vector size is default 16-byte for other architectures. */ -- .vec_size 16 -- .align 4 --+#endif -- .weak _nds32_vector_27 -- .type _nds32_vector_27, @function -- _nds32_vector_27: --diff --git a/libgcc/config/nds32/isr-library/vec_vid27_4b.S b/libgcc/config/nds32/isr-library/vec_vid27_4b.S --deleted file mode 100644 --index d61e3f9..0000000 ----- a/libgcc/config/nds32/isr-library/vec_vid27_4b.S --+++ /dev/null --@@ -1,34 +0,0 @@ ---/* c-isr library stuff of Andes NDS32 cpu for GNU compiler --- Copyright (C) 2012-2016 Free Software Foundation, Inc. --- Contributed by Andes Technology Corporation. --- --- This file is part of GCC. --- --- GCC is free software; you can redistribute it and/or modify it --- under the terms of the GNU General Public License as published --- by the Free Software Foundation; either version 3, or (at your --- option) any later version. --- --- GCC is distributed in the hope that it will be useful, but WITHOUT --- ANY WARRANTY; without even the implied warranty of MERCHANTABILITY --- or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public --- License for more details. --- --- Under Section 7 of GPL version 3, you are granted additional --- permissions described in the GCC Runtime Library Exception, version --- 3.1, as published by the Free Software Foundation. --- --- You should have received a copy of the GNU General Public License and --- a copy of the GCC Runtime Library Exception along with this program; --- see the files COPYING3 and COPYING.RUNTIME respectively. If not, see --- . */ --- --- .section .nds32_vector.27, "ax" --- .vec_size 4 --- .align 2 --- .weak _nds32_vector_27_4b --- .type _nds32_vector_27_4b, @function ---_nds32_vector_27_4b: ---1: --- j 1b --- .size _nds32_vector_27_4b, .-_nds32_vector_27_4b --diff --git a/libgcc/config/nds32/isr-library/vec_vid28.S b/libgcc/config/nds32/isr-library/vec_vid28.S --index 6b7610e..e1621c7 100644 ----- a/libgcc/config/nds32/isr-library/vec_vid28.S --+++ b/libgcc/config/nds32/isr-library/vec_vid28.S --@@ -24,8 +24,15 @@ -- . */ -- -- .section .nds32_vector.28, "ax" --+#if __NDS32_ISR_VECTOR_SIZE_4__ --+ /* The vector size is default 4-byte for v3 architecture. */ --+ .vec_size 4 --+ .align 2 --+#else --+ /* The vector size is default 16-byte for other architectures. */ -- .vec_size 16 -- .align 4 --+#endif -- .weak _nds32_vector_28 -- .type _nds32_vector_28, @function -- _nds32_vector_28: --diff --git a/libgcc/config/nds32/isr-library/vec_vid28_4b.S b/libgcc/config/nds32/isr-library/vec_vid28_4b.S --deleted file mode 100644 --index a39d015..0000000 ----- a/libgcc/config/nds32/isr-library/vec_vid28_4b.S --+++ /dev/null --@@ -1,34 +0,0 @@ ---/* c-isr library stuff of Andes NDS32 cpu for GNU compiler --- Copyright (C) 2012-2016 Free Software Foundation, Inc. --- Contributed by Andes Technology Corporation. --- --- This file is part of GCC. --- --- GCC is free software; you can redistribute it and/or modify it --- under the terms of the GNU General Public License as published --- by the Free Software Foundation; either version 3, or (at your --- option) any later version. --- --- GCC is distributed in the hope that it will be useful, but WITHOUT --- ANY WARRANTY; without even the implied warranty of MERCHANTABILITY --- or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public --- License for more details. --- --- Under Section 7 of GPL version 3, you are granted additional --- permissions described in the GCC Runtime Library Exception, version --- 3.1, as published by the Free Software Foundation. --- --- You should have received a copy of the GNU General Public License and --- a copy of the GCC Runtime Library Exception along with this program; --- see the files COPYING3 and COPYING.RUNTIME respectively. If not, see --- . */ --- --- .section .nds32_vector.28, "ax" --- .vec_size 4 --- .align 2 --- .weak _nds32_vector_28_4b --- .type _nds32_vector_28_4b, @function ---_nds32_vector_28_4b: ---1: --- j 1b --- .size _nds32_vector_28_4b, .-_nds32_vector_28_4b --diff --git a/libgcc/config/nds32/isr-library/vec_vid29.S b/libgcc/config/nds32/isr-library/vec_vid29.S --index b995841..4fa29c1 100644 ----- a/libgcc/config/nds32/isr-library/vec_vid29.S --+++ b/libgcc/config/nds32/isr-library/vec_vid29.S --@@ -24,8 +24,15 @@ -- . */ -- -- .section .nds32_vector.29, "ax" --+#if __NDS32_ISR_VECTOR_SIZE_4__ --+ /* The vector size is default 4-byte for v3 architecture. */ --+ .vec_size 4 --+ .align 2 --+#else --+ /* The vector size is default 16-byte for other architectures. */ -- .vec_size 16 -- .align 4 --+#endif -- .weak _nds32_vector_29 -- .type _nds32_vector_29, @function -- _nds32_vector_29: --diff --git a/libgcc/config/nds32/isr-library/vec_vid29_4b.S b/libgcc/config/nds32/isr-library/vec_vid29_4b.S --deleted file mode 100644 --index 803f323..0000000 ----- a/libgcc/config/nds32/isr-library/vec_vid29_4b.S --+++ /dev/null --@@ -1,34 +0,0 @@ ---/* c-isr library stuff of Andes NDS32 cpu for GNU compiler --- Copyright (C) 2012-2016 Free Software Foundation, Inc. --- Contributed by Andes Technology Corporation. --- --- This file is part of GCC. --- --- GCC is free software; you can redistribute it and/or modify it --- under the terms of the GNU General Public License as published --- by the Free Software Foundation; either version 3, or (at your --- option) any later version. --- --- GCC is distributed in the hope that it will be useful, but WITHOUT --- ANY WARRANTY; without even the implied warranty of MERCHANTABILITY --- or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public --- License for more details. --- --- Under Section 7 of GPL version 3, you are granted additional --- permissions described in the GCC Runtime Library Exception, version --- 3.1, as published by the Free Software Foundation. --- --- You should have received a copy of the GNU General Public License and --- a copy of the GCC Runtime Library Exception along with this program; --- see the files COPYING3 and COPYING.RUNTIME respectively. If not, see --- . */ --- --- .section .nds32_vector.29, "ax" --- .vec_size 4 --- .align 2 --- .weak _nds32_vector_29_4b --- .type _nds32_vector_29_4b, @function ---_nds32_vector_29_4b: ---1: --- j 1b --- .size _nds32_vector_29_4b, .-_nds32_vector_29_4b --diff --git a/libgcc/config/nds32/isr-library/vec_vid30.S b/libgcc/config/nds32/isr-library/vec_vid30.S --index 57d1507..214e67b 100644 ----- a/libgcc/config/nds32/isr-library/vec_vid30.S --+++ b/libgcc/config/nds32/isr-library/vec_vid30.S --@@ -24,8 +24,15 @@ -- . */ -- -- .section .nds32_vector.30, "ax" --+#if __NDS32_ISR_VECTOR_SIZE_4__ --+ /* The vector size is default 4-byte for v3 architecture. */ --+ .vec_size 4 --+ .align 2 --+#else --+ /* The vector size is default 16-byte for other architectures. */ -- .vec_size 16 -- .align 4 --+#endif -- .weak _nds32_vector_30 -- .type _nds32_vector_30, @function -- _nds32_vector_30: --diff --git a/libgcc/config/nds32/isr-library/vec_vid30_4b.S b/libgcc/config/nds32/isr-library/vec_vid30_4b.S --deleted file mode 100644 --index a2a1e3e..0000000 ----- a/libgcc/config/nds32/isr-library/vec_vid30_4b.S --+++ /dev/null --@@ -1,34 +0,0 @@ ---/* c-isr library stuff of Andes NDS32 cpu for GNU compiler --- Copyright (C) 2012-2016 Free Software Foundation, Inc. --- Contributed by Andes Technology Corporation. --- --- This file is part of GCC. --- --- GCC is free software; you can redistribute it and/or modify it --- under the terms of the GNU General Public License as published --- by the Free Software Foundation; either version 3, or (at your --- option) any later version. --- --- GCC is distributed in the hope that it will be useful, but WITHOUT --- ANY WARRANTY; without even the implied warranty of MERCHANTABILITY --- or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public --- License for more details. --- --- Under Section 7 of GPL version 3, you are granted additional --- permissions described in the GCC Runtime Library Exception, version --- 3.1, as published by the Free Software Foundation. --- --- You should have received a copy of the GNU General Public License and --- a copy of the GCC Runtime Library Exception along with this program; --- see the files COPYING3 and COPYING.RUNTIME respectively. If not, see --- . */ --- --- .section .nds32_vector.30, "ax" --- .vec_size 4 --- .align 2 --- .weak _nds32_vector_30_4b --- .type _nds32_vector_30_4b, @function ---_nds32_vector_30_4b: ---1: --- j 1b --- .size _nds32_vector_30_4b, .-_nds32_vector_30_4b --diff --git a/libgcc/config/nds32/isr-library/vec_vid31.S b/libgcc/config/nds32/isr-library/vec_vid31.S --index f9aee4e..b758b8c 100644 ----- a/libgcc/config/nds32/isr-library/vec_vid31.S --+++ b/libgcc/config/nds32/isr-library/vec_vid31.S --@@ -24,8 +24,15 @@ -- . */ -- -- .section .nds32_vector.31, "ax" --+#if __NDS32_ISR_VECTOR_SIZE_4__ --+ /* The vector size is default 4-byte for v3 architecture. */ --+ .vec_size 4 --+ .align 2 --+#else --+ /* The vector size is default 16-byte for other architectures. */ -- .vec_size 16 -- .align 4 --+#endif -- .weak _nds32_vector_31 -- .type _nds32_vector_31, @function -- _nds32_vector_31: --diff --git a/libgcc/config/nds32/isr-library/vec_vid31_4b.S b/libgcc/config/nds32/isr-library/vec_vid31_4b.S --deleted file mode 100644 --index 989645f..0000000 ----- a/libgcc/config/nds32/isr-library/vec_vid31_4b.S --+++ /dev/null --@@ -1,34 +0,0 @@ ---/* c-isr library stuff of Andes NDS32 cpu for GNU compiler --- Copyright (C) 2012-2016 Free Software Foundation, Inc. --- Contributed by Andes Technology Corporation. --- --- This file is part of GCC. --- --- GCC is free software; you can redistribute it and/or modify it --- under the terms of the GNU General Public License as published --- by the Free Software Foundation; either version 3, or (at your --- option) any later version. --- --- GCC is distributed in the hope that it will be useful, but WITHOUT --- ANY WARRANTY; without even the implied warranty of MERCHANTABILITY --- or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public --- License for more details. --- --- Under Section 7 of GPL version 3, you are granted additional --- permissions described in the GCC Runtime Library Exception, version --- 3.1, as published by the Free Software Foundation. --- --- You should have received a copy of the GNU General Public License and --- a copy of the GCC Runtime Library Exception along with this program; --- see the files COPYING3 and COPYING.RUNTIME respectively. If not, see --- . */ --- --- .section .nds32_vector.31, "ax" --- .vec_size 4 --- .align 2 --- .weak _nds32_vector_31_4b --- .type _nds32_vector_31_4b, @function ---_nds32_vector_31_4b: ---1: --- j 1b --- .size _nds32_vector_31_4b, .-_nds32_vector_31_4b --diff --git a/libgcc/config/nds32/isr-library/vec_vid32.S b/libgcc/config/nds32/isr-library/vec_vid32.S --index fc26cad..58234d5 100644 ----- a/libgcc/config/nds32/isr-library/vec_vid32.S --+++ b/libgcc/config/nds32/isr-library/vec_vid32.S --@@ -24,8 +24,15 @@ -- . */ -- -- .section .nds32_vector.32, "ax" --+#if __NDS32_ISR_VECTOR_SIZE_4__ --+ /* The vector size is default 4-byte for v3 architecture. */ --+ .vec_size 4 --+ .align 2 --+#else --+ /* The vector size is default 16-byte for other architectures. */ -- .vec_size 16 -- .align 4 --+#endif -- .weak _nds32_vector_32 -- .type _nds32_vector_32, @function -- _nds32_vector_32: --diff --git a/libgcc/config/nds32/isr-library/vec_vid32_4b.S b/libgcc/config/nds32/isr-library/vec_vid32_4b.S --deleted file mode 100644 --index 1ac7e31..0000000 ----- a/libgcc/config/nds32/isr-library/vec_vid32_4b.S --+++ /dev/null --@@ -1,34 +0,0 @@ ---/* c-isr library stuff of Andes NDS32 cpu for GNU compiler --- Copyright (C) 2012-2016 Free Software Foundation, Inc. --- Contributed by Andes Technology Corporation. --- --- This file is part of GCC. --- --- GCC is free software; you can redistribute it and/or modify it --- under the terms of the GNU General Public License as published --- by the Free Software Foundation; either version 3, or (at your --- option) any later version. --- --- GCC is distributed in the hope that it will be useful, but WITHOUT --- ANY WARRANTY; without even the implied warranty of MERCHANTABILITY --- or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public --- License for more details. --- --- Under Section 7 of GPL version 3, you are granted additional --- permissions described in the GCC Runtime Library Exception, version --- 3.1, as published by the Free Software Foundation. --- --- You should have received a copy of the GNU General Public License and --- a copy of the GCC Runtime Library Exception along with this program; --- see the files COPYING3 and COPYING.RUNTIME respectively. If not, see --- . */ --- --- .section .nds32_vector.32, "ax" --- .vec_size 4 --- .align 2 --- .weak _nds32_vector_32_4b --- .type _nds32_vector_32_4b, @function ---_nds32_vector_32_4b: ---1: --- j 1b --- .size _nds32_vector_32_4b, .-_nds32_vector_32_4b --diff --git a/libgcc/config/nds32/isr-library/vec_vid33.S b/libgcc/config/nds32/isr-library/vec_vid33.S --index dd655e6..d920352 100644 ----- a/libgcc/config/nds32/isr-library/vec_vid33.S --+++ b/libgcc/config/nds32/isr-library/vec_vid33.S --@@ -24,8 +24,15 @@ -- . */ -- -- .section .nds32_vector.33, "ax" --+#if __NDS32_ISR_VECTOR_SIZE_4__ --+ /* The vector size is default 4-byte for v3 architecture. */ --+ .vec_size 4 --+ .align 2 --+#else --+ /* The vector size is default 16-byte for other architectures. */ -- .vec_size 16 -- .align 4 --+#endif -- .weak _nds32_vector_33 -- .type _nds32_vector_33, @function -- _nds32_vector_33: --diff --git a/libgcc/config/nds32/isr-library/vec_vid33_4b.S b/libgcc/config/nds32/isr-library/vec_vid33_4b.S --deleted file mode 100644 --index 3c99412..0000000 ----- a/libgcc/config/nds32/isr-library/vec_vid33_4b.S --+++ /dev/null --@@ -1,34 +0,0 @@ ---/* c-isr library stuff of Andes NDS32 cpu for GNU compiler --- Copyright (C) 2012-2016 Free Software Foundation, Inc. --- Contributed by Andes Technology Corporation. --- --- This file is part of GCC. --- --- GCC is free software; you can redistribute it and/or modify it --- under the terms of the GNU General Public License as published --- by the Free Software Foundation; either version 3, or (at your --- option) any later version. --- --- GCC is distributed in the hope that it will be useful, but WITHOUT --- ANY WARRANTY; without even the implied warranty of MERCHANTABILITY --- or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public --- License for more details. --- --- Under Section 7 of GPL version 3, you are granted additional --- permissions described in the GCC Runtime Library Exception, version --- 3.1, as published by the Free Software Foundation. --- --- You should have received a copy of the GNU General Public License and --- a copy of the GCC Runtime Library Exception along with this program; --- see the files COPYING3 and COPYING.RUNTIME respectively. If not, see --- . */ --- --- .section .nds32_vector.33, "ax" --- .vec_size 4 --- .align 2 --- .weak _nds32_vector_33_4b --- .type _nds32_vector_33_4b, @function ---_nds32_vector_33_4b: ---1: --- j 1b --- .size _nds32_vector_33_4b, .-_nds32_vector_33_4b --diff --git a/libgcc/config/nds32/isr-library/vec_vid34.S b/libgcc/config/nds32/isr-library/vec_vid34.S --index a6b8517..01999b4 100644 ----- a/libgcc/config/nds32/isr-library/vec_vid34.S --+++ b/libgcc/config/nds32/isr-library/vec_vid34.S --@@ -24,8 +24,15 @@ -- . */ -- -- .section .nds32_vector.34, "ax" --+#if __NDS32_ISR_VECTOR_SIZE_4__ --+ /* The vector size is default 4-byte for v3 architecture. */ --+ .vec_size 4 --+ .align 2 --+#else --+ /* The vector size is default 16-byte for other architectures. */ -- .vec_size 16 -- .align 4 --+#endif -- .weak _nds32_vector_34 -- .type _nds32_vector_34, @function -- _nds32_vector_34: --diff --git a/libgcc/config/nds32/isr-library/vec_vid34_4b.S b/libgcc/config/nds32/isr-library/vec_vid34_4b.S --deleted file mode 100644 --index 77c07b9..0000000 ----- a/libgcc/config/nds32/isr-library/vec_vid34_4b.S --+++ /dev/null --@@ -1,34 +0,0 @@ ---/* c-isr library stuff of Andes NDS32 cpu for GNU compiler --- Copyright (C) 2012-2016 Free Software Foundation, Inc. --- Contributed by Andes Technology Corporation. --- --- This file is part of GCC. --- --- GCC is free software; you can redistribute it and/or modify it --- under the terms of the GNU General Public License as published --- by the Free Software Foundation; either version 3, or (at your --- option) any later version. --- --- GCC is distributed in the hope that it will be useful, but WITHOUT --- ANY WARRANTY; without even the implied warranty of MERCHANTABILITY --- or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public --- License for more details. --- --- Under Section 7 of GPL version 3, you are granted additional --- permissions described in the GCC Runtime Library Exception, version --- 3.1, as published by the Free Software Foundation. --- --- You should have received a copy of the GNU General Public License and --- a copy of the GCC Runtime Library Exception along with this program; --- see the files COPYING3 and COPYING.RUNTIME respectively. If not, see --- . */ --- --- .section .nds32_vector.34, "ax" --- .vec_size 4 --- .align 2 --- .weak _nds32_vector_34_4b --- .type _nds32_vector_34_4b, @function ---_nds32_vector_34_4b: ---1: --- j 1b --- .size _nds32_vector_34_4b, .-_nds32_vector_34_4b --diff --git a/libgcc/config/nds32/isr-library/vec_vid35.S b/libgcc/config/nds32/isr-library/vec_vid35.S --index 65ceeab..7ab0536 100644 ----- a/libgcc/config/nds32/isr-library/vec_vid35.S --+++ b/libgcc/config/nds32/isr-library/vec_vid35.S --@@ -24,8 +24,15 @@ -- . */ -- -- .section .nds32_vector.35, "ax" --+#if __NDS32_ISR_VECTOR_SIZE_4__ --+ /* The vector size is default 4-byte for v3 architecture. */ --+ .vec_size 4 --+ .align 2 --+#else --+ /* The vector size is default 16-byte for other architectures. */ -- .vec_size 16 -- .align 4 --+#endif -- .weak _nds32_vector_35 -- .type _nds32_vector_35, @function -- _nds32_vector_35: --diff --git a/libgcc/config/nds32/isr-library/vec_vid35_4b.S b/libgcc/config/nds32/isr-library/vec_vid35_4b.S --deleted file mode 100644 --index 432873a..0000000 ----- a/libgcc/config/nds32/isr-library/vec_vid35_4b.S --+++ /dev/null --@@ -1,34 +0,0 @@ ---/* c-isr library stuff of Andes NDS32 cpu for GNU compiler --- Copyright (C) 2012-2016 Free Software Foundation, Inc. --- Contributed by Andes Technology Corporation. --- --- This file is part of GCC. --- --- GCC is free software; you can redistribute it and/or modify it --- under the terms of the GNU General Public License as published --- by the Free Software Foundation; either version 3, or (at your --- option) any later version. --- --- GCC is distributed in the hope that it will be useful, but WITHOUT --- ANY WARRANTY; without even the implied warranty of MERCHANTABILITY --- or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public --- License for more details. --- --- Under Section 7 of GPL version 3, you are granted additional --- permissions described in the GCC Runtime Library Exception, version --- 3.1, as published by the Free Software Foundation. --- --- You should have received a copy of the GNU General Public License and --- a copy of the GCC Runtime Library Exception along with this program; --- see the files COPYING3 and COPYING.RUNTIME respectively. If not, see --- . */ --- --- .section .nds32_vector.35, "ax" --- .vec_size 4 --- .align 2 --- .weak _nds32_vector_35_4b --- .type _nds32_vector_35_4b, @function ---_nds32_vector_35_4b: ---1: --- j 1b --- .size _nds32_vector_35_4b, .-_nds32_vector_35_4b --diff --git a/libgcc/config/nds32/isr-library/vec_vid36.S b/libgcc/config/nds32/isr-library/vec_vid36.S --index 688dbb9..5da079d 100644 ----- a/libgcc/config/nds32/isr-library/vec_vid36.S --+++ b/libgcc/config/nds32/isr-library/vec_vid36.S --@@ -24,8 +24,15 @@ -- . */ -- -- .section .nds32_vector.36, "ax" --+#if __NDS32_ISR_VECTOR_SIZE_4__ --+ /* The vector size is default 4-byte for v3 architecture. */ --+ .vec_size 4 --+ .align 2 --+#else --+ /* The vector size is default 16-byte for other architectures. */ -- .vec_size 16 -- .align 4 --+#endif -- .weak _nds32_vector_36 -- .type _nds32_vector_36, @function -- _nds32_vector_36: --diff --git a/libgcc/config/nds32/isr-library/vec_vid36_4b.S b/libgcc/config/nds32/isr-library/vec_vid36_4b.S --deleted file mode 100644 --index dadd381..0000000 ----- a/libgcc/config/nds32/isr-library/vec_vid36_4b.S --+++ /dev/null --@@ -1,34 +0,0 @@ ---/* c-isr library stuff of Andes NDS32 cpu for GNU compiler --- Copyright (C) 2012-2016 Free Software Foundation, Inc. --- Contributed by Andes Technology Corporation. --- --- This file is part of GCC. --- --- GCC is free software; you can redistribute it and/or modify it --- under the terms of the GNU General Public License as published --- by the Free Software Foundation; either version 3, or (at your --- option) any later version. --- --- GCC is distributed in the hope that it will be useful, but WITHOUT --- ANY WARRANTY; without even the implied warranty of MERCHANTABILITY --- or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public --- License for more details. --- --- Under Section 7 of GPL version 3, you are granted additional --- permissions described in the GCC Runtime Library Exception, version --- 3.1, as published by the Free Software Foundation. --- --- You should have received a copy of the GNU General Public License and --- a copy of the GCC Runtime Library Exception along with this program; --- see the files COPYING3 and COPYING.RUNTIME respectively. If not, see --- . */ --- --- .section .nds32_vector.36, "ax" --- .vec_size 4 --- .align 2 --- .weak _nds32_vector_36_4b --- .type _nds32_vector_36_4b, @function ---_nds32_vector_36_4b: ---1: --- j 1b --- .size _nds32_vector_36_4b, .-_nds32_vector_36_4b --diff --git a/libgcc/config/nds32/isr-library/vec_vid37.S b/libgcc/config/nds32/isr-library/vec_vid37.S --index 712bbe8..704d6b8 100644 ----- a/libgcc/config/nds32/isr-library/vec_vid37.S --+++ b/libgcc/config/nds32/isr-library/vec_vid37.S --@@ -24,8 +24,15 @@ -- . */ -- -- .section .nds32_vector.37, "ax" --+#if __NDS32_ISR_VECTOR_SIZE_4__ --+ /* The vector size is default 4-byte for v3 architecture. */ --+ .vec_size 4 --+ .align 2 --+#else --+ /* The vector size is default 16-byte for other architectures. */ -- .vec_size 16 -- .align 4 --+#endif -- .weak _nds32_vector_37 -- .type _nds32_vector_37, @function -- _nds32_vector_37: --diff --git a/libgcc/config/nds32/isr-library/vec_vid37_4b.S b/libgcc/config/nds32/isr-library/vec_vid37_4b.S --deleted file mode 100644 --index ec845e1..0000000 ----- a/libgcc/config/nds32/isr-library/vec_vid37_4b.S --+++ /dev/null --@@ -1,34 +0,0 @@ ---/* c-isr library stuff of Andes NDS32 cpu for GNU compiler --- Copyright (C) 2012-2016 Free Software Foundation, Inc. --- Contributed by Andes Technology Corporation. --- --- This file is part of GCC. --- --- GCC is free software; you can redistribute it and/or modify it --- under the terms of the GNU General Public License as published --- by the Free Software Foundation; either version 3, or (at your --- option) any later version. --- --- GCC is distributed in the hope that it will be useful, but WITHOUT --- ANY WARRANTY; without even the implied warranty of MERCHANTABILITY --- or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public --- License for more details. --- --- Under Section 7 of GPL version 3, you are granted additional --- permissions described in the GCC Runtime Library Exception, version --- 3.1, as published by the Free Software Foundation. --- --- You should have received a copy of the GNU General Public License and --- a copy of the GCC Runtime Library Exception along with this program; --- see the files COPYING3 and COPYING.RUNTIME respectively. If not, see --- . */ --- --- .section .nds32_vector.37, "ax" --- .vec_size 4 --- .align 2 --- .weak _nds32_vector_37_4b --- .type _nds32_vector_37_4b, @function ---_nds32_vector_37_4b: ---1: --- j 1b --- .size _nds32_vector_37_4b, .-_nds32_vector_37_4b --diff --git a/libgcc/config/nds32/isr-library/vec_vid38.S b/libgcc/config/nds32/isr-library/vec_vid38.S --index b6e4979..fdfc4a9 100644 ----- a/libgcc/config/nds32/isr-library/vec_vid38.S --+++ b/libgcc/config/nds32/isr-library/vec_vid38.S --@@ -24,8 +24,15 @@ -- . */ -- -- .section .nds32_vector.38, "ax" --+#if __NDS32_ISR_VECTOR_SIZE_4__ --+ /* The vector size is default 4-byte for v3 architecture. */ --+ .vec_size 4 --+ .align 2 --+#else --+ /* The vector size is default 16-byte for other architectures. */ -- .vec_size 16 -- .align 4 --+#endif -- .weak _nds32_vector_38 -- .type _nds32_vector_38, @function -- _nds32_vector_38: --diff --git a/libgcc/config/nds32/isr-library/vec_vid38_4b.S b/libgcc/config/nds32/isr-library/vec_vid38_4b.S --deleted file mode 100644 --index 84919ed..0000000 ----- a/libgcc/config/nds32/isr-library/vec_vid38_4b.S --+++ /dev/null --@@ -1,34 +0,0 @@ ---/* c-isr library stuff of Andes NDS32 cpu for GNU compiler --- Copyright (C) 2012-2016 Free Software Foundation, Inc. --- Contributed by Andes Technology Corporation. --- --- This file is part of GCC. --- --- GCC is free software; you can redistribute it and/or modify it --- under the terms of the GNU General Public License as published --- by the Free Software Foundation; either version 3, or (at your --- option) any later version. --- --- GCC is distributed in the hope that it will be useful, but WITHOUT --- ANY WARRANTY; without even the implied warranty of MERCHANTABILITY --- or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public --- License for more details. --- --- Under Section 7 of GPL version 3, you are granted additional --- permissions described in the GCC Runtime Library Exception, version --- 3.1, as published by the Free Software Foundation. --- --- You should have received a copy of the GNU General Public License and --- a copy of the GCC Runtime Library Exception along with this program; --- see the files COPYING3 and COPYING.RUNTIME respectively. If not, see --- . */ --- --- .section .nds32_vector.38, "ax" --- .vec_size 4 --- .align 2 --- .weak _nds32_vector_38_4b --- .type _nds32_vector_38_4b, @function ---_nds32_vector_38_4b: ---1: --- j 1b --- .size _nds32_vector_38_4b, .-_nds32_vector_38_4b --diff --git a/libgcc/config/nds32/isr-library/vec_vid39.S b/libgcc/config/nds32/isr-library/vec_vid39.S --index 2dee269..00dd245 100644 ----- a/libgcc/config/nds32/isr-library/vec_vid39.S --+++ b/libgcc/config/nds32/isr-library/vec_vid39.S --@@ -24,8 +24,15 @@ -- . */ -- -- .section .nds32_vector.39, "ax" --+#if __NDS32_ISR_VECTOR_SIZE_4__ --+ /* The vector size is default 4-byte for v3 architecture. */ --+ .vec_size 4 --+ .align 2 --+#else --+ /* The vector size is default 16-byte for other architectures. */ -- .vec_size 16 -- .align 4 --+#endif -- .weak _nds32_vector_39 -- .type _nds32_vector_39, @function -- _nds32_vector_39: --diff --git a/libgcc/config/nds32/isr-library/vec_vid39_4b.S b/libgcc/config/nds32/isr-library/vec_vid39_4b.S --deleted file mode 100644 --index 8f2f634..0000000 ----- a/libgcc/config/nds32/isr-library/vec_vid39_4b.S --+++ /dev/null --@@ -1,34 +0,0 @@ ---/* c-isr library stuff of Andes NDS32 cpu for GNU compiler --- Copyright (C) 2012-2016 Free Software Foundation, Inc. --- Contributed by Andes Technology Corporation. --- --- This file is part of GCC. --- --- GCC is free software; you can redistribute it and/or modify it --- under the terms of the GNU General Public License as published --- by the Free Software Foundation; either version 3, or (at your --- option) any later version. --- --- GCC is distributed in the hope that it will be useful, but WITHOUT --- ANY WARRANTY; without even the implied warranty of MERCHANTABILITY --- or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public --- License for more details. --- --- Under Section 7 of GPL version 3, you are granted additional --- permissions described in the GCC Runtime Library Exception, version --- 3.1, as published by the Free Software Foundation. --- --- You should have received a copy of the GNU General Public License and --- a copy of the GCC Runtime Library Exception along with this program; --- see the files COPYING3 and COPYING.RUNTIME respectively. If not, see --- . */ --- --- .section .nds32_vector.39, "ax" --- .vec_size 4 --- .align 2 --- .weak _nds32_vector_39_4b --- .type _nds32_vector_39_4b, @function ---_nds32_vector_39_4b: ---1: --- j 1b --- .size _nds32_vector_39_4b, .-_nds32_vector_39_4b --diff --git a/libgcc/config/nds32/isr-library/vec_vid40.S b/libgcc/config/nds32/isr-library/vec_vid40.S --index fe7508c..82b579f 100644 ----- a/libgcc/config/nds32/isr-library/vec_vid40.S --+++ b/libgcc/config/nds32/isr-library/vec_vid40.S --@@ -24,8 +24,15 @@ -- . */ -- -- .section .nds32_vector.40, "ax" --+#if __NDS32_ISR_VECTOR_SIZE_4__ --+ /* The vector size is default 4-byte for v3 architecture. */ --+ .vec_size 4 --+ .align 2 --+#else --+ /* The vector size is default 16-byte for other architectures. */ -- .vec_size 16 -- .align 4 --+#endif -- .weak _nds32_vector_40 -- .type _nds32_vector_40, @function -- _nds32_vector_40: --diff --git a/libgcc/config/nds32/isr-library/vec_vid40_4b.S b/libgcc/config/nds32/isr-library/vec_vid40_4b.S --deleted file mode 100644 --index 0aab8f4..0000000 ----- a/libgcc/config/nds32/isr-library/vec_vid40_4b.S --+++ /dev/null --@@ -1,34 +0,0 @@ ---/* c-isr library stuff of Andes NDS32 cpu for GNU compiler --- Copyright (C) 2012-2016 Free Software Foundation, Inc. --- Contributed by Andes Technology Corporation. --- --- This file is part of GCC. --- --- GCC is free software; you can redistribute it and/or modify it --- under the terms of the GNU General Public License as published --- by the Free Software Foundation; either version 3, or (at your --- option) any later version. --- --- GCC is distributed in the hope that it will be useful, but WITHOUT --- ANY WARRANTY; without even the implied warranty of MERCHANTABILITY --- or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public --- License for more details. --- --- Under Section 7 of GPL version 3, you are granted additional --- permissions described in the GCC Runtime Library Exception, version --- 3.1, as published by the Free Software Foundation. --- --- You should have received a copy of the GNU General Public License and --- a copy of the GCC Runtime Library Exception along with this program; --- see the files COPYING3 and COPYING.RUNTIME respectively. If not, see --- . */ --- --- .section .nds32_vector.40, "ax" --- .vec_size 4 --- .align 2 --- .weak _nds32_vector_40_4b --- .type _nds32_vector_40_4b, @function ---_nds32_vector_40_4b: ---1: --- j 1b --- .size _nds32_vector_40_4b, .-_nds32_vector_40_4b --diff --git a/libgcc/config/nds32/isr-library/vec_vid41.S b/libgcc/config/nds32/isr-library/vec_vid41.S --index 711fcd5..721c735 100644 ----- a/libgcc/config/nds32/isr-library/vec_vid41.S --+++ b/libgcc/config/nds32/isr-library/vec_vid41.S --@@ -24,8 +24,15 @@ -- . */ -- -- .section .nds32_vector.41, "ax" --+#if __NDS32_ISR_VECTOR_SIZE_4__ --+ /* The vector size is default 4-byte for v3 architecture. */ --+ .vec_size 4 --+ .align 2 --+#else --+ /* The vector size is default 16-byte for other architectures. */ -- .vec_size 16 -- .align 4 --+#endif -- .weak _nds32_vector_41 -- .type _nds32_vector_41, @function -- _nds32_vector_41: --diff --git a/libgcc/config/nds32/isr-library/vec_vid41_4b.S b/libgcc/config/nds32/isr-library/vec_vid41_4b.S --deleted file mode 100644 --index e8a8527..0000000 ----- a/libgcc/config/nds32/isr-library/vec_vid41_4b.S --+++ /dev/null --@@ -1,34 +0,0 @@ ---/* c-isr library stuff of Andes NDS32 cpu for GNU compiler --- Copyright (C) 2012-2016 Free Software Foundation, Inc. --- Contributed by Andes Technology Corporation. --- --- This file is part of GCC. --- --- GCC is free software; you can redistribute it and/or modify it --- under the terms of the GNU General Public License as published --- by the Free Software Foundation; either version 3, or (at your --- option) any later version. --- --- GCC is distributed in the hope that it will be useful, but WITHOUT --- ANY WARRANTY; without even the implied warranty of MERCHANTABILITY --- or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public --- License for more details. --- --- Under Section 7 of GPL version 3, you are granted additional --- permissions described in the GCC Runtime Library Exception, version --- 3.1, as published by the Free Software Foundation. --- --- You should have received a copy of the GNU General Public License and --- a copy of the GCC Runtime Library Exception along with this program; --- see the files COPYING3 and COPYING.RUNTIME respectively. If not, see --- . */ --- --- .section .nds32_vector.41, "ax" --- .vec_size 4 --- .align 2 --- .weak _nds32_vector_41_4b --- .type _nds32_vector_41_4b, @function ---_nds32_vector_41_4b: ---1: --- j 1b --- .size _nds32_vector_41_4b, .-_nds32_vector_41_4b --diff --git a/libgcc/config/nds32/isr-library/vec_vid42.S b/libgcc/config/nds32/isr-library/vec_vid42.S --index 0c6a849..307b51d 100644 ----- a/libgcc/config/nds32/isr-library/vec_vid42.S --+++ b/libgcc/config/nds32/isr-library/vec_vid42.S --@@ -24,8 +24,15 @@ -- . */ -- -- .section .nds32_vector.42, "ax" --+#if __NDS32_ISR_VECTOR_SIZE_4__ --+ /* The vector size is default 4-byte for v3 architecture. */ --+ .vec_size 4 --+ .align 2 --+#else --+ /* The vector size is default 16-byte for other architectures. */ -- .vec_size 16 -- .align 4 --+#endif -- .weak _nds32_vector_42 -- .type _nds32_vector_42, @function -- _nds32_vector_42: --diff --git a/libgcc/config/nds32/isr-library/vec_vid42_4b.S b/libgcc/config/nds32/isr-library/vec_vid42_4b.S --deleted file mode 100644 --index cfe184c..0000000 ----- a/libgcc/config/nds32/isr-library/vec_vid42_4b.S --+++ /dev/null --@@ -1,34 +0,0 @@ ---/* c-isr library stuff of Andes NDS32 cpu for GNU compiler --- Copyright (C) 2012-2016 Free Software Foundation, Inc. --- Contributed by Andes Technology Corporation. --- --- This file is part of GCC. --- --- GCC is free software; you can redistribute it and/or modify it --- under the terms of the GNU General Public License as published --- by the Free Software Foundation; either version 3, or (at your --- option) any later version. --- --- GCC is distributed in the hope that it will be useful, but WITHOUT --- ANY WARRANTY; without even the implied warranty of MERCHANTABILITY --- or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public --- License for more details. --- --- Under Section 7 of GPL version 3, you are granted additional --- permissions described in the GCC Runtime Library Exception, version --- 3.1, as published by the Free Software Foundation. --- --- You should have received a copy of the GNU General Public License and --- a copy of the GCC Runtime Library Exception along with this program; --- see the files COPYING3 and COPYING.RUNTIME respectively. If not, see --- . */ --- --- .section .nds32_vector.42, "ax" --- .vec_size 4 --- .align 2 --- .weak _nds32_vector_42_4b --- .type _nds32_vector_42_4b, @function ---_nds32_vector_42_4b: ---1: --- j 1b --- .size _nds32_vector_42_4b, .-_nds32_vector_42_4b --diff --git a/libgcc/config/nds32/isr-library/vec_vid43.S b/libgcc/config/nds32/isr-library/vec_vid43.S --index 2b4681a..c0ce02d 100644 ----- a/libgcc/config/nds32/isr-library/vec_vid43.S --+++ b/libgcc/config/nds32/isr-library/vec_vid43.S --@@ -24,8 +24,15 @@ -- . */ -- -- .section .nds32_vector.43, "ax" --+#if __NDS32_ISR_VECTOR_SIZE_4__ --+ /* The vector size is default 4-byte for v3 architecture. */ --+ .vec_size 4 --+ .align 2 --+#else --+ /* The vector size is default 16-byte for other architectures. */ -- .vec_size 16 -- .align 4 --+#endif -- .weak _nds32_vector_43 -- .type _nds32_vector_43, @function -- _nds32_vector_43: --diff --git a/libgcc/config/nds32/isr-library/vec_vid43_4b.S b/libgcc/config/nds32/isr-library/vec_vid43_4b.S --deleted file mode 100644 --index 3edd606..0000000 ----- a/libgcc/config/nds32/isr-library/vec_vid43_4b.S --+++ /dev/null --@@ -1,34 +0,0 @@ ---/* c-isr library stuff of Andes NDS32 cpu for GNU compiler --- Copyright (C) 2012-2016 Free Software Foundation, Inc. --- Contributed by Andes Technology Corporation. --- --- This file is part of GCC. --- --- GCC is free software; you can redistribute it and/or modify it --- under the terms of the GNU General Public License as published --- by the Free Software Foundation; either version 3, or (at your --- option) any later version. --- --- GCC is distributed in the hope that it will be useful, but WITHOUT --- ANY WARRANTY; without even the implied warranty of MERCHANTABILITY --- or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public --- License for more details. --- --- Under Section 7 of GPL version 3, you are granted additional --- permissions described in the GCC Runtime Library Exception, version --- 3.1, as published by the Free Software Foundation. --- --- You should have received a copy of the GNU General Public License and --- a copy of the GCC Runtime Library Exception along with this program; --- see the files COPYING3 and COPYING.RUNTIME respectively. If not, see --- . */ --- --- .section .nds32_vector.43, "ax" --- .vec_size 4 --- .align 2 --- .weak _nds32_vector_43_4b --- .type _nds32_vector_43_4b, @function ---_nds32_vector_43_4b: ---1: --- j 1b --- .size _nds32_vector_43_4b, .-_nds32_vector_43_4b --diff --git a/libgcc/config/nds32/isr-library/vec_vid44.S b/libgcc/config/nds32/isr-library/vec_vid44.S --index 232ef41..c2a384c 100644 ----- a/libgcc/config/nds32/isr-library/vec_vid44.S --+++ b/libgcc/config/nds32/isr-library/vec_vid44.S --@@ -24,8 +24,15 @@ -- . */ -- -- .section .nds32_vector.44, "ax" --+#if __NDS32_ISR_VECTOR_SIZE_4__ --+ /* The vector size is default 4-byte for v3 architecture. */ --+ .vec_size 4 --+ .align 2 --+#else --+ /* The vector size is default 16-byte for other architectures. */ -- .vec_size 16 -- .align 4 --+#endif -- .weak _nds32_vector_44 -- .type _nds32_vector_44, @function -- _nds32_vector_44: --diff --git a/libgcc/config/nds32/isr-library/vec_vid44_4b.S b/libgcc/config/nds32/isr-library/vec_vid44_4b.S --deleted file mode 100644 --index 0f2b8a3..0000000 ----- a/libgcc/config/nds32/isr-library/vec_vid44_4b.S --+++ /dev/null --@@ -1,34 +0,0 @@ ---/* c-isr library stuff of Andes NDS32 cpu for GNU compiler --- Copyright (C) 2012-2016 Free Software Foundation, Inc. --- Contributed by Andes Technology Corporation. --- --- This file is part of GCC. --- --- GCC is free software; you can redistribute it and/or modify it --- under the terms of the GNU General Public License as published --- by the Free Software Foundation; either version 3, or (at your --- option) any later version. --- --- GCC is distributed in the hope that it will be useful, but WITHOUT --- ANY WARRANTY; without even the implied warranty of MERCHANTABILITY --- or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public --- License for more details. --- --- Under Section 7 of GPL version 3, you are granted additional --- permissions described in the GCC Runtime Library Exception, version --- 3.1, as published by the Free Software Foundation. --- --- You should have received a copy of the GNU General Public License and --- a copy of the GCC Runtime Library Exception along with this program; --- see the files COPYING3 and COPYING.RUNTIME respectively. If not, see --- . */ --- --- .section .nds32_vector.44, "ax" --- .vec_size 4 --- .align 2 --- .weak _nds32_vector_44_4b --- .type _nds32_vector_44_4b, @function ---_nds32_vector_44_4b: ---1: --- j 1b --- .size _nds32_vector_44_4b, .-_nds32_vector_44_4b --diff --git a/libgcc/config/nds32/isr-library/vec_vid45.S b/libgcc/config/nds32/isr-library/vec_vid45.S --index e2f9863..e13c52b 100644 ----- a/libgcc/config/nds32/isr-library/vec_vid45.S --+++ b/libgcc/config/nds32/isr-library/vec_vid45.S --@@ -24,8 +24,15 @@ -- . */ -- -- .section .nds32_vector.45, "ax" --+#if __NDS32_ISR_VECTOR_SIZE_4__ --+ /* The vector size is default 4-byte for v3 architecture. */ --+ .vec_size 4 --+ .align 2 --+#else --+ /* The vector size is default 16-byte for other architectures. */ -- .vec_size 16 -- .align 4 --+#endif -- .weak _nds32_vector_45 -- .type _nds32_vector_45, @function -- _nds32_vector_45: --diff --git a/libgcc/config/nds32/isr-library/vec_vid45_4b.S b/libgcc/config/nds32/isr-library/vec_vid45_4b.S --deleted file mode 100644 --index 7358ec1..0000000 ----- a/libgcc/config/nds32/isr-library/vec_vid45_4b.S --+++ /dev/null --@@ -1,34 +0,0 @@ ---/* c-isr library stuff of Andes NDS32 cpu for GNU compiler --- Copyright (C) 2012-2016 Free Software Foundation, Inc. --- Contributed by Andes Technology Corporation. --- --- This file is part of GCC. --- --- GCC is free software; you can redistribute it and/or modify it --- under the terms of the GNU General Public License as published --- by the Free Software Foundation; either version 3, or (at your --- option) any later version. --- --- GCC is distributed in the hope that it will be useful, but WITHOUT --- ANY WARRANTY; without even the implied warranty of MERCHANTABILITY --- or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public --- License for more details. --- --- Under Section 7 of GPL version 3, you are granted additional --- permissions described in the GCC Runtime Library Exception, version --- 3.1, as published by the Free Software Foundation. --- --- You should have received a copy of the GNU General Public License and --- a copy of the GCC Runtime Library Exception along with this program; --- see the files COPYING3 and COPYING.RUNTIME respectively. If not, see --- . */ --- --- .section .nds32_vector.45, "ax" --- .vec_size 4 --- .align 2 --- .weak _nds32_vector_45_4b --- .type _nds32_vector_45_4b, @function ---_nds32_vector_45_4b: ---1: --- j 1b --- .size _nds32_vector_45_4b, .-_nds32_vector_45_4b --diff --git a/libgcc/config/nds32/isr-library/vec_vid46.S b/libgcc/config/nds32/isr-library/vec_vid46.S --index f3b93aa..71bfb53 100644 ----- a/libgcc/config/nds32/isr-library/vec_vid46.S --+++ b/libgcc/config/nds32/isr-library/vec_vid46.S --@@ -24,8 +24,15 @@ -- . */ -- -- .section .nds32_vector.46, "ax" --+#if __NDS32_ISR_VECTOR_SIZE_4__ --+ /* The vector size is default 4-byte for v3 architecture. */ --+ .vec_size 4 --+ .align 2 --+#else --+ /* The vector size is default 16-byte for other architectures. */ -- .vec_size 16 -- .align 4 --+#endif -- .weak _nds32_vector_46 -- .type _nds32_vector_46, @function -- _nds32_vector_46: --diff --git a/libgcc/config/nds32/isr-library/vec_vid46_4b.S b/libgcc/config/nds32/isr-library/vec_vid46_4b.S --deleted file mode 100644 --index 2782e86..0000000 ----- a/libgcc/config/nds32/isr-library/vec_vid46_4b.S --+++ /dev/null --@@ -1,34 +0,0 @@ ---/* c-isr library stuff of Andes NDS32 cpu for GNU compiler --- Copyright (C) 2012-2016 Free Software Foundation, Inc. --- Contributed by Andes Technology Corporation. --- --- This file is part of GCC. --- --- GCC is free software; you can redistribute it and/or modify it --- under the terms of the GNU General Public License as published --- by the Free Software Foundation; either version 3, or (at your --- option) any later version. --- --- GCC is distributed in the hope that it will be useful, but WITHOUT --- ANY WARRANTY; without even the implied warranty of MERCHANTABILITY --- or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public --- License for more details. --- --- Under Section 7 of GPL version 3, you are granted additional --- permissions described in the GCC Runtime Library Exception, version --- 3.1, as published by the Free Software Foundation. --- --- You should have received a copy of the GNU General Public License and --- a copy of the GCC Runtime Library Exception along with this program; --- see the files COPYING3 and COPYING.RUNTIME respectively. If not, see --- . */ --- --- .section .nds32_vector.46, "ax" --- .vec_size 4 --- .align 2 --- .weak _nds32_vector_46_4b --- .type _nds32_vector_46_4b, @function ---_nds32_vector_46_4b: ---1: --- j 1b --- .size _nds32_vector_46_4b, .-_nds32_vector_46_4b --diff --git a/libgcc/config/nds32/isr-library/vec_vid47.S b/libgcc/config/nds32/isr-library/vec_vid47.S --index 130c8d7..d1f2131 100644 ----- a/libgcc/config/nds32/isr-library/vec_vid47.S --+++ b/libgcc/config/nds32/isr-library/vec_vid47.S --@@ -24,8 +24,15 @@ -- . */ -- -- .section .nds32_vector.47, "ax" --+#if __NDS32_ISR_VECTOR_SIZE_4__ --+ /* The vector size is default 4-byte for v3 architecture. */ --+ .vec_size 4 --+ .align 2 --+#else --+ /* The vector size is default 16-byte for other architectures. */ -- .vec_size 16 -- .align 4 --+#endif -- .weak _nds32_vector_47 -- .type _nds32_vector_47, @function -- _nds32_vector_47: --diff --git a/libgcc/config/nds32/isr-library/vec_vid47_4b.S b/libgcc/config/nds32/isr-library/vec_vid47_4b.S --deleted file mode 100644 --index f237577..0000000 ----- a/libgcc/config/nds32/isr-library/vec_vid47_4b.S --+++ /dev/null --@@ -1,34 +0,0 @@ ---/* c-isr library stuff of Andes NDS32 cpu for GNU compiler --- Copyright (C) 2012-2016 Free Software Foundation, Inc. --- Contributed by Andes Technology Corporation. --- --- This file is part of GCC. --- --- GCC is free software; you can redistribute it and/or modify it --- under the terms of the GNU General Public License as published --- by the Free Software Foundation; either version 3, or (at your --- option) any later version. --- --- GCC is distributed in the hope that it will be useful, but WITHOUT --- ANY WARRANTY; without even the implied warranty of MERCHANTABILITY --- or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public --- License for more details. --- --- Under Section 7 of GPL version 3, you are granted additional --- permissions described in the GCC Runtime Library Exception, version --- 3.1, as published by the Free Software Foundation. --- --- You should have received a copy of the GNU General Public License and --- a copy of the GCC Runtime Library Exception along with this program; --- see the files COPYING3 and COPYING.RUNTIME respectively. If not, see --- . */ --- --- .section .nds32_vector.47, "ax" --- .vec_size 4 --- .align 2 --- .weak _nds32_vector_47_4b --- .type _nds32_vector_47_4b, @function ---_nds32_vector_47_4b: ---1: --- j 1b --- .size _nds32_vector_47_4b, .-_nds32_vector_47_4b --diff --git a/libgcc/config/nds32/isr-library/vec_vid48.S b/libgcc/config/nds32/isr-library/vec_vid48.S --index f3bca05..4ba5eb9 100644 ----- a/libgcc/config/nds32/isr-library/vec_vid48.S --+++ b/libgcc/config/nds32/isr-library/vec_vid48.S --@@ -24,8 +24,15 @@ -- . */ -- -- .section .nds32_vector.48, "ax" --+#if __NDS32_ISR_VECTOR_SIZE_4__ --+ /* The vector size is default 4-byte for v3 architecture. */ --+ .vec_size 4 --+ .align 2 --+#else --+ /* The vector size is default 16-byte for other architectures. */ -- .vec_size 16 -- .align 4 --+#endif -- .weak _nds32_vector_48 -- .type _nds32_vector_48, @function -- _nds32_vector_48: --diff --git a/libgcc/config/nds32/isr-library/vec_vid48_4b.S b/libgcc/config/nds32/isr-library/vec_vid48_4b.S --deleted file mode 100644 --index 3e35f68..0000000 ----- a/libgcc/config/nds32/isr-library/vec_vid48_4b.S --+++ /dev/null --@@ -1,34 +0,0 @@ ---/* c-isr library stuff of Andes NDS32 cpu for GNU compiler --- Copyright (C) 2012-2016 Free Software Foundation, Inc. --- Contributed by Andes Technology Corporation. --- --- This file is part of GCC. --- --- GCC is free software; you can redistribute it and/or modify it --- under the terms of the GNU General Public License as published --- by the Free Software Foundation; either version 3, or (at your --- option) any later version. --- --- GCC is distributed in the hope that it will be useful, but WITHOUT --- ANY WARRANTY; without even the implied warranty of MERCHANTABILITY --- or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public --- License for more details. --- --- Under Section 7 of GPL version 3, you are granted additional --- permissions described in the GCC Runtime Library Exception, version --- 3.1, as published by the Free Software Foundation. --- --- You should have received a copy of the GNU General Public License and --- a copy of the GCC Runtime Library Exception along with this program; --- see the files COPYING3 and COPYING.RUNTIME respectively. If not, see --- . */ --- --- .section .nds32_vector.48, "ax" --- .vec_size 4 --- .align 2 --- .weak _nds32_vector_48_4b --- .type _nds32_vector_48_4b, @function ---_nds32_vector_48_4b: ---1: --- j 1b --- .size _nds32_vector_48_4b, .-_nds32_vector_48_4b --diff --git a/libgcc/config/nds32/isr-library/vec_vid49.S b/libgcc/config/nds32/isr-library/vec_vid49.S --index 0b32691..dd3d35e 100644 ----- a/libgcc/config/nds32/isr-library/vec_vid49.S --+++ b/libgcc/config/nds32/isr-library/vec_vid49.S --@@ -24,8 +24,15 @@ -- . */ -- -- .section .nds32_vector.49, "ax" --+#if __NDS32_ISR_VECTOR_SIZE_4__ --+ /* The vector size is default 4-byte for v3 architecture. */ --+ .vec_size 4 --+ .align 2 --+#else --+ /* The vector size is default 16-byte for other architectures. */ -- .vec_size 16 -- .align 4 --+#endif -- .weak _nds32_vector_49 -- .type _nds32_vector_49, @function -- _nds32_vector_49: --diff --git a/libgcc/config/nds32/isr-library/vec_vid49_4b.S b/libgcc/config/nds32/isr-library/vec_vid49_4b.S --deleted file mode 100644 --index a510bbb..0000000 ----- a/libgcc/config/nds32/isr-library/vec_vid49_4b.S --+++ /dev/null --@@ -1,34 +0,0 @@ ---/* c-isr library stuff of Andes NDS32 cpu for GNU compiler --- Copyright (C) 2012-2016 Free Software Foundation, Inc. --- Contributed by Andes Technology Corporation. --- --- This file is part of GCC. --- --- GCC is free software; you can redistribute it and/or modify it --- under the terms of the GNU General Public License as published --- by the Free Software Foundation; either version 3, or (at your --- option) any later version. --- --- GCC is distributed in the hope that it will be useful, but WITHOUT --- ANY WARRANTY; without even the implied warranty of MERCHANTABILITY --- or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public --- License for more details. --- --- Under Section 7 of GPL version 3, you are granted additional --- permissions described in the GCC Runtime Library Exception, version --- 3.1, as published by the Free Software Foundation. --- --- You should have received a copy of the GNU General Public License and --- a copy of the GCC Runtime Library Exception along with this program; --- see the files COPYING3 and COPYING.RUNTIME respectively. If not, see --- . */ --- --- .section .nds32_vector.49, "ax" --- .vec_size 4 --- .align 2 --- .weak _nds32_vector_49_4b --- .type _nds32_vector_49_4b, @function ---_nds32_vector_49_4b: ---1: --- j 1b --- .size _nds32_vector_49_4b, .-_nds32_vector_49_4b --diff --git a/libgcc/config/nds32/isr-library/vec_vid50.S b/libgcc/config/nds32/isr-library/vec_vid50.S --index 48334feb..8f801ec 100644 ----- a/libgcc/config/nds32/isr-library/vec_vid50.S --+++ b/libgcc/config/nds32/isr-library/vec_vid50.S --@@ -24,8 +24,15 @@ -- . */ -- -- .section .nds32_vector.50, "ax" --+#if __NDS32_ISR_VECTOR_SIZE_4__ --+ /* The vector size is default 4-byte for v3 architecture. */ --+ .vec_size 4 --+ .align 2 --+#else --+ /* The vector size is default 16-byte for other architectures. */ -- .vec_size 16 -- .align 4 --+#endif -- .weak _nds32_vector_50 -- .type _nds32_vector_50, @function -- _nds32_vector_50: --diff --git a/libgcc/config/nds32/isr-library/vec_vid50_4b.S b/libgcc/config/nds32/isr-library/vec_vid50_4b.S --deleted file mode 100644 --index 1f42b73..0000000 ----- a/libgcc/config/nds32/isr-library/vec_vid50_4b.S --+++ /dev/null --@@ -1,34 +0,0 @@ ---/* c-isr library stuff of Andes NDS32 cpu for GNU compiler --- Copyright (C) 2012-2016 Free Software Foundation, Inc. --- Contributed by Andes Technology Corporation. --- --- This file is part of GCC. --- --- GCC is free software; you can redistribute it and/or modify it --- under the terms of the GNU General Public License as published --- by the Free Software Foundation; either version 3, or (at your --- option) any later version. --- --- GCC is distributed in the hope that it will be useful, but WITHOUT --- ANY WARRANTY; without even the implied warranty of MERCHANTABILITY --- or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public --- License for more details. --- --- Under Section 7 of GPL version 3, you are granted additional --- permissions described in the GCC Runtime Library Exception, version --- 3.1, as published by the Free Software Foundation. --- --- You should have received a copy of the GNU General Public License and --- a copy of the GCC Runtime Library Exception along with this program; --- see the files COPYING3 and COPYING.RUNTIME respectively. If not, see --- . */ --- --- .section .nds32_vector.50, "ax" --- .vec_size 4 --- .align 2 --- .weak _nds32_vector_50_4b --- .type _nds32_vector_50_4b, @function ---_nds32_vector_50_4b: ---1: --- j 1b --- .size _nds32_vector_50_4b, .-_nds32_vector_50_4b --diff --git a/libgcc/config/nds32/isr-library/vec_vid51.S b/libgcc/config/nds32/isr-library/vec_vid51.S --index 4c27f27..445abf9 100644 ----- a/libgcc/config/nds32/isr-library/vec_vid51.S --+++ b/libgcc/config/nds32/isr-library/vec_vid51.S --@@ -24,8 +24,15 @@ -- . */ -- -- .section .nds32_vector.51, "ax" --+#if __NDS32_ISR_VECTOR_SIZE_4__ --+ /* The vector size is default 4-byte for v3 architecture. */ --+ .vec_size 4 --+ .align 2 --+#else --+ /* The vector size is default 16-byte for other architectures. */ -- .vec_size 16 -- .align 4 --+#endif -- .weak _nds32_vector_51 -- .type _nds32_vector_51, @function -- _nds32_vector_51: --diff --git a/libgcc/config/nds32/isr-library/vec_vid51_4b.S b/libgcc/config/nds32/isr-library/vec_vid51_4b.S --deleted file mode 100644 --index 7bb8abe..0000000 ----- a/libgcc/config/nds32/isr-library/vec_vid51_4b.S --+++ /dev/null --@@ -1,34 +0,0 @@ ---/* c-isr library stuff of Andes NDS32 cpu for GNU compiler --- Copyright (C) 2012-2016 Free Software Foundation, Inc. --- Contributed by Andes Technology Corporation. --- --- This file is part of GCC. --- --- GCC is free software; you can redistribute it and/or modify it --- under the terms of the GNU General Public License as published --- by the Free Software Foundation; either version 3, or (at your --- option) any later version. --- --- GCC is distributed in the hope that it will be useful, but WITHOUT --- ANY WARRANTY; without even the implied warranty of MERCHANTABILITY --- or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public --- License for more details. --- --- Under Section 7 of GPL version 3, you are granted additional --- permissions described in the GCC Runtime Library Exception, version --- 3.1, as published by the Free Software Foundation. --- --- You should have received a copy of the GNU General Public License and --- a copy of the GCC Runtime Library Exception along with this program; --- see the files COPYING3 and COPYING.RUNTIME respectively. If not, see --- . */ --- --- .section .nds32_vector.51, "ax" --- .vec_size 4 --- .align 2 --- .weak _nds32_vector_51_4b --- .type _nds32_vector_51_4b, @function ---_nds32_vector_51_4b: ---1: --- j 1b --- .size _nds32_vector_51_4b, .-_nds32_vector_51_4b --diff --git a/libgcc/config/nds32/isr-library/vec_vid52.S b/libgcc/config/nds32/isr-library/vec_vid52.S --index 4c44811..7283975 100644 ----- a/libgcc/config/nds32/isr-library/vec_vid52.S --+++ b/libgcc/config/nds32/isr-library/vec_vid52.S --@@ -24,8 +24,15 @@ -- . */ -- -- .section .nds32_vector.52, "ax" --+#if __NDS32_ISR_VECTOR_SIZE_4__ --+ /* The vector size is default 4-byte for v3 architecture. */ --+ .vec_size 4 --+ .align 2 --+#else --+ /* The vector size is default 16-byte for other architectures. */ -- .vec_size 16 -- .align 4 --+#endif -- .weak _nds32_vector_52 -- .type _nds32_vector_52, @function -- _nds32_vector_52: --diff --git a/libgcc/config/nds32/isr-library/vec_vid52_4b.S b/libgcc/config/nds32/isr-library/vec_vid52_4b.S --deleted file mode 100644 --index 4cb89f6..0000000 ----- a/libgcc/config/nds32/isr-library/vec_vid52_4b.S --+++ /dev/null --@@ -1,34 +0,0 @@ ---/* c-isr library stuff of Andes NDS32 cpu for GNU compiler --- Copyright (C) 2012-2016 Free Software Foundation, Inc. --- Contributed by Andes Technology Corporation. --- --- This file is part of GCC. --- --- GCC is free software; you can redistribute it and/or modify it --- under the terms of the GNU General Public License as published --- by the Free Software Foundation; either version 3, or (at your --- option) any later version. --- --- GCC is distributed in the hope that it will be useful, but WITHOUT --- ANY WARRANTY; without even the implied warranty of MERCHANTABILITY --- or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public --- License for more details. --- --- Under Section 7 of GPL version 3, you are granted additional --- permissions described in the GCC Runtime Library Exception, version --- 3.1, as published by the Free Software Foundation. --- --- You should have received a copy of the GNU General Public License and --- a copy of the GCC Runtime Library Exception along with this program; --- see the files COPYING3 and COPYING.RUNTIME respectively. If not, see --- . */ --- --- .section .nds32_vector.52, "ax" --- .vec_size 4 --- .align 2 --- .weak _nds32_vector_52_4b --- .type _nds32_vector_52_4b, @function ---_nds32_vector_52_4b: ---1: --- j 1b --- .size _nds32_vector_52_4b, .-_nds32_vector_52_4b --diff --git a/libgcc/config/nds32/isr-library/vec_vid53.S b/libgcc/config/nds32/isr-library/vec_vid53.S --index 2882583..299c645 100644 ----- a/libgcc/config/nds32/isr-library/vec_vid53.S --+++ b/libgcc/config/nds32/isr-library/vec_vid53.S --@@ -24,8 +24,15 @@ -- . */ -- -- .section .nds32_vector.53, "ax" --+#if __NDS32_ISR_VECTOR_SIZE_4__ --+ /* The vector size is default 4-byte for v3 architecture. */ --+ .vec_size 4 --+ .align 2 --+#else --+ /* The vector size is default 16-byte for other architectures. */ -- .vec_size 16 -- .align 4 --+#endif -- .weak _nds32_vector_53 -- .type _nds32_vector_53, @function -- _nds32_vector_53: --diff --git a/libgcc/config/nds32/isr-library/vec_vid53_4b.S b/libgcc/config/nds32/isr-library/vec_vid53_4b.S --deleted file mode 100644 --index 9abc839..0000000 ----- a/libgcc/config/nds32/isr-library/vec_vid53_4b.S --+++ /dev/null --@@ -1,34 +0,0 @@ ---/* c-isr library stuff of Andes NDS32 cpu for GNU compiler --- Copyright (C) 2012-2016 Free Software Foundation, Inc. --- Contributed by Andes Technology Corporation. --- --- This file is part of GCC. --- --- GCC is free software; you can redistribute it and/or modify it --- under the terms of the GNU General Public License as published --- by the Free Software Foundation; either version 3, or (at your --- option) any later version. --- --- GCC is distributed in the hope that it will be useful, but WITHOUT --- ANY WARRANTY; without even the implied warranty of MERCHANTABILITY --- or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public --- License for more details. --- --- Under Section 7 of GPL version 3, you are granted additional --- permissions described in the GCC Runtime Library Exception, version --- 3.1, as published by the Free Software Foundation. --- --- You should have received a copy of the GNU General Public License and --- a copy of the GCC Runtime Library Exception along with this program; --- see the files COPYING3 and COPYING.RUNTIME respectively. If not, see --- . */ --- --- .section .nds32_vector.53, "ax" --- .vec_size 4 --- .align 2 --- .weak _nds32_vector_53_4b --- .type _nds32_vector_53_4b, @function ---_nds32_vector_53_4b: ---1: --- j 1b --- .size _nds32_vector_53_4b, .-_nds32_vector_53_4b --diff --git a/libgcc/config/nds32/isr-library/vec_vid54.S b/libgcc/config/nds32/isr-library/vec_vid54.S --index a014c72..ae99390 100644 ----- a/libgcc/config/nds32/isr-library/vec_vid54.S --+++ b/libgcc/config/nds32/isr-library/vec_vid54.S --@@ -24,8 +24,15 @@ -- . */ -- -- .section .nds32_vector.54, "ax" --+#if __NDS32_ISR_VECTOR_SIZE_4__ --+ /* The vector size is default 4-byte for v3 architecture. */ --+ .vec_size 4 --+ .align 2 --+#else --+ /* The vector size is default 16-byte for other architectures. */ -- .vec_size 16 -- .align 4 --+#endif -- .weak _nds32_vector_54 -- .type _nds32_vector_54, @function -- _nds32_vector_54: --diff --git a/libgcc/config/nds32/isr-library/vec_vid54_4b.S b/libgcc/config/nds32/isr-library/vec_vid54_4b.S --deleted file mode 100644 --index f736ba8..0000000 ----- a/libgcc/config/nds32/isr-library/vec_vid54_4b.S --+++ /dev/null --@@ -1,34 +0,0 @@ ---/* c-isr library stuff of Andes NDS32 cpu for GNU compiler --- Copyright (C) 2012-2016 Free Software Foundation, Inc. --- Contributed by Andes Technology Corporation. --- --- This file is part of GCC. --- --- GCC is free software; you can redistribute it and/or modify it --- under the terms of the GNU General Public License as published --- by the Free Software Foundation; either version 3, or (at your --- option) any later version. --- --- GCC is distributed in the hope that it will be useful, but WITHOUT --- ANY WARRANTY; without even the implied warranty of MERCHANTABILITY --- or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public --- License for more details. --- --- Under Section 7 of GPL version 3, you are granted additional --- permissions described in the GCC Runtime Library Exception, version --- 3.1, as published by the Free Software Foundation. --- --- You should have received a copy of the GNU General Public License and --- a copy of the GCC Runtime Library Exception along with this program; --- see the files COPYING3 and COPYING.RUNTIME respectively. If not, see --- . */ --- --- .section .nds32_vector.54, "ax" --- .vec_size 4 --- .align 2 --- .weak _nds32_vector_54_4b --- .type _nds32_vector_54_4b, @function ---_nds32_vector_54_4b: ---1: --- j 1b --- .size _nds32_vector_54_4b, .-_nds32_vector_54_4b --diff --git a/libgcc/config/nds32/isr-library/vec_vid55.S b/libgcc/config/nds32/isr-library/vec_vid55.S --index 44d820c..e75d24a 100644 ----- a/libgcc/config/nds32/isr-library/vec_vid55.S --+++ b/libgcc/config/nds32/isr-library/vec_vid55.S --@@ -24,8 +24,15 @@ -- . */ -- -- .section .nds32_vector.55, "ax" --+#if __NDS32_ISR_VECTOR_SIZE_4__ --+ /* The vector size is default 4-byte for v3 architecture. */ --+ .vec_size 4 --+ .align 2 --+#else --+ /* The vector size is default 16-byte for other architectures. */ -- .vec_size 16 -- .align 4 --+#endif -- .weak _nds32_vector_55 -- .type _nds32_vector_55, @function -- _nds32_vector_55: --diff --git a/libgcc/config/nds32/isr-library/vec_vid55_4b.S b/libgcc/config/nds32/isr-library/vec_vid55_4b.S --deleted file mode 100644 --index d09c665..0000000 ----- a/libgcc/config/nds32/isr-library/vec_vid55_4b.S --+++ /dev/null --@@ -1,34 +0,0 @@ ---/* c-isr library stuff of Andes NDS32 cpu for GNU compiler --- Copyright (C) 2012-2016 Free Software Foundation, Inc. --- Contributed by Andes Technology Corporation. --- --- This file is part of GCC. --- --- GCC is free software; you can redistribute it and/or modify it --- under the terms of the GNU General Public License as published --- by the Free Software Foundation; either version 3, or (at your --- option) any later version. --- --- GCC is distributed in the hope that it will be useful, but WITHOUT --- ANY WARRANTY; without even the implied warranty of MERCHANTABILITY --- or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public --- License for more details. --- --- Under Section 7 of GPL version 3, you are granted additional --- permissions described in the GCC Runtime Library Exception, version --- 3.1, as published by the Free Software Foundation. --- --- You should have received a copy of the GNU General Public License and --- a copy of the GCC Runtime Library Exception along with this program; --- see the files COPYING3 and COPYING.RUNTIME respectively. If not, see --- . */ --- --- .section .nds32_vector.55, "ax" --- .vec_size 4 --- .align 2 --- .weak _nds32_vector_55_4b --- .type _nds32_vector_55_4b, @function ---_nds32_vector_55_4b: ---1: --- j 1b --- .size _nds32_vector_55_4b, .-_nds32_vector_55_4b --diff --git a/libgcc/config/nds32/isr-library/vec_vid56.S b/libgcc/config/nds32/isr-library/vec_vid56.S --index d5cb362..cc4904e 100644 ----- a/libgcc/config/nds32/isr-library/vec_vid56.S --+++ b/libgcc/config/nds32/isr-library/vec_vid56.S --@@ -24,8 +24,15 @@ -- . */ -- -- .section .nds32_vector.56, "ax" --+#if __NDS32_ISR_VECTOR_SIZE_4__ --+ /* The vector size is default 4-byte for v3 architecture. */ --+ .vec_size 4 --+ .align 2 --+#else --+ /* The vector size is default 16-byte for other architectures. */ -- .vec_size 16 -- .align 4 --+#endif -- .weak _nds32_vector_56 -- .type _nds32_vector_56, @function -- _nds32_vector_56: --diff --git a/libgcc/config/nds32/isr-library/vec_vid56_4b.S b/libgcc/config/nds32/isr-library/vec_vid56_4b.S --deleted file mode 100644 --index 86b4103..0000000 ----- a/libgcc/config/nds32/isr-library/vec_vid56_4b.S --+++ /dev/null --@@ -1,34 +0,0 @@ ---/* c-isr library stuff of Andes NDS32 cpu for GNU compiler --- Copyright (C) 2012-2016 Free Software Foundation, Inc. --- Contributed by Andes Technology Corporation. --- --- This file is part of GCC. --- --- GCC is free software; you can redistribute it and/or modify it --- under the terms of the GNU General Public License as published --- by the Free Software Foundation; either version 3, or (at your --- option) any later version. --- --- GCC is distributed in the hope that it will be useful, but WITHOUT --- ANY WARRANTY; without even the implied warranty of MERCHANTABILITY --- or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public --- License for more details. --- --- Under Section 7 of GPL version 3, you are granted additional --- permissions described in the GCC Runtime Library Exception, version --- 3.1, as published by the Free Software Foundation. --- --- You should have received a copy of the GNU General Public License and --- a copy of the GCC Runtime Library Exception along with this program; --- see the files COPYING3 and COPYING.RUNTIME respectively. If not, see --- . */ --- --- .section .nds32_vector.56, "ax" --- .vec_size 4 --- .align 2 --- .weak _nds32_vector_56_4b --- .type _nds32_vector_56_4b, @function ---_nds32_vector_56_4b: ---1: --- j 1b --- .size _nds32_vector_56_4b, .-_nds32_vector_56_4b --diff --git a/libgcc/config/nds32/isr-library/vec_vid57.S b/libgcc/config/nds32/isr-library/vec_vid57.S --index 5fb3ce9..a17ed45 100644 ----- a/libgcc/config/nds32/isr-library/vec_vid57.S --+++ b/libgcc/config/nds32/isr-library/vec_vid57.S --@@ -24,8 +24,15 @@ -- . */ -- -- .section .nds32_vector.57, "ax" --+#if __NDS32_ISR_VECTOR_SIZE_4__ --+ /* The vector size is default 4-byte for v3 architecture. */ --+ .vec_size 4 --+ .align 2 --+#else --+ /* The vector size is default 16-byte for other architectures. */ -- .vec_size 16 -- .align 4 --+#endif -- .weak _nds32_vector_57 -- .type _nds32_vector_57, @function -- _nds32_vector_57: --diff --git a/libgcc/config/nds32/isr-library/vec_vid57_4b.S b/libgcc/config/nds32/isr-library/vec_vid57_4b.S --deleted file mode 100644 --index 45c5d29..0000000 ----- a/libgcc/config/nds32/isr-library/vec_vid57_4b.S --+++ /dev/null --@@ -1,34 +0,0 @@ ---/* c-isr library stuff of Andes NDS32 cpu for GNU compiler --- Copyright (C) 2012-2016 Free Software Foundation, Inc. --- Contributed by Andes Technology Corporation. --- --- This file is part of GCC. --- --- GCC is free software; you can redistribute it and/or modify it --- under the terms of the GNU General Public License as published --- by the Free Software Foundation; either version 3, or (at your --- option) any later version. --- --- GCC is distributed in the hope that it will be useful, but WITHOUT --- ANY WARRANTY; without even the implied warranty of MERCHANTABILITY --- or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public --- License for more details. --- --- Under Section 7 of GPL version 3, you are granted additional --- permissions described in the GCC Runtime Library Exception, version --- 3.1, as published by the Free Software Foundation. --- --- You should have received a copy of the GNU General Public License and --- a copy of the GCC Runtime Library Exception along with this program; --- see the files COPYING3 and COPYING.RUNTIME respectively. If not, see --- . */ --- --- .section .nds32_vector.57, "ax" --- .vec_size 4 --- .align 2 --- .weak _nds32_vector_57_4b --- .type _nds32_vector_57_4b, @function ---_nds32_vector_57_4b: ---1: --- j 1b --- .size _nds32_vector_57_4b, .-_nds32_vector_57_4b --diff --git a/libgcc/config/nds32/isr-library/vec_vid58.S b/libgcc/config/nds32/isr-library/vec_vid58.S --index d420d68..629bf1a 100644 ----- a/libgcc/config/nds32/isr-library/vec_vid58.S --+++ b/libgcc/config/nds32/isr-library/vec_vid58.S --@@ -24,8 +24,15 @@ -- . */ -- -- .section .nds32_vector.58, "ax" --+#if __NDS32_ISR_VECTOR_SIZE_4__ --+ /* The vector size is default 4-byte for v3 architecture. */ --+ .vec_size 4 --+ .align 2 --+#else --+ /* The vector size is default 16-byte for other architectures. */ -- .vec_size 16 -- .align 4 --+#endif -- .weak _nds32_vector_58 -- .type _nds32_vector_58, @function -- _nds32_vector_58: --diff --git a/libgcc/config/nds32/isr-library/vec_vid58_4b.S b/libgcc/config/nds32/isr-library/vec_vid58_4b.S --deleted file mode 100644 --index 812470c..0000000 ----- a/libgcc/config/nds32/isr-library/vec_vid58_4b.S --+++ /dev/null --@@ -1,34 +0,0 @@ ---/* c-isr library stuff of Andes NDS32 cpu for GNU compiler --- Copyright (C) 2012-2016 Free Software Foundation, Inc. --- Contributed by Andes Technology Corporation. --- --- This file is part of GCC. --- --- GCC is free software; you can redistribute it and/or modify it --- under the terms of the GNU General Public License as published --- by the Free Software Foundation; either version 3, or (at your --- option) any later version. --- --- GCC is distributed in the hope that it will be useful, but WITHOUT --- ANY WARRANTY; without even the implied warranty of MERCHANTABILITY --- or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public --- License for more details. --- --- Under Section 7 of GPL version 3, you are granted additional --- permissions described in the GCC Runtime Library Exception, version --- 3.1, as published by the Free Software Foundation. --- --- You should have received a copy of the GNU General Public License and --- a copy of the GCC Runtime Library Exception along with this program; --- see the files COPYING3 and COPYING.RUNTIME respectively. If not, see --- . */ --- --- .section .nds32_vector.58, "ax" --- .vec_size 4 --- .align 2 --- .weak _nds32_vector_58_4b --- .type _nds32_vector_58_4b, @function ---_nds32_vector_58_4b: ---1: --- j 1b --- .size _nds32_vector_58_4b, .-_nds32_vector_58_4b --diff --git a/libgcc/config/nds32/isr-library/vec_vid59.S b/libgcc/config/nds32/isr-library/vec_vid59.S --index 78a1885..540e02e 100644 ----- a/libgcc/config/nds32/isr-library/vec_vid59.S --+++ b/libgcc/config/nds32/isr-library/vec_vid59.S --@@ -24,8 +24,15 @@ -- . */ -- -- .section .nds32_vector.59, "ax" --+#if __NDS32_ISR_VECTOR_SIZE_4__ --+ /* The vector size is default 4-byte for v3 architecture. */ --+ .vec_size 4 --+ .align 2 --+#else --+ /* The vector size is default 16-byte for other architectures. */ -- .vec_size 16 -- .align 4 --+#endif -- .weak _nds32_vector_59 -- .type _nds32_vector_59, @function -- _nds32_vector_59: --diff --git a/libgcc/config/nds32/isr-library/vec_vid59_4b.S b/libgcc/config/nds32/isr-library/vec_vid59_4b.S --deleted file mode 100644 --index fa3a467..0000000 ----- a/libgcc/config/nds32/isr-library/vec_vid59_4b.S --+++ /dev/null --@@ -1,34 +0,0 @@ ---/* c-isr library stuff of Andes NDS32 cpu for GNU compiler --- Copyright (C) 2012-2016 Free Software Foundation, Inc. --- Contributed by Andes Technology Corporation. --- --- This file is part of GCC. --- --- GCC is free software; you can redistribute it and/or modify it --- under the terms of the GNU General Public License as published --- by the Free Software Foundation; either version 3, or (at your --- option) any later version. --- --- GCC is distributed in the hope that it will be useful, but WITHOUT --- ANY WARRANTY; without even the implied warranty of MERCHANTABILITY --- or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public --- License for more details. --- --- Under Section 7 of GPL version 3, you are granted additional --- permissions described in the GCC Runtime Library Exception, version --- 3.1, as published by the Free Software Foundation. --- --- You should have received a copy of the GNU General Public License and --- a copy of the GCC Runtime Library Exception along with this program; --- see the files COPYING3 and COPYING.RUNTIME respectively. If not, see --- . */ --- --- .section .nds32_vector.59, "ax" --- .vec_size 4 --- .align 2 --- .weak _nds32_vector_59_4b --- .type _nds32_vector_59_4b, @function ---_nds32_vector_59_4b: ---1: --- j 1b --- .size _nds32_vector_59_4b, .-_nds32_vector_59_4b --diff --git a/libgcc/config/nds32/isr-library/vec_vid60.S b/libgcc/config/nds32/isr-library/vec_vid60.S --index a6f704d..8658249 100644 ----- a/libgcc/config/nds32/isr-library/vec_vid60.S --+++ b/libgcc/config/nds32/isr-library/vec_vid60.S --@@ -24,8 +24,15 @@ -- . */ -- -- .section .nds32_vector.60, "ax" --+#if __NDS32_ISR_VECTOR_SIZE_4__ --+ /* The vector size is default 4-byte for v3 architecture. */ --+ .vec_size 4 --+ .align 2 --+#else --+ /* The vector size is default 16-byte for other architectures. */ -- .vec_size 16 -- .align 4 --+#endif -- .weak _nds32_vector_60 -- .type _nds32_vector_60, @function -- _nds32_vector_60: --diff --git a/libgcc/config/nds32/isr-library/vec_vid60_4b.S b/libgcc/config/nds32/isr-library/vec_vid60_4b.S --deleted file mode 100644 --index 505da2a..0000000 ----- a/libgcc/config/nds32/isr-library/vec_vid60_4b.S --+++ /dev/null --@@ -1,34 +0,0 @@ ---/* c-isr library stuff of Andes NDS32 cpu for GNU compiler --- Copyright (C) 2012-2016 Free Software Foundation, Inc. --- Contributed by Andes Technology Corporation. --- --- This file is part of GCC. --- --- GCC is free software; you can redistribute it and/or modify it --- under the terms of the GNU General Public License as published --- by the Free Software Foundation; either version 3, or (at your --- option) any later version. --- --- GCC is distributed in the hope that it will be useful, but WITHOUT --- ANY WARRANTY; without even the implied warranty of MERCHANTABILITY --- or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public --- License for more details. --- --- Under Section 7 of GPL version 3, you are granted additional --- permissions described in the GCC Runtime Library Exception, version --- 3.1, as published by the Free Software Foundation. --- --- You should have received a copy of the GNU General Public License and --- a copy of the GCC Runtime Library Exception along with this program; --- see the files COPYING3 and COPYING.RUNTIME respectively. If not, see --- . */ --- --- .section .nds32_vector.60, "ax" --- .vec_size 4 --- .align 2 --- .weak _nds32_vector_60_4b --- .type _nds32_vector_60_4b, @function ---_nds32_vector_60_4b: ---1: --- j 1b --- .size _nds32_vector_60_4b, .-_nds32_vector_60_4b --diff --git a/libgcc/config/nds32/isr-library/vec_vid61.S b/libgcc/config/nds32/isr-library/vec_vid61.S --index 4e79bde..376acb9 100644 ----- a/libgcc/config/nds32/isr-library/vec_vid61.S --+++ b/libgcc/config/nds32/isr-library/vec_vid61.S --@@ -24,8 +24,15 @@ -- . */ -- -- .section .nds32_vector.61, "ax" --+#if __NDS32_ISR_VECTOR_SIZE_4__ --+ /* The vector size is default 4-byte for v3 architecture. */ --+ .vec_size 4 --+ .align 2 --+#else --+ /* The vector size is default 16-byte for other architectures. */ -- .vec_size 16 -- .align 4 --+#endif -- .weak _nds32_vector_61 -- .type _nds32_vector_61, @function -- _nds32_vector_61: --diff --git a/libgcc/config/nds32/isr-library/vec_vid61_4b.S b/libgcc/config/nds32/isr-library/vec_vid61_4b.S --deleted file mode 100644 --index 9a0cce5..0000000 ----- a/libgcc/config/nds32/isr-library/vec_vid61_4b.S --+++ /dev/null --@@ -1,34 +0,0 @@ ---/* c-isr library stuff of Andes NDS32 cpu for GNU compiler --- Copyright (C) 2012-2016 Free Software Foundation, Inc. --- Contributed by Andes Technology Corporation. --- --- This file is part of GCC. --- --- GCC is free software; you can redistribute it and/or modify it --- under the terms of the GNU General Public License as published --- by the Free Software Foundation; either version 3, or (at your --- option) any later version. --- --- GCC is distributed in the hope that it will be useful, but WITHOUT --- ANY WARRANTY; without even the implied warranty of MERCHANTABILITY --- or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public --- License for more details. --- --- Under Section 7 of GPL version 3, you are granted additional --- permissions described in the GCC Runtime Library Exception, version --- 3.1, as published by the Free Software Foundation. --- --- You should have received a copy of the GNU General Public License and --- a copy of the GCC Runtime Library Exception along with this program; --- see the files COPYING3 and COPYING.RUNTIME respectively. If not, see --- . */ --- --- .section .nds32_vector.61, "ax" --- .vec_size 4 --- .align 2 --- .weak _nds32_vector_61_4b --- .type _nds32_vector_61_4b, @function ---_nds32_vector_61_4b: ---1: --- j 1b --- .size _nds32_vector_61_4b, .-_nds32_vector_61_4b --diff --git a/libgcc/config/nds32/isr-library/vec_vid62.S b/libgcc/config/nds32/isr-library/vec_vid62.S --index 5eef0a6..5ab06a8 100644 ----- a/libgcc/config/nds32/isr-library/vec_vid62.S --+++ b/libgcc/config/nds32/isr-library/vec_vid62.S --@@ -24,8 +24,15 @@ -- . */ -- -- .section .nds32_vector.62, "ax" --+#if __NDS32_ISR_VECTOR_SIZE_4__ --+ /* The vector size is default 4-byte for v3 architecture. */ --+ .vec_size 4 --+ .align 2 --+#else --+ /* The vector size is default 16-byte for other architectures. */ -- .vec_size 16 -- .align 4 --+#endif -- .weak _nds32_vector_62 -- .type _nds32_vector_62, @function -- _nds32_vector_62: --diff --git a/libgcc/config/nds32/isr-library/vec_vid62_4b.S b/libgcc/config/nds32/isr-library/vec_vid62_4b.S --deleted file mode 100644 --index da8ba28..0000000 ----- a/libgcc/config/nds32/isr-library/vec_vid62_4b.S --+++ /dev/null --@@ -1,34 +0,0 @@ ---/* c-isr library stuff of Andes NDS32 cpu for GNU compiler --- Copyright (C) 2012-2016 Free Software Foundation, Inc. --- Contributed by Andes Technology Corporation. --- --- This file is part of GCC. --- --- GCC is free software; you can redistribute it and/or modify it --- under the terms of the GNU General Public License as published --- by the Free Software Foundation; either version 3, or (at your --- option) any later version. --- --- GCC is distributed in the hope that it will be useful, but WITHOUT --- ANY WARRANTY; without even the implied warranty of MERCHANTABILITY --- or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public --- License for more details. --- --- Under Section 7 of GPL version 3, you are granted additional --- permissions described in the GCC Runtime Library Exception, version --- 3.1, as published by the Free Software Foundation. --- --- You should have received a copy of the GNU General Public License and --- a copy of the GCC Runtime Library Exception along with this program; --- see the files COPYING3 and COPYING.RUNTIME respectively. If not, see --- . */ --- --- .section .nds32_vector.62, "ax" --- .vec_size 4 --- .align 2 --- .weak _nds32_vector_62_4b --- .type _nds32_vector_62_4b, @function ---_nds32_vector_62_4b: ---1: --- j 1b --- .size _nds32_vector_62_4b, .-_nds32_vector_62_4b --diff --git a/libgcc/config/nds32/isr-library/vec_vid63.S b/libgcc/config/nds32/isr-library/vec_vid63.S --index 0a8c0ad..6646bcc 100644 ----- a/libgcc/config/nds32/isr-library/vec_vid63.S --+++ b/libgcc/config/nds32/isr-library/vec_vid63.S --@@ -24,8 +24,15 @@ -- . */ -- -- .section .nds32_vector.63, "ax" --+#if __NDS32_ISR_VECTOR_SIZE_4__ --+ /* The vector size is default 4-byte for v3 architecture. */ --+ .vec_size 4 --+ .align 2 --+#else --+ /* The vector size is default 16-byte for other architectures. */ -- .vec_size 16 -- .align 4 --+#endif -- .weak _nds32_vector_63 -- .type _nds32_vector_63, @function -- _nds32_vector_63: --diff --git a/libgcc/config/nds32/isr-library/vec_vid63_4b.S b/libgcc/config/nds32/isr-library/vec_vid63_4b.S --deleted file mode 100644 --index 8f1045e..0000000 ----- a/libgcc/config/nds32/isr-library/vec_vid63_4b.S --+++ /dev/null --@@ -1,34 +0,0 @@ ---/* c-isr library stuff of Andes NDS32 cpu for GNU compiler --- Copyright (C) 2012-2016 Free Software Foundation, Inc. --- Contributed by Andes Technology Corporation. --- --- This file is part of GCC. --- --- GCC is free software; you can redistribute it and/or modify it --- under the terms of the GNU General Public License as published --- by the Free Software Foundation; either version 3, or (at your --- option) any later version. --- --- GCC is distributed in the hope that it will be useful, but WITHOUT --- ANY WARRANTY; without even the implied warranty of MERCHANTABILITY --- or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public --- License for more details. --- --- Under Section 7 of GPL version 3, you are granted additional --- permissions described in the GCC Runtime Library Exception, version --- 3.1, as published by the Free Software Foundation. --- --- You should have received a copy of the GNU General Public License and --- a copy of the GCC Runtime Library Exception along with this program; --- see the files COPYING3 and COPYING.RUNTIME respectively. If not, see --- . */ --- --- .section .nds32_vector.63, "ax" --- .vec_size 4 --- .align 2 --- .weak _nds32_vector_63_4b --- .type _nds32_vector_63_4b, @function ---_nds32_vector_63_4b: ---1: --- j 1b --- .size _nds32_vector_63_4b, .-_nds32_vector_63_4b --diff --git a/libgcc/config/nds32/isr-library/vec_vid64.S b/libgcc/config/nds32/isr-library/vec_vid64.S --index b3f034b..f892aec 100644 ----- a/libgcc/config/nds32/isr-library/vec_vid64.S --+++ b/libgcc/config/nds32/isr-library/vec_vid64.S --@@ -24,8 +24,15 @@ -- . */ -- -- .section .nds32_vector.64, "ax" --+#if __NDS32_ISR_VECTOR_SIZE_4__ --+ /* The vector size is default 4-byte for v3 architecture. */ --+ .vec_size 4 --+ .align 2 --+#else --+ /* The vector size is default 16-byte for other architectures. */ -- .vec_size 16 -- .align 4 --+#endif -- .weak _nds32_vector_64 -- .type _nds32_vector_64, @function -- _nds32_vector_64: --diff --git a/libgcc/config/nds32/isr-library/vec_vid64_4b.S b/libgcc/config/nds32/isr-library/vec_vid64_4b.S --deleted file mode 100644 --index 81d9679..0000000 ----- a/libgcc/config/nds32/isr-library/vec_vid64_4b.S --+++ /dev/null --@@ -1,34 +0,0 @@ ---/* c-isr library stuff of Andes NDS32 cpu for GNU compiler --- Copyright (C) 2012-2016 Free Software Foundation, Inc. --- Contributed by Andes Technology Corporation. --- --- This file is part of GCC. --- --- GCC is free software; you can redistribute it and/or modify it --- under the terms of the GNU General Public License as published --- by the Free Software Foundation; either version 3, or (at your --- option) any later version. --- --- GCC is distributed in the hope that it will be useful, but WITHOUT --- ANY WARRANTY; without even the implied warranty of MERCHANTABILITY --- or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public --- License for more details. --- --- Under Section 7 of GPL version 3, you are granted additional --- permissions described in the GCC Runtime Library Exception, version --- 3.1, as published by the Free Software Foundation. --- --- You should have received a copy of the GNU General Public License and --- a copy of the GCC Runtime Library Exception along with this program; --- see the files COPYING3 and COPYING.RUNTIME respectively. If not, see --- . */ --- --- .section .nds32_vector.64, "ax" --- .vec_size 4 --- .align 2 --- .weak _nds32_vector_64_4b --- .type _nds32_vector_64_4b, @function ---_nds32_vector_64_4b: ---1: --- j 1b --- .size _nds32_vector_64_4b, .-_nds32_vector_64_4b --diff --git a/libgcc/config/nds32/isr-library/vec_vid65.S b/libgcc/config/nds32/isr-library/vec_vid65.S --index 72db454..03f79a5 100644 ----- a/libgcc/config/nds32/isr-library/vec_vid65.S --+++ b/libgcc/config/nds32/isr-library/vec_vid65.S --@@ -24,8 +24,15 @@ -- . */ -- -- .section .nds32_vector.65, "ax" --+#if __NDS32_ISR_VECTOR_SIZE_4__ --+ /* The vector size is default 4-byte for v3 architecture. */ --+ .vec_size 4 --+ .align 2 --+#else --+ /* The vector size is default 16-byte for other architectures. */ -- .vec_size 16 -- .align 4 --+#endif -- .weak _nds32_vector_65 -- .type _nds32_vector_65, @function -- _nds32_vector_65: --diff --git a/libgcc/config/nds32/isr-library/vec_vid65_4b.S b/libgcc/config/nds32/isr-library/vec_vid65_4b.S --deleted file mode 100644 --index aa9ad2b..0000000 ----- a/libgcc/config/nds32/isr-library/vec_vid65_4b.S --+++ /dev/null --@@ -1,34 +0,0 @@ ---/* c-isr library stuff of Andes NDS32 cpu for GNU compiler --- Copyright (C) 2012-2016 Free Software Foundation, Inc. --- Contributed by Andes Technology Corporation. --- --- This file is part of GCC. --- --- GCC is free software; you can redistribute it and/or modify it --- under the terms of the GNU General Public License as published --- by the Free Software Foundation; either version 3, or (at your --- option) any later version. --- --- GCC is distributed in the hope that it will be useful, but WITHOUT --- ANY WARRANTY; without even the implied warranty of MERCHANTABILITY --- or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public --- License for more details. --- --- Under Section 7 of GPL version 3, you are granted additional --- permissions described in the GCC Runtime Library Exception, version --- 3.1, as published by the Free Software Foundation. --- --- You should have received a copy of the GNU General Public License and --- a copy of the GCC Runtime Library Exception along with this program; --- see the files COPYING3 and COPYING.RUNTIME respectively. If not, see --- . */ --- --- .section .nds32_vector.65, "ax" --- .vec_size 4 --- .align 2 --- .weak _nds32_vector_65_4b --- .type _nds32_vector_65_4b, @function ---_nds32_vector_65_4b: ---1: --- j 1b --- .size _nds32_vector_65_4b, .-_nds32_vector_65_4b --diff --git a/libgcc/config/nds32/isr-library/vec_vid66.S b/libgcc/config/nds32/isr-library/vec_vid66.S --index 75469e7..ff805bd 100644 ----- a/libgcc/config/nds32/isr-library/vec_vid66.S --+++ b/libgcc/config/nds32/isr-library/vec_vid66.S --@@ -24,8 +24,15 @@ -- . */ -- -- .section .nds32_vector.66, "ax" --+#if __NDS32_ISR_VECTOR_SIZE_4__ --+ /* The vector size is default 4-byte for v3 architecture. */ --+ .vec_size 4 --+ .align 2 --+#else --+ /* The vector size is default 16-byte for other architectures. */ -- .vec_size 16 -- .align 4 --+#endif -- .weak _nds32_vector_66 -- .type _nds32_vector_66, @function -- _nds32_vector_66: --diff --git a/libgcc/config/nds32/isr-library/vec_vid66_4b.S b/libgcc/config/nds32/isr-library/vec_vid66_4b.S --deleted file mode 100644 --index 9830fe2..0000000 ----- a/libgcc/config/nds32/isr-library/vec_vid66_4b.S --+++ /dev/null --@@ -1,34 +0,0 @@ ---/* c-isr library stuff of Andes NDS32 cpu for GNU compiler --- Copyright (C) 2012-2016 Free Software Foundation, Inc. --- Contributed by Andes Technology Corporation. --- --- This file is part of GCC. --- --- GCC is free software; you can redistribute it and/or modify it --- under the terms of the GNU General Public License as published --- by the Free Software Foundation; either version 3, or (at your --- option) any later version. --- --- GCC is distributed in the hope that it will be useful, but WITHOUT --- ANY WARRANTY; without even the implied warranty of MERCHANTABILITY --- or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public --- License for more details. --- --- Under Section 7 of GPL version 3, you are granted additional --- permissions described in the GCC Runtime Library Exception, version --- 3.1, as published by the Free Software Foundation. --- --- You should have received a copy of the GNU General Public License and --- a copy of the GCC Runtime Library Exception along with this program; --- see the files COPYING3 and COPYING.RUNTIME respectively. If not, see --- . */ --- --- .section .nds32_vector.66, "ax" --- .vec_size 4 --- .align 2 --- .weak _nds32_vector_66_4b --- .type _nds32_vector_66_4b, @function ---_nds32_vector_66_4b: ---1: --- j 1b --- .size _nds32_vector_66_4b, .-_nds32_vector_66_4b --diff --git a/libgcc/config/nds32/isr-library/vec_vid67.S b/libgcc/config/nds32/isr-library/vec_vid67.S --index 4b076cd..f592aba 100644 ----- a/libgcc/config/nds32/isr-library/vec_vid67.S --+++ b/libgcc/config/nds32/isr-library/vec_vid67.S --@@ -24,8 +24,15 @@ -- . */ -- -- .section .nds32_vector.67, "ax" --+#if __NDS32_ISR_VECTOR_SIZE_4__ --+ /* The vector size is default 4-byte for v3 architecture. */ --+ .vec_size 4 --+ .align 2 --+#else --+ /* The vector size is default 16-byte for other architectures. */ -- .vec_size 16 -- .align 4 --+#endif -- .weak _nds32_vector_67 -- .type _nds32_vector_67, @function -- _nds32_vector_67: --diff --git a/libgcc/config/nds32/isr-library/vec_vid67_4b.S b/libgcc/config/nds32/isr-library/vec_vid67_4b.S --deleted file mode 100644 --index c7e31dd..0000000 ----- a/libgcc/config/nds32/isr-library/vec_vid67_4b.S --+++ /dev/null --@@ -1,34 +0,0 @@ ---/* c-isr library stuff of Andes NDS32 cpu for GNU compiler --- Copyright (C) 2012-2016 Free Software Foundation, Inc. --- Contributed by Andes Technology Corporation. --- --- This file is part of GCC. --- --- GCC is free software; you can redistribute it and/or modify it --- under the terms of the GNU General Public License as published --- by the Free Software Foundation; either version 3, or (at your --- option) any later version. --- --- GCC is distributed in the hope that it will be useful, but WITHOUT --- ANY WARRANTY; without even the implied warranty of MERCHANTABILITY --- or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public --- License for more details. --- --- Under Section 7 of GPL version 3, you are granted additional --- permissions described in the GCC Runtime Library Exception, version --- 3.1, as published by the Free Software Foundation. --- --- You should have received a copy of the GNU General Public License and --- a copy of the GCC Runtime Library Exception along with this program; --- see the files COPYING3 and COPYING.RUNTIME respectively. If not, see --- . */ --- --- .section .nds32_vector.67, "ax" --- .vec_size 4 --- .align 2 --- .weak _nds32_vector_67_4b --- .type _nds32_vector_67_4b, @function ---_nds32_vector_67_4b: ---1: --- j 1b --- .size _nds32_vector_67_4b, .-_nds32_vector_67_4b --diff --git a/libgcc/config/nds32/isr-library/vec_vid68.S b/libgcc/config/nds32/isr-library/vec_vid68.S --index 7df1cdd..ee2702a 100644 ----- a/libgcc/config/nds32/isr-library/vec_vid68.S --+++ b/libgcc/config/nds32/isr-library/vec_vid68.S --@@ -24,8 +24,15 @@ -- . */ -- -- .section .nds32_vector.68, "ax" --+#if __NDS32_ISR_VECTOR_SIZE_4__ --+ /* The vector size is default 4-byte for v3 architecture. */ --+ .vec_size 4 --+ .align 2 --+#else --+ /* The vector size is default 16-byte for other architectures. */ -- .vec_size 16 -- .align 4 --+#endif -- .weak _nds32_vector_68 -- .type _nds32_vector_68, @function -- _nds32_vector_68: --diff --git a/libgcc/config/nds32/isr-library/vec_vid68_4b.S b/libgcc/config/nds32/isr-library/vec_vid68_4b.S --deleted file mode 100644 --index 0d6fcb5..0000000 ----- a/libgcc/config/nds32/isr-library/vec_vid68_4b.S --+++ /dev/null --@@ -1,34 +0,0 @@ ---/* c-isr library stuff of Andes NDS32 cpu for GNU compiler --- Copyright (C) 2012-2016 Free Software Foundation, Inc. --- Contributed by Andes Technology Corporation. --- --- This file is part of GCC. --- --- GCC is free software; you can redistribute it and/or modify it --- under the terms of the GNU General Public License as published --- by the Free Software Foundation; either version 3, or (at your --- option) any later version. --- --- GCC is distributed in the hope that it will be useful, but WITHOUT --- ANY WARRANTY; without even the implied warranty of MERCHANTABILITY --- or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public --- License for more details. --- --- Under Section 7 of GPL version 3, you are granted additional --- permissions described in the GCC Runtime Library Exception, version --- 3.1, as published by the Free Software Foundation. --- --- You should have received a copy of the GNU General Public License and --- a copy of the GCC Runtime Library Exception along with this program; --- see the files COPYING3 and COPYING.RUNTIME respectively. If not, see --- . */ --- --- .section .nds32_vector.68, "ax" --- .vec_size 4 --- .align 2 --- .weak _nds32_vector_68_4b --- .type _nds32_vector_68_4b, @function ---_nds32_vector_68_4b: ---1: --- j 1b --- .size _nds32_vector_68_4b, .-_nds32_vector_68_4b --diff --git a/libgcc/config/nds32/isr-library/vec_vid69.S b/libgcc/config/nds32/isr-library/vec_vid69.S --index e30e5bf..c152015 100644 ----- a/libgcc/config/nds32/isr-library/vec_vid69.S --+++ b/libgcc/config/nds32/isr-library/vec_vid69.S --@@ -24,8 +24,15 @@ -- . */ -- -- .section .nds32_vector.69, "ax" --+#if __NDS32_ISR_VECTOR_SIZE_4__ --+ /* The vector size is default 4-byte for v3 architecture. */ --+ .vec_size 4 --+ .align 2 --+#else --+ /* The vector size is default 16-byte for other architectures. */ -- .vec_size 16 -- .align 4 --+#endif -- .weak _nds32_vector_69 -- .type _nds32_vector_69, @function -- _nds32_vector_69: --diff --git a/libgcc/config/nds32/isr-library/vec_vid69_4b.S b/libgcc/config/nds32/isr-library/vec_vid69_4b.S --deleted file mode 100644 --index 3508162..0000000 ----- a/libgcc/config/nds32/isr-library/vec_vid69_4b.S --+++ /dev/null --@@ -1,34 +0,0 @@ ---/* c-isr library stuff of Andes NDS32 cpu for GNU compiler --- Copyright (C) 2012-2016 Free Software Foundation, Inc. --- Contributed by Andes Technology Corporation. --- --- This file is part of GCC. --- --- GCC is free software; you can redistribute it and/or modify it --- under the terms of the GNU General Public License as published --- by the Free Software Foundation; either version 3, or (at your --- option) any later version. --- --- GCC is distributed in the hope that it will be useful, but WITHOUT --- ANY WARRANTY; without even the implied warranty of MERCHANTABILITY --- or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public --- License for more details. --- --- Under Section 7 of GPL version 3, you are granted additional --- permissions described in the GCC Runtime Library Exception, version --- 3.1, as published by the Free Software Foundation. --- --- You should have received a copy of the GNU General Public License and --- a copy of the GCC Runtime Library Exception along with this program; --- see the files COPYING3 and COPYING.RUNTIME respectively. If not, see --- . */ --- --- .section .nds32_vector.69, "ax" --- .vec_size 4 --- .align 2 --- .weak _nds32_vector_69_4b --- .type _nds32_vector_69_4b, @function ---_nds32_vector_69_4b: ---1: --- j 1b --- .size _nds32_vector_69_4b, .-_nds32_vector_69_4b --diff --git a/libgcc/config/nds32/isr-library/vec_vid70.S b/libgcc/config/nds32/isr-library/vec_vid70.S --index d436ac5..a3578d6 100644 ----- a/libgcc/config/nds32/isr-library/vec_vid70.S --+++ b/libgcc/config/nds32/isr-library/vec_vid70.S --@@ -24,8 +24,15 @@ -- . */ -- -- .section .nds32_vector.70, "ax" --+#if __NDS32_ISR_VECTOR_SIZE_4__ --+ /* The vector size is default 4-byte for v3 architecture. */ --+ .vec_size 4 --+ .align 2 --+#else --+ /* The vector size is default 16-byte for other architectures. */ -- .vec_size 16 -- .align 4 --+#endif -- .weak _nds32_vector_70 -- .type _nds32_vector_70, @function -- _nds32_vector_70: --diff --git a/libgcc/config/nds32/isr-library/vec_vid70_4b.S b/libgcc/config/nds32/isr-library/vec_vid70_4b.S --deleted file mode 100644 --index f3f0dd6..0000000 ----- a/libgcc/config/nds32/isr-library/vec_vid70_4b.S --+++ /dev/null --@@ -1,34 +0,0 @@ ---/* c-isr library stuff of Andes NDS32 cpu for GNU compiler --- Copyright (C) 2012-2016 Free Software Foundation, Inc. --- Contributed by Andes Technology Corporation. --- --- This file is part of GCC. --- --- GCC is free software; you can redistribute it and/or modify it --- under the terms of the GNU General Public License as published --- by the Free Software Foundation; either version 3, or (at your --- option) any later version. --- --- GCC is distributed in the hope that it will be useful, but WITHOUT --- ANY WARRANTY; without even the implied warranty of MERCHANTABILITY --- or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public --- License for more details. --- --- Under Section 7 of GPL version 3, you are granted additional --- permissions described in the GCC Runtime Library Exception, version --- 3.1, as published by the Free Software Foundation. --- --- You should have received a copy of the GNU General Public License and --- a copy of the GCC Runtime Library Exception along with this program; --- see the files COPYING3 and COPYING.RUNTIME respectively. If not, see --- . */ --- --- .section .nds32_vector.70, "ax" --- .vec_size 4 --- .align 2 --- .weak _nds32_vector_70_4b --- .type _nds32_vector_70_4b, @function ---_nds32_vector_70_4b: ---1: --- j 1b --- .size _nds32_vector_70_4b, .-_nds32_vector_70_4b --diff --git a/libgcc/config/nds32/isr-library/vec_vid71.S b/libgcc/config/nds32/isr-library/vec_vid71.S --index d7d7ab3..6790888 100644 ----- a/libgcc/config/nds32/isr-library/vec_vid71.S --+++ b/libgcc/config/nds32/isr-library/vec_vid71.S --@@ -24,8 +24,15 @@ -- . */ -- -- .section .nds32_vector.71, "ax" --+#if __NDS32_ISR_VECTOR_SIZE_4__ --+ /* The vector size is default 4-byte for v3 architecture. */ --+ .vec_size 4 --+ .align 2 --+#else --+ /* The vector size is default 16-byte for other architectures. */ -- .vec_size 16 -- .align 4 --+#endif -- .weak _nds32_vector_71 -- .type _nds32_vector_71, @function -- _nds32_vector_71: --diff --git a/libgcc/config/nds32/isr-library/vec_vid71_4b.S b/libgcc/config/nds32/isr-library/vec_vid71_4b.S --deleted file mode 100644 --index 505c79e..0000000 ----- a/libgcc/config/nds32/isr-library/vec_vid71_4b.S --+++ /dev/null --@@ -1,34 +0,0 @@ ---/* c-isr library stuff of Andes NDS32 cpu for GNU compiler --- Copyright (C) 2012-2016 Free Software Foundation, Inc. --- Contributed by Andes Technology Corporation. --- --- This file is part of GCC. --- --- GCC is free software; you can redistribute it and/or modify it --- under the terms of the GNU General Public License as published --- by the Free Software Foundation; either version 3, or (at your --- option) any later version. --- --- GCC is distributed in the hope that it will be useful, but WITHOUT --- ANY WARRANTY; without even the implied warranty of MERCHANTABILITY --- or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public --- License for more details. --- --- Under Section 7 of GPL version 3, you are granted additional --- permissions described in the GCC Runtime Library Exception, version --- 3.1, as published by the Free Software Foundation. --- --- You should have received a copy of the GNU General Public License and --- a copy of the GCC Runtime Library Exception along with this program; --- see the files COPYING3 and COPYING.RUNTIME respectively. If not, see --- . */ --- --- .section .nds32_vector.71, "ax" --- .vec_size 4 --- .align 2 --- .weak _nds32_vector_71_4b --- .type _nds32_vector_71_4b, @function ---_nds32_vector_71_4b: ---1: --- j 1b --- .size _nds32_vector_71_4b, .-_nds32_vector_71_4b --diff --git a/libgcc/config/nds32/isr-library/vec_vid72.S b/libgcc/config/nds32/isr-library/vec_vid72.S --index 08652d2..32984a0 100644 ----- a/libgcc/config/nds32/isr-library/vec_vid72.S --+++ b/libgcc/config/nds32/isr-library/vec_vid72.S --@@ -24,8 +24,15 @@ -- . */ -- -- .section .nds32_vector.72, "ax" --+#if __NDS32_ISR_VECTOR_SIZE_4__ --+ /* The vector size is default 4-byte for v3 architecture. */ --+ .vec_size 4 --+ .align 2 --+#else --+ /* The vector size is default 16-byte for other architectures. */ -- .vec_size 16 -- .align 4 --+#endif -- .weak _nds32_vector_72 -- .type _nds32_vector_72, @function -- _nds32_vector_72: --diff --git a/libgcc/config/nds32/isr-library/vec_vid72_4b.S b/libgcc/config/nds32/isr-library/vec_vid72_4b.S --deleted file mode 100644 --index 1083c03..0000000 ----- a/libgcc/config/nds32/isr-library/vec_vid72_4b.S --+++ /dev/null --@@ -1,34 +0,0 @@ ---/* c-isr library stuff of Andes NDS32 cpu for GNU compiler --- Copyright (C) 2012-2016 Free Software Foundation, Inc. --- Contributed by Andes Technology Corporation. --- --- This file is part of GCC. --- --- GCC is free software; you can redistribute it and/or modify it --- under the terms of the GNU General Public License as published --- by the Free Software Foundation; either version 3, or (at your --- option) any later version. --- --- GCC is distributed in the hope that it will be useful, but WITHOUT --- ANY WARRANTY; without even the implied warranty of MERCHANTABILITY --- or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public --- License for more details. --- --- Under Section 7 of GPL version 3, you are granted additional --- permissions described in the GCC Runtime Library Exception, version --- 3.1, as published by the Free Software Foundation. --- --- You should have received a copy of the GNU General Public License and --- a copy of the GCC Runtime Library Exception along with this program; --- see the files COPYING3 and COPYING.RUNTIME respectively. If not, see --- . */ --- --- .section .nds32_vector.72, "ax" --- .vec_size 4 --- .align 2 --- .weak _nds32_vector_72_4b --- .type _nds32_vector_72_4b, @function ---_nds32_vector_72_4b: ---1: --- j 1b --- .size _nds32_vector_72_4b, .-_nds32_vector_72_4b --diff --git a/libgcc/config/nds32/lib1asmsrc-mculib.S b/libgcc/config/nds32/lib1asmsrc-mculib.S --deleted file mode 100644 --index bdbcd74..0000000 ----- a/libgcc/config/nds32/lib1asmsrc-mculib.S --+++ /dev/null --@@ -1,5213 +0,0 @@ ---/* mculib libgcc routines of Andes NDS32 cpu for GNU compiler --- Copyright (C) 2012-2016 Free Software Foundation, Inc. --- Contributed by Andes Technology Corporation. --- --- This file is part of GCC. --- --- GCC is free software; you can redistribute it and/or modify it --- under the terms of the GNU General Public License as published --- by the Free Software Foundation; either version 3, or (at your --- option) any later version. --- --- GCC is distributed in the hope that it will be useful, but WITHOUT --- ANY WARRANTY; without even the implied warranty of MERCHANTABILITY --- or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public --- License for more details. --- --- Under Section 7 of GPL version 3, you are granted additional --- permissions described in the GCC Runtime Library Exception, version --- 3.1, as published by the Free Software Foundation. --- --- You should have received a copy of the GNU General Public License and --- a copy of the GCC Runtime Library Exception along with this program; --- see the files COPYING3 and COPYING.RUNTIME respectively. If not, see --- . */ --- --- .section .mdebug.abi_nds32 --- .previous --- --- ---/* ------------------------------------------- */ ---/* FPBIT floating point operations for libgcc */ ---/* ------------------------------------------- */ --- ---#ifdef L_addsub_sf --- --- .text --- .align 2 --- .global __subsf3 --- .type __subsf3, @function ---__subsf3: --- push $lp --- pushm $r6, $r9 --- --- move $r2, #0x80000000 --- xor $r1, $r1, $r2 --- --- j .Lsfpadd --- --- .global __addsf3 --- .type __addsf3, @function ---__addsf3: --- push $lp --- pushm $r6, $r9 ---.Lsfpadd: --- srli $r5, $r0, #23 --- andi $r5, $r5, #0xff --- srli $r7, $r1, #23 --- andi $r7, $r7, #0xff --- move $r3, #0x80000000 --- slli $r4, $r0, #8 --- or $r4, $r4, $r3 --- slli $r6, $r1, #8 --- or $r6, $r6, $r3 --- --- addi $r9, $r5, #-1 --- slti $r15, $r9, #0xfe --- beqzs8 .LEspecA --- ---.LElab1: --- addi $r9, $r7, #-1 --- slti $r15, $r9, #0xfe --- beqzs8 .LEspecB --- ---.LElab2: --- sub $r8, $r5, $r7 --- sltsi $r15, $r8, #0 --- bnezs8 .Li1 --- sltsi $r15, $r8, #0x20 --- bnezs8 .Li2 --- move $r6, #2 --- j .Le1 ---.Li2: --- move $r2, $r6 --- srl $r6, $r6, $r8 --- sll $r9, $r6, $r8 --- beq $r9, $r2, .Le1 --- ori $r6, $r6, #2 --- j .Le1 ---.Li1: --- move $r5, $r7 --- subri $r8, $r8, #0 --- sltsi $r15, $r8, #0x20 --- bnezs8 .Li4 --- move $r4, #2 --- j .Le1 ---.Li4: --- move $r2, $r4 --- srl $r4, $r4, $r8 --- sll $r9, $r4, $r8 --- beq $r9, $r2, .Le1 --- ori $r4, $r4, #2 --- ---.Le1: --- and $r8, $r0, $r3 --- xor $r9, $r8, $r1 --- sltsi $r15, $r9, #0 --- bnezs8 .LEsub1 --- --- #ADD($r4, $r6) --- add $r4, $r4, $r6 --- slt $r15, $r4, $r6 --- beqzs8 .LEres --- andi $r9, $r4, #1 --- beqz $r9, .Li7 --- ori $r4, $r4, #2 ---.Li7: --- srli $r4, $r4, #1 --- addi $r5, $r5, #1 --- subri $r15, $r5, #0xff --- bnezs8 .LEres --- move $r4, #0 --- j .LEres --- ---.LEsub1: --- #SUB($r4, $r6) --- move $r15, $r4 --- sub $r4, $r4, $r6 --- slt $r15, $r15, $r4 --- beqzs8 .Li9 --- subri $r4, $r4, #0 --- xor $r8, $r8, $r3 --- j .Le9 ---.Li9: --- beqz $r4, .LEzer ---.Le9: ---#ifdef __NDS32_PERF_EXT__ --- clz $r2, $r4 ---#else --- pushm $r0, $r1 --- pushm $r3, $r5 --- move $r0, $r4 --- bal __clzsi2 --- move $r2, $r0 --- popm $r3, $r5 --- popm $r0, $r1 ---#endif --- sub $r5, $r5, $r2 --- sll $r4, $r4, $r2 --- ---.LEres: --- blez $r5, .LEund --- ---.LElab12: --- #ADD($r4, $0x80) --- move $r15, #0x80 --- add $r4, $r4, $r15 --- slt $r15, $r4, $r15 --- --- #ADDC($r5, $0x0) --- add $r5, $r5, $r15 --- srli $r9, $r4, #8 --- andi $r9, $r9, #1 --- sub $r4, $r4, $r9 --- slli $r4, $r4, #1 --- srli $r4, $r4, #9 --- slli $r9, $r5, #23 --- or $r4, $r4, $r9 --- or $r0, $r4, $r8 --- ---.LE999: --- popm $r6, $r9 --- pop $lp --- ret5 $lp --- ---.LEund: --- subri $r2, $r5, #1 --- slti $r15, $r2, #0x20 --- beqzs8 .LEzer --- move $r9, #0x80000000 --- or $r4, $r4, $r9 --- subri $r9, $r2, #0x20 --- sll $r5, $r4, $r9 --- srl $r4, $r4, $r2 --- beqz $r5, .Li10 --- ori $r4, $r4, #1 ---.Li10: --- move $r5, #0 --- addi $r9, $r4, #0x80 --- sltsi $r15, $r9, #0 --- beqzs8 .LElab12 --- move $r5, #1 --- j .LElab12 --- ---.LEspecA: --- bnez $r5, .Li12 --- add $r4, $r4, $r4 --- beqz $r4, .Li13 ---#ifdef __NDS32_PERF_EXT__ --- clz $r8, $r4 ---#else --- pushm $r0, $r5 --- move $r0, $r4 --- bal __clzsi2 --- move $r8, $r0 --- popm $r0, $r5 ---#endif --- sub $r5, $r5, $r8 --- sll $r4, $r4, $r8 --- j .LElab1 ---.Li13: --- subri $r15, $r7, #0xff --- beqzs8 .LEspecB --- move $r9, #0x80000000 --- bne $r1, $r9, .LEretB ---.Li12: --- add $r9, $r4, $r4 --- bnez $r9, .LEnan --- subri $r15, $r7, #0xff --- bnezs8 .LEretA --- xor $r9, $r0, $r1 --- sltsi $r15, $r9, #0 --- bnezs8 .LEnan --- j .LEretB --- ---.LEspecB: --- bnez $r7, .Li15 --- add $r6, $r6, $r6 --- beqz $r6, .LEretA ---#ifdef __NDS32_PERF_EXT__ --- clz $r8, $r6 ---#else --- pushm $r0, $r5 --- move $r0, $r6 --- bal __clzsi2 --- move $r8, $r0 --- popm $r0, $r5 ---#endif --- sub $r7, $r7, $r8 --- sll $r6, $r6, $r8 --- j .LElab2 ---.Li15: --- add $r9, $r6, $r6 --- bnez $r9, .LEnan --- ---.LEretB: --- move $r0, $r1 --- j .LE999 --- ---.LEretA: --- j .LE999 --- ---.LEzer: --- move $r0, #0 --- j .LE999 --- ---.LEnan: --- move $r0, #0xffc00000 --- j .LE999 --- .size __subsf3, .-__subsf3 --- .size __addsf3, .-__addsf3 ---#endif /* L_addsub_sf */ --- --- --- ---#ifdef L_sf_to_si --- --- .text --- .align 2 --- .global __fixsfsi --- .type __fixsfsi, @function ---__fixsfsi: --- push $lp --- --- slli $r1, $r0, #8 --- move $r3, #0x80000000 --- or $r1, $r1, $r3 --- srli $r3, $r0, #23 --- andi $r3, $r3, #0xff --- subri $r2, $r3, #0x9e --- blez $r2, .LJspec --- sltsi $r15, $r2, #0x20 --- bnezs8 .Li42 --- move $r0, #0 --- j .LJ999 ---.Li42: --- srl $r1, $r1, $r2 --- sltsi $r15, $r0, #0 --- beqzs8 .Li43 --- subri $r1, $r1, #0 ---.Li43: --- move $r0, $r1 --- ---.LJ999: --- pop $lp --- ret5 $lp --- ---.LJspec: --- move $r3, #0x7f800000 --- slt $r15, $r3, $r0 --- beqzs8 .Li44 --- move $r0, #0x80000000 --- j .LJ999 ---.Li44: --- move $r0, #0x7fffffff --- j .LJ999 --- .size __fixsfsi, .-__fixsfsi ---#endif /* L_sf_to_si */ --- --- --- ---#ifdef L_divsi3 --- --- .text --- .align 2 --- .globl __divsi3 --- .type __divsi3, @function ---__divsi3: --- ! --------------------------------------------------------------------- --- ! neg = 0; --- ! if (a < 0) --- ! { a = -a; --- ! neg = !neg; --- ! } --- ! --------------------------------------------------------------------- --- sltsi $r5, $r0, 0 ! $r5 <- neg = (a < 0) ? 1 : 0 --- subri $r4, $r0, 0 ! $r4 <- a = -a --- cmovn $r0, $r4, $r5 ! $r0 <- a = neg ? -a : a ---.L2: --- ! --------------------------------------------------------------------- --- ! if (b < 0) --- ! --------------------------------------------------------------------- --- bgez $r1, .L3 ! if b >= 0, skip --- ! --------------------------------------------------------------------- --- ! { b=-b; --- ! neg=!neg; --- ! } --- ! --------------------------------------------------------------------- --- subri $r1, $r1, 0 ! $r1 <- b = -b --- subri $r5, $r5, 1 ! $r5 <- neg = !neg ---.L3: --- ! --------------------------------------------------------------------- --- !!res = udivmodsi4 (a, b, 1); --- ! res = 0; --- ! if (den != 0) --- ! --------------------------------------------------------------------- --- movi $r2, 0 ! $r2 <- res = 0 --- beqz $r1, .L1 ! if den == 0, skip --- ! --------------------------------------------------------------------- --- ! bit = 1; --- ! --------------------------------------------------------------------- --- movi $r4, 1 ! $r4 <- bit = 1 ---#ifndef __OPTIMIZE_SIZE__ ---.L6: ---#endif --- ! --------------------------------------------------------------------- --- ! while (den < num && bit && !(den & (1L << 31))) --- ! --------------------------------------------------------------------- --- slt $ta, $r1, $r0 ! $ta <- den < num ? --- beqz $ta, .L5 ! if no, skip --- ! --------------------------------------------------------------------- --- ! { den << = 1; --- ! bit << = 1; --- ! } --- ! --------------------------------------------------------------------- ---#if defined (__OPTIMIZE_SIZE__) && !defined (__NDS32_ISA_V3M__) --- clz $r3, $r1 ! $r3 <- leading zero count for den --- clz $ta, $r0 ! $ta <- leading zero count for num --- sub $r3, $r3, $ta ! $r3 <- number of bits to shift --- sll $r1, $r1, $r3 ! $r1 <- den --- sll $r4, $r4, $r3 ! $r2 <- bit ---#else --- slli $r1, $r1, 1 ! $r1 <- den << = 1 --- slli $r4, $r4, 1 ! $r4 <- bit << = 1 --- b .L6 ! continue loop ---#endif ---.L5: --- ! --------------------------------------------------------------------- --- ! while (bit) --- ! { if (num >= den) --- ! --------------------------------------------------------------------- --- slt $ta, $r0, $r1 ! $ta <- num < den ? --- bnez $ta, .L9 ! if yes, skip --- ! --------------------------------------------------------------------- --- ! { num -= den; --- ! res |= bit; --- ! } --- ! --------------------------------------------------------------------- --- sub $r0, $r0, $r1 ! $r0 <- num -= den --- or $r2, $r2, $r4 ! $r2 <- res |= bit ---.L9: --- ! --------------------------------------------------------------------- --- ! bit >> = 1; --- ! den >> = 1; --- ! } --- !!if (modwanted) --- !! return num; --- !!return res; --- ! --------------------------------------------------------------------- --- srli $r4, $r4, 1 ! $r4 <- bit >> = 1 --- srli $r1, $r1, 1 ! $r1 <- den >> = 1 --- bnez $r4, .L5 ! if bit != 0, continue loop ---.L1: --- ! --------------------------------------------------------------------- --- ! if (neg) --- ! res = -res; --- ! return res; --- ! --------------------------------------------------------------------- --- subri $r0, $r2, 0 ! $r0 <- -res --- cmovz $r0, $r2, $r5 ! $r0 <- neg ? -res : res --- ! --------------------------------------------------------------------- --- ret --- .size __divsi3, .-__divsi3 ---#endif /* L_divsi3 */ --- --- --- ---#ifdef L_divdi3 --- --- !-------------------------------------- --- #ifdef __big_endian__ --- #define V1H $r0 --- #define V1L $r1 --- #define V2H $r2 --- #define V2L $r3 --- #else --- #define V1H $r1 --- #define V1L $r0 --- #define V2H $r3 --- #define V2L $r2 --- #endif --- !-------------------------------------- --- .text --- .align 2 --- .globl __divdi3 --- .type __divdi3, @function ---__divdi3: --- ! prologue ---#ifdef __NDS32_ISA_V3M__ --- push25 $r10, 0 ---#else --- smw.adm $r6, [$sp], $r10, 2 ---#endif --- ! end of prologue --- move $r8, V1L --- move $r9, V1H --- move $r6, V2L --- move $r7, V2H --- movi $r10, 0 --- bgez V1H, .L80 --- bal __negdi2 --- move $r8, V1L --- move $r9, V1H --- movi $r10, -1 ---.L80: --- bgez $r7, .L81 --- move V1L, $r6 --- move V1H, $r7 --- bal __negdi2 --- move $r6, V1L --- move $r7, V1H --- nor $r10, $r10, $r10 ---.L81: --- move V2L, $r6 --- move V2H, $r7 --- move V1L, $r8 --- move V1H, $r9 --- movi $r4, 0 --- bal __udivmoddi4 --- beqz $r10, .L82 --- bal __negdi2 ---.L82: --- ! epilogue ---#ifdef __NDS32_ISA_V3M__ --- pop25 $r10, 0 ---#else --- lmw.bim $r6, [$sp], $r10, 2 --- ret ---#endif --- .size __divdi3, .-__divdi3 ---#endif /* L_divdi3 */ --- --- --- ---#ifdef L_modsi3 --- --- .text --- .align 2 --- .globl __modsi3 --- .type __modsi3, @function ---__modsi3: --- ! --------------------------------------------------------------------- --- ! neg=0; --- ! if (a<0) --- ! { a=-a; --- ! neg=1; --- ! } --- ! --------------------------------------------------------------------- --- sltsi $r5, $r0, 0 ! $r5 <- neg < 0 ? 1 : 0 --- subri $r4, $r0, 0 ! $r4 <- -a --- cmovn $r0, $r4, $r5 ! $r0 <- |a| --- ! --------------------------------------------------------------------- --- ! if (b < 0) ---#ifndef __NDS32_PERF_EXT__ --- ! --------------------------------------------------------------------- --- bgez $r1, .L3 ! if b >= 0, skip --- ! --------------------------------------------------------------------- --- ! b = -b; --- ! --------------------------------------------------------------------- --- subri $r1, $r1, 0 ! $r1 <- |b| ---.L3: --- ! --------------------------------------------------------------------- --- !!res = udivmodsi4 (a, b, 1); --- ! if (den != 0) --- ! --------------------------------------------------------------------- ---#else /* __NDS32_PERF_EXT__ */ --- ! b = -b; --- !!res = udivmodsi4 (a, b, 1); --- ! if (den != 0) --- ! --------------------------------------------------------------------- --- abs $r1, $r1 ! $r1 <- |b| ---#endif /* __NDS32_PERF_EXT__ */ --- beqz $r1, .L1 ! if den == 0, skip --- ! --------------------------------------------------------------------- --- ! { bit = 1; --- ! res = 0; --- ! --------------------------------------------------------------------- --- movi $r4, 1 ! $r4 <- bit = 1 ---#ifndef __OPTIMIZE_SIZE__ ---.L6: ---#endif --- ! --------------------------------------------------------------------- --- ! while (den < num&&bit && !(den & (1L << 31))) --- ! --------------------------------------------------------------------- --- slt $ta, $r1, $r0 ! $ta <- den < num ? --- beqz $ta, .L5 ! if no, skip --- ! --------------------------------------------------------------------- --- ! { den << = 1; --- ! bit << = 1; --- ! } --- ! --------------------------------------------------------------------- ---#if defined (__OPTIMIZE_SIZE__) && ! defined (__NDS32_ISA_V3M__) --- clz $r3, $r1 ! $r3 <- leading zero count for den --- clz $ta, $r0 ! $ta <- leading zero count for num --- sub $r3, $r3, $ta ! $r3 <- number of bits to shift --- sll $r1, $r1, $r3 ! $r1 <- den --- sll $r4, $r4, $r3 ! $r2 <- bit ---#else --- slli $r1, $r1, 1 ! $r1 <- den << = 1 --- slli $r4, $r4, 1 ! $r4 <- bit << = 1 --- b .L6 ! continue loop ---#endif ---.L5: --- ! --------------------------------------------------------------------- --- ! while (bit) --- ! { if (num >= den) --- ! { num -= den; --- ! res |= bit; --- ! } --- ! bit >> = 1; --- ! den >> = 1; --- ! } --- ! } --- !!if (modwanted) --- !! return num; --- !!return res; --- ! --------------------------------------------------------------------- --- sub $r2, $r0, $r1 ! $r2 <- num - den --- slt $ta, $r0, $r1 ! $ta <- num < den ? --- srli $r4, $r4, 1 ! $r4 <- bit >> = 1 --- cmovz $r0, $r2, $ta ! $r0 <- num = (num < den) ? num : num - den --- srli $r1, $r1, 1 ! $r1 <- den >> = 1 --- bnez $r4, .L5 ! if bit != 0, continue loop ---.L1: --- ! --------------------------------------------------------------------- --- ! if (neg) --- ! res = -res; --- ! return res; --- ! --------------------------------------------------------------------- --- subri $r3, $r0, 0 ! $r3 <- -res --- cmovn $r0, $r3, $r5 ! $r0 <- neg ? -res : res --- ! --------------------------------------------------------------------- --- ret --- .size __modsi3, .-__modsi3 ---#endif /* L_modsi3 */ --- --- --- ---#ifdef L_moddi3 --- --- !-------------------------------------- --- #ifdef __big_endian__ --- #define V1H $r0 --- #define V1L $r1 --- #define V2H $r2 --- #define V2L $r3 --- #else --- #define V1H $r1 --- #define V1L $r0 --- #define V2H $r3 --- #define V2L $r2 --- #endif --- !-------------------------------------- --- .text --- .align 2 --- .globl __moddi3 --- .type __moddi3, @function ---__moddi3: --- ! ===================================================================== --- ! stack allocation: --- ! sp+32 +-----------------------+ --- ! | $lp | --- ! sp+28 +-----------------------+ --- ! | $r6 - $r10 | --- ! sp+8 +-----------------------+ --- ! | | --- ! sp+4 +-----------------------+ --- ! | | --- ! sp +-----------------------+ --- ! ===================================================================== --- ! prologue ---#ifdef __NDS32_ISA_V3M__ --- push25 $r10, 8 ---#else --- smw.adm $r6, [$sp], $r10, 2 --- addi $sp, $sp, -8 ---#endif --- ! end of prologue --- !------------------------------------------ --- ! __moddi3 (DWtype u, DWtype v) --- ! { --- ! word_type c = 0; --- ! DWunion uu = {.ll = u}; --- ! DWunion vv = {.ll = v}; --- ! DWtype w; --- ! if (uu.s.high < 0) --- ! c = ~c, --- ! uu.ll = -uu.ll; --- !--------------------------------------------- --- move $r8, V1L --- move $r9, V1H --- move $r6, V2L --- move $r7, V2H --- movi $r10, 0 ! r10 = c = 0 --- bgez V1H, .L80 ! if u > 0 , go L80 --- bal __negdi2 --- move $r8, V1L --- move $r9, V1H --- movi $r10, -1 ! r10 = c = ~c --- !------------------------------------------------ --- ! if (vv.s.high < 0) --- ! vv.ll = -vv.ll; --- !---------------------------------------------- ---.L80: --- bgez $r7, .L81 ! if v > 0 , go L81 --- move V1L, $r6 --- move V1H, $r7 --- bal __negdi2 --- move $r6, V1L --- move $r7, V1H --- !------------------------------------------ --- ! (void) __udivmoddi4 (uu.ll, vv.ll, &w); --- ! if (c) --- ! w = -w; --- ! return w; --- !----------------------------------------- ---.L81: --- move V2L, $r6 --- move V2H, $r7 --- move V1L, $r8 --- move V1H, $r9 --- addi $r4, $sp, 0 --- bal __udivmoddi4 --- lwi $r0, [$sp+(0)] ! le: sp + 0 is low, be: sp + 0 is high --- lwi $r1, [$sp+(4)] ! le: sp + 4 is low, be: sp + 4 is high --- beqz $r10, .L82 --- bal __negdi2 ---.L82: --- ! epilogue ---#ifdef __NDS32_ISA_V3M__ --- pop25 $r10, 8 ---#else --- addi $sp, $sp, 8 --- lmw.bim $r6, [$sp], $r10, 2 --- ret ---#endif --- .size __moddi3, .-__moddi3 ---#endif /* L_moddi3 */ --- --- --- ---#ifdef L_mulsi3 --- --- .text --- .align 2 --- .globl __mulsi3 --- .type __mulsi3, @function ---__mulsi3: --- ! --------------------------------------------------------------------- --- ! r = 0; --- ! while (a) --- ! $r0: r --- ! $r1: b --- ! $r2: a --- ! --------------------------------------------------------------------- --- beqz $r0, .L7 ! if a == 0, done --- move $r2, $r0 ! $r2 <- a --- movi $r0, 0 ! $r0 <- r <- 0 ---.L8: --- ! --------------------------------------------------------------------- --- ! { if (a & 1) --- ! r += b; --- ! a >> = 1; --- ! b << = 1; --- ! } --- ! $r0: r --- ! $r1: b --- ! $r2: a --- ! $r3: scratch --- ! $r4: scratch --- ! --------------------------------------------------------------------- --- andi $r3, $r2, 1 ! $r3 <- a & 1 --- add $r4, $r0, $r1 ! $r4 <- r += b --- cmovn $r0, $r4, $r3 ! $r0 <- r --- srli $r2, $r2, 1 ! $r2 <- a >> = 1 --- slli $r1, $r1, 1 ! $r1 <- b << = 1 --- bnez $r2, .L8 ! if a != 0, continue loop ---.L7: --- ! --------------------------------------------------------------------- --- ! $r0: return code --- ! --------------------------------------------------------------------- --- ret --- .size __mulsi3, .-__mulsi3 ---#endif /* L_mulsi3 */ --- --- --- ---#ifdef L_udivsi3 --- --- .text --- .align 2 --- .globl __udivsi3 --- .type __udivsi3, @function ---__udivsi3: --- ! --------------------------------------------------------------------- --- !!res=udivmodsi4(a,b,0); --- ! res=0; --- ! if (den!=0) --- ! --------------------------------------------------------------------- --- movi $r2, 0 ! $r2 <- res=0 --- beqz $r1, .L1 ! if den==0, skip --- ! --------------------------------------------------------------------- --- ! { bit=1; --- ! --------------------------------------------------------------------- --- movi $r4, 1 ! $r4 <- bit=1 ---#ifndef __OPTIMIZE_SIZE__ ---.L6: ---#endif --- ! --------------------------------------------------------------------- --- ! while (den=den) --- ! --------------------------------------------------------------------- --- slt $ta, $r0, $r1 ! $ta <- num>=1; --- ! den>>=1; --- ! } --- ! } --- !!if (modwanted) --- !! return num; --- !!return res; --- ! --------------------------------------------------------------------- --- srli $r4, $r4, 1 ! $r4 <- bit>>=1 --- srli $r1, $r1, 1 ! $r1 <- den>>=1 --- bnez $r4, .L5 ! if bit!=0, continue loop ---.L1: --- ! --------------------------------------------------------------------- --- ! return res; --- ! --------------------------------------------------------------------- --- move $r0, $r2 ! $r0 <- return value --- ! --------------------------------------------------------------------- --- ! --------------------------------------------------------------------- --- ret --- .size __udivsi3, .-__udivsi3 ---#endif /* L_udivsi3 */ --- --- --- ---#ifdef L_udivdi3 --- --- !-------------------------------------- --- #ifdef __big_endian__ --- #define V1H $r0 --- #define V1L $r1 --- #define V2H $r2 --- #define V2L $r3 --- #else --- #define V1H $r1 --- #define V1L $r0 --- #define V2H $r3 --- #define V2L $r2 --- #endif --- !-------------------------------------- --- --- .text --- .align 2 --- .globl __udivdi3 --- .type __udivdi3, @function ---__udivdi3: --- ! prologue ---#ifdef __NDS32_ISA_V3M__ --- push25 $r8, 0 ---#else --- smw.adm $r6, [$sp], $r8, 2 ---#endif --- ! end of prologue --- movi $r4, 0 --- bal __udivmoddi4 --- ! epilogue ---#ifdef __NDS32_ISA_V3M__ --- pop25 $r8, 0 ---#else --- lmw.bim $r6, [$sp], $r8, 2 --- ret ---#endif --- .size __udivdi3, .-__udivdi3 ---#endif /* L_udivdi3 */ --- --- --- ---#ifdef L_udivmoddi4 --- --- .text --- .align 2 --- .globl fudiv_qrnnd --- .type fudiv_qrnnd, @function --- #ifdef __big_endian__ --- #define P1H $r0 --- #define P1L $r1 --- #define P2H $r2 --- #define P2L $r3 --- #define W6H $r4 --- #define W6L $r5 --- #define OFFSET_L 4 --- #define OFFSET_H 0 --- #else --- #define P1H $r1 --- #define P1L $r0 --- #define P2H $r3 --- #define P2L $r2 --- #define W6H $r5 --- #define W6L $r4 --- #define OFFSET_L 0 --- #define OFFSET_H 4 --- #endif ---fudiv_qrnnd: --- !------------------------------------------------------ --- ! function: fudiv_qrnnd(quotient, remainder, high_numerator, low_numerator, denominator) --- ! divides a UDWtype, composed by the UWtype integers,HIGH_NUMERATOR (from $r4) --- ! and LOW_NUMERATOR(from $r5) by DENOMINATOR(from $r6), and places the quotient --- ! in $r7 and the remainder in $r8. --- !------------------------------------------------------ --- ! in reg:$r4(n1), $r5(n0), $r6(d0) --- ! __d1 = ((USItype) (d) >> ((4 * 8) / 2)); --- ! __d0 = ((USItype) (d) & (((USItype) 1 << ((4 * 8) / 2)) - 1)); --- ! __r1 = (n1) % __d1; --- ! __q1 = (n1) / __d1; --- ! __m = (USItype) __q1 * __d0; --- ! __r1 = __r1 * ((USItype) 1 << ((4 * 8) / 2)) | ((USItype) (n0) >> ((4 * 8) / 2)); --- ! if (__r1 < __m) --- ! { --- !------------------------------------------------------ --- smw.adm $r0, [$sp], $r4, 2 ! store $lp, when use BASELINE_V1,and must store $r0-$r3 --- srli $r7, $r6, 16 ! $r7 = d1 =__ll_highpart (d) --- movi $ta, 65535 --- and $r8, $r6, $ta ! $r8 = d0 = __ll_lowpart (d) --- --- divr $r9, $r10, $r4, $r7 ! $r9 = q1, $r10 = r1 --- and $r4, $r5, $ta ! $r4 = __ll_lowpart (n0) --- slli $r10, $r10, 16 ! $r10 = r1 << 16 --- srli $ta, $r5, 16 ! $ta = __ll_highpart (n0) --- --- or $r10, $r10, $ta ! $r10 <- $r0|$r3=__r1 --- mul $r5, $r9, $r8 ! $r5 = m = __q1*__d0 --- slt $ta, $r10, $r5 ! $ta <- __r1<__m --- beqz $ta, .L2 !if yes,skip --- !------------------------------------------------------ --- ! __q1--, __r1 += (d); --- ! if (__r1 >= (d)) --- ! { --- !------------------------------------------------------ --- --- add $r10, $r10, $r6 !$r10 <- __r1+d=__r1 --- addi $r9, $r9, -1 !$r9 <- __q1--=__q1 --- slt $ta, $r10, $r6 !$ta <- __r1= (d)) --- ! { --- !------------------------------------------------------ --- --- add $r10, $r10, $r6 !$r10 <- __r0+d=__r0 --- addi $r7, $r7, -1 !$r7 <- __q0--=__q0 --- slt $ta, $r10, $r6 !$ta <- __r0 n1) --- ! { --- !------------------------------------------------------ --- --- slt $ta, P1H, P2L !$ta <- n1> ((4 * 8) - bm)); --- ! n0 = n0 << bm; --- ! } --- !------------------------------------------------------ --- --- subri $r5, $r7, 32 !$r5 <- 32-bm --- srl $r5, P1L, $r5 !$r5 <- n0>>$r5 --- sll $r6, P1H, $r7 !$r6 <- n1< n1) --- !------------------------------------------------------ --- --- move $r4,P1H ! give fudiv_qrnnd args --- move $r5,P1L ! --- move $r6,P2L ! --- bal fudiv_qrnnd !calcaulte q0 n0 --- movi $r6, 0 !P1L <- 0 --- swi $r7,[$sp+32] !q0 --- swi $r6,[$sp+36] !q1 --- move P1L,$r8 !n0 --- b .L19 ---.L10: --- !------------------------------------------------------ --- ! else #if (d0 > n1) --- ! { --- ! if(d0 == 0) --- !------------------------------------------------------ --- --- bnez P2L, .L20 !if yes,skip --- !------------------------------------------------------ --- ! d0 = 1 / d0; --- !------------------------------------------------------ --- --- movi $r4, 1 !P1L <- 1 --- divr P2L, $r4, $r4, P2L !$r9=1/d0,P1L=1%d0 ---.L20: --- ---#ifndef __NDS32_PERF_EXT__ --- smw.adm $r0, [$sp], $r5, 0 --- move $r0, P2L --- bal __clzsi2 --- move $r7, $r0 --- lmw.bim $r0, [$sp], $r5, 0 ---#else --- clz $r7, P2L ---#endif --- swi $r7,[$sp+(28)] ! store bm --- beqz $r7, .L28 ! if yes,skip --- !------------------------------------------------------ --- ! b = (4 * 8) - bm; --- ! d0 = d0 << bm; --- ! n2 = n1 >> b; --- ! n1 = (n1 << bm) | (n0 >> b); --- ! n0 = n0 << bm; --- ! fudiv_qrnnd (&q1, &n1, n2, n1, d0); --- ! } --- !------------------------------------------------------ --- --- subri $r10, $r7, 32 !$r10 <- 32-bm=b --- srl $r4, P1L, $r10 !$r4 <- n0>>b --- sll $r5, P1H, $r7 !$r5 <- n1<>b=n2 !for fun --- --- move $r6,P2L !for fun --- bal fudiv_qrnnd !caculate q1, n1 --- --- swi $r7,[$sp+(36)] ! q1 store --- move P1H,$r8 ! n1 store --- --- move $r4,$r8 ! prepare for next fudiv_qrnnd() --- move $r5,P1L --- move $r6,P2L --- b .L29 ---.L28: --- !------------------------------------------------------ --- ! else // bm != 0 --- ! { --- ! n1 -= d0; --- ! q1 = 1; --- ! --- !------------------------------------------------------ --- --- sub P1H, P1H, P2L !P1L <- n1-d0=n1 --- movi $ta, 1 ! --- swi $ta, [$sp+(36)] !1 -> [$sp+(36)] --- --- move $r4,P1H ! give fudiv_qrnnd args --- move $r5,P1L --- move $r6,P2L ---.L29: --- !------------------------------------------------------ --- ! fudiv_qrnnd (&q0, &n0, n1, n0, d0); --- !------------------------------------------------------ --- --- bal fudiv_qrnnd !calcuate q0, n0 --- swi $r7,[$sp+(32)] !q0 store --- move P1L,$r8 !n0 ---.L19: --- !------------------------------------------------------ --- ! if (rp != 0) --- ! { --- !------------------------------------------------------ --- --- beqz $fp, .L31 !if yes,skip --- !------------------------------------------------------ --- ! rr.s.low = n0 >> bm; --- ! rr.s.high = 0; --- ! *rp = rr.ll; --- ! } --- !------------------------------------------------------ --- --- movi $r5, 0 !$r5 <- 0 --- lwi $r7,[$sp+(28)] !load bm --- srl $r4, P1L, $r7 !$r4 <- n0>>bm --- swi $r4, [$fp+OFFSET_L] !r0 !$r4 -> [$sp+(48)] --- swi $r5, [$fp+OFFSET_H] !r1 !0 -> [$sp+(52)] --- b .L31 ---.L9: --- !------------------------------------------------------ --- ! else # d1 == 0 --- ! { --- ! if(d1 > n1) --- ! { --- !------------------------------------------------------ --- --- slt $ta, P1H, P2H !$ta <- n1 [$sp+(40)]=q1 --- swi $r5, [$sp+(36)] !q1 !0 -> [$sp+(32)]=q0 --- beqz $fp, .L31 !if yes,skip --- !------------------------------------------------------ --- ! rr.s.low = n0; --- ! rr.s.high = n1; --- ! *rp = rr.ll; --- ! } --- !------------------------------------------------------ --- --- swi P1L, [$fp+OFFSET_L] !P1L -> [rp] --- swi P1H, [$fp+OFFSET_H] !P1H -> [rp+4] --- b .L31 ---.L32: ---#ifndef __NDS32_PERF_EXT__ --- smw.adm $r0, [$sp], $r5, 0 --- move $r0, P2H --- bal __clzsi2 --- move $r7, $r0 --- lmw.bim $r0, [$sp], $r5, 0 ---#else --- clz $r7,P2H ---#endif --- swi $r7,[$sp+(28)] !$r7=bm store --- beqz $r7, .L42 !if yes,skip --- !------------------------------------------------------ --- ! USItype m1, m0; --- ! b = (4 * 8) - bm; --- ! d1 = (d0 >> b) | (d1 << bm); --- ! d0 = d0 << bm; --- ! n2 = n1 >> b; --- ! n1 = (n0 >> b) | (n1 << bm); --- ! n0 = n0 << bm; --- ! fudiv_qrnnd (&q0, &n1, n2, n1, d1); --- !------------------------------------------------------ --- --- subri $r10, $r7, 32 !$r10 <- 32-bm=b --- srl $r5, P2L, $r10 !$r5 <- d0>>b --- sll $r6, P2H, $r7 !$r6 <- d1<>b=n2 !!! func --- srl $r8, P1L, $r10 !$r8 <- n0>>b !!$r8 --- sll $r9, P1H, $r7 !$r9 <- n1<> ((4 * 8) / 2)); --- ! __vl = ((USItype) (d0) & (((USItype) 1 << ((4 * 8) / 2)) - 1)); --- ! __vh = ((USItype) (d0) >> ((4 * 8) / 2)); --- ! __x0 = (USItype) __ul * __vl; --- ! __x1 = (USItype) __ul * __vh; --- ! __x2 = (USItype) __uh * __vl; --- ! __x3 = (USItype) __uh * __vh; --- ! __x1 += ((USItype) (__x0) >> ((4 * 8) / 2)); --- ! __x1 += __x2; --- ! if (__x1 < __x2) --- ! __x3 += ((USItype) 1 << ((4 * 8) / 2)); --- ! (m1) = __x3 + ((USItype) (__x1) >> ((4 * 8) / 2)); --- ! (m0) = (USItype)(q0*d0); --- ! } --- ! if (m1 > n1) --- !--------------------------------------------------- ---#ifdef __NDS32_ISA_V3M__ --- !mulr64 $r4, P2L, $r6 --- smw.adm $r0, [$sp], $r3, 0 --- move P1L, P2L --- move P2L, $r6 --- movi P1H, 0 --- movi P2H, 0 --- bal __muldi3 --- movd44 $r4, $r0 --- lmw.bim $r0, [$sp], $r3, 0 --- move $r8, W6H --- move $r5, W6L ---#else --- mulr64 $r4, P2L, $r6 --- move $r8, W6H --- move $r5, W6L ---#endif --- slt $ta, P1H, $r8 !$ta <- n1 n0) --- !------------------------------------------------------ --- --- slt $ta, P1L, $r5 !$ta <- n0 (m0)); --- ! (m0) = __x; --- ! } --- ! } --- !------------------------------------------------------ --- --- sub $r4, $r5, P2L !$r4 <- m0-d0=__x --- addi $r6, $r6, -1 !$r6 <- q0--=q0 --- sub $r8, $r8, P2H !$r8 <- m1-d1 --- swi $r6, [$sp+(32)] ! q0 !$r6->[$sp+(32)] --- slt $ta, $r5, $r4 !$ta <- m0<__x --- sub $r8, $r8, $ta !$r8 <- P1H-P1L=m1 --- move $r5, $r4 !$r5 <- __x=m0 ---.L45: --- !------------------------------------------------------ --- ! q1 = 0; --- ! if (rp != 0) --- ! { --- !------------------------------------------------------ --- --- movi $r4, 0 !$r4 <- 0 --- swi $r4, [$sp+(36)] !0 -> [$sp+(40)]=q1 --- beqz $fp, .L31 !if yes,skip --- !------------------------------------------------------ --- ! # sub_ddmmss (n1, n0, n1, n0, m1, m0); --- ! do --- ! { USItype __x; --- ! __x = (n0) - (m0); --- ! (n1) = (n1) - (m1) - (__x > (n0)); --- ! (n0) = __x; --- ! } --- ! rr.s.low = (n1 << b) | (n0 >> bm); --- ! rr.s.high = n1 >> bm; --- ! *rp = rr.ll; --- !------------------------------------------------------ --- --- sub $r4, P1H, $r8 !$r4 <- n1-m1 --- sub $r6, P1L, $r5 !$r6 <- n0-m0=__x=n0 --- slt $ta, P1L, $r6 !$ta <- n0<__x --- sub P1H, $r4, $ta !P1H <- $r4-$ta=n1 --- move P1L, $r6 --- --- lwi $r7,[$sp+(28)] ! load bm --- subri $r10,$r7,32 --- sll $r4, P1H, $r10 !$r4 <- n1<>bm --- or $r6, $r5, $r4 !$r6 <- $r5|$r4=rr.s.low --- srl $r8, P1H, $r7 !$r8 <- n1>>bm =rr.s.high --- swi $r6, [$fp+OFFSET_L] ! --- swi $r8, [$fp+OFFSET_H] ! --- b .L31 ---.L42: --- !------------------------------------------------------ --- ! else --- ! { --- ! if(n1 > d1) --- !------------------------------------------------------ --- --- slt $ta, P2H, P1H !$ta <- P2H= d0) --- !------------------------------------------------------ --- --- slt $ta, P1L, P2L !$ta <- P1L (n0)); --- ! (n0) = __x; --- ! } --- !------------------------------------------------------ ---.L52: --- sub $r4, P1H, P2H !$r4 <- P1H-P2H --- sub $r6, P1L, P2L !$r6 <- no-d0=__x=n0 --- slt $ta, P1L, $r6 !$ta <- no<__x --- sub P1H, $r4, $ta !P1H <- $r4-$ta=n1 --- move P1L, $r6 !n0 --- movi $r5, 1 ! --- swi $r5, [$sp+(32)] !1 -> [$sp+(32)]=q0 --- b .L54 ---.L51: --- !------------------------------------------------------ --- ! q0 = 0; --- !------------------------------------------------------ --- --- movi $r5,0 --- swi $r5, [$sp+(32)] !$r5=0 -> [$sp+(32)] ---.L54: --- !------------------------------------------------------ --- ! q1 = 0; --- ! if (rp != 0) --- ! { --- !------------------------------------------------------ --- --- movi $r5, 0 ! --- swi $r5, [$sp+(36)] !0 -> [$sp+(36)] --- beqz $fp, .L31 --- !------------------------------------------------------ --- ! rr.s.low = n0; --- ! rr.s.high = n1; --- ! *rp = rr.ll; --- ! } --- !------------------------------------------------------ --- --- swi P1L, [$fp+OFFSET_L] !remainder --- swi P1H, [$fp+OFFSET_H] ! ---.L31: --- !------------------------------------------------------ --- ! const DWunion ww = {{.low = q0, .high = q1}}; --- ! return ww.ll; --- !} --- !------------------------------------------------------ --- --- lwi P1L, [$sp+(32)] !quotient --- lwi P1H, [$sp+(36)] --- lmw.bim $r6, [$sp], $r10, 10 --- addi $sp, $sp, 12 --- ret --- .size __udivmoddi4, .-__udivmoddi4 ---#endif /* L_udivmoddi4 */ --- --- --- ---#ifdef L_umodsi3 --- --- ! ===================================================================== --- .text --- .align 2 --- .globl __umodsi3 --- .type __umodsi3, @function ---__umodsi3: --- ! --------------------------------------------------------------------- --- !!res=udivmodsi4(a,b,1); --- ! if (den==0) --- ! return num; --- ! --------------------------------------------------------------------- --- beqz $r1, .L1 ! if den==0, skip --- ! --------------------------------------------------------------------- --- ! bit=1; --- ! res=0; --- ! --------------------------------------------------------------------- --- movi $r4, 1 ! $r4 <- bit=1 ---#ifndef __OPTIMIZE_SIZE__ ---.L6: ---#endif --- ! --------------------------------------------------------------------- --- ! while (den=den) --- ! { num-=den; --- ! res|=bit; --- ! } --- ! bit>>=1; --- ! den>>=1; --- ! } --- !!if (modwanted) --- !! return num; --- !!return res; --- ! --------------------------------------------------------------------- --- sub $r2, $r0, $r1 ! $r2 <- num-den --- slt $ta, $r0, $r1 ! $ta <- num>=1 --- cmovz $r0, $r2, $ta ! $r0 <- num=(num>=1 --- bnez $r4, .L5 ! if bit!=0, continue loop ---.L1: --- ! --------------------------------------------------------------------- --- ! return res; --- ! --------------------------------------------------------------------- --- ret --- .size __umodsi3, .-__umodsi3 ---#endif /* L_umodsi3 */ --- --- --- ---#ifdef L_umoddi3 --- --- !-------------------------------------- --- #ifdef __big_endian__ --- #define V1H $r0 --- #define V1L $r1 --- #define V2H $r2 --- #define V2L $r3 --- #else --- #define V1H $r1 --- #define V1L $r0 --- #define V2H $r3 --- #define V2L $r2 --- #endif --- !-------------------------------------- --- .text --- .align 2 --- .globl __umoddi3 --- .type __umoddi3, @function ---__umoddi3: --- ! prologue --- addi $sp, $sp, -12 --- swi $lp, [$sp+(0)] --- ! end of prologue --- addi $r4, $sp, 4 --- bal __udivmoddi4 --- lwi $r0, [$sp+(4)] ! __udivmoddi4 return low when LE mode or return high when BE mode --- lwi $r1, [$sp+(8)] ! ---.L82: --- ! epilogue --- lwi $lp, [$sp+(0)] --- addi $sp, $sp, 12 --- ret --- .size __umoddi3, .-__umoddi3 ---#endif /* L_umoddi3 */ --- --- --- ---#ifdef L_muldi3 --- ---#ifdef __big_endian__ --- #define P1H $r0 --- #define P1L $r1 --- #define P2H $r2 --- #define P2L $r3 --- --- #define V2H $r4 --- #define V2L $r5 ---#else --- #define P1H $r1 --- #define P1L $r0 --- #define P2H $r3 --- #define P2L $r2 --- --- #define V2H $r5 --- #define V2L $r4 ---#endif --- --- ! ==================================================================== --- .text --- .align 2 --- .globl __muldi3 --- .type __muldi3, @function ---__muldi3: --- ! parameter passing for libgcc functions normally involves 2 doubles --- !--------------------------------------- ---#ifdef __NDS32_ISA_V3M__ --- ! There is no mulr64 instruction in Andes ISA V3M. --- ! So we must provide a sequence of calculations to complete the job. --- smw.adm $r6, [$sp], $r9, 0x0 --- zeh33 $r4, P1L --- srli $r7, P1L, 16 --- zeh33 $r5, P2L --- mul $r6, $r5, $r4 --- mul33 $r5, $r7 --- srli $r8, P2L, 16 --- mov55 $r9, $r5 --- maddr32 $r9, $r8, $r4 --- srli $r4, $r6, 16 --- add $r4, $r9, $r4 --- slt45 $r4, $r5 --- slli $r5, $r15, 16 --- maddr32 $r5, $r8, $r7 --- mul P2L, P1H, P2L --- srli $r7, $r4, 16 --- maddr32 P2L, P2H, P1L --- add333 P1H, $r5, $r7 --- slli $r4, $r4, 16 --- zeh33 $r6, $r6 --- add333 P1L, $r4, $r6 --- add333 P1H, P2L, P1H --- lmw.bim $r6, [$sp], $r9, 0x0 --- ret ---#else /* not __NDS32_ISA_V3M__ */ --- mul $ta, P1L, P2H --- mulr64 $r4, P1L, P2L --- maddr32 $ta, P1H, P2L --- move P1L, V2L --- add P1H, $ta, V2H --- ret ---#endif /* not __NDS32_ISA_V3M__ */ --- .size __muldi3, .-__muldi3 ---#endif /* L_muldi3 */ --- --- --- ---#ifdef L_addsub_df --- ---#ifndef __big_endian__ --- #define P1L $r0 --- #define P1H $r1 --- #define P2L $r2 --- #define P2H $r3 --- #define P3L $r4 --- #define P3H $r5 --- #define O1L $r7 --- #define O1H $r8 ---#else --- #define P1H $r0 --- #define P1L $r1 --- #define P2H $r2 --- #define P2L $r3 --- #define P3H $r4 --- #define P3L $r5 --- #define O1H $r7 --- #define O1L $r8 ---#endif --- .text --- .align 2 --- .global __subdf3 --- .type __subdf3, @function ---__subdf3: --- push $lp --- pushm $r6, $r10 --- --- move $r4, #0x80000000 --- xor P2H, P2H, $r4 --- --- j .Lsdpadd --- --- .global __adddf3 --- .type __adddf3, @function ---__adddf3: --- push $lp --- pushm $r6, $r10 ---.Lsdpadd: --- slli $r6, P1H, #1 --- srli $r6, $r6, #21 --- slli P3H, P1H, #11 --- srli $r10, P1L, #21 --- or P3H, P3H, $r10 --- slli P3L, P1L, #11 --- move O1L, #0x80000000 --- or P3H, P3H, O1L --- slli $r9, P2H, #1 --- srli $r9, $r9, #21 --- slli O1H, P2H, #11 --- srli $r10, P2L, #21 --- or O1H, O1H, $r10 --- or O1H, O1H, O1L --- slli O1L, P2L, #11 --- --- addi $r10, $r6, #-1 --- slti $r15, $r10, #0x7fe --- beqzs8 .LEspecA --- ---.LElab1: --- addi $r10, $r9, #-1 --- slti $r15, $r10, #0x7fe --- beqzs8 .LEspecB --- ---.LElab2: --- #NORMd($r4, P2L, P1L) --- bnez P3H, .LL1 --- bnez P3L, .LL2 --- move $r6, #0 --- j .LL3 ---.LL2: --- move P3H, P3L --- move P3L, #0 --- move P2L, #32 --- sub $r6, $r6, P2L ---.LL1: ---#ifndef __big_endian__ ---#ifdef __NDS32_PERF_EXT__ --- clz $r2, $r5 ---#else --- pushm $r0, $r1 --- pushm $r3, $r5 --- move $r0, $r5 --- bal __clzsi2 --- move $r2, $r0 --- popm $r3, $r5 --- popm $r0, $r1 ---#endif ---#else /* __big_endian__ */ ---#ifdef __NDS32_PERF_EXT__ --- clz $r3, $r4 ---#else --- pushm $r0, $r2 --- pushm $r4, $r5 --- move $r0, $r4 --- bal __clzsi2 --- move $r3, $r0 --- popm $r4, $r5 --- popm $r0, $r2 ---#endif ---#endif /* __big_endian__ */ --- beqz P2L, .LL3 --- sub $r6, $r6, P2L --- subri P1L, P2L, #32 --- srl P1L, P3L, P1L --- sll P3L, P3L, P2L --- sll P3H, P3H, P2L --- or P3H, P3H, P1L ---.LL3: --- #NORMd End --- --- #NORMd($r7, P2L, P1L) --- bnez O1H, .LL4 --- bnez O1L, .LL5 --- move $r9, #0 --- j .LL6 ---.LL5: --- move O1H, O1L --- move O1L, #0 --- move P2L, #32 --- sub $r9, $r9, P2L ---.LL4: ---#ifndef __big_endian__ ---#ifdef __NDS32_PERF_EXT__ --- clz $r2, O1H ---#else --- pushm $r0, $r1 --- pushm $r3, $r5 --- move $r0, O1H --- bal __clzsi2 --- move $r2, $r0 --- popm $r3, $r5 --- popm $r0, $r1 ---#endif ---#else /* __big_endian__ */ ---#ifdef __NDS32_PERF_EXT__ --- clz $r3, O1H ---#else --- pushm $r0, $r2 --- pushm $r4, $r5 --- move $r0, O1H --- bal __clzsi2 --- move $r3, $r0 --- popm $r4, $r5 --- popm $r0, $r2 ---#endif ---#endif /* __big_endian__ */ --- beqz P2L, .LL6 --- sub $r9, $r9, P2L --- subri P1L, P2L, #32 --- srl P1L, O1L, P1L --- sll O1L, O1L, P2L --- sll O1H, O1H, P2L --- or O1H, O1H, P1L ---.LL6: --- #NORMd End --- --- move $r10, #0x80000000 --- and P1H, P1H, $r10 --- --- beq $r6, $r9, .LEadd3 --- slts $r15, $r9, $r6 --- beqzs8 .Li1 --- sub $r9, $r6, $r9 --- move P2L, #0 ---.LL7: --- move $r10, #0x20 --- slt $r15, $r9, $r10 --- bnezs8 .LL8 --- or P2L, P2L, O1L --- move O1L, O1H --- move O1H, #0 --- addi $r9, $r9, #0xffffffe0 --- bnez O1L, .LL7 ---.LL8: --- beqz $r9, .LEadd3 --- move P1L, O1H --- move $r10, O1L --- srl O1L, O1L, $r9 --- srl O1H, O1H, $r9 --- subri $r9, $r9, #0x20 --- sll P1L, P1L, $r9 --- or O1L, O1L, P1L --- sll $r10, $r10, $r9 --- or P2L, P2L, $r10 --- beqz P2L, .LEadd3 --- ori O1L, O1L, #1 --- j .LEadd3 ---.Li1: --- move $r15, $r6 --- move $r6, $r9 --- sub $r9, $r9, $r15 --- move P2L, #0 ---.LL10: --- move $r10, #0x20 --- slt $r15, $r9, $r10 --- bnezs8 .LL11 --- or P2L, P2L, P3L --- move P3L, P3H --- move P3H, #0 --- addi $r9, $r9, #0xffffffe0 --- bnez P3L, .LL10 ---.LL11: --- beqz $r9, .LEadd3 --- move P1L, P3H --- move $r10, P3L --- srl P3L, P3L, $r9 --- srl P3H, P3H, $r9 --- subri $r9, $r9, #0x20 --- sll P1L, P1L, $r9 --- or P3L, P3L, P1L --- sll $r10, $r10, $r9 --- or P2L, P2L, $r10 --- beqz P2L, .LEadd3 --- ori P3L, P3L, #1 --- ---.LEadd3: --- xor $r10, P1H, P2H --- sltsi $r15, $r10, #0 --- bnezs8 .LEsub1 --- --- #ADD(P3L, O1L) --- add P3L, P3L, O1L --- slt $r15, P3L, O1L --- --- #ADDCC(P3H, O1H) --- beqzs8 .LL13 --- add P3H, P3H, O1H --- slt $r15, P3H, O1H --- beqzs8 .LL14 --- addi P3H, P3H, #0x1 --- j .LL15 ---.LL14: --- move $r15, #1 --- add P3H, P3H, $r15 --- slt $r15, P3H, $r15 --- j .LL15 ---.LL13: --- add P3H, P3H, O1H --- slt $r15, P3H, O1H ---.LL15: --- --- beqzs8 .LEres --- andi $r10, P3L, #1 --- beqz $r10, .Li3 --- ori P3L, P3L, #2 ---.Li3: --- srli P3L, P3L, #1 --- slli $r10, P3H, #31 --- or P3L, P3L, $r10 --- srli P3H, P3H, #1 --- move $r10, #0x80000000 --- or P3H, P3H, $r10 --- addi $r6, $r6, #1 --- subri $r15, $r6, #0x7ff --- bnezs8 .LEres --- move $r10, #0x7ff00000 --- or P1H, P1H, $r10 --- move P1L, #0 --- j .LEretA --- ---.LEsub1: --- #SUB(P3L, O1L) --- move $r15, P3L --- sub P3L, P3L, O1L --- slt $r15, $r15, P3L --- --- #SUBCC(P3H, O1H) --- beqzs8 .LL16 --- move $r15, P3H --- sub P3H, P3H, O1H --- slt $r15, $r15, P3H --- beqzs8 .LL17 --- subi333 P3H, P3H, #1 --- j .LL18 ---.LL17: --- move $r15, P3H --- subi333 P3H, P3H, #1 --- slt $r15, $r15, P3H --- j .LL18 ---.LL16: --- move $r15, P3H --- sub P3H, P3H, O1H --- slt $r15, $r15, P3H ---.LL18: --- --- beqzs8 .Li5 --- move $r10, #0x80000000 --- xor P1H, P1H, $r10 --- --- subri P3H, P3H, #0 --- beqz P3L, .LL19 --- subri P3L, P3L, #0 --- subi45 P3H, #1 ---.LL19: --- ---.Li5: --- #NORMd($r4, $r9, P1L) --- bnez P3H, .LL20 --- bnez P3L, .LL21 --- move $r6, #0 --- j .LL22 ---.LL21: --- move P3H, P3L --- move P3L, #0 --- move $r9, #32 --- sub $r6, $r6, $r9 ---.LL20: ---#ifdef __NDS32_PERF_EXT__ --- clz $r9, P3H ---#else --- pushm $r0, $r5 --- move $r0, P3H --- bal __clzsi2 --- move $r9, $r0 --- popm $r0, $r5 ---#endif --- beqz $r9, .LL22 --- sub $r6, $r6, $r9 --- subri P1L, $r9, #32 --- srl P1L, P3L, P1L --- sll P3L, P3L, $r9 --- sll P3H, P3H, $r9 --- or P3H, P3H, P1L ---.LL22: --- #NORMd End --- --- or $r10, P3H, P3L --- bnez $r10, .LEres --- move P1H, #0 --- ---.LEres: --- blez $r6, .LEund --- ---.LElab8: --- #ADD(P3L, $0x400) --- move $r15, #0x400 --- add P3L, P3L, $r15 --- slt $r15, P3L, $r15 --- --- #ADDCC(P3H, $0x0) --- beqzs8 .LL25 --- add P3H, P3H, $r15 --- slt $r15, P3H, $r15 ---.LL25: --- --- #ADDC($r6, $0x0) --- add $r6, $r6, $r15 --- srli $r10, P3L, #11 --- andi $r10, $r10, #1 --- sub P3L, P3L, $r10 --- srli P1L, P3L, #11 --- slli $r10, P3H, #21 --- or P1L, P1L, $r10 --- slli $r10, P3H, #1 --- srli $r10, $r10, #12 --- or P1H, P1H, $r10 --- slli $r10, $r6, #20 --- or P1H, P1H, $r10 --- ---.LEretA: ---.LE999: --- popm $r6, $r10 --- pop $lp --- ret5 $lp --- ---.LEspecA: --- #ADD(P3L, P3L) --- move $r15, P3L --- add P3L, P3L, P3L --- slt $r15, P3L, $r15 --- --- #ADDC(P3H, P3H) --- add P3H, P3H, P3H --- add P3H, P3H, $r15 --- bnez $r6, .Li7 --- or $r10, P3H, P3L --- beqz $r10, .Li8 --- j .LElab1 ---.Li8: --- subri $r15, $r9, #0x7ff --- beqzs8 .LEspecB --- add P3L, P2H, P2H --- or $r10, P3L, P2L --- bnez $r10, .LEretB --- sltsi $r15, P2H, #0 --- bnezs8 .LEretA --- ---.LEretB: --- move P1L, P2L --- move P1H, P2H --- j .LE999 ---.Li7: --- or $r10, P3H, P3L --- bnez $r10, .LEnan --- subri $r15, $r9, #0x7ff --- bnezs8 .LEretA --- xor $r10, P1H, P2H --- sltsi $r15, $r10, #0 --- bnezs8 .LEnan --- j .LEretB --- ---.LEspecB: --- #ADD(O1L, O1L) --- move $r15, O1L --- add O1L, O1L, O1L --- slt $r15, O1L, $r15 --- --- #ADDC(O1H, O1H) --- add O1H, O1H, O1H --- add O1H, O1H, $r15 --- bnez $r9, .Li11 --- or $r10, O1H, O1L --- beqz $r10, .LEretA --- j .LElab2 ---.Li11: --- or $r10, O1H, O1L --- beqz $r10, .LEretB --- ---.LEnan: --- move P1H, #0xfff80000 --- move P1L, #0 --- j .LEretA --- ---.LEund: --- subri $r9, $r6, #1 --- move P2L, #0 ---.LL26: --- move $r10, #0x20 --- slt $r15, $r9, $r10 --- bnezs8 .LL27 --- or P2L, P2L, P3L --- move P3L, P3H --- move P3H, #0 --- addi $r9, $r9, #0xffffffe0 --- bnez P3L, .LL26 ---.LL27: --- beqz $r9, .LL28 --- move P1L, P3H --- move $r10, P3L --- srl P3L, P3L, $r9 --- srl P3H, P3H, $r9 --- subri $r9, $r9, #0x20 --- sll P1L, P1L, $r9 --- or P3L, P3L, P1L --- sll $r10, $r10, $r9 --- or P2L, P2L, $r10 --- beqz P2L, .LL28 --- ori P3L, P3L, #1 ---.LL28: --- move $r6, #0 --- j .LElab8 --- .size __subdf3, .-__subdf3 --- .size __adddf3, .-__adddf3 ---#endif /* L_addsub_df */ --- --- --- ---#ifdef L_mul_sf --- ---#if !defined (__big_endian__) --- #define P1L $r0 --- #define P1H $r1 --- #define P2L $r2 --- #define P2H $r3 ---#else --- #define P1H $r0 --- #define P1L $r1 --- #define P2H $r2 --- #define P2L $r3 ---#endif --- .text --- .align 2 --- .global __mulsf3 --- .type __mulsf3, @function ---__mulsf3: --- push $lp --- pushm $r6, $r10 --- --- srli $r3, $r0, #23 --- andi $r3, $r3, #0xff --- srli $r5, $r1, #23 --- andi $r5, $r5, #0xff --- move $r6, #0x80000000 --- slli $r2, $r0, #8 --- or $r2, $r2, $r6 --- slli $r4, $r1, #8 --- or $r4, $r4, $r6 --- xor $r8, $r0, $r1 --- and $r6, $r6, $r8 --- --- addi $r8, $r3, #-1 --- slti $r15, $r8, #0xfe --- beqzs8 .LFspecA --- ---.LFlab1: --- addi $r8, $r5, #-1 --- slti $r15, $r8, #0xfe --- beqzs8 .LFspecB --- ---.LFlab2: --- move $r10, $r3 ---/* This is a 64-bit multiple. ($r2, $r7) is (high, low). */ ---#ifndef __NDS32_ISA_V3M__ --- mulr64 $r2, $r2, $r4 ---#else --- pushm $r0, $r1 --- pushm $r4, $r5 --- move P1L, $r2 --- movi P1H, #0 --- move P2L, $r4 --- movi P2H, #0 --- bal __muldi3 --- movd44 $r2, $r0 --- popm $r4, $r5 --- popm $r0, $r1 ---#endif ---#ifndef __big_endian__ --- move $r7, $r2 --- move $r2, $r3 ---#else --- move $r7, $r3 ---#endif --- move $r3, $r10 --- --- beqz $r7, .Li17 --- ori $r2, $r2, #1 --- ---.Li17: --- sltsi $r15, $r2, #0 --- bnezs8 .Li18 --- slli $r2, $r2, #1 --- addi $r3, $r3, #-1 ---.Li18: --- addi $r8, $r5, #0xffffff82 --- add $r3, $r3, $r8 --- addi $r8, $r3, #-1 --- slti $r15, $r8, #0xfe --- beqzs8 .LFoveund --- ---.LFlab8: --- #ADD($r2, $0x80) --- move $r15, #0x80 --- add $r2, $r2, $r15 --- slt $r15, $r2, $r15 --- --- #ADDC($r3, $0x0) --- add $r3, $r3, $r15 --- srli $r8, $r2, #8 --- andi $r8, $r8, #1 --- sub $r2, $r2, $r8 --- slli $r2, $r2, #1 --- srli $r2, $r2, #9 --- slli $r8, $r3, #23 --- or $r2, $r2, $r8 --- or $r0, $r2, $r6 --- ---.LF999: --- popm $r6, $r10 --- pop $lp --- ret5 $lp --- ---.LFspecA: --- bnez $r3, .Li19 --- add $r2, $r2, $r2 --- beqz $r2, .Li20 ---#ifdef __NDS32_PERF_EXT__ --- clz $r7, $r2 ---#else --- pushm $r0, $r5 --- move $r0, $r2 --- bal __clzsi2 --- move $r7, $r0 --- popm $r0, $r5 ---#endif --- sub $r3, $r3, $r7 --- sll $r2, $r2, $r7 --- j .LFlab1 ---.Li20: --- subri $r15, $r5, #0xff --- beqzs8 .LFnan --- j .LFzer ---.Li19: --- add $r8, $r2, $r2 --- bnez $r8, .LFnan --- bnez $r5, .Li21 --- add $r8, $r4, $r4 --- beqz $r8, .LFnan ---.Li21: --- subri $r15, $r5, #0xff --- bnezs8 .LFinf --- ---.LFspecB: --- bnez $r5, .Li22 --- add $r4, $r4, $r4 --- beqz $r4, .LFzer ---#ifdef __NDS32_PERF_EXT__ --- clz $r7, $r4 ---#else --- pushm $r0, $r5 --- move $r0, $r4 --- bal __clzsi2 --- move $r7, $r0 --- popm $r0, $r5 ---#endif --- sub $r5, $r5, $r7 --- sll $r4, $r4, $r7 --- j .LFlab2 --- ---.LFzer: --- move $r0, $r6 --- j .LF999 ---.Li22: --- add $r8, $r4, $r4 --- bnez $r8, .LFnan --- ---.LFinf: --- move $r8, #0x7f800000 --- or $r0, $r6, $r8 --- j .LF999 --- ---.LFnan: --- move $r0, #0xffc00000 --- j .LF999 --- ---.LFoveund: --- bgtz $r3, .LFinf --- subri $r7, $r3, #1 --- slti $r15, $r7, #0x20 --- beqzs8 .LFzer --- subri $r8, $r7, #0x20 --- sll $r3, $r2, $r8 --- srl $r2, $r2, $r7 --- beqz $r3, .Li25 --- ori $r2, $r2, #2 ---.Li25: --- move $r3, #0 --- addi $r8, $r2, #0x80 --- sltsi $r15, $r8, #0 --- beqzs8 .LFlab8 --- move $r3, #1 --- j .LFlab8 --- .size __mulsf3, .-__mulsf3 ---#endif /* L_mul_sf */ --- --- --- ---#ifdef L_mul_df --- ---#ifndef __big_endian__ --- #define P1L $r0 --- #define P1H $r1 --- #define P2L $r2 --- #define P2H $r3 --- #define P3L $r4 --- #define P3H $r5 --- #define O1L $r7 --- #define O1H $r8 ---#else --- #define P1H $r0 --- #define P1L $r1 --- #define P2H $r2 --- #define P2L $r3 --- #define P3H $r4 --- #define P3L $r5 --- #define O1H $r7 --- #define O1L $r8 ---#endif --- .text --- .align 2 --- .global __muldf3 --- .type __muldf3, @function ---__muldf3: --- push $lp --- pushm $r6, $r10 --- --- slli $r6, P1H, #1 --- srli $r6, $r6, #21 --- slli P3H, P1H, #11 --- srli $r10, P1L, #21 --- or P3H, P3H, $r10 --- slli P3L, P1L, #11 --- move O1L, #0x80000000 --- or P3H, P3H, O1L --- slli $r9, P2H, #1 --- srli $r9, $r9, #21 --- slli O1H, P2H, #11 --- srli $r10, P2L, #21 --- or O1H, O1H, $r10 --- or O1H, O1H, O1L --- xor P1H, P1H, P2H --- and P1H, P1H, O1L --- slli O1L, P2L, #11 --- --- addi $r10, $r6, #-1 --- slti $r15, $r10, #0x7fe --- beqzs8 .LFspecA --- ---.LFlab1: --- addi $r10, $r9, #-1 --- slti $r15, $r10, #0x7fe --- beqzs8 .LFspecB --- ---.LFlab2: --- addi $r10, $r9, #0xfffffc02 --- add $r6, $r6, $r10 --- --- move $r10, $r8 ---/* This is a 64-bit multiple. */ ---#ifndef __big_endian__ ---/* For little endian: ($r9, $r3) is (high, low). */ ---#ifndef __NDS32_ISA_V3M__ --- mulr64 $r8, $r5, $r8 ---#else --- pushm $r0, $r5 --- move $r0, $r5 --- movi $r1, #0 --- move $r2, $r8 --- movi $r3, #0 --- bal __muldi3 --- movd44 $r8, $r0 --- popm $r0, $r5 ---#endif --- move $r3, $r8 ---#else /* __big_endian__ */ ---/* For big endain: ($r9, $r2) is (high, low). */ ---#ifndef __NDS32_ISA_V3M__ --- mulr64 $r8, $r4, $r7 ---#else --- pushm $r0, $r5 --- move $r1, $r4 --- movi $r0, #0 --- move $r3, $r7 --- movi $r2, #0 --- bal __muldi3 --- movd44 $r8, $r0 --- popm $r0, $r5 ---#endif --- move $r2, $r9 --- move $r9, $r8 ---#endif /* __big_endian__ */ --- move $r8, $r10 --- --- move $r10, P1H ---/* This is a 64-bit multiple. */ ---#ifndef __big_endian__ ---/* For little endian: ($r0, $r2) is (high, low). */ ---#ifndef __NDS32_ISA_V3M__ --- mulr64 $r0, $r4, $r8 ---#else --- pushm $r2, $r5 --- move $r0, $r4 --- movi $r1, #0 --- move $r2, $r8 --- movi $r3, #0 --- bal __muldi3 --- popm $r2, $r5 ---#endif --- move $r2, $r0 --- move $r0, $r1 ---#else /* __big_endian__ */ ---/* For big endain: ($r1, $r3) is (high, low). */ ---#ifndef __NDS32_ISA_V3M__ --- mulr64 $r0, $r5, $r7 ---#else --- pushm $r2, $r5 --- move $r1, $r5 --- movi $r0, #0 --- move $r3, $r7 --- movi $r2, #0 --- bal __muldi3 --- popm $r2, $r5 ---#endif --- move $r3, $r1 --- move $r1, $r0 ---#endif /* __big_endian__ */ --- move P1H, $r10 --- --- #ADD(P2H, P1L) --- add P2H, P2H, P1L --- slt $r15, P2H, P1L --- --- #ADDC($r9, $0x0) --- add $r9, $r9, $r15 --- --- move $r10, P1H ---/* This is a 64-bit multiple. */ ---#ifndef __big_endian__ ---/* For little endian: ($r0, $r8) is (high, low). */ ---#ifndef __NDS32_ISA_V3M__ --- mulr64 $r0, $r5, $r7 ---#else --- pushm $r2, $r5 --- move $r0, $r5 --- movi $r1, #0 --- move $r2, $r7 --- movi $r3, #0 --- bal __muldi3 --- popm $r2, $r5 ---#endif --- move $r8, $r0 --- move $r0, $r1 ---#else /* __big_endian__ */ ---/* For big endian: ($r1, $r7) is (high, low). */ ---#ifndef __NDS32_ISA_V3M__ --- mulr64 $r0, $r4, $r8 ---#else --- pushm $r2, $r5 --- move $r1, $r4 --- movi $r0, #0 --- move $r3, $r8 --- movi $r2, #0 --- bal __muldi3 --- popm $r2, $r5 ---#endif --- move $r7, $r1 --- move $r1, $r0 ---#endif /* __big_endian__ */ --- move P1H, $r10 --- --- #ADD(P2L, O1H) --- add P2L, P2L, O1H --- slt $r15, P2L, O1H --- --- --- #ADDCC(P2H, P1L) --- beqzs8 .LL29 --- add P2H, P2H, P1L --- slt $r15, P2H, P1L --- beqzs8 .LL30 --- addi P2H, P2H, #0x1 --- j .LL31 ---.LL30: --- move $r15, #1 --- add P2H, P2H, $r15 --- slt $r15, P2H, $r15 --- j .LL31 ---.LL29: --- add P2H, P2H, P1L --- slt $r15, P2H, P1L ---.LL31: --- --- #ADDC($r9, $0x0) --- add $r9, $r9, $r15 --- ---/* This is a 64-bit multiple. */ ---#ifndef __big_endian__ ---/* For little endian: ($r8, $r0) is (high, low). */ --- move $r10, $r9 ---#ifndef __NDS32_ISA_V3M__ --- mulr64 $r8, $r4, $r7 ---#else --- pushm $r0, $r5 --- move $r0, $r4 --- movi $r1, #0 --- move $r2, $r7 --- movi $r3, #0 --- bal __muldi3 --- movd44 $r8, $r0 --- popm $r0, $r5 ---#endif --- move $r0, $r8 --- move $r8, $r9 --- move $r9, $r10 ---#else /* __big_endian__ */ ---/* For big endian: ($r7, $r1) is (high, low). */ --- move $r10, $r6 ---#ifndef __NDS32_ISA_V3M__ --- mulr64 $r6, $r5, $r8 ---#else --- pushm $r0, $r5 --- move $r1, $r5 --- movi $r0, #0 --- move $r3, $r8 --- movi $r2, #0 --- bal __muldi3 --- movd44 $r6, $r0 --- popm $r0, $r5 ---#endif --- move $r1, $r7 --- move $r7, $r6 --- move $r6, $r10 ---#endif /* __big_endian__ */ --- --- #ADD(P2L, O1H) --- add P2L, P2L, O1H --- slt $r15, P2L, O1H --- --- --- #ADDCC(P2H, $0x0) --- beqzs8 .LL34 --- add P2H, P2H, $r15 --- slt $r15, P2H, $r15 ---.LL34: --- --- #ADDC($r9, $0x0) --- add $r9, $r9, $r15 --- or $r10, P1L, P2L --- beqz $r10, .Li13 --- ori P2H, P2H, #1 ---.Li13: --- move P3H, $r9 --- move P3L, P2H --- sltsi $r15, P3H, #0 --- bnezs8 .Li14 --- --- move $r15, P3L --- add P3L, P3L, P3L --- slt $r15, P3L, $r15 --- add P3H, P3H, P3H --- add P3H, P3H, $r15 --- addi $r6, $r6, #-1 ---.Li14: --- addi $r10, $r6, #-1 --- slti $r15, $r10, #0x7fe --- beqzs8 .LFoveund --- --- #ADD(P3L, $0x400) --- move $r15, #0x400 --- add P3L, P3L, $r15 --- slt $r15, P3L, $r15 --- --- --- #ADDCC(P3H, $0x0) --- beqzs8 .LL37 --- add P3H, P3H, $r15 --- slt $r15, P3H, $r15 ---.LL37: --- --- #ADDC($r6, $0x0) --- add $r6, $r6, $r15 --- ---.LFlab8: --- srli $r10, P3L, #11 --- andi $r10, $r10, #1 --- sub P3L, P3L, $r10 --- srli P1L, P3L, #11 --- slli $r10, P3H, #21 --- or P1L, P1L, $r10 --- slli $r10, P3H, #1 --- srli $r10, $r10, #12 --- or P1H, P1H, $r10 --- slli $r10, $r6, #20 --- or P1H, P1H, $r10 --- ---.LFret: ---.LF999: --- popm $r6, $r10 --- pop $lp --- ret5 $lp --- ---.LFspecA: --- #ADD(P3L, P3L) --- move $r15, P3L --- add P3L, P3L, P3L --- slt $r15, P3L, $r15 --- --- #ADDC(P3H, P3H) --- add P3H, P3H, P3H --- add P3H, P3H, $r15 --- bnez $r6, .Li15 --- or $r10, P3H, P3L --- beqz $r10, .Li16 --- --- --- #NORMd($r4, P1L, P2H) --- bnez P3H, .LL38 --- bnez P3L, .LL39 --- move $r6, #0 --- j .LL40 ---.LL39: --- move P3H, P3L --- move P3L, #0 --- move P1L, #32 --- sub $r6, $r6, P1L ---.LL38: ---#ifndef __big_endian__ ---#ifdef __NDS32_PERF_EXT__ --- clz $r0, P3H ---#else --- pushm $r1, P3H --- move $r0, P3H --- bal __clzsi2 --- popm $r1, $r5 ---#endif ---#else /* __big_endian__ */ ---#ifdef __NDS32_PERF_EXT__ --- clz $r1, $r4 ---#else --- push $r0 --- pushm $r2, $r5 --- move $r0, $r4 --- bal __clzsi2 --- move $r1, $r0 --- popm $r2, $r5 --- pop $r0 ---#endif ---#endif /* __big_endian__ */ --- beqz P1L, .LL40 --- sub $r6, $r6, P1L --- subri P2H, P1L, #32 --- srl P2H, P3L, P2H --- sll P3L, P3L, P1L --- sll P3H, P3H, P1L --- or P3H, P3H, P2H ---.LL40: --- #NORMd End --- --- j .LFlab1 ---.Li16: --- subri $r15, $r9, #0x7ff --- beqzs8 .LFnan --- j .LFret ---.Li15: --- or $r10, P3H, P3L --- bnez $r10, .LFnan --- bnez $r9, .Li17 --- slli $r10, O1H, #1 --- or $r10, $r10, O1L --- beqz $r10, .LFnan ---.Li17: --- subri $r15, $r9, #0x7ff --- bnezs8 .LFinf --- ---.LFspecB: --- #ADD(O1L, O1L) --- move $r15, O1L --- add O1L, O1L, O1L --- slt $r15, O1L, $r15 --- --- #ADDC(O1H, O1H) --- add O1H, O1H, O1H --- add O1H, O1H, $r15 --- bnez $r9, .Li18 --- or $r10, O1H, O1L --- beqz $r10, .Li19 --- --- --- #NORMd($r7, P2L, P1L) --- bnez O1H, .LL41 --- bnez O1L, .LL42 --- move $r9, #0 --- j .LL43 ---.LL42: --- move O1H, O1L --- move O1L, #0 --- move P2L, #32 --- sub $r9, $r9, P2L ---.LL41: ---#ifndef __big_endian__ ---#ifdef __NDS32_PERF_EXT__ --- clz $r2, $r8 ---#else --- pushm $r0, $r1 --- pushm $r3, $r5 --- move $r0, $r8 --- bal __clzsi2 --- move $r2, $r0 --- popm $r3, $r5 --- popm $r0, $r1 ---#endif ---#else /* __big_endian__ */ ---#ifdef __NDS32_PERF_EXT__ --- clz $r3, $r7 ---#else --- pushm $r0, $r2 --- pushm $r4, $r5 --- move $r0, $r7 --- bal __clzsi2 --- move $r3, $r0 --- popm $r4, $r5 --- popm $r0, $r2 ---#endif ---#endif /* __big_endian__ */ --- beqz P2L, .LL43 --- sub $r9, $r9, P2L --- subri P1L, P2L, #32 --- srl P1L, O1L, P1L --- sll O1L, O1L, P2L --- sll O1H, O1H, P2L --- or O1H, O1H, P1L ---.LL43: --- #NORMd End --- --- j .LFlab2 ---.Li19: --- move P1L, #0 --- j .LFret ---.Li18: --- or $r10, O1H, O1L --- bnez $r10, .LFnan --- ---.LFinf: --- move $r10, #0x7ff00000 --- or P1H, P1H, $r10 --- move P1L, #0 --- j .LFret --- ---.LFnan: --- move P1H, #0xfff80000 --- move P1L, #0 --- j .LFret --- ---.LFoveund: --- bgtz $r6, .LFinf --- subri P1L, $r6, #1 --- move P2L, #0 ---.LL44: --- move $r10, #0x20 --- slt $r15, P1L, $r10 --- bnezs8 .LL45 --- or P2L, P2L, P3L --- move P3L, P3H --- move P3H, #0 --- addi P1L, P1L, #0xffffffe0 --- bnez P3L, .LL44 ---.LL45: --- beqz P1L, .LL46 --- move P2H, P3H --- move $r10, P3L --- srl P3L, P3L, P1L --- srl P3H, P3H, P1L --- subri P1L, P1L, #0x20 --- sll P2H, P2H, P1L --- or P3L, P3L, P2H --- sll $r10, $r10, P1L --- or P2L, P2L, $r10 --- beqz P2L, .LL46 --- ori P3L, P3L, #1 ---.LL46: --- #ADD(P3L, $0x400) --- move $r15, #0x400 --- add P3L, P3L, $r15 --- slt $r15, P3L, $r15 --- --- #ADDC(P3H, $0x0) --- add P3H, P3H, $r15 --- srli $r6, P3H, #31 --- j .LFlab8 --- .size __muldf3, .-__muldf3 ---#endif /* L_mul_df */ --- --- --- ---#ifdef L_div_sf --- --- .text --- .align 2 --- .global __divsf3 --- .type __divsf3, @function ---__divsf3: --- push $lp --- pushm $r6, $r10 --- --- move $r7, #0x80000000 --- srli $r4, $r0, #23 --- andi $r4, $r4, #0xff --- srli $r6, $r1, #23 --- andi $r6, $r6, #0xff --- slli $r3, $r0, #8 --- or $r3, $r3, $r7 --- slli $r5, $r1, #8 --- or $r5, $r5, $r7 --- xor $r10, $r0, $r1 --- and $r7, $r7, $r10 --- --- addi $r10, $r4, #-1 --- slti $r15, $r10, #0xfe --- beqzs8 .LGspecA --- ---.LGlab1: --- addi $r10, $r6, #-1 --- slti $r15, $r10, #0xfe --- beqzs8 .LGspecB --- ---.LGlab2: --- slt $r15, $r3, $r5 --- bnezs8 .Li27 --- srli $r3, $r3, #1 --- addi $r4, $r4, #1 ---.Li27: --- srli $r8, $r5, #14 --- divr $r0, $r2, $r3, $r8 --- andi $r9, $r5, #0x3fff --- mul $r1, $r9, $r0 --- slli $r2, $r2, #14 --- --- #SUB($r2, $r1) --- move $r15, $r2 --- sub $r2, $r2, $r1 --- slt $r15, $r15, $r2 --- beqzs8 .Li28 --- addi $r0, $r0, #-1 --- --- #ADD($r2, $r5) --- add $r2, $r2, $r5 --- slt $r15, $r2, $r5 ---.Li28: --- divr $r3, $r2, $r2, $r8 --- mul $r1, $r9, $r3 --- slli $r2, $r2, #14 --- --- #SUB($r2, $r1) --- move $r15, $r2 --- sub $r2, $r2, $r1 --- slt $r15, $r15, $r2 --- beqzs8 .Li29 --- addi $r3, $r3, #-1 --- --- #ADD($r2, $r5) --- add $r2, $r2, $r5 --- slt $r15, $r2, $r5 ---.Li29: --- slli $r10, $r0, #14 --- add $r3, $r3, $r10 --- slli $r3, $r3, #4 --- beqz $r2, .Li30 --- ori $r3, $r3, #1 ---.Li30: --- subri $r10, $r6, #0x7e --- add $r4, $r4, $r10 --- addi $r10, $r4, #-1 --- slti $r15, $r10, #0xfe --- beqzs8 .LGoveund --- ---.LGlab8: --- #ADD($r3, $0x80) --- move $r15, #0x80 --- add $r3, $r3, $r15 --- slt $r15, $r3, $r15 --- --- #ADDC($r4, $0x0) --- add $r4, $r4, $r15 --- srli $r10, $r3, #8 --- andi $r10, $r10, #1 --- sub $r3, $r3, $r10 --- slli $r3, $r3, #1 --- srli $r3, $r3, #9 --- slli $r10, $r4, #23 --- or $r3, $r3, $r10 --- or $r0, $r3, $r7 --- ---.LG999: --- popm $r6, $r10 --- pop $lp --- ret5 $lp --- ---.LGspecA: --- bnez $r4, .Li31 --- add $r3, $r3, $r3 --- beqz $r3, .Li31 ---#ifdef __NDS32_PERF_EXT__ --- clz $r8, $r3 ---#else --- pushm $r0, $r5 --- move $r0, $r3 --- bal __clzsi2 --- move $r8, $r0 --- popm $r0, $r5 ---#endif --- sub $r4, $r4, $r8 --- sll $r3, $r3, $r8 --- j .LGlab1 ---.Li31: --- bne $r6, $r4, .Li33 --- add $r10, $r5, $r5 --- beqz $r10, .LGnan ---.Li33: --- subri $r15, $r6, #0xff --- beqzs8 .LGspecB --- beqz $r4, .LGzer --- add $r10, $r3, $r3 --- bnez $r10, .LGnan --- j .LGinf --- ---.LGspecB: --- bnez $r6, .Li34 --- add $r5, $r5, $r5 --- beqz $r5, .LGinf ---#ifdef __NDS32_PERF_EXT__ --- clz $r8, $r5 ---#else --- pushm $r0, $r5 --- move $r0, $r5 --- bal __clzsi2 --- move $r8, $r0 --- popm $r0, $r5 ---#endif --- sub $r6, $r6, $r8 --- sll $r5, $r5, $r8 --- j .LGlab2 ---.Li34: --- add $r10, $r5, $r5 --- bnez $r10, .LGnan --- ---.LGzer: --- move $r0, $r7 --- j .LG999 --- ---.LGoveund: --- bgtz $r4, .LGinf --- subri $r8, $r4, #1 --- slti $r15, $r8, #0x20 --- beqzs8 .LGzer --- subri $r10, $r8, #0x20 --- sll $r4, $r3, $r10 --- srl $r3, $r3, $r8 --- beqz $r4, .Li37 --- ori $r3, $r3, #2 ---.Li37: --- move $r4, #0 --- addi $r10, $r3, #0x80 --- sltsi $r15, $r10, #0 --- beqzs8 .LGlab8 --- move $r4, #1 --- j .LGlab8 --- ---.LGinf: --- move $r10, #0x7f800000 --- or $r0, $r7, $r10 --- j .LG999 --- ---.LGnan: --- move $r0, #0xffc00000 --- j .LG999 --- .size __divsf3, .-__divsf3 ---#endif /* L_div_sf */ --- --- --- ---#ifdef L_div_df --- ---#ifndef __big_endian__ --- #define P1L $r0 --- #define P1H $r1 --- #define P2L $r2 --- #define P2H $r3 --- #define P3L $r4 --- #define P3H $r5 --- #define O1L $r7 --- #define O1H $r8 ---#else --- #define P1H $r0 --- #define P1L $r1 --- #define P2H $r2 --- #define P2L $r3 --- #define P3H $r4 --- #define P3L $r5 --- #define O1H $r7 --- #define O1L $r8 ---#endif --- .text --- .align 2 --- .global __divdf3 --- .type __divdf3, @function ---__divdf3: --- push $lp --- pushm $r6, $r10 --- --- slli $r6, P1H, #1 --- srli $r6, $r6, #21 --- slli P3H, P1H, #11 --- srli $r10, P1L, #21 --- or P3H, P3H, $r10 --- slli P3L, P1L, #11 --- move O1L, #0x80000000 --- or P3H, P3H, O1L --- slli $r9, P2H, #1 --- srli $r9, $r9, #21 --- slli O1H, P2H, #11 --- srli $r10, P2L, #21 --- or O1H, O1H, $r10 --- or O1H, O1H, O1L --- xor P1H, P1H, P2H --- and P1H, P1H, O1L --- slli O1L, P2L, #11 --- --- addi $r10, $r6, #-1 --- slti $r15, $r10, #0x7fe --- beqzs8 .LGspecA --- ---.LGlab1: --- addi $r10, $r9, #-1 --- slti $r15, $r10, #0x7fe --- beqzs8 .LGspecB --- ---.LGlab2: --- sub $r6, $r6, $r9 --- addi $r6, $r6, #0x3ff --- srli P3L, P3L, #1 --- slli $r10, P3H, #31 --- or P3L, P3L, $r10 --- srli P3H, P3H, #1 --- srli $r9, O1H, #16 --- divr P2H, P3H, P3H, $r9 --- move $r10, #0xffff --- and P2L, O1H, $r10 --- mul P1L, P2L, P2H --- slli P3H, P3H, #16 --- srli $r10, P3L, #16 --- or P3H, P3H, $r10 --- --- #SUB(P3H, P1L) --- move $r15, P3H --- sub P3H, P3H, P1L --- slt $r15, $r15, P3H --- beqzs8 .Li20 --- ---.Lb21: --- addi P2H, P2H, #-1 --- add P3H, P3H, O1H --- slt $r15, P3H, O1H --- beqzs8 .Lb21 ---.Li20: --- divr $r9, P3H, P3H, $r9 --- mul P1L, P2L, $r9 --- slli P3H, P3H, #16 --- move $r15, #0xffff --- and $r10, P3L, $r15 --- or P3H, P3H, $r10 --- --- #SUB(P3H, P1L) --- move $r15, P3H --- sub P3H, P3H, P1L --- slt $r15, $r15, P3H --- beqzs8 .Li22 --- ---.Lb23: --- addi $r9, $r9, #-1 --- add P3H, P3H, O1H --- slt $r15, P3H, O1H --- beqzs8 .Lb23 ---.Li22: --- slli P2H, P2H, #16 --- add P2H, P2H, $r9 --- ---/* This is a 64-bit multiple. */ ---#ifndef __big_endian__ ---/* For little endian: ($r0, $r9) is (high, low). */ --- move $r10, $r1 ---#ifndef __NDS32_ISA_V3M__ --- mulr64 $r0, $r3, $r7 ---#else --- pushm $r2, $r5 --- move $r0, $r3 --- movi $r1, #0 --- move $r2, $r7 --- movi $r3, #0 --- bal __muldi3 --- popm $r2, $r5 ---#endif --- move $r9, $r0 --- move $r0, $r1 --- move $r1, $r10 ---#else /* __big_endian__ */ ---/* For big endian: ($r1, $r9) is (high, low). */ --- move $r10, $r0 ---#ifndef __NDS32_ISA_V3M__ --- mulr64 $r0, $r2, $r8 ---#else --- pushm $r2, $r5 --- move $r1, $r2 --- movi $r0, #0 --- move $r3, $r8 --- movi $r2, #0 --- bal __muldi3 --- popm $r2, $r5 ---#endif --- move $r9, $r1 --- move $r1, $r0 --- move $r0, $r10 ---#endif /* __big_endian__ */ --- --- move P3L, #0 --- --- #SUB(P3L, $r9) --- move $r15, P3L --- sub P3L, P3L, $r9 --- slt $r15, $r15, P3L --- --- --- #SUBCC(P3H, P1L) --- beqzs8 .LL47 --- move $r15, P3H --- sub P3H, P3H, P1L --- slt $r15, $r15, P3H --- beqzs8 .LL48 --- subi333 P3H, P3H, #1 --- j .LL49 ---.LL48: --- move $r15, P3H --- subi333 P3H, P3H, #1 --- slt $r15, $r15, P3H --- j .LL49 ---.LL47: --- move $r15, P3H --- sub P3H, P3H, P1L --- slt $r15, $r15, P3H ---.LL49: --- --- beqzs8 .Li24 --- ---.LGlab3: --- addi P2H, P2H, #-1 --- --- #ADD(P3L, O1L) --- add P3L, P3L, O1L --- slt $r15, P3L, O1L --- --- --- #ADDCC(P3H, O1H) --- beqzs8 .LL50 --- add P3H, P3H, O1H --- slt $r15, P3H, O1H --- beqzs8 .LL51 --- addi P3H, P3H, #0x1 --- j .LL52 ---.LL51: --- move $r15, #1 --- add P3H, P3H, $r15 --- slt $r15, P3H, $r15 --- j .LL52 ---.LL50: --- add P3H, P3H, O1H --- slt $r15, P3H, O1H ---.LL52: --- --- beqzs8 .LGlab3 ---.Li24: --- bne P3H, O1H, .Li25 --- move P1L, O1L --- move P3H, P3L --- move $r9, #0 --- move P2L, $r9 --- j .Le25 ---.Li25: --- srli P2L, O1H, #16 --- divr $r9, P3H, P3H, P2L --- move $r10, #0xffff --- and $r10, O1H, $r10 --- mul P1L, $r10, $r9 --- slli P3H, P3H, #16 --- srli $r15, P3L, #16 --- or P3H, P3H, $r15 --- --- #SUB(P3H, P1L) --- move $r15, P3H --- sub P3H, P3H, P1L --- slt $r15, $r15, P3H --- beqzs8 .Li26 --- ---.Lb27: --- addi $r9, $r9, #-1 --- add P3H, P3H, O1H --- slt $r15, P3H, O1H --- beqzs8 .Lb27 ---.Li26: --- divr P2L, P3H, P3H, P2L --- mul P1L, $r10, P2L --- slli P3H, P3H, #16 --- move $r10, #0xffff --- and $r10, P3L, $r10 --- or P3H, P3H, $r10 --- --- #SUB(P3H, P1L) --- move $r15, P3H --- sub P3H, P3H, P1L --- slt $r15, $r15, P3H --- beqzs8 .Li28 --- ---.Lb29: --- addi P2L, P2L, #-1 --- add P3H, P3H, O1H --- slt $r15, P3H, O1H --- beqzs8 .Lb29 ---.Li28: --- slli $r9, $r9, #16 --- add $r9, $r9, P2L --- ---/* This is a 64-bit multiple. */ ---#ifndef __big_endian__ ---/* For little endian: ($r0, $r2) is (high, low). */ --- move $r10, $r1 ---#ifndef __NDS32_ISA_V3M__ --- mulr64 $r0, $r9, $r7 ---#else --- pushm $r2, $r5 --- move $r0, $r9 --- movi $r1, #0 --- move $r2, $r7 --- movi $r3, #0 --- bal __muldi3 --- popm $r2, $r5 ---#endif --- move $r2, $r0 --- move $r0, $r1 --- move $r1, $r10 ---#else /* __big_endian__ */ ---/* For big endian: ($r1, $r3) is (high, low). */ --- move $r10, $r0 ---#ifndef __NDS32_ISA_V3M__ --- mulr64 $r0, $r9, $r8 ---#else --- pushm $r2, $r5 --- move $r0, $r9 --- movi $r1, #0 --- move $r2, $r7 --- movi $r3, #0 --- bal __muldi3 --- popm $r2, $r5 ---#endif --- move $r3, $r1 --- move $r1, $r0 --- move $r0, $r10 ---#endif /* __big_endian__ */ --- ---.Le25: --- move P3L, #0 --- --- #SUB(P3L, P2L) --- move $r15, P3L --- sub P3L, P3L, P2L --- slt $r15, $r15, P3L --- --- --- #SUBCC(P3H, P1L) --- beqzs8 .LL53 --- move $r15, P3H --- sub P3H, P3H, P1L --- slt $r15, $r15, P3H --- beqzs8 .LL54 --- subi333 P3H, P3H, #1 --- j .LL55 ---.LL54: --- move $r15, P3H --- subi333 P3H, P3H, #1 --- slt $r15, $r15, P3H --- j .LL55 ---.LL53: --- move $r15, P3H --- sub P3H, P3H, P1L --- slt $r15, $r15, P3H ---.LL55: --- --- beqzs8 .Li30 --- ---.LGlab4: --- addi $r9, $r9, #-1 --- --- #ADD(P3L, O1L) --- add P3L, P3L, O1L --- slt $r15, P3L, O1L --- --- --- #ADDCC(P3H, O1H) --- beqzs8 .LL56 --- add P3H, P3H, O1H --- slt $r15, P3H, O1H --- beqzs8 .LL57 --- addi P3H, P3H, #0x1 --- j .LL58 ---.LL57: --- move $r15, #1 --- add P3H, P3H, $r15 --- slt $r15, P3H, $r15 --- j .LL58 ---.LL56: --- add P3H, P3H, O1H --- slt $r15, P3H, O1H ---.LL58: --- --- beqzs8 .LGlab4 ---.Li30: --- sltsi $r15, P2H, #0 --- bnezs8 .Li31 --- --- #ADD($r9, $r9) --- move $r15, $r9 --- add $r9, $r9, $r9 --- slt $r15, $r9, $r15 --- --- #ADDC(P2H, P2H) --- add P2H, P2H, P2H --- add P2H, P2H, $r15 --- addi $r6, $r6, #-1 ---.Li31: --- or $r10, P3H, P3L --- beqz $r10, .Li32 --- ori $r9, $r9, #1 ---.Li32: --- move P3H, P2H --- move P3L, $r9 --- addi $r10, $r6, #-1 --- slti $r15, $r10, #0x7fe --- beqzs8 .LGoveund --- --- #ADD(P3L, $0x400) --- move $r15, #0x400 --- add P3L, P3L, $r15 --- slt $r15, P3L, $r15 --- --- --- #ADDCC(P3H, $0x0) --- beqzs8 .LL61 --- add P3H, P3H, $r15 --- slt $r15, P3H, $r15 ---.LL61: --- --- #ADDC($r6, $0x0) --- add $r6, $r6, $r15 --- ---.LGlab8: --- srli $r10, P3L, #11 --- andi $r10, $r10, #1 --- sub P3L, P3L, $r10 --- srli P1L, P3L, #11 --- slli $r10, P3H, #21 --- or P1L, P1L, $r10 --- slli $r10, P3H, #1 --- srli $r10, $r10, #12 --- or P1H, P1H, $r10 --- slli $r10, $r6, #20 --- or P1H, P1H, $r10 --- ---.LGret: ---.LG999: --- popm $r6, $r10 --- pop $lp --- ret5 $lp --- ---.LGoveund: --- bgtz $r6, .LGinf --- subri P2H, $r6, #1 --- move P1L, #0 ---.LL62: --- move $r10, #0x20 --- slt $r15, P2H, $r10 --- bnezs8 .LL63 --- or P1L, P1L, P3L --- move P3L, P3H --- move P3H, #0 --- addi P2H, P2H, #0xffffffe0 --- bnez P3L, .LL62 ---.LL63: --- beqz P2H, .LL64 --- move P2L, P3H --- move $r10, P3L --- srl P3L, P3L, P2H --- srl P3H, P3H, P2H --- subri P2H, P2H, #0x20 --- sll P2L, P2L, P2H --- or P3L, P3L, P2L --- sll $r10, $r10, P2H --- or P1L, P1L, $r10 --- beqz P1L, .LL64 --- ori P3L, P3L, #1 ---.LL64: --- #ADD(P3L, $0x400) --- move $r15, #0x400 --- add P3L, P3L, $r15 --- slt $r15, P3L, $r15 --- --- #ADDC(P3H, $0x0) --- add P3H, P3H, $r15 --- srli $r6, P3H, #31 --- j .LGlab8 --- ---.LGspecA: --- #ADD(P3L, P3L) --- move $r15, P3L --- add P3L, P3L, P3L --- slt $r15, P3L, $r15 --- --- #ADDC(P3H, P3H) --- add P3H, P3H, P3H --- add P3H, P3H, $r15 --- bnez $r6, .Li33 --- or $r10, P3H, P3L --- beqz $r10, .Li33 --- --- --- #NORMd($r4, P2H, P2L) --- bnez P3H, .LL65 --- bnez P3L, .LL66 --- move $r6, #0 --- j .LL67 ---.LL66: --- move P3H, P3L --- move P3L, #0 --- move P2H, #32 --- sub $r6, $r6, P2H ---.LL65: ---#ifndef __big_endian__ ---#ifdef __NDS32_PERF_EXT__ --- clz $r3, $r5 ---#else --- pushm $r0, $r2 --- pushm $r4, $r5 --- move $r0, $r5 --- bal __clzsi2 --- move $r3, $r0 --- popm $r4, $r5 --- popm $r0, $r2 ---#endif ---#else /* __big_endian__ */ ---#ifdef __NDS32_PERF_EXT__ --- clz $r2, $r4 ---#else --- pushm $r0, $r1 --- pushm $r3, $r5 --- move $r0, $r4 --- bal __clzsi2 --- move $r2, $r0 --- popm $r3, $r5 --- popm $r0, $r1 ---#endif ---#endif /* __big_endian_ */ --- beqz P2H, .LL67 --- sub $r6, $r6, P2H --- subri P2L, P2H, #32 --- srl P2L, P3L, P2L --- sll P3L, P3L, P2H --- sll P3H, P3H, P2H --- or P3H, P3H, P2L ---.LL67: --- #NORMd End --- --- j .LGlab1 ---.Li33: --- bne $r6, $r9, .Li35 --- slli $r10, O1H, #1 --- or $r10, $r10, O1L --- beqz $r10, .LGnan ---.Li35: --- subri $r15, $r9, #0x7ff --- beqzs8 .LGspecB --- beqz $r6, .LGret --- or $r10, P3H, P3L --- bnez $r10, .LGnan --- ---.LGinf: --- move $r10, #0x7ff00000 --- or P1H, P1H, $r10 --- move P1L, #0 --- j .LGret --- ---.LGspecB: --- #ADD(O1L, O1L) --- move $r15, O1L --- add O1L, O1L, O1L --- slt $r15, O1L, $r15 --- --- #ADDC(O1H, O1H) --- add O1H, O1H, O1H --- add O1H, O1H, $r15 --- bnez $r9, .Li36 --- or $r10, O1H, O1L --- beqz $r10, .LGinf --- --- --- #NORMd($r7, P2H, P2L) --- bnez O1H, .LL68 --- bnez O1L, .LL69 --- move $r9, #0 --- j .LL70 ---.LL69: --- move O1H, O1L --- move O1L, #0 --- move P2H, #32 --- sub $r9, $r9, P2H ---.LL68: ---#ifndef __big_endian__ ---#ifdef __NDS32_PERF_EXT__ --- clz $r3, $r8 ---#else --- pushm $r0, $r2 --- pushm $r4, $r5 --- move $r0, $r8 --- bal __clzsi2 --- move $r3, $r0 --- popm $r4, $r5 --- popm $r0, $r2 ---#endif ---#else /* __big_endian__ */ ---#ifdef __NDS32_PERF_EXT__ --- clz $r2, $r7 ---#else --- pushm $r0, $r1 --- pushm $r3, $r5 --- move $r0, $r7 --- bal __clzsi2 --- move $r2, $r0 --- popm $r3, $r5 --- popm $r0, $r1 ---#endif ---#endif /* __big_endian__ */ --- beqz P2H, .LL70 --- sub $r9, $r9, P2H --- subri P2L, P2H, #32 --- srl P2L, O1L, P2L --- sll O1L, O1L, P2H --- sll O1H, O1H, P2H --- or O1H, O1H, P2L ---.LL70: --- #NORMd End --- --- j .LGlab2 ---.Li36: --- or $r10, O1H, O1L --- beqz $r10, .Li38 --- ---.LGnan: --- move P1H, #0xfff80000 ---.Li38: --- move P1L, #0 --- j .LGret --- .size __divdf3, .-__divdf3 ---#endif /* L_div_df */ --- --- --- ---#ifdef L_negate_sf --- --- .text --- .align 2 --- .global __negsf2 --- .type __negsf2, @function ---__negsf2: --- push $lp --- --- move $r1, #0x80000000 --- xor $r0, $r0, $r1 --- ---.LN999: --- pop $lp --- ret5 $lp --- .size __negsf2, .-__negsf2 ---#endif /* L_negate_sf */ --- --- --- ---#ifdef L_negate_df --- ---#ifndef __big_endian__ --- #define P1H $r1 ---#else --- #define P1H $r0 ---#endif --- .text --- .align 2 --- .global __negdf2 --- .type __negdf2, @function ---__negdf2: --- push $lp --- --- move $r2, #0x80000000 --- xor P1H, P1H, $r2 --- ---.LP999: --- pop $lp --- ret5 $lp --- .size __negdf2, .-__negdf2 ---#endif /* L_negate_df */ --- --- --- ---#ifdef L_sf_to_df --- ---#ifndef __big_endian__ --- #define O1L $r1 --- #define O1H $r2 ---#else --- #define O1H $r1 --- #define O1L $r2 ---#endif --- .text --- .align 2 --- .global __extendsfdf2 --- .type __extendsfdf2, @function ---__extendsfdf2: --- push $lp --- --- srli $r3, $r0, #23 --- andi $r3, $r3, #0xff --- move $r5, #0x80000000 --- and O1H, $r0, $r5 --- addi $r5, $r3, #-1 --- slti $r15, $r5, #0xfe --- beqzs8 .LJspec --- ---.LJlab1: --- addi $r3, $r3, #0x380 --- slli $r5, $r0, #9 --- srli $r5, $r5, #12 --- or O1H, O1H, $r5 --- slli O1L, $r0, #29 --- ---.LJret: --- slli $r5, $r3, #20 --- or O1H, O1H, $r5 --- move $r0, $r1 --- move $r1, $r2 --- ---.LJ999: --- pop $lp --- ret5 $lp --- ---.LJspec: --- move O1L, #0 --- add $r0, $r0, $r0 --- beqz $r0, .LJret --- bnez $r3, .Li42 --- ---.Lb43: --- addi $r3, $r3, #-1 --- add $r0, $r0, $r0 --- move $r5, #0x800000 --- slt $r15, $r0, $r5 --- bnezs8 .Lb43 --- j .LJlab1 ---.Li42: --- move $r3, #0x7ff --- move $r5, #0xff000000 --- slt $r15, $r5, $r0 --- beqzs8 .LJret --- move O1H, #0xfff80000 --- j .LJret --- .size __extendsfdf2, .-__extendsfdf2 ---#endif /* L_sf_to_df */ --- --- --- ---#ifdef L_df_to_sf --- ---#ifndef __big_endian__ --- #define P1L $r0 --- #define P1H $r1 --- #define P2L $r2 --- #define P2H $r3 ---#else --- #define P1H $r0 --- #define P1L $r1 --- #define P2H $r2 --- #define P2L $r3 ---#endif --- .text --- .align 2 --- .global __truncdfsf2 --- .type __truncdfsf2, @function ---__truncdfsf2: --- push $lp --- pushm $r6, $r8 --- --- slli P2H, P1H, #11 --- srli $r7, P1L, #21 --- or P2H, P2H, $r7 --- slli P2L, P1L, #11 --- move $r7, #0x80000000 --- or P2H, P2H, $r7 --- and $r5, P1H, $r7 --- slli $r4, P1H, #1 --- srli $r4, $r4, #21 --- addi $r4, $r4, #0xfffffc80 --- addi $r7, $r4, #-1 --- slti $r15, $r7, #0xfe --- beqzs8 .LKspec --- ---.LKlab1: --- beqz P2L, .Li45 --- ori P2H, P2H, #1 ---.Li45: --- #ADD(P2H, $0x80) --- move $r15, #0x80 --- add P2H, P2H, $r15 --- slt $r15, P2H, $r15 --- --- #ADDC($r4, $0x0) --- add $r4, $r4, $r15 --- srli $r7, P2H, #8 --- andi $r7, $r7, #1 --- sub P2H, P2H, $r7 --- slli P2H, P2H, #1 --- srli P2H, P2H, #9 --- slli $r7, $r4, #23 --- or P2H, P2H, $r7 --- or $r0, P2H, $r5 --- ---.LK999: --- popm $r6, $r8 --- pop $lp --- ret5 $lp --- ---.LKspec: --- subri $r15, $r4, #0x47f --- bnezs8 .Li46 --- slli $r7, P2H, #1 --- or $r7, $r7, P2L --- beqz $r7, .Li46 --- move $r0, #0xffc00000 --- j .LK999 ---.Li46: --- sltsi $r15, $r4, #0xff --- bnezs8 .Li48 --- move $r7, #0x7f800000 --- or $r0, $r5, $r7 --- j .LK999 ---.Li48: --- subri $r6, $r4, #1 --- move $r7, #0x20 --- slt $r15, $r6, $r7 --- bnezs8 .Li49 --- move $r0, $r5 --- j .LK999 ---.Li49: --- subri $r8, $r6, #0x20 --- sll $r7, P2H, $r8 --- or P2L, P2L, $r7 --- srl P2H, P2H, $r6 --- move $r4, #0 --- move $r7, #0x80000000 --- or P2H, P2H, $r7 --- j .LKlab1 --- .size __truncdfsf2, .-__truncdfsf2 ---#endif /* L_df_to_sf */ --- --- --- ---#ifdef L_df_to_si --- ---#ifndef __big_endian__ --- #define P1L $r0 --- #define P1H $r1 ---#else --- #define P1H $r0 --- #define P1L $r1 ---#endif --- .global __fixdfsi --- .type __fixdfsi, @function ---__fixdfsi: --- push $lp --- pushm $r6, $r6 --- --- slli $r3, P1H, #11 --- srli $r6, P1L, #21 --- or $r3, $r3, $r6 --- move $r6, #0x80000000 --- or $r3, $r3, $r6 --- slli $r6, P1H, #1 --- srli $r6, $r6, #21 --- subri $r2, $r6, #0x41e --- blez $r2, .LLnaninf --- move $r6, #0x20 --- slt $r15, $r2, $r6 --- bnezs8 .LL72 --- move $r3, #0 ---.LL72: --- srl $r3, $r3, $r2 --- sltsi $r15, P1H, #0 --- beqzs8 .Li50 --- subri $r3, $r3, #0 ---.Li50: --- move $r0, $r3 --- ---.LL999: --- popm $r6, $r6 --- pop $lp --- ret5 $lp --- ---.LLnaninf: --- beqz P1L, .Li51 --- ori P1H, P1H, #1 ---.Li51: --- move $r6, #0x7ff00000 --- slt $r15, $r6, P1H --- beqzs8 .Li52 --- move $r0, #0x80000000 --- j .LL999 ---.Li52: --- move $r0, #0x7fffffff --- j .LL999 --- .size __fixdfsi, .-__fixdfsi ---#endif /* L_df_to_si */ --- --- --- ---#ifdef L_fixsfdi --- ---#ifndef __big_endian__ --- #define O1L $r1 --- #define O1H $r2 ---#else --- #define O1H $r1 --- #define O1L $r2 ---#endif --- .text --- .align 2 --- .global __fixsfdi --- .type __fixsfdi, @function ---__fixsfdi: --- push $lp --- --- srli $r3, $r0, #23 --- andi $r3, $r3, #0xff --- slli O1H, $r0, #8 --- move $r5, #0x80000000 --- or O1H, O1H, $r5 --- move O1L, #0 --- sltsi $r15, $r3, #0xbe --- beqzs8 .LCinfnan --- subri $r3, $r3, #0xbe ---.LL8: --- move $r5, #0x20 --- slt $r15, $r3, $r5 --- bnezs8 .LL9 --- move O1L, O1H --- move O1H, #0 --- addi $r3, $r3, #0xffffffe0 --- bnez O1L, .LL8 ---.LL9: --- beqz $r3, .LL10 --- move $r4, O1H --- srl O1L, O1L, $r3 --- srl O1H, O1H, $r3 --- subri $r3, $r3, #0x20 --- sll $r4, $r4, $r3 --- or O1L, O1L, $r4 ---.LL10: --- sltsi $r15, $r0, #0 --- beqzs8 .LCret --- --- subri O1H, O1H, #0 --- beqz O1L, .LL11 --- subri O1L, O1L, #0 --- subi45 O1H, #1 ---.LL11: --- ---.LCret: --- move $r0, $r1 --- move $r1, $r2 --- ---.LC999: --- pop $lp --- ret5 $lp --- ---.LCinfnan: --- sltsi $r15, $r0, #0 --- bnezs8 .LCret3 --- subri $r15, $r3, #0xff --- bnezs8 .Li7 --- slli $r5, O1H, #1 --- beqz $r5, .Li7 --- ---.LCret3: --- move O1H, #0x80000000 --- j .LCret ---.Li7: --- move O1H, #0x7fffffff --- move O1L, #-1 --- j .LCret --- .size __fixsfdi, .-__fixsfdi ---#endif /* L_fixsfdi */ --- --- --- ---#ifdef L_fixdfdi --- ---#ifndef __big_endian__ --- #define P1L $r0 --- #define P1H $r1 --- #define O1L $r3 --- #define O1H $r4 ---#else --- #define P1H $r0 --- #define P1L $r1 --- #define O1H $r3 --- #define O1L $r4 ---#endif --- .text --- .align 2 --- .global __fixdfdi --- .type __fixdfdi, @function ---__fixdfdi: --- push $lp --- pushm $r6, $r6 --- --- slli $r5, P1H, #1 --- srli $r5, $r5, #21 --- slli O1H, P1H, #11 --- srli $r6, P1L, #21 --- or O1H, O1H, $r6 --- slli O1L, P1L, #11 --- move $r6, #0x80000000 --- or O1H, O1H, $r6 --- slti $r15, $r5, #0x43e --- beqzs8 .LCnaninf --- subri $r2, $r5, #0x43e ---.LL14: --- move $r6, #0x20 --- slt $r15, $r2, $r6 --- bnezs8 .LL15 --- move O1L, O1H --- move O1H, #0 --- addi $r2, $r2, #0xffffffe0 --- bnez O1L, .LL14 ---.LL15: --- beqz $r2, .LL16 --- move P1L, O1H --- srl O1L, O1L, $r2 --- srl O1H, O1H, $r2 --- subri $r2, $r2, #0x20 --- sll P1L, P1L, $r2 --- or O1L, O1L, P1L ---.LL16: --- sltsi $r15, P1H, #0 --- beqzs8 .LCret --- --- subri O1H, O1H, #0 --- beqz O1L, .LL17 --- subri O1L, O1L, #0 --- subi45 O1H, #1 ---.LL17: --- ---.LCret: --- move P1L, O1L --- move P1H, O1H --- ---.LC999: --- popm $r6, $r6 --- pop $lp --- ret5 $lp --- ---.LCnaninf: --- sltsi $r15, P1H, #0 --- bnezs8 .LCret3 --- subri $r15, $r5, #0x7ff --- bnezs8 .Li5 --- slli $r6, O1H, #1 --- or $r6, $r6, O1L --- beqz $r6, .Li5 --- ---.LCret3: --- move O1H, #0x80000000 --- move O1L, #0 --- j .LCret ---.Li5: --- move O1H, #0x7fffffff --- move O1L, #-1 --- j .LCret --- .size __fixdfdi, .-__fixdfdi ---#endif /* L_fixdfdi */ --- --- --- ---#ifdef L_fixunssfsi --- --- .global __fixunssfsi --- .type __fixunssfsi, @function ---__fixunssfsi: --- push $lp --- --- slli $r1, $r0, #8 --- move $r3, #0x80000000 --- or $r1, $r1, $r3 --- srli $r3, $r0, #23 --- andi $r3, $r3, #0xff --- subri $r2, $r3, #0x9e --- sltsi $r15, $r2, #0 --- bnezs8 .LLspec --- sltsi $r15, $r2, #0x20 --- bnezs8 .Li45 --- move $r0, #0 --- j .LL999 ---.Li45: --- srl $r1, $r1, $r2 --- sltsi $r15, $r0, #0 --- beqzs8 .Li46 --- subri $r1, $r1, #0 ---.Li46: --- move $r0, $r1 --- ---.LL999: --- pop $lp --- ret5 $lp --- ---.LLspec: --- move $r3, #0x7f800000 --- slt $r15, $r3, $r0 --- beqzs8 .Li47 --- move $r0, #0x80000000 --- j .LL999 ---.Li47: --- move $r0, #-1 --- j .LL999 --- .size __fixunssfsi, .-__fixunssfsi ---#endif /* L_fixunssfsi */ --- --- --- ---#ifdef L_fixunsdfsi --- ---#ifndef __big_endian__ --- #define P1L $r0 --- #define P1H $r1 ---#else --- #define P1H $r0 --- #define P1L $r1 ---#endif --- .text --- .align 2 --- .global __fixunsdfsi --- .type __fixunsdfsi, @function ---__fixunsdfsi: --- push $lp --- pushm $r6, $r6 --- --- slli $r3, P1H, #11 --- srli $r6, P1L, #21 --- or $r3, $r3, $r6 --- move $r6, #0x80000000 --- or $r3, $r3, $r6 --- slli $r6, P1H, #1 --- srli $r6, $r6, #21 --- subri $r2, $r6, #0x41e --- sltsi $r15, $r2, #0 --- bnezs8 .LNnaninf --- move $r6, #0x20 --- slt $r15, $r2, $r6 --- bnezs8 .LL73 --- move $r3, #0 ---.LL73: --- srl $r3, $r3, $r2 --- sltsi $r15, P1H, #0 --- beqzs8 .Li53 --- subri $r3, $r3, #0 ---.Li53: --- move $r0, $r3 --- ---.LN999: --- popm $r6, $r6 --- pop $lp --- ret5 $lp --- ---.LNnaninf: --- beqz P1L, .Li54 --- ori P1H, P1H, #1 ---.Li54: --- move $r6, #0x7ff00000 --- slt $r15, $r6, P1H --- beqzs8 .Li55 --- move $r0, #0x80000000 --- j .LN999 ---.Li55: --- move $r0, #-1 --- j .LN999 --- .size __fixunsdfsi, .-__fixunsdfsi ---#endif /* L_fixunsdfsi */ --- --- --- ---#ifdef L_fixunssfdi --- ---#ifndef __big_endian__ --- #define O1L $r1 --- #define O1H $r2 ---#else --- #define O1H $r1 --- #define O1L $r2 ---#endif --- .text --- .align 2 --- .global __fixunssfdi --- .type __fixunssfdi, @function ---__fixunssfdi: --- push $lp --- --- srli $r3, $r0, #23 --- andi $r3, $r3, #0xff --- slli O1H, $r0, #8 --- move $r5, #0x80000000 --- or O1H, O1H, $r5 --- move O1L, #0 --- sltsi $r15, $r3, #0xbe --- beqzs8 .LDinfnan --- subri $r3, $r3, #0xbe ---.LL12: --- move $r5, #0x20 --- slt $r15, $r3, $r5 --- bnezs8 .LL13 --- move O1L, O1H --- move O1H, #0 --- addi $r3, $r3, #0xffffffe0 --- bnez O1L, .LL12 ---.LL13: --- beqz $r3, .LL14 --- move $r4, O1H --- srl O1L, O1L, $r3 --- srl O1H, O1H, $r3 --- subri $r3, $r3, #0x20 --- sll $r4, $r4, $r3 --- or O1L, O1L, $r4 ---.LL14: --- sltsi $r15, $r0, #0 --- beqzs8 .LDret --- --- subri O1H, O1H, #0 --- beqz O1L, .LL15 --- subri O1L, O1L, #0 --- subi45 O1H, #1 ---.LL15: --- ---.LDret: --- move $r0, $r1 --- move $r1, $r2 --- ---.LD999: --- pop $lp --- ret5 $lp --- ---.LDinfnan: --- move O1H, #0x80000000 --- move O1L, #0 --- j .LDret --- .size __fixunssfdi, .-__fixunssfdi ---#endif /* L_fixunssfdi */ --- --- --- ---#ifdef L_fixunsdfdi --- ---#ifndef __big_endian__ --- #define P1L $r0 --- #define P1H $r1 --- #define O1L $r3 --- #define O1H $r4 ---#else --- #define P1H $r0 --- #define P1L $r1 --- #define O1H $r3 --- #define O1L $r4 ---#endif --- .text --- .align 2 --- .global __fixunsdfdi --- .type __fixunsdfdi, @function ---__fixunsdfdi: --- push $lp --- pushm $r6, $r6 --- --- slli $r5, P1H, #1 --- srli $r5, $r5, #21 --- slli O1H, P1H, #11 --- srli $r6, P1L, #21 --- or O1H, O1H, $r6 --- slli O1L, P1L, #11 --- move $r6, #0x80000000 --- or O1H, O1H, $r6 --- slti $r15, $r5, #0x43e --- beqzs8 .LDnaninf --- subri $r2, $r5, #0x43e ---.LL18: --- move $r6, #0x20 --- slt $r15, $r2, $r6 --- bnezs8 .LL19 --- move O1L, O1H --- move O1H, #0 --- addi $r2, $r2, #0xffffffe0 --- bnez O1L, .LL18 ---.LL19: --- beqz $r2, .LL20 --- move P1L, O1H --- srl O1L, O1L, $r2 --- srl O1H, O1H, $r2 --- subri $r2, $r2, #0x20 --- sll P1L, P1L, $r2 --- or O1L, O1L, P1L ---.LL20: --- sltsi $r15, P1H, #0 --- beqzs8 .LDret --- --- subri O1H, O1H, #0 --- beqz O1L, .LL21 --- subri O1L, O1L, #0 --- subi45 O1H, #1 ---.LL21: --- ---.LDret: --- move P1L, O1L --- move P1H, O1H --- ---.LD999: --- popm $r6, $r6 --- pop $lp --- ret5 $lp --- ---.LDnaninf: --- move O1H, #0x80000000 --- move O1L, #0 --- j .LDret --- .size __fixunsdfdi, .-__fixunsdfdi ---#endif /* L_fixunsdfdi */ --- --- --- ---#ifdef L_si_to_sf --- --- .text --- .align 2 --- .global __floatsisf --- .type __floatsisf, @function ---__floatsisf: --- push $lp --- --- move $r4, #0x80000000 --- and $r2, $r0, $r4 --- beqz $r0, .Li39 --- sltsi $r15, $r0, #0 --- beqzs8 .Li40 --- subri $r0, $r0, #0 ---.Li40: --- move $r1, #0x9e ---#ifdef __NDS32_PERF_EXT__ --- clz $r3, $r0 ---#else --- pushm $r0, $r2 --- pushm $r4, $r5 --- bal __clzsi2 --- move $r3, $r0 --- popm $r4, $r5 --- popm $r0, $r2 ---#endif --- sub $r1, $r1, $r3 --- sll $r0, $r0, $r3 --- --- #ADD($r0, $0x80) --- move $r15, #0x80 --- add $r0, $r0, $r15 --- slt $r15, $r0, $r15 --- --- #ADDC($r1, $0x0) --- add $r1, $r1, $r15 --- srai $r4, $r0, #8 --- andi $r4, $r4, #1 --- sub $r0, $r0, $r4 --- slli $r0, $r0, #1 --- srli $r0, $r0, #9 --- slli $r4, $r1, #23 --- or $r0, $r0, $r4 ---.Li39: --- or $r0, $r0, $r2 --- ---.LH999: --- pop $lp --- ret5 $lp --- .size __floatsisf, .-__floatsisf ---#endif /* L_si_to_sf */ --- --- --- ---#ifdef L_si_to_df --- ---#ifndef __big_endian__ --- #define O1L $r1 --- #define O1H $r2 --- #define O2L $r4 --- #define O2H $r5 ---#else --- #define O1H $r1 --- #define O1L $r2 --- #define O2H $r4 --- #define O2L $r5 ---#endif --- .text --- .align 2 --- .global __floatsidf --- .type __floatsidf, @function ---__floatsidf: --- push $lp --- pushm $r6, $r6 --- --- move O1L, #0 --- move O2H, O1L --- move $r3, O1L --- move O1H, $r0 --- beqz O1H, .Li39 --- sltsi $r15, O1H, #0 --- beqzs8 .Li40 --- move O2H, #0x80000000 --- --- subri O1H, O1H, #0 --- beqz O1L, .LL71 --- subri O1L, O1L, #0 --- subi45 O1H, #1 ---.LL71: ---.Li40: --- move $r3, #0x41e ---#ifndef __big_endian__ ---#ifdef __NDS32_PERF_EXT__ --- clz $r4, $r2 ---#else --- pushm $r0, $r3 --- push $r5 --- move $r0, $r2 --- bal __clzsi2 --- move $r4, $r0 --- pop $r5 --- popm $r0, $r3 ---#endif ---#else /* __big_endian__ */ ---#ifdef __NDS32_PERF_EXT__ --- clz $r5, $r1 ---#else --- pushm $r0, $r4 --- move $r0, $r1 --- bal __clzsi2 --- move $r5, $r0 --- popm $r0, $r4 ---#endif ---#endif /* __big_endian__ */ --- sub $r3, $r3, O2L --- sll O1H, O1H, O2L ---.Li39: --- srli O2L, O1L, #11 --- slli $r6, O1H, #21 --- or O2L, O2L, $r6 --- slli $r6, O1H, #1 --- srli $r6, $r6, #12 --- or O2H, O2H, $r6 --- slli $r6, $r3, #20 --- or O2H, O2H, $r6 --- move $r0, $r4 --- move $r1, $r5 --- ---.LH999: --- popm $r6, $r6 --- pop $lp --- ret5 $lp --- .size __floatsidf, .-__floatsidf ---#endif /* L_si_to_df */ --- --- --- ---#ifdef L_floatdisf --- ---#ifndef __big_endian__ --- #define P1L $r0 --- #define P1H $r1 --- #define P2L $r2 --- #define P2H $r3 ---#else --- #define P1H $r0 --- #define P1L $r1 --- #define P2H $r2 --- #define P2L $r3 ---#endif --- .text --- .align 2 --- .global __floatdisf --- .type __floatdisf, @function ---__floatdisf: --- push $lp --- pushm $r6, $r7 --- --- move $r7, #0x80000000 --- and $r5, P1H, $r7 --- move P2H, P1H --- move P2L, P1L --- or $r7, P1H, P1L --- beqz $r7, .Li1 --- sltsi $r15, P1H, #0 --- beqzs8 .Li2 --- --- subri P2H, P2H, #0 --- beqz P2L, .LL1 --- subri P2L, P2L, #0 --- subi45 P2H, #1 ---.LL1: ---.Li2: --- move $r4, #0xbe --- --- --- #NORMd($r2, $r6, P1L) --- bnez P2H, .LL2 --- bnez P2L, .LL3 --- move $r4, #0 --- j .LL4 ---.LL3: --- move P2H, P2L --- move P2L, #0 --- move $r6, #32 --- sub $r4, $r4, $r6 ---.LL2: ---#ifdef __NDS32_PERF_EXT__ --- clz $r6, P2H ---#else --- pushm $r0, $r5 --- move $r0, P2H --- bal __clzsi2 --- move $r6, $r0 --- popm $r0, $r5 ---#endif --- beqz $r6, .LL4 --- sub $r4, $r4, $r6 --- subri P1L, $r6, #32 --- srl P1L, P2L, P1L --- sll P2L, P2L, $r6 --- sll P2H, P2H, $r6 --- or P2H, P2H, P1L ---.LL4: --- #NORMd End --- --- beqz P2L, .Li3 --- ori P2H, P2H, #1 ---.Li3: --- #ADD(P2H, $0x80) --- move $r15, #0x80 --- add P2H, P2H, $r15 --- slt $r15, P2H, $r15 --- --- #ADDC($r4, $0x0) --- add $r4, $r4, $r15 --- srli $r7, P2H, #8 --- andi $r7, $r7, #1 --- sub P2H, P2H, $r7 --- slli P2H, P2H, #1 --- srli P2H, P2H, #9 --- slli $r7, $r4, #23 --- or P2H, P2H, $r7 ---.Li1: --- or $r0, P2H, $r5 --- ---.LA999: --- popm $r6, $r7 --- pop $lp --- ret5 $lp --- .size __floatdisf, .-__floatdisf ---#endif /* L_floatdisf */ --- --- --- ---#ifdef L_floatdidf --- ---#ifndef __big_endian__ --- #define P1L $r0 --- #define P1H $r1 --- #define P2L $r2 --- #define P2H $r3 --- #define O1L $r5 --- #define O1H $r6 ---#else --- #define P1H $r0 --- #define P1L $r1 --- #define P2H $r2 --- #define P2L $r3 --- #define O1H $r5 --- #define O1L $r6 ---#endif --- .text --- .align 2 --- .global __floatdidf --- .type __floatdidf, @function ---__floatdidf: --- push $lp --- pushm $r6, $r8 --- --- move $r4, #0 --- move $r7, $r4 --- move P2H, P1H --- move P2L, P1L --- or $r8, P1H, P1L --- beqz $r8, .Li1 --- move $r4, #0x43e --- sltsi $r15, P1H, #0 --- beqzs8 .Li2 --- move $r7, #0x80000000 --- --- subri P2H, P2H, #0 --- beqz P2L, .LL1 --- subri P2L, P2L, #0 --- subi45 P2H, #1 ---.LL1: --- ---.Li2: --- #NORMd($r2, O1H, O1L) --- bnez P2H, .LL2 --- bnez P2L, .LL3 --- move $r4, #0 --- j .LL4 ---.LL3: --- move P2H, P2L --- move P2L, #0 --- move O1H, #32 --- sub $r4, $r4, O1H ---.LL2: ---#ifdef __NDS32_PERF_EXT__ --- clz O1H, P2H ---#else /* not __NDS32_PERF_EXT__ */ ---/* --- Replace clz with function call. --- clz O1H, P2H --- EL: clz $r6, $r3 --- EB: clz $r5, $r2 ---*/ ---#ifndef __big_endian__ --- pushm $r0, $r5 --- move $r0, $r3 --- bal __clzsi2 --- move $r6, $r0 --- popm $r0, $r5 ---#else --- pushm $r0, $r4 --- move $r0, $r2 --- bal __clzsi2 --- move $r5, $r0 --- popm $r0, $r4 ---#endif ---#endif /* not __NDS32_PERF_EXT__ */ --- beqz O1H, .LL4 --- sub $r4, $r4, O1H --- subri O1L, O1H, #32 --- srl O1L, P2L, O1L --- sll P2L, P2L, O1H --- sll P2H, P2H, O1H --- or P2H, P2H, O1L ---.LL4: --- #NORMd End --- --- #ADD(P2L, $0x400) --- move $r15, #0x400 --- add P2L, P2L, $r15 --- slt $r15, P2L, $r15 --- --- --- #ADDCC(P2H, $0x0) --- beqzs8 .LL7 --- add P2H, P2H, $r15 --- slt $r15, P2H, $r15 ---.LL7: --- --- #ADDC($r4, $0x0) --- add $r4, $r4, $r15 --- srli $r8, P2L, #11 --- andi $r8, $r8, #1 --- sub P2L, P2L, $r8 ---.Li1: --- srli O1L, P2L, #11 --- slli $r8, P2H, #21 --- or O1L, O1L, $r8 --- slli O1H, P2H, #1 --- srli O1H, O1H, #12 --- slli $r8, $r4, #20 --- or O1H, O1H, $r8 --- or O1H, O1H, $r7 --- move P1L, O1L --- move P1H, O1H --- ---.LA999: --- popm $r6, $r8 --- pop $lp --- ret5 $lp --- .size __floatdidf, .-__floatdidf ---#endif /* L_floatdidf */ --- --- --- ---#ifdef L_floatunsisf --- --- .text --- .align 2 --- .global __floatunsisf --- .type __floatunsisf, @function ---__floatunsisf: --- push $lp --- --- beqz $r0, .Li41 --- move $r2, #0x9e ---#ifdef __NDS32_PERF_EXT__ --- clz $r1, $r0 ---#else --- push $r0 --- pushm $r2, $r5 --- bal __clzsi2 --- move $r1, $r0 --- popm $r2, $r5 --- pop $r0 ---#endif --- --- sub $r2, $r2, $r1 --- sll $r0, $r0, $r1 --- --- #ADD($r0, $0x80) --- move $r15, #0x80 --- add $r0, $r0, $r15 --- slt $r15, $r0, $r15 --- --- #ADDC($r2, $0x0) --- add $r2, $r2, $r15 --- srli $r3, $r0, #8 --- andi $r3, $r3, #1 --- sub $r0, $r0, $r3 --- slli $r0, $r0, #1 --- srli $r0, $r0, #9 --- slli $r3, $r2, #23 --- or $r0, $r0, $r3 --- ---.Li41: ---.LI999: --- pop $lp --- ret5 $lp --- .size __floatunsisf, .-__floatunsisf ---#endif /* L_floatunsisf */ --- --- --- ---#ifdef L_floatunsidf --- ---#ifndef __big_endian__ --- #define O1L $r1 --- #define O1H $r2 --- #define O2L $r4 --- #define O2H $r5 ---#else --- #define O1H $r1 --- #define O1L $r2 --- #define O2H $r4 --- #define O2L $r5 ---#endif --- .text --- .align 2 --- .global __floatunsidf --- .type __floatunsidf, @function ---__floatunsidf: --- push $lp --- pushm $r6, $r6 --- --- move O1L, #0 --- move $r3, O1L --- move O1H, $r0 --- beqz O1H, .Li41 --- move $r3, #0x41e ---#ifndef __big_endian__ ---#ifdef __NDS32_PERF_EXT__ --- clz $r5, $r2 ---#else --- pushm $r0, $r4 --- move $r0, $r2 --- bal __clzsi2 --- move $r5, $r0 --- popm $r0, $r4 ---#endif ---#else /* __big_endian__ */ ---#ifdef __NDS32_PERF_EXT__ --- clz $r4, $r1 ---#else --- pushm $r0, $r3 --- push $r5 --- move $r0, $r1 --- bal __clzsi2 --- move $r4, $r0 --- pop $r5 --- popm $r0, $r3 ---#endif ---#endif /* __big_endian__ */ --- sub $r3, $r3, O2H --- sll O1H, O1H, O2H ---.Li41: --- srli O2L, O1L, #11 --- slli $r6, O1H, #21 --- or O2L, O2L, $r6 --- slli O2H, O1H, #1 --- srli O2H, O2H, #12 --- slli $r6, $r3, #20 --- or O2H, O2H, $r6 --- move $r0, $r4 --- move $r1, $r5 --- ---.LI999: --- popm $r6, $r6 --- pop $lp --- ret5 $lp --- .size __floatunsidf, .-__floatunsidf ---#endif /* L_floatunsidf */ --- --- --- ---#ifdef L_floatundisf --- ---#ifndef __big_endian__ --- #define P1L $r0 --- #define P1H $r1 --- #define P2L $r2 --- #define P2H $r3 ---#else --- #define P1H $r0 --- #define P1L $r1 --- #define P2H $r2 --- #define P2L $r3 ---#endif --- .text --- .align 2 --- .global __floatundisf --- .type __floatundisf, @function ---__floatundisf: --- push $lp --- pushm $r6, $r6 --- --- move P2H, P1H --- move P2L, P1L --- or $r6, P1H, P1L --- beqz $r6, .Li4 --- move $r4, #0xbe --- --- --- #NORMd($r2, $r5, P1L) --- bnez P2H, .LL5 --- bnez P2L, .LL6 --- move $r4, #0 --- j .LL7 ---.LL6: --- move P2H, P2L --- move P2L, #0 --- move $r5, #32 --- sub $r4, $r4, $r5 ---.LL5: ---#ifdef __NDS32_PERF_EXT__ --- clz $r5, P2H ---#else --- pushm $r0, $r4 --- move $r0, P2H --- bal __clzsi2 --- move $r5, $r0 --- popm $r0, $r4 ---#endif --- beqz $r5, .LL7 --- sub $r4, $r4, $r5 --- subri P1L, $r5, #32 --- srl P1L, P2L, P1L --- sll P2L, P2L, $r5 --- sll P2H, P2H, $r5 --- or P2H, P2H, P1L ---.LL7: --- #NORMd End --- --- beqz P2L, .Li5 --- ori P2H, P2H, #1 ---.Li5: --- #ADD(P2H, $0x80) --- move $r15, #0x80 --- add P2H, P2H, $r15 --- slt $r15, P2H, $r15 --- --- #ADDC($r4, $0x0) --- add $r4, $r4, $r15 --- srli $r6, P2H, #8 --- andi $r6, $r6, #1 --- sub P2H, P2H, $r6 --- slli P2H, P2H, #1 --- srli P2H, P2H, #9 --- slli $r6, $r4, #23 --- or P2H, P2H, $r6 ---.Li4: --- move $r0, P2H --- ---.LB999: --- popm $r6, $r6 --- pop $lp --- ret5 $lp --- .size __floatundisf, .-__floatundisf ---#endif /* L_floatundisf */ --- --- --- ---#ifdef L_floatundidf --- ---#ifndef __big_endian__ --- #define P1L $r0 --- #define P1H $r1 --- #define P2L $r2 --- #define P2H $r3 --- #define O1L $r5 --- #define O1H $r6 ---#else --- #define P1H $r0 --- #define P1L $r1 --- #define P2H $r2 --- #define P2L $r3 --- #define O1H $r5 --- #define O1L $r6 ---#endif --- .text --- .align 2 --- .global __floatundidf --- .type __floatundidf, @function ---__floatundidf: --- push $lp --- pushm $r6, $r7 --- --- move $r4, #0 --- move P2H, P1H --- move P2L, P1L --- or $r7, P1H, P1L --- beqz $r7, .Li3 --- move $r4, #0x43e --- --- --- #NORMd($r2, O1H, O1L) --- bnez P2H, .LL8 --- bnez P2L, .LL9 --- move $r4, #0 --- j .LL10 ---.LL9: --- move P2H, P2L --- move P2L, #0 --- move O1H, #32 --- sub $r4, $r4, O1H ---.LL8: ---#ifdef __NDS32_PERF_EXT__ --- clz O1H, P2H ---#else /* not __NDS32_PERF_EXT__ */ ---/* --- Replace clz with function call. --- clz O1H, P2H --- EL: clz $r6, $r3 --- EB: clz $r5, $r2 ---*/ ---#ifndef __big_endian__ --- pushm $r0, $r5 --- move $r0, $r3 --- bal __clzsi2 --- move $r6, $r0 --- popm $r0, $r5 ---#else --- pushm $r0, $r4 --- move $r0, $r2 --- bal __clzsi2 --- move $r5, $r0 --- popm $r0, $r4 ---#endif ---#endif /* not __NDS32_PERF_EXT__ */ --- beqz O1H, .LL10 --- sub $r4, $r4, O1H --- subri O1L, O1H, #32 --- srl O1L, P2L, O1L --- sll P2L, P2L, O1H --- sll P2H, P2H, O1H --- or P2H, P2H, O1L ---.LL10: --- #NORMd End --- --- #ADD(P2L, $0x400) --- move $r15, #0x400 --- add P2L, P2L, $r15 --- slt $r15, P2L, $r15 --- --- --- #ADDCC(P2H, $0x0) --- beqzs8 .LL13 --- add P2H, P2H, $r15 --- slt $r15, P2H, $r15 ---.LL13: --- --- #ADDC($r4, $0x0) --- add $r4, $r4, $r15 --- srli $r7, P2L, #11 --- andi $r7, $r7, #1 --- sub P2L, P2L, $r7 ---.Li3: --- srli O1L, P2L, #11 --- slli $r7, P2H, #21 --- or O1L, O1L, $r7 --- slli O1H, P2H, #1 --- srli O1H, O1H, #12 --- slli $r7, $r4, #20 --- or O1H, O1H, $r7 --- move P1L, O1L --- move P1H, O1H --- ---.LB999: --- popm $r6, $r7 --- pop $lp --- ret5 $lp --- .size __floatundidf, .-__floatundidf ---#endif /* L_floatundidf */ --- --- --- ---#ifdef L_compare_sf --- --- .text --- .align 2 --- .global __cmpsf2 --- .type __cmpsf2, @function ---__cmpsf2: --- .global __eqsf2 --- .type __eqsf2, @function ---__eqsf2: --- .global __ltsf2 --- .type __ltsf2, @function ---__ltsf2: --- .global __lesf2 --- .type __lesf2, @function ---__lesf2: --- .global __nesf2 --- .type __nesf2, @function ---__nesf2: --- move $r4, #1 --- j .LA --- --- .global __gesf2 --- .type __gesf2, @function ---__gesf2: --- .global __gtsf2 --- .type __gtsf2, @function ---__gtsf2: --- move $r4, #-1 ---.LA: --- push $lp --- --- slli $r2, $r0, #1 --- slli $r3, $r1, #1 --- or $r5, $r2, $r3 --- beqz $r5, .LMequ --- move $r5, #0xff000000 --- slt $r15, $r5, $r2 --- bnezs8 .LMnan --- slt $r15, $r5, $r3 --- bnezs8 .LMnan --- srli $r2, $r2, #1 --- sltsi $r15, $r0, #0 --- beqzs8 .Li48 --- subri $r2, $r2, #0 ---.Li48: --- srli $r3, $r3, #1 --- sltsi $r15, $r1, #0 --- beqzs8 .Li49 --- subri $r3, $r3, #0 ---.Li49: --- slts $r15, $r2, $r3 --- beqzs8 .Li50 --- move $r0, #-1 --- j .LM999 ---.Li50: --- slts $r15, $r3, $r2 --- beqzs8 .LMequ --- move $r0, #1 --- j .LM999 --- ---.LMequ: --- move $r0, #0 --- ---.LM999: --- pop $lp --- ret5 $lp --- ---.LMnan: --- move $r0, $r4 --- j .LM999 --- .size __cmpsf2, .-__cmpsf2 --- .size __eqsf2, .-__eqsf2 --- .size __ltsf2, .-__ltsf2 --- .size __lesf2, .-__lesf2 --- .size __nesf2, .-__nesf2 --- .size __gesf2, .-__gesf2 --- .size __gtsf2, .-__gtsf2 ---#endif /* L_compare_sf */ --- --- --- ---#ifdef L_compare_df --- ---#ifdef __big_endian__ --- #define P1H $r0 --- #define P1L $r1 --- #define P2H $r2 --- #define P2L $r3 ---#else --- #define P1H $r1 --- #define P1L $r0 --- #define P2H $r3 --- #define P2L $r2 ---#endif --- .align 2 --- .globl __gtdf2 --- .globl __gedf2 --- .globl __ltdf2 --- .globl __ledf2 --- .globl __eqdf2 --- .globl __nedf2 --- .globl __cmpdf2 --- .type __gtdf2, @function --- .type __gedf2, @function --- .type __ltdf2, @function --- .type __ledf2, @function --- .type __eqdf2, @function --- .type __nedf2, @function --- .type __cmpdf2, @function ---__gtdf2: ---__gedf2: --- movi $r4, -1 --- b .L1 --- ---__ltdf2: ---__ledf2: ---__cmpdf2: ---__nedf2: ---__eqdf2: --- movi $r4, 1 ---.L1: ---#if defined (__NDS32_ISA_V3M__) --- push25 $r10, 0 ---#else --- smw.adm $r6, [$sp], $r9, 0 ---#endif --- --- sethi $r5, 0x7ff00 --- and $r6, P1H, $r5 ! r6=aExp --- and $r7, P2H, $r5 ! r7=bExp --- slli $r8, P1H, 12 ! r8=aSig0 --- slli $r9, P2H, 12 ! r9=bSig0 --- beq $r6, $r5, .L11 ! aExp==0x7ff --- beq $r7, $r5, .L12 ! bExp==0x7ff ---.L2: --- slli $ta, P1H, 1 ! ta=ahigh<<1 --- or $ta, P1L, $ta ! --- xor $r5, P1H, P2H ! r5=ahigh^bhigh --- beqz $ta, .L3 ! if(ahigh<<1)==0,go .L3 --- !------------------------------- --- ! (ahigh<<1)!=0 || (bhigh<<1)!=0 --- !------------------------------- ---.L4: --- beqz $r5, .L5 ! ahigh==bhigh, go .L5 --- !-------------------- --- ! a != b --- !-------------------- ---.L6: --- bltz $r5, .L7 ! if(aSign!=bSign), go .L7 --- !-------------------- --- ! aSign==bSign --- !-------------------- --- slt $ta, $r6, $r7 ! ta=(aExp|b|), go .L10 --- nor $r0, P2H, P2H ! if(|a|<|b|),return (~yh) ---.L14: ---#if defined (__NDS32_ISA_V3M__) --- pop25 $r10, 0 ---#else --- lmw.bim $r6, [$sp], $r9, 0 --- ret ---#endif ---.L10: --- ori $r0, P2H, 1 ! return (yh|1) --- b .L14 --- !-------------------- --- ! (ahigh<<1)=0 --- !-------------------- ---.L3: --- slli $ta, P2H, 1 ! ta=bhigh<<1 --- or $ta, P2L, $ta ! --- bnez $ta, .L4 ! ta=(bhigh<<1)!=0,go .L4 ---.L5: --- xor $ta, P1L, P2L ! ta=alow^blow --- bnez $ta, .L6 ! alow!=blow,go .L6 --- movi $r0, 0 ! a==b, return 0 --- b .L14 --- !-------------------- --- ! aExp=0x7ff; --- !-------------------- ---.L11: --- or P1L, P1L, $r8 ! x1=(aSig0|aSig1) --- bnez P1L, .L13 ! if(a=nan), go.L13 --- xor $ta, $r7, $r5 ! ta=(bExp^0x7ff) --- bnez $ta, .L2 ! if(bExp!=0x7ff), go .L2 --- !-------------------- --- ! bExp=0x7ff; --- !-------------------- ---.L12: --- or $ta, P2L, $r9 ! ta=(bSig0|bSig1) --- beqz $ta, .L2 ! if(b!=nan), go .L2 ---.L13: --- move $r0, $r4 --- b .L14 --- !-------------------- --- ! aSign!=bSign --- !-------------------- ---.L7: --- ori $r0, P1H, 1 ! if(aSign!=bSign), return (ahigh|1) --- b .L14 --- --- .size __gtdf2, .-__gtdf2 --- .size __gedf2, .-__gedf2 --- .size __ltdf2, .-__ltdf2 --- .size __ledf2, .-__ledf2 --- .size __eqdf2, .-__eqdf2 --- .size __nedf2, .-__nedf2 --- .size __cmpdf2, .-__cmpdf2 ---#endif /* L_compare_df */ --- --- --- ---#ifdef L_unord_sf --- --- .text --- .align 2 --- .global __unordsf2 --- .type __unordsf2, @function ---__unordsf2: --- push $lp --- --- slli $r2, $r0, #1 --- move $r3, #0xff000000 --- slt $r15, $r3, $r2 --- beqzs8 .Li52 --- move $r0, #1 --- j .LP999 ---.Li52: --- slli $r2, $r1, #1 --- move $r3, #0xff000000 --- slt $r15, $r3, $r2 --- beqzs8 .Li53 --- move $r0, #1 --- j .LP999 ---.Li53: --- move $r0, #0 --- ---.LP999: --- pop $lp --- ret5 $lp --- .size __unordsf2, .-__unordsf2 ---#endif /* L_unord_sf */ --- --- --- ---#ifdef L_unord_df --- ---#ifndef __big_endian__ --- #define P1L $r0 --- #define P1H $r1 --- #define P2L $r2 --- #define P2H $r3 ---#else --- #define P1H $r0 --- #define P1L $r1 --- #define P2H $r2 --- #define P2L $r3 ---#endif --- .text --- .align 2 --- .global __unorddf2 --- .type __unorddf2, @function ---__unorddf2: --- push $lp --- --- slli $r4, P1H, #1 --- beqz P1L, .Li66 --- addi $r4, $r4, #1 ---.Li66: --- move $r5, #0xffe00000 --- slt $r15, $r5, $r4 --- beqzs8 .Li67 --- move $r0, #1 --- j .LR999 ---.Li67: --- slli $r4, P2H, #1 --- beqz P2L, .Li68 --- addi $r4, $r4, #1 ---.Li68: --- move $r5, #0xffe00000 --- slt $r15, $r5, $r4 --- beqzs8 .Li69 --- move $r0, #1 --- j .LR999 ---.Li69: --- move $r0, #0 --- ---.LR999: --- pop $lp --- ret5 $lp --- .size __unorddf2, .-__unorddf2 ---#endif /* L_unord_df */ ---/* ------------------------------------------- */ ---/* DPBIT floating point operations for libgcc */ ---/* ------------------------------------------- */ --diff --git a/libgcc/config/nds32/lib2csrc-mculib/_clzdi2.c b/libgcc/config/nds32/lib2csrc-mculib/_clzdi2.c --deleted file mode 100644 --index 6afd6ab..0000000 ----- a/libgcc/config/nds32/lib2csrc-mculib/_clzdi2.c --+++ /dev/null --@@ -1,38 +0,0 @@ ---/* mculib libgcc routines of Andes NDS32 cpu for GNU compiler --- Copyright (C) 2012-2016 Free Software Foundation, Inc. --- Contributed by Andes Technology Corporation. --- --- This file is part of GCC. --- --- GCC is free software; you can redistribute it and/or modify it --- under the terms of the GNU General Public License as published --- by the Free Software Foundation; either version 3, or (at your --- option) any later version. --- --- GCC is distributed in the hope that it will be useful, but WITHOUT --- ANY WARRANTY; without even the implied warranty of MERCHANTABILITY --- or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public --- License for more details. --- --- Under Section 7 of GPL version 3, you are granted additional --- permissions described in the GCC Runtime Library Exception, version --- 3.1, as published by the Free Software Foundation. --- --- You should have received a copy of the GNU General Public License and --- a copy of the GCC Runtime Library Exception along with this program; --- see the files COPYING3 and COPYING.RUNTIME respectively. If not, see --- . */ --- ---extern int __clzsi2 (int val); ---int ---__clzdi2 (long long val) ---{ --- if (val >> 32) --- { --- return __clzsi2 (val >> 32); --- } --- else --- { --- return __clzsi2 (val) + 32; --- } ---} --diff --git a/libgcc/config/nds32/lib2csrc-mculib/_clzsi2.c b/libgcc/config/nds32/lib2csrc-mculib/_clzsi2.c --deleted file mode 100644 --index 407caaf..0000000 ----- a/libgcc/config/nds32/lib2csrc-mculib/_clzsi2.c --+++ /dev/null --@@ -1,49 +0,0 @@ ---/* mculib libgcc routines of Andes NDS32 cpu for GNU compiler --- Copyright (C) 2012-2016 Free Software Foundation, Inc. --- Contributed by Andes Technology Corporation. --- --- This file is part of GCC. --- --- GCC is free software; you can redistribute it and/or modify it --- under the terms of the GNU General Public License as published --- by the Free Software Foundation; either version 3, or (at your --- option) any later version. --- --- GCC is distributed in the hope that it will be useful, but WITHOUT --- ANY WARRANTY; without even the implied warranty of MERCHANTABILITY --- or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public --- License for more details. --- --- Under Section 7 of GPL version 3, you are granted additional --- permissions described in the GCC Runtime Library Exception, version --- 3.1, as published by the Free Software Foundation. --- --- You should have received a copy of the GNU General Public License and --- a copy of the GCC Runtime Library Exception along with this program; --- see the files COPYING3 and COPYING.RUNTIME respectively. If not, see --- . */ --- ---int ---__clzsi2 (int val) ---{ --- int i = 32; --- int j = 16; --- int temp; --- --- for (; j; j >>= 1) --- { --- if (temp = val >> j) --- { --- if (j == 1) --- { --- return (i - 2); --- } --- else --- { --- i -= j; --- val = temp; --- } --- } --- } --- return (i - val); ---} --diff --git a/libgcc/config/nds32/linux-atomic.c b/libgcc/config/nds32/linux-atomic.c --new file mode 100644 --index 0000000..69f589b ----- /dev/null --+++ b/libgcc/config/nds32/linux-atomic.c --@@ -0,0 +1,282 @@ --+/* Linux-specific atomic operations for NDS32 Linux. --+ Copyright (C) 2012-2016 Free Software Foundation, Inc. --+ --+This file is free software; you can redistribute it and/or modify it --+under the terms of the GNU General Public License as published by the --+Free Software Foundation; either version 3, or (at your option) any --+later version. --+ --+This file 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. --+ --+Under Section 7 of GPL version 3, you are granted additional --+permissions described in the GCC Runtime Library Exception, version --+3.1, as published by the Free Software Foundation. --+ --+You should have received a copy of the GNU General Public License and --+a copy of the GCC Runtime Library Exception along with this program; --+see the files COPYING3 and COPYING.RUNTIME respectively. If not, see --+. */ --+ --+/* We implement byte, short and int versions of each atomic operation --+ using the kernel helper defined below. There is no support for --+ 64-bit operations yet. */ --+ --+/* This function copy form NDS32 Linux-kernal. */ --+static inline int --+__kernel_cmpxchg (int oldval, int newval, int *mem) --+{ --+ int temp1, temp2, temp3, offset; --+ --+ asm volatile ("msync\tall\n" --+ "movi\t%0, #0\n" --+ "1:\n" --+ "\tllw\t%1, [%4+%0]\n" --+ "\tsub\t%3, %1, %6\n" --+ "\tcmovz\t%2, %5, %3\n" --+ "\tcmovn\t%2, %1, %3\n" --+ "\tscw\t%2, [%4+%0]\n" --+ "\tbeqz\t%2, 1b\n" --+ : "=&r" (offset), "=&r" (temp3), "=&r" (temp2), "=&r" (temp1) --+ : "r" (mem), "r" (newval), "r" (oldval) : "memory"); --+ --+ return temp1; --+} --+ --+#define HIDDEN __attribute__ ((visibility ("hidden"))) --+ --+#ifdef __NDS32_EL__ --+#define INVERT_MASK_1 0 --+#define INVERT_MASK_2 0 --+#else --+#define INVERT_MASK_1 24 --+#define INVERT_MASK_2 16 --+#endif --+ --+#define MASK_1 0xffu --+#define MASK_2 0xffffu --+ --+#define FETCH_AND_OP_WORD(OP, PFX_OP, INF_OP) \ --+ int HIDDEN \ --+ __sync_fetch_and_##OP##_4 (int *ptr, int val) \ --+ { \ --+ int failure, tmp; \ --+ \ --+ do { \ --+ tmp = __atomic_load_n (ptr, __ATOMIC_SEQ_CST); \ --+ failure = __kernel_cmpxchg (tmp, PFX_OP (tmp INF_OP val), ptr); \ --+ } while (failure != 0); \ --+ \ --+ return tmp; \ --+ } --+ --+FETCH_AND_OP_WORD (add, , +) --+FETCH_AND_OP_WORD (sub, , -) --+FETCH_AND_OP_WORD (or, , |) --+FETCH_AND_OP_WORD (and, , &) --+FETCH_AND_OP_WORD (xor, , ^) --+FETCH_AND_OP_WORD (nand, ~, &) --+ --+#define NAME_oldval(OP, WIDTH) __sync_fetch_and_##OP##_##WIDTH --+#define NAME_newval(OP, WIDTH) __sync_##OP##_and_fetch_##WIDTH --+ --+/* Implement both __sync__and_fetch and __sync_fetch_and_ for --+ subword-sized quantities. */ --+ --+#define SUBWORD_SYNC_OP(OP, PFX_OP, INF_OP, TYPE, WIDTH, RETURN) \ --+ TYPE HIDDEN \ --+ NAME##_##RETURN (OP, WIDTH) (TYPE *ptr, TYPE val) \ --+ { \ --+ int *wordptr = (int *) ((unsigned long) ptr & ~3); \ --+ unsigned int mask, shift, oldval, newval; \ --+ int failure; \ --+ \ --+ shift = (((unsigned long) ptr & 3) << 3) ^ INVERT_MASK_##WIDTH; \ --+ mask = MASK_##WIDTH << shift; \ --+ \ --+ do { \ --+ oldval = __atomic_load_n (wordptr, __ATOMIC_SEQ_CST); \ --+ newval = ((PFX_OP (((oldval & mask) >> shift) \ --+ INF_OP (unsigned int) val)) << shift) & mask; \ --+ newval |= oldval & ~mask; \ --+ failure = __kernel_cmpxchg (oldval, newval, wordptr); \ --+ } while (failure != 0); \ --+ \ --+ return (RETURN & mask) >> shift; \ --+ } --+ --+ --+SUBWORD_SYNC_OP (add, , +, unsigned short, 2, oldval) --+SUBWORD_SYNC_OP (sub, , -, unsigned short, 2, oldval) --+SUBWORD_SYNC_OP (or, , |, unsigned short, 2, oldval) --+SUBWORD_SYNC_OP (and, , &, unsigned short, 2, oldval) --+SUBWORD_SYNC_OP (xor, , ^, unsigned short, 2, oldval) --+SUBWORD_SYNC_OP (nand, ~, &, unsigned short, 2, oldval) --+ --+SUBWORD_SYNC_OP (add, , +, unsigned char, 1, oldval) --+SUBWORD_SYNC_OP (sub, , -, unsigned char, 1, oldval) --+SUBWORD_SYNC_OP (or, , |, unsigned char, 1, oldval) --+SUBWORD_SYNC_OP (and, , &, unsigned char, 1, oldval) --+SUBWORD_SYNC_OP (xor, , ^, unsigned char, 1, oldval) --+SUBWORD_SYNC_OP (nand, ~, &, unsigned char, 1, oldval) --+ --+#define OP_AND_FETCH_WORD(OP, PFX_OP, INF_OP) \ --+ int HIDDEN \ --+ __sync_##OP##_and_fetch_4 (int *ptr, int val) \ --+ { \ --+ int tmp, failure; \ --+ \ --+ do { \ --+ tmp = __atomic_load_n (ptr, __ATOMIC_SEQ_CST); \ --+ failure = __kernel_cmpxchg (tmp, PFX_OP (tmp INF_OP val), ptr); \ --+ } while (failure != 0); \ --+ \ --+ return PFX_OP (tmp INF_OP val); \ --+ } --+ --+OP_AND_FETCH_WORD (add, , +) --+OP_AND_FETCH_WORD (sub, , -) --+OP_AND_FETCH_WORD (or, , |) --+OP_AND_FETCH_WORD (and, , &) --+OP_AND_FETCH_WORD (xor, , ^) --+OP_AND_FETCH_WORD (nand, ~, &) --+ --+SUBWORD_SYNC_OP (add, , +, unsigned short, 2, newval) --+SUBWORD_SYNC_OP (sub, , -, unsigned short, 2, newval) --+SUBWORD_SYNC_OP (or, , |, unsigned short, 2, newval) --+SUBWORD_SYNC_OP (and, , &, unsigned short, 2, newval) --+SUBWORD_SYNC_OP (xor, , ^, unsigned short, 2, newval) --+SUBWORD_SYNC_OP (nand, ~, &, unsigned short, 2, newval) --+ --+SUBWORD_SYNC_OP (add, , +, unsigned char, 1, newval) --+SUBWORD_SYNC_OP (sub, , -, unsigned char, 1, newval) --+SUBWORD_SYNC_OP (or, , |, unsigned char, 1, newval) --+SUBWORD_SYNC_OP (and, , &, unsigned char, 1, newval) --+SUBWORD_SYNC_OP (xor, , ^, unsigned char, 1, newval) --+SUBWORD_SYNC_OP (nand, ~, &, unsigned char, 1, newval) --+ --+int HIDDEN --+__sync_val_compare_and_swap_4 (int *ptr, int oldval, int newval) --+{ --+ int actual_oldval, fail; --+ --+ while (1) --+ { --+ actual_oldval = __atomic_load_n (ptr, __ATOMIC_SEQ_CST); --+ --+ if (oldval != actual_oldval) --+ return actual_oldval; --+ --+ fail = __kernel_cmpxchg (actual_oldval, newval, ptr); --+ --+ if (!fail) --+ return oldval; --+ } --+} --+ --+#define SUBWORD_VAL_CAS(TYPE, WIDTH) \ --+ TYPE HIDDEN \ --+ __sync_val_compare_and_swap_##WIDTH (TYPE *ptr, TYPE oldval, \ --+ TYPE newval) \ --+ { \ --+ int *wordptr = (int *)((unsigned long) ptr & ~3), fail; \ --+ unsigned int mask, shift, actual_oldval, actual_newval; \ --+ \ --+ shift = (((unsigned long) ptr & 3) << 3) ^ INVERT_MASK_##WIDTH; \ --+ mask = MASK_##WIDTH << shift; \ --+ \ --+ while (1) \ --+ { \ --+ actual_oldval = __atomic_load_n (wordptr, __ATOMIC_SEQ_CST); \ --+ \ --+ if (((actual_oldval & mask) >> shift) != (unsigned int) oldval) \ --+ return (actual_oldval & mask) >> shift; \ --+ \ --+ actual_newval = (actual_oldval & ~mask) \ --+ | (((unsigned int) newval << shift) & mask); \ --+ \ --+ fail = __kernel_cmpxchg (actual_oldval, actual_newval, \ --+ wordptr); \ --+ \ --+ if (!fail) \ --+ return oldval; \ --+ } \ --+ } --+ --+SUBWORD_VAL_CAS (unsigned short, 2) --+SUBWORD_VAL_CAS (unsigned char, 1) --+ --+typedef unsigned char bool; --+ --+bool HIDDEN --+__sync_bool_compare_and_swap_4 (int *ptr, int oldval, int newval) --+{ --+ int failure = __kernel_cmpxchg (oldval, newval, ptr); --+ return (failure == 0); --+} --+ --+#define SUBWORD_BOOL_CAS(TYPE, WIDTH) \ --+ bool HIDDEN \ --+ __sync_bool_compare_and_swap_##WIDTH (TYPE *ptr, TYPE oldval, \ --+ TYPE newval) \ --+ { \ --+ TYPE actual_oldval \ --+ = __sync_val_compare_and_swap_##WIDTH (ptr, oldval, newval); \ --+ return (oldval == actual_oldval); \ --+ } --+ --+SUBWORD_BOOL_CAS (unsigned short, 2) --+SUBWORD_BOOL_CAS (unsigned char, 1) --+ --+int HIDDEN --+__sync_lock_test_and_set_4 (int *ptr, int val) --+{ --+ int failure, oldval; --+ --+ do { --+ oldval = __atomic_load_n (ptr, __ATOMIC_SEQ_CST); --+ failure = __kernel_cmpxchg (oldval, val, ptr); --+ } while (failure != 0); --+ --+ return oldval; --+} --+ --+#define SUBWORD_TEST_AND_SET(TYPE, WIDTH) \ --+ TYPE HIDDEN \ --+ __sync_lock_test_and_set_##WIDTH (TYPE *ptr, TYPE val) \ --+ { \ --+ int failure; \ --+ unsigned int oldval, newval, shift, mask; \ --+ int *wordptr = (int *) ((unsigned long) ptr & ~3); \ --+ \ --+ shift = (((unsigned long) ptr & 3) << 3) ^ INVERT_MASK_##WIDTH; \ --+ mask = MASK_##WIDTH << shift; \ --+ \ --+ do { \ --+ oldval = __atomic_load_n (wordptr, __ATOMIC_SEQ_CST); \ --+ newval = (oldval & ~mask) \ --+ | (((unsigned int) val << shift) & mask); \ --+ failure = __kernel_cmpxchg (oldval, newval, wordptr); \ --+ } while (failure != 0); \ --+ \ --+ return (oldval & mask) >> shift; \ --+ } --+ --+SUBWORD_TEST_AND_SET (unsigned short, 2) --+SUBWORD_TEST_AND_SET (unsigned char, 1) --+ --+#define SYNC_LOCK_RELEASE(TYPE, WIDTH) \ --+ void HIDDEN \ --+ __sync_lock_release_##WIDTH (TYPE *ptr) \ --+ { \ --+ /* All writes before this point must be seen before we release \ --+ the lock itself. */ \ --+ __builtin_nds32_msync_all (); \ --+ *ptr = 0; \ --+ } --+ --+SYNC_LOCK_RELEASE (int, 4) --+SYNC_LOCK_RELEASE (short, 2) --+SYNC_LOCK_RELEASE (char, 1) --diff --git a/libgcc/config/nds32/linux-unwind.h b/libgcc/config/nds32/linux-unwind.h --new file mode 100644 --index 0000000..921edf9 ----- /dev/null --+++ b/libgcc/config/nds32/linux-unwind.h --@@ -0,0 +1,156 @@ --+/* DWARF2 EH unwinding support for NDS32 Linux signal frame. --+ Copyright (C) 2014-2015 Free Software Foundation, Inc. --+ Contributed by Andes Technology Corporation. --+ --+ This file is part of GCC. --+ --+ GCC is free software; you can redistribute it and/or modify it --+ under the terms of the GNU General Public License as published --+ by the Free Software Foundation; either version 3, or (at your --+ option) any later version. --+ --+ GCC is distributed in the hope that it will be useful, but WITHOUT --+ ANY WARRANTY; without even the implied warranty of MERCHANTABILITY --+ or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public --+ License for more details. --+ --+ Under Section 7 of GPL version 3, you are granted additional --+ permissions described in the GCC Runtime Library Exception, version --+ 3.1, as published by the Free Software Foundation. --+ --+ You should have received a copy of the GNU General Public License and --+ a copy of the GCC Runtime Library Exception along with this program; --+ see the files COPYING3 and COPYING.RUNTIME respectively. If not, see --+ . */ --+ --+#ifndef inhibit_libc --+ --+/* Do code reading to identify a signal frame, and set the frame --+ state data appropriately. See unwind-dw2.c for the structs. --+ The corresponding bits in the Linux kernel are in --+ arch/nds32/kernel/signal.c. */ --+ --+#include --+#include --+ --+/* Exactly the same layout as the kernel structures, unique names. */ --+ --+/* arch/nds32/kernel/signal.c */ --+struct _sigframe { --+ struct ucontext uc; --+ unsigned long retcode; --+}; --+ --+struct _rt_sigframe { --+ siginfo_t info; --+ struct _sigframe sig; --+}; --+#define SIGRETURN 0xeb0e0a64 --+#define RT_SIGRETURN 0xab150a64 --+ --+#define MD_FALLBACK_FRAME_STATE_FOR nds32_fallback_frame_state --+ --+/* This function is supposed to be invoked by uw_frame_state_for() --+ when there is no unwind data available. --+ --+ Generally, given the _Unwind_Context CONTEXT for a stack frame, --+ we need to look up its caller and decode information into FS. --+ However, if the exception handling happens within a signal handler, --+ the return address of signal handler is a special module, which --+ contains signal return syscall and has no FDE in the .eh_frame section. --+ We need to implement MD_FALLBACK_FRAME_STATE_FOR so that we can --+ unwind through signal frames. */ --+static _Unwind_Reason_Code --+nds32_fallback_frame_state (struct _Unwind_Context *context, --+ _Unwind_FrameState *fs) --+{ --+ u_int32_t *pc = (u_int32_t *) context->ra; --+ struct sigcontext *sc_; --+ _Unwind_Ptr new_cfa; --+ --+#ifdef __NDS32_EB__ --+#error "Signal handler is not supported for force unwind." --+#endif --+ --+ if ((_Unwind_Ptr) pc & 3) --+ return _URC_END_OF_STACK; --+ --+ /* Check if we are going through a signal handler. --+ See arch/nds32/kernel/signal.c implementation. --+ SWI_SYS_SIGRETURN -> (0xeb0e0a64) --+ SWI_SYS_RT_SIGRETURN -> (0xab150a64) --+ FIXME: Currently we only handle little endian (EL) case. */ --+ if (pc[0] == SIGRETURN) --+ { --+ /* Using '_sigfame' memory address to locate kernal's sigcontext. --+ The sigcontext structures in arch/nds32/include/asm/sigcontext.h. */ --+ struct _sigframe *rt_; --+ rt_ = context->cfa; --+ sc_ = &rt_->uc.uc_mcontext; --+ } --+ else if (pc[0] == RT_SIGRETURN) --+ { --+ /* Using '_sigfame' memory address to locate kernal's sigcontext. */ --+ struct _rt_sigframe *rt_; --+ rt_ = context->cfa; --+ sc_ = &rt_->sig.uc.uc_mcontext; --+ } --+ else --+ return _URC_END_OF_STACK; --+ --+ /* Update cfa from sigcontext. */ --+ new_cfa = (_Unwind_Ptr) sc_; --+ fs->regs.cfa_how = CFA_REG_OFFSET; --+ fs->regs.cfa_reg = STACK_POINTER_REGNUM; --+ fs->regs.cfa_offset = new_cfa - (_Unwind_Ptr) context->cfa; --+ --+#define NDS32_PUT_FS_REG(NUM, NAME) \ --+ (fs->regs.reg[NUM].how = REG_SAVED_OFFSET, \ --+ fs->regs.reg[NUM].loc.offset = (_Unwind_Ptr) &(sc_->NAME) - new_cfa) --+ --+ /* Restore all registers value. */ --+ NDS32_PUT_FS_REG (0, nds32_r0); --+ NDS32_PUT_FS_REG (1, nds32_r1); --+ NDS32_PUT_FS_REG (2, nds32_r2); --+ NDS32_PUT_FS_REG (3, nds32_r3); --+ NDS32_PUT_FS_REG (4, nds32_r4); --+ NDS32_PUT_FS_REG (5, nds32_r5); --+ NDS32_PUT_FS_REG (6, nds32_r6); --+ NDS32_PUT_FS_REG (7, nds32_r7); --+ NDS32_PUT_FS_REG (8, nds32_r8); --+ NDS32_PUT_FS_REG (9, nds32_r9); --+ NDS32_PUT_FS_REG (10, nds32_r10); --+ NDS32_PUT_FS_REG (11, nds32_r11); --+ NDS32_PUT_FS_REG (12, nds32_r12); --+ NDS32_PUT_FS_REG (13, nds32_r13); --+ NDS32_PUT_FS_REG (14, nds32_r14); --+ NDS32_PUT_FS_REG (15, nds32_r15); --+ NDS32_PUT_FS_REG (16, nds32_r16); --+ NDS32_PUT_FS_REG (17, nds32_r17); --+ NDS32_PUT_FS_REG (18, nds32_r18); --+ NDS32_PUT_FS_REG (19, nds32_r19); --+ NDS32_PUT_FS_REG (20, nds32_r20); --+ NDS32_PUT_FS_REG (21, nds32_r21); --+ NDS32_PUT_FS_REG (22, nds32_r22); --+ NDS32_PUT_FS_REG (23, nds32_r23); --+ NDS32_PUT_FS_REG (24, nds32_r24); --+ NDS32_PUT_FS_REG (25, nds32_r25); --+ --+ NDS32_PUT_FS_REG (28, nds32_fp); --+ NDS32_PUT_FS_REG (29, nds32_gp); --+ NDS32_PUT_FS_REG (30, nds32_lp); --+ NDS32_PUT_FS_REG (31, nds32_sp); --+ --+ /* Restore PC, point to trigger signal instruction. */ --+ NDS32_PUT_FS_REG (32, nds32_ipc); --+ --+#undef NDS32_PUT_FS_REG --+ --+ /* The retaddr is PC, use PC to find FDE. */ --+ fs->retaddr_column = 32; --+ fs->signal_frame = 1; --+ --+ return _URC_NO_REASON; --+} --+ --+#endif --diff --git a/libgcc/config/nds32/sfp-machine.h b/libgcc/config/nds32/sfp-machine.h --index d822898..930a32e 100644 ----- a/libgcc/config/nds32/sfp-machine.h --+++ b/libgcc/config/nds32/sfp-machine.h --@@ -76,6 +76,25 @@ typedef int __gcc_CMPtype __attribute__ ((mode (__libgcc_cmp_return__))); -- R##_c = FP_CLS_NAN; \ -- } while (0) -- --+#ifdef NDS32_ABI_2FP_PLUS --+#define FP_RND_NEAREST 0x0 --+#define FP_RND_PINF 0x1 --+#define FP_RND_MINF 0x2 --+#define FP_RND_ZERO 0x3 --+#define FP_RND_MASK 0x3 --+ --+#define _FP_DECL_EX \ --+ unsigned long int _fcsr __attribute__ ((unused)) = FP_RND_NEAREST --+ --+#define FP_INIT_ROUNDMODE \ --+ do { \ --+ _fcsr = __builtin_nds32_fmfcsr (); \ --+ } while (0) --+ --+#define FP_ROUNDMODE (_fcsr & FP_RND_MASK) --+ --+#endif --+ -- /* Not checked. */ -- #define _FP_TININESS_AFTER_ROUNDING 0 -- --diff --git a/libgcc/config/nds32/t-nds32 b/libgcc/config/nds32/t-nds32 --index 20c8a3f..4e58b1b 100644 ----- a/libgcc/config/nds32/t-nds32 --+++ b/libgcc/config/nds32/t-nds32 --@@ -26,33 +26,22 @@ -- # Make sure the linker script include these two objects -- # for building .ctors/.dtors sections. -- ---# Use -DCRT_BEGIN to create beginning parts of .init and .fini content ---# Make sure you are building crtbegin1.o with -O0 optimization, ---# otherwise the static function will be optimized out --+# Use -DCRT_BEGIN to create beginning parts of .init and .fini content. -- crtbegin1.o: $(srcdir)/config/nds32/initfini.c $(GCC_PASSES) $(CONFIG_H) -- $(GCC_FOR_TARGET) $(INCLUDES) \ -- $(CFLAGS) \ -- -DCRT_BEGIN \ -- -finhibit-size-directive -fno-inline-functions \ --- -O0 -c $(srcdir)/config/nds32/initfini.c -o crtbegin1.o --+ -fno-toplevel-reorder \ --+ -Os -c $(srcdir)/config/nds32/initfini.c -o crtbegin1.o -- ---# Use -DCRT_END to create ending parts of .init and .fini content ---# Make sure you are building crtend1.o with -O0 optimization, ---# otherwise the static function will be optimized out --+# Use -DCRT_END to create ending parts of .init and .fini content. -- crtend1.o: $(srcdir)/config/nds32/initfini.c $(GCC_PASSES) $(CONFIG_H) -- $(GCC_FOR_TARGET) $(INCLUDES) \ -- $(CFLAGS) \ -- -DCRT_END \ -- -finhibit-size-directive -fno-inline-functions \ --- -O0 -c $(srcdir)/config/nds32/initfini.c -o crtend1.o --- ---# Use this rule if and only if your crt0.o does not come from library ---# Also, be sure to add 'crtzero.o' in extra_parts in libgcc/config.host ---# and change STARTFILE_SPEC in nds32.h ---# ---#crtzero.o: $(srcdir)/config/nds32/crtzero.S $(GCC_PASSES) $(CONFIG_H) ---# $(GCC_FOR_TARGET) $(INCLUDES) \ ---# -c $(srcdir)/config/nds32/crtzero.S -o crtzero.o --- --+ -fno-toplevel-reorder \ --+ -Os -c $(srcdir)/config/nds32/initfini.c -o crtend1.o -- -- # ------------------------------------------------------------------------ --diff --git a/libgcc/config/nds32/t-nds32-mculib b/libgcc/config/nds32/t-nds32-glibc --similarity index 50% --rename from libgcc/config/nds32/t-nds32-mculib --rename to libgcc/config/nds32/t-nds32-glibc --index b4f7b4c..385644b 100644 ----- a/libgcc/config/nds32/t-nds32-mculib --+++ b/libgcc/config/nds32/t-nds32-glibc --@@ -1,4 +1,4 @@ ---# Rules of mculib library makefile of Andes NDS32 cpu for GNU compiler --+# Rules of glibc library makefile of Andes NDS32 cpu for GNU compiler -- # Copyright (C) 2012-2016 Free Software Foundation, Inc. -- # Contributed by Andes Technology Corporation. -- # --@@ -19,59 +19,16 @@ -- # . -- -- # Compiler flags to use when compiling 'libgcc2.c' ---HOST_LIBGCC2_CFLAGS = -Os --+HOST_LIBGCC2_CFLAGS = -O2 -fPIC -fwrapv --+LIB2ADD += $(srcdir)/config/nds32/linux-atomic.c -- --- ---LIB1ASMSRC = nds32/lib1asmsrc-mculib.S --- ---LIB1ASMFUNCS = \ --- _addsub_sf \ --- _sf_to_si \ --- _divsi3 \ --- _divdi3 \ --- _modsi3 \ --- _moddi3 \ --- _mulsi3 \ --- _udivsi3 \ --- _udivdi3 \ --- _udivmoddi4 \ --- _umodsi3 \ --- _umoddi3 \ --- _muldi3 \ --- _addsub_df \ --- _mul_sf \ --- _mul_df \ --- _div_sf \ --- _div_df \ --- _negate_sf \ --- _negate_df \ --- _sf_to_df \ --- _df_to_sf \ --- _df_to_si \ --- _fixsfdi \ --- _fixdfdi \ --- _fixunssfsi \ --- _fixunsdfsi \ --- _fixunssfdi \ --- _fixunsdfdi \ --- _si_to_sf \ --- _si_to_df \ --- _floatdisf \ --- _floatdidf \ --- _floatunsisf \ --- _floatunsidf \ --- _floatundisf \ --- _floatundidf \ --- _compare_sf \ --- _compare_df \ --- _unord_sf \ --- _unord_df --+#LIB1ASMSRC = nds32/lib1asmsrc-newlib.S --+#LIB1ASMFUNCS = _divsi3 _modsi3 _udivsi3 _umodsi3 -- -- # List of functions not to build from libgcc2.c. ---LIB2FUNCS_EXCLUDE = _clzsi2 _clzdi2 --+#LIB2FUNCS_EXCLUDE = _clzsi2 -- -- # List of extra C and assembler files(*.S) to add to static libgcc2. ---LIB2ADD_ST += $(srcdir)/config/nds32/lib2csrc-mculib/_clzsi2.c ---LIB2ADD_ST += $(srcdir)/config/nds32/lib2csrc-mculib/_clzdi2.c --+#LIB2ADD_ST += $(srcdir)/config/nds32/lib2csrc-newlib/_clzsi2.c -- -- # ------------------------------------------------------------------------ --diff --git a/libgcc/config/nds32/t-nds32-isr b/libgcc/config/nds32/t-nds32-isr --index 62b6867..6493838 100644 ----- a/libgcc/config/nds32/t-nds32-isr --+++ b/libgcc/config/nds32/t-nds32-isr --@@ -23,11 +23,15 @@ -- # Makfile fragment rules for libnds32_isr.a to support ISR attribute extension -- ############################################################################### -- ---# basic flags setting ---ISR_CFLAGS = $(CFLAGS) -c --- ---# the object files we would like to create ---LIBNDS32_ISR_16B_OBJS = \ --+# Basic flags setting. --+ifneq ($(filter -mext-dsp,$(CFLAGS)),) --+ISR_CFLAGS = $(CFLAGS) -mno-force-no-ext-zol -mext-zol -c --+else --+ISR_CFLAGS = $(CFLAGS) -mno-force-no-ext-zol -c --+endif --+ --+# The object files we would like to create. --+LIBNDS32_ISR_VEC_OBJS = \ -- vec_vid00.o vec_vid01.o vec_vid02.o vec_vid03.o \ -- vec_vid04.o vec_vid05.o vec_vid06.o vec_vid07.o \ -- vec_vid08.o vec_vid09.o vec_vid10.o vec_vid11.o \ --@@ -46,40 +50,9 @@ LIBNDS32_ISR_16B_OBJS = \ -- vec_vid60.o vec_vid61.o vec_vid62.o vec_vid63.o \ -- vec_vid64.o vec_vid65.o vec_vid66.o vec_vid67.o \ -- vec_vid68.o vec_vid69.o vec_vid70.o vec_vid71.o \ --- vec_vid72.o \ --- excp_isr_ps_nn.o excp_isr_ps_ns.o excp_isr_ps_nr.o \ --- excp_isr_sa_nn.o excp_isr_sa_ns.o excp_isr_sa_nr.o \ --- intr_isr_ps_nn.o intr_isr_ps_ns.o intr_isr_ps_nr.o \ --- intr_isr_sa_nn.o intr_isr_sa_ns.o intr_isr_sa_nr.o \ --- reset.o --- ---LIBNDS32_ISR_4B_OBJS = \ --- vec_vid00_4b.o vec_vid01_4b.o vec_vid02_4b.o vec_vid03_4b.o \ --- vec_vid04_4b.o vec_vid05_4b.o vec_vid06_4b.o vec_vid07_4b.o \ --- vec_vid08_4b.o vec_vid09_4b.o vec_vid10_4b.o vec_vid11_4b.o \ --- vec_vid12_4b.o vec_vid13_4b.o vec_vid14_4b.o vec_vid15_4b.o \ --- vec_vid16_4b.o vec_vid17_4b.o vec_vid18_4b.o vec_vid19_4b.o \ --- vec_vid20_4b.o vec_vid21_4b.o vec_vid22_4b.o vec_vid23_4b.o \ --- vec_vid24_4b.o vec_vid25_4b.o vec_vid26_4b.o vec_vid27_4b.o \ --- vec_vid28_4b.o vec_vid29_4b.o vec_vid30_4b.o vec_vid31_4b.o \ --- vec_vid32_4b.o vec_vid33_4b.o vec_vid34_4b.o vec_vid35_4b.o \ --- vec_vid36_4b.o vec_vid37_4b.o vec_vid38_4b.o vec_vid39_4b.o \ --- vec_vid40_4b.o vec_vid41_4b.o vec_vid42_4b.o vec_vid43_4b.o \ --- vec_vid44_4b.o vec_vid45_4b.o vec_vid46_4b.o vec_vid47_4b.o \ --- vec_vid48_4b.o vec_vid49_4b.o vec_vid50_4b.o vec_vid51_4b.o \ --- vec_vid52_4b.o vec_vid53_4b.o vec_vid54_4b.o vec_vid55_4b.o \ --- vec_vid56_4b.o vec_vid57_4b.o vec_vid58_4b.o vec_vid59_4b.o \ --- vec_vid60_4b.o vec_vid61_4b.o vec_vid62_4b.o vec_vid63_4b.o \ --- vec_vid64_4b.o vec_vid65_4b.o vec_vid66_4b.o vec_vid67_4b.o \ --- vec_vid68_4b.o vec_vid69_4b.o vec_vid70_4b.o vec_vid71_4b.o \ --- vec_vid72_4b.o \ --- excp_isr_ps_nn_4b.o excp_isr_ps_ns_4b.o excp_isr_ps_nr_4b.o \ --- excp_isr_sa_nn_4b.o excp_isr_sa_ns_4b.o excp_isr_sa_nr_4b.o \ --- intr_isr_ps_nn_4b.o intr_isr_ps_ns_4b.o intr_isr_ps_nr_4b.o \ --- intr_isr_sa_nn_4b.o intr_isr_sa_ns_4b.o intr_isr_sa_nr_4b.o \ --- reset_4b.o --+ vec_vid72.o -- ---LIBNDS32_ISR_COMMON_OBJS = \ --+LIBNDS32_ISR_JMP_OBJS = \ -- jmptbl_vid00.o jmptbl_vid01.o jmptbl_vid02.o jmptbl_vid03.o \ -- jmptbl_vid04.o jmptbl_vid05.o jmptbl_vid06.o jmptbl_vid07.o \ -- jmptbl_vid08.o jmptbl_vid09.o jmptbl_vid10.o jmptbl_vid11.o \ --@@ -98,29 +71,32 @@ LIBNDS32_ISR_COMMON_OBJS = \ -- jmptbl_vid60.o jmptbl_vid61.o jmptbl_vid62.o jmptbl_vid63.o \ -- jmptbl_vid64.o jmptbl_vid65.o jmptbl_vid66.o jmptbl_vid67.o \ -- jmptbl_vid68.o jmptbl_vid69.o jmptbl_vid70.o jmptbl_vid71.o \ --- jmptbl_vid72.o \ --+ jmptbl_vid72.o --+ --+LIBNDS32_ISR_COMMON_OBJS = \ --+ excp_isr_ps_nn.o excp_isr_ps_ns.o excp_isr_ps_nr.o \ --+ excp_isr_sa_nn.o excp_isr_sa_ns.o excp_isr_sa_nr.o \ --+ intr_isr_ps_nn.o intr_isr_ps_ns.o intr_isr_ps_nr.o \ --+ intr_isr_sa_nn.o intr_isr_sa_ns.o intr_isr_sa_nr.o \ --+ reset.o \ -- nmih.o \ -- wrh.o -- ---LIBNDS32_ISR_COMPLETE_OBJS = $(LIBNDS32_ISR_16B_OBJS) $(LIBNDS32_ISR_4B_OBJS) $(LIBNDS32_ISR_COMMON_OBJS) --- --+LIBNDS32_ISR_COMPLETE_OBJS = $(LIBNDS32_ISR_VEC_OBJS) $(LIBNDS32_ISR_JMP_OBJS) $(LIBNDS32_ISR_COMMON_OBJS) -- ---# Build common objects for ISR library ---nmih.o: $(srcdir)/config/nds32/isr-library/nmih.S --- $(GCC_FOR_TARGET) $(ISR_CFLAGS) $(srcdir)/config/nds32/isr-library/nmih.S -o nmih.o -- ---wrh.o: $(srcdir)/config/nds32/isr-library/wrh.S --- $(GCC_FOR_TARGET) $(ISR_CFLAGS) $(srcdir)/config/nds32/isr-library/wrh.S -o wrh.o -- ---jmptbl_vid%.o: $(srcdir)/config/nds32/isr-library/jmptbl_vid%.S --+# Build vector vid objects for ISR library. --+vec_vid%.o: $(srcdir)/config/nds32/isr-library/vec_vid%.S -- $(GCC_FOR_TARGET) $(ISR_CFLAGS) $< -o $@ -- -- --- ---# Build 16b version objects for ISR library. (no "_4b" postfix string) ---vec_vid%.o: $(srcdir)/config/nds32/isr-library/vec_vid%.S --+# Build jump table objects for ISR library. --+jmptbl_vid%.o: $(srcdir)/config/nds32/isr-library/jmptbl_vid%.S -- $(GCC_FOR_TARGET) $(ISR_CFLAGS) $< -o $@ -- --+ --+# Build commen objects for ISR library. -- excp_isr_ps_nn.o: $(srcdir)/config/nds32/isr-library/excp_isr.S -- $(GCC_FOR_TARGET) $(ISR_CFLAGS) $(srcdir)/config/nds32/isr-library/excp_isr.S -o excp_isr_ps_nn.o -- --@@ -160,48 +136,12 @@ intr_isr_sa_nr.o: $(srcdir)/config/nds32/isr-library/intr_isr.S -- reset.o: $(srcdir)/config/nds32/isr-library/reset.S -- $(GCC_FOR_TARGET) $(ISR_CFLAGS) $(srcdir)/config/nds32/isr-library/reset.S -o reset.o -- ---# Build 4b version objects for ISR library. ---vec_vid%_4b.o: $(srcdir)/config/nds32/isr-library/vec_vid%_4b.S --- $(GCC_FOR_TARGET) $(ISR_CFLAGS) $< -o $@ --- ---excp_isr_ps_nn_4b.o: $(srcdir)/config/nds32/isr-library/excp_isr_4b.S --- $(GCC_FOR_TARGET) $(ISR_CFLAGS) $(srcdir)/config/nds32/isr-library/excp_isr_4b.S -o excp_isr_ps_nn_4b.o --- ---excp_isr_ps_ns_4b.o: $(srcdir)/config/nds32/isr-library/excp_isr_4b.S --- $(GCC_FOR_TARGET) $(ISR_CFLAGS) -DNDS32_NESTED $(srcdir)/config/nds32/isr-library/excp_isr_4b.S -o excp_isr_ps_ns_4b.o --- ---excp_isr_ps_nr_4b.o: $(srcdir)/config/nds32/isr-library/excp_isr_4b.S --- $(GCC_FOR_TARGET) $(ISR_CFLAGS) -DNDS32_NESTED_READY $(srcdir)/config/nds32/isr-library/excp_isr_4b.S -o excp_isr_ps_nr_4b.o --- ---excp_isr_sa_nn_4b.o: $(srcdir)/config/nds32/isr-library/excp_isr_4b.S --- $(GCC_FOR_TARGET) $(ISR_CFLAGS) -DNDS32_SAVE_ALL_REGS $(srcdir)/config/nds32/isr-library/excp_isr_4b.S -o excp_isr_sa_nn_4b.o --- ---excp_isr_sa_ns_4b.o: $(srcdir)/config/nds32/isr-library/excp_isr_4b.S --- $(GCC_FOR_TARGET) $(ISR_CFLAGS) -DNDS32_SAVE_ALL_REGS -DNDS32_NESTED $(srcdir)/config/nds32/isr-library/excp_isr_4b.S -o excp_isr_sa_ns_4b.o --- ---excp_isr_sa_nr_4b.o: $(srcdir)/config/nds32/isr-library/excp_isr_4b.S --- $(GCC_FOR_TARGET) $(ISR_CFLAGS) -DNDS32_SAVE_ALL_REGS -DNDS32_NESTED_READY $(srcdir)/config/nds32/isr-library/excp_isr_4b.S -o excp_isr_sa_nr_4b.o --- ---intr_isr_ps_nn_4b.o: $(srcdir)/config/nds32/isr-library/intr_isr_4b.S --- $(GCC_FOR_TARGET) $(ISR_CFLAGS) $(srcdir)/config/nds32/isr-library/intr_isr_4b.S -o intr_isr_ps_nn_4b.o --- ---intr_isr_ps_ns_4b.o: $(srcdir)/config/nds32/isr-library/intr_isr_4b.S --- $(GCC_FOR_TARGET) $(ISR_CFLAGS) -DNDS32_NESTED $(srcdir)/config/nds32/isr-library/intr_isr_4b.S -o intr_isr_ps_ns_4b.o --- ---intr_isr_ps_nr_4b.o: $(srcdir)/config/nds32/isr-library/intr_isr_4b.S --- $(GCC_FOR_TARGET) $(ISR_CFLAGS) -DNDS32_NESTED_READY $(srcdir)/config/nds32/isr-library/intr_isr_4b.S -o intr_isr_ps_nr_4b.o --- ---intr_isr_sa_nn_4b.o: $(srcdir)/config/nds32/isr-library/intr_isr_4b.S --- $(GCC_FOR_TARGET) $(ISR_CFLAGS) -DNDS32_SAVE_ALL_REGS $(srcdir)/config/nds32/isr-library/intr_isr_4b.S -o intr_isr_sa_nn_4b.o --- ---intr_isr_sa_ns_4b.o: $(srcdir)/config/nds32/isr-library/intr_isr_4b.S --- $(GCC_FOR_TARGET) $(ISR_CFLAGS) -DNDS32_SAVE_ALL_REGS -DNDS32_NESTED $(srcdir)/config/nds32/isr-library/intr_isr_4b.S -o intr_isr_sa_ns_4b.o --+nmih.o: $(srcdir)/config/nds32/isr-library/nmih.S --+ $(GCC_FOR_TARGET) $(ISR_CFLAGS) $(srcdir)/config/nds32/isr-library/nmih.S -o nmih.o -- ---intr_isr_sa_nr_4b.o: $(srcdir)/config/nds32/isr-library/intr_isr_4b.S --- $(GCC_FOR_TARGET) $(ISR_CFLAGS) -DNDS32_SAVE_ALL_REGS -DNDS32_NESTED_READY $(srcdir)/config/nds32/isr-library/intr_isr_4b.S -o intr_isr_sa_nr_4b.o --+wrh.o: $(srcdir)/config/nds32/isr-library/wrh.S --+ $(GCC_FOR_TARGET) $(ISR_CFLAGS) $(srcdir)/config/nds32/isr-library/wrh.S -o wrh.o -- ---reset_4b.o: $(srcdir)/config/nds32/isr-library/reset_4b.S --- $(GCC_FOR_TARGET) $(ISR_CFLAGS) $(srcdir)/config/nds32/isr-library/reset_4b.S -o reset_4b.o -- -- -- # The rule to create libnds32_isr.a file --diff --git a/libgcc/config/nds32/t-nds32-newlib b/libgcc/config/nds32/t-nds32-newlib --index e4af03e..c356b60 100644 ----- a/libgcc/config/nds32/t-nds32-newlib --+++ b/libgcc/config/nds32/t-nds32-newlib --@@ -19,7 +19,7 @@ -- # . -- -- # Compiler flags to use when compiling 'libgcc2.c' ---HOST_LIBGCC2_CFLAGS = -O2 --+HOST_LIBGCC2_CFLAGS = -O2 -fwrapv -- -- -- #LIB1ASMSRC = nds32/lib1asmsrc-newlib.S -diff --git a/util/crossgcc/patches/gcc-6.3.0_no-p-var.patch b/util/crossgcc/patches/gcc-6.3.0_no-p-var.patch -deleted file mode 100644 -index 0600a66cd1..0000000000 ---- a/util/crossgcc/patches/gcc-6.3.0_no-p-var.patch -+++ /dev/null -@@ -1,15 +0,0 @@ ----- gcc-6.3.0/gcc/ada/gcc-interface/Makefile.in.orig 2017-07-17 12:52:05.541815635 +0200 --+++ gcc-6.3.0/gcc/ada/gcc-interface/Makefile.in 2017-07-17 12:52:18.693764268 +0200 --@@ -2637,10 +2637,10 @@ -- # stamp target in the parent directory whenever gnat1 is rebuilt -- -- # Likewise for the tools ---../../gnatmake$(exeext): $(P) b_gnatm.o $(GNATMAKE_OBJS) --+../../gnatmake$(exeext): b_gnatm.o $(GNATMAKE_OBJS) -- +$(GCC_LINK) $(ALL_CFLAGS) -o $@ b_gnatm.o $(GNATMAKE_OBJS) $(TOOLS_LIBS) $(TOOLS1_LIBS) -- ---../../gnatlink$(exeext): $(P) b_gnatl.o $(GNATLINK_OBJS) --+../../gnatlink$(exeext): b_gnatl.o $(GNATLINK_OBJS) -- +$(GCC_LINK) $(ALL_CFLAGS) -o $@ b_gnatl.o $(GNATLINK_OBJS) $(TOOLS_LIBS) $(TOOLS1_LIBS) -- -- ../stamp-gnatlib-$(RTSDIR): -diff --git a/util/crossgcc/patches/gcc-6.3.0_pointer_integer.patch b/util/crossgcc/patches/gcc-6.3.0_pointer_integer.patch -deleted file mode 100644 -index f34d6cc36e..0000000000 ---- a/util/crossgcc/patches/gcc-6.3.0_pointer_integer.patch -+++ /dev/null -@@ -1,27 +0,0 @@ --From 8db2cf6353c13f2a84cbe49b689654897906c499 Mon Sep 17 00:00:00 2001 --From: kyukhin --Date: Sat, 3 Sep 2016 10:57:05 +0000 --Subject: [PATCH] gcc/ * ubsan.c (ubsan_use_new_style_p): Fix check for empty -- string. -- --git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@239971 138bc75d-0d04-0410-961f-82ee72b054a4 ----- -- gcc/ubsan.c | 2 +- -- 2 files changed, 5 insertions(+), 1 deletion(-) -- --diff --git a/gcc/ubsan.c b/gcc/ubsan.c --index 5cbc98dbabb..d3bd8e3393d 100644 ----- a/gcc/ubsan.c --+++ b/gcc/ubsan.c --@@ -1469,7 +1469,7 @@ ubsan_use_new_style_p (location_t loc) -- -- expanded_location xloc = expand_location (loc); -- if (xloc.file == NULL || strncmp (xloc.file, "\1", 2) == 0 --- || xloc.file == '\0' || xloc.file[0] == '\xff' --+ || xloc.file[0] == '\0' || xloc.file[0] == '\xff' -- || xloc.file[1] == '\xff') -- return false; -- ---- --2.13.0 -- -diff --git a/util/crossgcc/patches/gcc-6.3.0_riscv.patch b/util/crossgcc/patches/gcc-6.3.0_riscv.patch -deleted file mode 100644 -index a60511362a..0000000000 ---- a/util/crossgcc/patches/gcc-6.3.0_riscv.patch -+++ /dev/null -@@ -1,10521 +0,0 @@ --diff --git original-gcc/gcc/common/config/riscv/riscv-common.c gcc-6.3.0/gcc/common/config/riscv/riscv-common.c --new file mode 100644 --index 00000000000..50f1485f87a ----- /dev/null --+++ gcc-6.3.0/gcc/common/config/riscv/riscv-common.c --@@ -0,0 +1,131 @@ --+/* Common hooks for RISC-V. --+ Copyright (C) 2016 Free Software Foundation, Inc. --+ --+This file is part of GCC. --+ --+GCC is free software; you can redistribute it and/or modify --+it under the terms of the GNU General Public License as published by --+the Free Software Foundation; either version 3, or (at your option) --+any later version. --+ --+GCC is distributed in the hope that it will be useful, --+but WITHOUT ANY WARRANTY; without even the implied warranty of --+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the --+GNU General Public License for more details. --+ --+You should have received a copy of the GNU General Public License --+along with GCC; see the file COPYING3. If not see --+. */ --+ --+#include "config.h" --+#include "system.h" --+#include "coretypes.h" --+#include "tm.h" --+#include "common/common-target.h" --+#include "common/common-target-def.h" --+#include "opts.h" --+#include "flags.h" --+#include "diagnostic-core.h" --+ --+/* Parse a RISC-V ISA string into an option mask. */ --+ --+static void --+riscv_parse_arch_string (const char *isa, int *flags, location_t loc) --+{ --+ const char *p = isa; --+ --+ if (strncmp (p, "rv32", 4) == 0) --+ *flags &= ~MASK_64BIT, p += 4; --+ else if (strncmp (p, "rv64", 4) == 0) --+ *flags |= MASK_64BIT, p += 4; --+ else --+ { --+ error_at (loc, "-march=%s: ISA string must begin with rv32 or rv64", isa); --+ return; --+ } --+ --+ if (*p == 'g') --+ { --+ p++; --+ --+ *flags |= MASK_MUL; --+ *flags |= MASK_ATOMIC; --+ *flags |= MASK_HARD_FLOAT; --+ *flags |= MASK_DOUBLE_FLOAT; --+ } --+ else if (*p == 'i') --+ { --+ p++; --+ --+ *flags &= ~MASK_MUL; --+ if (*p == 'm') --+ *flags |= MASK_MUL, p++; --+ --+ *flags &= ~MASK_ATOMIC; --+ if (*p == 'a') --+ *flags |= MASK_ATOMIC, p++; --+ --+ *flags &= ~(MASK_HARD_FLOAT | MASK_DOUBLE_FLOAT); --+ if (*p == 'f') --+ { --+ *flags |= MASK_HARD_FLOAT, p++; --+ --+ if (*p == 'd') --+ { --+ *flags |= MASK_DOUBLE_FLOAT; --+ p++; --+ } --+ } --+ } --+ else --+ { --+ error_at (loc, "-march=%s: invalid ISA string", isa); --+ return; --+ } --+ --+ *flags &= ~MASK_RVC; --+ if (*p == 'c') --+ *flags |= MASK_RVC, p++; --+ --+ if (*p) --+ { --+ error_at (loc, "-march=%s: unsupported ISA substring %qs", isa, p); --+ return; --+ } --+} --+ --+/* Implement TARGET_HANDLE_OPTION. */ --+ --+static bool --+riscv_handle_option (struct gcc_options *opts, --+ struct gcc_options *opts_set ATTRIBUTE_UNUSED, --+ const struct cl_decoded_option *decoded, --+ location_t loc) --+{ --+ switch (decoded->opt_index) --+ { --+ case OPT_march_: --+ riscv_parse_arch_string (decoded->arg, &opts->x_target_flags, loc); --+ return true; --+ --+ default: --+ return true; --+ } --+} --+ --+/* Implement TARGET_OPTION_OPTIMIZATION_TABLE. */ --+static const struct default_options riscv_option_optimization_table[] = --+ { --+ { OPT_LEVELS_1_PLUS, OPT_fsection_anchors, NULL, 1 }, --+ { OPT_LEVELS_1_PLUS, OPT_fomit_frame_pointer, NULL, 1 }, --+ { OPT_LEVELS_2_PLUS, OPT_free, NULL, 1 }, --+ { OPT_LEVELS_NONE, 0, NULL, 0 } --+ }; --+ --+#undef TARGET_OPTION_OPTIMIZATION_TABLE --+#define TARGET_OPTION_OPTIMIZATION_TABLE riscv_option_optimization_table --+ --+#undef TARGET_HANDLE_OPTION --+#define TARGET_HANDLE_OPTION riscv_handle_option --+ --+struct gcc_targetm_common targetm_common = TARGETM_COMMON_INITIALIZER; --diff --git original-gcc/gcc/config.gcc gcc-6.3.0/gcc/config.gcc --index bc389eb45e7..ddfa4dccb52 100644 ----- original-gcc/gcc/config.gcc --+++ gcc-6.3.0/gcc/config.gcc --@@ -451,6 +451,10 @@ powerpc*-*-*) -- esac -- extra_options="${extra_options} g.opt fused-madd.opt rs6000/rs6000-tables.opt" -- ;; --+riscv*) --+ cpu_type=riscv --+ extra_objs="riscv-builtins.o riscv-c.o" --+ ;; -- rs6000*-*-*) -- extra_options="${extra_options} g.opt fused-madd.opt rs6000/rs6000-tables.opt" -- ;; --@@ -2016,6 +2020,34 @@ microblaze*-*-elf) -- cxx_target_objs="${cxx_target_objs} microblaze-c.o" -- tmake_file="${tmake_file} microblaze/t-microblaze" -- ;; --+riscv*-*-linux*) --+ tm_file="elfos.h gnu-user.h linux.h glibc-stdint.h ${tm_file} riscv/linux.h" --+ case "x${enable_multilib}" in --+ xno) ;; --+ xyes) tmake_file="${tmake_file} riscv/t-linux-multilib" ;; --+ *) echo "Unknown value for enable_multilib"; exit 1 --+ esac --+ tmake_file="${tmake_file} riscv/t-riscv riscv/t-linux" --+ gnu_ld=yes --+ gas=yes --+ # Force .init_array support. The configure script cannot always --+ # automatically detect that GAS supports it, yet we require it. --+ gcc_cv_initfini_array=yes --+ ;; --+riscv*-*-elf*) --+ tm_file="elfos.h newlib-stdint.h ${tm_file} riscv/elf.h" --+ case "x${enable_multilib}" in --+ xno) ;; --+ xyes) tmake_file="${tmake_file} riscv/t-elf-multilib" ;; --+ *) echo "Unknown value for enable_multilib"; exit 1 --+ esac --+ tmake_file="${tmake_file} riscv/t-riscv" --+ gnu_ld=yes --+ gas=yes --+ # Force .init_array support. The configure script cannot always --+ # automatically detect that GAS supports it, yet we require it. --+ gcc_cv_initfini_array=yes --+ ;; -- mips*-*-netbsd*) # NetBSD/mips, either endian. -- target_cpu_default="MASK_ABICALLS" -- tm_file="elfos.h ${tm_file} mips/elf.h netbsd.h netbsd-elf.h mips/netbsd.h" --@@ -3939,6 +3971,70 @@ case "${target}" in -- done -- ;; -- --+ riscv*-*-*) --+ supported_defaults="abi arch tune" --+ --+ case "${target}" in --+ riscv32*) xlen=32 ;; --+ riscv64*) xlen=64 ;; --+ *) echo "Unsupported RISC-V target ${target}" 1>&2; exit 1 ;; --+ esac --+ --+ # Infer arch from --with-arch, --target, and --with-abi. --+ case "${with_arch}" in --+ rv32i* | rv32g* | rv64i* | rv64g*) --+ # OK. --+ ;; --+ "") --+ # Infer XLEN, but otherwise assume GC. --+ case "${with_abi}" in --+ ilp32 | ilp32f | ilp32d) with_arch="rv32gc" ;; --+ lp64 | lp64f | lp64d) with_arch="rv64gc" ;; --+ *) with_arch="rv${xlen}gc" ;; --+ esac --+ ;; --+ *) --+ echo "--with-arch=${with_arch} is not supported. The argument must begin with rv32i, rv32g, rv64i, or rv64g." 1>&2 --+ exit 1 --+ ;; --+ esac --+ --+ # Make sure --with-abi is valid. If it was not specified, --+ # pick a default based on the ISA, preferring soft-float --+ # unless the D extension is present. --+ case "${with_abi}" in --+ ilp32 | ilp32f | ilp32d | lp64 | lp64f | lp64d) --+ ;; --+ "") --+ case "${with_arch}" in --+ rv32*d* | rv32g*) with_abi=ilp32d ;; --+ rv32*) with_abi=ilp32 ;; --+ rv64*d* | rv64g*) with_abi=lp64d ;; --+ rv64*) with_abi=lp64 ;; --+ esac --+ ;; --+ *) --+ echo "--with-abi=${with_abi} is not supported" 1>&2 --+ exit 1 --+ ;; --+ esac --+ --+ # Make sure ABI and ISA are compatible. --+ case "${with_abi},${with_arch}" in --+ ilp32,rv32* \ --+ | ilp32f,rv32*f* | ilp32f,rv32g* \ --+ | ilp32d,rv32*d* | ilp32d,rv32g* \ --+ | lp64,rv64* \ --+ | lp64f,rv64*f* | lp64f,rv64g* \ --+ | lp64d,rv64*d* | lp64d,rv64g*) --+ ;; --+ *) --+ echo "--with-abi=${with_abi} is not supported for ISA ${with_arch}" 1>&2 --+ exit 1 --+ ;; --+ esac --+ ;; --+ -- mips*-*-*) -- supported_defaults="abi arch arch_32 arch_64 float fpu nan fp_32 odd_spreg_32 tune tune_32 tune_64 divide llsc mips-plt synci lxc1-sxc1 madd4" -- --diff --git original-gcc/gcc/config/riscv/constraints.md gcc-6.3.0/gcc/config/riscv/constraints.md --new file mode 100644 --index 00000000000..ae93788e44a ----- /dev/null --+++ gcc-6.3.0/gcc/config/riscv/constraints.md --@@ -0,0 +1,78 @@ --+;; Constraint definitions for RISC-V target. --+;; Copyright (C) 2011-2017 Free Software Foundation, Inc. --+;; Contributed by Andrew Waterman (andrew@sifive.com). --+;; Based on MIPS target for GNU compiler. --+;; --+;; This file is part of GCC. --+;; --+;; GCC is free software; you can redistribute it and/or modify --+;; it under the terms of the GNU General Public License as published by --+;; the Free Software Foundation; either version 3, or (at your option) --+;; any later version. --+;; --+;; GCC is distributed in the hope that it will be useful, --+;; but WITHOUT ANY WARRANTY; without even the implied warranty of --+;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the --+;; GNU General Public License for more details. --+;; --+;; You should have received a copy of the GNU General Public License --+;; along with GCC; see the file COPYING3. If not see --+;; . --+ --+;; Register constraints --+ --+(define_register_constraint "f" "TARGET_HARD_FLOAT ? FP_REGS : NO_REGS" --+ "A floating-point register (if available).") --+ --+(define_register_constraint "j" "SIBCALL_REGS" --+ "@internal") --+ --+;; Avoid using register t0 for JALR's argument, because for some --+;; microarchitectures that is a return-address stack hint. --+(define_register_constraint "l" "JALR_REGS" --+ "@internal") --+ --+;; General constraints --+ --+(define_constraint "I" --+ "An I-type 12-bit signed immediate." --+ (and (match_code "const_int") --+ (match_test "SMALL_OPERAND (ival)"))) --+ --+(define_constraint "J" --+ "Integer zero." --+ (and (match_code "const_int") --+ (match_test "ival == 0"))) --+ --+(define_constraint "K" --+ "A 5-bit unsigned immediate for CSR access instructions." --+ (and (match_code "const_int") --+ (match_test "IN_RANGE (ival, 0, 31)"))) --+ --+;; Floating-point constant +0.0, used for FCVT-based moves when FMV is --+;; not available in RV32. --+(define_constraint "G" --+ "@internal" --+ (and (match_code "const_double") --+ (match_test "op == CONST0_RTX (mode)"))) --+ --+(define_memory_constraint "A" --+ "An address that is held in a general-purpose register." --+ (and (match_code "mem") --+ (match_test "GET_CODE(XEXP(op,0)) == REG"))) --+ --+(define_constraint "S" --+ "@internal --+ A constant call address." --+ (match_operand 0 "absolute_symbolic_operand")) --+ --+(define_constraint "U" --+ "@internal --+ A PLT-indirect call address." --+ (match_operand 0 "plt_symbolic_operand")) --+ --+(define_constraint "T" --+ "@internal --+ A constant @code{move_operand}." --+ (and (match_operand 0 "move_operand") --+ (match_test "CONSTANT_P (op)"))) --diff --git original-gcc/gcc/config/riscv/elf.h gcc-6.3.0/gcc/config/riscv/elf.h --new file mode 100644 --index 00000000000..391e59f49b9 ----- /dev/null --+++ gcc-6.3.0/gcc/config/riscv/elf.h --@@ -0,0 +1,35 @@ --+/* Target macros for riscv*-elf targets. --+ Copyright (C) 1994-2017 Free Software Foundation, Inc. --+ --+This file is part of GCC. --+ --+GCC is free software; you can redistribute it and/or modify --+it under the terms of the GNU General Public License as published by --+the Free Software Foundation; either version 3, or (at your option) --+any later version. --+ --+GCC is distributed in the hope that it will be useful, --+but WITHOUT ANY WARRANTY; without even the implied warranty of --+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the --+GNU General Public License for more details. --+ --+You should have received a copy of the GNU General Public License --+along with GCC; see the file COPYING3. If not see --+. */ --+ --+#define LINK_SPEC "\ --+-melf" XLEN_SPEC "lriscv \ --+%{shared}" --+ --+/* Link against Newlib libraries, because the ELF backend assumes Newlib. --+ Handle the circular dependence between libc and libgloss. */ --+#undef LIB_SPEC --+#define LIB_SPEC "--start-group -lc -lgloss --end-group" --+ --+#undef STARTFILE_SPEC --+#define STARTFILE_SPEC "crt0%O%s crtbegin%O%s" --+ --+#undef ENDFILE_SPEC --+#define ENDFILE_SPEC "crtend%O%s" --+ --+#define NO_IMPLICIT_EXTERN_C 1 --diff --git original-gcc/gcc/config/riscv/generic.md gcc-6.3.0/gcc/config/riscv/generic.md --new file mode 100644 --index 00000000000..294c7ef729d ----- /dev/null --+++ gcc-6.3.0/gcc/config/riscv/generic.md --@@ -0,0 +1,78 @@ --+;; Generic DFA-based pipeline description for RISC-V targets. --+;; Copyright (C) 2011-2017 Free Software Foundation, Inc. --+;; Contributed by Andrew Waterman (andrew@sifive.com). --+;; Based on MIPS target for GNU compiler. --+ --+;; This file is part of GCC. --+ --+;; GCC is free software; you can redistribute it and/or modify it --+;; under the terms of the GNU General Public License as published --+;; by the Free Software Foundation; either version 3, or (at your --+;; option) any later version. --+ --+;; GCC is distributed in the hope that it will be useful, but WITHOUT --+;; ANY WARRANTY; without even the implied warranty of MERCHANTABILITY --+;; or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public --+;; License for more details. --+ --+;; You should have received a copy of the GNU General Public License --+;; along with GCC; see the file COPYING3. If not see --+;; . --+ --+ --+(define_automaton "pipe0") --+(define_cpu_unit "alu" "pipe0") --+(define_cpu_unit "imuldiv" "pipe0") --+(define_cpu_unit "fdivsqrt" "pipe0") --+ --+(define_insn_reservation "generic_alu" 1 --+ (eq_attr "type" "unknown,const,arith,shift,slt,multi,nop,logical,move") --+ "alu") --+ --+(define_insn_reservation "generic_load" 3 --+ (eq_attr "type" "load,fpload") --+ "alu") --+ --+(define_insn_reservation "generic_store" 1 --+ (eq_attr "type" "store,fpstore") --+ "alu") --+ --+(define_insn_reservation "generic_xfer" 3 --+ (eq_attr "type" "mfc,mtc,fcvt,fmove,fcmp") --+ "alu") --+ --+(define_insn_reservation "generic_branch" 1 --+ (eq_attr "type" "branch,jump,call") --+ "alu") --+ --+(define_insn_reservation "generic_imul" 10 --+ (eq_attr "type" "imul") --+ "imuldiv*10") --+ --+(define_insn_reservation "generic_idivsi" 34 --+ (and (eq_attr "type" "idiv") --+ (eq_attr "mode" "SI")) --+ "imuldiv*34") --+ --+(define_insn_reservation "generic_idivdi" 66 --+ (and (eq_attr "type" "idiv") --+ (eq_attr "mode" "DI")) --+ "imuldiv*66") --+ --+(define_insn_reservation "generic_fmul_single" 5 --+ (and (eq_attr "type" "fadd,fmul,fmadd") --+ (eq_attr "mode" "SF")) --+ "alu") --+ --+(define_insn_reservation "generic_fmul_double" 7 --+ (and (eq_attr "type" "fadd,fmul,fmadd") --+ (eq_attr "mode" "DF")) --+ "alu") --+ --+(define_insn_reservation "generic_fdiv" 20 --+ (eq_attr "type" "fdiv") --+ "fdivsqrt*20") --+ --+(define_insn_reservation "generic_fsqrt" 25 --+ (eq_attr "type" "fsqrt") --+ "fdivsqrt*25") --diff --git original-gcc/gcc/config/riscv/linux.h gcc-6.3.0/gcc/config/riscv/linux.h --new file mode 100644 --index 00000000000..0c622118056 ----- /dev/null --+++ gcc-6.3.0/gcc/config/riscv/linux.h --@@ -0,0 +1,40 @@ --+/* Definitions for RISC-V GNU/Linux systems with ELF format. --+ Copyright (C) 1998-2017 Free Software Foundation, Inc. --+ --+This file is part of GCC. --+ --+GCC is free software; you can redistribute it and/or modify --+it under the terms of the GNU General Public License as published by --+the Free Software Foundation; either version 3, or (at your option) --+any later version. --+ --+GCC is distributed in the hope that it will be useful, --+but WITHOUT ANY WARRANTY; without even the implied warranty of --+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the --+GNU General Public License for more details. --+ --+You should have received a copy of the GNU General Public License --+along with GCC; see the file COPYING3. If not see --+. */ --+ --+#define TARGET_OS_CPP_BUILTINS() \ --+ do { \ --+ GNU_USER_TARGET_OS_CPP_BUILTINS(); \ --+ } while (0) --+ --+#define GLIBC_DYNAMIC_LINKER "/lib/ld-linux-riscv" XLEN_SPEC "-" ABI_SPEC ".so.1" --+ --+/* Because RISC-V only has word-sized atomics, it requries libatomic where --+ others do not. So link libatomic by default, as needed. */ --+#undef LIB_SPEC --+#define LIB_SPEC GNU_USER_TARGET_LIB_SPEC \ --+ " %{pthread:" LD_AS_NEEDED_OPTION " -latomic " LD_NO_AS_NEEDED_OPTION "}" \ --+ --+#define LINK_SPEC "\ --+-melf" XLEN_SPEC "lriscv \ --+%{shared} \ --+ %{!shared: \ --+ %{!static: \ --+ %{rdynamic:-export-dynamic} \ --+ -dynamic-linker " GNU_USER_DYNAMIC_LINKER "} \ --+ %{static:-static}}" --diff --git original-gcc/gcc/config/riscv/multilib-generator gcc-6.3.0/gcc/config/riscv/multilib-generator --new file mode 100755 --index 00000000000..b7ebf7bed41 ----- /dev/null --+++ gcc-6.3.0/gcc/config/riscv/multilib-generator --@@ -0,0 +1,65 @@ --+#!/usr/bin/env python --+ --+# RISC-V multilib list generator. --+# Copyright (C) 2011-2017 Free Software Foundation, Inc. --+# Contributed by Andrew Waterman (andrew@sifive.com). --+# --+# This file is part of GCC. --+# --+# GCC is free software; you can redistribute it and/or modify --+# it under the terms of the GNU General Public License as published by --+# the Free Software Foundation; either version 3, or (at your option) --+# any later version. --+# --+# GCC is distributed in the hope that it will be useful, --+# but WITHOUT ANY WARRANTY; without even the implied warranty of --+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the --+# GNU General Public License for more details. --+# --+# You should have received a copy of the GNU General Public License --+# along with GCC; see the file COPYING3. If not see --+# . --+ --+# Each argument to this script is of the form --+# --- --+# For example, --+# rv32imafd-ilp32d-rv32g-c,v --+# means that, in addition to rv32imafd, these configurations can also use the --+# rv32imafd-ilp32d libraries: rv32imafdc, rv32imafdv, rv32g, rv32gc, rv32gv --+ --+from __future__ import print_function --+import sys --+import collections --+ --+arches = collections.OrderedDict() --+abis = collections.OrderedDict() --+required = [] --+reuse = [] --+ --+for cfg in sys.argv[1:]: --+ (arch, abi, extra, ext) = cfg.split('-') --+ arches[arch] = 1 --+ abis[abi] = 1 --+ extra = list(filter(None, extra.split(','))) --+ ext = list(filter(None, ext.split(','))) --+ alts = sum([[x] + [x + y for y in ext] for x in [arch] + extra], []) --+ alts = alts + [x.replace('imafd', 'g') for x in alts if 'imafd' in x] --+ for alt in alts[1:]: --+ arches[alt] = 1 --+ reuse.append('march.%s/mabi.%s=march.%s/mabi.%s' % (arch, abi, alt, abi)) --+ required.append('march=%s/mabi=%s' % (arch, abi)) --+ --+arch_options = '/'.join(['march=%s' % x for x in arches.keys()]) --+arch_dirnames = ' '.join(arches.keys()) --+ --+abi_options = '/'.join(['mabi=%s' % x for x in abis.keys()]) --+abi_dirnames = ' '.join(abis.keys()) --+ --+prog = sys.argv[0].split('/')[-1] --+print('# This file was generated by %s with the command:' % prog) --+print('# %s' % ' '.join(sys.argv)) --+ --+print('MULTILIB_OPTIONS = %s %s' % (arch_options, abi_options)) --+print('MULTILIB_DIRNAMES = %s %s' % (arch_dirnames, abi_dirnames)) --+print('MULTILIB_REQUIRED = %s' % ' '.join(required)) --+print('MULTILIB_REUSE = %s' % ' '.join(reuse)) --diff --git original-gcc/gcc/config/riscv/peephole.md gcc-6.3.0/gcc/config/riscv/peephole.md --new file mode 100644 --index 00000000000..7e644e01759 ----- /dev/null --+++ gcc-6.3.0/gcc/config/riscv/peephole.md --@@ -0,0 +1,40 @@ --+;; Peephole optimizations for RISC-V for GNU compiler. --+;; Copyright (C) 2011-2017 Free Software Foundation, Inc. --+;; Contributed by Andrew Waterman (andrew@sifive.com). --+ --+;; This file is part of GCC. --+ --+;; GCC is free software; you can redistribute it and/or modify --+;; it under the terms of the GNU General Public License as published by --+;; the Free Software Foundation; either version 3, or (at your option) --+;; any later version. --+ --+;; GCC is distributed in the hope that it will be useful, --+;; but WITHOUT ANY WARRANTY; without even the implied warranty of --+;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the --+;; GNU General Public License for more details. --+ --+;; You should have received a copy of the GNU General Public License --+;; along with GCC; see the file COPYING3. If not see --+;; . --+ --+;; Simplify (unsigned long)(unsigned int)a << const --+(define_peephole2 --+ [(set (match_operand:DI 0 "register_operand") --+ (ashift:DI (match_operand:DI 1 "register_operand") --+ (match_operand 2 "const_int_operand"))) --+ (set (match_operand:DI 3 "register_operand") --+ (lshiftrt:DI (match_dup 0) (match_dup 2))) --+ (set (match_operand:DI 4 "register_operand") --+ (ashift:DI (match_dup 3) (match_operand 5 "const_int_operand")))] --+ "TARGET_64BIT --+ && INTVAL (operands[5]) < INTVAL (operands[2]) --+ && (REGNO (operands[3]) == REGNO (operands[4]) --+ || peep2_reg_dead_p (3, operands[3]))" --+ [(set (match_dup 0) --+ (ashift:DI (match_dup 1) (match_dup 2))) --+ (set (match_dup 4) --+ (lshiftrt:DI (match_dup 0) (match_operand 5)))] --+{ --+ operands[5] = GEN_INT (INTVAL (operands[2]) - INTVAL (operands[5])); --+}) --diff --git original-gcc/gcc/config/riscv/pic.md gcc-6.3.0/gcc/config/riscv/pic.md --new file mode 100644 --index 00000000000..6a29ead32d3 ----- /dev/null --+++ gcc-6.3.0/gcc/config/riscv/pic.md --@@ -0,0 +1,85 @@ --+;; PIC codegen for RISC-V for GNU compiler. --+;; Copyright (C) 2011-2017 Free Software Foundation, Inc. --+;; Contributed by Andrew Waterman (andrew@sifive.com). --+ --+;; This file is part of GCC. --+ --+;; GCC is free software; you can redistribute it and/or modify --+;; it under the terms of the GNU General Public License as published by --+;; the Free Software Foundation; either version 3, or (at your option) --+;; any later version. --+ --+;; GCC is distributed in the hope that it will be useful, --+;; but WITHOUT ANY WARRANTY; without even the implied warranty of --+;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the --+;; GNU General Public License for more details. --+ --+;; You should have received a copy of the GNU General Public License --+;; along with GCC; see the file COPYING3. If not see --+;; . --+ --+ --+;; Simplify PIC loads to static variables. --+;; These should go away once we figure out how to emit auipc discretely. --+ --+(define_insn "*local_pic_load" --+ [(set (match_operand:ANYI 0 "register_operand" "=r") --+ (mem:ANYI (match_operand 1 "absolute_symbolic_operand" "")))] --+ "USE_LOAD_ADDRESS_MACRO (operands[1])" --+ "\t%0,%1" --+ [(set (attr "length") (const_int 8))]) --+ --+(define_insn "*local_pic_load" --+ [(set (match_operand:ANYF 0 "register_operand" "=f") --+ (mem:ANYF (match_operand 1 "absolute_symbolic_operand" ""))) --+ (clobber (match_scratch:DI 2 "=r"))] --+ "TARGET_HARD_FLOAT && TARGET_64BIT && USE_LOAD_ADDRESS_MACRO (operands[1])" --+ "\t%0,%1,%2" --+ [(set (attr "length") (const_int 8))]) --+ --+(define_insn "*local_pic_load" --+ [(set (match_operand:ANYF 0 "register_operand" "=f") --+ (mem:ANYF (match_operand 1 "absolute_symbolic_operand" ""))) --+ (clobber (match_scratch:SI 2 "=r"))] --+ "TARGET_HARD_FLOAT && !TARGET_64BIT && USE_LOAD_ADDRESS_MACRO (operands[1])" --+ "\t%0,%1,%2" --+ [(set (attr "length") (const_int 8))]) --+ --+(define_insn "*local_pic_loadu" --+ [(set (match_operand:SUPERQI 0 "register_operand" "=r") --+ (zero_extend:SUPERQI (mem:SUBX (match_operand 1 "absolute_symbolic_operand" ""))))] --+ "USE_LOAD_ADDRESS_MACRO (operands[1])" --+ "u\t%0,%1" --+ [(set (attr "length") (const_int 8))]) --+ --+(define_insn "*local_pic_storedi" --+ [(set (mem:ANYI (match_operand 0 "absolute_symbolic_operand" "")) --+ (match_operand:ANYI 1 "reg_or_0_operand" "rJ")) --+ (clobber (match_scratch:DI 2 "=&r"))] --+ "TARGET_64BIT && USE_LOAD_ADDRESS_MACRO (operands[0])" --+ "\t%z1,%0,%2" --+ [(set (attr "length") (const_int 8))]) --+ --+(define_insn "*local_pic_storesi" --+ [(set (mem:ANYI (match_operand 0 "absolute_symbolic_operand" "")) --+ (match_operand:ANYI 1 "reg_or_0_operand" "rJ")) --+ (clobber (match_scratch:SI 2 "=&r"))] --+ "!TARGET_64BIT && USE_LOAD_ADDRESS_MACRO (operands[0])" --+ "\t%z1,%0,%2" --+ [(set (attr "length") (const_int 8))]) --+ --+(define_insn "*local_pic_storedi" --+ [(set (mem:ANYF (match_operand 0 "absolute_symbolic_operand" "")) --+ (match_operand:ANYF 1 "register_operand" "f")) --+ (clobber (match_scratch:DI 2 "=r"))] --+ "TARGET_HARD_FLOAT && TARGET_64BIT && USE_LOAD_ADDRESS_MACRO (operands[0])" --+ "\t%1,%0,%2" --+ [(set (attr "length") (const_int 8))]) --+ --+(define_insn "*local_pic_storesi" --+ [(set (mem:ANYF (match_operand 0 "absolute_symbolic_operand" "")) --+ (match_operand:ANYF 1 "register_operand" "f")) --+ (clobber (match_scratch:SI 2 "=r"))] --+ "TARGET_HARD_FLOAT && !TARGET_64BIT && USE_LOAD_ADDRESS_MACRO (operands[0])" --+ "\t%1,%0,%2" --+ [(set (attr "length") (const_int 8))]) --diff --git original-gcc/gcc/config/riscv/predicates.md gcc-6.3.0/gcc/config/riscv/predicates.md --new file mode 100644 --index 00000000000..854af1481f7 ----- /dev/null --+++ gcc-6.3.0/gcc/config/riscv/predicates.md --@@ -0,0 +1,180 @@ --+;; Predicate description for RISC-V target. --+;; Copyright (C) 2011-2017 Free Software Foundation, Inc. --+;; Contributed by Andrew Waterman (andrew@sifive.com). --+;; Based on MIPS target for GNU compiler. --+;; --+;; This file is part of GCC. --+;; --+;; GCC is free software; you can redistribute it and/or modify --+;; it under the terms of the GNU General Public License as published by --+;; the Free Software Foundation; either version 3, or (at your option) --+;; any later version. --+;; --+;; GCC is distributed in the hope that it will be useful, --+;; but WITHOUT ANY WARRANTY; without even the implied warranty of --+;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the --+;; GNU General Public License for more details. --+;; --+;; You should have received a copy of the GNU General Public License --+;; along with GCC; see the file COPYING3. If not see --+;; . --+ --+(define_predicate "const_arith_operand" --+ (and (match_code "const_int") --+ (match_test "SMALL_OPERAND (INTVAL (op))"))) --+ --+(define_predicate "arith_operand" --+ (ior (match_operand 0 "const_arith_operand") --+ (match_operand 0 "register_operand"))) --+ --+(define_predicate "const_csr_operand" --+ (and (match_code "const_int") --+ (match_test "IN_RANGE (INTVAL (op), 0, 31)"))) --+ --+(define_predicate "csr_operand" --+ (ior (match_operand 0 "const_csr_operand") --+ (match_operand 0 "register_operand"))) --+ --+(define_predicate "sle_operand" --+ (and (match_code "const_int") --+ (match_test "SMALL_OPERAND (INTVAL (op) + 1)"))) --+ --+(define_predicate "sleu_operand" --+ (and (match_operand 0 "sle_operand") --+ (match_test "INTVAL (op) + 1 != 0"))) --+ --+(define_predicate "const_0_operand" --+ (and (match_code "const_int,const_wide_int,const_double,const_vector") --+ (match_test "op == CONST0_RTX (GET_MODE (op))"))) --+ --+(define_predicate "reg_or_0_operand" --+ (ior (match_operand 0 "const_0_operand") --+ (match_operand 0 "register_operand"))) --+ --+;; Only use branch-on-bit sequences when the mask is not an ANDI immediate. --+(define_predicate "branch_on_bit_operand" --+ (and (match_code "const_int") --+ (match_test "INTVAL (op) >= IMM_BITS - 1"))) --+ --+;; A legitimate CONST_INT operand that takes more than one instruction --+;; to load. --+(define_predicate "splittable_const_int_operand" --+ (match_code "const_int") --+{ --+ /* Don't handle multi-word moves this way; we don't want to introduce --+ the individual word-mode moves until after reload. */ --+ if (GET_MODE_SIZE (mode) > UNITS_PER_WORD) --+ return false; --+ --+ /* Otherwise check whether the constant can be loaded in a single --+ instruction. */ --+ return !LUI_OPERAND (INTVAL (op)) && !SMALL_OPERAND (INTVAL (op)); --+}) --+ --+(define_predicate "move_operand" --+ (match_operand 0 "general_operand") --+{ --+ enum riscv_symbol_type symbol_type; --+ --+ /* The thinking here is as follows: --+ --+ (1) The move expanders should split complex load sequences into --+ individual instructions. Those individual instructions can --+ then be optimized by all rtl passes. --+ --+ (2) The target of pre-reload load sequences should not be used --+ to store temporary results. If the target register is only --+ assigned one value, reload can rematerialize that value --+ on demand, rather than spill it to the stack. --+ --+ (3) If we allowed pre-reload passes like combine and cse to recreate --+ complex load sequences, we would want to be able to split the --+ sequences before reload as well, so that the pre-reload scheduler --+ can see the individual instructions. This falls foul of (2); --+ the splitter would be forced to reuse the target register for --+ intermediate results. --+ --+ (4) We want to define complex load splitters for combine. These --+ splitters can request a temporary scratch register, which avoids --+ the problem in (2). They allow things like: --+ --+ (set (reg T1) (high SYM)) --+ (set (reg T2) (low (reg T1) SYM)) --+ (set (reg X) (plus (reg T2) (const_int OFFSET))) --+ --+ to be combined into: --+ --+ (set (reg T3) (high SYM+OFFSET)) --+ (set (reg X) (lo_sum (reg T3) SYM+OFFSET)) --+ --+ if T2 is only used this once. */ --+ switch (GET_CODE (op)) --+ { --+ case CONST_INT: --+ return !splittable_const_int_operand (op, mode); --+ --+ case CONST: --+ case SYMBOL_REF: --+ case LABEL_REF: --+ return riscv_symbolic_constant_p (op, &symbol_type) --+ && !riscv_split_symbol_type (symbol_type); --+ --+ case HIGH: --+ op = XEXP (op, 0); --+ return riscv_symbolic_constant_p (op, &symbol_type) --+ && riscv_split_symbol_type (symbol_type) --+ && symbol_type != SYMBOL_PCREL; --+ --+ default: --+ return true; --+ } --+}) --+ --+(define_predicate "symbolic_operand" --+ (match_code "const,symbol_ref,label_ref") --+{ --+ enum riscv_symbol_type type; --+ return riscv_symbolic_constant_p (op, &type); --+}) --+ --+(define_predicate "absolute_symbolic_operand" --+ (match_code "const,symbol_ref,label_ref") --+{ --+ enum riscv_symbol_type type; --+ return (riscv_symbolic_constant_p (op, &type) --+ && (type == SYMBOL_ABSOLUTE || type == SYMBOL_PCREL)); --+}) --+ --+(define_predicate "plt_symbolic_operand" --+ (match_code "const,symbol_ref,label_ref") --+{ --+ enum riscv_symbol_type type; --+ return (riscv_symbolic_constant_p (op, &type) --+ && type == SYMBOL_GOT_DISP && !SYMBOL_REF_WEAK (op) && TARGET_PLT); --+}) --+ --+(define_predicate "call_insn_operand" --+ (ior (match_operand 0 "absolute_symbolic_operand") --+ (match_operand 0 "plt_symbolic_operand") --+ (match_operand 0 "register_operand"))) --+ --+(define_predicate "modular_operator" --+ (match_code "plus,minus,mult,ashift")) --+ --+(define_predicate "equality_operator" --+ (match_code "eq,ne")) --+ --+(define_predicate "order_operator" --+ (match_code "eq,ne,lt,ltu,le,leu,ge,geu,gt,gtu")) --+ --+(define_predicate "signed_order_operator" --+ (match_code "eq,ne,lt,le,ge,gt")) --+ --+(define_predicate "fp_native_comparison" --+ (match_code "eq,lt,le,gt,ge")) --+ --+(define_predicate "fp_scc_comparison" --+ (match_code "unordered,ordered,unlt,unge,unle,ungt,ltgt,ne,eq,lt,le,gt,ge")) --+ --+(define_predicate "fp_branch_comparison" --+ (match_code "unordered,ordered,unlt,unge,unle,ungt,uneq,ltgt,ne,eq,lt,le,gt,ge")) --diff --git original-gcc/gcc/config/riscv/riscv-builtins.c gcc-6.3.0/gcc/config/riscv/riscv-builtins.c --new file mode 100644 --index 00000000000..626a6a33f99 ----- /dev/null --+++ gcc-6.3.0/gcc/config/riscv/riscv-builtins.c --@@ -0,0 +1,287 @@ --+/* Subroutines used for expanding RISC-V builtins. --+ Copyright (C) 2011-2017 Free Software Foundation, Inc. --+ Contributed by Andrew Waterman (andrew@sifive.com). --+ --+This file is part of GCC. --+ --+GCC is free software; you can redistribute it and/or modify --+it under the terms of the GNU General Public License as published by --+the Free Software Foundation; either version 3, or (at your option) --+any later version. --+ --+GCC is distributed in the hope that it will be useful, --+but WITHOUT ANY WARRANTY; without even the implied warranty of --+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the --+GNU General Public License for more details. --+ --+You should have received a copy of the GNU General Public License --+along with GCC; see the file COPYING3. If not see --+. */ --+ --+#include "config.h" --+#include "system.h" --+#include "coretypes.h" --+#include "tm.h" --+#include "rtl.h" --+#include "tree.h" --+#include "gimple-expr.h" --+#include "memmodel.h" --+#include "expmed.h" --+#include "optabs.h" --+#include "recog.h" --+#include "diagnostic-core.h" --+#include "stor-layout.h" --+#include "expr.h" --+#include "langhooks.h" --+ --+/* Macros to create an enumeration identifier for a function prototype. */ --+#define RISCV_FTYPE_NAME1(A, B) RISCV_##A##_FTYPE_##B --+ --+/* Classifies the prototype of a built-in function. */ --+enum riscv_function_type { --+#define DEF_RISCV_FTYPE(NARGS, LIST) RISCV_FTYPE_NAME##NARGS LIST, --+#include "config/riscv/riscv-ftypes.def" --+#undef DEF_RISCV_FTYPE --+ RISCV_MAX_FTYPE_MAX --+}; --+ --+/* Specifies how a built-in function should be converted into rtl. */ --+enum riscv_builtin_type { --+ /* The function corresponds directly to an .md pattern. */ --+ RISCV_BUILTIN_DIRECT, --+ --+ /* Likewise, but with return type VOID. */ --+ RISCV_BUILTIN_DIRECT_NO_TARGET --+}; --+ --+/* Declare an availability predicate for built-in functions. */ --+#define AVAIL(NAME, COND) \ --+ static unsigned int \ --+ riscv_builtin_avail_##NAME (void) \ --+ { \ --+ return (COND); \ --+ } --+ --+/* This structure describes a single built-in function. */ --+struct riscv_builtin_description { --+ /* The code of the main .md file instruction. See riscv_builtin_type --+ for more information. */ --+ enum insn_code icode; --+ --+ /* The name of the built-in function. */ --+ const char *name; --+ --+ /* Specifies how the function should be expanded. */ --+ enum riscv_builtin_type builtin_type; --+ --+ /* The function's prototype. */ --+ enum riscv_function_type prototype; --+ --+ /* Whether the function is available. */ --+ unsigned int (*avail) (void); --+}; --+ --+AVAIL (hard_float, TARGET_HARD_FLOAT) --+ --+/* Construct a riscv_builtin_description from the given arguments. --+ --+ INSN is the name of the associated instruction pattern, without the --+ leading CODE_FOR_riscv_. --+ --+ NAME is the name of the function itself, without the leading --+ "__builtin_riscv_". --+ --+ BUILTIN_TYPE and FUNCTION_TYPE are riscv_builtin_description fields. --+ --+ AVAIL is the name of the availability predicate, without the leading --+ riscv_builtin_avail_. */ --+#define RISCV_BUILTIN(INSN, NAME, BUILTIN_TYPE, FUNCTION_TYPE, AVAIL) \ --+ { CODE_FOR_riscv_ ## INSN, "__builtin_riscv_" NAME, \ --+ BUILTIN_TYPE, FUNCTION_TYPE, riscv_builtin_avail_ ## AVAIL } --+ --+/* Define __builtin_riscv_, which is a RISCV_BUILTIN_DIRECT function --+ mapped to instruction CODE_FOR_riscv_, FUNCTION_TYPE and AVAIL --+ are as for RISCV_BUILTIN. */ --+#define DIRECT_BUILTIN(INSN, FUNCTION_TYPE, AVAIL) \ --+ RISCV_BUILTIN (INSN, #INSN, RISCV_BUILTIN_DIRECT, FUNCTION_TYPE, AVAIL) --+ --+/* Define __builtin_riscv_, which is a RISCV_BUILTIN_DIRECT_NO_TARGET --+ function mapped to instruction CODE_FOR_riscv_, FUNCTION_TYPE --+ and AVAIL are as for RISCV_BUILTIN. */ --+#define DIRECT_NO_TARGET_BUILTIN(INSN, FUNCTION_TYPE, AVAIL) \ --+ RISCV_BUILTIN (INSN, #INSN, RISCV_BUILTIN_DIRECT_NO_TARGET, \ --+ FUNCTION_TYPE, AVAIL) --+ --+/* Argument types. */ --+#define RISCV_ATYPE_VOID void_type_node --+#define RISCV_ATYPE_USI unsigned_intSI_type_node --+ --+/* RISCV_FTYPE_ATYPESN takes N RISCV_FTYPES-like type codes and lists --+ their associated RISCV_ATYPEs. */ --+#define RISCV_FTYPE_ATYPES1(A, B) \ --+ RISCV_ATYPE_##A, RISCV_ATYPE_##B --+ --+static const struct riscv_builtin_description riscv_builtins[] = { --+ DIRECT_BUILTIN (frflags, RISCV_USI_FTYPE_VOID, hard_float), --+ DIRECT_NO_TARGET_BUILTIN (fsflags, RISCV_VOID_FTYPE_USI, hard_float) --+}; --+ --+/* Index I is the function declaration for riscv_builtins[I], or null if the --+ function isn't defined on this target. */ --+static GTY(()) tree riscv_builtin_decls[ARRAY_SIZE (riscv_builtins)]; --+ --+/* Get the index I of the function declaration for riscv_builtin_decls[I] --+ using the instruction code or return null if not defined for the target. */ --+static GTY(()) int riscv_builtin_decl_index[NUM_INSN_CODES]; --+ --+#define GET_BUILTIN_DECL(CODE) \ --+ riscv_builtin_decls[riscv_builtin_decl_index[(CODE)]] --+ --+/* Return the function type associated with function prototype TYPE. */ --+ --+static tree --+riscv_build_function_type (enum riscv_function_type type) --+{ --+ static tree types[(int) RISCV_MAX_FTYPE_MAX]; --+ --+ if (types[(int) type] == NULL_TREE) --+ switch (type) --+ { --+#define DEF_RISCV_FTYPE(NUM, ARGS) \ --+ case RISCV_FTYPE_NAME##NUM ARGS: \ --+ types[(int) type] \ --+ = build_function_type_list (RISCV_FTYPE_ATYPES##NUM ARGS, \ --+ NULL_TREE); \ --+ break; --+#include "config/riscv/riscv-ftypes.def" --+#undef DEF_RISCV_FTYPE --+ default: --+ gcc_unreachable (); --+ } --+ --+ return types[(int) type]; --+} --+ --+/* Implement TARGET_INIT_BUILTINS. */ --+ --+void --+riscv_init_builtins (void) --+{ --+ for (size_t i = 0; i < ARRAY_SIZE (riscv_builtins); i++) --+ { --+ const struct riscv_builtin_description *d = &riscv_builtins[i]; --+ if (d->avail ()) --+ { --+ tree type = riscv_build_function_type (d->prototype); --+ riscv_builtin_decls[i] --+ = add_builtin_function (d->name, type, i, BUILT_IN_MD, NULL, NULL); --+ riscv_builtin_decl_index[d->icode] = i; --+ } --+ } --+} --+ --+/* Implement TARGET_BUILTIN_DECL. */ --+ --+tree --+riscv_builtin_decl (unsigned int code, bool initialize_p ATTRIBUTE_UNUSED) --+{ --+ if (code >= ARRAY_SIZE (riscv_builtins)) --+ return error_mark_node; --+ return riscv_builtin_decls[code]; --+} --+ --+/* Take argument ARGNO from EXP's argument list and convert it into --+ an expand operand. Store the operand in *OP. */ --+ --+static void --+riscv_prepare_builtin_arg (struct expand_operand *op, tree exp, unsigned argno) --+{ --+ tree arg = CALL_EXPR_ARG (exp, argno); --+ create_input_operand (op, expand_normal (arg), TYPE_MODE (TREE_TYPE (arg))); --+} --+ --+/* Expand instruction ICODE as part of a built-in function sequence. --+ Use the first NOPS elements of OPS as the instruction's operands. --+ HAS_TARGET_P is true if operand 0 is a target; it is false if the --+ instruction has no target. --+ --+ Return the target rtx if HAS_TARGET_P, otherwise return const0_rtx. */ --+ --+static rtx --+riscv_expand_builtin_insn (enum insn_code icode, unsigned int n_ops, --+ struct expand_operand *ops, bool has_target_p) --+{ --+ if (!maybe_expand_insn (icode, n_ops, ops)) --+ { --+ error ("invalid argument to built-in function"); --+ return has_target_p ? gen_reg_rtx (ops[0].mode) : const0_rtx; --+ } --+ --+ return has_target_p ? ops[0].value : const0_rtx; --+} --+ --+/* Expand a RISCV_BUILTIN_DIRECT or RISCV_BUILTIN_DIRECT_NO_TARGET function; --+ HAS_TARGET_P says which. EXP is the CALL_EXPR that calls the function --+ and ICODE is the code of the associated .md pattern. TARGET, if nonnull, --+ suggests a good place to put the result. */ --+ --+static rtx --+riscv_expand_builtin_direct (enum insn_code icode, rtx target, tree exp, --+ bool has_target_p) --+{ --+ struct expand_operand ops[MAX_RECOG_OPERANDS]; --+ --+ /* Map any target to operand 0. */ --+ int opno = 0; --+ if (has_target_p) --+ create_output_operand (&ops[opno++], target, TYPE_MODE (TREE_TYPE (exp))); --+ --+ /* Map the arguments to the other operands. */ --+ gcc_assert (opno + call_expr_nargs (exp) --+ == insn_data[icode].n_generator_args); --+ for (int argno = 0; argno < call_expr_nargs (exp); argno++) --+ riscv_prepare_builtin_arg (&ops[opno++], exp, argno); --+ --+ return riscv_expand_builtin_insn (icode, opno, ops, has_target_p); --+} --+ --+/* Implement TARGET_EXPAND_BUILTIN. */ --+ --+rtx --+riscv_expand_builtin (tree exp, rtx target, rtx subtarget ATTRIBUTE_UNUSED, --+ machine_mode mode ATTRIBUTE_UNUSED, --+ int ignore ATTRIBUTE_UNUSED) --+{ --+ tree fndecl = TREE_OPERAND (CALL_EXPR_FN (exp), 0); --+ unsigned int fcode = DECL_FUNCTION_CODE (fndecl); --+ const struct riscv_builtin_description *d = &riscv_builtins[fcode]; --+ --+ switch (d->builtin_type) --+ { --+ case RISCV_BUILTIN_DIRECT: --+ return riscv_expand_builtin_direct (d->icode, target, exp, true); --+ --+ case RISCV_BUILTIN_DIRECT_NO_TARGET: --+ return riscv_expand_builtin_direct (d->icode, target, exp, false); --+ } --+ --+ gcc_unreachable (); --+} --+ --+/* Implement TARGET_ATOMIC_ASSIGN_EXPAND_FENV. */ --+ --+void --+riscv_atomic_assign_expand_fenv (tree *hold, tree *clear, tree *update) --+{ --+ if (!TARGET_HARD_FLOAT) --+ return; --+ --+ tree frflags = GET_BUILTIN_DECL (CODE_FOR_riscv_frflags); --+ tree fsflags = GET_BUILTIN_DECL (CODE_FOR_riscv_fsflags); --+ tree old_flags = create_tmp_var_raw (RISCV_ATYPE_USI); --+ --+ *hold = build2 (MODIFY_EXPR, RISCV_ATYPE_USI, old_flags, --+ build_call_expr (frflags, 0)); --+ *clear = build_call_expr (fsflags, 1, old_flags); --+ *update = NULL_TREE; --+} --diff --git original-gcc/gcc/config/riscv/riscv-c.c gcc-6.3.0/gcc/config/riscv/riscv-c.c --new file mode 100644 --index 00000000000..64e7cf877af ----- /dev/null --+++ gcc-6.3.0/gcc/config/riscv/riscv-c.c --@@ -0,0 +1,92 @@ --+/* RISC-V-specific code for C family languages. --+ Copyright (C) 2011-2017 Free Software Foundation, Inc. --+ Contributed by Andrew Waterman (andrew@sifive.com). --+ --+This file is part of GCC. --+ --+GCC is free software; you can redistribute it and/or modify --+it under the terms of the GNU General Public License as published by --+the Free Software Foundation; either version 3, or (at your option) --+any later version. --+ --+GCC is distributed in the hope that it will be useful, --+but WITHOUT ANY WARRANTY; without even the implied warranty of --+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the --+GNU General Public License for more details. --+ --+You should have received a copy of the GNU General Public License --+along with GCC; see the file COPYING3. If not see --+. */ --+ --+#include "config.h" --+#include "system.h" --+#include "coretypes.h" --+#include "tm.h" --+#include "c-family/c-common.h" --+#include "cpplib.h" --+ --+#define builtin_define(TXT) cpp_define (pfile, TXT) --+ --+/* Implement TARGET_CPU_CPP_BUILTINS. */ --+ --+void --+riscv_cpu_cpp_builtins (cpp_reader *pfile) --+{ --+ builtin_define ("__riscv"); --+ --+ if (TARGET_RVC) --+ builtin_define ("__riscv_compressed"); --+ --+ if (TARGET_ATOMIC) --+ builtin_define ("__riscv_atomic"); --+ --+ if (TARGET_MUL) --+ builtin_define ("__riscv_mul"); --+ if (TARGET_DIV) --+ builtin_define ("__riscv_div"); --+ if (TARGET_DIV && TARGET_MUL) --+ builtin_define ("__riscv_muldiv"); --+ --+ builtin_define_with_int_value ("__riscv_xlen", UNITS_PER_WORD * 8); --+ if (TARGET_HARD_FLOAT) --+ builtin_define_with_int_value ("__riscv_flen", UNITS_PER_FP_REG * 8); --+ --+ if (TARGET_HARD_FLOAT && TARGET_FDIV) --+ { --+ builtin_define ("__riscv_fdiv"); --+ builtin_define ("__riscv_fsqrt"); --+ } --+ --+ switch (riscv_abi) --+ { --+ case ABI_ILP32: --+ case ABI_LP64: --+ builtin_define ("__riscv_float_abi_soft"); --+ break; --+ --+ case ABI_ILP32F: --+ case ABI_LP64F: --+ builtin_define ("__riscv_float_abi_single"); --+ break; --+ --+ case ABI_ILP32D: --+ case ABI_LP64D: --+ builtin_define ("__riscv_float_abi_double"); --+ break; --+ } --+ --+ switch (riscv_cmodel) --+ { --+ case CM_MEDLOW: --+ builtin_define ("__riscv_cmodel_medlow"); --+ break; --+ --+ case CM_MEDANY: --+ builtin_define ("__riscv_cmodel_medany"); --+ break; --+ --+ case CM_PIC: --+ builtin_define ("__riscv_cmodel_pic"); --+ break; --+ } --+} --diff --git original-gcc/gcc/config/riscv/riscv-ftypes.def gcc-6.3.0/gcc/config/riscv/riscv-ftypes.def --new file mode 100644 --index 00000000000..eb69148368f ----- /dev/null --+++ gcc-6.3.0/gcc/config/riscv/riscv-ftypes.def --@@ -0,0 +1,30 @@ --+/* Definitions of prototypes for RISC-V built-in functions. -*- C -*- --+ Copyright (C) 2011-2017 Free Software Foundation, Inc. --+ Contributed by Andrew Waterman (andrew@sifive.com). --+ Based on MIPS target for GNU compiler. --+ --+This file is part of GCC. --+ --+GCC is free software; you can redistribute it and/or modify --+it under the terms of the GNU General Public License as published by --+the Free Software Foundation; either version 3, or (at your option) --+any later version. --+ --+GCC is distributed in the hope that it will be useful, --+but WITHOUT ANY WARRANTY; without even the implied warranty of --+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the --+GNU General Public License for more details. --+ --+You should have received a copy of the GNU General Public License --+along with GCC; see the file COPYING3. If not see --+. */ --+ --+/* Invoke DEF_RISCV_FTYPE (NARGS, LIST) for each prototype used by --+ RISCV built-in functions, where: --+ --+ NARGS is the number of arguments. --+ LIST contains the return-type code followed by the codes for each --+ argument type. */ --+ --+DEF_RISCV_FTYPE (1, (USI, VOID)) --+DEF_RISCV_FTYPE (1, (VOID, USI)) --diff --git original-gcc/gcc/config/riscv/riscv-modes.def gcc-6.3.0/gcc/config/riscv/riscv-modes.def --new file mode 100644 --index 00000000000..5c65667da68 ----- /dev/null --+++ gcc-6.3.0/gcc/config/riscv/riscv-modes.def --@@ -0,0 +1,22 @@ --+/* Extra machine modes for RISC-V target. --+ Copyright (C) 2011-2017 Free Software Foundation, Inc. --+ Contributed by Andrew Waterman (andrew@sifive.com). --+ Based on MIPS target for GNU compiler. --+ --+This file is part of GCC. --+ --+GCC is free software; you can redistribute it and/or modify --+it under the terms of the GNU General Public License as published by --+the Free Software Foundation; either version 3, or (at your option) --+any later version. --+ --+GCC is distributed in the hope that it will be useful, --+but WITHOUT ANY WARRANTY; without even the implied warranty of --+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the --+GNU General Public License for more details. --+ --+You should have received a copy of the GNU General Public License --+along with GCC; see the file COPYING3. If not see --+. */ --+ --+FLOAT_MODE (TF, 16, ieee_quad_format); --diff --git original-gcc/gcc/config/riscv/riscv-opts.h gcc-6.3.0/gcc/config/riscv/riscv-opts.h --new file mode 100644 --index 00000000000..2b19233379c ----- /dev/null --+++ gcc-6.3.0/gcc/config/riscv/riscv-opts.h --@@ -0,0 +1,41 @@ --+/* Definition of RISC-V target for GNU compiler. --+ Copyright (C) 2016-2017 Free Software Foundation, Inc. --+ Contributed by Andrew Waterman (andrew@sifive.com). --+ --+This file is part of GCC. --+ --+GCC is free software; you can redistribute it and/or modify --+it under the terms of the GNU General Public License as published by --+the Free Software Foundation; either version 3, or (at your option) --+any later version. --+ --+GCC is distributed in the hope that it will be useful, --+but WITHOUT ANY WARRANTY; without even the implied warranty of --+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the --+GNU General Public License for more details. --+ --+You should have received a copy of the GNU General Public License --+along with GCC; see the file COPYING3. If not see --+. */ --+ --+#ifndef GCC_RISCV_OPTS_H --+#define GCC_RISCV_OPTS_H --+ --+enum riscv_abi_type { --+ ABI_ILP32, --+ ABI_ILP32F, --+ ABI_ILP32D, --+ ABI_LP64, --+ ABI_LP64F, --+ ABI_LP64D --+}; --+extern enum riscv_abi_type riscv_abi; --+ --+enum riscv_code_model { --+ CM_MEDLOW, --+ CM_MEDANY, --+ CM_PIC --+}; --+extern enum riscv_code_model riscv_cmodel; --+ --+#endif /* ! GCC_RISCV_OPTS_H */ --diff --git original-gcc/gcc/config/riscv/riscv-protos.h gcc-6.3.0/gcc/config/riscv/riscv-protos.h --new file mode 100644 --index 00000000000..de7023f88c5 ----- /dev/null --+++ gcc-6.3.0/gcc/config/riscv/riscv-protos.h --@@ -0,0 +1,83 @@ --+/* Definition of RISC-V target for GNU compiler. --+ Copyright (C) 2011-2017 Free Software Foundation, Inc. --+ Contributed by Andrew Waterman (andrew@sifive.com). --+ Based on MIPS target for GNU compiler. --+ --+This file is part of GCC. --+ --+GCC is free software; you can redistribute it and/or modify --+it under the terms of the GNU General Public License as published by --+the Free Software Foundation; either version 3, or (at your option) --+any later version. --+ --+GCC is distributed in the hope that it will be useful, --+but WITHOUT ANY WARRANTY; without even the implied warranty of --+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the --+GNU General Public License for more details. --+ --+You should have received a copy of the GNU General Public License --+along with GCC; see the file COPYING3. If not see --+. */ --+ --+#ifndef GCC_RISCV_PROTOS_H --+#define GCC_RISCV_PROTOS_H --+ --+/* Symbol types we understand. The order of this list must match that of --+ the unspec enum in riscv.md, subsequent to UNSPEC_ADDRESS_FIRST. */ --+enum riscv_symbol_type { --+ SYMBOL_ABSOLUTE, --+ SYMBOL_PCREL, --+ SYMBOL_GOT_DISP, --+ SYMBOL_TLS, --+ SYMBOL_TLS_LE, --+ SYMBOL_TLS_IE, --+ SYMBOL_TLS_GD --+}; --+#define NUM_SYMBOL_TYPES (SYMBOL_TLS_GD + 1) --+ --+/* Routines implemented in riscv.c. */ --+extern enum riscv_symbol_type riscv_classify_symbolic_expression (rtx); --+extern bool riscv_symbolic_constant_p (rtx, enum riscv_symbol_type *); --+extern int riscv_regno_mode_ok_for_base_p (int, enum machine_mode, bool); --+extern bool riscv_hard_regno_mode_ok_p (unsigned int, enum machine_mode); --+extern int riscv_address_insns (rtx, enum machine_mode, bool); --+extern int riscv_const_insns (rtx); --+extern int riscv_split_const_insns (rtx); --+extern int riscv_load_store_insns (rtx, rtx_insn *); --+extern rtx riscv_emit_move (rtx, rtx); --+extern bool riscv_split_symbol (rtx, rtx, enum machine_mode, rtx *); --+extern bool riscv_split_symbol_type (enum riscv_symbol_type); --+extern rtx riscv_unspec_address (rtx, enum riscv_symbol_type); --+extern void riscv_move_integer (rtx, rtx, HOST_WIDE_INT); --+extern bool riscv_legitimize_move (enum machine_mode, rtx, rtx); --+extern rtx riscv_subword (rtx, bool); --+extern bool riscv_split_64bit_move_p (rtx, rtx); --+extern void riscv_split_doubleword_move (rtx, rtx); --+extern const char *riscv_output_move (rtx, rtx); --+extern const char *riscv_output_gpr_save (unsigned); --+#ifdef RTX_CODE --+extern void riscv_expand_int_scc (rtx, enum rtx_code, rtx, rtx); --+extern void riscv_expand_float_scc (rtx, enum rtx_code, rtx, rtx); --+extern void riscv_expand_conditional_branch (rtx, enum rtx_code, rtx, rtx); --+#endif --+extern rtx riscv_legitimize_call_address (rtx); --+extern void riscv_set_return_address (rtx, rtx); --+extern bool riscv_expand_block_move (rtx, rtx, rtx); --+extern rtx riscv_return_addr (int, rtx); --+extern HOST_WIDE_INT riscv_initial_elimination_offset (int, int); --+extern void riscv_expand_prologue (void); --+extern void riscv_expand_epilogue (bool); --+extern bool riscv_can_use_return_insn (void); --+extern rtx riscv_function_value (const_tree, const_tree, enum machine_mode); --+extern unsigned int riscv_hard_regno_nregs (int, enum machine_mode); --+ --+/* Routines implemented in riscv-c.c. */ --+void riscv_cpu_cpp_builtins (cpp_reader *); --+ --+/* Routines implemented in riscv-builtins.c. */ --+extern void riscv_atomic_assign_expand_fenv (tree *, tree *, tree *); --+extern rtx riscv_expand_builtin (tree, rtx, rtx, enum machine_mode, int); --+extern tree riscv_builtin_decl (unsigned int, bool); --+extern void riscv_init_builtins (void); --+ --+#endif /* ! GCC_RISCV_PROTOS_H */ --diff --git original-gcc/gcc/config/riscv/riscv.c gcc-6.3.0/gcc/config/riscv/riscv.c --new file mode 100644 --index 00000000000..834651f4214 ----- /dev/null --+++ gcc-6.3.0/gcc/config/riscv/riscv.c --@@ -0,0 +1,4138 @@ --+/* Subroutines used for code generation for RISC-V. --+ Copyright (C) 2011-2017 Free Software Foundation, Inc. --+ Contributed by Andrew Waterman (andrew@sifive.com). --+ Based on MIPS target for GNU compiler. --+ --+This file is part of GCC. --+ --+GCC is free software; you can redistribute it and/or modify --+it under the terms of the GNU General Public License as published by --+the Free Software Foundation; either version 3, or (at your option) --+any later version. --+ --+GCC is distributed in the hope that it will be useful, --+but WITHOUT ANY WARRANTY; without even the implied warranty of --+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the --+GNU General Public License for more details. --+ --+You should have received a copy of the GNU General Public License --+along with GCC; see the file COPYING3. If not see --+. */ --+ --+#include "config.h" --+#include "system.h" --+#include "coretypes.h" --+#include "tm.h" --+#include "rtl.h" --+#include "regs.h" --+#include "hard-reg-set.h" --+#include "insn-config.h" --+#include "conditions.h" --+#include "insn-attr.h" --+#include "recog.h" --+#include "output.h" --+#include "hash-set.h" --+#include "machmode.h" --+#include "vec.h" --+#include "double-int.h" --+#include "input.h" --+#include "alias.h" --+#include "symtab.h" --+#include "wide-int.h" --+#include "inchash.h" --+#include "tree.h" --+#include "fold-const.h" --+#include "varasm.h" --+#include "stringpool.h" --+#include "stor-layout.h" --+#include "calls.h" --+#include "function.h" --+#include "hashtab.h" --+#include "flags.h" --+#include "statistics.h" --+#include "real.h" --+#include "fixed-value.h" --+#include "expmed.h" --+#include "dojump.h" --+#include "explow.h" --+#include "memmodel.h" --+#include "emit-rtl.h" --+#include "stmt.h" --+#include "expr.h" --+#include "insn-codes.h" --+#include "optabs.h" --+#include "libfuncs.h" --+#include "reload.h" --+#include "tm_p.h" --+#include "ggc.h" --+#include "gstab.h" --+#include "hash-table.h" --+#include "debug.h" --+#include "target.h" --+#include "target-def.h" --+#include "common/common-target.h" --+#include "langhooks.h" --+#include "dominance.h" --+#include "cfg.h" --+#include "cfgrtl.h" --+#include "cfganal.h" --+#include "lcm.h" --+#include "cfgbuild.h" --+#include "cfgcleanup.h" --+#include "predict.h" --+#include "basic-block.h" --+#include "bitmap.h" --+#include "regset.h" --+#include "df.h" --+#include "sched-int.h" --+#include "tree-ssa-alias.h" --+#include "internal-fn.h" --+#include "gimple-fold.h" --+#include "tree-eh.h" --+#include "gimple-expr.h" --+#include "is-a.h" --+#include "gimple.h" --+#include "gimplify.h" --+#include "diagnostic.h" --+#include "target-globals.h" --+#include "opts.h" --+#include "tree-pass.h" --+#include "context.h" --+#include "hash-map.h" --+#include "plugin-api.h" --+#include "ipa-ref.h" --+#include "cgraph.h" --+#include "builtins.h" --+#include "rtl-iter.h" --+ --+/* True if X is an UNSPEC wrapper around a SYMBOL_REF or LABEL_REF. */ --+#define UNSPEC_ADDRESS_P(X) \ --+ (GET_CODE (X) == UNSPEC \ --+ && XINT (X, 1) >= UNSPEC_ADDRESS_FIRST \ --+ && XINT (X, 1) < UNSPEC_ADDRESS_FIRST + NUM_SYMBOL_TYPES) --+ --+/* Extract the symbol or label from UNSPEC wrapper X. */ --+#define UNSPEC_ADDRESS(X) \ --+ XVECEXP (X, 0, 0) --+ --+/* Extract the symbol type from UNSPEC wrapper X. */ --+#define UNSPEC_ADDRESS_TYPE(X) \ --+ ((enum riscv_symbol_type) (XINT (X, 1) - UNSPEC_ADDRESS_FIRST)) --+ --+/* True if bit BIT is set in VALUE. */ --+#define BITSET_P(VALUE, BIT) (((VALUE) & (1ULL << (BIT))) != 0) --+ --+/* Classifies an address. --+ --+ ADDRESS_REG --+ A natural register + offset address. The register satisfies --+ riscv_valid_base_register_p and the offset is a const_arith_operand. --+ --+ ADDRESS_LO_SUM --+ A LO_SUM rtx. The first operand is a valid base register and --+ the second operand is a symbolic address. --+ --+ ADDRESS_CONST_INT --+ A signed 16-bit constant address. --+ --+ ADDRESS_SYMBOLIC: --+ A constant symbolic address. */ --+enum riscv_address_type { --+ ADDRESS_REG, --+ ADDRESS_LO_SUM, --+ ADDRESS_CONST_INT, --+ ADDRESS_SYMBOLIC --+}; --+ --+/* Information about a function's frame layout. */ --+struct GTY(()) riscv_frame_info { --+ /* The size of the frame in bytes. */ --+ HOST_WIDE_INT total_size; --+ --+ /* Bit X is set if the function saves or restores GPR X. */ --+ unsigned int mask; --+ --+ /* Likewise FPR X. */ --+ unsigned int fmask; --+ --+ /* How much the GPR save/restore routines adjust sp (or 0 if unused). */ --+ unsigned save_libcall_adjustment; --+ --+ /* Offsets of fixed-point and floating-point save areas from frame bottom */ --+ HOST_WIDE_INT gp_sp_offset; --+ HOST_WIDE_INT fp_sp_offset; --+ --+ /* Offset of virtual frame pointer from stack pointer/frame bottom */ --+ HOST_WIDE_INT frame_pointer_offset; --+ --+ /* Offset of hard frame pointer from stack pointer/frame bottom */ --+ HOST_WIDE_INT hard_frame_pointer_offset; --+ --+ /* The offset of arg_pointer_rtx from the bottom of the frame. */ --+ HOST_WIDE_INT arg_pointer_offset; --+}; --+ --+struct GTY(()) machine_function { --+ /* The number of extra stack bytes taken up by register varargs. --+ This area is allocated by the callee at the very top of the frame. */ --+ int varargs_size; --+ --+ /* Memoized return value of leaf_function_p. <0 if false, >0 if true. */ --+ int is_leaf; --+ --+ /* The current frame information, calculated by riscv_compute_frame_info. */ --+ struct riscv_frame_info frame; --+}; --+ --+/* Information about a single argument. */ --+struct riscv_arg_info { --+ /* True if the argument is at least partially passed on the stack. */ --+ bool stack_p; --+ --+ /* The number of integer registers allocated to this argument. */ --+ unsigned int num_gprs; --+ --+ /* The offset of the first register used, provided num_gprs is nonzero. --+ If passed entirely on the stack, the value is MAX_ARGS_IN_REGISTERS. */ --+ unsigned int gpr_offset; --+ --+ /* The number of floating-point registers allocated to this argument. */ --+ unsigned int num_fprs; --+ --+ /* The offset of the first register used, provided num_fprs is nonzero. */ --+ unsigned int fpr_offset; --+}; --+ --+/* Information about an address described by riscv_address_type. --+ --+ ADDRESS_CONST_INT --+ No fields are used. --+ --+ ADDRESS_REG --+ REG is the base register and OFFSET is the constant offset. --+ --+ ADDRESS_LO_SUM --+ REG and OFFSET are the operands to the LO_SUM and SYMBOL_TYPE --+ is the type of symbol it references. --+ --+ ADDRESS_SYMBOLIC --+ SYMBOL_TYPE is the type of symbol that the address references. */ --+struct riscv_address_info { --+ enum riscv_address_type type; --+ rtx reg; --+ rtx offset; --+ enum riscv_symbol_type symbol_type; --+}; --+ --+/* One stage in a constant building sequence. These sequences have --+ the form: --+ --+ A = VALUE[0] --+ A = A CODE[1] VALUE[1] --+ A = A CODE[2] VALUE[2] --+ ... --+ --+ where A is an accumulator, each CODE[i] is a binary rtl operation --+ and each VALUE[i] is a constant integer. CODE[0] is undefined. */ --+struct riscv_integer_op { --+ enum rtx_code code; --+ unsigned HOST_WIDE_INT value; --+}; --+ --+/* The largest number of operations needed to load an integer constant. --+ The worst case is LUI, ADDI, SLLI, ADDI, SLLI, ADDI, SLLI, ADDI. */ --+#define RISCV_MAX_INTEGER_OPS 8 --+ --+/* Costs of various operations on the different architectures. */ --+ --+struct riscv_tune_info --+{ --+ unsigned short fp_add[2]; --+ unsigned short fp_mul[2]; --+ unsigned short fp_div[2]; --+ unsigned short int_mul[2]; --+ unsigned short int_div[2]; --+ unsigned short issue_rate; --+ unsigned short branch_cost; --+ unsigned short memory_cost; --+}; --+ --+/* Information about one CPU we know about. */ --+struct riscv_cpu_info { --+ /* This CPU's canonical name. */ --+ const char *name; --+ --+ /* Tuning parameters for this CPU. */ --+ const struct riscv_tune_info *tune_info; --+}; --+ --+/* Global variables for machine-dependent things. */ --+ --+/* Which tuning parameters to use. */ --+static const struct riscv_tune_info *tune_info; --+ --+/* Index R is the smallest register class that contains register R. */ --+const enum reg_class riscv_regno_to_class[FIRST_PSEUDO_REGISTER] = { --+ GR_REGS, GR_REGS, GR_REGS, GR_REGS, --+ GR_REGS, GR_REGS, SIBCALL_REGS, SIBCALL_REGS, --+ JALR_REGS, JALR_REGS, JALR_REGS, JALR_REGS, --+ JALR_REGS, JALR_REGS, JALR_REGS, JALR_REGS, --+ JALR_REGS, JALR_REGS, JALR_REGS, JALR_REGS, --+ JALR_REGS, JALR_REGS, JALR_REGS, JALR_REGS, --+ JALR_REGS, JALR_REGS, JALR_REGS, JALR_REGS, --+ SIBCALL_REGS, SIBCALL_REGS, SIBCALL_REGS, SIBCALL_REGS, --+ FP_REGS, FP_REGS, FP_REGS, FP_REGS, --+ FP_REGS, FP_REGS, FP_REGS, FP_REGS, --+ FP_REGS, FP_REGS, FP_REGS, FP_REGS, --+ FP_REGS, FP_REGS, FP_REGS, FP_REGS, --+ FP_REGS, FP_REGS, FP_REGS, FP_REGS, --+ FP_REGS, FP_REGS, FP_REGS, FP_REGS, --+ FP_REGS, FP_REGS, FP_REGS, FP_REGS, --+ FP_REGS, FP_REGS, FP_REGS, FP_REGS, --+ FRAME_REGS, FRAME_REGS, --+}; --+ --+/* Costs to use when optimizing for rocket. */ --+static const struct riscv_tune_info rocket_tune_info = { --+ {COSTS_N_INSNS (4), COSTS_N_INSNS (5)}, /* fp_add */ --+ {COSTS_N_INSNS (4), COSTS_N_INSNS (5)}, /* fp_mul */ --+ {COSTS_N_INSNS (20), COSTS_N_INSNS (20)}, /* fp_div */ --+ {COSTS_N_INSNS (4), COSTS_N_INSNS (4)}, /* int_mul */ --+ {COSTS_N_INSNS (6), COSTS_N_INSNS (6)}, /* int_div */ --+ 1, /* issue_rate */ --+ 3, /* branch_cost */ --+ 5 /* memory_cost */ --+}; --+ --+/* Costs to use when optimizing for size. */ --+static const struct riscv_tune_info optimize_size_tune_info = { --+ {COSTS_N_INSNS (1), COSTS_N_INSNS (1)}, /* fp_add */ --+ {COSTS_N_INSNS (1), COSTS_N_INSNS (1)}, /* fp_mul */ --+ {COSTS_N_INSNS (1), COSTS_N_INSNS (1)}, /* fp_div */ --+ {COSTS_N_INSNS (1), COSTS_N_INSNS (1)}, /* int_mul */ --+ {COSTS_N_INSNS (1), COSTS_N_INSNS (1)}, /* int_div */ --+ 1, /* issue_rate */ --+ 1, /* branch_cost */ --+ 2 /* memory_cost */ --+}; --+ --+/* A table describing all the processors GCC knows about. */ --+static const struct riscv_cpu_info riscv_cpu_info_table[] = { --+ { "rocket", &rocket_tune_info }, --+}; --+ --+/* Return the riscv_cpu_info entry for the given name string. */ --+ --+static const struct riscv_cpu_info * --+riscv_parse_cpu (const char *cpu_string) --+{ --+ for (unsigned i = 0; i < ARRAY_SIZE (riscv_cpu_info_table); i++) --+ if (strcmp (riscv_cpu_info_table[i].name, cpu_string) == 0) --+ return riscv_cpu_info_table + i; --+ --+ error ("unknown cpu %qs for -mtune", cpu_string); --+ return riscv_cpu_info_table; --+} --+ --+/* Helper function for riscv_build_integer; arguments are as for --+ riscv_build_integer. */ --+ --+static int --+riscv_build_integer_1 (struct riscv_integer_op codes[RISCV_MAX_INTEGER_OPS], --+ HOST_WIDE_INT value, enum machine_mode mode) --+{ --+ HOST_WIDE_INT low_part = CONST_LOW_PART (value); --+ int cost = RISCV_MAX_INTEGER_OPS + 1, alt_cost; --+ struct riscv_integer_op alt_codes[RISCV_MAX_INTEGER_OPS]; --+ --+ if (SMALL_OPERAND (value) || LUI_OPERAND (value)) --+ { --+ /* Simply ADDI or LUI. */ --+ codes[0].code = UNKNOWN; --+ codes[0].value = value; --+ return 1; --+ } --+ --+ /* End with ADDI. When constructing HImode constants, do not generate any --+ intermediate value that is not itself a valid HImode constant. The --+ XORI case below will handle those remaining HImode constants. */ --+ if (low_part != 0 && (mode != HImode || value - low_part <= INT16_MAX)) --+ { --+ alt_cost = 1 + riscv_build_integer_1 (alt_codes, value - low_part, mode); --+ if (alt_cost < cost) --+ { --+ alt_codes[alt_cost-1].code = PLUS; --+ alt_codes[alt_cost-1].value = low_part; --+ memcpy (codes, alt_codes, sizeof (alt_codes)); --+ cost = alt_cost; --+ } --+ } --+ --+ /* End with XORI. */ --+ if (cost > 2 && (low_part < 0 || mode == HImode)) --+ { --+ alt_cost = 1 + riscv_build_integer_1 (alt_codes, value ^ low_part, mode); --+ if (alt_cost < cost) --+ { --+ alt_codes[alt_cost-1].code = XOR; --+ alt_codes[alt_cost-1].value = low_part; --+ memcpy (codes, alt_codes, sizeof (alt_codes)); --+ cost = alt_cost; --+ } --+ } --+ --+ /* Eliminate trailing zeros and end with SLLI. */ --+ if (cost > 2 && (value & 1) == 0) --+ { --+ int shift = ctz_hwi (value); --+ unsigned HOST_WIDE_INT x = value; --+ x = sext_hwi (x >> shift, HOST_BITS_PER_WIDE_INT - shift); --+ --+ /* Don't eliminate the lower 12 bits if LUI might apply. */ --+ if (shift > IMM_BITS && !SMALL_OPERAND (x) && LUI_OPERAND (x << IMM_BITS)) --+ shift -= IMM_BITS, x <<= IMM_BITS; --+ --+ alt_cost = 1 + riscv_build_integer_1 (alt_codes, x, mode); --+ if (alt_cost < cost) --+ { --+ alt_codes[alt_cost-1].code = ASHIFT; --+ alt_codes[alt_cost-1].value = shift; --+ memcpy (codes, alt_codes, sizeof (alt_codes)); --+ cost = alt_cost; --+ } --+ } --+ --+ gcc_assert (cost <= RISCV_MAX_INTEGER_OPS); --+ return cost; --+} --+ --+/* Fill CODES with a sequence of rtl operations to load VALUE. --+ Return the number of operations needed. */ --+ --+static int --+riscv_build_integer (struct riscv_integer_op *codes, HOST_WIDE_INT value, --+ enum machine_mode mode) --+{ --+ int cost = riscv_build_integer_1 (codes, value, mode); --+ --+ /* Eliminate leading zeros and end with SRLI. */ --+ if (value > 0 && cost > 2) --+ { --+ struct riscv_integer_op alt_codes[RISCV_MAX_INTEGER_OPS]; --+ int alt_cost, shift = clz_hwi (value); --+ HOST_WIDE_INT shifted_val; --+ --+ /* Try filling trailing bits with 1s. */ --+ shifted_val = (value << shift) | ((((HOST_WIDE_INT) 1) << shift) - 1); --+ alt_cost = 1 + riscv_build_integer_1 (alt_codes, shifted_val, mode); --+ if (alt_cost < cost) --+ { --+ alt_codes[alt_cost-1].code = LSHIFTRT; --+ alt_codes[alt_cost-1].value = shift; --+ memcpy (codes, alt_codes, sizeof (alt_codes)); --+ cost = alt_cost; --+ } --+ --+ /* Try filling trailing bits with 0s. */ --+ shifted_val = value << shift; --+ alt_cost = 1 + riscv_build_integer_1 (alt_codes, shifted_val, mode); --+ if (alt_cost < cost) --+ { --+ alt_codes[alt_cost-1].code = LSHIFTRT; --+ alt_codes[alt_cost-1].value = shift; --+ memcpy (codes, alt_codes, sizeof (alt_codes)); --+ cost = alt_cost; --+ } --+ } --+ --+ return cost; --+} --+ --+/* Return the cost of constructing VAL in the event that a scratch --+ register is available. */ --+ --+static int --+riscv_split_integer_cost (HOST_WIDE_INT val) --+{ --+ int cost; --+ unsigned HOST_WIDE_INT loval = sext_hwi (val, 32); --+ unsigned HOST_WIDE_INT hival = sext_hwi ((val - loval) >> 32, 32); --+ struct riscv_integer_op codes[RISCV_MAX_INTEGER_OPS]; --+ --+ cost = 2 + riscv_build_integer (codes, loval, VOIDmode); --+ if (loval != hival) --+ cost += riscv_build_integer (codes, hival, VOIDmode); --+ --+ return cost; --+} --+ --+/* Return the cost of constructing the integer constant VAL. */ --+ --+static int --+riscv_integer_cost (HOST_WIDE_INT val) --+{ --+ struct riscv_integer_op codes[RISCV_MAX_INTEGER_OPS]; --+ return MIN (riscv_build_integer (codes, val, VOIDmode), --+ riscv_split_integer_cost (val)); --+} --+ --+/* Try to split a 64b integer into 32b parts, then reassemble. */ --+ --+static rtx --+riscv_split_integer (HOST_WIDE_INT val, enum machine_mode mode) --+{ --+ unsigned HOST_WIDE_INT loval = sext_hwi (val, 32); --+ unsigned HOST_WIDE_INT hival = sext_hwi ((val - loval) >> 32, 32); --+ rtx hi = gen_reg_rtx (mode), lo = gen_reg_rtx (mode); --+ --+ riscv_move_integer (hi, hi, hival); --+ riscv_move_integer (lo, lo, loval); --+ --+ hi = gen_rtx_fmt_ee (ASHIFT, mode, hi, GEN_INT (32)); --+ hi = force_reg (mode, hi); --+ --+ return gen_rtx_fmt_ee (PLUS, mode, hi, lo); --+} --+ --+/* Return true if X is a thread-local symbol. */ --+ --+static bool --+riscv_tls_symbol_p (const_rtx x) --+{ --+ return SYMBOL_REF_P (x) && SYMBOL_REF_TLS_MODEL (x) != 0; --+} --+ --+/* Return true if symbol X binds locally. */ --+ --+static bool --+riscv_symbol_binds_local_p (const_rtx x) --+{ --+ if (SYMBOL_REF_P (x)) --+ return (SYMBOL_REF_DECL (x) --+ ? targetm.binds_local_p (SYMBOL_REF_DECL (x)) --+ : SYMBOL_REF_LOCAL_P (x)); --+ else --+ return false; --+} --+ --+/* Return the method that should be used to access SYMBOL_REF or --+ LABEL_REF X. */ --+ --+static enum riscv_symbol_type --+riscv_classify_symbol (const_rtx x) --+{ --+ if (riscv_tls_symbol_p (x)) --+ return SYMBOL_TLS; --+ --+ if (GET_CODE (x) == SYMBOL_REF && flag_pic && !riscv_symbol_binds_local_p (x)) --+ return SYMBOL_GOT_DISP; --+ --+ return riscv_cmodel == CM_MEDLOW ? SYMBOL_ABSOLUTE : SYMBOL_PCREL; --+} --+ --+/* Classify the base of symbolic expression X. */ --+ --+enum riscv_symbol_type --+riscv_classify_symbolic_expression (rtx x) --+{ --+ rtx offset; --+ --+ split_const (x, &x, &offset); --+ if (UNSPEC_ADDRESS_P (x)) --+ return UNSPEC_ADDRESS_TYPE (x); --+ --+ return riscv_classify_symbol (x); --+} --+ --+/* Return true if X is a symbolic constant. If it is, store the type of --+ the symbol in *SYMBOL_TYPE. */ --+ --+bool --+riscv_symbolic_constant_p (rtx x, enum riscv_symbol_type *symbol_type) --+{ --+ rtx offset; --+ --+ split_const (x, &x, &offset); --+ if (UNSPEC_ADDRESS_P (x)) --+ { --+ *symbol_type = UNSPEC_ADDRESS_TYPE (x); --+ x = UNSPEC_ADDRESS (x); --+ } --+ else if (GET_CODE (x) == SYMBOL_REF || GET_CODE (x) == LABEL_REF) --+ *symbol_type = riscv_classify_symbol (x); --+ else --+ return false; --+ --+ if (offset == const0_rtx) --+ return true; --+ --+ /* Nonzero offsets are only valid for references that don't use the GOT. */ --+ switch (*symbol_type) --+ { --+ case SYMBOL_ABSOLUTE: --+ case SYMBOL_PCREL: --+ case SYMBOL_TLS_LE: --+ /* GAS rejects offsets outside the range [-2^31, 2^31-1]. */ --+ return sext_hwi (INTVAL (offset), 32) == INTVAL (offset); --+ --+ default: --+ return false; --+ } --+} --+ --+/* Returns the number of instructions necessary to reference a symbol. */ --+ --+static int riscv_symbol_insns (enum riscv_symbol_type type) --+{ --+ switch (type) --+ { --+ case SYMBOL_TLS: return 0; /* Depends on the TLS model. */ --+ case SYMBOL_ABSOLUTE: return 2; /* LUI + the reference. */ --+ case SYMBOL_PCREL: return 2; /* AUIPC + the reference. */ --+ case SYMBOL_TLS_LE: return 3; /* LUI + ADD TP + the reference. */ --+ case SYMBOL_GOT_DISP: return 3; /* AUIPC + LD GOT + the reference. */ --+ default: gcc_unreachable (); --+ } --+} --+ --+/* Implement TARGET_LEGITIMATE_CONSTANT_P. */ --+ --+static bool --+riscv_legitimate_constant_p (enum machine_mode mode ATTRIBUTE_UNUSED, rtx x) --+{ --+ return riscv_const_insns (x) > 0; --+} --+ --+/* Implement TARGET_CANNOT_FORCE_CONST_MEM. */ --+ --+static bool --+riscv_cannot_force_const_mem (enum machine_mode mode ATTRIBUTE_UNUSED, rtx x) --+{ --+ enum riscv_symbol_type type; --+ rtx base, offset; --+ --+ /* There is no assembler syntax for expressing an address-sized --+ high part. */ --+ if (GET_CODE (x) == HIGH) --+ return true; --+ --+ split_const (x, &base, &offset); --+ if (riscv_symbolic_constant_p (base, &type)) --+ { --+ /* As an optimization, don't spill symbolic constants that are as --+ cheap to rematerialize as to access in the constant pool. */ --+ if (SMALL_OPERAND (INTVAL (offset)) && riscv_symbol_insns (type) > 0) --+ return true; --+ --+ /* As an optimization, avoid needlessly generate dynamic relocations. */ --+ if (flag_pic) --+ return true; --+ } --+ --+ /* TLS symbols must be computed by riscv_legitimize_move. */ --+ if (tls_referenced_p (x)) --+ return true; --+ --+ return false; --+} --+ --+/* Return true if register REGNO is a valid base register for mode MODE. --+ STRICT_P is true if REG_OK_STRICT is in effect. */ --+ --+int --+riscv_regno_mode_ok_for_base_p (int regno, --+ enum machine_mode mode ATTRIBUTE_UNUSED, --+ bool strict_p) --+{ --+ if (!HARD_REGISTER_NUM_P (regno)) --+ { --+ if (!strict_p) --+ return true; --+ regno = reg_renumber[regno]; --+ } --+ --+ /* These fake registers will be eliminated to either the stack or --+ hard frame pointer, both of which are usually valid base registers. --+ Reload deals with the cases where the eliminated form isn't valid. */ --+ if (regno == ARG_POINTER_REGNUM || regno == FRAME_POINTER_REGNUM) --+ return true; --+ --+ return GP_REG_P (regno); --+} --+ --+/* Return true if X is a valid base register for mode MODE. --+ STRICT_P is true if REG_OK_STRICT is in effect. */ --+ --+static bool --+riscv_valid_base_register_p (rtx x, enum machine_mode mode, bool strict_p) --+{ --+ if (!strict_p && GET_CODE (x) == SUBREG) --+ x = SUBREG_REG (x); --+ --+ return (REG_P (x) --+ && riscv_regno_mode_ok_for_base_p (REGNO (x), mode, strict_p)); --+} --+ --+/* Return true if, for every base register BASE_REG, (plus BASE_REG X) --+ can address a value of mode MODE. */ --+ --+static bool --+riscv_valid_offset_p (rtx x, enum machine_mode mode) --+{ --+ /* Check that X is a signed 12-bit number. */ --+ if (!const_arith_operand (x, Pmode)) --+ return false; --+ --+ /* We may need to split multiword moves, so make sure that every word --+ is accessible. */ --+ if (GET_MODE_SIZE (mode) > UNITS_PER_WORD --+ && !SMALL_OPERAND (INTVAL (x) + GET_MODE_SIZE (mode) - UNITS_PER_WORD)) --+ return false; --+ --+ return true; --+} --+ --+/* Should a symbol of type SYMBOL_TYPE should be split in two? */ --+ --+bool --+riscv_split_symbol_type (enum riscv_symbol_type symbol_type) --+{ --+ if (symbol_type == SYMBOL_TLS_LE) --+ return true; --+ --+ if (!TARGET_EXPLICIT_RELOCS) --+ return false; --+ --+ return symbol_type == SYMBOL_ABSOLUTE || symbol_type == SYMBOL_PCREL; --+} --+ --+/* Return true if a LO_SUM can address a value of mode MODE when the --+ LO_SUM symbol has type SYM_TYPE. */ --+ --+static bool --+riscv_valid_lo_sum_p (enum riscv_symbol_type sym_type, enum machine_mode mode) --+{ --+ /* Check that symbols of type SYMBOL_TYPE can be used to access values --+ of mode MODE. */ --+ if (riscv_symbol_insns (sym_type) == 0) --+ return false; --+ --+ /* Check that there is a known low-part relocation. */ --+ if (!riscv_split_symbol_type (sym_type)) --+ return false; --+ --+ /* We may need to split multiword moves, so make sure that each word --+ can be accessed without inducing a carry. */ --+ if (GET_MODE_SIZE (mode) > UNITS_PER_WORD --+ && GET_MODE_BITSIZE (mode) > GET_MODE_ALIGNMENT (mode)) --+ return false; --+ --+ return true; --+} --+ --+/* Return true if X is a valid address for machine mode MODE. If it is, --+ fill in INFO appropriately. STRICT_P is true if REG_OK_STRICT is in --+ effect. */ --+ --+static bool --+riscv_classify_address (struct riscv_address_info *info, rtx x, --+ enum machine_mode mode, bool strict_p) --+{ --+ switch (GET_CODE (x)) --+ { --+ case REG: --+ case SUBREG: --+ info->type = ADDRESS_REG; --+ info->reg = x; --+ info->offset = const0_rtx; --+ return riscv_valid_base_register_p (info->reg, mode, strict_p); --+ --+ case PLUS: --+ info->type = ADDRESS_REG; --+ info->reg = XEXP (x, 0); --+ info->offset = XEXP (x, 1); --+ return (riscv_valid_base_register_p (info->reg, mode, strict_p) --+ && riscv_valid_offset_p (info->offset, mode)); --+ --+ case LO_SUM: --+ info->type = ADDRESS_LO_SUM; --+ info->reg = XEXP (x, 0); --+ info->offset = XEXP (x, 1); --+ /* We have to trust the creator of the LO_SUM to do something vaguely --+ sane. Target-independent code that creates a LO_SUM should also --+ create and verify the matching HIGH. Target-independent code that --+ adds an offset to a LO_SUM must prove that the offset will not --+ induce a carry. Failure to do either of these things would be --+ a bug, and we are not required to check for it here. The RISC-V --+ backend itself should only create LO_SUMs for valid symbolic --+ constants, with the high part being either a HIGH or a copy --+ of _gp. */ --+ info->symbol_type --+ = riscv_classify_symbolic_expression (info->offset); --+ return (riscv_valid_base_register_p (info->reg, mode, strict_p) --+ && riscv_valid_lo_sum_p (info->symbol_type, mode)); --+ --+ case CONST_INT: --+ /* Small-integer addresses don't occur very often, but they --+ are legitimate if x0 is a valid base register. */ --+ info->type = ADDRESS_CONST_INT; --+ return SMALL_OPERAND (INTVAL (x)); --+ --+ default: --+ return false; --+ } --+} --+ --+/* Implement TARGET_LEGITIMATE_ADDRESS_P. */ --+ --+static bool --+riscv_legitimate_address_p (enum machine_mode mode, rtx x, bool strict_p) --+{ --+ struct riscv_address_info addr; --+ --+ return riscv_classify_address (&addr, x, mode, strict_p); --+} --+ --+/* Return the number of instructions needed to load or store a value --+ of mode MODE at address X. Return 0 if X isn't valid for MODE. --+ Assume that multiword moves may need to be split into word moves --+ if MIGHT_SPLIT_P, otherwise assume that a single load or store is --+ enough. */ --+ --+int --+riscv_address_insns (rtx x, enum machine_mode mode, bool might_split_p) --+{ --+ struct riscv_address_info addr; --+ int n = 1; --+ --+ if (!riscv_classify_address (&addr, x, mode, false)) --+ return 0; --+ --+ /* BLKmode is used for single unaligned loads and stores and should --+ not count as a multiword mode. */ --+ if (mode != BLKmode && might_split_p) --+ n += (GET_MODE_SIZE (mode) + UNITS_PER_WORD - 1) / UNITS_PER_WORD; --+ --+ if (addr.type == ADDRESS_LO_SUM) --+ n += riscv_symbol_insns (addr.symbol_type) - 1; --+ --+ return n; --+} --+ --+/* Return the number of instructions needed to load constant X. --+ Return 0 if X isn't a valid constant. */ --+ --+int --+riscv_const_insns (rtx x) --+{ --+ enum riscv_symbol_type symbol_type; --+ rtx offset; --+ --+ switch (GET_CODE (x)) --+ { --+ case HIGH: --+ if (!riscv_symbolic_constant_p (XEXP (x, 0), &symbol_type) --+ || !riscv_split_symbol_type (symbol_type)) --+ return 0; --+ --+ /* This is simply an LUI. */ --+ return 1; --+ --+ case CONST_INT: --+ { --+ int cost = riscv_integer_cost (INTVAL (x)); --+ /* Force complicated constants to memory. */ --+ return cost < 4 ? cost : 0; --+ } --+ --+ case CONST_DOUBLE: --+ case CONST_VECTOR: --+ /* We can use x0 to load floating-point zero. */ --+ return x == CONST0_RTX (GET_MODE (x)) ? 1 : 0; --+ --+ case CONST: --+ /* See if we can refer to X directly. */ --+ if (riscv_symbolic_constant_p (x, &symbol_type)) --+ return riscv_symbol_insns (symbol_type); --+ --+ /* Otherwise try splitting the constant into a base and offset. */ --+ split_const (x, &x, &offset); --+ if (offset != 0) --+ { --+ int n = riscv_const_insns (x); --+ if (n != 0) --+ return n + riscv_integer_cost (INTVAL (offset)); --+ } --+ return 0; --+ --+ case SYMBOL_REF: --+ case LABEL_REF: --+ return riscv_symbol_insns (riscv_classify_symbol (x)); --+ --+ default: --+ return 0; --+ } --+} --+ --+/* X is a doubleword constant that can be handled by splitting it into --+ two words and loading each word separately. Return the number of --+ instructions required to do this. */ --+ --+int --+riscv_split_const_insns (rtx x) --+{ --+ unsigned int low, high; --+ --+ low = riscv_const_insns (riscv_subword (x, false)); --+ high = riscv_const_insns (riscv_subword (x, true)); --+ gcc_assert (low > 0 && high > 0); --+ return low + high; --+} --+ --+/* Return the number of instructions needed to implement INSN, --+ given that it loads from or stores to MEM. */ --+ --+int --+riscv_load_store_insns (rtx mem, rtx_insn *insn) --+{ --+ enum machine_mode mode; --+ bool might_split_p; --+ rtx set; --+ --+ gcc_assert (MEM_P (mem)); --+ mode = GET_MODE (mem); --+ --+ /* Try to prove that INSN does not need to be split. */ --+ might_split_p = true; --+ if (GET_MODE_BITSIZE (mode) <= 32) --+ might_split_p = false; --+ else if (GET_MODE_BITSIZE (mode) == 64) --+ { --+ set = single_set (insn); --+ if (set && !riscv_split_64bit_move_p (SET_DEST (set), SET_SRC (set))) --+ might_split_p = false; --+ } --+ --+ return riscv_address_insns (XEXP (mem, 0), mode, might_split_p); --+} --+ --+/* Emit a move from SRC to DEST. Assume that the move expanders can --+ handle all moves if !can_create_pseudo_p (). The distinction is --+ important because, unlike emit_move_insn, the move expanders know --+ how to force Pmode objects into the constant pool even when the --+ constant pool address is not itself legitimate. */ --+ --+rtx --+riscv_emit_move (rtx dest, rtx src) --+{ --+ return (can_create_pseudo_p () --+ ? emit_move_insn (dest, src) --+ : emit_move_insn_1 (dest, src)); --+} --+ --+/* Emit an instruction of the form (set TARGET SRC). */ --+ --+static rtx --+riscv_emit_set (rtx target, rtx src) --+{ --+ emit_insn (gen_rtx_SET (target, src)); --+ return target; --+} --+ --+/* Emit an instruction of the form (set DEST (CODE X Y)). */ --+ --+static rtx --+riscv_emit_binary (enum rtx_code code, rtx dest, rtx x, rtx y) --+{ --+ return riscv_emit_set (dest, gen_rtx_fmt_ee (code, GET_MODE (dest), x, y)); --+} --+ --+/* Compute (CODE X Y) and store the result in a new register --+ of mode MODE. Return that new register. */ --+ --+static rtx --+riscv_force_binary (enum machine_mode mode, enum rtx_code code, rtx x, rtx y) --+{ --+ return riscv_emit_binary (code, gen_reg_rtx (mode), x, y); --+} --+ --+/* Copy VALUE to a register and return that register. If new pseudos --+ are allowed, copy it into a new register, otherwise use DEST. */ --+ --+static rtx --+riscv_force_temporary (rtx dest, rtx value) --+{ --+ if (can_create_pseudo_p ()) --+ return force_reg (Pmode, value); --+ else --+ { --+ riscv_emit_move (dest, value); --+ return dest; --+ } --+} --+ --+/* Wrap symbol or label BASE in an UNSPEC address of type SYMBOL_TYPE, --+ then add CONST_INT OFFSET to the result. */ --+ --+static rtx --+riscv_unspec_address_offset (rtx base, rtx offset, --+ enum riscv_symbol_type symbol_type) --+{ --+ base = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, base), --+ UNSPEC_ADDRESS_FIRST + symbol_type); --+ if (offset != const0_rtx) --+ base = gen_rtx_PLUS (Pmode, base, offset); --+ return gen_rtx_CONST (Pmode, base); --+} --+ --+/* Return an UNSPEC address with underlying address ADDRESS and symbol --+ type SYMBOL_TYPE. */ --+ --+rtx --+riscv_unspec_address (rtx address, enum riscv_symbol_type symbol_type) --+{ --+ rtx base, offset; --+ --+ split_const (address, &base, &offset); --+ return riscv_unspec_address_offset (base, offset, symbol_type); --+} --+ --+/* If OP is an UNSPEC address, return the address to which it refers, --+ otherwise return OP itself. */ --+ --+static rtx --+riscv_strip_unspec_address (rtx op) --+{ --+ rtx base, offset; --+ --+ split_const (op, &base, &offset); --+ if (UNSPEC_ADDRESS_P (base)) --+ op = plus_constant (Pmode, UNSPEC_ADDRESS (base), INTVAL (offset)); --+ return op; --+} --+ --+/* If riscv_unspec_address (ADDR, SYMBOL_TYPE) is a 32-bit value, add the --+ high part to BASE and return the result. Just return BASE otherwise. --+ TEMP is as for riscv_force_temporary. --+ --+ The returned expression can be used as the first operand to a LO_SUM. */ --+ --+static rtx --+riscv_unspec_offset_high (rtx temp, rtx addr, enum riscv_symbol_type symbol_type) --+{ --+ addr = gen_rtx_HIGH (Pmode, riscv_unspec_address (addr, symbol_type)); --+ return riscv_force_temporary (temp, addr); --+} --+ --+/* Load an entry from the GOT for a TLS GD access. */ --+ --+static rtx riscv_got_load_tls_gd (rtx dest, rtx sym) --+{ --+ if (Pmode == DImode) --+ return gen_got_load_tls_gddi (dest, sym); --+ else --+ return gen_got_load_tls_gdsi (dest, sym); --+} --+ --+/* Load an entry from the GOT for a TLS IE access. */ --+ --+static rtx riscv_got_load_tls_ie (rtx dest, rtx sym) --+{ --+ if (Pmode == DImode) --+ return gen_got_load_tls_iedi (dest, sym); --+ else --+ return gen_got_load_tls_iesi (dest, sym); --+} --+ --+/* Add in the thread pointer for a TLS LE access. */ --+ --+static rtx riscv_tls_add_tp_le (rtx dest, rtx base, rtx sym) --+{ --+ rtx tp = gen_rtx_REG (Pmode, THREAD_POINTER_REGNUM); --+ if (Pmode == DImode) --+ return gen_tls_add_tp_ledi (dest, base, tp, sym); --+ else --+ return gen_tls_add_tp_lesi (dest, base, tp, sym); --+} --+ --+/* If MODE is MAX_MACHINE_MODE, ADDR appears as a move operand, otherwise --+ it appears in a MEM of that mode. Return true if ADDR is a legitimate --+ constant in that context and can be split into high and low parts. --+ If so, and if LOW_OUT is nonnull, emit the high part and store the --+ low part in *LOW_OUT. Leave *LOW_OUT unchanged otherwise. --+ --+ TEMP is as for riscv_force_temporary and is used to load the high --+ part into a register. --+ --+ When MODE is MAX_MACHINE_MODE, the low part is guaranteed to be --+ a legitimize SET_SRC for an .md pattern, otherwise the low part --+ is guaranteed to be a legitimate address for mode MODE. */ --+ --+bool --+riscv_split_symbol (rtx temp, rtx addr, enum machine_mode mode, rtx *low_out) --+{ --+ enum riscv_symbol_type symbol_type; --+ --+ if ((GET_CODE (addr) == HIGH && mode == MAX_MACHINE_MODE) --+ || !riscv_symbolic_constant_p (addr, &symbol_type) --+ || riscv_symbol_insns (symbol_type) == 0 --+ || !riscv_split_symbol_type (symbol_type)) --+ return false; --+ --+ if (low_out) --+ switch (symbol_type) --+ { --+ case SYMBOL_ABSOLUTE: --+ { --+ rtx high = gen_rtx_HIGH (Pmode, copy_rtx (addr)); --+ high = riscv_force_temporary (temp, high); --+ *low_out = gen_rtx_LO_SUM (Pmode, high, addr); --+ } --+ break; --+ --+ case SYMBOL_PCREL: --+ { --+ static unsigned seqno; --+ char buf[32]; --+ rtx label; --+ --+ ssize_t bytes = snprintf (buf, sizeof (buf), ".LA%u", seqno); --+ gcc_assert ((size_t) bytes < sizeof (buf)); --+ --+ label = gen_rtx_SYMBOL_REF (Pmode, ggc_strdup (buf)); --+ SYMBOL_REF_FLAGS (label) |= SYMBOL_FLAG_LOCAL; --+ --+ if (temp == NULL) --+ temp = gen_reg_rtx (Pmode); --+ --+ if (Pmode == DImode) --+ emit_insn (gen_auipcdi (temp, copy_rtx (addr), GEN_INT (seqno))); --+ else --+ emit_insn (gen_auipcsi (temp, copy_rtx (addr), GEN_INT (seqno))); --+ --+ *low_out = gen_rtx_LO_SUM (Pmode, temp, label); --+ --+ seqno++; --+ } --+ break; --+ --+ default: --+ gcc_unreachable (); --+ } --+ --+ return true; --+} --+ --+/* Return a legitimate address for REG + OFFSET. TEMP is as for --+ riscv_force_temporary; it is only needed when OFFSET is not a --+ SMALL_OPERAND. */ --+ --+static rtx --+riscv_add_offset (rtx temp, rtx reg, HOST_WIDE_INT offset) --+{ --+ if (!SMALL_OPERAND (offset)) --+ { --+ rtx high; --+ --+ /* Leave OFFSET as a 16-bit offset and put the excess in HIGH. --+ The addition inside the macro CONST_HIGH_PART may cause an --+ overflow, so we need to force a sign-extension check. */ --+ high = gen_int_mode (CONST_HIGH_PART (offset), Pmode); --+ offset = CONST_LOW_PART (offset); --+ high = riscv_force_temporary (temp, high); --+ reg = riscv_force_temporary (temp, gen_rtx_PLUS (Pmode, high, reg)); --+ } --+ return plus_constant (Pmode, reg, offset); --+} --+ --+/* The __tls_get_attr symbol. */ --+static GTY(()) rtx riscv_tls_symbol; --+ --+/* Return an instruction sequence that calls __tls_get_addr. SYM is --+ the TLS symbol we are referencing and TYPE is the symbol type to use --+ (either global dynamic or local dynamic). RESULT is an RTX for the --+ return value location. */ --+ --+static rtx_insn * --+riscv_call_tls_get_addr (rtx sym, rtx result) --+{ --+ rtx a0 = gen_rtx_REG (Pmode, GP_ARG_FIRST), func; --+ rtx_insn *insn; --+ --+ if (!riscv_tls_symbol) --+ riscv_tls_symbol = init_one_libfunc ("__tls_get_addr"); --+ func = gen_rtx_MEM (FUNCTION_MODE, riscv_tls_symbol); --+ --+ start_sequence (); --+ --+ emit_insn (riscv_got_load_tls_gd (a0, sym)); --+ insn = emit_call_insn (gen_call_value (result, func, const0_rtx, NULL)); --+ RTL_CONST_CALL_P (insn) = 1; --+ use_reg (&CALL_INSN_FUNCTION_USAGE (insn), a0); --+ insn = get_insns (); --+ --+ end_sequence (); --+ --+ return insn; --+} --+ --+/* Generate the code to access LOC, a thread-local SYMBOL_REF, and return --+ its address. The return value will be both a valid address and a valid --+ SET_SRC (either a REG or a LO_SUM). */ --+ --+static rtx --+riscv_legitimize_tls_address (rtx loc) --+{ --+ rtx dest, tp, tmp; --+ enum tls_model model = SYMBOL_REF_TLS_MODEL (loc); --+ --+ /* Since we support TLS copy relocs, non-PIC TLS accesses may all use LE. */ --+ if (!flag_pic) --+ model = TLS_MODEL_LOCAL_EXEC; --+ --+ switch (model) --+ { --+ case TLS_MODEL_LOCAL_DYNAMIC: --+ /* Rely on section anchors for the optimization that LDM TLS --+ provides. The anchor's address is loaded with GD TLS. */ --+ case TLS_MODEL_GLOBAL_DYNAMIC: --+ tmp = gen_rtx_REG (Pmode, GP_RETURN); --+ dest = gen_reg_rtx (Pmode); --+ emit_libcall_block (riscv_call_tls_get_addr (loc, tmp), dest, tmp, loc); --+ break; --+ --+ case TLS_MODEL_INITIAL_EXEC: --+ /* la.tls.ie; tp-relative add */ --+ tp = gen_rtx_REG (Pmode, THREAD_POINTER_REGNUM); --+ tmp = gen_reg_rtx (Pmode); --+ emit_insn (riscv_got_load_tls_ie (tmp, loc)); --+ dest = gen_reg_rtx (Pmode); --+ emit_insn (gen_add3_insn (dest, tmp, tp)); --+ break; --+ --+ case TLS_MODEL_LOCAL_EXEC: --+ tmp = riscv_unspec_offset_high (NULL, loc, SYMBOL_TLS_LE); --+ dest = gen_reg_rtx (Pmode); --+ emit_insn (riscv_tls_add_tp_le (dest, tmp, loc)); --+ dest = gen_rtx_LO_SUM (Pmode, dest, --+ riscv_unspec_address (loc, SYMBOL_TLS_LE)); --+ break; --+ --+ default: --+ gcc_unreachable (); --+ } --+ return dest; --+} --+ --+/* If X is not a valid address for mode MODE, force it into a register. */ --+ --+static rtx --+riscv_force_address (rtx x, enum machine_mode mode) --+{ --+ if (!riscv_legitimate_address_p (mode, x, false)) --+ x = force_reg (Pmode, x); --+ return x; --+} --+ --+/* This function is used to implement LEGITIMIZE_ADDRESS. If X can --+ be legitimized in a way that the generic machinery might not expect, --+ return a new address, otherwise return NULL. MODE is the mode of --+ the memory being accessed. */ --+ --+static rtx --+riscv_legitimize_address (rtx x, rtx oldx ATTRIBUTE_UNUSED, --+ enum machine_mode mode) --+{ --+ rtx addr; --+ --+ if (riscv_tls_symbol_p (x)) --+ return riscv_legitimize_tls_address (x); --+ --+ /* See if the address can split into a high part and a LO_SUM. */ --+ if (riscv_split_symbol (NULL, x, mode, &addr)) --+ return riscv_force_address (addr, mode); --+ --+ /* Handle BASE + OFFSET using riscv_add_offset. */ --+ if (GET_CODE (x) == PLUS && CONST_INT_P (XEXP (x, 1)) --+ && INTVAL (XEXP (x, 1)) != 0) --+ { --+ rtx base = XEXP (x, 0); --+ HOST_WIDE_INT offset = INTVAL (XEXP (x, 1)); --+ --+ if (!riscv_valid_base_register_p (base, mode, false)) --+ base = copy_to_mode_reg (Pmode, base); --+ addr = riscv_add_offset (NULL, base, offset); --+ return riscv_force_address (addr, mode); --+ } --+ --+ return x; --+} --+ --+/* Load VALUE into DEST. TEMP is as for riscv_force_temporary. */ --+ --+void --+riscv_move_integer (rtx temp, rtx dest, HOST_WIDE_INT value) --+{ --+ struct riscv_integer_op codes[RISCV_MAX_INTEGER_OPS]; --+ enum machine_mode mode; --+ int i, num_ops; --+ rtx x; --+ --+ mode = GET_MODE (dest); --+ num_ops = riscv_build_integer (codes, value, mode); --+ --+ if (can_create_pseudo_p () && num_ops > 2 /* not a simple constant */ --+ && num_ops >= riscv_split_integer_cost (value)) --+ x = riscv_split_integer (value, mode); --+ else --+ { --+ /* Apply each binary operation to X. */ --+ x = GEN_INT (codes[0].value); --+ --+ for (i = 1; i < num_ops; i++) --+ { --+ if (!can_create_pseudo_p ()) --+ x = riscv_emit_set (temp, x); --+ else --+ x = force_reg (mode, x); --+ --+ x = gen_rtx_fmt_ee (codes[i].code, mode, x, GEN_INT (codes[i].value)); --+ } --+ } --+ --+ riscv_emit_set (dest, x); --+} --+ --+/* Subroutine of riscv_legitimize_move. Move constant SRC into register --+ DEST given that SRC satisfies immediate_operand but doesn't satisfy --+ move_operand. */ --+ --+static void --+riscv_legitimize_const_move (enum machine_mode mode, rtx dest, rtx src) --+{ --+ rtx base, offset; --+ --+ /* Split moves of big integers into smaller pieces. */ --+ if (splittable_const_int_operand (src, mode)) --+ { --+ riscv_move_integer (dest, dest, INTVAL (src)); --+ return; --+ } --+ --+ /* Split moves of symbolic constants into high/low pairs. */ --+ if (riscv_split_symbol (dest, src, MAX_MACHINE_MODE, &src)) --+ { --+ riscv_emit_set (dest, src); --+ return; --+ } --+ --+ /* Generate the appropriate access sequences for TLS symbols. */ --+ if (riscv_tls_symbol_p (src)) --+ { --+ riscv_emit_move (dest, riscv_legitimize_tls_address (src)); --+ return; --+ } --+ --+ /* If we have (const (plus symbol offset)), and that expression cannot --+ be forced into memory, load the symbol first and add in the offset. Also --+ prefer to do this even if the constant _can_ be forced into memory, as it --+ usually produces better code. */ --+ split_const (src, &base, &offset); --+ if (offset != const0_rtx --+ && (targetm.cannot_force_const_mem (mode, src) || can_create_pseudo_p ())) --+ { --+ base = riscv_force_temporary (dest, base); --+ riscv_emit_move (dest, riscv_add_offset (NULL, base, INTVAL (offset))); --+ return; --+ } --+ --+ src = force_const_mem (mode, src); --+ --+ /* When using explicit relocs, constant pool references are sometimes --+ not legitimate addresses. */ --+ riscv_split_symbol (dest, XEXP (src, 0), mode, &XEXP (src, 0)); --+ riscv_emit_move (dest, src); --+} --+ --+/* If (set DEST SRC) is not a valid move instruction, emit an equivalent --+ sequence that is valid. */ --+ --+bool --+riscv_legitimize_move (enum machine_mode mode, rtx dest, rtx src) --+{ --+ if (!register_operand (dest, mode) && !reg_or_0_operand (src, mode)) --+ { --+ riscv_emit_move (dest, force_reg (mode, src)); --+ return true; --+ } --+ --+ /* We need to deal with constants that would be legitimate --+ immediate_operands but aren't legitimate move_operands. */ --+ if (CONSTANT_P (src) && !move_operand (src, mode)) --+ { --+ riscv_legitimize_const_move (mode, dest, src); --+ set_unique_reg_note (get_last_insn (), REG_EQUAL, copy_rtx (src)); --+ return true; --+ } --+ --+ return false; --+} --+ --+/* Return true if there is an instruction that implements CODE and accepts --+ X as an immediate operand. */ --+ --+static int --+riscv_immediate_operand_p (int code, HOST_WIDE_INT x) --+{ --+ switch (code) --+ { --+ case ASHIFT: --+ case ASHIFTRT: --+ case LSHIFTRT: --+ /* All shift counts are truncated to a valid constant. */ --+ return true; --+ --+ case AND: --+ case IOR: --+ case XOR: --+ case PLUS: --+ case LT: --+ case LTU: --+ /* These instructions take 12-bit signed immediates. */ --+ return SMALL_OPERAND (x); --+ --+ case LE: --+ /* We add 1 to the immediate and use SLT. */ --+ return SMALL_OPERAND (x + 1); --+ --+ case LEU: --+ /* Likewise SLTU, but reject the always-true case. */ --+ return SMALL_OPERAND (x + 1) && x + 1 != 0; --+ --+ case GE: --+ case GEU: --+ /* We can emulate an immediate of 1 by using GT/GTU against x0. */ --+ return x == 1; --+ --+ default: --+ /* By default assume that x0 can be used for 0. */ --+ return x == 0; --+ } --+} --+ --+/* Return the cost of binary operation X, given that the instruction --+ sequence for a word-sized or smaller operation takes SIGNLE_INSNS --+ instructions and that the sequence of a double-word operation takes --+ DOUBLE_INSNS instructions. */ --+ --+static int --+riscv_binary_cost (rtx x, int single_insns, int double_insns) --+{ --+ if (GET_MODE_SIZE (GET_MODE (x)) == UNITS_PER_WORD * 2) --+ return COSTS_N_INSNS (double_insns); --+ return COSTS_N_INSNS (single_insns); --+} --+ --+/* Return the cost of sign- or zero-extending OP. */ --+ --+static int --+riscv_extend_cost (rtx op, bool unsigned_p) --+{ --+ if (MEM_P (op)) --+ return 0; --+ --+ if (unsigned_p && GET_MODE (op) == QImode) --+ /* We can use ANDI. */ --+ return COSTS_N_INSNS (1); --+ --+ if (!unsigned_p && GET_MODE (op) == SImode) --+ /* We can use SEXT.W. */ --+ return COSTS_N_INSNS (1); --+ --+ /* We need to use a shift left and a shift right. */ --+ return COSTS_N_INSNS (2); --+} --+ --+/* Implement TARGET_RTX_COSTS. */ --+ --+static bool --+riscv_rtx_costs (rtx x, machine_mode mode, int outer_code, int opno ATTRIBUTE_UNUSED, --+ int *total, bool speed) --+{ --+ bool float_mode_p = FLOAT_MODE_P (mode); --+ int cost; --+ --+ switch (GET_CODE (x)) --+ { --+ case CONST_INT: --+ if (riscv_immediate_operand_p (outer_code, INTVAL (x))) --+ { --+ *total = 0; --+ return true; --+ } --+ /* Fall through. */ --+ --+ case SYMBOL_REF: --+ case LABEL_REF: --+ case CONST_DOUBLE: --+ case CONST: --+ if ((cost = riscv_const_insns (x)) > 0) --+ { --+ /* If the constant is likely to be stored in a GPR, SETs of --+ single-insn constants are as cheap as register sets; we --+ never want to CSE them. */ --+ if (cost == 1 && outer_code == SET) --+ *total = 0; --+ /* When we load a constant more than once, it usually is better --+ to duplicate the last operation in the sequence than to CSE --+ the constant itself. */ --+ else if (outer_code == SET || GET_MODE (x) == VOIDmode) --+ *total = COSTS_N_INSNS (1); --+ } --+ else /* The instruction will be fetched from the constant pool. */ --+ *total = COSTS_N_INSNS (riscv_symbol_insns (SYMBOL_ABSOLUTE)); --+ return true; --+ --+ case MEM: --+ /* If the address is legitimate, return the number of --+ instructions it needs. */ --+ if ((cost = riscv_address_insns (XEXP (x, 0), mode, true)) > 0) --+ { --+ *total = COSTS_N_INSNS (cost + tune_info->memory_cost); --+ return true; --+ } --+ /* Otherwise use the default handling. */ --+ return false; --+ --+ case NOT: --+ *total = COSTS_N_INSNS (GET_MODE_SIZE (mode) > UNITS_PER_WORD ? 2 : 1); --+ return false; --+ --+ case AND: --+ case IOR: --+ case XOR: --+ /* Double-word operations use two single-word operations. */ --+ *total = riscv_binary_cost (x, 1, 2); --+ return false; --+ --+ case ASHIFT: --+ case ASHIFTRT: --+ case LSHIFTRT: --+ *total = riscv_binary_cost (x, 1, CONSTANT_P (XEXP (x, 1)) ? 4 : 9); --+ return false; --+ --+ case ABS: --+ *total = COSTS_N_INSNS (float_mode_p ? 1 : 3); --+ return false; --+ --+ case LO_SUM: --+ *total = set_src_cost (XEXP (x, 0), mode, speed); --+ return true; --+ --+ case LT: --+ case LTU: --+ case LE: --+ case LEU: --+ case GT: --+ case GTU: --+ case GE: --+ case GEU: --+ case EQ: --+ case NE: --+ /* Branch comparisons have VOIDmode, so use the first operand's --+ mode instead. */ --+ mode = GET_MODE (XEXP (x, 0)); --+ if (float_mode_p) --+ *total = tune_info->fp_add[mode == DFmode]; --+ else --+ *total = riscv_binary_cost (x, 1, 3); --+ return false; --+ --+ case UNORDERED: --+ case ORDERED: --+ /* (FEQ(A, A) & FEQ(B, B)) compared against 0. */ --+ mode = GET_MODE (XEXP (x, 0)); --+ *total = tune_info->fp_add[mode == DFmode] + COSTS_N_INSNS (2); --+ return false; --+ --+ case UNEQ: --+ case LTGT: --+ /* (FEQ(A, A) & FEQ(B, B)) compared against FEQ(A, B). */ --+ mode = GET_MODE (XEXP (x, 0)); --+ *total = tune_info->fp_add[mode == DFmode] + COSTS_N_INSNS (3); --+ return false; --+ --+ case UNGE: --+ case UNGT: --+ case UNLE: --+ case UNLT: --+ /* FLT or FLE, but guarded by an FFLAGS read and write. */ --+ mode = GET_MODE (XEXP (x, 0)); --+ *total = tune_info->fp_add[mode == DFmode] + COSTS_N_INSNS (4); --+ return false; --+ --+ case MINUS: --+ case PLUS: --+ if (float_mode_p) --+ *total = tune_info->fp_add[mode == DFmode]; --+ else --+ *total = riscv_binary_cost (x, 1, 4); --+ return false; --+ --+ case NEG: --+ { --+ rtx op = XEXP (x, 0); --+ if (GET_CODE (op) == FMA && !HONOR_SIGNED_ZEROS (mode)) --+ { --+ *total = (tune_info->fp_mul[mode == DFmode] --+ + set_src_cost (XEXP (op, 0), mode, speed) --+ + set_src_cost (XEXP (op, 1), mode, speed) --+ + set_src_cost (XEXP (op, 2), mode, speed)); --+ return true; --+ } --+ } --+ --+ if (float_mode_p) --+ *total = tune_info->fp_add[mode == DFmode]; --+ else --+ *total = COSTS_N_INSNS (GET_MODE_SIZE (mode) > UNITS_PER_WORD ? 4 : 1); --+ return false; --+ --+ case MULT: --+ if (float_mode_p) --+ *total = tune_info->fp_mul[mode == DFmode]; --+ else if (GET_MODE_SIZE (mode) > UNITS_PER_WORD) --+ *total = 3 * tune_info->int_mul[0] + COSTS_N_INSNS (2); --+ else if (!speed) --+ *total = COSTS_N_INSNS (1); --+ else --+ *total = tune_info->int_mul[mode == DImode]; --+ return false; --+ --+ case DIV: --+ case SQRT: --+ case MOD: --+ if (float_mode_p) --+ { --+ *total = tune_info->fp_div[mode == DFmode]; --+ return false; --+ } --+ /* Fall through. */ --+ --+ case UDIV: --+ case UMOD: --+ if (speed) --+ *total = tune_info->int_div[mode == DImode]; --+ else --+ *total = COSTS_N_INSNS (1); --+ return false; --+ --+ case SIGN_EXTEND: --+ case ZERO_EXTEND: --+ *total = riscv_extend_cost (XEXP (x, 0), GET_CODE (x) == ZERO_EXTEND); --+ return false; --+ --+ case FLOAT: --+ case UNSIGNED_FLOAT: --+ case FIX: --+ case FLOAT_EXTEND: --+ case FLOAT_TRUNCATE: --+ *total = tune_info->fp_add[mode == DFmode]; --+ return false; --+ --+ case FMA: --+ *total = (tune_info->fp_mul[mode == DFmode] --+ + set_src_cost (XEXP (x, 0), mode, speed) --+ + set_src_cost (XEXP (x, 1), mode, speed) --+ + set_src_cost (XEXP (x, 2), mode, speed)); --+ return true; --+ --+ case UNSPEC: --+ if (XINT (x, 1) == UNSPEC_AUIPC) --+ { --+ /* Make AUIPC cheap to avoid spilling its result to the stack. */ --+ *total = 1; --+ return true; --+ } --+ return false; --+ --+ default: --+ return false; --+ } --+} --+ --+/* Implement TARGET_ADDRESS_COST. */ --+ --+static int --+riscv_address_cost (rtx addr, enum machine_mode mode, --+ addr_space_t as ATTRIBUTE_UNUSED, --+ bool speed ATTRIBUTE_UNUSED) --+{ --+ return riscv_address_insns (addr, mode, false); --+} --+ --+/* Return one word of double-word value OP. HIGH_P is true to select the --+ high part or false to select the low part. */ --+ --+rtx --+riscv_subword (rtx op, bool high_p) --+{ --+ unsigned int byte = high_p ? UNITS_PER_WORD : 0; --+ enum machine_mode mode = GET_MODE (op); --+ --+ if (mode == VOIDmode) --+ mode = TARGET_64BIT ? TImode : DImode; --+ --+ if (MEM_P (op)) --+ return adjust_address (op, word_mode, byte); --+ --+ if (REG_P (op)) --+ gcc_assert (!FP_REG_RTX_P (op)); --+ --+ return simplify_gen_subreg (word_mode, op, mode, byte); --+} --+ --+/* Return true if a 64-bit move from SRC to DEST should be split into two. */ --+ --+bool --+riscv_split_64bit_move_p (rtx dest, rtx src) --+{ --+ if (TARGET_64BIT) --+ return false; --+ --+ /* Allow FPR <-> FPR and FPR <-> MEM moves, and permit the special case --+ of zeroing an FPR with FCVT.D.W. */ --+ if (TARGET_DOUBLE_FLOAT --+ && ((FP_REG_RTX_P (src) && FP_REG_RTX_P (dest)) --+ || (FP_REG_RTX_P (dest) && MEM_P (src)) --+ || (FP_REG_RTX_P (src) && MEM_P (dest)) --+ || (FP_REG_RTX_P (dest) && src == CONST0_RTX (GET_MODE (src))))) --+ return false; --+ --+ return true; --+} --+ --+/* Split a doubleword move from SRC to DEST. On 32-bit targets, --+ this function handles 64-bit moves for which riscv_split_64bit_move_p --+ holds. For 64-bit targets, this function handles 128-bit moves. */ --+ --+void --+riscv_split_doubleword_move (rtx dest, rtx src) --+{ --+ rtx low_dest; --+ --+ /* The operation can be split into two normal moves. Decide in --+ which order to do them. */ --+ low_dest = riscv_subword (dest, false); --+ if (REG_P (low_dest) && reg_overlap_mentioned_p (low_dest, src)) --+ { --+ riscv_emit_move (riscv_subword (dest, true), riscv_subword (src, true)); --+ riscv_emit_move (low_dest, riscv_subword (src, false)); --+ } --+ else --+ { --+ riscv_emit_move (low_dest, riscv_subword (src, false)); --+ riscv_emit_move (riscv_subword (dest, true), riscv_subword (src, true)); --+ } --+} --+ --+/* Return the appropriate instructions to move SRC into DEST. Assume --+ that SRC is operand 1 and DEST is operand 0. */ --+ --+const char * --+riscv_output_move (rtx dest, rtx src) --+{ --+ enum rtx_code dest_code, src_code; --+ enum machine_mode mode; --+ bool dbl_p; --+ --+ dest_code = GET_CODE (dest); --+ src_code = GET_CODE (src); --+ mode = GET_MODE (dest); --+ dbl_p = (GET_MODE_SIZE (mode) == 8); --+ --+ if (dbl_p && riscv_split_64bit_move_p (dest, src)) --+ return "#"; --+ --+ if (dest_code == REG && GP_REG_P (REGNO (dest))) --+ { --+ if (src_code == REG && FP_REG_P (REGNO (src))) --+ return dbl_p ? "fmv.x.d\t%0,%1" : "fmv.x.s\t%0,%1"; --+ --+ if (src_code == MEM) --+ switch (GET_MODE_SIZE (mode)) --+ { --+ case 1: return "lbu\t%0,%1"; --+ case 2: return "lhu\t%0,%1"; --+ case 4: return "lw\t%0,%1"; --+ case 8: return "ld\t%0,%1"; --+ } --+ --+ if (src_code == CONST_INT) --+ return "li\t%0,%1"; --+ --+ if (src_code == HIGH) --+ return "lui\t%0,%h1"; --+ --+ if (symbolic_operand (src, VOIDmode)) --+ switch (riscv_classify_symbolic_expression (src)) --+ { --+ case SYMBOL_GOT_DISP: return "la\t%0,%1"; --+ case SYMBOL_ABSOLUTE: return "lla\t%0,%1"; --+ case SYMBOL_PCREL: return "lla\t%0,%1"; --+ default: gcc_unreachable (); --+ } --+ } --+ if ((src_code == REG && GP_REG_P (REGNO (src))) --+ || (src == CONST0_RTX (mode))) --+ { --+ if (dest_code == REG) --+ { --+ if (GP_REG_P (REGNO (dest))) --+ return "mv\t%0,%z1"; --+ --+ if (FP_REG_P (REGNO (dest))) --+ { --+ if (!dbl_p) --+ return "fmv.s.x\t%0,%z1"; --+ if (TARGET_64BIT) --+ return "fmv.d.x\t%0,%z1"; --+ /* in RV32, we can emulate fmv.d.x %0, x0 using fcvt.d.w */ --+ gcc_assert (src == CONST0_RTX (mode)); --+ return "fcvt.d.w\t%0,x0"; --+ } --+ } --+ if (dest_code == MEM) --+ switch (GET_MODE_SIZE (mode)) --+ { --+ case 1: return "sb\t%z1,%0"; --+ case 2: return "sh\t%z1,%0"; --+ case 4: return "sw\t%z1,%0"; --+ case 8: return "sd\t%z1,%0"; --+ } --+ } --+ if (src_code == REG && FP_REG_P (REGNO (src))) --+ { --+ if (dest_code == REG && FP_REG_P (REGNO (dest))) --+ return dbl_p ? "fmv.d\t%0,%1" : "fmv.s\t%0,%1"; --+ --+ if (dest_code == MEM) --+ return dbl_p ? "fsd\t%1,%0" : "fsw\t%1,%0"; --+ } --+ if (dest_code == REG && FP_REG_P (REGNO (dest))) --+ { --+ if (src_code == MEM) --+ return dbl_p ? "fld\t%0,%1" : "flw\t%0,%1"; --+ } --+ gcc_unreachable (); --+} --+ --+/* Return true if CMP1 is a suitable second operand for integer ordering --+ test CODE. See also the *sCC patterns in riscv.md. */ --+ --+static bool --+riscv_int_order_operand_ok_p (enum rtx_code code, rtx cmp1) --+{ --+ switch (code) --+ { --+ case GT: --+ case GTU: --+ return reg_or_0_operand (cmp1, VOIDmode); --+ --+ case GE: --+ case GEU: --+ return cmp1 == const1_rtx; --+ --+ case LT: --+ case LTU: --+ return arith_operand (cmp1, VOIDmode); --+ --+ case LE: --+ return sle_operand (cmp1, VOIDmode); --+ --+ case LEU: --+ return sleu_operand (cmp1, VOIDmode); --+ --+ default: --+ gcc_unreachable (); --+ } --+} --+ --+/* Return true if *CMP1 (of mode MODE) is a valid second operand for --+ integer ordering test *CODE, or if an equivalent combination can --+ be formed by adjusting *CODE and *CMP1. When returning true, update --+ *CODE and *CMP1 with the chosen code and operand, otherwise leave --+ them alone. */ --+ --+static bool --+riscv_canonicalize_int_order_test (enum rtx_code *code, rtx *cmp1, --+ enum machine_mode mode) --+{ --+ HOST_WIDE_INT plus_one; --+ --+ if (riscv_int_order_operand_ok_p (*code, *cmp1)) --+ return true; --+ --+ if (CONST_INT_P (*cmp1)) --+ switch (*code) --+ { --+ case LE: --+ plus_one = trunc_int_for_mode (UINTVAL (*cmp1) + 1, mode); --+ if (INTVAL (*cmp1) < plus_one) --+ { --+ *code = LT; --+ *cmp1 = force_reg (mode, GEN_INT (plus_one)); --+ return true; --+ } --+ break; --+ --+ case LEU: --+ plus_one = trunc_int_for_mode (UINTVAL (*cmp1) + 1, mode); --+ if (plus_one != 0) --+ { --+ *code = LTU; --+ *cmp1 = force_reg (mode, GEN_INT (plus_one)); --+ return true; --+ } --+ break; --+ --+ default: --+ break; --+ } --+ return false; --+} --+ --+/* Compare CMP0 and CMP1 using ordering test CODE and store the result --+ in TARGET. CMP0 and TARGET are register_operands. If INVERT_PTR --+ is nonnull, it's OK to set TARGET to the inverse of the result and --+ flip *INVERT_PTR instead. */ --+ --+static void --+riscv_emit_int_order_test (enum rtx_code code, bool *invert_ptr, --+ rtx target, rtx cmp0, rtx cmp1) --+{ --+ enum machine_mode mode; --+ --+ /* First see if there is a RISCV instruction that can do this operation. --+ If not, try doing the same for the inverse operation. If that also --+ fails, force CMP1 into a register and try again. */ --+ mode = GET_MODE (cmp0); --+ if (riscv_canonicalize_int_order_test (&code, &cmp1, mode)) --+ riscv_emit_binary (code, target, cmp0, cmp1); --+ else --+ { --+ enum rtx_code inv_code = reverse_condition (code); --+ if (!riscv_canonicalize_int_order_test (&inv_code, &cmp1, mode)) --+ { --+ cmp1 = force_reg (mode, cmp1); --+ riscv_emit_int_order_test (code, invert_ptr, target, cmp0, cmp1); --+ } --+ else if (invert_ptr == 0) --+ { --+ rtx inv_target = riscv_force_binary (GET_MODE (target), --+ inv_code, cmp0, cmp1); --+ riscv_emit_binary (XOR, target, inv_target, const1_rtx); --+ } --+ else --+ { --+ *invert_ptr = !*invert_ptr; --+ riscv_emit_binary (inv_code, target, cmp0, cmp1); --+ } --+ } --+} --+ --+/* Return a register that is zero iff CMP0 and CMP1 are equal. --+ The register will have the same mode as CMP0. */ --+ --+static rtx --+riscv_zero_if_equal (rtx cmp0, rtx cmp1) --+{ --+ if (cmp1 == const0_rtx) --+ return cmp0; --+ --+ return expand_binop (GET_MODE (cmp0), sub_optab, --+ cmp0, cmp1, 0, 0, OPTAB_DIRECT); --+} --+ --+/* Sign- or zero-extend OP0 and OP1 for integer comparisons. */ --+ --+static void --+riscv_extend_comparands (rtx_code code, rtx *op0, rtx *op1) --+{ --+ /* Comparisons consider all XLEN bits, so extend sub-XLEN values. */ --+ if (GET_MODE_SIZE (word_mode) > GET_MODE_SIZE (GET_MODE (*op0))) --+ { --+ /* It is more profitable to zero-extend QImode values. */ --+ if (unsigned_condition (code) == code && GET_MODE (*op0) == QImode) --+ { --+ *op0 = gen_rtx_ZERO_EXTEND (word_mode, *op0); --+ if (CONST_INT_P (*op1)) --+ *op1 = GEN_INT ((uint8_t) INTVAL (*op1)); --+ else --+ *op1 = gen_rtx_ZERO_EXTEND (word_mode, *op1); --+ } --+ else --+ { --+ *op0 = gen_rtx_SIGN_EXTEND (word_mode, *op0); --+ if (*op1 != const0_rtx) --+ *op1 = gen_rtx_SIGN_EXTEND (word_mode, *op1); --+ } --+ } --+} --+ --+/* Convert a comparison into something that can be used in a branch. On --+ entry, *OP0 and *OP1 are the values being compared and *CODE is the code --+ used to compare them. Update them to describe the final comparison. */ --+ --+static void --+riscv_emit_int_compare (enum rtx_code *code, rtx *op0, rtx *op1) --+{ --+ if (splittable_const_int_operand (*op1, VOIDmode)) --+ { --+ HOST_WIDE_INT rhs = INTVAL (*op1); --+ --+ if (*code == EQ || *code == NE) --+ { --+ /* Convert e.g. OP0 == 2048 into OP0 - 2048 == 0. */ --+ if (SMALL_OPERAND (-rhs)) --+ { --+ *op0 = riscv_force_binary (GET_MODE (*op0), PLUS, *op0, --+ GEN_INT (-rhs)); --+ *op1 = const0_rtx; --+ } --+ } --+ else --+ { --+ static const enum rtx_code mag_comparisons[][2] = { --+ {LEU, LTU}, {GTU, GEU}, {LE, LT}, {GT, GE} --+ }; --+ --+ /* Convert e.g. (OP0 <= 0xFFF) into (OP0 < 0x1000). */ --+ for (size_t i = 0; i < ARRAY_SIZE (mag_comparisons); i++) --+ { --+ HOST_WIDE_INT new_rhs; --+ bool increment = *code == mag_comparisons[i][0]; --+ bool decrement = *code == mag_comparisons[i][1]; --+ if (!increment && !decrement) --+ continue; --+ --+ new_rhs = rhs + (increment ? 1 : -1); --+ if (riscv_integer_cost (new_rhs) < riscv_integer_cost (rhs) --+ && (rhs < 0) == (new_rhs < 0)) --+ { --+ *op1 = GEN_INT (new_rhs); --+ *code = mag_comparisons[i][increment]; --+ } --+ break; --+ } --+ } --+ } --+ --+ riscv_extend_comparands (*code, op0, op1); --+ --+ *op0 = force_reg (word_mode, *op0); --+ if (*op1 != const0_rtx) --+ *op1 = force_reg (word_mode, *op1); --+} --+ --+/* Like riscv_emit_int_compare, but for floating-point comparisons. */ --+ --+static void --+riscv_emit_float_compare (enum rtx_code *code, rtx *op0, rtx *op1) --+{ --+ rtx tmp0, tmp1, cmp_op0 = *op0, cmp_op1 = *op1; --+ enum rtx_code fp_code = *code; --+ *code = NE; --+ --+ switch (fp_code) --+ { --+ case UNORDERED: --+ *code = EQ; --+ /* Fall through. */ --+ --+ case ORDERED: --+ /* a == a && b == b */ --+ tmp0 = riscv_force_binary (word_mode, EQ, cmp_op0, cmp_op0); --+ tmp1 = riscv_force_binary (word_mode, EQ, cmp_op1, cmp_op1); --+ *op0 = riscv_force_binary (word_mode, AND, tmp0, tmp1); --+ *op1 = const0_rtx; --+ break; --+ --+ case UNEQ: --+ case LTGT: --+ /* ordered(a, b) > (a == b) */ --+ *code = fp_code == LTGT ? GTU : EQ; --+ tmp0 = riscv_force_binary (word_mode, EQ, cmp_op0, cmp_op0); --+ tmp1 = riscv_force_binary (word_mode, EQ, cmp_op1, cmp_op1); --+ *op0 = riscv_force_binary (word_mode, AND, tmp0, tmp1); --+ *op1 = riscv_force_binary (word_mode, EQ, cmp_op0, cmp_op1); --+ break; --+ --+#define UNORDERED_COMPARISON(CODE, CMP) \ --+ case CODE: \ --+ *code = EQ; \ --+ *op0 = gen_reg_rtx (word_mode); \ --+ if (GET_MODE (cmp_op0) == SFmode && TARGET_64BIT) \ --+ emit_insn (gen_f##CMP##_quietsfdi4 (*op0, cmp_op0, cmp_op1)); \ --+ else if (GET_MODE (cmp_op0) == SFmode) \ --+ emit_insn (gen_f##CMP##_quietsfsi4 (*op0, cmp_op0, cmp_op1)); \ --+ else if (GET_MODE (cmp_op0) == DFmode && TARGET_64BIT) \ --+ emit_insn (gen_f##CMP##_quietdfdi4 (*op0, cmp_op0, cmp_op1)); \ --+ else if (GET_MODE (cmp_op0) == DFmode) \ --+ emit_insn (gen_f##CMP##_quietdfsi4 (*op0, cmp_op0, cmp_op1)); \ --+ else \ --+ gcc_unreachable (); \ --+ *op1 = const0_rtx; \ --+ break; --+ --+ case UNLT: --+ std::swap (cmp_op0, cmp_op1); --+ /* Fall through. */ --+ --+ UNORDERED_COMPARISON(UNGT, le) --+ --+ case UNLE: --+ std::swap (cmp_op0, cmp_op1); --+ /* Fall through. */ --+ --+ UNORDERED_COMPARISON(UNGE, lt) --+#undef UNORDERED_COMPARISON --+ --+ case NE: --+ fp_code = EQ; --+ *code = EQ; --+ /* Fall through. */ --+ --+ case EQ: --+ case LE: --+ case LT: --+ case GE: --+ case GT: --+ /* We have instructions for these cases. */ --+ *op0 = riscv_force_binary (word_mode, fp_code, cmp_op0, cmp_op1); --+ *op1 = const0_rtx; --+ break; --+ --+ default: --+ gcc_unreachable (); --+ } --+} --+ --+/* CODE-compare OP0 and OP1. Store the result in TARGET. */ --+ --+void --+riscv_expand_int_scc (rtx target, enum rtx_code code, rtx op0, rtx op1) --+{ --+ riscv_extend_comparands (code, &op0, &op1); --+ op0 = force_reg (word_mode, op0); --+ --+ if (code == EQ || code == NE) --+ { --+ rtx zie = riscv_zero_if_equal (op0, op1); --+ riscv_emit_binary (code, target, zie, const0_rtx); --+ } --+ else --+ riscv_emit_int_order_test (code, 0, target, op0, op1); --+} --+ --+/* Like riscv_expand_int_scc, but for floating-point comparisons. */ --+ --+void --+riscv_expand_float_scc (rtx target, enum rtx_code code, rtx op0, rtx op1) --+{ --+ riscv_emit_float_compare (&code, &op0, &op1); --+ --+ rtx cmp = riscv_force_binary (word_mode, code, op0, op1); --+ riscv_emit_set (target, lowpart_subreg (SImode, cmp, word_mode)); --+} --+ --+/* Jump to LABEL if (CODE OP0 OP1) holds. */ --+ --+void --+riscv_expand_conditional_branch (rtx label, rtx_code code, rtx op0, rtx op1) --+{ --+ if (FLOAT_MODE_P (GET_MODE (op1))) --+ riscv_emit_float_compare (&code, &op0, &op1); --+ else --+ riscv_emit_int_compare (&code, &op0, &op1); --+ --+ rtx condition = gen_rtx_fmt_ee (code, VOIDmode, op0, op1); --+ emit_jump_insn (gen_condjump (condition, label)); --+} --+ --+/* Implement TARGET_FUNCTION_ARG_BOUNDARY. Every parameter gets at --+ least PARM_BOUNDARY bits of alignment, but will be given anything up --+ to STACK_BOUNDARY bits if the type requires it. */ --+ --+static unsigned int --+riscv_function_arg_boundary (enum machine_mode mode, const_tree type) --+{ --+ unsigned int alignment; --+ --+ /* Use natural alignment if the type is not aggregate data. */ --+ if (type && !AGGREGATE_TYPE_P (type)) --+ alignment = TYPE_ALIGN (TYPE_MAIN_VARIANT (type)); --+ else --+ alignment = type ? TYPE_ALIGN (type) : GET_MODE_ALIGNMENT (mode); --+ --+ return MIN (STACK_BOUNDARY, MAX (PARM_BOUNDARY, alignment)); --+} --+ --+/* If MODE represents an argument that can be passed or returned in --+ floating-point registers, return the number of registers, else 0. */ --+ --+static unsigned --+riscv_pass_mode_in_fpr_p (enum machine_mode mode) --+{ --+ if (GET_MODE_UNIT_SIZE (mode) <= UNITS_PER_FP_ARG) --+ { --+ if (GET_MODE_CLASS (mode) == MODE_FLOAT) --+ return 1; --+ --+ if (GET_MODE_CLASS (mode) == MODE_COMPLEX_FLOAT) --+ return 2; --+ } --+ --+ return 0; --+} --+ --+typedef struct { --+ const_tree type; --+ HOST_WIDE_INT offset; --+} riscv_aggregate_field; --+ --+/* Identify subfields of aggregates that are candidates for passing in --+ floating-point registers. */ --+ --+static int --+riscv_flatten_aggregate_field (const_tree type, --+ riscv_aggregate_field fields[2], --+ int n, HOST_WIDE_INT offset) --+{ --+ switch (TREE_CODE (type)) --+ { --+ case RECORD_TYPE: --+ /* Can't handle incomplete types nor sizes that are not fixed. */ --+ if (!COMPLETE_TYPE_P (type) --+ || TREE_CODE (TYPE_SIZE (type)) != INTEGER_CST --+ || !tree_fits_uhwi_p (TYPE_SIZE (type))) --+ return -1; --+ --+ for (tree f = TYPE_FIELDS (type); f; f = DECL_CHAIN (f)) --+ if (TREE_CODE (f) == FIELD_DECL) --+ { --+ if (!TYPE_P (TREE_TYPE (f))) --+ return -1; --+ --+ HOST_WIDE_INT pos = offset + int_byte_position (f); --+ n = riscv_flatten_aggregate_field (TREE_TYPE (f), fields, n, pos); --+ if (n < 0) --+ return -1; --+ } --+ return n; --+ --+ case ARRAY_TYPE: --+ { --+ HOST_WIDE_INT n_elts; --+ riscv_aggregate_field subfields[2]; --+ tree index = TYPE_DOMAIN (type); --+ tree elt_size = TYPE_SIZE_UNIT (TREE_TYPE (type)); --+ int n_subfields = riscv_flatten_aggregate_field (TREE_TYPE (type), --+ subfields, 0, offset); --+ --+ /* Can't handle incomplete types nor sizes that are not fixed. */ --+ if (n_subfields <= 0 --+ || !COMPLETE_TYPE_P (type) --+ || TREE_CODE (TYPE_SIZE (type)) != INTEGER_CST --+ || !index --+ || !TYPE_MAX_VALUE (index) --+ || !tree_fits_uhwi_p (TYPE_MAX_VALUE (index)) --+ || !TYPE_MIN_VALUE (index) --+ || !tree_fits_uhwi_p (TYPE_MIN_VALUE (index)) --+ || !tree_fits_uhwi_p (elt_size)) --+ return -1; --+ --+ n_elts = 1 + tree_to_uhwi (TYPE_MAX_VALUE (index)) --+ - tree_to_uhwi (TYPE_MIN_VALUE (index)); --+ gcc_assert (n_elts >= 0); --+ --+ for (HOST_WIDE_INT i = 0; i < n_elts; i++) --+ for (int j = 0; j < n_subfields; j++) --+ { --+ if (n >= 2) --+ return -1; --+ --+ fields[n] = subfields[j]; --+ fields[n++].offset += i * tree_to_uhwi (elt_size); --+ } --+ --+ return n; --+ } --+ --+ case COMPLEX_TYPE: --+ { --+ /* Complex type need consume 2 field, so n must be 0. */ --+ if (n != 0) --+ return -1; --+ --+ HOST_WIDE_INT elt_size = GET_MODE_SIZE (TYPE_MODE (TREE_TYPE (type))); --+ --+ if (elt_size <= UNITS_PER_FP_ARG) --+ { --+ fields[0].type = TREE_TYPE (type); --+ fields[0].offset = offset; --+ fields[1].type = TREE_TYPE (type); --+ fields[1].offset = offset + elt_size; --+ --+ return 2; --+ } --+ --+ return -1; --+ } --+ --+ default: --+ if (n < 2 --+ && ((SCALAR_FLOAT_TYPE_P (type) --+ && GET_MODE_SIZE (TYPE_MODE (type)) <= UNITS_PER_FP_ARG) --+ || (INTEGRAL_TYPE_P (type) --+ && GET_MODE_SIZE (TYPE_MODE (type)) <= UNITS_PER_WORD))) --+ { --+ fields[n].type = type; --+ fields[n].offset = offset; --+ return n + 1; --+ } --+ else --+ return -1; --+ } --+} --+ --+/* Identify candidate aggregates for passing in floating-point registers. --+ Candidates have at most two fields after flattening. */ --+ --+static int --+riscv_flatten_aggregate_argument (const_tree type, --+ riscv_aggregate_field fields[2]) --+{ --+ if (!type || TREE_CODE (type) != RECORD_TYPE) --+ return -1; --+ --+ return riscv_flatten_aggregate_field (type, fields, 0, 0); --+} --+ --+/* See whether TYPE is a record whose fields should be returned in one or --+ two floating-point registers. If so, populate FIELDS accordingly. */ --+ --+static unsigned --+riscv_pass_aggregate_in_fpr_pair_p (const_tree type, --+ riscv_aggregate_field fields[2]) --+{ --+ int n = riscv_flatten_aggregate_argument (type, fields); --+ --+ for (int i = 0; i < n; i++) --+ if (!SCALAR_FLOAT_TYPE_P (fields[i].type)) --+ return 0; --+ --+ return n > 0 ? n : 0; --+} --+ --+/* See whether TYPE is a record whose fields should be returned in one or --+ floating-point register and one integer register. If so, populate --+ FIELDS accordingly. */ --+ --+static bool --+riscv_pass_aggregate_in_fpr_and_gpr_p (const_tree type, --+ riscv_aggregate_field fields[2]) --+{ --+ unsigned num_int = 0, num_float = 0; --+ int n = riscv_flatten_aggregate_argument (type, fields); --+ --+ for (int i = 0; i < n; i++) --+ { --+ num_float += SCALAR_FLOAT_TYPE_P (fields[i].type); --+ num_int += INTEGRAL_TYPE_P (fields[i].type); --+ } --+ --+ return num_int == 1 && num_float == 1; --+} --+ --+/* Return the representation of an argument passed or returned in an FPR --+ when the value has mode VALUE_MODE and the type has TYPE_MODE. The --+ two modes may be different for structures like: --+ --+ struct __attribute__((packed)) foo { float f; } --+ --+ where the SFmode value "f" is passed in REGNO but the struct itself --+ has mode BLKmode. */ --+ --+static rtx --+riscv_pass_fpr_single (enum machine_mode type_mode, unsigned regno, --+ enum machine_mode value_mode) --+{ --+ rtx x = gen_rtx_REG (value_mode, regno); --+ --+ if (type_mode != value_mode) --+ { --+ x = gen_rtx_EXPR_LIST (VOIDmode, x, const0_rtx); --+ x = gen_rtx_PARALLEL (type_mode, gen_rtvec (1, x)); --+ } --+ return x; --+} --+ --+/* Pass or return a composite value in the FPR pair REGNO and REGNO + 1. --+ MODE is the mode of the composite. MODE1 and OFFSET1 are the mode and --+ byte offset for the first value, likewise MODE2 and OFFSET2 for the --+ second value. */ --+ --+static rtx --+riscv_pass_fpr_pair (enum machine_mode mode, unsigned regno1, --+ enum machine_mode mode1, HOST_WIDE_INT offset1, --+ unsigned regno2, enum machine_mode mode2, --+ HOST_WIDE_INT offset2) --+{ --+ return gen_rtx_PARALLEL --+ (mode, --+ gen_rtvec (2, --+ gen_rtx_EXPR_LIST (VOIDmode, --+ gen_rtx_REG (mode1, regno1), --+ GEN_INT (offset1)), --+ gen_rtx_EXPR_LIST (VOIDmode, --+ gen_rtx_REG (mode2, regno2), --+ GEN_INT (offset2)))); --+} --+ --+/* Fill INFO with information about a single argument, and return an --+ RTL pattern to pass or return the argument. CUM is the cumulative --+ state for earlier arguments. MODE is the mode of this argument and --+ TYPE is its type (if known). NAMED is true if this is a named --+ (fixed) argument rather than a variable one. RETURN_P is true if --+ returning the argument, or false if passing the argument. */ --+ --+static rtx --+riscv_get_arg_info (struct riscv_arg_info *info, const CUMULATIVE_ARGS *cum, --+ enum machine_mode mode, const_tree type, bool named, --+ bool return_p) --+{ --+ unsigned num_bytes, num_words; --+ unsigned fpr_base = return_p ? FP_RETURN : FP_ARG_FIRST; --+ unsigned gpr_base = return_p ? GP_RETURN : GP_ARG_FIRST; --+ unsigned alignment = riscv_function_arg_boundary (mode, type); --+ --+ memset (info, 0, sizeof (*info)); --+ info->gpr_offset = cum->num_gprs; --+ info->fpr_offset = cum->num_fprs; --+ --+ if (named) --+ { --+ riscv_aggregate_field fields[2]; --+ unsigned fregno = fpr_base + info->fpr_offset; --+ unsigned gregno = gpr_base + info->gpr_offset; --+ --+ /* Pass one- or two-element floating-point aggregates in FPRs. */ --+ if ((info->num_fprs = riscv_pass_aggregate_in_fpr_pair_p (type, fields)) --+ && info->fpr_offset + info->num_fprs <= MAX_ARGS_IN_REGISTERS) --+ switch (info->num_fprs) --+ { --+ case 1: --+ return riscv_pass_fpr_single (mode, fregno, --+ TYPE_MODE (fields[0].type)); --+ --+ case 2: --+ return riscv_pass_fpr_pair (mode, fregno, --+ TYPE_MODE (fields[0].type), --+ fields[0].offset, --+ fregno + 1, --+ TYPE_MODE (fields[1].type), --+ fields[1].offset); --+ --+ default: --+ gcc_unreachable (); --+ } --+ --+ /* Pass real and complex floating-point numbers in FPRs. */ --+ if ((info->num_fprs = riscv_pass_mode_in_fpr_p (mode)) --+ && info->fpr_offset + info->num_fprs <= MAX_ARGS_IN_REGISTERS) --+ switch (GET_MODE_CLASS (mode)) --+ { --+ case MODE_FLOAT: --+ return gen_rtx_REG (mode, fregno); --+ --+ case MODE_COMPLEX_FLOAT: --+ return riscv_pass_fpr_pair (mode, fregno, GET_MODE_INNER (mode), 0, --+ fregno + 1, GET_MODE_INNER (mode), --+ GET_MODE_UNIT_SIZE (mode)); --+ --+ default: --+ gcc_unreachable (); --+ } --+ --+ /* Pass structs with one float and one integer in an FPR and a GPR. */ --+ if (riscv_pass_aggregate_in_fpr_and_gpr_p (type, fields) --+ && info->gpr_offset < MAX_ARGS_IN_REGISTERS --+ && info->fpr_offset < MAX_ARGS_IN_REGISTERS) --+ { --+ info->num_gprs = 1; --+ info->num_fprs = 1; --+ --+ if (!SCALAR_FLOAT_TYPE_P (fields[0].type)) --+ std::swap (fregno, gregno); --+ --+ return riscv_pass_fpr_pair (mode, fregno, TYPE_MODE (fields[0].type), --+ fields[0].offset, --+ gregno, TYPE_MODE (fields[1].type), --+ fields[1].offset); --+ } --+ } --+ --+ /* Work out the size of the argument. */ --+ num_bytes = type ? int_size_in_bytes (type) : GET_MODE_SIZE (mode); --+ num_words = (num_bytes + UNITS_PER_WORD - 1) / UNITS_PER_WORD; --+ --+ /* Doubleword-aligned varargs start on an even register boundary. */ --+ if (!named && num_bytes != 0 && alignment > BITS_PER_WORD) --+ info->gpr_offset += info->gpr_offset & 1; --+ --+ /* Partition the argument between registers and stack. */ --+ info->num_fprs = 0; --+ info->num_gprs = MIN (num_words, MAX_ARGS_IN_REGISTERS - info->gpr_offset); --+ info->stack_p = (num_words - info->num_gprs) != 0; --+ --+ if (info->num_gprs || return_p) --+ return gen_rtx_REG (mode, gpr_base + info->gpr_offset); --+ --+ return NULL_RTX; --+} --+ --+/* Implement TARGET_FUNCTION_ARG. */ --+ --+static rtx --+riscv_function_arg (cumulative_args_t cum_v, enum machine_mode mode, --+ const_tree type, bool named) --+{ --+ CUMULATIVE_ARGS *cum = get_cumulative_args (cum_v); --+ struct riscv_arg_info info; --+ --+ if (mode == VOIDmode) --+ return NULL; --+ --+ return riscv_get_arg_info (&info, cum, mode, type, named, false); --+} --+ --+/* Implement TARGET_FUNCTION_ARG_ADVANCE. */ --+ --+static void --+riscv_function_arg_advance (cumulative_args_t cum_v, enum machine_mode mode, --+ const_tree type, bool named) --+{ --+ CUMULATIVE_ARGS *cum = get_cumulative_args (cum_v); --+ struct riscv_arg_info info; --+ --+ riscv_get_arg_info (&info, cum, mode, type, named, false); --+ --+ /* Advance the register count. This has the effect of setting --+ num_gprs to MAX_ARGS_IN_REGISTERS if a doubleword-aligned --+ argument required us to skip the final GPR and pass the whole --+ argument on the stack. */ --+ cum->num_fprs = info.fpr_offset + info.num_fprs; --+ cum->num_gprs = info.gpr_offset + info.num_gprs; --+} --+ --+/* Implement TARGET_ARG_PARTIAL_BYTES. */ --+ --+static int --+riscv_arg_partial_bytes (cumulative_args_t cum, --+ enum machine_mode mode, tree type, bool named) --+{ --+ struct riscv_arg_info arg; --+ --+ riscv_get_arg_info (&arg, get_cumulative_args (cum), mode, type, named, false); --+ return arg.stack_p ? arg.num_gprs * UNITS_PER_WORD : 0; --+} --+ --+/* Implement FUNCTION_VALUE and LIBCALL_VALUE. For normal calls, --+ VALTYPE is the return type and MODE is VOIDmode. For libcalls, --+ VALTYPE is null and MODE is the mode of the return value. */ --+ --+rtx --+riscv_function_value (const_tree type, const_tree func, enum machine_mode mode) --+{ --+ struct riscv_arg_info info; --+ CUMULATIVE_ARGS args; --+ --+ if (type) --+ { --+ int unsigned_p = TYPE_UNSIGNED (type); --+ --+ mode = TYPE_MODE (type); --+ --+ /* Since TARGET_PROMOTE_FUNCTION_MODE unconditionally promotes, --+ return values, promote the mode here too. */ --+ mode = promote_function_mode (type, mode, &unsigned_p, func, 1); --+ } --+ --+ memset (&args, 0, sizeof args); --+ return riscv_get_arg_info (&info, &args, mode, type, true, true); --+} --+ --+/* Implement TARGET_PASS_BY_REFERENCE. */ --+ --+static bool --+riscv_pass_by_reference (cumulative_args_t cum_v, enum machine_mode mode, --+ const_tree type, bool named) --+{ --+ HOST_WIDE_INT size = type ? int_size_in_bytes (type) : GET_MODE_SIZE (mode); --+ struct riscv_arg_info info; --+ CUMULATIVE_ARGS *cum = get_cumulative_args (cum_v); --+ --+ /* ??? std_gimplify_va_arg_expr passes NULL for cum. Fortunately, we --+ never pass variadic arguments in floating-point registers, so we can --+ avoid the call to riscv_get_arg_info in this case. */ --+ if (cum != NULL) --+ { --+ /* Don't pass by reference if we can use a floating-point register. */ --+ riscv_get_arg_info (&info, cum, mode, type, named, false); --+ if (info.num_fprs) --+ return false; --+ } --+ --+ /* Pass by reference if the data do not fit in two integer registers. */ --+ return !IN_RANGE (size, 0, 2 * UNITS_PER_WORD); --+} --+ --+/* Implement TARGET_RETURN_IN_MEMORY. */ --+ --+static bool --+riscv_return_in_memory (const_tree type, const_tree fndecl ATTRIBUTE_UNUSED) --+{ --+ CUMULATIVE_ARGS args; --+ cumulative_args_t cum = pack_cumulative_args (&args); --+ --+ /* The rules for returning in memory are the same as for passing the --+ first named argument by reference. */ --+ memset (&args, 0, sizeof args); --+ return riscv_pass_by_reference (cum, TYPE_MODE (type), type, true); --+} --+ --+/* Implement TARGET_SETUP_INCOMING_VARARGS. */ --+ --+static void --+riscv_setup_incoming_varargs (cumulative_args_t cum, enum machine_mode mode, --+ tree type, int *pretend_size ATTRIBUTE_UNUSED, --+ int no_rtl) --+{ --+ CUMULATIVE_ARGS local_cum; --+ int gp_saved; --+ --+ /* The caller has advanced CUM up to, but not beyond, the last named --+ argument. Advance a local copy of CUM past the last "real" named --+ argument, to find out how many registers are left over. */ --+ local_cum = *get_cumulative_args (cum); --+ riscv_function_arg_advance (pack_cumulative_args (&local_cum), mode, type, 1); --+ --+ /* Found out how many registers we need to save. */ --+ gp_saved = MAX_ARGS_IN_REGISTERS - local_cum.num_gprs; --+ --+ if (!no_rtl && gp_saved > 0) --+ { --+ rtx ptr = plus_constant (Pmode, virtual_incoming_args_rtx, --+ REG_PARM_STACK_SPACE (cfun->decl) --+ - gp_saved * UNITS_PER_WORD); --+ rtx mem = gen_frame_mem (BLKmode, ptr); --+ set_mem_alias_set (mem, get_varargs_alias_set ()); --+ --+ move_block_from_reg (local_cum.num_gprs + GP_ARG_FIRST, --+ mem, gp_saved); --+ } --+ if (REG_PARM_STACK_SPACE (cfun->decl) == 0) --+ cfun->machine->varargs_size = gp_saved * UNITS_PER_WORD; --+} --+ --+/* Implement TARGET_EXPAND_BUILTIN_VA_START. */ --+ --+static void --+riscv_va_start (tree valist, rtx nextarg) --+{ --+ nextarg = plus_constant (Pmode, nextarg, -cfun->machine->varargs_size); --+ std_expand_builtin_va_start (valist, nextarg); --+} --+ --+/* Make ADDR suitable for use as a call or sibcall target. */ --+ --+rtx --+riscv_legitimize_call_address (rtx addr) --+{ --+ if (!call_insn_operand (addr, VOIDmode)) --+ { --+ rtx reg = RISCV_PROLOGUE_TEMP (Pmode); --+ riscv_emit_move (reg, addr); --+ return reg; --+ } --+ return addr; --+} --+ --+/* Print symbolic operand OP, which is part of a HIGH or LO_SUM --+ in context CONTEXT. HI_RELOC indicates a high-part reloc. */ --+ --+static void --+riscv_print_operand_reloc (FILE *file, rtx op, bool hi_reloc) --+{ --+ const char *reloc; --+ --+ switch (riscv_classify_symbolic_expression (op)) --+ { --+ case SYMBOL_ABSOLUTE: --+ reloc = hi_reloc ? "%hi" : "%lo"; --+ break; --+ --+ case SYMBOL_PCREL: --+ reloc = hi_reloc ? "%pcrel_hi" : "%pcrel_lo"; --+ break; --+ --+ case SYMBOL_TLS_LE: --+ reloc = hi_reloc ? "%tprel_hi" : "%tprel_lo"; --+ break; --+ --+ default: --+ gcc_unreachable (); --+ } --+ --+ fprintf (file, "%s(", reloc); --+ output_addr_const (file, riscv_strip_unspec_address (op)); --+ fputc (')', file); --+} --+ --+/* Return true if the .AQ suffix should be added to an AMO to implement the --+ acquire portion of memory model MODEL. */ --+ --+static bool --+riscv_memmodel_needs_amo_acquire (enum memmodel model) --+{ --+ switch (model) --+ { --+ case MEMMODEL_ACQ_REL: --+ case MEMMODEL_SEQ_CST: --+ case MEMMODEL_SYNC_SEQ_CST: --+ case MEMMODEL_ACQUIRE: --+ case MEMMODEL_CONSUME: --+ case MEMMODEL_SYNC_ACQUIRE: --+ return true; --+ --+ case MEMMODEL_RELEASE: --+ case MEMMODEL_SYNC_RELEASE: --+ case MEMMODEL_RELAXED: --+ return false; --+ --+ default: --+ gcc_unreachable (); --+ } --+} --+ --+/* Return true if a FENCE should be emitted to before a memory access to --+ implement the release portion of memory model MODEL. */ --+ --+static bool --+riscv_memmodel_needs_release_fence (enum memmodel model) --+{ --+ switch (model) --+ { --+ case MEMMODEL_ACQ_REL: --+ case MEMMODEL_SEQ_CST: --+ case MEMMODEL_SYNC_SEQ_CST: --+ case MEMMODEL_RELEASE: --+ case MEMMODEL_SYNC_RELEASE: --+ return true; --+ --+ case MEMMODEL_ACQUIRE: --+ case MEMMODEL_CONSUME: --+ case MEMMODEL_SYNC_ACQUIRE: --+ case MEMMODEL_RELAXED: --+ return false; --+ --+ default: --+ gcc_unreachable (); --+ } --+} --+ --+/* Implement TARGET_PRINT_OPERAND. The RISCV-specific operand codes are: --+ --+ 'h' Print the high-part relocation associated with OP, after stripping --+ any outermost HIGH. --+ 'R' Print the low-part relocation associated with OP. --+ 'C' Print the integer branch condition for comparison OP. --+ 'A' Print the atomic operation suffix for memory model OP. --+ 'F' Print a FENCE if the memory model requires a release. --+ 'z' Print x0 if OP is zero, otherwise print OP normally. */ --+ --+static void --+riscv_print_operand (FILE *file, rtx op, int letter) --+{ --+ enum machine_mode mode = GET_MODE (op); --+ enum rtx_code code = GET_CODE (op); --+ --+ switch (letter) --+ { --+ case 'h': --+ if (code == HIGH) --+ op = XEXP (op, 0); --+ riscv_print_operand_reloc (file, op, true); --+ break; --+ --+ case 'R': --+ riscv_print_operand_reloc (file, op, false); --+ break; --+ --+ case 'C': --+ /* The RTL names match the instruction names. */ --+ fputs (GET_RTX_NAME (code), file); --+ break; --+ --+ case 'A': --+ if (riscv_memmodel_needs_amo_acquire ((enum memmodel) INTVAL (op))) --+ fputs (".aq", file); --+ break; --+ --+ case 'F': --+ if (riscv_memmodel_needs_release_fence ((enum memmodel) INTVAL (op))) --+ fputs ("fence rw,w; ", file); --+ break; --+ --+ default: --+ switch (code) --+ { --+ case REG: --+ if (letter && letter != 'z') --+ output_operand_lossage ("invalid use of '%%%c'", letter); --+ fprintf (file, "%s", reg_names[REGNO (op)]); --+ break; --+ --+ case MEM: --+ if (letter && letter != 'z') --+ output_operand_lossage ("invalid use of '%%%c'", letter); --+ else --+ output_address (mode, XEXP (op, 0)); --+ break; --+ --+ default: --+ if (letter == 'z' && op == CONST0_RTX (GET_MODE (op))) --+ fputs (reg_names[GP_REG_FIRST], file); --+ else if (letter && letter != 'z') --+ output_operand_lossage ("invalid use of '%%%c'", letter); --+ else --+ output_addr_const (file, riscv_strip_unspec_address (op)); --+ break; --+ } --+ } --+} --+ --+/* Implement TARGET_PRINT_OPERAND_ADDRESS. */ --+ --+static void --+riscv_print_operand_address (FILE *file, machine_mode mode ATTRIBUTE_UNUSED, rtx x) --+{ --+ struct riscv_address_info addr; --+ --+ if (riscv_classify_address (&addr, x, word_mode, true)) --+ switch (addr.type) --+ { --+ case ADDRESS_REG: --+ riscv_print_operand (file, addr.offset, 0); --+ fprintf (file, "(%s)", reg_names[REGNO (addr.reg)]); --+ return; --+ --+ case ADDRESS_LO_SUM: --+ riscv_print_operand_reloc (file, addr.offset, false); --+ fprintf (file, "(%s)", reg_names[REGNO (addr.reg)]); --+ return; --+ --+ case ADDRESS_CONST_INT: --+ output_addr_const (file, x); --+ fprintf (file, "(%s)", reg_names[GP_REG_FIRST]); --+ return; --+ --+ case ADDRESS_SYMBOLIC: --+ output_addr_const (file, riscv_strip_unspec_address (x)); --+ return; --+ } --+ gcc_unreachable (); --+} --+ --+static bool --+riscv_size_ok_for_small_data_p (int size) --+{ --+ return g_switch_value && IN_RANGE (size, 1, g_switch_value); --+} --+ --+/* Return true if EXP should be placed in the small data section. */ --+ --+static bool --+riscv_in_small_data_p (const_tree x) --+{ --+ if (TREE_CODE (x) == STRING_CST || TREE_CODE (x) == FUNCTION_DECL) --+ return false; --+ --+ if (TREE_CODE (x) == VAR_DECL && DECL_SECTION_NAME (x)) --+ { --+ const char *sec = DECL_SECTION_NAME (x); --+ return strcmp (sec, ".sdata") == 0 || strcmp (sec, ".sbss") == 0; --+ } --+ --+ return riscv_size_ok_for_small_data_p (int_size_in_bytes (TREE_TYPE (x))); --+} --+ --+/* Return a section for X, handling small data. */ --+ --+static section * --+riscv_elf_select_rtx_section (enum machine_mode mode, rtx x, --+ unsigned HOST_WIDE_INT align) --+{ --+ section *s = default_elf_select_rtx_section (mode, x, align); --+ --+ if (riscv_size_ok_for_small_data_p (GET_MODE_SIZE (mode))) --+ { --+ if (strncmp (s->named.name, ".rodata.cst", strlen (".rodata.cst")) == 0) --+ { --+ /* Rename .rodata.cst* to .srodata.cst*. */ --+ char *name = (char *) alloca (strlen (s->named.name) + 2); --+ sprintf (name, ".s%s", s->named.name + 1); --+ return get_section (name, s->named.common.flags, NULL); --+ } --+ --+ if (s == data_section) --+ return sdata_section; --+ } --+ --+ return s; --+} --+ --+/* Make the last instruction frame-related and note that it performs --+ the operation described by FRAME_PATTERN. */ --+ --+static void --+riscv_set_frame_expr (rtx frame_pattern) --+{ --+ rtx insn; --+ --+ insn = get_last_insn (); --+ RTX_FRAME_RELATED_P (insn) = 1; --+ REG_NOTES (insn) = alloc_EXPR_LIST (REG_FRAME_RELATED_EXPR, --+ frame_pattern, --+ REG_NOTES (insn)); --+} --+ --+/* Return a frame-related rtx that stores REG at MEM. --+ REG must be a single register. */ --+ --+static rtx --+riscv_frame_set (rtx mem, rtx reg) --+{ --+ rtx set = gen_rtx_SET (mem, reg); --+ RTX_FRAME_RELATED_P (set) = 1; --+ return set; --+} --+ --+/* Return true if the current function must save register REGNO. */ --+ --+static bool --+riscv_save_reg_p (unsigned int regno) --+{ --+ bool call_saved = !global_regs[regno] && !call_used_regs[regno]; --+ bool might_clobber = crtl->saves_all_registers --+ || df_regs_ever_live_p (regno); --+ --+ if (call_saved && might_clobber) --+ return true; --+ --+ if (regno == HARD_FRAME_POINTER_REGNUM && frame_pointer_needed) --+ return true; --+ --+ if (regno == RETURN_ADDR_REGNUM && crtl->calls_eh_return) --+ return true; --+ --+ return false; --+} --+ --+/* Determine whether to call GPR save/restore routines. */ --+static bool --+riscv_use_save_libcall (const struct riscv_frame_info *frame) --+{ --+ if (!TARGET_SAVE_RESTORE || crtl->calls_eh_return || frame_pointer_needed) --+ return false; --+ --+ return frame->save_libcall_adjustment != 0; --+} --+ --+/* Determine which GPR save/restore routine to call. */ --+ --+static unsigned --+riscv_save_libcall_count (unsigned mask) --+{ --+ for (unsigned n = GP_REG_LAST; n > GP_REG_FIRST; n--) --+ if (BITSET_P (mask, n)) --+ return CALLEE_SAVED_REG_NUMBER (n) + 1; --+ abort (); --+} --+ --+/* Populate the current function's riscv_frame_info structure. --+ --+ RISC-V stack frames grown downward. High addresses are at the top. --+ --+ +-------------------------------+ --+ | | --+ | incoming stack arguments | --+ | | --+ +-------------------------------+ <-- incoming stack pointer --+ | | --+ | callee-allocated save area | --+ | for arguments that are | --+ | split between registers and | --+ | the stack | --+ | | --+ +-------------------------------+ <-- arg_pointer_rtx --+ | | --+ | callee-allocated save area | --+ | for register varargs | --+ | | --+ +-------------------------------+ <-- hard_frame_pointer_rtx; --+ | | stack_pointer_rtx + gp_sp_offset --+ | GPR save area | + UNITS_PER_WORD --+ | | --+ +-------------------------------+ <-- stack_pointer_rtx + fp_sp_offset --+ | | + UNITS_PER_HWVALUE --+ | FPR save area | --+ | | --+ +-------------------------------+ <-- frame_pointer_rtx (virtual) --+ | | --+ | local variables | --+ | | --+ P +-------------------------------+ --+ | | --+ | outgoing stack arguments | --+ | | --+ +-------------------------------+ <-- stack_pointer_rtx --+ --+ Dynamic stack allocations such as alloca insert data at point P. --+ They decrease stack_pointer_rtx but leave frame_pointer_rtx and --+ hard_frame_pointer_rtx unchanged. */ --+ --+static void --+riscv_compute_frame_info (void) --+{ --+ struct riscv_frame_info *frame; --+ HOST_WIDE_INT offset; --+ unsigned int regno, i, num_x_saved = 0, num_f_saved = 0; --+ --+ frame = &cfun->machine->frame; --+ memset (frame, 0, sizeof (*frame)); --+ --+ /* Find out which GPRs we need to save. */ --+ for (regno = GP_REG_FIRST; regno <= GP_REG_LAST; regno++) --+ if (riscv_save_reg_p (regno)) --+ frame->mask |= 1 << (regno - GP_REG_FIRST), num_x_saved++; --+ --+ /* If this function calls eh_return, we must also save and restore the --+ EH data registers. */ --+ if (crtl->calls_eh_return) --+ for (i = 0; (regno = EH_RETURN_DATA_REGNO (i)) != INVALID_REGNUM; i++) --+ frame->mask |= 1 << (regno - GP_REG_FIRST), num_x_saved++; --+ --+ /* Find out which FPRs we need to save. This loop must iterate over --+ the same space as its companion in riscv_for_each_saved_reg. */ --+ if (TARGET_HARD_FLOAT) --+ for (regno = FP_REG_FIRST; regno <= FP_REG_LAST; regno++) --+ if (riscv_save_reg_p (regno)) --+ frame->fmask |= 1 << (regno - FP_REG_FIRST), num_f_saved++; --+ --+ /* At the bottom of the frame are any outgoing stack arguments. */ --+ offset = crtl->outgoing_args_size; --+ /* Next are local stack variables. */ --+ offset += RISCV_STACK_ALIGN (get_frame_size ()); --+ /* The virtual frame pointer points above the local variables. */ --+ frame->frame_pointer_offset = offset; --+ /* Next are the callee-saved FPRs. */ --+ if (frame->fmask) --+ offset += RISCV_STACK_ALIGN (num_f_saved * UNITS_PER_FP_REG); --+ frame->fp_sp_offset = offset - UNITS_PER_FP_REG; --+ /* Next are the callee-saved GPRs. */ --+ if (frame->mask) --+ { --+ unsigned x_save_size = RISCV_STACK_ALIGN (num_x_saved * UNITS_PER_WORD); --+ unsigned num_save_restore = 1 + riscv_save_libcall_count (frame->mask); --+ --+ /* Only use save/restore routines if they don't alter the stack size. */ --+ if (RISCV_STACK_ALIGN (num_save_restore * UNITS_PER_WORD) == x_save_size) --+ frame->save_libcall_adjustment = x_save_size; --+ --+ offset += x_save_size; --+ } --+ frame->gp_sp_offset = offset - UNITS_PER_WORD; --+ /* The hard frame pointer points above the callee-saved GPRs. */ --+ frame->hard_frame_pointer_offset = offset; --+ /* Above the hard frame pointer is the callee-allocated varags save area. */ --+ offset += RISCV_STACK_ALIGN (cfun->machine->varargs_size); --+ frame->arg_pointer_offset = offset; --+ /* Next is the callee-allocated area for pretend stack arguments. */ --+ offset += crtl->args.pretend_args_size; --+ frame->total_size = offset; --+ /* Next points the incoming stack pointer and any incoming arguments. */ --+ --+ /* Only use save/restore routines when the GPRs are atop the frame. */ --+ if (frame->hard_frame_pointer_offset != frame->total_size) --+ frame->save_libcall_adjustment = 0; --+} --+ --+/* Make sure that we're not trying to eliminate to the wrong hard frame --+ pointer. */ --+ --+static bool --+riscv_can_eliminate (const int from ATTRIBUTE_UNUSED, const int to) --+{ --+ return (to == HARD_FRAME_POINTER_REGNUM || to == STACK_POINTER_REGNUM); --+} --+ --+/* Implement INITIAL_ELIMINATION_OFFSET. FROM is either the frame pointer --+ or argument pointer. TO is either the stack pointer or hard frame --+ pointer. */ --+ --+HOST_WIDE_INT --+riscv_initial_elimination_offset (int from, int to) --+{ --+ HOST_WIDE_INT src, dest; --+ --+ riscv_compute_frame_info (); --+ --+ if (to == HARD_FRAME_POINTER_REGNUM) --+ dest = cfun->machine->frame.hard_frame_pointer_offset; --+ else if (to == STACK_POINTER_REGNUM) --+ dest = 0; /* The stack pointer is the base of all offsets, hence 0. */ --+ else --+ gcc_unreachable (); --+ --+ if (from == FRAME_POINTER_REGNUM) --+ src = cfun->machine->frame.frame_pointer_offset; --+ else if (from == ARG_POINTER_REGNUM) --+ src = cfun->machine->frame.arg_pointer_offset; --+ else --+ gcc_unreachable (); --+ --+ return src - dest; --+} --+ --+/* Implement RETURN_ADDR_RTX. We do not support moving back to a --+ previous frame. */ --+ --+rtx --+riscv_return_addr (int count, rtx frame ATTRIBUTE_UNUSED) --+{ --+ if (count != 0) --+ return const0_rtx; --+ --+ return get_hard_reg_initial_val (Pmode, RETURN_ADDR_REGNUM); --+} --+ --+/* Emit code to change the current function's return address to --+ ADDRESS. SCRATCH is available as a scratch register, if needed. --+ ADDRESS and SCRATCH are both word-mode GPRs. */ --+ --+void --+riscv_set_return_address (rtx address, rtx scratch) --+{ --+ rtx slot_address; --+ --+ gcc_assert (BITSET_P (cfun->machine->frame.mask, RETURN_ADDR_REGNUM)); --+ slot_address = riscv_add_offset (scratch, stack_pointer_rtx, --+ cfun->machine->frame.gp_sp_offset); --+ riscv_emit_move (gen_frame_mem (GET_MODE (address), slot_address), address); --+} --+ --+/* A function to save or store a register. The first argument is the --+ register and the second is the stack slot. */ --+typedef void (*riscv_save_restore_fn) (rtx, rtx); --+ --+/* Use FN to save or restore register REGNO. MODE is the register's --+ mode and OFFSET is the offset of its save slot from the current --+ stack pointer. */ --+ --+static void --+riscv_save_restore_reg (enum machine_mode mode, int regno, --+ HOST_WIDE_INT offset, riscv_save_restore_fn fn) --+{ --+ rtx mem; --+ --+ mem = gen_frame_mem (mode, plus_constant (Pmode, stack_pointer_rtx, offset)); --+ fn (gen_rtx_REG (mode, regno), mem); --+} --+ --+/* Call FN for each register that is saved by the current function. --+ SP_OFFSET is the offset of the current stack pointer from the start --+ of the frame. */ --+ --+static void --+riscv_for_each_saved_reg (HOST_WIDE_INT sp_offset, riscv_save_restore_fn fn) --+{ --+ HOST_WIDE_INT offset; --+ --+ /* Save the link register and s-registers. */ --+ offset = cfun->machine->frame.gp_sp_offset - sp_offset; --+ for (int regno = GP_REG_FIRST; regno <= GP_REG_LAST-1; regno++) --+ if (BITSET_P (cfun->machine->frame.mask, regno - GP_REG_FIRST)) --+ { --+ riscv_save_restore_reg (word_mode, regno, offset, fn); --+ offset -= UNITS_PER_WORD; --+ } --+ --+ /* This loop must iterate over the same space as its companion in --+ riscv_compute_frame_info. */ --+ offset = cfun->machine->frame.fp_sp_offset - sp_offset; --+ for (int regno = FP_REG_FIRST; regno <= FP_REG_LAST; regno++) --+ if (BITSET_P (cfun->machine->frame.fmask, regno - FP_REG_FIRST)) --+ { --+ enum machine_mode mode = TARGET_DOUBLE_FLOAT ? DFmode : SFmode; --+ --+ riscv_save_restore_reg (mode, regno, offset, fn); --+ offset -= GET_MODE_SIZE (mode); --+ } --+} --+ --+/* Save register REG to MEM. Make the instruction frame-related. */ --+ --+static void --+riscv_save_reg (rtx reg, rtx mem) --+{ --+ riscv_emit_move (mem, reg); --+ riscv_set_frame_expr (riscv_frame_set (mem, reg)); --+} --+ --+/* Restore register REG from MEM. */ --+ --+static void --+riscv_restore_reg (rtx reg, rtx mem) --+{ --+ rtx insn = riscv_emit_move (reg, mem); --+ rtx dwarf = NULL_RTX; --+ dwarf = alloc_reg_note (REG_CFA_RESTORE, reg, dwarf); --+ REG_NOTES (insn) = dwarf; --+ --+ RTX_FRAME_RELATED_P (insn) = 1; --+} --+ --+/* Return the code to invoke the GPR save routine. */ --+ --+const char * --+riscv_output_gpr_save (unsigned mask) --+{ --+ static char s[32]; --+ unsigned n = riscv_save_libcall_count (mask); --+ --+ ssize_t bytes = snprintf (s, sizeof (s), "call\tt0,__riscv_save_%u", n); --+ gcc_assert ((size_t) bytes < sizeof (s)); --+ --+ return s; --+} --+ --+/* For stack frames that can't be allocated with a single ADDI instruction, --+ compute the best value to initially allocate. It must at a minimum --+ allocate enough space to spill the callee-saved registers. */ --+ --+static HOST_WIDE_INT --+riscv_first_stack_step (struct riscv_frame_info *frame) --+{ --+ HOST_WIDE_INT min_first_step = frame->total_size - frame->fp_sp_offset; --+ HOST_WIDE_INT max_first_step = IMM_REACH / 2 - STACK_BOUNDARY / 8; --+ --+ if (SMALL_OPERAND (frame->total_size)) --+ return frame->total_size; --+ --+ /* As an optimization, use the least-significant bits of the total frame --+ size, so that the second adjustment step is just LUI + ADD. */ --+ if (!SMALL_OPERAND (frame->total_size - max_first_step) --+ && frame->total_size % IMM_REACH < IMM_REACH / 2 --+ && frame->total_size % IMM_REACH >= min_first_step) --+ return frame->total_size % IMM_REACH; --+ --+ gcc_assert (min_first_step <= max_first_step); --+ return max_first_step; --+} --+ --+static rtx --+riscv_adjust_libcall_cfi_prologue () --+{ --+ rtx dwarf = NULL_RTX; --+ rtx adjust_sp_rtx, reg, mem, insn; --+ int saved_size = cfun->machine->frame.save_libcall_adjustment; --+ int offset; --+ --+ for (int regno = GP_REG_FIRST; regno <= GP_REG_LAST-1; regno++) --+ if (BITSET_P (cfun->machine->frame.mask, regno - GP_REG_FIRST)) --+ { --+ /* The save order is ra, s0, s1, s2 to s11. */ --+ if (regno == RETURN_ADDR_REGNUM) --+ offset = saved_size - UNITS_PER_WORD; --+ else if (regno == S0_REGNUM) --+ offset = saved_size - UNITS_PER_WORD * 2; --+ else if (regno == S1_REGNUM) --+ offset = saved_size - UNITS_PER_WORD * 3; --+ else --+ offset = saved_size - ((regno - S2_REGNUM + 4) * UNITS_PER_WORD); --+ --+ reg = gen_rtx_REG (SImode, regno); --+ mem = gen_frame_mem (SImode, plus_constant (Pmode, --+ stack_pointer_rtx, --+ offset)); --+ --+ insn = gen_rtx_SET (mem, reg); --+ dwarf = alloc_reg_note (REG_CFA_OFFSET, insn, dwarf); --+ } --+ --+ /* Debug info for adjust sp. */ --+ adjust_sp_rtx = gen_add3_insn (stack_pointer_rtx, --+ stack_pointer_rtx, GEN_INT (-saved_size)); --+ dwarf = alloc_reg_note (REG_CFA_ADJUST_CFA, adjust_sp_rtx, --+ dwarf); --+ return dwarf; --+} --+ --+static void --+riscv_emit_stack_tie (void) --+{ --+ if (Pmode == SImode) --+ emit_insn (gen_stack_tiesi (stack_pointer_rtx, hard_frame_pointer_rtx)); --+ else --+ emit_insn (gen_stack_tiedi (stack_pointer_rtx, hard_frame_pointer_rtx)); --+} --+ --+/* Expand the "prologue" pattern. */ --+ --+void --+riscv_expand_prologue (void) --+{ --+ struct riscv_frame_info *frame = &cfun->machine->frame; --+ HOST_WIDE_INT size = frame->total_size; --+ unsigned mask = frame->mask; --+ rtx insn; --+ --+ if (flag_stack_usage_info) --+ current_function_static_stack_size = size; --+ --+ /* When optimizing for size, call a subroutine to save the registers. */ --+ if (riscv_use_save_libcall (frame)) --+ { --+ rtx dwarf = NULL_RTX; --+ dwarf = riscv_adjust_libcall_cfi_prologue (); --+ --+ frame->mask = 0; /* Temporarily fib that we need not save GPRs. */ --+ size -= frame->save_libcall_adjustment; --+ insn = emit_insn (gen_gpr_save (GEN_INT (mask))); --+ --+ RTX_FRAME_RELATED_P (insn) = 1; --+ REG_NOTES (insn) = dwarf; --+ } --+ --+ /* Save the registers. */ --+ if ((frame->mask | frame->fmask) != 0) --+ { --+ HOST_WIDE_INT step1 = MIN (size, riscv_first_stack_step (frame)); --+ --+ insn = gen_add3_insn (stack_pointer_rtx, --+ stack_pointer_rtx, --+ GEN_INT (-step1)); --+ RTX_FRAME_RELATED_P (emit_insn (insn)) = 1; --+ size -= step1; --+ riscv_for_each_saved_reg (size, riscv_save_reg); --+ } --+ --+ frame->mask = mask; /* Undo the above fib. */ --+ --+ /* Set up the frame pointer, if we're using one. */ --+ if (frame_pointer_needed) --+ { --+ insn = gen_add3_insn (hard_frame_pointer_rtx, stack_pointer_rtx, --+ GEN_INT (frame->hard_frame_pointer_offset - size)); --+ RTX_FRAME_RELATED_P (emit_insn (insn)) = 1; --+ --+ riscv_emit_stack_tie (); --+ } --+ --+ /* Allocate the rest of the frame. */ --+ if (size > 0) --+ { --+ if (SMALL_OPERAND (-size)) --+ { --+ insn = gen_add3_insn (stack_pointer_rtx, stack_pointer_rtx, --+ GEN_INT (-size)); --+ RTX_FRAME_RELATED_P (emit_insn (insn)) = 1; --+ } --+ else --+ { --+ riscv_emit_move (RISCV_PROLOGUE_TEMP (Pmode), GEN_INT (-size)); --+ emit_insn (gen_add3_insn (stack_pointer_rtx, --+ stack_pointer_rtx, --+ RISCV_PROLOGUE_TEMP (Pmode))); --+ --+ /* Describe the effect of the previous instructions. */ --+ insn = plus_constant (Pmode, stack_pointer_rtx, -size); --+ insn = gen_rtx_SET (stack_pointer_rtx, insn); --+ riscv_set_frame_expr (insn); --+ } --+ } --+} --+ --+static rtx --+riscv_adjust_libcall_cfi_epilogue () --+{ --+ rtx dwarf = NULL_RTX; --+ rtx adjust_sp_rtx, reg; --+ int saved_size = cfun->machine->frame.save_libcall_adjustment; --+ --+ /* Debug info for adjust sp. */ --+ adjust_sp_rtx = gen_add3_insn (stack_pointer_rtx, --+ stack_pointer_rtx, GEN_INT (saved_size)); --+ dwarf = alloc_reg_note (REG_CFA_ADJUST_CFA, adjust_sp_rtx, --+ dwarf); --+ --+ for (int regno = GP_REG_FIRST; regno <= GP_REG_LAST-1; regno++) --+ if (BITSET_P (cfun->machine->frame.mask, regno - GP_REG_FIRST)) --+ { --+ reg = gen_rtx_REG (SImode, regno); --+ dwarf = alloc_reg_note (REG_CFA_RESTORE, reg, dwarf); --+ } --+ --+ return dwarf; --+} --+ --+/* Expand an "epilogue" or "sibcall_epilogue" pattern; SIBCALL_P --+ says which. */ --+ --+void --+riscv_expand_epilogue (bool sibcall_p) --+{ --+ /* Split the frame into two. STEP1 is the amount of stack we should --+ deallocate before restoring the registers. STEP2 is the amount we --+ should deallocate afterwards. --+ --+ Start off by assuming that no registers need to be restored. */ --+ struct riscv_frame_info *frame = &cfun->machine->frame; --+ unsigned mask = frame->mask; --+ HOST_WIDE_INT step1 = frame->total_size; --+ HOST_WIDE_INT step2 = 0; --+ bool use_restore_libcall = !sibcall_p && riscv_use_save_libcall (frame); --+ rtx ra = gen_rtx_REG (Pmode, RETURN_ADDR_REGNUM); --+ rtx insn; --+ --+ /* We need to add memory barrier to prevent read from deallocated stack. */ --+ bool need_barrier_p = (get_frame_size () --+ + cfun->machine->frame.arg_pointer_offset) != 0; --+ --+ if (!sibcall_p && riscv_can_use_return_insn ()) --+ { --+ emit_jump_insn (gen_return ()); --+ return; --+ } --+ --+ /* Move past any dynamic stack allocations. */ --+ if (cfun->calls_alloca) --+ { --+ /* Emit a barrier to prevent loads from a deallocated stack. */ --+ riscv_emit_stack_tie (); --+ need_barrier_p = false; --+ --+ rtx adjust = GEN_INT (-frame->hard_frame_pointer_offset); --+ if (!SMALL_OPERAND (INTVAL (adjust))) --+ { --+ riscv_emit_move (RISCV_PROLOGUE_TEMP (Pmode), adjust); --+ adjust = RISCV_PROLOGUE_TEMP (Pmode); --+ } --+ --+ insn = emit_insn ( --+ gen_add3_insn (stack_pointer_rtx, hard_frame_pointer_rtx, --+ adjust)); --+ --+ rtx dwarf = NULL_RTX; --+ rtx cfa_adjust_value = gen_rtx_PLUS ( --+ Pmode, hard_frame_pointer_rtx, --+ GEN_INT (-frame->hard_frame_pointer_offset)); --+ rtx cfa_adjust_rtx = gen_rtx_SET (stack_pointer_rtx, cfa_adjust_value); --+ dwarf = alloc_reg_note (REG_CFA_ADJUST_CFA, cfa_adjust_rtx, dwarf); --+ RTX_FRAME_RELATED_P (insn) = 1; --+ --+ REG_NOTES (insn) = dwarf; --+ } --+ --+ /* If we need to restore registers, deallocate as much stack as --+ possible in the second step without going out of range. */ --+ if ((frame->mask | frame->fmask) != 0) --+ { --+ step2 = riscv_first_stack_step (frame); --+ step1 -= step2; --+ } --+ --+ /* Set TARGET to BASE + STEP1. */ --+ if (step1 > 0) --+ { --+ /* Emit a barrier to prevent loads from a deallocated stack. */ --+ riscv_emit_stack_tie (); --+ need_barrier_p = false; --+ --+ /* Get an rtx for STEP1 that we can add to BASE. */ --+ rtx adjust = GEN_INT (step1); --+ if (!SMALL_OPERAND (step1)) --+ { --+ riscv_emit_move (RISCV_PROLOGUE_TEMP (Pmode), adjust); --+ adjust = RISCV_PROLOGUE_TEMP (Pmode); --+ } --+ --+ insn = emit_insn ( --+ gen_add3_insn (stack_pointer_rtx, stack_pointer_rtx, adjust)); --+ --+ rtx dwarf = NULL_RTX; --+ rtx cfa_adjust_rtx = gen_rtx_PLUS (Pmode, stack_pointer_rtx, --+ GEN_INT (step2)); --+ --+ dwarf = alloc_reg_note (REG_CFA_DEF_CFA, cfa_adjust_rtx, dwarf); --+ RTX_FRAME_RELATED_P (insn) = 1; --+ --+ REG_NOTES (insn) = dwarf; --+ } --+ --+ if (use_restore_libcall) --+ frame->mask = 0; /* Temporarily fib that we need not save GPRs. */ --+ --+ /* Restore the registers. */ --+ riscv_for_each_saved_reg (frame->total_size - step2, riscv_restore_reg); --+ --+ if (use_restore_libcall) --+ { --+ frame->mask = mask; /* Undo the above fib. */ --+ gcc_assert (step2 >= frame->save_libcall_adjustment); --+ step2 -= frame->save_libcall_adjustment; --+ } --+ --+ if (need_barrier_p) --+ riscv_emit_stack_tie (); --+ --+ /* Deallocate the final bit of the frame. */ --+ if (step2 > 0) --+ { --+ insn = emit_insn (gen_add3_insn (stack_pointer_rtx, stack_pointer_rtx, --+ GEN_INT (step2))); --+ --+ rtx dwarf = NULL_RTX; --+ rtx cfa_adjust_rtx = gen_rtx_PLUS (Pmode, stack_pointer_rtx, --+ const0_rtx); --+ dwarf = alloc_reg_note (REG_CFA_DEF_CFA, cfa_adjust_rtx, dwarf); --+ RTX_FRAME_RELATED_P (insn) = 1; --+ --+ REG_NOTES (insn) = dwarf; --+ } --+ --+ if (use_restore_libcall) --+ { --+ rtx dwarf = riscv_adjust_libcall_cfi_epilogue (); --+ insn = emit_insn (gen_gpr_restore (GEN_INT (riscv_save_libcall_count (mask)))); --+ RTX_FRAME_RELATED_P (insn) = 1; --+ REG_NOTES (insn) = dwarf; --+ --+ emit_jump_insn (gen_gpr_restore_return (ra)); --+ return; --+ } --+ --+ /* Add in the __builtin_eh_return stack adjustment. */ --+ if (crtl->calls_eh_return) --+ emit_insn (gen_add3_insn (stack_pointer_rtx, stack_pointer_rtx, --+ EH_RETURN_STACKADJ_RTX)); --+ --+ if (!sibcall_p) --+ emit_jump_insn (gen_simple_return_internal (ra)); --+} --+ --+/* Return nonzero if this function is known to have a null epilogue. --+ This allows the optimizer to omit jumps to jumps if no stack --+ was created. */ --+ --+bool --+riscv_can_use_return_insn (void) --+{ --+ return reload_completed && cfun->machine->frame.total_size == 0; --+} --+ --+/* Implement TARGET_REGISTER_MOVE_COST. */ --+ --+static int --+riscv_register_move_cost (enum machine_mode mode, --+ reg_class_t from, reg_class_t to) --+{ --+ return SECONDARY_MEMORY_NEEDED (from, to, mode) ? 8 : 2; --+} --+ --+/* Return true if register REGNO can store a value of mode MODE. */ --+ --+bool --+riscv_hard_regno_mode_ok_p (unsigned int regno, enum machine_mode mode) --+{ --+ unsigned int nregs = riscv_hard_regno_nregs (regno, mode); --+ --+ if (GP_REG_P (regno)) --+ { --+ if (!GP_REG_P (regno + nregs - 1)) --+ return false; --+ } --+ else if (FP_REG_P (regno)) --+ { --+ if (!FP_REG_P (regno + nregs - 1)) --+ return false; --+ --+ if (GET_MODE_CLASS (mode) != MODE_FLOAT --+ && GET_MODE_CLASS (mode) != MODE_COMPLEX_FLOAT) --+ return false; --+ --+ /* Only use callee-saved registers if a potential callee is guaranteed --+ to spill the requisite width. */ --+ if (GET_MODE_UNIT_SIZE (mode) > UNITS_PER_FP_REG --+ || (!call_used_regs[regno] --+ && GET_MODE_UNIT_SIZE (mode) > UNITS_PER_FP_ARG)) --+ return false; --+ } --+ else --+ return false; --+ --+ /* Require same callee-savedness for all registers. */ --+ for (unsigned i = 1; i < nregs; i++) --+ if (call_used_regs[regno] != call_used_regs[regno + i]) --+ return false; --+ --+ return true; --+} --+ --+/* Implement HARD_REGNO_NREGS. */ --+ --+unsigned int --+riscv_hard_regno_nregs (int regno, enum machine_mode mode) --+{ --+ if (FP_REG_P (regno)) --+ return (GET_MODE_SIZE (mode) + UNITS_PER_FP_REG - 1) / UNITS_PER_FP_REG; --+ --+ /* All other registers are word-sized. */ --+ return (GET_MODE_SIZE (mode) + UNITS_PER_WORD - 1) / UNITS_PER_WORD; --+} --+ --+/* Implement CLASS_MAX_NREGS. */ --+ --+static unsigned char --+riscv_class_max_nregs (reg_class_t rclass, enum machine_mode mode) --+{ --+ if (reg_class_subset_p (FP_REGS, rclass)) --+ return riscv_hard_regno_nregs (FP_REG_FIRST, mode); --+ --+ if (reg_class_subset_p (GR_REGS, rclass)) --+ return riscv_hard_regno_nregs (GP_REG_FIRST, mode); --+ --+ return 0; --+} --+ --+/* Implement TARGET_PREFERRED_RELOAD_CLASS. */ --+ --+static reg_class_t --+riscv_preferred_reload_class (rtx x ATTRIBUTE_UNUSED, reg_class_t rclass) --+{ --+ return reg_class_subset_p (FP_REGS, rclass) ? FP_REGS : --+ reg_class_subset_p (GR_REGS, rclass) ? GR_REGS : --+ rclass; --+} --+ --+/* Implement TARGET_MEMORY_MOVE_COST. */ --+ --+static int --+riscv_memory_move_cost (enum machine_mode mode, reg_class_t rclass, bool in) --+{ --+ return (tune_info->memory_cost --+ + memory_move_secondary_cost (mode, rclass, in)); --+} --+ --+/* Return the number of instructions that can be issued per cycle. */ --+ --+static int --+riscv_issue_rate (void) --+{ --+ return tune_info->issue_rate; --+} --+ --+/* Implement TARGET_ASM_FILE_START. */ --+ --+static void --+riscv_file_start (void) --+{ --+ default_file_start (); --+ --+ /* Instruct GAS to generate position-[in]dependent code. */ --+ fprintf (asm_out_file, "\t.option %spic\n", (flag_pic ? "" : "no")); --+} --+ --+/* Implement TARGET_ASM_OUTPUT_MI_THUNK. Generate rtl rather than asm text --+ in order to avoid duplicating too much logic from elsewhere. */ --+ --+static void --+riscv_output_mi_thunk (FILE *file, tree thunk_fndecl ATTRIBUTE_UNUSED, --+ HOST_WIDE_INT delta, HOST_WIDE_INT vcall_offset, --+ tree function) --+{ --+ rtx this_rtx, temp1, temp2, fnaddr; --+ rtx_insn *insn; --+ --+ /* Pretend to be a post-reload pass while generating rtl. */ --+ reload_completed = 1; --+ --+ /* Mark the end of the (empty) prologue. */ --+ emit_note (NOTE_INSN_PROLOGUE_END); --+ --+ /* Determine if we can use a sibcall to call FUNCTION directly. */ --+ fnaddr = gen_rtx_MEM (FUNCTION_MODE, XEXP (DECL_RTL (function), 0)); --+ --+ /* We need two temporary registers in some cases. */ --+ temp1 = gen_rtx_REG (Pmode, RISCV_PROLOGUE_TEMP_REGNUM); --+ temp2 = gen_rtx_REG (Pmode, STATIC_CHAIN_REGNUM); --+ --+ /* Find out which register contains the "this" pointer. */ --+ if (aggregate_value_p (TREE_TYPE (TREE_TYPE (function)), function)) --+ this_rtx = gen_rtx_REG (Pmode, GP_ARG_FIRST + 1); --+ else --+ this_rtx = gen_rtx_REG (Pmode, GP_ARG_FIRST); --+ --+ /* Add DELTA to THIS_RTX. */ --+ if (delta != 0) --+ { --+ rtx offset = GEN_INT (delta); --+ if (!SMALL_OPERAND (delta)) --+ { --+ riscv_emit_move (temp1, offset); --+ offset = temp1; --+ } --+ emit_insn (gen_add3_insn (this_rtx, this_rtx, offset)); --+ } --+ --+ /* If needed, add *(*THIS_RTX + VCALL_OFFSET) to THIS_RTX. */ --+ if (vcall_offset != 0) --+ { --+ rtx addr; --+ --+ /* Set TEMP1 to *THIS_RTX. */ --+ riscv_emit_move (temp1, gen_rtx_MEM (Pmode, this_rtx)); --+ --+ /* Set ADDR to a legitimate address for *THIS_RTX + VCALL_OFFSET. */ --+ addr = riscv_add_offset (temp2, temp1, vcall_offset); --+ --+ /* Load the offset and add it to THIS_RTX. */ --+ riscv_emit_move (temp1, gen_rtx_MEM (Pmode, addr)); --+ emit_insn (gen_add3_insn (this_rtx, this_rtx, temp1)); --+ } --+ --+ /* Jump to the target function. */ --+ insn = emit_call_insn (gen_sibcall (fnaddr, const0_rtx, NULL, const0_rtx)); --+ SIBLING_CALL_P (insn) = 1; --+ --+ /* Run just enough of rest_of_compilation. This sequence was --+ "borrowed" from alpha.c. */ --+ insn = get_insns (); --+ split_all_insns_noflow (); --+ shorten_branches (insn); --+ final_start_function (insn, file, 1); --+ final (insn, file, 1); --+ final_end_function (); --+ --+ /* Clean up the vars set above. Note that final_end_function resets --+ the global pointer for us. */ --+ reload_completed = 0; --+} --+ --+/* Allocate a chunk of memory for per-function machine-dependent data. */ --+ --+static struct machine_function * --+riscv_init_machine_status (void) --+{ --+ return ggc_cleared_alloc (); --+} --+ --+/* Implement TARGET_OPTION_OVERRIDE. */ --+ --+static void --+riscv_option_override (void) --+{ --+ const struct riscv_cpu_info *cpu; --+ --+#ifdef SUBTARGET_OVERRIDE_OPTIONS --+ SUBTARGET_OVERRIDE_OPTIONS; --+#endif --+ --+ flag_pcc_struct_return = 0; --+ --+ if (flag_pic) --+ g_switch_value = 0; --+ --+ /* The presence of the M extension implies that division instructions --+ are present, so include them unless explicitly disabled. */ --+ if (TARGET_MUL && (target_flags_explicit & MASK_DIV) == 0) --+ target_flags |= MASK_DIV; --+ else if (!TARGET_MUL && TARGET_DIV) --+ error ("-mdiv requires -march to subsume the % extension"); --+ --+ /* Likewise floating-point division and square root. */ --+ if (TARGET_HARD_FLOAT && (target_flags_explicit & MASK_FDIV) == 0) --+ target_flags |= MASK_FDIV; --+ --+ /* Handle -mtune. */ --+ cpu = riscv_parse_cpu (riscv_tune_string ? riscv_tune_string : --+ RISCV_TUNE_STRING_DEFAULT); --+ tune_info = optimize_size ? &optimize_size_tune_info : cpu->tune_info; --+ --+ /* If the user hasn't specified a branch cost, use the processor's --+ default. */ --+ if (riscv_branch_cost == 0) --+ riscv_branch_cost = tune_info->branch_cost; --+ --+ /* Function to allocate machine-dependent function status. */ --+ init_machine_status = &riscv_init_machine_status; --+ --+ if (flag_pic) --+ riscv_cmodel = CM_PIC; --+ --+ /* We get better code with explicit relocs for CM_MEDLOW, but --+ worse code for the others (for now). Pick the best default. */ --+ if ((target_flags_explicit & MASK_EXPLICIT_RELOCS) == 0) --+ if (riscv_cmodel == CM_MEDLOW) --+ target_flags |= MASK_EXPLICIT_RELOCS; --+ --+ /* Require that the ISA supports the requested floating-point ABI. */ --+ if (UNITS_PER_FP_ARG > (TARGET_HARD_FLOAT ? UNITS_PER_FP_REG : 0)) --+ error ("requested ABI requires -march to subsume the %qc extension", --+ UNITS_PER_FP_ARG > 8 ? 'Q' : (UNITS_PER_FP_ARG > 4 ? 'D' : 'F')); --+ --+ /* We do not yet support ILP32 on RV64. */ --+ if (BITS_PER_WORD != POINTER_SIZE) --+ error ("ABI requires -march=rv%d", POINTER_SIZE); --+} --+ --+/* Implement TARGET_CONDITIONAL_REGISTER_USAGE. */ --+ --+static void --+riscv_conditional_register_usage (void) --+{ --+ if (!TARGET_HARD_FLOAT) --+ { --+ for (int regno = FP_REG_FIRST; regno <= FP_REG_LAST; regno++) --+ fixed_regs[regno] = call_used_regs[regno] = 1; --+ } --+} --+ --+/* Return a register priority for hard reg REGNO. */ --+ --+static int --+riscv_register_priority (int regno) --+{ --+ /* Favor x8-x15/f8-f15 to improve the odds of RVC instruction selection. */ --+ if (TARGET_RVC && (IN_RANGE (regno, GP_REG_FIRST + 8, GP_REG_FIRST + 15) --+ || IN_RANGE (regno, FP_REG_FIRST + 8, FP_REG_FIRST + 15))) --+ return 1; --+ --+ return 0; --+} --+ --+/* Implement TARGET_TRAMPOLINE_INIT. */ --+ --+static void --+riscv_trampoline_init (rtx m_tramp, tree fndecl, rtx chain_value) --+{ --+ rtx addr, end_addr, mem; --+ uint32_t trampoline[4]; --+ unsigned int i; --+ HOST_WIDE_INT static_chain_offset, target_function_offset; --+ --+ /* Work out the offsets of the pointers from the start of the --+ trampoline code. */ --+ gcc_assert (ARRAY_SIZE (trampoline) * 4 == TRAMPOLINE_CODE_SIZE); --+ --+ /* Get pointers to the beginning and end of the code block. */ --+ addr = force_reg (Pmode, XEXP (m_tramp, 0)); --+ end_addr = riscv_force_binary (Pmode, PLUS, addr, --+ GEN_INT (TRAMPOLINE_CODE_SIZE)); --+ --+ --+ if (Pmode == SImode) --+ { --+ chain_value = force_reg (Pmode, chain_value); --+ --+ rtx target_function = force_reg (Pmode, XEXP (DECL_RTL (fndecl), 0)); --+ /* lui t2, hi(chain) --+ lui t1, hi(func) --+ addi t2, t2, lo(chain) --+ jr r1, lo(func) --+ */ --+ unsigned HOST_WIDE_INT lui_hi_chain_code, lui_hi_func_code; --+ unsigned HOST_WIDE_INT lo_chain_code, lo_func_code; --+ --+ rtx uimm_mask = force_reg (SImode, gen_int_mode (-IMM_REACH, SImode)); --+ --+ /* 0xfff. */ --+ rtx imm12_mask = gen_reg_rtx (SImode); --+ emit_insn (gen_one_cmplsi2 (imm12_mask, uimm_mask)); --+ --+ rtx fixup_value = force_reg (SImode, gen_int_mode (IMM_REACH/2, SImode)); --+ --+ /* Gen lui t2, hi(chain). */ --+ rtx hi_chain = riscv_force_binary (SImode, PLUS, chain_value, --+ fixup_value); --+ hi_chain = riscv_force_binary (SImode, AND, hi_chain, --+ uimm_mask); --+ lui_hi_chain_code = OPCODE_LUI | (STATIC_CHAIN_REGNUM << SHIFT_RD); --+ rtx lui_hi_chain = riscv_force_binary (SImode, IOR, hi_chain, --+ gen_int_mode (lui_hi_chain_code, SImode)); --+ --+ mem = adjust_address (m_tramp, SImode, 0); --+ riscv_emit_move (mem, lui_hi_chain); --+ --+ /* Gen lui t1, hi(func). */ --+ rtx hi_func = riscv_force_binary (SImode, PLUS, target_function, --+ fixup_value); --+ hi_func = riscv_force_binary (SImode, AND, hi_func, --+ uimm_mask); --+ lui_hi_func_code = OPCODE_LUI | (RISCV_PROLOGUE_TEMP_REGNUM << SHIFT_RD); --+ rtx lui_hi_func = riscv_force_binary (SImode, IOR, hi_func, --+ gen_int_mode (lui_hi_func_code, SImode)); --+ --+ mem = adjust_address (m_tramp, SImode, 1 * GET_MODE_SIZE (SImode)); --+ riscv_emit_move (mem, lui_hi_func); --+ --+ /* Gen addi t2, t2, lo(chain). */ --+ rtx lo_chain = riscv_force_binary (SImode, AND, chain_value, --+ imm12_mask); --+ lo_chain = riscv_force_binary (SImode, ASHIFT, lo_chain, GEN_INT (20)); --+ --+ lo_chain_code = OPCODE_ADDI --+ | (STATIC_CHAIN_REGNUM << SHIFT_RD) --+ | (STATIC_CHAIN_REGNUM << SHIFT_RS1); --+ --+ rtx addi_lo_chain = riscv_force_binary (SImode, IOR, lo_chain, --+ force_reg (SImode, GEN_INT (lo_chain_code))); --+ --+ mem = adjust_address (m_tramp, SImode, 2 * GET_MODE_SIZE (SImode)); --+ riscv_emit_move (mem, addi_lo_chain); --+ --+ /* Gen jr r1, lo(func). */ --+ rtx lo_func = riscv_force_binary (SImode, AND, target_function, --+ imm12_mask); --+ lo_func = riscv_force_binary (SImode, ASHIFT, lo_func, GEN_INT (20)); --+ --+ lo_func_code = OPCODE_JALR | (RISCV_PROLOGUE_TEMP_REGNUM << SHIFT_RS1); --+ --+ rtx jr_lo_func = riscv_force_binary (SImode, IOR, lo_func, --+ force_reg (SImode, GEN_INT (lo_func_code))); --+ --+ mem = adjust_address (m_tramp, SImode, 3 * GET_MODE_SIZE (SImode)); --+ riscv_emit_move (mem, jr_lo_func); --+ } --+ else --+ { --+ static_chain_offset = TRAMPOLINE_CODE_SIZE; --+ target_function_offset = static_chain_offset + GET_MODE_SIZE (ptr_mode); --+ --+ /* auipc t2, 0 --+ l[wd] t1, target_function_offset(t2) --+ l[wd] t2, static_chain_offset(t2) --+ jr t1 --+ */ --+ trampoline[0] = OPCODE_AUIPC | (STATIC_CHAIN_REGNUM << SHIFT_RD); --+ trampoline[1] = (Pmode == DImode ? OPCODE_LD : OPCODE_LW) --+ | (RISCV_PROLOGUE_TEMP_REGNUM << SHIFT_RD) --+ | (STATIC_CHAIN_REGNUM << SHIFT_RS1) --+ | (target_function_offset << SHIFT_IMM); --+ trampoline[2] = (Pmode == DImode ? OPCODE_LD : OPCODE_LW) --+ | (STATIC_CHAIN_REGNUM << SHIFT_RD) --+ | (STATIC_CHAIN_REGNUM << SHIFT_RS1) --+ | (static_chain_offset << SHIFT_IMM); --+ trampoline[3] = OPCODE_JALR | (RISCV_PROLOGUE_TEMP_REGNUM << SHIFT_RS1); --+ --+ /* Copy the trampoline code. */ --+ for (i = 0; i < ARRAY_SIZE (trampoline); i++) --+ { --+ mem = adjust_address (m_tramp, SImode, i * GET_MODE_SIZE (SImode)); --+ riscv_emit_move (mem, gen_int_mode (trampoline[i], SImode)); --+ } --+ --+ /* Set up the static chain pointer field. */ --+ mem = adjust_address (m_tramp, ptr_mode, static_chain_offset); --+ riscv_emit_move (mem, chain_value); --+ --+ /* Set up the target function field. */ --+ mem = adjust_address (m_tramp, ptr_mode, target_function_offset); --+ riscv_emit_move (mem, XEXP (DECL_RTL (fndecl), 0)); --+ } --+ --+ /* Flush the code part of the trampoline. */ --+ emit_insn (gen_add3_insn (end_addr, addr, GEN_INT (TRAMPOLINE_SIZE))); --+ emit_insn (gen_clear_cache (addr, end_addr)); --+} --+ --+/* Return leaf_function_p () and memoize the result. */ --+ --+static bool --+riscv_leaf_function_p (void) --+{ --+ if (cfun->machine->is_leaf == 0) --+ cfun->machine->is_leaf = leaf_function_p () ? 1 : -1; --+ --+ return cfun->machine->is_leaf > 0; --+} --+ --+/* Implement TARGET_FUNCTION_OK_FOR_SIBCALL. */ --+ --+static bool --+riscv_function_ok_for_sibcall (tree decl ATTRIBUTE_UNUSED, --+ tree exp ATTRIBUTE_UNUSED) --+{ --+ /* When optimzing for size, don't use sibcalls in non-leaf routines */ --+ if (TARGET_SAVE_RESTORE) --+ return riscv_leaf_function_p (); --+ --+ return true; --+} --+ --+/* Implement TARGET_CANNOT_COPY_INSN_P. */ --+ --+static bool --+riscv_cannot_copy_insn_p (rtx_insn *insn) --+{ --+ return recog_memoized (insn) >= 0 && get_attr_cannot_copy (insn); --+} --+ --+/* Initialize the GCC target structure. */ --+#undef TARGET_ASM_ALIGNED_HI_OP --+#define TARGET_ASM_ALIGNED_HI_OP "\t.half\t" --+#undef TARGET_ASM_ALIGNED_SI_OP --+#define TARGET_ASM_ALIGNED_SI_OP "\t.word\t" --+#undef TARGET_ASM_ALIGNED_DI_OP --+#define TARGET_ASM_ALIGNED_DI_OP "\t.dword\t" --+ --+#undef TARGET_OPTION_OVERRIDE --+#define TARGET_OPTION_OVERRIDE riscv_option_override --+ --+#undef TARGET_LEGITIMIZE_ADDRESS --+#define TARGET_LEGITIMIZE_ADDRESS riscv_legitimize_address --+ --+#undef TARGET_SCHED_ISSUE_RATE --+#define TARGET_SCHED_ISSUE_RATE riscv_issue_rate --+ --+#undef TARGET_FUNCTION_OK_FOR_SIBCALL --+#define TARGET_FUNCTION_OK_FOR_SIBCALL riscv_function_ok_for_sibcall --+ --+#undef TARGET_REGISTER_MOVE_COST --+#define TARGET_REGISTER_MOVE_COST riscv_register_move_cost --+#undef TARGET_MEMORY_MOVE_COST --+#define TARGET_MEMORY_MOVE_COST riscv_memory_move_cost --+#undef TARGET_RTX_COSTS --+#define TARGET_RTX_COSTS riscv_rtx_costs --+#undef TARGET_ADDRESS_COST --+#define TARGET_ADDRESS_COST riscv_address_cost --+ --+#undef TARGET_PREFERRED_RELOAD_CLASS --+#define TARGET_PREFERRED_RELOAD_CLASS riscv_preferred_reload_class --+ --+#undef TARGET_ASM_FILE_START --+#define TARGET_ASM_FILE_START riscv_file_start --+#undef TARGET_ASM_FILE_START_FILE_DIRECTIVE --+#define TARGET_ASM_FILE_START_FILE_DIRECTIVE true --+ --+#undef TARGET_EXPAND_BUILTIN_VA_START --+#define TARGET_EXPAND_BUILTIN_VA_START riscv_va_start --+ --+#undef TARGET_PROMOTE_FUNCTION_MODE --+#define TARGET_PROMOTE_FUNCTION_MODE default_promote_function_mode_always_promote --+ --+#undef TARGET_RETURN_IN_MEMORY --+#define TARGET_RETURN_IN_MEMORY riscv_return_in_memory --+ --+#undef TARGET_ASM_OUTPUT_MI_THUNK --+#define TARGET_ASM_OUTPUT_MI_THUNK riscv_output_mi_thunk --+#undef TARGET_ASM_CAN_OUTPUT_MI_THUNK --+#define TARGET_ASM_CAN_OUTPUT_MI_THUNK hook_bool_const_tree_hwi_hwi_const_tree_true --+ --+#undef TARGET_PRINT_OPERAND --+#define TARGET_PRINT_OPERAND riscv_print_operand --+#undef TARGET_PRINT_OPERAND_ADDRESS --+#define TARGET_PRINT_OPERAND_ADDRESS riscv_print_operand_address --+ --+#undef TARGET_SETUP_INCOMING_VARARGS --+#define TARGET_SETUP_INCOMING_VARARGS riscv_setup_incoming_varargs --+#undef TARGET_STRICT_ARGUMENT_NAMING --+#define TARGET_STRICT_ARGUMENT_NAMING hook_bool_CUMULATIVE_ARGS_true --+#undef TARGET_MUST_PASS_IN_STACK --+#define TARGET_MUST_PASS_IN_STACK must_pass_in_stack_var_size --+#undef TARGET_PASS_BY_REFERENCE --+#define TARGET_PASS_BY_REFERENCE riscv_pass_by_reference --+#undef TARGET_ARG_PARTIAL_BYTES --+#define TARGET_ARG_PARTIAL_BYTES riscv_arg_partial_bytes --+#undef TARGET_FUNCTION_ARG --+#define TARGET_FUNCTION_ARG riscv_function_arg --+#undef TARGET_FUNCTION_ARG_ADVANCE --+#define TARGET_FUNCTION_ARG_ADVANCE riscv_function_arg_advance --+#undef TARGET_FUNCTION_ARG_BOUNDARY --+#define TARGET_FUNCTION_ARG_BOUNDARY riscv_function_arg_boundary --+ --+/* The generic ELF target does not always have TLS support. */ --+#ifdef HAVE_AS_TLS --+#undef TARGET_HAVE_TLS --+#define TARGET_HAVE_TLS true --+#endif --+ --+#undef TARGET_CANNOT_FORCE_CONST_MEM --+#define TARGET_CANNOT_FORCE_CONST_MEM riscv_cannot_force_const_mem --+ --+#undef TARGET_LEGITIMATE_CONSTANT_P --+#define TARGET_LEGITIMATE_CONSTANT_P riscv_legitimate_constant_p --+ --+#undef TARGET_USE_BLOCKS_FOR_CONSTANT_P --+#define TARGET_USE_BLOCKS_FOR_CONSTANT_P hook_bool_mode_const_rtx_true --+ --+#undef TARGET_LEGITIMATE_ADDRESS_P --+#define TARGET_LEGITIMATE_ADDRESS_P riscv_legitimate_address_p --+ --+#undef TARGET_CAN_ELIMINATE --+#define TARGET_CAN_ELIMINATE riscv_can_eliminate --+ --+#undef TARGET_CONDITIONAL_REGISTER_USAGE --+#define TARGET_CONDITIONAL_REGISTER_USAGE riscv_conditional_register_usage --+ --+#undef TARGET_CLASS_MAX_NREGS --+#define TARGET_CLASS_MAX_NREGS riscv_class_max_nregs --+ --+#undef TARGET_TRAMPOLINE_INIT --+#define TARGET_TRAMPOLINE_INIT riscv_trampoline_init --+ --+#undef TARGET_IN_SMALL_DATA_P --+#define TARGET_IN_SMALL_DATA_P riscv_in_small_data_p --+ --+#undef TARGET_ASM_SELECT_RTX_SECTION --+#define TARGET_ASM_SELECT_RTX_SECTION riscv_elf_select_rtx_section --+ --+#undef TARGET_MIN_ANCHOR_OFFSET --+#define TARGET_MIN_ANCHOR_OFFSET (-IMM_REACH/2) --+ --+#undef TARGET_MAX_ANCHOR_OFFSET --+#define TARGET_MAX_ANCHOR_OFFSET (IMM_REACH/2-1) --+ --+#undef TARGET_REGISTER_PRIORITY --+#define TARGET_REGISTER_PRIORITY riscv_register_priority --+ --+#undef TARGET_CANNOT_COPY_INSN_P --+#define TARGET_CANNOT_COPY_INSN_P riscv_cannot_copy_insn_p --+ --+#undef TARGET_ATOMIC_ASSIGN_EXPAND_FENV --+#define TARGET_ATOMIC_ASSIGN_EXPAND_FENV riscv_atomic_assign_expand_fenv --+ --+#undef TARGET_INIT_BUILTINS --+#define TARGET_INIT_BUILTINS riscv_init_builtins --+ --+#undef TARGET_BUILTIN_DECL --+#define TARGET_BUILTIN_DECL riscv_builtin_decl --+ --+#undef TARGET_EXPAND_BUILTIN --+#define TARGET_EXPAND_BUILTIN riscv_expand_builtin --+ --+struct gcc_target targetm = TARGET_INITIALIZER; --+ --+#include "gt-riscv.h" --diff --git original-gcc/gcc/config/riscv/riscv.h gcc-6.3.0/gcc/config/riscv/riscv.h --new file mode 100644 --index 00000000000..8d4c75e6770 ----- /dev/null --+++ gcc-6.3.0/gcc/config/riscv/riscv.h --@@ -0,0 +1,906 @@ --+/* Definition of RISC-V target for GNU compiler. --+ Copyright (C) 2011-2017 Free Software Foundation, Inc. --+ Contributed by Andrew Waterman (andrew@sifive.com). --+ Based on MIPS target for GNU compiler. --+ --+This file is part of GCC. --+ --+GCC is free software; you can redistribute it and/or modify --+it under the terms of the GNU General Public License as published by --+the Free Software Foundation; either version 3, or (at your option) --+any later version. --+ --+GCC is distributed in the hope that it will be useful, --+but WITHOUT ANY WARRANTY; without even the implied warranty of --+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the --+GNU General Public License for more details. --+ --+You should have received a copy of the GNU General Public License --+along with GCC; see the file COPYING3. If not see --+. */ --+ --+#ifndef GCC_RISCV_H --+#define GCC_RISCV_H --+ --+#include "config/riscv/riscv-opts.h" --+ --+/* Target CPU builtins. */ --+#define TARGET_CPU_CPP_BUILTINS() riscv_cpu_cpp_builtins (pfile) --+ --+/* Default target_flags if no switches are specified */ --+ --+#ifndef TARGET_DEFAULT --+#define TARGET_DEFAULT 0 --+#endif --+ --+#ifndef RISCV_TUNE_STRING_DEFAULT --+#define RISCV_TUNE_STRING_DEFAULT "rocket" --+#endif --+ --+/* Support for a compile-time default CPU, et cetera. The rules are: --+ --with-arch is ignored if -march is specified. --+ --with-abi is ignored if -mabi is specified. --+ --with-tune is ignored if -mtune is specified. */ --+#define OPTION_DEFAULT_SPECS \ --+ {"tune", "%{!mtune=*:-mtune=%(VALUE)}" }, \ --+ {"arch", "%{!march=*:-march=%(VALUE)}" }, \ --+ {"abi", "%{!mabi=*:-mabi=%(VALUE)}" }, \ --+ --+#ifdef IN_LIBGCC2 --+#undef TARGET_64BIT --+/* Make this compile time constant for libgcc2 */ --+#define TARGET_64BIT (__riscv_xlen == 64) --+#endif /* IN_LIBGCC2 */ --+ --+#undef ASM_SPEC --+#define ASM_SPEC "\ --+%(subtarget_asm_debugging_spec) \ --+%{" FPIE_OR_FPIC_SPEC ":-fpic} \ --+%{march=*} \ --+%{mabi=*} \ --+%(subtarget_asm_spec)" --+ --+#define TARGET_DEFAULT_CMODEL CM_MEDLOW --+ --+#define LOCAL_LABEL_PREFIX "." --+#define USER_LABEL_PREFIX "" --+ --+/* Offsets recorded in opcodes are a multiple of this alignment factor. --+ The default for this in 64-bit mode is 8, which causes problems with --+ SFmode register saves. */ --+#define DWARF_CIE_DATA_ALIGNMENT -4 --+ --+/* The mapping from gcc register number to DWARF 2 CFA column number. */ --+#define DWARF_FRAME_REGNUM(REGNO) \ --+ (GP_REG_P (REGNO) || FP_REG_P (REGNO) ? REGNO : INVALID_REGNUM) --+ --+/* The DWARF 2 CFA column which tracks the return address. */ --+#define DWARF_FRAME_RETURN_COLUMN RETURN_ADDR_REGNUM --+#define INCOMING_RETURN_ADDR_RTX gen_rtx_REG (VOIDmode, RETURN_ADDR_REGNUM) --+ --+/* Describe how we implement __builtin_eh_return. */ --+#define EH_RETURN_DATA_REGNO(N) \ --+ ((N) < 4 ? (N) + GP_ARG_FIRST : INVALID_REGNUM) --+ --+#define EH_RETURN_STACKADJ_RTX gen_rtx_REG (Pmode, GP_ARG_FIRST + 4) --+ --+/* Target machine storage layout */ --+ --+#define BITS_BIG_ENDIAN 0 --+#define BYTES_BIG_ENDIAN 0 --+#define WORDS_BIG_ENDIAN 0 --+ --+#define MAX_BITS_PER_WORD 64 --+ --+/* Width of a word, in units (bytes). */ --+#define UNITS_PER_WORD (TARGET_64BIT ? 8 : 4) --+#ifndef IN_LIBGCC2 --+#define MIN_UNITS_PER_WORD 4 --+#endif --+ --+/* The `Q' extension is not yet supported. */ --+#define UNITS_PER_FP_REG (TARGET_DOUBLE_FLOAT ? 8 : 4) --+ --+/* The largest type that can be passed in floating-point registers. */ --+#define UNITS_PER_FP_ARG \ --+ (riscv_abi == ABI_ILP32 || riscv_abi == ABI_LP64 ? 0 : \ --+ riscv_abi == ABI_ILP32F || riscv_abi == ABI_LP64F ? 4 : 8) \ --+ --+/* Set the sizes of the core types. */ --+#define SHORT_TYPE_SIZE 16 --+#define INT_TYPE_SIZE 32 --+#define LONG_LONG_TYPE_SIZE 64 --+#define POINTER_SIZE (riscv_abi >= ABI_LP64 ? 64 : 32) --+#define LONG_TYPE_SIZE POINTER_SIZE --+ --+#define FLOAT_TYPE_SIZE 32 --+#define DOUBLE_TYPE_SIZE 64 --+#define LONG_DOUBLE_TYPE_SIZE 128 --+ --+/* Allocation boundary (in *bits*) for storing arguments in argument list. */ --+#define PARM_BOUNDARY BITS_PER_WORD --+ --+/* Allocation boundary (in *bits*) for the code of a function. */ --+#define FUNCTION_BOUNDARY (TARGET_RVC ? 16 : 32) --+ --+/* There is no point aligning anything to a rounder boundary than this. */ --+#define BIGGEST_ALIGNMENT 128 --+ --+/* The user-level ISA permits misaligned accesses, but they may execute --+ extremely slowly and non-atomically. Some privileged architectures --+ do not permit them at all. It is best to enforce strict alignment. */ --+#define STRICT_ALIGNMENT 1 --+ --+/* Define this if you wish to imitate the way many other C compilers --+ handle alignment of bitfields and the structures that contain --+ them. --+ --+ The behavior is that the type written for a bit-field (`int', --+ `short', or other integer type) imposes an alignment for the --+ entire structure, as if the structure really did contain an --+ ordinary field of that type. In addition, the bit-field is placed --+ within the structure so that it would fit within such a field, --+ not crossing a boundary for it. --+ --+ Thus, on most machines, a bit-field whose type is written as `int' --+ would not cross a four-byte boundary, and would force four-byte --+ alignment for the whole structure. (The alignment used may not --+ be four bytes; it is controlled by the other alignment --+ parameters.) --+ --+ If the macro is defined, its definition should be a C expression; --+ a nonzero value for the expression enables this behavior. */ --+ --+#define PCC_BITFIELD_TYPE_MATTERS 1 --+ --+/* If defined, a C expression to compute the alignment given to a --+ constant that is being placed in memory. CONSTANT is the constant --+ and ALIGN is the alignment that the object would ordinarily have. --+ The value of this macro is used instead of that alignment to align --+ the object. --+ --+ If this macro is not defined, then ALIGN is used. --+ --+ The typical use of this macro is to increase alignment for string --+ constants to be word aligned so that `strcpy' calls that copy --+ constants can be done inline. */ --+ --+#define CONSTANT_ALIGNMENT(EXP, ALIGN) \ --+ ((TREE_CODE (EXP) == STRING_CST || TREE_CODE (EXP) == CONSTRUCTOR) \ --+ && (ALIGN) < BITS_PER_WORD ? BITS_PER_WORD : (ALIGN)) --+ --+/* If defined, a C expression to compute the alignment for a static --+ variable. TYPE is the data type, and ALIGN is the alignment that --+ the object would ordinarily have. The value of this macro is used --+ instead of that alignment to align the object. --+ --+ If this macro is not defined, then ALIGN is used. --+ --+ One use of this macro is to increase alignment of medium-size --+ data to make it all fit in fewer cache lines. Another is to --+ cause character arrays to be word-aligned so that `strcpy' calls --+ that copy constants to character arrays can be done inline. */ --+ --+#define DATA_ALIGNMENT(TYPE, ALIGN) \ --+ ((((ALIGN) < BITS_PER_WORD) \ --+ && (TREE_CODE (TYPE) == ARRAY_TYPE \ --+ || TREE_CODE (TYPE) == UNION_TYPE \ --+ || TREE_CODE (TYPE) == RECORD_TYPE)) ? BITS_PER_WORD : (ALIGN)) --+ --+/* We need this for the same reason as DATA_ALIGNMENT, namely to cause --+ character arrays to be word-aligned so that `strcpy' calls that copy --+ constants to character arrays can be done inline, and 'strcmp' can be --+ optimised to use word loads. */ --+#define LOCAL_ALIGNMENT(TYPE, ALIGN) \ --+ DATA_ALIGNMENT (TYPE, ALIGN) --+ --+/* Define if operations between registers always perform the operation --+ on the full register even if a narrower mode is specified. */ --+#define WORD_REGISTER_OPERATIONS 1 --+ --+/* When in 64-bit mode, move insns will sign extend SImode and CCmode --+ moves. All other references are zero extended. */ --+#define LOAD_EXTEND_OP(MODE) \ --+ (TARGET_64BIT && (MODE) == SImode ? SIGN_EXTEND : ZERO_EXTEND) --+ --+/* Define this macro if it is advisable to hold scalars in registers --+ in a wider mode than that declared by the program. In such cases, --+ the value is constrained to be within the bounds of the declared --+ type, but kept valid in the wider mode. The signedness of the --+ extension may differ from that of the type. */ --+ --+#define PROMOTE_MODE(MODE, UNSIGNEDP, TYPE) \ --+ if (GET_MODE_CLASS (MODE) == MODE_INT \ --+ && GET_MODE_SIZE (MODE) < UNITS_PER_WORD) \ --+ { \ --+ if ((MODE) == SImode) \ --+ (UNSIGNEDP) = 0; \ --+ (MODE) = word_mode; \ --+ } --+ --+/* Pmode is always the same as ptr_mode, but not always the same as word_mode. --+ Extensions of pointers to word_mode must be signed. */ --+#define POINTERS_EXTEND_UNSIGNED false --+ --+/* When floating-point registers are wider than integer ones, moves between --+ them must go through memory. */ --+#define SECONDARY_MEMORY_NEEDED(CLASS1,CLASS2,MODE) \ --+ (GET_MODE_SIZE (MODE) > UNITS_PER_WORD \ --+ && ((CLASS1) == FP_REGS) != ((CLASS2) == FP_REGS)) --+ --+/* Define if loading short immediate values into registers sign extends. */ --+#define SHORT_IMMEDIATES_SIGN_EXTEND 1 --+ --+/* Standard register usage. */ --+ --+/* Number of hardware registers. We have: --+ --+ - 32 integer registers --+ - 32 floating point registers --+ - 2 fake registers: --+ - ARG_POINTER_REGNUM --+ - FRAME_POINTER_REGNUM */ --+ --+#define FIRST_PSEUDO_REGISTER 66 --+ --+/* x0, sp, gp, and tp are fixed. */ --+ --+#define FIXED_REGISTERS \ --+{ /* General registers. */ \ --+ 1, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, \ --+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, \ --+ /* Floating-point registers. */ \ --+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, \ --+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, \ --+ /* Others. */ \ --+ 1, 1 \ --+} --+ --+/* a0-a7, t0-a6, fa0-fa7, and ft0-ft11 are volatile across calls. --+ The call RTLs themselves clobber ra. */ --+ --+#define CALL_USED_REGISTERS \ --+{ /* General registers. */ \ --+ 1, 0, 1, 1, 1, 1, 1, 1, 0, 0, 1, 1, 1, 1, 1, 1, \ --+ 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, \ --+ /* Floating-point registers. */ \ --+ 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 1, 1, 1, 1, 1, 1, \ --+ 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, \ --+ /* Others. */ \ --+ 1, 1 \ --+} --+ --+/* Internal macros to classify an ISA register's type. */ --+ --+#define GP_REG_FIRST 0 --+#define GP_REG_LAST 31 --+#define GP_REG_NUM (GP_REG_LAST - GP_REG_FIRST + 1) --+ --+#define FP_REG_FIRST 32 --+#define FP_REG_LAST 63 --+#define FP_REG_NUM (FP_REG_LAST - FP_REG_FIRST + 1) --+ --+/* The DWARF 2 CFA column which tracks the return address from a --+ signal handler context. This means that to maintain backwards --+ compatibility, no hard register can be assigned this column if it --+ would need to be handled by the DWARF unwinder. */ --+#define DWARF_ALT_FRAME_RETURN_COLUMN 64 --+ --+#define GP_REG_P(REGNO) \ --+ ((unsigned int) ((int) (REGNO) - GP_REG_FIRST) < GP_REG_NUM) --+#define FP_REG_P(REGNO) \ --+ ((unsigned int) ((int) (REGNO) - FP_REG_FIRST) < FP_REG_NUM) --+ --+#define FP_REG_RTX_P(X) (REG_P (X) && FP_REG_P (REGNO (X))) --+ --+#define HARD_REGNO_NREGS(REGNO, MODE) riscv_hard_regno_nregs (REGNO, MODE) --+ --+#define HARD_REGNO_MODE_OK(REGNO, MODE) \ --+ riscv_hard_regno_mode_ok_p (REGNO, MODE) --+ --+/* Don't allow floating-point modes to be tied, since type punning of --+ single-precision and double-precision is implementation defined. */ --+#define MODES_TIEABLE_P(MODE1, MODE2) \ --+ ((MODE1) == (MODE2) \ --+ || !(GET_MODE_CLASS (MODE1) == MODE_FLOAT \ --+ && GET_MODE_CLASS (MODE2) == MODE_FLOAT)) --+ --+/* Use s0 as the frame pointer if it is so requested. */ --+#define HARD_FRAME_POINTER_REGNUM 8 --+#define STACK_POINTER_REGNUM 2 --+#define THREAD_POINTER_REGNUM 4 --+ --+/* These two registers don't really exist: they get eliminated to either --+ the stack or hard frame pointer. */ --+#define ARG_POINTER_REGNUM 64 --+#define FRAME_POINTER_REGNUM 65 --+ --+/* Register in which static-chain is passed to a function. */ --+#define STATIC_CHAIN_REGNUM (GP_TEMP_FIRST + 2) --+ --+/* Registers used as temporaries in prologue/epilogue code. --+ --+ The prologue registers mustn't conflict with any --+ incoming arguments, the static chain pointer, or the frame pointer. --+ The epilogue temporary mustn't conflict with the return registers, --+ the frame pointer, the EH stack adjustment, or the EH data registers. */ --+ --+#define RISCV_PROLOGUE_TEMP_REGNUM (GP_TEMP_FIRST + 1) --+#define RISCV_PROLOGUE_TEMP(MODE) gen_rtx_REG (MODE, RISCV_PROLOGUE_TEMP_REGNUM) --+ --+#define MCOUNT_NAME "_mcount" --+ --+#define NO_PROFILE_COUNTERS 1 --+ --+/* Emit rtl for profiling. Output assembler code to FILE --+ to call "_mcount" for profiling a function entry. */ --+#define PROFILE_HOOK(LABEL) \ --+ { \ --+ rtx fun, ra; \ --+ ra = get_hard_reg_initial_val (Pmode, RETURN_ADDR_REGNUM); \ --+ fun = gen_rtx_SYMBOL_REF (Pmode, MCOUNT_NAME); \ --+ emit_library_call (fun, LCT_NORMAL, VOIDmode, 1, ra, Pmode); \ --+ } --+ --+/* All the work done in PROFILE_HOOK, but still required. */ --+#define FUNCTION_PROFILER(STREAM, LABELNO) do { } while (0) --+ --+/* Define this macro if it is as good or better to call a constant --+ function address than to call an address kept in a register. */ --+#define NO_FUNCTION_CSE 1 --+ --+/* Define the classes of registers for register constraints in the --+ machine description. Also define ranges of constants. --+ --+ One of the classes must always be named ALL_REGS and include all hard regs. --+ If there is more than one class, another class must be named NO_REGS --+ and contain no registers. --+ --+ The name GENERAL_REGS must be the name of a class (or an alias for --+ another name such as ALL_REGS). This is the class of registers --+ that is allowed by "g" or "r" in a register constraint. --+ Also, registers outside this class are allocated only when --+ instructions express preferences for them. --+ --+ The classes must be numbered in nondecreasing order; that is, --+ a larger-numbered class must never be contained completely --+ in a smaller-numbered class. --+ --+ For any two classes, it is very desirable that there be another --+ class that represents their union. */ --+ --+enum reg_class --+{ --+ NO_REGS, /* no registers in set */ --+ SIBCALL_REGS, /* registers used by indirect sibcalls */ --+ JALR_REGS, /* registers used by indirect calls */ --+ GR_REGS, /* integer registers */ --+ FP_REGS, /* floating-point registers */ --+ FRAME_REGS, /* arg pointer and frame pointer */ --+ ALL_REGS, /* all registers */ --+ LIM_REG_CLASSES /* max value + 1 */ --+}; --+ --+#define N_REG_CLASSES (int) LIM_REG_CLASSES --+ --+#define GENERAL_REGS GR_REGS --+ --+/* An initializer containing the names of the register classes as C --+ string constants. These names are used in writing some of the --+ debugging dumps. */ --+ --+#define REG_CLASS_NAMES \ --+{ \ --+ "NO_REGS", \ --+ "SIBCALL_REGS", \ --+ "JALR_REGS", \ --+ "GR_REGS", \ --+ "FP_REGS", \ --+ "FRAME_REGS", \ --+ "ALL_REGS" \ --+} --+ --+/* An initializer containing the contents of the register classes, --+ as integers which are bit masks. The Nth integer specifies the --+ contents of class N. The way the integer MASK is interpreted is --+ that register R is in the class if `MASK & (1 << R)' is 1. --+ --+ When the machine has more than 32 registers, an integer does not --+ suffice. Then the integers are replaced by sub-initializers, --+ braced groupings containing several integers. Each --+ sub-initializer must be suitable as an initializer for the type --+ `HARD_REG_SET' which is defined in `hard-reg-set.h'. */ --+ --+#define REG_CLASS_CONTENTS \ --+{ \ --+ { 0x00000000, 0x00000000, 0x00000000 }, /* NO_REGS */ \ --+ { 0xf00000c0, 0x00000000, 0x00000000 }, /* SIBCALL_REGS */ \ --+ { 0xffffffc0, 0x00000000, 0x00000000 }, /* JALR_REGS */ \ --+ { 0xffffffff, 0x00000000, 0x00000000 }, /* GR_REGS */ \ --+ { 0x00000000, 0xffffffff, 0x00000000 }, /* FP_REGS */ \ --+ { 0x00000000, 0x00000000, 0x00000003 }, /* FRAME_REGS */ \ --+ { 0xffffffff, 0xffffffff, 0x00000003 } /* ALL_REGS */ \ --+} --+ --+/* A C expression whose value is a register class containing hard --+ register REGNO. In general there is more that one such class; --+ choose a class which is "minimal", meaning that no smaller class --+ also contains the register. */ --+ --+#define REGNO_REG_CLASS(REGNO) riscv_regno_to_class[ (REGNO) ] --+ --+/* A macro whose definition is the name of the class to which a --+ valid base register must belong. A base register is one used in --+ an address which is the register value plus a displacement. */ --+ --+#define BASE_REG_CLASS GR_REGS --+ --+/* A macro whose definition is the name of the class to which a --+ valid index register must belong. An index register is one used --+ in an address where its value is either multiplied by a scale --+ factor or added to another register (as well as added to a --+ displacement). */ --+ --+#define INDEX_REG_CLASS NO_REGS --+ --+/* We generally want to put call-clobbered registers ahead of --+ call-saved ones. (IRA expects this.) */ --+ --+#define REG_ALLOC_ORDER \ --+{ \ --+ /* Call-clobbered GPRs. */ \ --+ 15, 14, 13, 12, 11, 10, 16, 17, 6, 28, 29, 30, 31, 5, 7, 1, \ --+ /* Call-saved GPRs. */ \ --+ 8, 9, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, \ --+ /* GPRs that can never be exposed to the register allocator. */ \ --+ 0, 2, 3, 4, \ --+ /* Call-clobbered FPRs. */ \ --+ 47, 46, 45, 44, 43, 42, 32, 33, 34, 35, 36, 37, 38, 39, 48, 49, \ --+ 60, 61, 62, 63, \ --+ /* Call-saved FPRs. */ \ --+ 40, 41, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, \ --+ /* None of the remaining classes have defined call-saved \ --+ registers. */ \ --+ 64, 65 \ --+} --+ --+/* True if VALUE is a signed 12-bit number. */ --+ --+#define SMALL_OPERAND(VALUE) \ --+ ((unsigned HOST_WIDE_INT) (VALUE) + IMM_REACH/2 < IMM_REACH) --+ --+/* True if VALUE can be loaded into a register using LUI. */ --+ --+#define LUI_OPERAND(VALUE) \ --+ (((VALUE) | ((1UL<<31) - IMM_REACH)) == ((1UL<<31) - IMM_REACH) \ --+ || ((VALUE) | ((1UL<<31) - IMM_REACH)) + IMM_REACH == 0) --+ --+#define CANNOT_CHANGE_MODE_CLASS(FROM, TO, CLASS) \ --+ reg_classes_intersect_p (FP_REGS, CLASS) --+ --+/* Stack layout; function entry, exit and calling. */ --+ --+#define STACK_GROWS_DOWNWARD 1 --+ --+#define FRAME_GROWS_DOWNWARD 1 --+ --+#define STARTING_FRAME_OFFSET 0 --+ --+#define RETURN_ADDR_RTX riscv_return_addr --+ --+#define ELIMINABLE_REGS \ --+{{ ARG_POINTER_REGNUM, STACK_POINTER_REGNUM}, \ --+ { ARG_POINTER_REGNUM, HARD_FRAME_POINTER_REGNUM}, \ --+ { FRAME_POINTER_REGNUM, STACK_POINTER_REGNUM}, \ --+ { FRAME_POINTER_REGNUM, HARD_FRAME_POINTER_REGNUM}} \ --+ --+#define INITIAL_ELIMINATION_OFFSET(FROM, TO, OFFSET) \ --+ (OFFSET) = riscv_initial_elimination_offset (FROM, TO) --+ --+/* Allocate stack space for arguments at the beginning of each function. */ --+#define ACCUMULATE_OUTGOING_ARGS 1 --+ --+/* The argument pointer always points to the first argument. */ --+#define FIRST_PARM_OFFSET(FNDECL) 0 --+ --+#define REG_PARM_STACK_SPACE(FNDECL) 0 --+ --+/* Define this if it is the responsibility of the caller to --+ allocate the area reserved for arguments passed in registers. --+ If `ACCUMULATE_OUTGOING_ARGS' is also defined, the only effect --+ of this macro is to determine whether the space is included in --+ `crtl->outgoing_args_size'. */ --+#define OUTGOING_REG_PARM_STACK_SPACE(FNTYPE) 1 --+ --+#define STACK_BOUNDARY 128 --+ --+/* Symbolic macros for the registers used to return integer and floating --+ point values. */ --+ --+#define GP_RETURN GP_ARG_FIRST --+#define FP_RETURN (UNITS_PER_FP_ARG == 0 ? GP_RETURN : FP_ARG_FIRST) --+ --+#define MAX_ARGS_IN_REGISTERS 8 --+ --+/* Symbolic macros for the first/last argument registers. */ --+ --+#define GP_ARG_FIRST (GP_REG_FIRST + 10) --+#define GP_ARG_LAST (GP_ARG_FIRST + MAX_ARGS_IN_REGISTERS - 1) --+#define GP_TEMP_FIRST (GP_REG_FIRST + 5) --+#define FP_ARG_FIRST (FP_REG_FIRST + 10) --+#define FP_ARG_LAST (FP_ARG_FIRST + MAX_ARGS_IN_REGISTERS - 1) --+ --+#define CALLEE_SAVED_REG_NUMBER(REGNO) \ --+ ((REGNO) >= 8 && (REGNO) <= 9 ? (REGNO) - 8 : \ --+ (REGNO) >= 18 && (REGNO) <= 27 ? (REGNO) - 16 : -1) --+ --+#define LIBCALL_VALUE(MODE) \ --+ riscv_function_value (NULL_TREE, NULL_TREE, MODE) --+ --+#define FUNCTION_VALUE(VALTYPE, FUNC) \ --+ riscv_function_value (VALTYPE, FUNC, VOIDmode) --+ --+#define FUNCTION_VALUE_REGNO_P(N) ((N) == GP_RETURN || (N) == FP_RETURN) --+ --+/* 1 if N is a possible register number for function argument passing. --+ We have no FP argument registers when soft-float. When FP registers --+ are 32 bits, we can't directly reference the odd numbered ones. */ --+ --+/* Accept arguments in a0-a7, and in fa0-fa7 if permitted by the ABI. */ --+#define FUNCTION_ARG_REGNO_P(N) \ --+ (IN_RANGE ((N), GP_ARG_FIRST, GP_ARG_LAST) \ --+ || (UNITS_PER_FP_ARG && IN_RANGE ((N), FP_ARG_FIRST, FP_ARG_LAST))) --+ --+typedef struct { --+ /* Number of integer registers used so far, up to MAX_ARGS_IN_REGISTERS. */ --+ unsigned int num_gprs; --+ --+ /* Number of floating-point registers used so far, likewise. */ --+ unsigned int num_fprs; --+} CUMULATIVE_ARGS; --+ --+/* Initialize a variable CUM of type CUMULATIVE_ARGS --+ for a call to a function whose data type is FNTYPE. --+ For a library call, FNTYPE is 0. */ --+ --+#define INIT_CUMULATIVE_ARGS(CUM, FNTYPE, LIBNAME, INDIRECT, N_NAMED_ARGS) \ --+ memset (&(CUM), 0, sizeof (CUM)) --+ --+#define EPILOGUE_USES(REGNO) ((REGNO) == RETURN_ADDR_REGNUM) --+ --+/* ABI requires 16-byte alignment, even on RV32. */ --+#define RISCV_STACK_ALIGN(LOC) (((LOC) + 15) & -16) --+ --+/* EXIT_IGNORE_STACK should be nonzero if, when returning from a function, --+ the stack pointer does not matter. The value is tested only in --+ functions that have frame pointers. --+ No definition is equivalent to always zero. */ --+ --+#define EXIT_IGNORE_STACK 1 --+ --+ --+/* Trampolines are a block of code followed by two pointers. */ --+ --+#define TRAMPOLINE_CODE_SIZE 16 --+#define TRAMPOLINE_SIZE \ --+ ((Pmode == SImode) \ --+ ? TRAMPOLINE_CODE_SIZE \ --+ : (TRAMPOLINE_CODE_SIZE + POINTER_SIZE * 2)) --+#define TRAMPOLINE_ALIGNMENT POINTER_SIZE --+ --+/* Addressing modes, and classification of registers for them. */ --+ --+#define REGNO_OK_FOR_INDEX_P(REGNO) 0 --+#define REGNO_MODE_OK_FOR_BASE_P(REGNO, MODE) \ --+ riscv_regno_mode_ok_for_base_p (REGNO, MODE, 1) --+ --+/* The macros REG_OK_FOR..._P assume that the arg is a REG rtx --+ and check its validity for a certain class. --+ We have two alternate definitions for each of them. --+ The usual definition accepts all pseudo regs; the other rejects them all. --+ The symbol REG_OK_STRICT causes the latter definition to be used. --+ --+ Most source files want to accept pseudo regs in the hope that --+ they will get allocated to the class that the insn wants them to be in. --+ Some source files that are used after register allocation --+ need to be strict. */ --+ --+#ifndef REG_OK_STRICT --+#define REG_MODE_OK_FOR_BASE_P(X, MODE) \ --+ riscv_regno_mode_ok_for_base_p (REGNO (X), MODE, 0) --+#else --+#define REG_MODE_OK_FOR_BASE_P(X, MODE) \ --+ riscv_regno_mode_ok_for_base_p (REGNO (X), MODE, 1) --+#endif --+ --+#define REG_OK_FOR_INDEX_P(X) 0 --+ --+/* Maximum number of registers that can appear in a valid memory address. */ --+ --+#define MAX_REGS_PER_ADDRESS 1 --+ --+#define CONSTANT_ADDRESS_P(X) \ --+ (CONSTANT_P (X) && memory_address_p (SImode, X)) --+ --+/* This handles the magic '..CURRENT_FUNCTION' symbol, which means --+ 'the start of the function that this code is output in'. */ --+ --+#define ASM_OUTPUT_LABELREF(FILE,NAME) \ --+ if (strcmp (NAME, "..CURRENT_FUNCTION") == 0) \ --+ asm_fprintf ((FILE), "%U%s", \ --+ XSTR (XEXP (DECL_RTL (current_function_decl), 0), 0)); \ --+ else \ --+ asm_fprintf ((FILE), "%U%s", (NAME)) --+ --+#define JUMP_TABLES_IN_TEXT_SECTION 0 --+#define CASE_VECTOR_MODE SImode --+#define CASE_VECTOR_PC_RELATIVE (riscv_cmodel != CM_MEDLOW) --+ --+/* The load-address macro is used for PC-relative addressing of symbols --+ that bind locally. Don't use it for symbols that should be addressed --+ via the GOT. Also, avoid it for CM_MEDLOW, where LUI addressing --+ currently results in more opportunities for linker relaxation. */ --+#define USE_LOAD_ADDRESS_MACRO(sym) \ --+ (!TARGET_EXPLICIT_RELOCS && \ --+ ((flag_pic \ --+ && ((SYMBOL_REF_P (sym) && SYMBOL_REF_LOCAL_P (sym)) \ --+ || ((GET_CODE (sym) == CONST) \ --+ && SYMBOL_REF_P (XEXP (XEXP (sym, 0),0)) \ --+ && SYMBOL_REF_LOCAL_P (XEXP (XEXP (sym, 0),0))))) \ --+ || riscv_cmodel == CM_MEDANY)) --+ --+/* Define this as 1 if `char' should by default be signed; else as 0. */ --+#define DEFAULT_SIGNED_CHAR 0 --+ --+#define MOVE_MAX UNITS_PER_WORD --+#define MAX_MOVE_MAX 8 --+ --+#define SLOW_BYTE_ACCESS 0 --+ --+#define SHIFT_COUNT_TRUNCATED 1 --+ --+#define TRULY_NOOP_TRUNCATION(OUTPREC, INPREC) 1 --+ --+/* Specify the machine mode that pointers have. --+ After generation of rtl, the compiler makes no further distinction --+ between pointers and any other objects of this machine mode. */ --+ --+#define Pmode word_mode --+ --+/* Give call MEMs SImode since it is the "most permissive" mode --+ for both 32-bit and 64-bit targets. */ --+ --+#define FUNCTION_MODE SImode --+ --+/* A C expression for the cost of a branch instruction. A value of 2 --+ seems to minimize code size. */ --+ --+#define BRANCH_COST(speed_p, predictable_p) \ --+ ((!(speed_p) || (predictable_p)) ? 2 : riscv_branch_cost) --+ --+#define LOGICAL_OP_NON_SHORT_CIRCUIT 0 --+ --+/* Control the assembler format that we output. */ --+ --+/* Output to assembler file text saying following lines --+ may contain character constants, extra white space, comments, etc. */ --+ --+#ifndef ASM_APP_ON --+#define ASM_APP_ON " #APP\n" --+#endif --+ --+/* Output to assembler file text saying following lines --+ no longer contain unusual constructs. */ --+ --+#ifndef ASM_APP_OFF --+#define ASM_APP_OFF " #NO_APP\n" --+#endif --+ --+#define REGISTER_NAMES \ --+{ "zero","ra", "sp", "gp", "tp", "t0", "t1", "t2", \ --+ "s0", "s1", "a0", "a1", "a2", "a3", "a4", "a5", \ --+ "a6", "a7", "s2", "s3", "s4", "s5", "s6", "s7", \ --+ "s8", "s9", "s10", "s11", "t3", "t4", "t5", "t6", \ --+ "ft0", "ft1", "ft2", "ft3", "ft4", "ft5", "ft6", "ft7", \ --+ "fs0", "fs1", "fa0", "fa1", "fa2", "fa3", "fa4", "fa5", \ --+ "fa6", "fa7", "fs2", "fs3", "fs4", "fs5", "fs6", "fs7", \ --+ "fs8", "fs9", "fs10","fs11","ft8", "ft9", "ft10","ft11", \ --+ "arg", "frame", } --+ --+#define ADDITIONAL_REGISTER_NAMES \ --+{ \ --+ { "x0", 0 + GP_REG_FIRST }, \ --+ { "x1", 1 + GP_REG_FIRST }, \ --+ { "x2", 2 + GP_REG_FIRST }, \ --+ { "x3", 3 + GP_REG_FIRST }, \ --+ { "x4", 4 + GP_REG_FIRST }, \ --+ { "x5", 5 + GP_REG_FIRST }, \ --+ { "x6", 6 + GP_REG_FIRST }, \ --+ { "x7", 7 + GP_REG_FIRST }, \ --+ { "x8", 8 + GP_REG_FIRST }, \ --+ { "x9", 9 + GP_REG_FIRST }, \ --+ { "x10", 10 + GP_REG_FIRST }, \ --+ { "x11", 11 + GP_REG_FIRST }, \ --+ { "x12", 12 + GP_REG_FIRST }, \ --+ { "x13", 13 + GP_REG_FIRST }, \ --+ { "x14", 14 + GP_REG_FIRST }, \ --+ { "x15", 15 + GP_REG_FIRST }, \ --+ { "x16", 16 + GP_REG_FIRST }, \ --+ { "x17", 17 + GP_REG_FIRST }, \ --+ { "x18", 18 + GP_REG_FIRST }, \ --+ { "x19", 19 + GP_REG_FIRST }, \ --+ { "x20", 20 + GP_REG_FIRST }, \ --+ { "x21", 21 + GP_REG_FIRST }, \ --+ { "x22", 22 + GP_REG_FIRST }, \ --+ { "x23", 23 + GP_REG_FIRST }, \ --+ { "x24", 24 + GP_REG_FIRST }, \ --+ { "x25", 25 + GP_REG_FIRST }, \ --+ { "x26", 26 + GP_REG_FIRST }, \ --+ { "x27", 27 + GP_REG_FIRST }, \ --+ { "x28", 28 + GP_REG_FIRST }, \ --+ { "x29", 29 + GP_REG_FIRST }, \ --+ { "x30", 30 + GP_REG_FIRST }, \ --+ { "x31", 31 + GP_REG_FIRST }, \ --+ { "f0", 0 + FP_REG_FIRST }, \ --+ { "f1", 1 + FP_REG_FIRST }, \ --+ { "f2", 2 + FP_REG_FIRST }, \ --+ { "f3", 3 + FP_REG_FIRST }, \ --+ { "f4", 4 + FP_REG_FIRST }, \ --+ { "f5", 5 + FP_REG_FIRST }, \ --+ { "f6", 6 + FP_REG_FIRST }, \ --+ { "f7", 7 + FP_REG_FIRST }, \ --+ { "f8", 8 + FP_REG_FIRST }, \ --+ { "f9", 9 + FP_REG_FIRST }, \ --+ { "f10", 10 + FP_REG_FIRST }, \ --+ { "f11", 11 + FP_REG_FIRST }, \ --+ { "f12", 12 + FP_REG_FIRST }, \ --+ { "f13", 13 + FP_REG_FIRST }, \ --+ { "f14", 14 + FP_REG_FIRST }, \ --+ { "f15", 15 + FP_REG_FIRST }, \ --+ { "f16", 16 + FP_REG_FIRST }, \ --+ { "f17", 17 + FP_REG_FIRST }, \ --+ { "f18", 18 + FP_REG_FIRST }, \ --+ { "f19", 19 + FP_REG_FIRST }, \ --+ { "f20", 20 + FP_REG_FIRST }, \ --+ { "f21", 21 + FP_REG_FIRST }, \ --+ { "f22", 22 + FP_REG_FIRST }, \ --+ { "f23", 23 + FP_REG_FIRST }, \ --+ { "f24", 24 + FP_REG_FIRST }, \ --+ { "f25", 25 + FP_REG_FIRST }, \ --+ { "f26", 26 + FP_REG_FIRST }, \ --+ { "f27", 27 + FP_REG_FIRST }, \ --+ { "f28", 28 + FP_REG_FIRST }, \ --+ { "f29", 29 + FP_REG_FIRST }, \ --+ { "f30", 30 + FP_REG_FIRST }, \ --+ { "f31", 31 + FP_REG_FIRST }, \ --+} --+ --+/* Globalizing directive for a label. */ --+#define GLOBAL_ASM_OP "\t.globl\t" --+ --+/* This is how to store into the string LABEL --+ the symbol_ref name of an internal numbered label where --+ PREFIX is the class of label and NUM is the number within the class. --+ This is suitable for output with `assemble_name'. */ --+ --+#undef ASM_GENERATE_INTERNAL_LABEL --+#define ASM_GENERATE_INTERNAL_LABEL(LABEL,PREFIX,NUM) \ --+ sprintf ((LABEL), "*%s%s%ld", (LOCAL_LABEL_PREFIX), (PREFIX), (long)(NUM)) --+ --+/* This is how to output an element of a case-vector that is absolute. */ --+ --+#define ASM_OUTPUT_ADDR_VEC_ELT(STREAM, VALUE) \ --+ fprintf (STREAM, "\t.word\t%sL%d\n", LOCAL_LABEL_PREFIX, VALUE) --+ --+/* This is how to output an element of a PIC case-vector. */ --+ --+#define ASM_OUTPUT_ADDR_DIFF_ELT(STREAM, BODY, VALUE, REL) \ --+ fprintf (STREAM, "\t.word\t%sL%d-%sL%d\n", \ --+ LOCAL_LABEL_PREFIX, VALUE, LOCAL_LABEL_PREFIX, REL) --+ --+/* This is how to output an assembler line --+ that says to advance the location counter --+ to a multiple of 2**LOG bytes. */ --+ --+#define ASM_OUTPUT_ALIGN(STREAM,LOG) \ --+ fprintf (STREAM, "\t.align\t%d\n", (LOG)) --+ --+/* Define the strings to put out for each section in the object file. */ --+#define TEXT_SECTION_ASM_OP "\t.text" /* instructions */ --+#define DATA_SECTION_ASM_OP "\t.data" /* large data */ --+#define READONLY_DATA_SECTION_ASM_OP "\t.section\t.rodata" --+#define BSS_SECTION_ASM_OP "\t.bss" --+#define SBSS_SECTION_ASM_OP "\t.section\t.sbss,\"aw\",@nobits" --+#define SDATA_SECTION_ASM_OP "\t.section\t.sdata,\"aw\",@progbits" --+ --+#define ASM_OUTPUT_REG_PUSH(STREAM,REGNO) \ --+do \ --+ { \ --+ fprintf (STREAM, "\taddi\t%s,%s,-8\n\t%s\t%s,0(%s)\n", \ --+ reg_names[STACK_POINTER_REGNUM], \ --+ reg_names[STACK_POINTER_REGNUM], \ --+ TARGET_64BIT ? "sd" : "sw", \ --+ reg_names[REGNO], \ --+ reg_names[STACK_POINTER_REGNUM]); \ --+ } \ --+while (0) --+ --+#define ASM_OUTPUT_REG_POP(STREAM,REGNO) \ --+do \ --+ { \ --+ fprintf (STREAM, "\t%s\t%s,0(%s)\n\taddi\t%s,%s,8\n", \ --+ TARGET_64BIT ? "ld" : "lw", \ --+ reg_names[REGNO], \ --+ reg_names[STACK_POINTER_REGNUM], \ --+ reg_names[STACK_POINTER_REGNUM], \ --+ reg_names[STACK_POINTER_REGNUM]); \ --+ } \ --+while (0) --+ --+#define ASM_COMMENT_START "#" --+ --+#undef SIZE_TYPE --+#define SIZE_TYPE (POINTER_SIZE == 64 ? "long unsigned int" : "unsigned int") --+ --+#undef PTRDIFF_TYPE --+#define PTRDIFF_TYPE (POINTER_SIZE == 64 ? "long int" : "int") --+ --+/* If a memory-to-memory move would take MOVE_RATIO or more simple --+ move-instruction pairs, we will do a movmem or libcall instead. */ --+ --+#define MOVE_RATIO(speed) (CLEAR_RATIO (speed) / 2) --+ --+/* For CLEAR_RATIO, when optimizing for size, give a better estimate --+ of the length of a memset call, but use the default otherwise. */ --+ --+#define CLEAR_RATIO(speed) ((speed) ? 16 : 6) --+ --+/* This is similar to CLEAR_RATIO, but for a non-zero constant, so when --+ optimizing for size adjust the ratio to account for the overhead of --+ loading the constant and replicating it across the word. */ --+ --+#define SET_RATIO(speed) (CLEAR_RATIO (speed) - ((speed) ? 0 : 2)) --+ --+#ifndef USED_FOR_TARGET --+extern const enum reg_class riscv_regno_to_class[]; --+extern bool riscv_hard_regno_mode_ok[][FIRST_PSEUDO_REGISTER]; --+#endif --+ --+#define ASM_PREFERRED_EH_DATA_FORMAT(CODE,GLOBAL) \ --+ (((GLOBAL) ? DW_EH_PE_indirect : 0) | DW_EH_PE_pcrel | DW_EH_PE_sdata4) --+ --+#define XLEN_SPEC \ --+ "%{march=rv32*:32}" \ --+ "%{march=rv64*:64}" \ --+ --+#define ABI_SPEC \ --+ "%{mabi=ilp32:ilp32}" \ --+ "%{mabi=ilp32f:ilp32f}" \ --+ "%{mabi=ilp32d:ilp32d}" \ --+ "%{mabi=lp64:lp64}" \ --+ "%{mabi=lp64f:lp64f}" \ --+ "%{mabi=lp64d:lp64d}" \ --+ --+#define STARTFILE_PREFIX_SPEC \ --+ "/lib" XLEN_SPEC "/" ABI_SPEC "/ " \ --+ "/usr/lib" XLEN_SPEC "/" ABI_SPEC "/ " \ --+ "/lib/ " \ --+ "/usr/lib/ " --+ --+/* ISA constants needed for code generation. */ --+#define OPCODE_LW 0x2003 --+#define OPCODE_LD 0x3003 --+#define OPCODE_AUIPC 0x17 --+#define OPCODE_JALR 0x67 --+#define OPCODE_LUI 0x37 --+#define OPCODE_ADDI 0x13 --+#define SHIFT_RD 7 --+#define SHIFT_RS1 15 --+#define SHIFT_IMM 20 --+#define IMM_BITS 12 --+ --+#define IMM_REACH (1LL << IMM_BITS) --+#define CONST_HIGH_PART(VALUE) (((VALUE) + (IMM_REACH/2)) & ~(IMM_REACH-1)) --+#define CONST_LOW_PART(VALUE) ((VALUE) - CONST_HIGH_PART (VALUE)) --+ --+#endif /* ! GCC_RISCV_H */ --diff --git original-gcc/gcc/config/riscv/riscv.md gcc-6.3.0/gcc/config/riscv/riscv.md --new file mode 100644 --index 00000000000..4cbb2431335 ----- /dev/null --+++ gcc-6.3.0/gcc/config/riscv/riscv.md --@@ -0,0 +1,2079 @@ --+;; Machine description for RISC-V for GNU compiler. --+;; Copyright (C) 2011-2017 Free Software Foundation, Inc. --+;; Contributed by Andrew Waterman (andrew@sifive.com). --+;; Based on MIPS target for GNU compiler. --+ --+;; This file is part of GCC. --+ --+;; GCC is free software; you can redistribute it and/or modify --+;; it under the terms of the GNU General Public License as published by --+;; the Free Software Foundation; either version 3, or (at your option) --+;; any later version. --+ --+;; GCC is distributed in the hope that it will be useful, --+;; but WITHOUT ANY WARRANTY; without even the implied warranty of --+;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the --+;; GNU General Public License for more details. --+ --+;; You should have received a copy of the GNU General Public License --+;; along with GCC; see the file COPYING3. If not see --+;; . --+ --+(define_c_enum "unspec" [ --+ ;; Override return address for exception handling. --+ UNSPEC_EH_RETURN --+ --+ ;; Symbolic accesses. The order of this list must match that of --+ ;; enum riscv_symbol_type in riscv-protos.h. --+ UNSPEC_ADDRESS_FIRST --+ UNSPEC_PCREL --+ UNSPEC_LOAD_GOT --+ UNSPEC_TLS --+ UNSPEC_TLS_LE --+ UNSPEC_TLS_IE --+ UNSPEC_TLS_GD --+ --+ ;; High part of PC-relative address. --+ UNSPEC_AUIPC --+ --+ ;; Floating-point unspecs. --+ UNSPEC_FLT_QUIET --+ UNSPEC_FLE_QUIET --+ UNSPEC_COPYSIGN --+ UNSPEC_LRINT --+ UNSPEC_LROUND --+ --+ ;; Stack tie --+ UNSPEC_TIE --+]) --+ --+(define_c_enum "unspecv" [ --+ ;; Register save and restore. --+ UNSPECV_GPR_SAVE --+ UNSPECV_GPR_RESTORE --+ --+ ;; Floating-point unspecs. --+ UNSPECV_FRFLAGS --+ UNSPECV_FSFLAGS --+ --+ ;; Blockage and synchronization. --+ UNSPECV_BLOCKAGE --+ UNSPECV_FENCE --+ UNSPECV_FENCE_I --+]) --+ --+(define_constants --+ [(RETURN_ADDR_REGNUM 1) --+ (T0_REGNUM 5) --+ (T1_REGNUM 6) --+ (S0_REGNUM 8) --+ (S1_REGNUM 9) --+ (S2_REGNUM 18) --+]) --+ --+(include "predicates.md") --+(include "constraints.md") --+ --+;; .................... --+;; --+;; Attributes --+;; --+;; .................... --+ --+(define_attr "got" "unset,xgot_high,load" --+ (const_string "unset")) --+ --+;; Classification of moves, extensions and truncations. Most values --+;; are as for "type" (see below) but there are also the following --+;; move-specific values: --+;; --+;; andi a single ANDI instruction --+;; shift_shift a shift left followed by a shift right --+;; --+;; This attribute is used to determine the instruction's length and --+;; scheduling type. For doubleword moves, the attribute always describes --+;; the split instructions; in some cases, it is more appropriate for the --+;; scheduling type to be "multi" instead. --+(define_attr "move_type" --+ "unknown,load,fpload,store,fpstore,mtc,mfc,move,fmove, --+ const,logical,arith,andi,shift_shift" --+ (const_string "unknown")) --+ --+;; Main data type used by the insn --+(define_attr "mode" "unknown,none,QI,HI,SI,DI,TI,SF,DF,TF" --+ (const_string "unknown")) --+ --+;; True if the main data type is twice the size of a word. --+(define_attr "dword_mode" "no,yes" --+ (cond [(and (eq_attr "mode" "DI,DF") --+ (eq (symbol_ref "TARGET_64BIT") (const_int 0))) --+ (const_string "yes") --+ --+ (and (eq_attr "mode" "TI,TF") --+ (ne (symbol_ref "TARGET_64BIT") (const_int 0))) --+ (const_string "yes")] --+ (const_string "no"))) --+ --+;; Classification of each insn. --+;; branch conditional branch --+;; jump unconditional jump --+;; call unconditional call --+;; load load instruction(s) --+;; fpload floating point load --+;; store store instruction(s) --+;; fpstore floating point store --+;; mtc transfer to coprocessor --+;; mfc transfer from coprocessor --+;; const load constant --+;; arith integer arithmetic instructions --+;; logical integer logical instructions --+;; shift integer shift instructions --+;; slt set less than instructions --+;; imul integer multiply --+;; idiv integer divide --+;; move integer register move (addi rd, rs1, 0) --+;; fmove floating point register move --+;; fadd floating point add/subtract --+;; fmul floating point multiply --+;; fmadd floating point multiply-add --+;; fdiv floating point divide --+;; fcmp floating point compare --+;; fcvt floating point convert --+;; fsqrt floating point square root --+;; multi multiword sequence (or user asm statements) --+;; nop no operation --+;; ghost an instruction that produces no real code --+(define_attr "type" --+ "unknown,branch,jump,call,load,fpload,store,fpstore, --+ mtc,mfc,const,arith,logical,shift,slt,imul,idiv,move,fmove,fadd,fmul, --+ fmadd,fdiv,fcmp,fcvt,fsqrt,multi,nop,ghost" --+ (cond [(eq_attr "got" "load") (const_string "load") --+ --+ ;; If a doubleword move uses these expensive instructions, --+ ;; it is usually better to schedule them in the same way --+ ;; as the singleword form, rather than as "multi". --+ (eq_attr "move_type" "load") (const_string "load") --+ (eq_attr "move_type" "fpload") (const_string "fpload") --+ (eq_attr "move_type" "store") (const_string "store") --+ (eq_attr "move_type" "fpstore") (const_string "fpstore") --+ (eq_attr "move_type" "mtc") (const_string "mtc") --+ (eq_attr "move_type" "mfc") (const_string "mfc") --+ --+ ;; These types of move are always single insns. --+ (eq_attr "move_type" "fmove") (const_string "fmove") --+ (eq_attr "move_type" "arith") (const_string "arith") --+ (eq_attr "move_type" "logical") (const_string "logical") --+ (eq_attr "move_type" "andi") (const_string "logical") --+ --+ ;; These types of move are always split. --+ (eq_attr "move_type" "shift_shift") --+ (const_string "multi") --+ --+ ;; These types of move are split for doubleword modes only. --+ (and (eq_attr "move_type" "move,const") --+ (eq_attr "dword_mode" "yes")) --+ (const_string "multi") --+ (eq_attr "move_type" "move") (const_string "move") --+ (eq_attr "move_type" "const") (const_string "const")] --+ (const_string "unknown"))) --+ --+;; Length of instruction in bytes. --+(define_attr "length" "" --+ (cond [ --+ ;; Branches further than +/- 4 KiB require two instructions. --+ (eq_attr "type" "branch") --+ (if_then_else (and (le (minus (match_dup 0) (pc)) (const_int 4088)) --+ (le (minus (pc) (match_dup 0)) (const_int 4092))) --+ (const_int 4) --+ (const_int 8)) --+ --+ ;; Conservatively assume calls take two instructions (AUIPC + JALR). --+ ;; The linker will opportunistically relax the sequence to JAL. --+ (eq_attr "type" "call") (const_int 8) --+ --+ ;; "Ghost" instructions occupy no space. --+ (eq_attr "type" "ghost") (const_int 0) --+ --+ (eq_attr "got" "load") (const_int 8) --+ --+ (eq_attr "type" "fcmp") (const_int 8) --+ --+ ;; SHIFT_SHIFTs are decomposed into two separate instructions. --+ (eq_attr "move_type" "shift_shift") --+ (const_int 8) --+ --+ ;; Check for doubleword moves that are decomposed into two --+ ;; instructions. --+ (and (eq_attr "move_type" "mtc,mfc,move") --+ (eq_attr "dword_mode" "yes")) --+ (const_int 8) --+ --+ ;; Doubleword CONST{,N} moves are split into two word --+ ;; CONST{,N} moves. --+ (and (eq_attr "move_type" "const") --+ (eq_attr "dword_mode" "yes")) --+ (symbol_ref "riscv_split_const_insns (operands[1]) * 4") --+ --+ ;; Otherwise, constants, loads and stores are handled by external --+ ;; routines. --+ (eq_attr "move_type" "load,fpload") --+ (symbol_ref "riscv_load_store_insns (operands[1], insn) * 4") --+ (eq_attr "move_type" "store,fpstore") --+ (symbol_ref "riscv_load_store_insns (operands[0], insn) * 4") --+ ] (const_int 4))) --+ --+;; Is copying of this instruction disallowed? --+(define_attr "cannot_copy" "no,yes" (const_string "no")) --+ --+;; Describe a user's asm statement. --+(define_asm_attributes --+ [(set_attr "type" "multi")]) --+ --+;; This mode iterator allows 32-bit and 64-bit GPR patterns to be generated --+;; from the same template. --+(define_mode_iterator GPR [SI (DI "TARGET_64BIT")]) --+ --+;; This mode iterator allows :P to be used for patterns that operate on --+;; pointer-sized quantities. Exactly one of the two alternatives will match. --+(define_mode_iterator P [(SI "Pmode == SImode") (DI "Pmode == DImode")]) --+ --+;; Likewise, but for XLEN-sized quantities. --+(define_mode_iterator X [(SI "!TARGET_64BIT") (DI "TARGET_64BIT")]) --+ --+;; Branches operate on XLEN-sized quantities, but for RV64 we accept --+;; QImode values so we can force zero-extension. --+(define_mode_iterator BR [(QI "TARGET_64BIT") SI (DI "TARGET_64BIT")]) --+ --+;; 32-bit moves for which we provide move patterns. --+(define_mode_iterator MOVE32 [SI]) --+ --+;; 64-bit modes for which we provide move patterns. --+(define_mode_iterator MOVE64 [DI DF]) --+ --+;; Iterator for sub-32-bit integer modes. --+(define_mode_iterator SHORT [QI HI]) --+ --+;; Iterator for HImode constant generation. --+(define_mode_iterator HISI [HI SI]) --+ --+;; Iterator for QImode extension patterns. --+(define_mode_iterator SUPERQI [HI SI (DI "TARGET_64BIT")]) --+ --+;; Iterator for hardware integer modes narrower than XLEN. --+(define_mode_iterator SUBX [QI HI (SI "TARGET_64BIT")]) --+ --+;; Iterator for hardware-supported integer modes. --+(define_mode_iterator ANYI [QI HI SI (DI "TARGET_64BIT")]) --+ --+;; Iterator for hardware-supported floating-point modes. --+(define_mode_iterator ANYF [(SF "TARGET_HARD_FLOAT") --+ (DF "TARGET_DOUBLE_FLOAT")]) --+ --+;; This attribute gives the length suffix for a sign- or zero-extension --+;; instruction. --+(define_mode_attr size [(QI "b") (HI "h")]) --+ --+;; Mode attributes for loads. --+(define_mode_attr load [(QI "lb") (HI "lh") (SI "lw") (DI "ld") (SF "flw") (DF "fld")]) --+ --+;; Instruction names for stores. --+(define_mode_attr store [(QI "sb") (HI "sh") (SI "sw") (DI "sd") (SF "fsw") (DF "fsd")]) --+ --+;; This attribute gives the best constraint to use for registers of --+;; a given mode. --+(define_mode_attr reg [(SI "d") (DI "d") (CC "d")]) --+ --+;; This attribute gives the format suffix for floating-point operations. --+(define_mode_attr fmt [(SF "s") (DF "d")]) --+ --+;; This attribute gives the integer suffix for floating-point conversions. --+(define_mode_attr ifmt [(SI "w") (DI "l")]) --+ --+;; This attribute gives the format suffix for atomic memory operations. --+(define_mode_attr amo [(SI "w") (DI "d")]) --+ --+;; This attribute gives the upper-case mode name for one unit of a --+;; floating-point mode. --+(define_mode_attr UNITMODE [(SF "SF") (DF "DF")]) --+ --+;; This attribute gives the integer mode that has half the size of --+;; the controlling mode. --+(define_mode_attr HALFMODE [(DF "SI") (DI "SI") (TF "DI")]) --+ --+;; Iterator and attributes for floating-point rounding instructions. --+(define_int_iterator RINT [UNSPEC_LRINT UNSPEC_LROUND]) --+(define_int_attr rint_pattern [(UNSPEC_LRINT "rint") (UNSPEC_LROUND "round")]) --+(define_int_attr rint_rm [(UNSPEC_LRINT "dyn") (UNSPEC_LROUND "rmm")]) --+ --+;; Iterator and attributes for quiet comparisons. --+(define_int_iterator QUIET_COMPARISON [UNSPEC_FLT_QUIET UNSPEC_FLE_QUIET]) --+(define_int_attr quiet_pattern [(UNSPEC_FLT_QUIET "lt") (UNSPEC_FLE_QUIET "le")]) --+ --+;; This code iterator allows signed and unsigned widening multiplications --+;; to use the same template. --+(define_code_iterator any_extend [sign_extend zero_extend]) --+ --+;; This code iterator allows the two right shift instructions to be --+;; generated from the same template. --+(define_code_iterator any_shiftrt [ashiftrt lshiftrt]) --+ --+;; This code iterator allows the three shift instructions to be generated --+;; from the same template. --+(define_code_iterator any_shift [ashift ashiftrt lshiftrt]) --+ --+;; This code iterator allows the three bitwise instructions to be generated --+;; from the same template. --+(define_code_iterator any_bitwise [and ior xor]) --+ --+;; This code iterator allows unsigned and signed division to be generated --+;; from the same template. --+(define_code_iterator any_div [div udiv mod umod]) --+ --+;; This code iterator allows unsigned and signed modulus to be generated --+;; from the same template. --+(define_code_iterator any_mod [mod umod]) --+ --+;; These code iterators allow the signed and unsigned scc operations to use --+;; the same template. --+(define_code_iterator any_gt [gt gtu]) --+(define_code_iterator any_ge [ge geu]) --+(define_code_iterator any_lt [lt ltu]) --+(define_code_iterator any_le [le leu]) --+ --+;; expands to an empty string when doing a signed operation and --+;; "u" when doing an unsigned operation. --+(define_code_attr u [(sign_extend "") (zero_extend "u") --+ (gt "") (gtu "u") --+ (ge "") (geu "u") --+ (lt "") (ltu "u") --+ (le "") (leu "u")]) --+ --+;; is like , but the signed form expands to "s" rather than "". --+(define_code_attr su [(sign_extend "s") (zero_extend "u")]) --+ --+;; expands to the name of the optab for a particular code. --+(define_code_attr optab [(ashift "ashl") --+ (ashiftrt "ashr") --+ (lshiftrt "lshr") --+ (div "div") --+ (mod "mod") --+ (udiv "udiv") --+ (umod "umod") --+ (ge "ge") --+ (le "le") --+ (gt "gt") --+ (lt "lt") --+ (ior "ior") --+ (xor "xor") --+ (and "and") --+ (plus "add") --+ (minus "sub")]) --+ --+;; expands to the name of the insn that implements a particular code. --+(define_code_attr insn [(ashift "sll") --+ (ashiftrt "sra") --+ (lshiftrt "srl") --+ (div "div") --+ (mod "rem") --+ (udiv "divu") --+ (umod "remu") --+ (ior "or") --+ (xor "xor") --+ (and "and") --+ (plus "add") --+ (minus "sub")]) --+ --+;; Ghost instructions produce no real code and introduce no hazards. --+;; They exist purely to express an effect on dataflow. --+(define_insn_reservation "ghost" 0 --+ (eq_attr "type" "ghost") --+ "nothing") --+ --+;; --+;; .................... --+;; --+;; ADDITION --+;; --+;; .................... --+;; --+ --+(define_insn "add3" --+ [(set (match_operand:ANYF 0 "register_operand" "=f") --+ (plus:ANYF (match_operand:ANYF 1 "register_operand" "f") --+ (match_operand:ANYF 2 "register_operand" "f")))] --+ "TARGET_HARD_FLOAT" --+ "fadd.\t%0,%1,%2" --+ [(set_attr "type" "fadd") --+ (set_attr "mode" "")]) --+ --+(define_insn "addsi3" --+ [(set (match_operand:SI 0 "register_operand" "=r,r") --+ (plus:SI (match_operand:SI 1 "register_operand" "r,r") --+ (match_operand:SI 2 "arith_operand" "r,I")))] --+ "" --+ { return TARGET_64BIT ? "addw\t%0,%1,%2" : "add\t%0,%1,%2"; } --+ [(set_attr "type" "arith") --+ (set_attr "mode" "SI")]) --+ --+(define_insn "adddi3" --+ [(set (match_operand:DI 0 "register_operand" "=r,r") --+ (plus:DI (match_operand:DI 1 "register_operand" "r,r") --+ (match_operand:DI 2 "arith_operand" "r,I")))] --+ "TARGET_64BIT" --+ "add\t%0,%1,%2" --+ [(set_attr "type" "arith") --+ (set_attr "mode" "DI")]) --+ --+(define_insn "*addsi3_extended" --+ [(set (match_operand:DI 0 "register_operand" "=r,r") --+ (sign_extend:DI --+ (plus:SI (match_operand:SI 1 "register_operand" "r,r") --+ (match_operand:SI 2 "arith_operand" "r,I"))))] --+ "TARGET_64BIT" --+ "addw\t%0,%1,%2" --+ [(set_attr "type" "arith") --+ (set_attr "mode" "SI")]) --+ --+(define_insn "*addsi3_extended2" --+ [(set (match_operand:DI 0 "register_operand" "=r,r") --+ (sign_extend:DI --+ (subreg:SI (plus:DI (match_operand:DI 1 "register_operand" "r,r") --+ (match_operand:DI 2 "arith_operand" "r,I")) --+ 0)))] --+ "TARGET_64BIT" --+ "addw\t%0,%1,%2" --+ [(set_attr "type" "arith") --+ (set_attr "mode" "SI")]) --+ --+;; --+;; .................... --+;; --+;; SUBTRACTION --+;; --+;; .................... --+;; --+ --+(define_insn "sub3" --+ [(set (match_operand:ANYF 0 "register_operand" "=f") --+ (minus:ANYF (match_operand:ANYF 1 "register_operand" "f") --+ (match_operand:ANYF 2 "register_operand" "f")))] --+ "TARGET_HARD_FLOAT" --+ "fsub.\t%0,%1,%2" --+ [(set_attr "type" "fadd") --+ (set_attr "mode" "")]) --+ --+(define_insn "subdi3" --+ [(set (match_operand:DI 0 "register_operand" "=r") --+ (minus:DI (match_operand:DI 1 "reg_or_0_operand" "rJ") --+ (match_operand:DI 2 "register_operand" "r")))] --+ "TARGET_64BIT" --+ "sub\t%0,%z1,%2" --+ [(set_attr "type" "arith") --+ (set_attr "mode" "DI")]) --+ --+(define_insn "subsi3" --+ [(set (match_operand:SI 0 "register_operand" "=r") --+ (minus:SI (match_operand:SI 1 "reg_or_0_operand" "rJ") --+ (match_operand:SI 2 "register_operand" "r")))] --+ "" --+ { return TARGET_64BIT ? "subw\t%0,%z1,%2" : "sub\t%0,%z1,%2"; } --+ [(set_attr "type" "arith") --+ (set_attr "mode" "SI")]) --+ --+(define_insn "*subsi3_extended" --+ [(set (match_operand:DI 0 "register_operand" "=r") --+ (sign_extend:DI --+ (minus:SI (match_operand:SI 1 "reg_or_0_operand" "rJ") --+ (match_operand:SI 2 "register_operand" "r"))))] --+ "TARGET_64BIT" --+ "subw\t%0,%z1,%2" --+ [(set_attr "type" "arith") --+ (set_attr "mode" "SI")]) --+ --+(define_insn "*subsi3_extended2" --+ [(set (match_operand:DI 0 "register_operand" "=r") --+ (sign_extend:DI --+ (subreg:SI (minus:DI (match_operand:DI 1 "reg_or_0_operand" "r") --+ (match_operand:DI 2 "register_operand" "r")) --+ 0)))] --+ "TARGET_64BIT" --+ "subw\t%0,%z1,%2" --+ [(set_attr "type" "arith") --+ (set_attr "mode" "SI")]) --+ --+;; --+;; .................... --+;; --+;; MULTIPLICATION --+;; --+;; .................... --+;; --+ --+(define_insn "mul3" --+ [(set (match_operand:ANYF 0 "register_operand" "=f") --+ (mult:ANYF (match_operand:ANYF 1 "register_operand" "f") --+ (match_operand:ANYF 2 "register_operand" "f")))] --+ "TARGET_HARD_FLOAT" --+ "fmul.\t%0,%1,%2" --+ [(set_attr "type" "fmul") --+ (set_attr "mode" "")]) --+ --+(define_insn "mulsi3" --+ [(set (match_operand:SI 0 "register_operand" "=r") --+ (mult:SI (match_operand:SI 1 "register_operand" "r") --+ (match_operand:SI 2 "register_operand" "r")))] --+ "TARGET_MUL" --+ { return TARGET_64BIT ? "mulw\t%0,%1,%2" : "mul\t%0,%1,%2"; } --+ [(set_attr "type" "imul") --+ (set_attr "mode" "SI")]) --+ --+(define_insn "muldi3" --+ [(set (match_operand:DI 0 "register_operand" "=r") --+ (mult:DI (match_operand:DI 1 "register_operand" "r") --+ (match_operand:DI 2 "register_operand" "r")))] --+ "TARGET_MUL && TARGET_64BIT" --+ "mul\t%0,%1,%2" --+ [(set_attr "type" "imul") --+ (set_attr "mode" "DI")]) --+ --+(define_insn "*mulsi3_extended" --+ [(set (match_operand:DI 0 "register_operand" "=r") --+ (sign_extend:DI --+ (mult:SI (match_operand:SI 1 "register_operand" "r") --+ (match_operand:SI 2 "register_operand" "r"))))] --+ "TARGET_MUL && TARGET_64BIT" --+ "mulw\t%0,%1,%2" --+ [(set_attr "type" "imul") --+ (set_attr "mode" "SI")]) --+ --+(define_insn "*mulsi3_extended2" --+ [(set (match_operand:DI 0 "register_operand" "=r") --+ (sign_extend:DI --+ (subreg:SI (mult:DI (match_operand:DI 1 "register_operand" "r") --+ (match_operand:DI 2 "register_operand" "r")) --+ 0)))] --+ "TARGET_MUL && TARGET_64BIT" --+ "mulw\t%0,%1,%2" --+ [(set_attr "type" "imul") --+ (set_attr "mode" "SI")]) --+ --+;; --+;; ........................ --+;; --+;; MULTIPLICATION HIGH-PART --+;; --+;; ........................ --+;; --+ --+ --+(define_expand "mulditi3" --+ [(set (match_operand:TI 0 "register_operand") --+ (mult:TI (any_extend:TI (match_operand:DI 1 "register_operand")) --+ (any_extend:TI (match_operand:DI 2 "register_operand"))))] --+ "TARGET_MUL && TARGET_64BIT" --+{ --+ rtx low = gen_reg_rtx (DImode); --+ emit_insn (gen_muldi3 (low, operands[1], operands[2])); --+ --+ rtx high = gen_reg_rtx (DImode); --+ emit_insn (gen_muldi3_highpart (high, operands[1], operands[2])); --+ --+ emit_move_insn (gen_lowpart (DImode, operands[0]), low); --+ emit_move_insn (gen_highpart (DImode, operands[0]), high); --+ DONE; --+}) --+ --+(define_insn "muldi3_highpart" --+ [(set (match_operand:DI 0 "register_operand" "=r") --+ (truncate:DI --+ (lshiftrt:TI --+ (mult:TI (any_extend:TI --+ (match_operand:DI 1 "register_operand" "r")) --+ (any_extend:TI --+ (match_operand:DI 2 "register_operand" "r"))) --+ (const_int 64))))] --+ "TARGET_MUL && TARGET_64BIT" --+ "mulh\t%0,%1,%2" --+ [(set_attr "type" "imul") --+ (set_attr "mode" "DI")]) --+ --+(define_expand "usmulditi3" --+ [(set (match_operand:TI 0 "register_operand") --+ (mult:TI (zero_extend:TI (match_operand:DI 1 "register_operand")) --+ (sign_extend:TI (match_operand:DI 2 "register_operand"))))] --+ "TARGET_MUL && TARGET_64BIT" --+{ --+ rtx low = gen_reg_rtx (DImode); --+ emit_insn (gen_muldi3 (low, operands[1], operands[2])); --+ --+ rtx high = gen_reg_rtx (DImode); --+ emit_insn (gen_usmuldi3_highpart (high, operands[1], operands[2])); --+ --+ emit_move_insn (gen_lowpart (DImode, operands[0]), low); --+ emit_move_insn (gen_highpart (DImode, operands[0]), high); --+ DONE; --+}) --+ --+(define_insn "usmuldi3_highpart" --+ [(set (match_operand:DI 0 "register_operand" "=r") --+ (truncate:DI --+ (lshiftrt:TI --+ (mult:TI (zero_extend:TI --+ (match_operand:DI 1 "register_operand" "r")) --+ (sign_extend:TI --+ (match_operand:DI 2 "register_operand" "r"))) --+ (const_int 64))))] --+ "TARGET_MUL && TARGET_64BIT" --+ "mulhsu\t%0,%2,%1" --+ [(set_attr "type" "imul") --+ (set_attr "mode" "DI")]) --+ --+(define_expand "mulsidi3" --+ [(set (match_operand:DI 0 "register_operand" "=r") --+ (mult:DI (any_extend:DI --+ (match_operand:SI 1 "register_operand" "r")) --+ (any_extend:DI --+ (match_operand:SI 2 "register_operand" "r"))))] --+ "TARGET_MUL && !TARGET_64BIT" --+{ --+ rtx temp = gen_reg_rtx (SImode); --+ emit_insn (gen_mulsi3 (temp, operands[1], operands[2])); --+ emit_insn (gen_mulsi3_highpart (riscv_subword (operands[0], true), --+ operands[1], operands[2])); --+ emit_insn (gen_movsi (riscv_subword (operands[0], false), temp)); --+ DONE; --+}) --+ --+(define_insn "mulsi3_highpart" --+ [(set (match_operand:SI 0 "register_operand" "=r") --+ (truncate:SI --+ (lshiftrt:DI --+ (mult:DI (any_extend:DI --+ (match_operand:SI 1 "register_operand" "r")) --+ (any_extend:DI --+ (match_operand:SI 2 "register_operand" "r"))) --+ (const_int 32))))] --+ "TARGET_MUL && !TARGET_64BIT" --+ "mulh\t%0,%1,%2" --+ [(set_attr "type" "imul") --+ (set_attr "mode" "SI")]) --+ --+ --+(define_expand "usmulsidi3" --+ [(set (match_operand:DI 0 "register_operand" "=r") --+ (mult:DI (zero_extend:DI --+ (match_operand:SI 1 "register_operand" "r")) --+ (sign_extend:DI --+ (match_operand:SI 2 "register_operand" "r"))))] --+ "TARGET_MUL && !TARGET_64BIT" --+{ --+ rtx temp = gen_reg_rtx (SImode); --+ emit_insn (gen_mulsi3 (temp, operands[1], operands[2])); --+ emit_insn (gen_usmulsi3_highpart (riscv_subword (operands[0], true), --+ operands[1], operands[2])); --+ emit_insn (gen_movsi (riscv_subword (operands[0], false), temp)); --+ DONE; --+}) --+ --+(define_insn "usmulsi3_highpart" --+ [(set (match_operand:SI 0 "register_operand" "=r") --+ (truncate:SI --+ (lshiftrt:DI --+ (mult:DI (zero_extend:DI --+ (match_operand:SI 1 "register_operand" "r")) --+ (sign_extend:DI --+ (match_operand:SI 2 "register_operand" "r"))) --+ (const_int 32))))] --+ "TARGET_MUL && !TARGET_64BIT" --+ "mulhsu\t%0,%2,%1" --+ [(set_attr "type" "imul") --+ (set_attr "mode" "SI")]) --+ --+;; --+;; .................... --+;; --+;; DIVISION and REMAINDER --+;; --+;; .................... --+;; --+ --+(define_insn "si3" --+ [(set (match_operand:SI 0 "register_operand" "=r") --+ (any_div:SI (match_operand:SI 1 "register_operand" "r") --+ (match_operand:SI 2 "register_operand" "r")))] --+ "TARGET_DIV" --+ { return TARGET_64BIT ? "w\t%0,%1,%2" : "\t%0,%1,%2"; } --+ [(set_attr "type" "idiv") --+ (set_attr "mode" "SI")]) --+ --+(define_insn "di3" --+ [(set (match_operand:DI 0 "register_operand" "=r") --+ (any_div:DI (match_operand:DI 1 "register_operand" "r") --+ (match_operand:DI 2 "register_operand" "r")))] --+ "TARGET_DIV && TARGET_64BIT" --+ "\t%0,%1,%2" --+ [(set_attr "type" "idiv") --+ (set_attr "mode" "DI")]) --+ --+(define_insn "*si3_extended" --+ [(set (match_operand:DI 0 "register_operand" "=r") --+ (sign_extend:DI --+ (any_div:SI (match_operand:SI 1 "register_operand" "r") --+ (match_operand:SI 2 "register_operand" "r"))))] --+ "TARGET_DIV && TARGET_64BIT" --+ "w\t%0,%1,%2" --+ [(set_attr "type" "idiv") --+ (set_attr "mode" "DI")]) --+ --+(define_insn "div3" --+ [(set (match_operand:ANYF 0 "register_operand" "=f") --+ (div:ANYF (match_operand:ANYF 1 "register_operand" "f") --+ (match_operand:ANYF 2 "register_operand" "f")))] --+ "TARGET_HARD_FLOAT && TARGET_FDIV" --+ "fdiv.\t%0,%1,%2" --+ [(set_attr "type" "fdiv") --+ (set_attr "mode" "")]) --+ --+;; --+;; .................... --+;; --+;; SQUARE ROOT --+;; --+;; .................... --+ --+(define_insn "sqrt2" --+ [(set (match_operand:ANYF 0 "register_operand" "=f") --+ (sqrt:ANYF (match_operand:ANYF 1 "register_operand" "f")))] --+ "TARGET_HARD_FLOAT && TARGET_FDIV" --+{ --+ return "fsqrt.\t%0,%1"; --+} --+ [(set_attr "type" "fsqrt") --+ (set_attr "mode" "")]) --+ --+;; Floating point multiply accumulate instructions. --+ --+;; a * b + c --+(define_insn "fma4" --+ [(set (match_operand:ANYF 0 "register_operand" "=f") --+ (fma:ANYF --+ (match_operand:ANYF 1 "register_operand" "f") --+ (match_operand:ANYF 2 "register_operand" "f") --+ (match_operand:ANYF 3 "register_operand" "f")))] --+ "TARGET_HARD_FLOAT" --+ "fmadd.\t%0,%1,%2,%3" --+ [(set_attr "type" "fmadd") --+ (set_attr "mode" "")]) --+ --+;; a * b - c --+(define_insn "fms4" --+ [(set (match_operand:ANYF 0 "register_operand" "=f") --+ (fma:ANYF --+ (match_operand:ANYF 1 "register_operand" "f") --+ (match_operand:ANYF 2 "register_operand" "f") --+ (neg:ANYF (match_operand:ANYF 3 "register_operand" "f"))))] --+ "TARGET_HARD_FLOAT" --+ "fmsub.\t%0,%1,%2,%3" --+ [(set_attr "type" "fmadd") --+ (set_attr "mode" "")]) --+ --+;; -a * b - c --+(define_insn "fnms4" --+ [(set (match_operand:ANYF 0 "register_operand" "=f") --+ (fma:ANYF --+ (neg:ANYF (match_operand:ANYF 1 "register_operand" "f")) --+ (match_operand:ANYF 2 "register_operand" "f") --+ (neg:ANYF (match_operand:ANYF 3 "register_operand" "f"))))] --+ "TARGET_HARD_FLOAT" --+ "fnmadd.\t%0,%1,%2,%3" --+ [(set_attr "type" "fmadd") --+ (set_attr "mode" "")]) --+ --+;; -a * b + c --+(define_insn "fnma4" --+ [(set (match_operand:ANYF 0 "register_operand" "=f") --+ (fma:ANYF --+ (neg:ANYF (match_operand:ANYF 1 "register_operand" "f")) --+ (match_operand:ANYF 2 "register_operand" "f") --+ (match_operand:ANYF 3 "register_operand" "f")))] --+ "TARGET_HARD_FLOAT" --+ "fnmsub.\t%0,%1,%2,%3" --+ [(set_attr "type" "fmadd") --+ (set_attr "mode" "")]) --+ --+;; -(-a * b - c), modulo signed zeros --+(define_insn "*fma4" --+ [(set (match_operand:ANYF 0 "register_operand" "=f") --+ (neg:ANYF --+ (fma:ANYF --+ (neg:ANYF (match_operand:ANYF 1 "register_operand" "f")) --+ (match_operand:ANYF 2 "register_operand" "f") --+ (neg:ANYF (match_operand:ANYF 3 "register_operand" "f")))))] --+ "TARGET_HARD_FLOAT && !HONOR_SIGNED_ZEROS (mode)" --+ "fmadd.\t%0,%1,%2,%3" --+ [(set_attr "type" "fmadd") --+ (set_attr "mode" "")]) --+ --+;; -(-a * b + c), modulo signed zeros --+(define_insn "*fms4" --+ [(set (match_operand:ANYF 0 "register_operand" "=f") --+ (neg:ANYF --+ (fma:ANYF --+ (neg:ANYF (match_operand:ANYF 1 "register_operand" "f")) --+ (match_operand:ANYF 2 "register_operand" "f") --+ (match_operand:ANYF 3 "register_operand" "f"))))] --+ "TARGET_HARD_FLOAT && !HONOR_SIGNED_ZEROS (mode)" --+ "fmsub.\t%0,%1,%2,%3" --+ [(set_attr "type" "fmadd") --+ (set_attr "mode" "")]) --+ --+;; -(a * b + c), modulo signed zeros --+(define_insn "*fnms4" --+ [(set (match_operand:ANYF 0 "register_operand" "=f") --+ (neg:ANYF --+ (fma:ANYF --+ (match_operand:ANYF 1 "register_operand" "f") --+ (match_operand:ANYF 2 "register_operand" "f") --+ (match_operand:ANYF 3 "register_operand" "f"))))] --+ "TARGET_HARD_FLOAT && !HONOR_SIGNED_ZEROS (mode)" --+ "fnmadd.\t%0,%1,%2,%3" --+ [(set_attr "type" "fmadd") --+ (set_attr "mode" "")]) --+ --+;; -(a * b - c), modulo signed zeros --+(define_insn "*fnma4" --+ [(set (match_operand:ANYF 0 "register_operand" "=f") --+ (neg:ANYF --+ (fma:ANYF --+ (match_operand:ANYF 1 "register_operand" "f") --+ (match_operand:ANYF 2 "register_operand" "f") --+ (neg:ANYF (match_operand:ANYF 3 "register_operand" "f")))))] --+ "TARGET_HARD_FLOAT && !HONOR_SIGNED_ZEROS (mode)" --+ "fnmsub.\t%0,%1,%2,%3" --+ [(set_attr "type" "fmadd") --+ (set_attr "mode" "")]) --+ --+;; --+;; .................... --+;; --+;; SIGN INJECTION --+;; --+;; .................... --+ --+(define_insn "abs2" --+ [(set (match_operand:ANYF 0 "register_operand" "=f") --+ (abs:ANYF (match_operand:ANYF 1 "register_operand" "f")))] --+ "TARGET_HARD_FLOAT" --+ "fabs.\t%0,%1" --+ [(set_attr "type" "fmove") --+ (set_attr "mode" "")]) --+ --+(define_insn "copysign3" --+ [(set (match_operand:ANYF 0 "register_operand" "=f") --+ (unspec:ANYF [(match_operand:ANYF 1 "register_operand" "f") --+ (match_operand:ANYF 2 "register_operand" "f")] --+ UNSPEC_COPYSIGN))] --+ "TARGET_HARD_FLOAT" --+ "fsgnj.\t%0,%1,%2" --+ [(set_attr "type" "fmove") --+ (set_attr "mode" "")]) --+ --+(define_insn "neg2" --+ [(set (match_operand:ANYF 0 "register_operand" "=f") --+ (neg:ANYF (match_operand:ANYF 1 "register_operand" "f")))] --+ "TARGET_HARD_FLOAT" --+ "fneg.\t%0,%1" --+ [(set_attr "type" "fmove") --+ (set_attr "mode" "")]) --+ --+;; --+;; .................... --+;; --+;; MIN/MAX --+;; --+;; .................... --+ --+(define_insn "smin3" --+ [(set (match_operand:ANYF 0 "register_operand" "=f") --+ (smin:ANYF (match_operand:ANYF 1 "register_operand" "f") --+ (match_operand:ANYF 2 "register_operand" "f")))] --+ "TARGET_HARD_FLOAT" --+ "fmin.\t%0,%1,%2" --+ [(set_attr "type" "fmove") --+ (set_attr "mode" "")]) --+ --+(define_insn "smax3" --+ [(set (match_operand:ANYF 0 "register_operand" "=f") --+ (smax:ANYF (match_operand:ANYF 1 "register_operand" "f") --+ (match_operand:ANYF 2 "register_operand" "f")))] --+ "TARGET_HARD_FLOAT" --+ "fmax.\t%0,%1,%2" --+ [(set_attr "type" "fmove") --+ (set_attr "mode" "")]) --+ --+;; --+;; .................... --+;; --+;; LOGICAL --+;; --+;; .................... --+;; --+ --+;; For RV64, we don't expose the SImode operations to the rtl expanders, --+;; but SImode versions exist for combine. --+ --+(define_insn "3" --+ [(set (match_operand:X 0 "register_operand" "=r,r") --+ (any_bitwise:X (match_operand:X 1 "register_operand" "%r,r") --+ (match_operand:X 2 "arith_operand" "r,I")))] --+ "" --+ "\t%0,%1,%2" --+ [(set_attr "type" "logical") --+ (set_attr "mode" "")]) --+ --+(define_insn "*si3_internal" --+ [(set (match_operand:SI 0 "register_operand" "=r,r") --+ (any_bitwise:SI (match_operand:SI 1 "register_operand" "%r,r") --+ (match_operand:SI 2 "arith_operand" "r,I")))] --+ "TARGET_64BIT" --+ "\t%0,%1,%2" --+ [(set_attr "type" "logical") --+ (set_attr "mode" "SI")]) --+ --+(define_insn "one_cmpl2" --+ [(set (match_operand:X 0 "register_operand" "=r") --+ (not:X (match_operand:X 1 "register_operand" "r")))] --+ "" --+ "not\t%0,%1" --+ [(set_attr "type" "logical") --+ (set_attr "mode" "")]) --+ --+(define_insn "*one_cmplsi2_internal" --+ [(set (match_operand:SI 0 "register_operand" "=r") --+ (not:SI (match_operand:SI 1 "register_operand" "r")))] --+ "TARGET_64BIT" --+ "not\t%0,%1" --+ [(set_attr "type" "logical") --+ (set_attr "mode" "SI")]) --+ --+;; --+;; .................... --+;; --+;; TRUNCATION --+;; --+;; .................... --+ --+(define_insn "truncdfsf2" --+ [(set (match_operand:SF 0 "register_operand" "=f") --+ (float_truncate:SF (match_operand:DF 1 "register_operand" "f")))] --+ "TARGET_DOUBLE_FLOAT" --+ "fcvt.s.d\t%0,%1" --+ [(set_attr "type" "fcvt") --+ (set_attr "mode" "SF")]) --+ --+;; --+;; .................... --+;; --+;; ZERO EXTENSION --+;; --+;; .................... --+ --+;; Extension insns. --+ --+(define_insn_and_split "zero_extendsidi2" --+ [(set (match_operand:DI 0 "register_operand" "=r,r") --+ (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "r,m")))] --+ "TARGET_64BIT" --+ "@ --+ # --+ lwu\t%0,%1" --+ "&& reload_completed && REG_P (operands[1])" --+ [(set (match_dup 0) --+ (ashift:DI (match_dup 1) (const_int 32))) --+ (set (match_dup 0) --+ (lshiftrt:DI (match_dup 0) (const_int 32)))] --+ { operands[1] = gen_lowpart (DImode, operands[1]); } --+ [(set_attr "move_type" "shift_shift,load") --+ (set_attr "mode" "DI")]) --+ --+(define_insn_and_split "zero_extendhi2" --+ [(set (match_operand:GPR 0 "register_operand" "=r,r") --+ (zero_extend:GPR (match_operand:HI 1 "nonimmediate_operand" "r,m")))] --+ "" --+ "@ --+ # --+ lhu\t%0,%1" --+ "&& reload_completed && REG_P (operands[1])" --+ [(set (match_dup 0) --+ (ashift:GPR (match_dup 1) (match_dup 2))) --+ (set (match_dup 0) --+ (lshiftrt:GPR (match_dup 0) (match_dup 2)))] --+ { --+ operands[1] = gen_lowpart (mode, operands[1]); --+ operands[2] = GEN_INT(GET_MODE_BITSIZE(mode) - 16); --+ } --+ [(set_attr "move_type" "shift_shift,load") --+ (set_attr "mode" "")]) --+ --+(define_insn "zero_extendqi2" --+ [(set (match_operand:SUPERQI 0 "register_operand" "=r,r") --+ (zero_extend:SUPERQI --+ (match_operand:QI 1 "nonimmediate_operand" "r,m")))] --+ "" --+ "@ --+ and\t%0,%1,0xff --+ lbu\t%0,%1" --+ [(set_attr "move_type" "andi,load") --+ (set_attr "mode" "")]) --+ --+;; --+;; .................... --+;; --+;; SIGN EXTENSION --+;; --+;; .................... --+ --+(define_insn "extendsidi2" --+ [(set (match_operand:DI 0 "register_operand" "=r,r") --+ (sign_extend:DI (match_operand:SI 1 "nonimmediate_operand" "r,m")))] --+ "TARGET_64BIT" --+ "@ --+ sext.w\t%0,%1 --+ lw\t%0,%1" --+ [(set_attr "move_type" "move,load") --+ (set_attr "mode" "DI")]) --+ --+(define_insn_and_split "extend2" --+ [(set (match_operand:SUPERQI 0 "register_operand" "=r,r") --+ (sign_extend:SUPERQI --+ (match_operand:SHORT 1 "nonimmediate_operand" "r,m")))] --+ "" --+ "@ --+ # --+ l\t%0,%1" --+ "&& reload_completed && REG_P (operands[1])" --+ [(set (match_dup 0) (ashift:SI (match_dup 1) (match_dup 2))) --+ (set (match_dup 0) (ashiftrt:SI (match_dup 0) (match_dup 2)))] --+{ --+ operands[0] = gen_lowpart (SImode, operands[0]); --+ operands[1] = gen_lowpart (SImode, operands[1]); --+ operands[2] = GEN_INT (GET_MODE_BITSIZE (SImode) --+ - GET_MODE_BITSIZE (mode)); --+} --+ [(set_attr "move_type" "shift_shift,load") --+ (set_attr "mode" "SI")]) --+ --+(define_insn "extendsfdf2" --+ [(set (match_operand:DF 0 "register_operand" "=f") --+ (float_extend:DF (match_operand:SF 1 "register_operand" "f")))] --+ "TARGET_DOUBLE_FLOAT" --+ "fcvt.d.s\t%0,%1" --+ [(set_attr "type" "fcvt") --+ (set_attr "mode" "DF")]) --+ --+;; --+;; .................... --+;; --+;; CONVERSIONS --+;; --+;; .................... --+ --+(define_insn "fix_trunc2" --+ [(set (match_operand:GPR 0 "register_operand" "=r") --+ (fix:GPR (match_operand:ANYF 1 "register_operand" "f")))] --+ "TARGET_HARD_FLOAT" --+ "fcvt.. %0,%1,rtz" --+ [(set_attr "type" "fcvt") --+ (set_attr "mode" "")]) --+ --+(define_insn "fixuns_trunc2" --+ [(set (match_operand:GPR 0 "register_operand" "=r") --+ (unsigned_fix:GPR (match_operand:ANYF 1 "register_operand" "f")))] --+ "TARGET_HARD_FLOAT" --+ "fcvt.u. %0,%1,rtz" --+ [(set_attr "type" "fcvt") --+ (set_attr "mode" "")]) --+ --+(define_insn "float2" --+ [(set (match_operand:ANYF 0 "register_operand" "=f") --+ (float:ANYF (match_operand:GPR 1 "reg_or_0_operand" "rJ")))] --+ "TARGET_HARD_FLOAT" --+ "fcvt..\t%0,%z1" --+ [(set_attr "type" "fcvt") --+ (set_attr "mode" "")]) --+ --+(define_insn "floatuns2" --+ [(set (match_operand:ANYF 0 "register_operand" "=f") --+ (unsigned_float:ANYF (match_operand:GPR 1 "reg_or_0_operand" "rJ")))] --+ "TARGET_HARD_FLOAT" --+ "fcvt..u\t%0,%z1" --+ [(set_attr "type" "fcvt") --+ (set_attr "mode" "")]) --+ --+(define_insn "l2" --+ [(set (match_operand:GPR 0 "register_operand" "=r") --+ (unspec:GPR [(match_operand:ANYF 1 "register_operand" "f")] --+ RINT))] --+ "TARGET_HARD_FLOAT" --+ "fcvt.. %0,%1," --+ [(set_attr "type" "fcvt") --+ (set_attr "mode" "")]) --+ --+;; --+;; .................... --+;; --+;; DATA MOVEMENT --+;; --+;; .................... --+ --+;; Lower-level instructions for loading an address from the GOT. --+;; We could use MEMs, but an unspec gives more optimization --+;; opportunities. --+ --+(define_insn "got_load" --+ [(set (match_operand:P 0 "register_operand" "=r") --+ (unspec:P [(match_operand:P 1 "symbolic_operand" "")] --+ UNSPEC_LOAD_GOT))] --+ "" --+ "la\t%0,%1" --+ [(set_attr "got" "load") --+ (set_attr "mode" "")]) --+ --+(define_insn "tls_add_tp_le" --+ [(set (match_operand:P 0 "register_operand" "=r") --+ (unspec:P [(match_operand:P 1 "register_operand" "r") --+ (match_operand:P 2 "register_operand" "r") --+ (match_operand:P 3 "symbolic_operand" "")] --+ UNSPEC_TLS_LE))] --+ "" --+ "add\t%0,%1,%2,%%tprel_add(%3)" --+ [(set_attr "type" "arith") --+ (set_attr "mode" "")]) --+ --+(define_insn "got_load_tls_gd" --+ [(set (match_operand:P 0 "register_operand" "=r") --+ (unspec:P [(match_operand:P 1 "symbolic_operand" "")] --+ UNSPEC_TLS_GD))] --+ "" --+ "la.tls.gd\t%0,%1" --+ [(set_attr "got" "load") --+ (set_attr "mode" "")]) --+ --+(define_insn "got_load_tls_ie" --+ [(set (match_operand:P 0 "register_operand" "=r") --+ (unspec:P [(match_operand:P 1 "symbolic_operand" "")] --+ UNSPEC_TLS_IE))] --+ "" --+ "la.tls.ie\t%0,%1" --+ [(set_attr "got" "load") --+ (set_attr "mode" "")]) --+ --+(define_insn "auipc" --+ [(set (match_operand:P 0 "register_operand" "=r") --+ (unspec:P [(match_operand:P 1 "symbolic_operand" "") --+ (match_operand:P 2 "const_int_operand") --+ (pc)] --+ UNSPEC_AUIPC))] --+ "" --+ ".LA%2: auipc\t%0,%h1" --+ [(set_attr "type" "arith") --+ (set_attr "cannot_copy" "yes")]) --+ --+;; Instructions for adding the low 12 bits of an address to a register. --+;; Operand 2 is the address: riscv_print_operand works out which relocation --+;; should be applied. --+ --+(define_insn "*low" --+ [(set (match_operand:P 0 "register_operand" "=r") --+ (lo_sum:P (match_operand:P 1 "register_operand" "r") --+ (match_operand:P 2 "symbolic_operand" "")))] --+ "" --+ "addi\t%0,%1,%R2" --+ [(set_attr "type" "arith") --+ (set_attr "mode" "")]) --+ --+;; Allow combine to split complex const_int load sequences, using operand 2 --+;; to store the intermediate results. See move_operand for details. --+(define_split --+ [(set (match_operand:GPR 0 "register_operand") --+ (match_operand:GPR 1 "splittable_const_int_operand")) --+ (clobber (match_operand:GPR 2 "register_operand"))] --+ "" --+ [(const_int 0)] --+{ --+ riscv_move_integer (operands[2], operands[0], INTVAL (operands[1])); --+ DONE; --+}) --+ --+;; Likewise, for symbolic operands. --+(define_split --+ [(set (match_operand:P 0 "register_operand") --+ (match_operand:P 1)) --+ (clobber (match_operand:P 2 "register_operand"))] --+ "riscv_split_symbol (operands[2], operands[1], MAX_MACHINE_MODE, NULL)" --+ [(set (match_dup 0) (match_dup 3))] --+{ --+ riscv_split_symbol (operands[2], operands[1], --+ MAX_MACHINE_MODE, &operands[3]); --+}) --+ --+;; 64-bit integer moves --+ --+(define_expand "movdi" --+ [(set (match_operand:DI 0 "") --+ (match_operand:DI 1 ""))] --+ "" --+{ --+ if (riscv_legitimize_move (DImode, operands[0], operands[1])) --+ DONE; --+}) --+ --+(define_insn "*movdi_32bit" --+ [(set (match_operand:DI 0 "nonimmediate_operand" "=r,r,r,m, *f,*f,*r,*f,*m") --+ (match_operand:DI 1 "move_operand" " r,i,m,r,*J*r,*m,*f,*f,*f"))] --+ "!TARGET_64BIT --+ && (register_operand (operands[0], DImode) --+ || reg_or_0_operand (operands[1], DImode))" --+ { return riscv_output_move (operands[0], operands[1]); } --+ [(set_attr "move_type" "move,const,load,store,mtc,fpload,mfc,fmove,fpstore") --+ (set_attr "mode" "DI")]) --+ --+(define_insn "*movdi_64bit" --+ [(set (match_operand:DI 0 "nonimmediate_operand" "=r,r,r, m,*f,*f,*r,*f,*m") --+ (match_operand:DI 1 "move_operand" " r,T,m,rJ,*r*J,*m,*f,*f,*f"))] --+ "TARGET_64BIT --+ && (register_operand (operands[0], DImode) --+ || reg_or_0_operand (operands[1], DImode))" --+ { return riscv_output_move (operands[0], operands[1]); } --+ [(set_attr "move_type" "move,const,load,store,mtc,fpload,mfc,fmove,fpstore") --+ (set_attr "mode" "DI")]) --+ --+;; 32-bit Integer moves --+ --+(define_expand "mov" --+ [(set (match_operand:MOVE32 0 "") --+ (match_operand:MOVE32 1 ""))] --+ "" --+{ --+ if (riscv_legitimize_move (mode, operands[0], operands[1])) --+ DONE; --+}) --+ --+(define_insn "*movsi_internal" --+ [(set (match_operand:SI 0 "nonimmediate_operand" "=r,r,r,m,*f,*f,*r,*m") --+ (match_operand:SI 1 "move_operand" "r,T,m,rJ,*r*J,*m,*f,*f"))] --+ "(register_operand (operands[0], SImode) --+ || reg_or_0_operand (operands[1], SImode))" --+ { return riscv_output_move (operands[0], operands[1]); } --+ [(set_attr "move_type" "move,const,load,store,mtc,fpload,mfc,fpstore") --+ (set_attr "mode" "SI")]) --+ --+;; 16-bit Integer moves --+ --+;; Unlike most other insns, the move insns can't be split with --+;; different predicates, because register spilling and other parts of --+;; the compiler, have memoized the insn number already. --+;; Unsigned loads are used because LOAD_EXTEND_OP returns ZERO_EXTEND. --+ --+(define_expand "movhi" --+ [(set (match_operand:HI 0 "") --+ (match_operand:HI 1 ""))] --+ "" --+{ --+ if (riscv_legitimize_move (HImode, operands[0], operands[1])) --+ DONE; --+}) --+ --+(define_insn "*movhi_internal" --+ [(set (match_operand:HI 0 "nonimmediate_operand" "=r,r,r,m,*f,*r") --+ (match_operand:HI 1 "move_operand" "r,T,m,rJ,*r*J,*f"))] --+ "(register_operand (operands[0], HImode) --+ || reg_or_0_operand (operands[1], HImode))" --+ { return riscv_output_move (operands[0], operands[1]); } --+ [(set_attr "move_type" "move,const,load,store,mtc,mfc") --+ (set_attr "mode" "HI")]) --+ --+;; HImode constant generation; see riscv_move_integer for details. --+;; si+si->hi without truncation is legal because of TRULY_NOOP_TRUNCATION. --+ --+(define_insn "*addhi3" --+ [(set (match_operand:HI 0 "register_operand" "=r,r") --+ (plus:HI (match_operand:HISI 1 "register_operand" "r,r") --+ (match_operand:HISI 2 "arith_operand" "r,I")))] --+ "" --+ { return TARGET_64BIT ? "addw\t%0,%1,%2" : "add\t%0,%1,%2"; } --+ [(set_attr "type" "arith") --+ (set_attr "mode" "HI")]) --+ --+(define_insn "*xorhi3" --+ [(set (match_operand:HI 0 "register_operand" "=r,r") --+ (xor:HI (match_operand:HISI 1 "register_operand" "r,r") --+ (match_operand:HISI 2 "arith_operand" "r,I")))] --+ "" --+ "xor\t%0,%1,%2" --+ [(set_attr "type" "logical") --+ (set_attr "mode" "HI")]) --+ --+;; 8-bit Integer moves --+ --+(define_expand "movqi" --+ [(set (match_operand:QI 0 "") --+ (match_operand:QI 1 ""))] --+ "" --+{ --+ if (riscv_legitimize_move (QImode, operands[0], operands[1])) --+ DONE; --+}) --+ --+(define_insn "*movqi_internal" --+ [(set (match_operand:QI 0 "nonimmediate_operand" "=r,r,r,m,*f,*r") --+ (match_operand:QI 1 "move_operand" "r,I,m,rJ,*r*J,*f"))] --+ "(register_operand (operands[0], QImode) --+ || reg_or_0_operand (operands[1], QImode))" --+ { return riscv_output_move (operands[0], operands[1]); } --+ [(set_attr "move_type" "move,const,load,store,mtc,mfc") --+ (set_attr "mode" "QI")]) --+ --+;; 32-bit floating point moves --+ --+(define_expand "movsf" --+ [(set (match_operand:SF 0 "") --+ (match_operand:SF 1 ""))] --+ "" --+{ --+ if (riscv_legitimize_move (SFmode, operands[0], operands[1])) --+ DONE; --+}) --+ --+(define_insn "*movsf_hardfloat" --+ [(set (match_operand:SF 0 "nonimmediate_operand" "=f,f,f,m,m,*f,*r,*r,*r,*m") --+ (match_operand:SF 1 "move_operand" "f,G,m,f,G,*r,*f,*G*r,*m,*r"))] --+ "TARGET_HARD_FLOAT --+ && (register_operand (operands[0], SFmode) --+ || reg_or_0_operand (operands[1], SFmode))" --+ { return riscv_output_move (operands[0], operands[1]); } --+ [(set_attr "move_type" "fmove,mtc,fpload,fpstore,store,mtc,mfc,move,load,store") --+ (set_attr "mode" "SF")]) --+ --+(define_insn "*movsf_softfloat" --+ [(set (match_operand:SF 0 "nonimmediate_operand" "=r,r,m") --+ (match_operand:SF 1 "move_operand" "Gr,m,r"))] --+ "!TARGET_HARD_FLOAT --+ && (register_operand (operands[0], SFmode) --+ || reg_or_0_operand (operands[1], SFmode))" --+ { return riscv_output_move (operands[0], operands[1]); } --+ [(set_attr "move_type" "move,load,store") --+ (set_attr "mode" "SF")]) --+ --+;; 64-bit floating point moves --+ --+(define_expand "movdf" --+ [(set (match_operand:DF 0 "") --+ (match_operand:DF 1 ""))] --+ "" --+{ --+ if (riscv_legitimize_move (DFmode, operands[0], operands[1])) --+ DONE; --+}) --+ --+;; In RV32, we lack fmv.x.d and fmv.d.x. Go through memory instead. --+;; (However, we can still use fcvt.d.w to zero a floating-point register.) --+(define_insn "*movdf_hardfloat_rv32" --+ [(set (match_operand:DF 0 "nonimmediate_operand" "=f,f,f,m,m,*r,*r,*m") --+ (match_operand:DF 1 "move_operand" "f,G,m,f,G,*r*G,*m,*r"))] --+ "!TARGET_64BIT && TARGET_DOUBLE_FLOAT --+ && (register_operand (operands[0], DFmode) --+ || reg_or_0_operand (operands[1], DFmode))" --+ { return riscv_output_move (operands[0], operands[1]); } --+ [(set_attr "move_type" "fmove,mtc,fpload,fpstore,store,move,load,store") --+ (set_attr "mode" "DF")]) --+ --+(define_insn "*movdf_hardfloat_rv64" --+ [(set (match_operand:DF 0 "nonimmediate_operand" "=f,f,f,m,m,*f,*r,*r,*r,*m") --+ (match_operand:DF 1 "move_operand" "f,G,m,f,G,*r,*f,*r*G,*m,*r"))] --+ "TARGET_64BIT && TARGET_DOUBLE_FLOAT --+ && (register_operand (operands[0], DFmode) --+ || reg_or_0_operand (operands[1], DFmode))" --+ { return riscv_output_move (operands[0], operands[1]); } --+ [(set_attr "move_type" "fmove,mtc,fpload,fpstore,store,mtc,mfc,move,load,store") --+ (set_attr "mode" "DF")]) --+ --+(define_insn "*movdf_softfloat" --+ [(set (match_operand:DF 0 "nonimmediate_operand" "=r,r,m") --+ (match_operand:DF 1 "move_operand" "rG,m,rG"))] --+ "!TARGET_DOUBLE_FLOAT --+ && (register_operand (operands[0], DFmode) --+ || reg_or_0_operand (operands[1], DFmode))" --+ { return riscv_output_move (operands[0], operands[1]); } --+ [(set_attr "move_type" "move,load,store") --+ (set_attr "mode" "DF")]) --+ --+(define_split --+ [(set (match_operand:MOVE64 0 "nonimmediate_operand") --+ (match_operand:MOVE64 1 "move_operand"))] --+ "reload_completed --+ && riscv_split_64bit_move_p (operands[0], operands[1])" --+ [(const_int 0)] --+{ --+ riscv_split_doubleword_move (operands[0], operands[1]); --+ DONE; --+}) --+ --+;; Expand in-line code to clear the instruction cache between operand[0] and --+;; operand[1]. --+(define_expand "clear_cache" --+ [(match_operand 0 "pmode_register_operand") --+ (match_operand 1 "pmode_register_operand")] --+ "" --+{ --+ emit_insn (gen_fence_i ()); --+ DONE; --+}) --+ --+(define_insn "fence" --+ [(unspec_volatile [(const_int 0)] UNSPECV_FENCE)] --+ "" --+ "%|fence%-") --+ --+(define_insn "fence_i" --+ [(unspec_volatile [(const_int 0)] UNSPECV_FENCE_I)] --+ "" --+ "fence.i") --+ --+;; --+;; .................... --+;; --+;; SHIFTS --+;; --+;; .................... --+ --+(define_insn "si3" --+ [(set (match_operand:SI 0 "register_operand" "=r") --+ (any_shift:SI (match_operand:SI 1 "register_operand" "r") --+ (match_operand:SI 2 "arith_operand" "rI")))] --+ "" --+{ --+ if (GET_CODE (operands[2]) == CONST_INT) --+ operands[2] = GEN_INT (INTVAL (operands[2]) --+ & (GET_MODE_BITSIZE (SImode) - 1)); --+ --+ return TARGET_64BIT ? "w\t%0,%1,%2" : "\t%0,%1,%2"; --+} --+ [(set_attr "type" "shift") --+ (set_attr "mode" "SI")]) --+ --+(define_insn "di3" --+ [(set (match_operand:DI 0 "register_operand" "=r") --+ (any_shift:DI (match_operand:DI 1 "register_operand" "r") --+ (match_operand:DI 2 "arith_operand" "rI")))] --+ "TARGET_64BIT" --+{ --+ if (GET_CODE (operands[2]) == CONST_INT) --+ operands[2] = GEN_INT (INTVAL (operands[2]) --+ & (GET_MODE_BITSIZE (DImode) - 1)); --+ --+ return "\t%0,%1,%2"; --+} --+ [(set_attr "type" "shift") --+ (set_attr "mode" "DI")]) --+ --+(define_insn "*si3_extend" --+ [(set (match_operand:DI 0 "register_operand" "=r") --+ (sign_extend:DI --+ (any_shift:SI (match_operand:SI 1 "register_operand" "r") --+ (match_operand:SI 2 "arith_operand" "rI"))))] --+ "TARGET_64BIT" --+{ --+ if (GET_CODE (operands[2]) == CONST_INT) --+ operands[2] = GEN_INT (INTVAL (operands[2]) & 0x1f); --+ --+ return "w\t%0,%1,%2"; --+} --+ [(set_attr "type" "shift") --+ (set_attr "mode" "SI")]) --+ --+;; --+;; .................... --+;; --+;; CONDITIONAL BRANCHES --+;; --+;; .................... --+ --+;; Conditional branches --+ --+(define_insn "*branch_order" --+ [(set (pc) --+ (if_then_else --+ (match_operator 1 "order_operator" --+ [(match_operand:X 2 "register_operand" "r") --+ (match_operand:X 3 "register_operand" "r")]) --+ (label_ref (match_operand 0 "" "")) --+ (pc)))] --+ "" --+ "b%C1\t%2,%3,%0" --+ [(set_attr "type" "branch") --+ (set_attr "mode" "none")]) --+ --+(define_insn "*branch_zero" --+ [(set (pc) --+ (if_then_else --+ (match_operator 1 "signed_order_operator" --+ [(match_operand:X 2 "register_operand" "r") --+ (const_int 0)]) --+ (label_ref (match_operand 0 "" "")) --+ (pc)))] --+ "" --+ "b%C1z\t%2,%0" --+ [(set_attr "type" "branch") --+ (set_attr "mode" "none")]) --+ --+;; Used to implement built-in functions. --+(define_expand "condjump" --+ [(set (pc) --+ (if_then_else (match_operand 0) --+ (label_ref (match_operand 1)) --+ (pc)))]) --+ --+(define_expand "cbranch4" --+ [(set (pc) --+ (if_then_else (match_operator 0 "comparison_operator" --+ [(match_operand:BR 1 "register_operand") --+ (match_operand:BR 2 "nonmemory_operand")]) --+ (label_ref (match_operand 3 "")) --+ (pc)))] --+ "" --+{ --+ riscv_expand_conditional_branch (operands[3], GET_CODE (operands[0]), --+ operands[1], operands[2]); --+ DONE; --+}) --+ --+(define_expand "cbranch4" --+ [(set (pc) --+ (if_then_else (match_operator 0 "fp_branch_comparison" --+ [(match_operand:ANYF 1 "register_operand") --+ (match_operand:ANYF 2 "register_operand")]) --+ (label_ref (match_operand 3 "")) --+ (pc)))] --+ "TARGET_HARD_FLOAT" --+{ --+ riscv_expand_conditional_branch (operands[3], GET_CODE (operands[0]), --+ operands[1], operands[2]); --+ DONE; --+}) --+ --+(define_insn_and_split "*branch_on_bit" --+ [(set (pc) --+ (if_then_else --+ (match_operator 0 "equality_operator" --+ [(zero_extract:X (match_operand:X 2 "register_operand" "r") --+ (const_int 1) --+ (match_operand 3 "branch_on_bit_operand")) --+ (const_int 0)]) --+ (label_ref (match_operand 1)) --+ (pc))) --+ (clobber (match_scratch:X 4 "=&r"))] --+ "" --+ "#" --+ "reload_completed" --+ [(set (match_dup 4) --+ (ashift:X (match_dup 2) (match_dup 3))) --+ (set (pc) --+ (if_then_else --+ (match_op_dup 0 [(match_dup 4) (const_int 0)]) --+ (label_ref (match_operand 1)) --+ (pc)))] --+{ --+ int shift = GET_MODE_BITSIZE (mode) - 1 - INTVAL (operands[3]); --+ operands[3] = GEN_INT (shift); --+ --+ if (GET_CODE (operands[0]) == EQ) --+ operands[0] = gen_rtx_GE (mode, operands[4], const0_rtx); --+ else --+ operands[0] = gen_rtx_LT (mode, operands[4], const0_rtx); --+}) --+ --+(define_insn_and_split "*branch_on_bit_range" --+ [(set (pc) --+ (if_then_else --+ (match_operator 0 "equality_operator" --+ [(zero_extract:X (match_operand:X 2 "register_operand" "r") --+ (match_operand 3 "branch_on_bit_operand") --+ (const_int 0)) --+ (const_int 0)]) --+ (label_ref (match_operand 1)) --+ (pc))) --+ (clobber (match_scratch:X 4 "=&r"))] --+ "" --+ "#" --+ "reload_completed" --+ [(set (match_dup 4) --+ (ashift:X (match_dup 2) (match_dup 3))) --+ (set (pc) --+ (if_then_else --+ (match_op_dup 0 [(match_dup 4) (const_int 0)]) --+ (label_ref (match_operand 1)) --+ (pc)))] --+{ --+ operands[3] = GEN_INT (GET_MODE_BITSIZE (mode) - INTVAL (operands[3])); --+}) --+ --+;; --+;; .................... --+;; --+;; SETTING A REGISTER FROM A COMPARISON --+;; --+;; .................... --+ --+;; Destination is always set in SI mode. --+ --+(define_expand "cstore4" --+ [(set (match_operand:SI 0 "register_operand") --+ (match_operator:SI 1 "order_operator" --+ [(match_operand:GPR 2 "register_operand") --+ (match_operand:GPR 3 "nonmemory_operand")]))] --+ "" --+{ --+ riscv_expand_int_scc (operands[0], GET_CODE (operands[1]), operands[2], --+ operands[3]); --+ DONE; --+}) --+ --+(define_expand "cstore4" --+ [(set (match_operand:SI 0 "register_operand") --+ (match_operator:SI 1 "fp_scc_comparison" --+ [(match_operand:ANYF 2 "register_operand") --+ (match_operand:ANYF 3 "register_operand")]))] --+ "TARGET_HARD_FLOAT" --+{ --+ riscv_expand_float_scc (operands[0], GET_CODE (operands[1]), operands[2], --+ operands[3]); --+ DONE; --+}) --+ --+(define_insn "*cstore4" --+ [(set (match_operand:X 0 "register_operand" "=r") --+ (match_operator:X 1 "fp_native_comparison" --+ [(match_operand:ANYF 2 "register_operand" "f") --+ (match_operand:ANYF 3 "register_operand" "f")]))] --+ "TARGET_HARD_FLOAT" --+ "f%C1.\t%0,%2,%3" --+ [(set_attr "type" "fcmp") --+ (set_attr "mode" "")]) --+ --+(define_insn "f_quiet4" --+ [(set (match_operand:X 0 "register_operand" "=r") --+ (unspec:X --+ [(match_operand:ANYF 1 "register_operand" "f") --+ (match_operand:ANYF 2 "register_operand" "f")] --+ QUIET_COMPARISON)) --+ (clobber (match_scratch:X 3 "=&r"))] --+ "TARGET_HARD_FLOAT" --+ "frflags\t%3\n\tf.\t%0,%1,%2\n\tfsflags %3" --+ [(set_attr "type" "fcmp") --+ (set_attr "mode" "") --+ (set (attr "length") (const_int 12))]) --+ --+(define_insn "*seq_zero_" --+ [(set (match_operand:GPR 0 "register_operand" "=r") --+ (eq:GPR (match_operand:X 1 "register_operand" "r") --+ (const_int 0)))] --+ "" --+ "seqz\t%0,%1" --+ [(set_attr "type" "slt") --+ (set_attr "mode" "")]) --+ --+(define_insn "*sne_zero_" --+ [(set (match_operand:GPR 0 "register_operand" "=r") --+ (ne:GPR (match_operand:X 1 "register_operand" "r") --+ (const_int 0)))] --+ "" --+ "snez\t%0,%1" --+ [(set_attr "type" "slt") --+ (set_attr "mode" "")]) --+ --+(define_insn "*sgt_" --+ [(set (match_operand:GPR 0 "register_operand" "=r") --+ (any_gt:GPR (match_operand:X 1 "register_operand" "r") --+ (match_operand:X 2 "reg_or_0_operand" "rJ")))] --+ "" --+ "sgt\t%0,%1,%z2" --+ [(set_attr "type" "slt") --+ (set_attr "mode" "")]) --+ --+(define_insn "*sge_" --+ [(set (match_operand:GPR 0 "register_operand" "=r") --+ (any_ge:GPR (match_operand:X 1 "register_operand" "r") --+ (const_int 1)))] --+ "" --+ "slt\t%0,zero,%1" --+ [(set_attr "type" "slt") --+ (set_attr "mode" "")]) --+ --+(define_insn "*slt_" --+ [(set (match_operand:GPR 0 "register_operand" "=r") --+ (any_lt:GPR (match_operand:X 1 "register_operand" "r") --+ (match_operand:X 2 "arith_operand" "rI")))] --+ "" --+ "slt\t%0,%1,%2" --+ [(set_attr "type" "slt") --+ (set_attr "mode" "")]) --+ --+(define_insn "*sle_" --+ [(set (match_operand:GPR 0 "register_operand" "=r") --+ (any_le:GPR (match_operand:X 1 "register_operand" "r") --+ (match_operand:X 2 "sle_operand" "")))] --+ "" --+{ --+ operands[2] = GEN_INT (INTVAL (operands[2]) + 1); --+ return "slt\t%0,%1,%2"; --+} --+ [(set_attr "type" "slt") --+ (set_attr "mode" "")]) --+ --+;; --+;; .................... --+;; --+;; UNCONDITIONAL BRANCHES --+;; --+;; .................... --+ --+;; Unconditional branches. --+ --+(define_insn "jump" --+ [(set (pc) --+ (label_ref (match_operand 0 "" "")))] --+ "" --+ "j\t%l0" --+ [(set_attr "type" "jump") --+ (set_attr "mode" "none")]) --+ --+(define_expand "indirect_jump" --+ [(set (pc) (match_operand 0 "register_operand"))] --+ "" --+{ --+ operands[0] = force_reg (Pmode, operands[0]); --+ if (Pmode == SImode) --+ emit_jump_insn (gen_indirect_jumpsi (operands[0])); --+ else --+ emit_jump_insn (gen_indirect_jumpdi (operands[0])); --+ DONE; --+}) --+ --+(define_insn "indirect_jump" --+ [(set (pc) (match_operand:P 0 "register_operand" "l"))] --+ "" --+ "jr\t%0" --+ [(set_attr "type" "jump") --+ (set_attr "mode" "none")]) --+ --+(define_expand "tablejump" --+ [(set (pc) (match_operand 0 "register_operand" "")) --+ (use (label_ref (match_operand 1 "" "")))] --+ "" --+{ --+ if (CASE_VECTOR_PC_RELATIVE) --+ operands[0] = expand_simple_binop (Pmode, PLUS, operands[0], --+ gen_rtx_LABEL_REF (Pmode, operands[1]), --+ NULL_RTX, 0, OPTAB_DIRECT); --+ --+ if (CASE_VECTOR_PC_RELATIVE && Pmode == DImode) --+ emit_jump_insn (gen_tablejumpdi (operands[0], operands[1])); --+ else --+ emit_jump_insn (gen_tablejumpsi (operands[0], operands[1])); --+ DONE; --+}) --+ --+(define_insn "tablejump" --+ [(set (pc) (match_operand:GPR 0 "register_operand" "l")) --+ (use (label_ref (match_operand 1 "" "")))] --+ "" --+ "jr\t%0" --+ [(set_attr "type" "jump") --+ (set_attr "mode" "none")]) --+ --+;; --+;; .................... --+;; --+;; Function prologue/epilogue --+;; --+;; .................... --+;; --+ --+(define_expand "prologue" --+ [(const_int 1)] --+ "" --+{ --+ riscv_expand_prologue (); --+ DONE; --+}) --+ --+;; Block any insns from being moved before this point, since the --+;; profiling call to mcount can use various registers that aren't --+;; saved or used to pass arguments. --+ --+(define_insn "blockage" --+ [(unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)] --+ "" --+ "" --+ [(set_attr "type" "ghost") --+ (set_attr "mode" "none")]) --+ --+(define_expand "epilogue" --+ [(const_int 2)] --+ "" --+{ --+ riscv_expand_epilogue (false); --+ DONE; --+}) --+ --+(define_expand "sibcall_epilogue" --+ [(const_int 2)] --+ "" --+{ --+ riscv_expand_epilogue (true); --+ DONE; --+}) --+ --+;; Trivial return. Make it look like a normal return insn as that --+;; allows jump optimizations to work better. --+ --+(define_expand "return" --+ [(simple_return)] --+ "riscv_can_use_return_insn ()" --+ "") --+ --+(define_insn "simple_return" --+ [(simple_return)] --+ "" --+ "ret" --+ [(set_attr "type" "jump") --+ (set_attr "mode" "none")]) --+ --+;; Normal return. --+ --+(define_insn "simple_return_internal" --+ [(simple_return) --+ (use (match_operand 0 "pmode_register_operand" ""))] --+ "" --+ "jr\t%0" --+ [(set_attr "type" "jump") --+ (set_attr "mode" "none")]) --+ --+;; This is used in compiling the unwind routines. --+(define_expand "eh_return" --+ [(use (match_operand 0 "general_operand"))] --+ "" --+{ --+ if (GET_MODE (operands[0]) != word_mode) --+ operands[0] = convert_to_mode (word_mode, operands[0], 0); --+ if (TARGET_64BIT) --+ emit_insn (gen_eh_set_lr_di (operands[0])); --+ else --+ emit_insn (gen_eh_set_lr_si (operands[0])); --+ DONE; --+}) --+ --+;; Clobber the return address on the stack. We can't expand this --+;; until we know where it will be put in the stack frame. --+ --+(define_insn "eh_set_lr_si" --+ [(unspec [(match_operand:SI 0 "register_operand" "r")] UNSPEC_EH_RETURN) --+ (clobber (match_scratch:SI 1 "=&r"))] --+ "! TARGET_64BIT" --+ "#") --+ --+(define_insn "eh_set_lr_di" --+ [(unspec [(match_operand:DI 0 "register_operand" "r")] UNSPEC_EH_RETURN) --+ (clobber (match_scratch:DI 1 "=&r"))] --+ "TARGET_64BIT" --+ "#") --+ --+(define_split --+ [(unspec [(match_operand 0 "register_operand")] UNSPEC_EH_RETURN) --+ (clobber (match_scratch 1))] --+ "reload_completed" --+ [(const_int 0)] --+{ --+ riscv_set_return_address (operands[0], operands[1]); --+ DONE; --+}) --+ --+;; --+;; .................... --+;; --+;; FUNCTION CALLS --+;; --+;; .................... --+ --+(define_expand "sibcall" --+ [(parallel [(call (match_operand 0 "") --+ (match_operand 1 "")) --+ (use (match_operand 2 "")) ;; next_arg_reg --+ (use (match_operand 3 ""))])] ;; struct_value_size_rtx --+ "" --+{ --+ rtx target = riscv_legitimize_call_address (XEXP (operands[0], 0)); --+ emit_call_insn (gen_sibcall_internal (target, operands[1])); --+ DONE; --+}) --+ --+(define_insn "sibcall_internal" --+ [(call (mem:SI (match_operand 0 "call_insn_operand" "j,S,U")) --+ (match_operand 1 "" ""))] --+ "SIBLING_CALL_P (insn)" --+ "@ --+ jr\t%0 --+ tail\t%0 --+ tail\t%0@plt" --+ [(set_attr "type" "call")]) --+ --+(define_expand "sibcall_value" --+ [(parallel [(set (match_operand 0 "") --+ (call (match_operand 1 "") --+ (match_operand 2 ""))) --+ (use (match_operand 3 ""))])] ;; next_arg_reg --+ "" --+{ --+ rtx target = riscv_legitimize_call_address (XEXP (operands[1], 0)); --+ emit_call_insn (gen_sibcall_value_internal (operands[0], target, operands[2])); --+ DONE; --+}) --+ --+(define_insn "sibcall_value_internal" --+ [(set (match_operand 0 "" "") --+ (call (mem:SI (match_operand 1 "call_insn_operand" "j,S,U")) --+ (match_operand 2 "" "")))] --+ "SIBLING_CALL_P (insn)" --+ "@ --+ jr\t%1 --+ tail\t%1 --+ tail\t%1@plt" --+ [(set_attr "type" "call")]) --+ --+(define_expand "call" --+ [(parallel [(call (match_operand 0 "") --+ (match_operand 1 "")) --+ (use (match_operand 2 "")) ;; next_arg_reg --+ (use (match_operand 3 ""))])] ;; struct_value_size_rtx --+ "" --+{ --+ rtx target = riscv_legitimize_call_address (XEXP (operands[0], 0)); --+ emit_call_insn (gen_call_internal (target, operands[1])); --+ DONE; --+}) --+ --+(define_insn "call_internal" --+ [(call (mem:SI (match_operand 0 "call_insn_operand" "l,S,U")) --+ (match_operand 1 "" "")) --+ (clobber (reg:SI RETURN_ADDR_REGNUM))] --+ "" --+ "@ --+ jalr\t%0 --+ call\t%0 --+ call\t%0@plt" --+ [(set_attr "type" "call")]) --+ --+(define_expand "call_value" --+ [(parallel [(set (match_operand 0 "") --+ (call (match_operand 1 "") --+ (match_operand 2 ""))) --+ (use (match_operand 3 ""))])] ;; next_arg_reg --+ "" --+{ --+ rtx target = riscv_legitimize_call_address (XEXP (operands[1], 0)); --+ emit_call_insn (gen_call_value_internal (operands[0], target, operands[2])); --+ DONE; --+}) --+ --+(define_insn "call_value_internal" --+ [(set (match_operand 0 "" "") --+ (call (mem:SI (match_operand 1 "call_insn_operand" "l,S,U")) --+ (match_operand 2 "" ""))) --+ (clobber (reg:SI RETURN_ADDR_REGNUM))] --+ "" --+ "@ --+ jalr\t%1 --+ call\t%1 --+ call\t%1@plt" --+ [(set_attr "type" "call")]) --+ --+;; Call subroutine returning any type. --+ --+(define_expand "untyped_call" --+ [(parallel [(call (match_operand 0 "") --+ (const_int 0)) --+ (match_operand 1 "") --+ (match_operand 2 "")])] --+ "" --+{ --+ int i; --+ --+ emit_call_insn (gen_call (operands[0], const0_rtx, NULL, const0_rtx)); --+ --+ for (i = 0; i < XVECLEN (operands[2], 0); i++) --+ { --+ rtx set = XVECEXP (operands[2], 0, i); --+ riscv_emit_move (SET_DEST (set), SET_SRC (set)); --+ } --+ --+ emit_insn (gen_blockage ()); --+ DONE; --+}) --+ --+(define_insn "nop" --+ [(const_int 0)] --+ "" --+ "nop" --+ [(set_attr "type" "nop") --+ (set_attr "mode" "none")]) --+ --+(define_insn "trap" --+ [(trap_if (const_int 1) (const_int 0))] --+ "" --+ "ebreak") --+ --+(define_insn "gpr_save" --+ [(unspec_volatile [(match_operand 0 "const_int_operand")] UNSPECV_GPR_SAVE) --+ (clobber (reg:SI T0_REGNUM)) --+ (clobber (reg:SI T1_REGNUM))] --+ "" --+ { return riscv_output_gpr_save (INTVAL (operands[0])); }) --+ --+(define_insn "gpr_restore" --+ [(unspec_volatile [(match_operand 0 "const_int_operand")] UNSPECV_GPR_RESTORE)] --+ "" --+ "tail\t__riscv_restore_%0") --+ --+(define_insn "gpr_restore_return" --+ [(return) --+ (use (match_operand 0 "pmode_register_operand" "")) --+ (const_int 0)] --+ "" --+ "") --+ --+(define_insn "riscv_frflags" --+ [(set (match_operand:SI 0 "register_operand" "=r") --+ (unspec_volatile [(const_int 0)] UNSPECV_FRFLAGS))] --+ "TARGET_HARD_FLOAT" --+ "frflags %0") --+ --+(define_insn "riscv_fsflags" --+ [(unspec_volatile [(match_operand:SI 0 "csr_operand" "rK")] UNSPECV_FSFLAGS)] --+ "TARGET_HARD_FLOAT" --+ "fsflags %0") --+ --+(define_insn "stack_tie" --+ [(set (mem:BLK (scratch)) --+ (unspec:BLK [(match_operand:X 0 "register_operand" "r") --+ (match_operand:X 1 "register_operand" "r")] --+ UNSPEC_TIE))] --+ "" --+ "" --+ [(set_attr "length" "0")] --+) --+ --+(include "sync.md") --+(include "peephole.md") --+(include "pic.md") --+(include "generic.md") --diff --git original-gcc/gcc/config/riscv/riscv.opt gcc-6.3.0/gcc/config/riscv/riscv.opt --new file mode 100644 --index 00000000000..0466bb29d14 ----- /dev/null --+++ gcc-6.3.0/gcc/config/riscv/riscv.opt --@@ -0,0 +1,111 @@ --+; Options for the RISC-V port of the compiler --+; --+; Copyright (C) 2011-2017 Free Software Foundation, Inc. --+; --+; This file is part of GCC. --+; --+; GCC is free software; you can redistribute it and/or modify it under --+; the terms of the GNU General Public License as published by the Free --+; Software Foundation; either version 3, or (at your option) any later --+; version. --+; --+; GCC is distributed in the hope that it will be useful, but WITHOUT --+; ANY WARRANTY; without even the implied warranty of MERCHANTABILITY --+; or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public --+; License for more details. --+; --+; You should have received a copy of the GNU General Public License --+; along with GCC; see the file COPYING3. If not see --+; . --+ --+HeaderInclude --+config/riscv/riscv-opts.h --+ --+mbranch-cost= --+Target RejectNegative Joined UInteger Var(riscv_branch_cost) --+-mbranch-cost=N Set the cost of branches to roughly N instructions. --+ --+mplt --+Target Report Var(TARGET_PLT) Init(1) --+When generating -fpic code, allow the use of PLTs. Ignored for fno-pic. --+ --+mabi= --+Target Report RejectNegative Joined Enum(abi_type) Var(riscv_abi) Init(ABI_ILP32) --+Specify integer and floating-point calling convention. --+ --+Enum --+Name(abi_type) Type(enum riscv_abi_type) --+Supported ABIs (for use with the -mabi= option): --+ --+EnumValue --+Enum(abi_type) String(ilp32) Value(ABI_ILP32) --+ --+EnumValue --+Enum(abi_type) String(ilp32f) Value(ABI_ILP32F) --+ --+EnumValue --+Enum(abi_type) String(ilp32d) Value(ABI_ILP32D) --+ --+EnumValue --+Enum(abi_type) String(lp64) Value(ABI_LP64) --+ --+EnumValue --+Enum(abi_type) String(lp64f) Value(ABI_LP64F) --+ --+EnumValue --+Enum(abi_type) String(lp64d) Value(ABI_LP64D) --+ --+mfdiv --+Target Report Mask(FDIV) --+Use hardware floating-point divide and square root instructions. --+ --+mdiv --+Target Report Mask(DIV) --+Use hardware instructions for integer division. --+ --+march= --+Target Report RejectNegative Joined --+-march= Generate code for given RISC-V ISA (e.g. RV64IM). ISA strings must be --+lower-case. --+ --+mtune= --+Target RejectNegative Joined Var(riscv_tune_string) --+-mtune=PROCESSOR Optimize the output for PROCESSOR. --+ --+msmall-data-limit= --+Target Joined Separate UInteger Var(g_switch_value) Init(8) --+-msmall-data-limit=N Put global and static data smaller than bytes into a special section (on some targets). --+ --+msave-restore --+Target Report Mask(SAVE_RESTORE) --+Use smaller but slower prologue and epilogue code. --+ --+mcmodel= --+Target Report RejectNegative Joined Enum(code_model) Var(riscv_cmodel) Init(TARGET_DEFAULT_CMODEL) --+Specify the code model. --+ --+Enum --+Name(code_model) Type(enum riscv_code_model) --+Known code models (for use with the -mcmodel= option): --+ --+EnumValue --+Enum(code_model) String(medlow) Value(CM_MEDLOW) --+ --+EnumValue --+Enum(code_model) String(medany) Value(CM_MEDANY) --+ --+mexplicit-relocs --+Target Report Mask(EXPLICIT_RELOCS) --+Use %reloc() operators, rather than assembly macros, to load addresses. --+ --+Mask(64BIT) --+ --+Mask(MUL) --+ --+Mask(ATOMIC) --+ --+Mask(HARD_FLOAT) --+ --+Mask(DOUBLE_FLOAT) --+ --+Mask(RVC) --diff --git original-gcc/gcc/config/riscv/sync.md gcc-6.3.0/gcc/config/riscv/sync.md --new file mode 100644 --index 00000000000..09970b9f36b ----- /dev/null --+++ gcc-6.3.0/gcc/config/riscv/sync.md --@@ -0,0 +1,194 @@ --+;; Machine description for RISC-V atomic operations. --+;; Copyright (C) 2011-2017 Free Software Foundation, Inc. --+;; Contributed by Andrew Waterman (andrew@sifive.com). --+;; Based on MIPS target for GNU compiler. --+ --+;; This file is part of GCC. --+ --+;; GCC is free software; you can redistribute it and/or modify --+;; it under the terms of the GNU General Public License as published by --+;; the Free Software Foundation; either version 3, or (at your option) --+;; any later version. --+ --+;; GCC is distributed in the hope that it will be useful, --+;; but WITHOUT ANY WARRANTY; without even the implied warranty of --+;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the --+;; GNU General Public License for more details. --+ --+;; You should have received a copy of the GNU General Public License --+;; along with GCC; see the file COPYING3. If not see --+;; . --+ --+(define_c_enum "unspec" [ --+ UNSPEC_COMPARE_AND_SWAP --+ UNSPEC_SYNC_OLD_OP --+ UNSPEC_SYNC_EXCHANGE --+ UNSPEC_ATOMIC_STORE --+ UNSPEC_MEMORY_BARRIER --+]) --+ --+(define_code_iterator any_atomic [plus ior xor and]) --+(define_code_attr atomic_optab --+ [(plus "add") (ior "or") (xor "xor") (and "and")]) --+ --+;; Memory barriers. --+ --+(define_expand "mem_thread_fence" --+ [(match_operand:SI 0 "const_int_operand" "")] ;; model --+ "" --+{ --+ if (INTVAL (operands[0]) != MEMMODEL_RELAXED) --+ { --+ rtx mem = gen_rtx_MEM (BLKmode, gen_rtx_SCRATCH (Pmode)); --+ MEM_VOLATILE_P (mem) = 1; --+ emit_insn (gen_mem_thread_fence_1 (mem, operands[0])); --+ } --+ DONE; --+}) --+ --+;; Until the RISC-V memory model (hence its mapping from C++) is finalized, --+;; conservatively emit a full FENCE. --+(define_insn "mem_thread_fence_1" --+ [(set (match_operand:BLK 0 "" "") --+ (unspec:BLK [(match_dup 0)] UNSPEC_MEMORY_BARRIER)) --+ (match_operand:SI 1 "const_int_operand" "")] ;; model --+ "" --+ "fence\trw,rw") --+ --+;; Atomic memory operations. --+ --+;; Implement atomic stores with amoswap. Fall back to fences for atomic loads. --+(define_insn "atomic_store" --+ [(set (match_operand:GPR 0 "memory_operand" "=A") --+ (unspec_volatile:GPR --+ [(match_operand:GPR 1 "reg_or_0_operand" "rJ") --+ (match_operand:SI 2 "const_int_operand")] ;; model --+ UNSPEC_ATOMIC_STORE))] --+ "TARGET_ATOMIC" --+ "%F2amoswap.%A2 zero,%z1,%0" --+ [(set (attr "length") (const_int 8))]) --+ --+(define_insn "atomic_" --+ [(set (match_operand:GPR 0 "memory_operand" "+A") --+ (unspec_volatile:GPR --+ [(any_atomic:GPR (match_dup 0) --+ (match_operand:GPR 1 "reg_or_0_operand" "rJ")) --+ (match_operand:SI 2 "const_int_operand")] ;; model --+ UNSPEC_SYNC_OLD_OP))] --+ "TARGET_ATOMIC" --+ "%F2amo.%A2 zero,%z1,%0" --+ [(set (attr "length") (const_int 8))]) --+ --+(define_insn "atomic_fetch_" --+ [(set (match_operand:GPR 0 "register_operand" "=&r") --+ (match_operand:GPR 1 "memory_operand" "+A")) --+ (set (match_dup 1) --+ (unspec_volatile:GPR --+ [(any_atomic:GPR (match_dup 1) --+ (match_operand:GPR 2 "reg_or_0_operand" "rJ")) --+ (match_operand:SI 3 "const_int_operand")] ;; model --+ UNSPEC_SYNC_OLD_OP))] --+ "TARGET_ATOMIC" --+ "%F3amo.%A3 %0,%z2,%1" --+ [(set (attr "length") (const_int 8))]) --+ --+(define_insn "atomic_exchange" --+ [(set (match_operand:GPR 0 "register_operand" "=&r") --+ (unspec_volatile:GPR --+ [(match_operand:GPR 1 "memory_operand" "+A") --+ (match_operand:SI 3 "const_int_operand")] ;; model --+ UNSPEC_SYNC_EXCHANGE)) --+ (set (match_dup 1) --+ (match_operand:GPR 2 "register_operand" "0"))] --+ "TARGET_ATOMIC" --+ "%F3amoswap.%A3 %0,%z2,%1" --+ [(set (attr "length") (const_int 8))]) --+ --+(define_insn "atomic_cas_value_strong" --+ [(set (match_operand:GPR 0 "register_operand" "=&r") --+ (match_operand:GPR 1 "memory_operand" "+A")) --+ (set (match_dup 1) --+ (unspec_volatile:GPR [(match_operand:GPR 2 "reg_or_0_operand" "rJ") --+ (match_operand:GPR 3 "reg_or_0_operand" "rJ") --+ (match_operand:SI 4 "const_int_operand") ;; mod_s --+ (match_operand:SI 5 "const_int_operand")] ;; mod_f --+ UNSPEC_COMPARE_AND_SWAP)) --+ (clobber (match_scratch:GPR 6 "=&r"))] --+ "TARGET_ATOMIC" --+ "%F5 1: lr.%A5 %0,%1; bne %0,%z2,1f; sc.%A4 %6,%z3,%1; bnez %6,1b; 1:" --+ [(set (attr "length") (const_int 20))]) --+ --+(define_expand "atomic_compare_and_swap" --+ [(match_operand:SI 0 "register_operand" "") ;; bool output --+ (match_operand:GPR 1 "register_operand" "") ;; val output --+ (match_operand:GPR 2 "memory_operand" "") ;; memory --+ (match_operand:GPR 3 "reg_or_0_operand" "") ;; expected value --+ (match_operand:GPR 4 "reg_or_0_operand" "") ;; desired value --+ (match_operand:SI 5 "const_int_operand" "") ;; is_weak --+ (match_operand:SI 6 "const_int_operand" "") ;; mod_s --+ (match_operand:SI 7 "const_int_operand" "")] ;; mod_f --+ "TARGET_ATOMIC" --+{ --+ emit_insn (gen_atomic_cas_value_strong (operands[1], operands[2], --+ operands[3], operands[4], --+ operands[6], operands[7])); --+ --+ rtx compare = operands[1]; --+ if (operands[3] != const0_rtx) --+ { --+ rtx difference = gen_rtx_MINUS (mode, operands[1], operands[3]); --+ compare = gen_reg_rtx (mode); --+ emit_insn (gen_rtx_SET (compare, difference)); --+ } --+ --+ if (word_mode != mode) --+ { --+ rtx reg = gen_reg_rtx (word_mode); --+ emit_insn (gen_rtx_SET (reg, gen_rtx_SIGN_EXTEND (word_mode, compare))); --+ compare = reg; --+ } --+ --+ emit_insn (gen_rtx_SET (operands[0], gen_rtx_EQ (SImode, compare, const0_rtx))); --+ DONE; --+}) --+ --+(define_expand "atomic_test_and_set" --+ [(match_operand:QI 0 "register_operand" "") ;; bool output --+ (match_operand:QI 1 "memory_operand" "+A") ;; memory --+ (match_operand:SI 2 "const_int_operand" "")] ;; model --+ "TARGET_ATOMIC" --+{ --+ /* We have no QImode atomics, so use the address LSBs to form a mask, --+ then use an aligned SImode atomic. */ --+ rtx result = operands[0]; --+ rtx mem = operands[1]; --+ rtx model = operands[2]; --+ rtx addr = force_reg (Pmode, XEXP (mem, 0)); --+ --+ rtx aligned_addr = gen_reg_rtx (Pmode); --+ emit_move_insn (aligned_addr, gen_rtx_AND (Pmode, addr, GEN_INT (-4))); --+ --+ rtx aligned_mem = change_address (mem, SImode, aligned_addr); --+ set_mem_alias_set (aligned_mem, 0); --+ --+ rtx offset = gen_reg_rtx (SImode); --+ emit_move_insn (offset, gen_rtx_AND (SImode, gen_lowpart (SImode, addr), --+ GEN_INT (3))); --+ --+ rtx tmp = gen_reg_rtx (SImode); --+ emit_move_insn (tmp, GEN_INT (1)); --+ --+ rtx shmt = gen_reg_rtx (SImode); --+ emit_move_insn (shmt, gen_rtx_ASHIFT (SImode, offset, GEN_INT (3))); --+ --+ rtx word = gen_reg_rtx (SImode); --+ emit_move_insn (word, gen_rtx_ASHIFT (SImode, tmp, shmt)); --+ --+ tmp = gen_reg_rtx (SImode); --+ emit_insn (gen_atomic_fetch_orsi (tmp, aligned_mem, word, model)); --+ --+ emit_move_insn (gen_lowpart (SImode, result), --+ gen_rtx_LSHIFTRT (SImode, tmp, --+ gen_lowpart (SImode, shmt))); --+ DONE; --+}) --diff --git original-gcc/gcc/config/riscv/t-elf-multilib gcc-6.3.0/gcc/config/riscv/t-elf-multilib --new file mode 100644 --index 00000000000..6a39ece03bd ----- /dev/null --+++ gcc-6.3.0/gcc/config/riscv/t-elf-multilib --@@ -0,0 +1,6 @@ --+# This file was generated by multilib-generator with the command: --+# ./multilib-generator rv32i-ilp32--c rv32im-ilp32--c rv32iac-ilp32-- rv32imac-ilp32-- rv32imafc-ilp32f-rv32imafdc- rv64imac-lp64-- rv64imafdc-lp64d-- --+MULTILIB_OPTIONS = march=rv32i/march=rv32ic/march=rv32im/march=rv32imc/march=rv32iac/march=rv32imac/march=rv32imafc/march=rv32imafdc/march=rv32gc/march=rv64imac/march=rv64imafdc/march=rv64gc mabi=ilp32/mabi=ilp32f/mabi=lp64/mabi=lp64d --+MULTILIB_DIRNAMES = rv32i rv32ic rv32im rv32imc rv32iac rv32imac rv32imafc rv32imafdc rv32gc rv64imac rv64imafdc rv64gc ilp32 ilp32f lp64 lp64d --+MULTILIB_REQUIRED = march=rv32i/mabi=ilp32 march=rv32im/mabi=ilp32 march=rv32iac/mabi=ilp32 march=rv32imac/mabi=ilp32 march=rv32imafc/mabi=ilp32f march=rv64imac/mabi=lp64 march=rv64imafdc/mabi=lp64d --+MULTILIB_REUSE = march.rv32i/mabi.ilp32=march.rv32ic/mabi.ilp32 march.rv32im/mabi.ilp32=march.rv32imc/mabi.ilp32 march.rv32imafc/mabi.ilp32f=march.rv32imafdc/mabi.ilp32f march.rv32imafc/mabi.ilp32f=march.rv32gc/mabi.ilp32f march.rv64imafdc/mabi.lp64d=march.rv64gc/mabi.lp64d --diff --git original-gcc/gcc/config/riscv/t-linux gcc-6.3.0/gcc/config/riscv/t-linux --new file mode 100644 --index 00000000000..216d2776a18 ----- /dev/null --+++ gcc-6.3.0/gcc/config/riscv/t-linux --@@ -0,0 +1,3 @@ --+# Only XLEN and ABI affect Linux multilib dir names, e.g. /lib32/ilp32d/ --+MULTILIB_DIRNAMES := $(patsubst rv32%,lib32,$(patsubst rv64%,lib64,$(MULTILIB_DIRNAMES))) --+MULTILIB_OSDIRNAMES := $(patsubst lib%,../lib%,$(MULTILIB_DIRNAMES)) --diff --git original-gcc/gcc/config/riscv/t-linux-multilib gcc-6.3.0/gcc/config/riscv/t-linux-multilib --new file mode 100644 --index 00000000000..e94d4da5212 ----- /dev/null --+++ gcc-6.3.0/gcc/config/riscv/t-linux-multilib --@@ -0,0 +1,6 @@ --+# This file was generated by multilib-generator with the command: --+# ./multilib-generator rv32imac-ilp32-rv32ima,rv32imaf,rv32imafd,rv32imafc,rv32imafdc- rv32imafdc-ilp32d-rv32imafd- rv64imac-lp64-rv64ima,rv64imaf,rv64imafd,rv64imafc,rv64imafdc- rv64imafdc-lp64d-rv64imafd- --+MULTILIB_OPTIONS = march=rv32imac/march=rv32ima/march=rv32imaf/march=rv32imafd/march=rv32imafc/march=rv32imafdc/march=rv32g/march=rv32gc/march=rv64imac/march=rv64ima/march=rv64imaf/march=rv64imafd/march=rv64imafc/march=rv64imafdc/march=rv64g/march=rv64gc mabi=ilp32/mabi=ilp32d/mabi=lp64/mabi=lp64d --+MULTILIB_DIRNAMES = rv32imac rv32ima rv32imaf rv32imafd rv32imafc rv32imafdc rv32g rv32gc rv64imac rv64ima rv64imaf rv64imafd rv64imafc rv64imafdc rv64g rv64gc ilp32 ilp32d lp64 lp64d --+MULTILIB_REQUIRED = march=rv32imac/mabi=ilp32 march=rv32imafdc/mabi=ilp32d march=rv64imac/mabi=lp64 march=rv64imafdc/mabi=lp64d --+MULTILIB_REUSE = march.rv32imac/mabi.ilp32=march.rv32ima/mabi.ilp32 march.rv32imac/mabi.ilp32=march.rv32imaf/mabi.ilp32 march.rv32imac/mabi.ilp32=march.rv32imafd/mabi.ilp32 march.rv32imac/mabi.ilp32=march.rv32imafc/mabi.ilp32 march.rv32imac/mabi.ilp32=march.rv32imafdc/mabi.ilp32 march.rv32imac/mabi.ilp32=march.rv32g/mabi.ilp32 march.rv32imac/mabi.ilp32=march.rv32gc/mabi.ilp32 march.rv32imafdc/mabi.ilp32d=march.rv32imafd/mabi.ilp32d march.rv32imafdc/mabi.ilp32d=march.rv32gc/mabi.ilp32d march.rv32imafdc/mabi.ilp32d=march.rv32g/mabi.ilp32d march.rv64imac/mabi.lp64=march.rv64ima/mabi.lp64 march.rv64imac/mabi.lp64=march.rv64imaf/mabi.lp64 march.rv64imac/mabi.lp64=march.rv64imafd/mabi.lp64 march.rv64imac/mabi.lp64=march.rv64imafc/mabi.lp64 march.rv64imac/mabi.lp64=march.rv64imafdc/mabi.lp64 march.rv64imac/mabi.lp64=march.rv64g/mabi.lp64 march.rv64imac/mabi.lp64=march.rv64gc/mabi.lp64 march.rv64imafdc/mabi.lp64d=march.rv64imafd/mabi.lp64d march.rv64imafdc/mabi.lp64d=march.rv64gc/mabi.lp64d march.rv64imafdc/mabi.lp64d=march.rv64g/mabi.lp64d --diff --git original-gcc/gcc/config/riscv/t-riscv gcc-6.3.0/gcc/config/riscv/t-riscv --new file mode 100644 --index 00000000000..0765b49f90f ----- /dev/null --+++ gcc-6.3.0/gcc/config/riscv/t-riscv --@@ -0,0 +1,11 @@ --+riscv-builtins.o: $(srcdir)/config/riscv/riscv-builtins.c $(CONFIG_H) \ --+ $(SYSTEM_H) coretypes.h $(TM_H) $(RTL_H) $(TREE_H) $(RECOG_H) langhooks.h \ --+ $(DIAGNOSTIC_CORE_H) $(OPTABS_H) $(srcdir)/config/riscv/riscv-ftypes.def \ --+ $(srcdir)/config/riscv/riscv-modes.def --+ $(COMPILER) -c $(ALL_COMPILERFLAGS) $(ALL_CPPFLAGS) $(INCLUDES) \ --+ $(srcdir)/config/riscv/riscv-builtins.c --+ --+riscv-c.o: $(srcdir)/config/riscv/riscv-c.c $(CONFIG_H) $(SYSTEM_H) \ --+ coretypes.h $(TM_H) $(TREE_H) output.h $(C_COMMON_H) $(TARGET_H) --+ $(COMPILER) -c $(ALL_COMPILERFLAGS) $(ALL_CPPFLAGS) $(INCLUDES) \ --+ $(srcdir)/config/riscv/riscv-c.c --diff --git original-gcc/gcc/configure gcc-6.3.0/gcc/configure --index c9e43fb80e3..5359a4e6ee5 100755 ----- original-gcc/gcc/configure --+++ gcc-6.3.0/gcc/configure --@@ -24156,6 +24156,17 @@ x3: .space 4 -- tls_first_minor=14 -- tls_as_opt="-a32 --fatal-warnings" -- ;; --+ riscv*-*-*) --+ conftest_s=' --+ .section .tdata,"awT",@progbits --+x: .word 2 --+ .text --+ la.tls.gd a0,x --+ call __tls_get_addr' --+ tls_first_major=2 --+ tls_first_minor=21 --+ tls_as_opt='--fatal-warnings' --+ ;; -- s390-*-*) -- conftest_s=' -- .section ".tdata","awT",@progbits --@@ -27516,8 +27527,8 @@ esac -- # version to the per-target configury. -- case "$cpu_type" in -- aarch64 | alpha | arm | avr | bfin | cris | i386 | m32c | m68k | microblaze \ --- | mips | nds32 | nios2 | pa | rs6000 | score | sparc | spu | tilegx | tilepro \ --- | visium | xstormy16 | xtensa) --+ | mips | nds32 | nios2 | pa | riscv | rs6000 | score | sparc | spu | tilegx \ --+ | tilepro | visium | xstormy16 | xtensa) -- insn="nop" -- ;; -- ia64 | s390) --diff --git original-gcc/gcc/configure.ac gcc-6.3.0/gcc/configure.ac --index 33f9a0ecdc6..673fb1bb891 100644 ----- original-gcc/gcc/configure.ac --+++ gcc-6.3.0/gcc/configure.ac --@@ -3393,6 +3393,17 @@ x3: .space 4 -- tls_first_minor=14 -- tls_as_opt="-a32 --fatal-warnings" -- ;; --+ riscv*-*-*) --+ conftest_s=' --+ .section .tdata,"awT",@progbits --+x: .word 2 --+ .text --+ la.tls.gd a0,x --+ call __tls_get_addr' --+ tls_first_major=2 --+ tls_first_minor=21 --+ tls_as_opt='--fatal-warnings' --+ ;; -- s390-*-*) -- conftest_s=' -- .section ".tdata","awT",@progbits --@@ -4744,8 +4755,8 @@ esac -- # version to the per-target configury. -- case "$cpu_type" in -- aarch64 | alpha | arm | avr | bfin | cris | i386 | m32c | m68k | microblaze \ --- | mips | nds32 | nios2 | pa | rs6000 | score | sparc | spu | tilegx | tilepro \ --- | visium | xstormy16 | xtensa) --+ | mips | nds32 | nios2 | pa | riscv | rs6000 | score | sparc | spu | tilegx \ --+ | tilepro | visium | xstormy16 | xtensa) -- insn="nop" -- ;; -- ia64 | s390) --diff --git original-gcc/gcc/doc/contrib.texi gcc-6.3.0/gcc/doc/contrib.texi --index 5554d5f04c8..5b14fc445b5 100644 ----- original-gcc/gcc/doc/contrib.texi --+++ gcc-6.3.0/gcc/doc/contrib.texi --@@ -173,6 +173,10 @@ Denis Chertykov for contributing and maintaining the AVR port, the first GCC por -- for an 8-bit architecture. -- -- @item --+Kito Cheng for his work on the RISC-V port, including bringing up the test --+suite and maintiance. --+ --+@item -- Scott Christley for his Objective-C contributions. -- -- @item --@@ -217,6 +221,9 @@ Paul Dale for his work to add uClinux platform support to the -- m68k backend. -- -- @item --+Palmer Dabbelt for his work maintaining the RISC-V port. --+ --+@item -- Dario Dariol contributed the four varieties of sample programs -- that print a copy of their source. -- --@@ -1035,6 +1042,9 @@ associated configure steps. -- Todd Vierling for contributions for NetBSD ports. -- -- @item --+Andrew Waterman for contributing the RISC-V port, as well as maintaining it. --+ --+@item -- Jonathan Wakely for contributing libstdc++ Doxygen notes and XHTML -- guidance. -- --diff --git original-gcc/gcc/doc/install.texi gcc-6.3.0/gcc/doc/install.texi --index bc4edfdb096..0c82fe9eb94 100644 ----- original-gcc/gcc/doc/install.texi --+++ gcc-6.3.0/gcc/doc/install.texi --@@ -4297,6 +4297,36 @@ This configuration is intended for embedded systems. -- @html --
-- @end html --+@anchor{riscv32-x-elf} --+@heading riscv32-*-elf --+The RISC-V RV32 instruction set. --+This configuration is intended for embedded systems. --+ --+@html --+
--+@end html --+@anchor{riscv64-x-elf} --+@heading riscv64-*-elf --+The RISC-V RV64 instruction set. --+This configuration is intended for embedded systems. --+ --+@html --+
--+@end html --+@anchor{riscv32-x-linux} --+@heading riscv32-*-linux --+The RISC-V RV32 instruction set running GNU/Linux. --+ --+@html --+
--+@end html --+@anchor{riscv64-x-linux} --+@heading riscv64-*-linux --+The RISC-V RV64 instruction set running GNU/Linux. --+ --+@html --+
--+@end html -- @anchor{rx-x-elf} -- @heading rx-*-elf -- The Renesas RX processor. See --diff --git original-gcc/gcc/doc/invoke.texi gcc-6.3.0/gcc/doc/invoke.texi --index 4b13aeb7426..581c4effbc5 100644 ----- original-gcc/gcc/doc/invoke.texi --+++ gcc-6.3.0/gcc/doc/invoke.texi --@@ -1046,6 +1046,20 @@ See RS/6000 and PowerPC Options. -- -mstack-protector-guard-offset=@var{offset} @gol -- -mlra -mno-lra} -- --+@emph{RISC-V Options} --+@gccoptlist{-mbranch-cost=@var{N-instruction} @gol --+-mmemcpy -mno-memcpy @gol --+-mplt -mno-plt @gol --+-mabi=@var{ABI-string} @gol --+-mfdiv -mno-fdiv @gol --+-mdiv -mno-div @gol --+-march=@var{ISA-string} @gol --+-mtune=@var{processor-string} @gol --+-msmall-data-limit=@var{N-bytes} @gol --+-msave-restore -mno-save-restore @gol --+-mcmodel=@var{code-model} @gol --+-mexplicit-relocs -mno-explicit-relocs @gol} --+ -- @emph{RX Options} -- @gccoptlist{-m64bit-doubles -m32bit-doubles -fpu -nofpu@gol -- -mcpu=@gol --@@ -13881,6 +13895,7 @@ platform. -- * PowerPC Options:: -- * RL78 Options:: -- * RS/6000 and PowerPC Options:: --+* RISC-V Options:: -- * RX Options:: -- * S/390 and zSeries Options:: -- * Score Options:: --@@ -22274,6 +22289,70 @@ offset from that base register. The default for those is as specified in the -- relevant ABI. -- @end table -- --+@node RISC-V Options --+@subsection RISC-V Options --+@cindex RISC-V Options --+ --+These command-line options are defined for RISC-V targets: --+ --+@table @gcctabopt --+@item -mbranch-cost=@var{N} --+@opindex mbranch-cost --+Set the cost of branches to roughly N instructions. --+ --+@item -mmemcpy --+@itemx -mno-memcpy --+@opindex mmemcpy --+Don't optimize block moves. --+ --+@item -mplt --+@itemx -mno-plt --+@opindex plt --+When generating -fpic code, allow the use of PLTs. Ignored for fno-pic. --+ --+@item -mabi=@var{ABI-string} --+@opindex mabi --+Specify integer and floating-point calling convention. This defaults to the --+natural calling convention: eg LP64 for RV64I, ILP32 for RV32I, LP64D for --+RV64G. --+ --+@item -mfdiv --+@itemx -mno-fdiv --+@opindex mfdiv --+Use hardware floating-point divide and square root instructions. This requires --+the F or D extensions for floating-point registers. --+ --+@item -mdiv --+@itemx -mno-div --+@opindex mdiv --+Use hardware instructions for integer division. This requires the M extension. --+ --+@item -march=@var{ISA-string} --+@opindex march --+Generate code for given RISC-V ISA (e.g. rv64im). ISA strings must be --+lower-case. Examples include "rv64i", "rv32g", and "rv32imaf". --+ --+@item -mtune=@var{processor-string} --+@opindex mtune --+Optimize the output for the given processor, specified by microarchitecture --+name. --+ --+@item -msmall-data-limit=@var{N} --+@opindex msmall-data-limit --+Put global and static data smaller than @var{N} bytes into a special section --+(on some targets). --+ --+@item -msave-restore --+@itemx -mno-save-restore --+@opindex msave-restore --+Use smaller but slower prologue and epilogue code. --+ --+@item -mcmodel=@var{code-model} --+@opindex mcmodel --+Specify the code model. --+ --+@end table --+ -- @node RX Options -- @subsection RX Options -- @cindex RX Options --diff --git original-gcc/gcc/doc/md.texi gcc-6.3.0/gcc/doc/md.texi --index 11266d7dd3f..3f710740b22 100644 ----- original-gcc/gcc/doc/md.texi --+++ gcc-6.3.0/gcc/doc/md.texi --@@ -3362,6 +3362,26 @@ The @code{X} register. -- -- @end table -- --+@item RISC-V---@file{config/riscv/constraints.md} --+@table @code --+ --+@item f --+A floating-point register (if availiable). --+ --+@item I --+An I-type 12-bit signed immediate. --+ --+@item J --+Integer zero. --+ --+@item K --+A 5-bit unsigned immediate for CSR access instructions. --+ --+@item A --+An address that is held in a general-purpose register. --+ --+@end table --+ -- @item RX---@file{config/rx/constraints.md} -- @table @code -- @item Q --diff --git original-gcc/libatomic/configure.tgt gcc-6.3.0/libatomic/configure.tgt --index 6d77c9482a5..b8af3ab2546 100644 ----- original-gcc/libatomic/configure.tgt --+++ gcc-6.3.0/libatomic/configure.tgt --@@ -37,6 +37,7 @@ case "${target_cpu}" in -- ARCH=alpha -- ;; -- rs6000 | powerpc*) ARCH=powerpc ;; --+ riscv*) ARCH=riscv ;; -- sh*) ARCH=sh ;; -- -- arm*) --diff --git original-gcc/libgcc/config.host gcc-6.3.0/libgcc/config.host --index 540bfa96358..9472a60886c 100644 ----- original-gcc/libgcc/config.host --+++ gcc-6.3.0/libgcc/config.host --@@ -167,6 +167,9 @@ powerpc*-*-*) -- ;; -- rs6000*-*-*) -- ;; --+riscv*-*-*) --+ cpu_type=riscv --+ ;; -- sparc64*-*-*) -- cpu_type=sparc -- ;; --@@ -1093,6 +1096,15 @@ powerpcle-*-eabi*) -- tmake_file="${tmake_file} rs6000/t-ppccomm rs6000/t-crtstuff t-crtstuff-pic t-fdpbit" -- extra_parts="$extra_parts crtbegin.o crtend.o crtbeginS.o crtendS.o crtbeginT.o ecrti.o ecrtn.o ncrti.o ncrtn.o" -- ;; --+riscv*-*-linux*) --+ tmake_file="${tmake_file} riscv/t-softfp${host_address} t-softfp riscv/t-elf riscv/t-elf${host_address}" --+ extra_parts="$extra_parts crtbegin.o crtend.o crti.o crtn.o crtendS.o crtbeginT.o" --+ md_unwind_header=riscv/linux-unwind.h --+ ;; --+riscv*-*-*) --+ tmake_file="${tmake_file} riscv/t-softfp${host_address} t-softfp riscv/t-elf riscv/t-elf${host_address}" --+ extra_parts="$extra_parts crtbegin.o crtend.o crti.o crtn.o" --+ ;; -- rs6000-ibm-aix4.[3456789]* | powerpc-ibm-aix4.[3456789]*) -- md_unwind_header=rs6000/aix-unwind.h -- tmake_file="t-fdpbit rs6000/t-ppc64-fp rs6000/t-slibgcc-aix rs6000/t-ibm-ldouble" --diff --git original-gcc/libgcc/config/riscv/atomic.c gcc-6.3.0/libgcc/config/riscv/atomic.c --new file mode 100644 --index 00000000000..448b0e55b5a ----- /dev/null --+++ gcc-6.3.0/libgcc/config/riscv/atomic.c --@@ -0,0 +1,111 @@ --+/* Legacy sub-word atomics for RISC-V. --+ --+ Copyright (C) 2016-2017 Free Software Foundation, Inc. --+ --+This file is part of GCC. --+ --+GCC is free software; you can redistribute it and/or modify it under --+the terms of the GNU General Public License as published by the Free --+Software Foundation; either version 3, or (at your option) any later --+version. --+ --+GCC is distributed in the hope that it will be useful, but WITHOUT ANY --+WARRANTY; without even the implied warranty of MERCHANTABILITY or --+FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License --+for more details. --+ --+Under Section 7 of GPL version 3, you are granted additional --+permissions described in the GCC Runtime Library Exception, version --+3.1, as published by the Free Software Foundation. --+ --+You should have received a copy of the GNU General Public License and --+a copy of the GCC Runtime Library Exception along with this program; --+see the files COPYING3 and COPYING.RUNTIME respectively. If not, see --+. */ --+ --+#ifdef __riscv_atomic --+ --+#include --+ --+#define INVERT "not %[tmp1], %[tmp1]\n\t" --+#define DONT_INVERT "" --+ --+#define GENERATE_FETCH_AND_OP(type, size, opname, insn, invert, cop) \ --+ type __sync_fetch_and_ ## opname ## _ ## size (type *p, type v) \ --+ { \ --+ unsigned long aligned_addr = ((unsigned long) p) & ~3UL; \ --+ int shift = (((unsigned long) p) & 3) * 8; \ --+ unsigned mask = ((1U << ((sizeof v) * 8)) - 1) << shift; \ --+ unsigned old, tmp1, tmp2; \ --+ \ --+ asm volatile ("1:\n\t" \ --+ "lr.w.aq %[old], %[mem]\n\t" \ --+ #insn " %[tmp1], %[old], %[value]\n\t" \ --+ invert \ --+ "and %[tmp1], %[tmp1], %[mask]\n\t" \ --+ "and %[tmp2], %[old], %[not_mask]\n\t" \ --+ "or %[tmp2], %[tmp2], %[tmp1]\n\t" \ --+ "sc.w.rl %[tmp1], %[tmp2], %[mem]\n\t" \ --+ "bnez %[tmp1], 1b" \ --+ : [old] "=&r" (old), \ --+ [mem] "+A" (*(volatile unsigned*) aligned_addr), \ --+ [tmp1] "=&r" (tmp1), \ --+ [tmp2] "=&r" (tmp2) \ --+ : [value] "r" (((unsigned) v) << shift), \ --+ [mask] "r" (mask), \ --+ [not_mask] "r" (~mask)); \ --+ \ --+ return (type) (old >> shift); \ --+ } \ --+ \ --+ type __sync_ ## opname ## _and_fetch_ ## size (type *p, type v) \ --+ { \ --+ type o = __sync_fetch_and_ ## opname ## _ ## size (p, v); \ --+ return cop; \ --+ } --+ --+#define GENERATE_COMPARE_AND_SWAP(type, size) \ --+ type __sync_val_compare_and_swap_ ## size (type *p, type o, type n) \ --+ { \ --+ unsigned long aligned_addr = ((unsigned long) p) & ~3UL; \ --+ int shift = (((unsigned long) p) & 3) * 8; \ --+ unsigned mask = ((1U << ((sizeof o) * 8)) - 1) << shift; \ --+ unsigned old, tmp1; \ --+ \ --+ asm volatile ("1:\n\t" \ --+ "lr.w.aq %[old], %[mem]\n\t" \ --+ "and %[tmp1], %[old], %[mask]\n\t" \ --+ "bne %[tmp1], %[o], 1f\n\t" \ --+ "and %[tmp1], %[old], %[not_mask]\n\t" \ --+ "or %[tmp1], %[tmp1], %[n]\n\t" \ --+ "sc.w.rl %[tmp1], %[tmp1], %[mem]\n\t" \ --+ "bnez %[tmp1], 1b\n\t" \ --+ "1:" \ --+ : [old] "=&r" (old), \ --+ [mem] "+A" (*(volatile unsigned*) aligned_addr), \ --+ [tmp1] "=&r" (tmp1) \ --+ : [o] "r" ((((unsigned) o) << shift) & mask), \ --+ [n] "r" ((((unsigned) n) << shift) & mask), \ --+ [mask] "r" (mask), \ --+ [not_mask] "r" (~mask)); \ --+ \ --+ return (type) (old >> shift); \ --+ } \ --+ bool __sync_bool_compare_and_swap_ ## size (type *p, type o, type n) \ --+ { \ --+ return __sync_val_compare_and_swap(p, o, n) == o; \ --+ } --+ --+#define GENERATE_ALL(type, size) \ --+ GENERATE_FETCH_AND_OP(type, size, add, add, DONT_INVERT, o + v) \ --+ GENERATE_FETCH_AND_OP(type, size, sub, sub, DONT_INVERT, o - v) \ --+ GENERATE_FETCH_AND_OP(type, size, and, and, DONT_INVERT, o & v) \ --+ GENERATE_FETCH_AND_OP(type, size, xor, xor, DONT_INVERT, o ^ v) \ --+ GENERATE_FETCH_AND_OP(type, size, or, or, DONT_INVERT, o | v) \ --+ GENERATE_FETCH_AND_OP(type, size, nand, and, INVERT, ~(o & v)) \ --+ GENERATE_COMPARE_AND_SWAP(type, size) --+ --+GENERATE_ALL(unsigned char, 1) --+GENERATE_ALL(unsigned short, 2) --+ --+#endif --diff --git original-gcc/libgcc/config/riscv/crti.S gcc-6.3.0/libgcc/config/riscv/crti.S --new file mode 100644 --index 00000000000..89bac706c63 ----- /dev/null --+++ gcc-6.3.0/libgcc/config/riscv/crti.S --@@ -0,0 +1 @@ --+/* crti.S is empty because .init_array/.fini_array are used exclusively. */ --diff --git original-gcc/libgcc/config/riscv/crtn.S gcc-6.3.0/libgcc/config/riscv/crtn.S --new file mode 100644 --index 00000000000..ca6ee7b6fba ----- /dev/null --+++ gcc-6.3.0/libgcc/config/riscv/crtn.S --@@ -0,0 +1 @@ --+/* crtn.S is empty because .init_array/.fini_array are used exclusively. */ --diff --git original-gcc/libgcc/config/riscv/div.S gcc-6.3.0/libgcc/config/riscv/div.S --new file mode 100644 --index 00000000000..63d542e846c ----- /dev/null --+++ gcc-6.3.0/libgcc/config/riscv/div.S --@@ -0,0 +1,146 @@ --+/* Integer division routines for RISC-V. --+ --+ Copyright (C) 2016-2017 Free Software Foundation, Inc. --+ --+This file is part of GCC. --+ --+GCC is free software; you can redistribute it and/or modify it under --+the terms of the GNU General Public License as published by the Free --+Software Foundation; either version 3, or (at your option) any later --+version. --+ --+GCC is distributed in the hope that it will be useful, but WITHOUT ANY --+WARRANTY; without even the implied warranty of MERCHANTABILITY or --+FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License --+for more details. --+ --+Under Section 7 of GPL version 3, you are granted additional --+permissions described in the GCC Runtime Library Exception, version --+3.1, as published by the Free Software Foundation. --+ --+You should have received a copy of the GNU General Public License and --+a copy of the GCC Runtime Library Exception along with this program; --+see the files COPYING3 and COPYING.RUNTIME respectively. If not, see --+. */ --+ --+ .text --+ .align 2 --+ --+#if __riscv_xlen == 32 --+/* Our RV64 64-bit routines are equivalent to our RV32 32-bit routines. */ --+# define __udivdi3 __udivsi3 --+# define __umoddi3 __umodsi3 --+# define __divdi3 __divsi3 --+# define __moddi3 __modsi3 --+#else --+ .globl __udivsi3 --+__udivsi3: --+ /* Compute __udivdi3(a0 << 32, a1 << 32); cast result to uint32_t. */ --+ sll a0, a0, 32 --+ sll a1, a1, 32 --+ move t0, ra --+ jal __udivdi3 --+ sext.w a0, a0 --+ jr t0 --+ --+ .globl __umodsi3 --+__umodsi3: --+ /* Compute __udivdi3((uint32_t)a0, (uint32_t)a1); cast a1 to uint32_t. */ --+ sll a0, a0, 32 --+ sll a1, a1, 32 --+ srl a0, a0, 32 --+ srl a1, a1, 32 --+ move t0, ra --+ jal __udivdi3 --+ sext.w a0, a1 --+ jr t0 --+ --+ .globl __modsi3 --+ __modsi3 = __moddi3 --+ --+ .globl __divsi3 --+__divsi3: --+ /* Check for special case of INT_MIN/-1. Otherwise, fall into __divdi3. */ --+ li t0, -1 --+ beq a1, t0, .L20 --+#endif --+ --+ .globl __divdi3 --+__divdi3: --+ bltz a0, .L10 --+ bltz a1, .L11 --+ /* Since the quotient is positive, fall into __udivdi3. */ --+ --+ .globl __udivdi3 --+__udivdi3: --+ mv a2, a1 --+ mv a1, a0 --+ li a0, -1 --+ beqz a2, .L5 --+ li a3, 1 --+ bgeu a2, a1, .L2 --+.L1: --+ blez a2, .L2 --+ slli a2, a2, 1 --+ slli a3, a3, 1 --+ bgtu a1, a2, .L1 --+.L2: --+ li a0, 0 --+.L3: --+ bltu a1, a2, .L4 --+ sub a1, a1, a2 --+ or a0, a0, a3 --+.L4: --+ srli a3, a3, 1 --+ srli a2, a2, 1 --+ bnez a3, .L3 --+.L5: --+ ret --+ --+ .globl __umoddi3 --+__umoddi3: --+ /* Call __udivdi3(a0, a1), then return the remainder, which is in a1. */ --+ move t0, ra --+ jal __udivdi3 --+ move a0, a1 --+ jr t0 --+ --+ /* Handle negative arguments to __divdi3. */ --+.L10: --+ neg a0, a0 --+ bgez a1, .L12 /* Compute __udivdi3(-a0, a1), then negate the result. */ --+ neg a1, a1 --+ j __udivdi3 /* Compute __udivdi3(-a0, -a1). */ --+.L11: /* Compute __udivdi3(a0, -a1), then negate the result. */ --+ neg a1, a1 --+.L12: --+ move t0, ra --+ jal __udivdi3 --+ neg a0, a0 --+ jr t0 --+ --+ .globl __moddi3 --+__moddi3: --+ move t0, ra --+ bltz a1, .L31 --+ bltz a0, .L32 --+.L30: --+ jal __udivdi3 /* The dividend is not negative. */ --+ move a0, a1 --+ jr t0 --+.L31: --+ neg a1, a1 --+ bgez a0, .L30 --+.L32: --+ neg a0, a0 --+ jal __udivdi3 /* The dividend is hella negative. */ --+ neg a0, a1 --+ jr t0 --+ --+#if __riscv_xlen == 64 --+ /* continuation of __divsi3 */ --+.L20: --+ sll t0, t0, 31 --+ bne a0, t0, __divdi3 --+ ret --+#endif --diff --git original-gcc/libgcc/config/riscv/linux-unwind.h gcc-6.3.0/libgcc/config/riscv/linux-unwind.h --new file mode 100644 --index 00000000000..a051a2869d4 ----- /dev/null --+++ gcc-6.3.0/libgcc/config/riscv/linux-unwind.h --@@ -0,0 +1,89 @@ --+/* Copyright (C) 2016-2017 Free Software Foundation, Inc. --+ --+ This file is free software; you can redistribute it and/or modify it --+ under the terms of the GNU General Public License as published by the --+ Free Software Foundation; either version 3, or (at your option) any --+ later version. --+ --+ This file 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. --+ --+ Under Section 7 of GPL version 3, you are granted additional --+ permissions described in the GCC Runtime Library Exception, version --+ 3.1, as published by the Free Software Foundation. --+ --+ You should have received a copy of the GNU General Public License and --+ a copy of the GCC Runtime Library Exception along with this program; --+ see the files COPYING3 and COPYING.RUNTIME respectively. If not, see --+ . */ --+ --+#ifndef inhibit_libc --+ --+#include --+#include --+#include --+ --+#define LI_A7_8B 0x08b00893 --+#define ECALL 0x00000073 --+ --+#define MD_FALLBACK_FRAME_STATE_FOR riscv_fallback_frame_state --+ --+static _Unwind_Reason_Code --+riscv_fallback_frame_state (struct _Unwind_Context *context, --+ _Unwind_FrameState * fs) --+{ --+ /* The kernel creates an rt_sigframe on the stack immediately prior --+ to delivering a signal. --+ --+ This structure must have the same shape as the linux kernel --+ equivalent. */ --+ struct rt_sigframe --+ { --+ siginfo_t info; --+ struct ucontext uc; --+ }; --+ --+ struct rt_sigframe *rt_; --+ _Unwind_Ptr new_cfa; --+ uint16_t *pc = context->ra; --+ struct sigcontext *sc; --+ int i; --+ --+ /* A signal frame will have a return address pointing to --+ __default_sa_restorer. This code is hardwired as: --+ --+ 0x08b00893 li a7,0x8b --+ 0x00000073 ecall --+ --+ Note, the PC might only have 2-byte alignment. --+ */ --+ if (pc[0] != (uint16_t)LI_A7_8B || pc[1] != (uint16_t)(LI_A7_8B >> 16) --+ || pc[2] != (uint16_t)ECALL || pc[3] != (uint16_t)(ECALL >> 16)) --+ return _URC_END_OF_STACK; --+ --+ rt_ = context->cfa; --+ sc = &rt_->uc.uc_mcontext; --+ --+ new_cfa = (_Unwind_Ptr) sc; --+ fs->regs.cfa_how = CFA_REG_OFFSET; --+ fs->regs.cfa_reg = __LIBGCC_STACK_POINTER_REGNUM__; --+ fs->regs.cfa_offset = new_cfa - (_Unwind_Ptr) context->cfa; --+ --+ for (i = 0; i < 32; i++) --+ { --+ fs->regs.reg[i].how = REG_SAVED_OFFSET; --+ fs->regs.reg[i].loc.offset = (_Unwind_Ptr) &sc->gregs[i] - new_cfa; --+ } --+ --+ fs->signal_frame = 1; --+ fs->retaddr_column = __LIBGCC_DWARF_ALT_FRAME_RETURN_COLUMN__; --+ fs->regs.reg[fs->retaddr_column].how = REG_SAVED_VAL_OFFSET; --+ fs->regs.reg[fs->retaddr_column].loc.offset = --+ (_Unwind_Ptr) sc->gregs[0] - new_cfa; --+ --+ return _URC_NO_REASON; --+} --+ --+#endif --diff --git original-gcc/libgcc/config/riscv/muldi3.S gcc-6.3.0/libgcc/config/riscv/muldi3.S --new file mode 100644 --index 00000000000..eb3d9b0df3d ----- /dev/null --+++ gcc-6.3.0/libgcc/config/riscv/muldi3.S --@@ -0,0 +1,46 @@ --+/* Integer multiplication routines for RISC-V. --+ --+ Copyright (C) 2016-2017 Free Software Foundation, Inc. --+ --+This file is part of GCC. --+ --+GCC is free software; you can redistribute it and/or modify it under --+the terms of the GNU General Public License as published by the Free --+Software Foundation; either version 3, or (at your option) any later --+version. --+ --+GCC is distributed in the hope that it will be useful, but WITHOUT ANY --+WARRANTY; without even the implied warranty of MERCHANTABILITY or --+FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License --+for more details. --+ --+Under Section 7 of GPL version 3, you are granted additional --+permissions described in the GCC Runtime Library Exception, version --+3.1, as published by the Free Software Foundation. --+ --+You should have received a copy of the GNU General Public License and --+a copy of the GCC Runtime Library Exception along with this program; --+see the files COPYING3 and COPYING.RUNTIME respectively. If not, see --+. */ --+ --+ .text --+ .align 2 --+ --+#if __riscv_xlen == 32 --+/* Our RV64 64-bit routine is equivalent to our RV32 32-bit routine. */ --+# define __muldi3 __mulsi3 --+#endif --+ --+ .globl __muldi3 --+__muldi3: --+ mv a2, a0 --+ li a0, 0 --+.L1: --+ andi a3, a1, 1 --+ beqz a3, .L2 --+ add a0, a0, a2 --+.L2: --+ srli a1, a1, 1 --+ slli a2, a2, 1 --+ bnez a1, .L1 --+ ret --diff --git original-gcc/libgcc/config/riscv/multi3.S gcc-6.3.0/libgcc/config/riscv/multi3.S --new file mode 100644 --index 00000000000..4d454e65013 ----- /dev/null --+++ gcc-6.3.0/libgcc/config/riscv/multi3.S --@@ -0,0 +1,81 @@ --+/* Integer multiplication routines for RISC-V. --+ --+ Copyright (C) 2016-2017 Free Software Foundation, Inc. --+ --+This file is part of GCC. --+ --+GCC is free software; you can redistribute it and/or modify it under --+the terms of the GNU General Public License as published by the Free --+Software Foundation; either version 3, or (at your option) any later --+version. --+ --+GCC is distributed in the hope that it will be useful, but WITHOUT ANY --+WARRANTY; without even the implied warranty of MERCHANTABILITY or --+FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License --+for more details. --+ --+Under Section 7 of GPL version 3, you are granted additional --+permissions described in the GCC Runtime Library Exception, version --+3.1, as published by the Free Software Foundation. --+ --+You should have received a copy of the GNU General Public License and --+a copy of the GCC Runtime Library Exception along with this program; --+see the files COPYING3 and COPYING.RUNTIME respectively. If not, see --+. */ --+ --+ .text --+ .align 2 --+ --+#if __riscv_xlen == 32 --+/* Our RV64 64-bit routines are equivalent to our RV32 32-bit routines. */ --+# define __multi3 __muldi3 --+#endif --+ --+ .globl __multi3 --+__multi3: --+ --+#if __riscv_xlen == 32 --+/* Our RV64 64-bit routines are equivalent to our RV32 32-bit routines. */ --+# define __muldi3 __mulsi3 --+#endif --+ --+/* We rely on the fact that __muldi3 doesn't clobber the t-registers. */ --+ --+ mv t0, ra --+ mv t5, a0 --+ mv a0, a1 --+ mv t6, a3 --+ mv a1, t5 --+ mv a4, a2 --+ li a5, 0 --+ li t2, 0 --+ li t4, 0 --+.L1: --+ add a6, t2, a1 --+ andi t3, a4, 1 --+ slli a7, a5, 1 --+ slti t1, a1, 0 --+ srli a4, a4, 1 --+ add a5, t4, a5 --+ beqz t3, .L2 --+ sltu t3, a6, t2 --+ mv t2, a6 --+ add t4, t3, a5 --+.L2: --+ slli a1, a1, 1 --+ or a5, t1, a7 --+ bnez a4, .L1 --+ beqz a0, .L3 --+ mv a1, a2 --+ call __muldi3 --+ add t4, t4, a0 --+.L3: --+ beqz t6, .L4 --+ mv a1, t6 --+ mv a0, t5 --+ call __muldi3 --+ add t4, t4, a0 --+.L4: --+ mv a0, t2 --+ mv a1, t4 --+ jr t0 --diff --git original-gcc/libgcc/config/riscv/save-restore.S gcc-6.3.0/libgcc/config/riscv/save-restore.S --new file mode 100644 --index 00000000000..2073a73089b ----- /dev/null --+++ gcc-6.3.0/libgcc/config/riscv/save-restore.S --@@ -0,0 +1,463 @@ --+/* Callee-saved register spill and fill routines for RISC-V. --+ --+ Copyright (C) 2016-2017 Free Software Foundation, Inc. --+ --+This file is part of GCC. --+ --+GCC is free software; you can redistribute it and/or modify it under --+the terms of the GNU General Public License as published by the Free --+Software Foundation; either version 3, or (at your option) any later --+version. --+ --+GCC is distributed in the hope that it will be useful, but WITHOUT ANY --+WARRANTY; without even the implied warranty of MERCHANTABILITY or --+FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License --+for more details. --+ --+Under Section 7 of GPL version 3, you are granted additional --+permissions described in the GCC Runtime Library Exception, version --+3.1, as published by the Free Software Foundation. --+ --+You should have received a copy of the GNU General Public License and --+a copy of the GCC Runtime Library Exception along with this program; --+see the files COPYING3 and COPYING.RUNTIME respectively. If not, see --+. */ --+ --+ .text --+ --+ .globl __riscv_save_12 --+ .globl __riscv_save_11 --+ .globl __riscv_save_10 --+ .globl __riscv_save_9 --+ .globl __riscv_save_8 --+ .globl __riscv_save_7 --+ .globl __riscv_save_6 --+ .globl __riscv_save_5 --+ .globl __riscv_save_4 --+ .globl __riscv_save_3 --+ .globl __riscv_save_2 --+ .globl __riscv_save_1 --+ .globl __riscv_save_0 --+ --+ .globl __riscv_restore_12 --+ .globl __riscv_restore_11 --+ .globl __riscv_restore_10 --+ .globl __riscv_restore_9 --+ .globl __riscv_restore_8 --+ .globl __riscv_restore_7 --+ .globl __riscv_restore_6 --+ .globl __riscv_restore_5 --+ .globl __riscv_restore_4 --+ .globl __riscv_restore_3 --+ .globl __riscv_restore_2 --+ .globl __riscv_restore_1 --+ .globl __riscv_restore_0 --+ --+#if __riscv_xlen == 64 --+ --+__riscv_save_12: --+ .cfi_startproc --+ # __riscv_save_* routine use t0/x5 as return address --+ .cfi_return_column 5 --+ addi sp, sp, -112 --+ .cfi_def_cfa_offset 112 --+ li t1, 0 --+ sd s11, 8(sp) --+ .cfi_offset 27, -104 --+ j .Ls10 --+ --+__riscv_save_11: --+__riscv_save_10: --+ .cfi_restore 27 --+ addi sp, sp, -112 --+ .cfi_def_cfa_offset 112 --+ li t1, -16 --+.Ls10: --+ sd s10, 16(sp) --+ .cfi_offset 26, -96 --+ sd s9, 24(sp) --+ .cfi_offset 25, -88 --+ j .Ls8 --+ --+__riscv_save_9: --+__riscv_save_8: --+ .cfi_restore 25 --+ .cfi_restore 26 --+ .cfi_restore 27 --+ addi sp, sp, -112 --+ .cfi_def_cfa_offset 112 --+ li t1, -32 --+.Ls8: --+ sd s8, 32(sp) --+ .cfi_offset 24, -80 --+ sd s7, 40(sp) --+ .cfi_offset 23, -72 --+ j .Ls6 --+ --+__riscv_save_7: --+__riscv_save_6: --+ .cfi_restore 23 --+ .cfi_restore 24 --+ .cfi_restore 25 --+ .cfi_restore 26 --+ .cfi_restore 27 --+ addi sp, sp, -112 --+ .cfi_def_cfa_offset 112 --+ li t1, -48 --+.Ls6: --+ sd s6, 48(sp) --+ .cfi_offset 22, -64 --+ sd s5, 56(sp) --+ .cfi_offset 21, -56 --+ j .Ls4 --+ --+__riscv_save_5: --+__riscv_save_4: --+ .cfi_restore 21 --+ .cfi_restore 22 --+ .cfi_restore 24 --+ .cfi_restore 25 --+ .cfi_restore 26 --+ .cfi_restore 27 --+ .cfi_restore 24 --+ .cfi_restore 25 --+ .cfi_restore 26 --+ .cfi_restore 27 --+ addi sp, sp, -112 --+ .cfi_def_cfa_offset 112 --+ li t1, -64 --+.Ls4: --+ sd s4, 64(sp) --+ .cfi_offset 20, -48 --+ sd s3, 72(sp) --+ .cfi_offset 19, -40 --+ j .Ls2 --+ --+__riscv_save_3: --+__riscv_save_2: --+ .cfi_restore 19 --+ .cfi_restore 20 --+ .cfi_restore 21 --+ .cfi_restore 22 --+ .cfi_restore 24 --+ .cfi_restore 25 --+ .cfi_restore 26 --+ .cfi_restore 27 --+ .cfi_restore 24 --+ .cfi_restore 25 --+ .cfi_restore 26 --+ .cfi_restore 27 --+ addi sp, sp, -112 --+ .cfi_def_cfa_offset 112 --+ li t1, -80 --+.Ls2: --+ sd s2, 80(sp) --+ .cfi_offset 18, -32 --+ sd s1, 88(sp) --+ .cfi_offset 9, -24 --+ sd s0, 96(sp) --+ .cfi_offset 8, -16 --+ sd ra, 104(sp) --+ .cfi_offset 1, -8 --+ # CFA info is not correct in next 2 instruction since t1's --+ # value is depend on how may register really save. --+ sub sp, sp, t1 --+ jr t0 --+ .cfi_endproc --+ --+__riscv_save_1: --+__riscv_save_0: --+ .cfi_startproc --+ # __riscv_save_* routine use t0/x5 as return address --+ .cfi_return_column 5 --+ addi sp, sp, -16 --+ .cfi_def_cfa_offset 16 --+ sd s0, 0(sp) --+ .cfi_offset 8, -16 --+ sd ra, 8(sp) --+ .cfi_offset 1, -8 --+ jr t0 --+ .cfi_endproc --+ --+__riscv_restore_12: --+ .cfi_startproc --+ .cfi_def_cfa_offset 112 --+ .cfi_offset 27, -104 --+ .cfi_offset 26, -96 --+ .cfi_offset 25, -88 --+ .cfi_offset 24, -80 --+ .cfi_offset 23, -72 --+ .cfi_offset 22, -64 --+ .cfi_offset 21, -56 --+ .cfi_offset 20, -48 --+ .cfi_offset 19, -40 --+ .cfi_offset 18, -32 --+ .cfi_offset 9, -24 --+ .cfi_offset 8, -16 --+ .cfi_offset 1, -8 --+ ld s11, 8(sp) --+ .cfi_restore 27 --+ addi sp, sp, 16 --+ --+__riscv_restore_11: --+__riscv_restore_10: --+ .cfi_restore 27 --+ .cfi_def_cfa_offset 96 --+ ld s10, 0(sp) --+ .cfi_restore 26 --+ ld s9, 8(sp) --+ .cfi_restore 25 --+ addi sp, sp, 16 --+ --+__riscv_restore_9: --+__riscv_restore_8: --+ .cfi_restore 25 --+ .cfi_restore 26 --+ .cfi_restore 27 --+ .cfi_def_cfa_offset 80 --+ ld s8, 0(sp) --+ .cfi_restore 24 --+ ld s7, 8(sp) --+ .cfi_restore 23 --+ addi sp, sp, 16 --+ --+__riscv_restore_7: --+__riscv_restore_6: --+ .cfi_restore 23 --+ .cfi_restore 24 --+ .cfi_restore 25 --+ .cfi_restore 26 --+ .cfi_restore 27 --+ .cfi_def_cfa_offset 64 --+ ld s6, 0(sp) --+ .cfi_restore 22 --+ ld s5, 8(sp) --+ .cfi_restore 21 --+ addi sp, sp, 16 --+ --+__riscv_restore_5: --+__riscv_restore_4: --+ .cfi_restore 21 --+ .cfi_restore 22 --+ .cfi_restore 23 --+ .cfi_restore 24 --+ .cfi_restore 25 --+ .cfi_restore 26 --+ .cfi_restore 27 --+ .cfi_def_cfa_offset 48 --+ ld s4, 0(sp) --+ .cfi_restore 20 --+ ld s3, 8(sp) --+ .cfi_restore 19 --+ addi sp, sp, 16 --+ --+__riscv_restore_3: --+__riscv_restore_2: --+ .cfi_restore 19 --+ .cfi_restore 20 --+ .cfi_restore 21 --+ .cfi_restore 22 --+ .cfi_restore 23 --+ .cfi_restore 24 --+ .cfi_restore 25 --+ .cfi_restore 26 --+ .cfi_restore 27 --+ .cfi_def_cfa_offset 32 --+ ld s2, 0(sp) --+ .cfi_restore 18 --+ ld s1, 8(sp) --+ .cfi_restore 9 --+ addi sp, sp, 16 --+ --+__riscv_restore_1: --+__riscv_restore_0: --+ .cfi_restore 9 --+ .cfi_restore 18 --+ .cfi_restore 19 --+ .cfi_restore 20 --+ .cfi_restore 21 --+ .cfi_restore 22 --+ .cfi_restore 23 --+ .cfi_restore 24 --+ .cfi_restore 25 --+ .cfi_restore 26 --+ .cfi_restore 27 --+ .cfi_def_cfa_offset 16 --+ ld s0, 0(sp) --+ .cfi_restore 8 --+ ld ra, 8(sp) --+ .cfi_restore 1 --+ addi sp, sp, 16 --+ .cfi_def_cfa_offset 0 --+ ret --+ .cfi_endproc --+ --+#else --+ --+__riscv_save_12: --+ .cfi_startproc --+ # __riscv_save_* routine use t0/x5 as return address --+ .cfi_return_column 5 --+ addi sp, sp, -64 --+ .cfi_def_cfa_offset 64 --+ li t1, 0 --+ sw s11, 12(sp) --+ .cfi_offset 27, -52 --+ j .Ls10 --+ --+__riscv_save_11: --+__riscv_save_10: --+__riscv_save_9: --+__riscv_save_8: --+ .cfi_restore 27 --+ addi sp, sp, -64 --+ .cfi_def_cfa_offset 64 --+ li t1, -16 --+.Ls10: --+ sw s10, 16(sp) --+ .cfi_offset 26, -48 --+ sw s9, 20(sp) --+ .cfi_offset 25, -44 --+ sw s8, 24(sp) --+ .cfi_offset 24, -40 --+ sw s7, 28(sp) --+ .cfi_offset 23, -36 --+ j .Ls6 --+ --+__riscv_save_7: --+__riscv_save_6: --+__riscv_save_5: --+__riscv_save_4: --+ .cfi_restore 23 --+ .cfi_restore 24 --+ .cfi_restore 25 --+ .cfi_restore 26 --+ .cfi_restore 27 --+ addi sp, sp, -64 --+ .cfi_def_cfa_offset 64 --+ li t1, -32 --+.Ls6: --+ sw s6, 32(sp) --+ .cfi_offset 22, -32 --+ sw s5, 36(sp) --+ .cfi_offset 21, -28 --+ sw s4, 40(sp) --+ .cfi_offset 20, -24 --+ sw s3, 44(sp) --+ .cfi_offset 19, -20 --+ sw s2, 48(sp) --+ .cfi_offset 18, -16 --+ sw s1, 52(sp) --+ .cfi_offset 9, -12 --+ sw s0, 56(sp) --+ .cfi_offset 8, -8 --+ sw ra, 60(sp) --+ .cfi_offset 1, -4 --+ # CFA info is not correct in next 2 instruction since t1's --+ # value is depend on how may register really save. --+ sub sp, sp, t1 --+ jr t0 --+ .cfi_endproc --+ --+__riscv_save_3: --+__riscv_save_2: --+__riscv_save_1: --+__riscv_save_0: --+ .cfi_startproc --+ # __riscv_save_* routine use t0/x5 as return address --+ .cfi_return_column 5 --+ addi sp, sp, -16 --+ .cfi_def_cfa_offset 16 --+ sw s2, 0(sp) --+ sw s1, 4(sp) --+ .cfi_offset 9, -16 --+ sw s0, 8(sp) --+ .cfi_offset 8, -8 --+ sw ra, 12(sp) --+ .cfi_offset 1, -4 --+ jr t0 --+ .cfi_endproc --+ --+__riscv_restore_12: --+ .cfi_startproc --+ .cfi_def_cfa_offset 64 --+ .cfi_offset 27, -52 --+ .cfi_offset 26, -48 --+ .cfi_offset 25, -44 --+ .cfi_offset 24, -40 --+ .cfi_offset 23, -36 --+ .cfi_offset 22, -32 --+ .cfi_offset 21, -28 --+ .cfi_offset 20, -24 --+ .cfi_offset 19, -20 --+ .cfi_offset 18, -16 --+ .cfi_offset 9, -12 --+ .cfi_offset 8, -8 --+ .cfi_offset 1, -4 --+ lw s11, 12(sp) --+ .cfi_restore 27 --+ addi sp, sp, 16 --+ --+__riscv_restore_11: --+__riscv_restore_10: --+__riscv_restore_9: --+__riscv_restore_8: --+ .cfi_restore 27 --+ .cfi_def_cfa_offset 48 --+ lw s10, 0(sp) --+ .cfi_restore 26 --+ lw s9, 4(sp) --+ .cfi_restore 25 --+ lw s8, 8(sp) --+ .cfi_restore 24 --+ lw s7, 12(sp) --+ .cfi_restore 23 --+ addi sp, sp, 16 --+ --+__riscv_restore_7: --+__riscv_restore_6: --+__riscv_restore_5: --+__riscv_restore_4: --+ .cfi_restore 23 --+ .cfi_restore 24 --+ .cfi_restore 25 --+ .cfi_restore 26 --+ .cfi_restore 27 --+ .cfi_def_cfa_offset 32 --+ lw s6, 0(sp) --+ .cfi_restore 22 --+ lw s5, 4(sp) --+ .cfi_restore 21 --+ lw s4, 8(sp) --+ .cfi_restore 20 --+ lw s3, 12(sp) --+ .cfi_restore 19 --+ addi sp, sp, 16 --+ --+__riscv_restore_3: --+__riscv_restore_2: --+__riscv_restore_1: --+__riscv_restore_0: --+ .cfi_restore 19 --+ .cfi_restore 20 --+ .cfi_restore 21 --+ .cfi_restore 22 --+ .cfi_restore 24 --+ .cfi_restore 25 --+ .cfi_restore 26 --+ .cfi_restore 27 --+ .cfi_def_cfa_offset 16 --+ lw s2, 0(sp) --+ .cfi_restore 18 --+ lw s1, 4(sp) --+ .cfi_restore 9 --+ lw s0, 8(sp) --+ .cfi_restore 8 --+ lw ra, 12(sp) --+ .cfi_restore 1 --+ addi sp, sp, 16 --+ .cfi_def_cfa_offset 0 --+ ret --+ .cfi_endproc --+ --+#endif --diff --git original-gcc/libgcc/config/riscv/sfp-machine.h gcc-6.3.0/libgcc/config/riscv/sfp-machine.h --new file mode 100644 --index 00000000000..b1a27e7ed44 ----- /dev/null --+++ gcc-6.3.0/libgcc/config/riscv/sfp-machine.h --@@ -0,0 +1,137 @@ --+/* Software floating-point machine description for RISC-V. --+ --+ Copyright (C) 2016-2017 Free Software Foundation, Inc. --+ --+This file is part of GCC. --+ --+GCC is free software; you can redistribute it and/or modify it under --+the terms of the GNU General Public License as published by the Free --+Software Foundation; either version 3, or (at your option) any later --+version. --+ --+GCC is distributed in the hope that it will be useful, but WITHOUT ANY --+WARRANTY; without even the implied warranty of MERCHANTABILITY or --+FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License --+for more details. --+ --+Under Section 7 of GPL version 3, you are granted additional --+permissions described in the GCC Runtime Library Exception, version --+3.1, as published by the Free Software Foundation. --+ --+You should have received a copy of the GNU General Public License and --+a copy of the GCC Runtime Library Exception along with this program; --+see the files COPYING3 and COPYING.RUNTIME respectively. If not, see --+. */ --+ --+#if __riscv_xlen == 32 --+ --+#define _FP_W_TYPE_SIZE 32 --+#define _FP_W_TYPE unsigned long --+#define _FP_WS_TYPE signed long --+#define _FP_I_TYPE long --+ --+#define _FP_MUL_MEAT_S(R,X,Y) \ --+ _FP_MUL_MEAT_1_wide(_FP_WFRACBITS_S,R,X,Y,umul_ppmm) --+#define _FP_MUL_MEAT_D(R,X,Y) \ --+ _FP_MUL_MEAT_2_wide(_FP_WFRACBITS_D,R,X,Y,umul_ppmm) --+#define _FP_MUL_MEAT_Q(R,X,Y) \ --+ _FP_MUL_MEAT_4_wide(_FP_WFRACBITS_Q,R,X,Y,umul_ppmm) --+ --+#define _FP_DIV_MEAT_S(R,X,Y) _FP_DIV_MEAT_1_udiv_norm(S,R,X,Y) --+#define _FP_DIV_MEAT_D(R,X,Y) _FP_DIV_MEAT_2_udiv(D,R,X,Y) --+#define _FP_DIV_MEAT_Q(R,X,Y) _FP_DIV_MEAT_4_udiv(Q,R,X,Y) --+ --+#define _FP_NANFRAC_S _FP_QNANBIT_S --+#define _FP_NANFRAC_D _FP_QNANBIT_D, 0 --+#define _FP_NANFRAC_Q _FP_QNANBIT_Q, 0, 0, 0 --+ --+#else --+ --+#define _FP_W_TYPE_SIZE 64 --+#define _FP_W_TYPE unsigned long long --+#define _FP_WS_TYPE signed long long --+#define _FP_I_TYPE long long --+ --+#define _FP_MUL_MEAT_S(R,X,Y) \ --+ _FP_MUL_MEAT_1_imm(_FP_WFRACBITS_S,R,X,Y) --+#define _FP_MUL_MEAT_D(R,X,Y) \ --+ _FP_MUL_MEAT_1_wide(_FP_WFRACBITS_D,R,X,Y,umul_ppmm) --+#define _FP_MUL_MEAT_Q(R,X,Y) \ --+ _FP_MUL_MEAT_2_wide_3mul(_FP_WFRACBITS_Q,R,X,Y,umul_ppmm) --+ --+#define _FP_DIV_MEAT_S(R,X,Y) _FP_DIV_MEAT_1_imm(S,R,X,Y,_FP_DIV_HELP_imm) --+#define _FP_DIV_MEAT_D(R,X,Y) _FP_DIV_MEAT_1_udiv_norm(D,R,X,Y) --+#define _FP_DIV_MEAT_Q(R,X,Y) _FP_DIV_MEAT_2_udiv(Q,R,X,Y) --+ --+#define _FP_NANFRAC_S _FP_QNANBIT_S --+#define _FP_NANFRAC_D _FP_QNANBIT_D --+#define _FP_NANFRAC_Q _FP_QNANBIT_Q, 0 --+ --+#endif --+ --+#if __riscv_xlen == 64 --+typedef int TItype __attribute__ ((mode (TI))); --+typedef unsigned int UTItype __attribute__ ((mode (TI))); --+#define TI_BITS (__CHAR_BIT__ * (int)sizeof(TItype)) --+#endif --+ --+/* The type of the result of a floating point comparison. This must --+ match __libgcc_cmp_return__ in GCC for the target. */ --+typedef int __gcc_CMPtype __attribute__ ((mode (__libgcc_cmp_return__))); --+#define CMPtype __gcc_CMPtype --+ --+#define _FP_NANSIGN_S 0 --+#define _FP_NANSIGN_D 0 --+#define _FP_NANSIGN_Q 0 --+ --+#define _FP_KEEPNANFRACP 0 --+#define _FP_QNANNEGATEDP 0 --+ --+#define _FP_CHOOSENAN(fs, wc, R, X, Y, OP) \ --+ do { \ --+ R##_s = _FP_NANSIGN_##fs; \ --+ _FP_FRAC_SET_##wc(R,_FP_NANFRAC_##fs); \ --+ R##_c = FP_CLS_NAN; \ --+ } while (0) --+ --+#define _FP_DECL_EX int _frm __attribute__ ((unused)); --+#define FP_ROUNDMODE _frm --+ --+#define FP_RND_NEAREST 0x0 --+#define FP_RND_ZERO 0x1 --+#define FP_RND_PINF 0x3 --+#define FP_RND_MINF 0x2 --+ --+#define FP_EX_INVALID 0x10 --+#define FP_EX_OVERFLOW 0x04 --+#define FP_EX_UNDERFLOW 0x02 --+#define FP_EX_DIVZERO 0x08 --+#define FP_EX_INEXACT 0x01 --+ --+#define _FP_TININESS_AFTER_ROUNDING 1 --+ --+#ifdef __riscv_flen --+#define FP_INIT_ROUNDMODE \ --+do { \ --+ __asm__ volatile ("frrm %0" : "=r" (_frm)); \ --+} while (0) --+ --+#define FP_HANDLE_EXCEPTIONS \ --+do { \ --+ if (__builtin_expect (_fex, 0)) \ --+ __asm__ volatile ("csrs fflags, %0" : : "rK" (_fex)); \ --+} while (0) --+#else --+#define FP_INIT_ROUNDMODE _frm = FP_RND_NEAREST --+#endif --+ --+#define __LITTLE_ENDIAN 1234 --+#define __BIG_ENDIAN 4321 --+ --+#define __BYTE_ORDER __LITTLE_ENDIAN --+ --+ --+/* Define ALIASNAME as a strong alias for NAME. */ --+# define strong_alias(name, aliasname) _strong_alias(name, aliasname) --+# define _strong_alias(name, aliasname) \ --+ extern __typeof (name) aliasname __attribute__ ((alias (#name))); --diff --git original-gcc/libgcc/config/riscv/t-elf gcc-6.3.0/libgcc/config/riscv/t-elf --new file mode 100644 --index 00000000000..01d5ebaa417 ----- /dev/null --+++ gcc-6.3.0/libgcc/config/riscv/t-elf --@@ -0,0 +1,6 @@ --+LIB2ADD += $(srcdir)/config/riscv/save-restore.S \ --+ $(srcdir)/config/riscv/muldi3.S \ --+ $(srcdir)/config/riscv/multi3.S \ --+ $(srcdir)/config/riscv/div.S \ --+ $(srcdir)/config/riscv/atomic.c \ --+ --diff --git original-gcc/libgcc/config/riscv/t-elf32 gcc-6.3.0/libgcc/config/riscv/t-elf32 --new file mode 100644 --index 00000000000..f3751234d55 ----- /dev/null --+++ gcc-6.3.0/libgcc/config/riscv/t-elf32 --@@ -0,0 +1 @@ --+LIB2FUNCS_EXCLUDE += _divsi3 _modsi3 _udivsi3 _umodsi3 _mulsi3 _muldi3 --diff --git original-gcc/libgcc/config/riscv/t-elf64 gcc-6.3.0/libgcc/config/riscv/t-elf64 --new file mode 100644 --index 00000000000..f3751234d55 ----- /dev/null --+++ gcc-6.3.0/libgcc/config/riscv/t-elf64 --@@ -0,0 +1 @@ --+LIB2FUNCS_EXCLUDE += _divsi3 _modsi3 _udivsi3 _umodsi3 _mulsi3 _muldi3 --diff --git original-gcc/libgcc/config/riscv/t-softfp32 gcc-6.3.0/libgcc/config/riscv/t-softfp32 --new file mode 100644 --index 00000000000..1bd51e803d1 ----- /dev/null --+++ gcc-6.3.0/libgcc/config/riscv/t-softfp32 --@@ -0,0 +1,26 @@ --+ABI_SINGLE:=$(findstring __riscv_float_abi_single,$(shell $(gcc_compile_bare) -dM -E - 3) -++ { -++ error_at (loc, "for the option -misr-secure=X, the valid X " -++ "must be: 0, 1, 2, or 3"); -++ return false; -++ } -++ return true; -++ -+ case OPT_mcache_block_size_: -+ /* Check valid value: 4 8 16 32 64 128 256 512. */ -+ if (exact_log2 (value) < 2 || exact_log2 (value) > 9) -+@@ -74,12 +84,19 @@ nds32_handle_option (struct gcc_options *opts ATTRIBUTE_UNUSED, -+ /* Implement TARGET_OPTION_OPTIMIZATION_TABLE. */ -+ static const struct default_options nds32_option_optimization_table[] = -+ { -++#if TARGET_LINUX_ABI == 0 -++ /* Disable -fdelete-null-pointer-checks by default in ELF toolchain. */ -++ { OPT_LEVELS_ALL, OPT_fdelete_null_pointer_checks, -++ NULL, 0 }, -++#endif -+ /* Enable -fsched-pressure by default at -O1 and above. */ -+ { OPT_LEVELS_1_PLUS, OPT_fsched_pressure, NULL, 1 }, -+ /* Enable -fomit-frame-pointer by default at all optimization levels. */ -+ { OPT_LEVELS_ALL, OPT_fomit_frame_pointer, NULL, 1 }, -+ /* Enable -mrelax-hint by default at all optimization levels. */ -+ { OPT_LEVELS_ALL, OPT_mrelax_hint, NULL, 1 }, -++ /* Enalbe -malways-align by default at -O1 and above, but not -Os or -Og. */ -++ { OPT_LEVELS_1_PLUS_SPEED_ONLY, OPT_malways_align, NULL, 1 }, -+ /* Enable -mv3push by default at -Os, but it is useless under V2 ISA. */ -+ { OPT_LEVELS_SIZE, OPT_mv3push, NULL, 1 }, -+ -+@@ -87,6 +104,19 @@ static const struct default_options nds32_option_optimization_table[] = -+ }; -+ -+ /* ------------------------------------------------------------------------ */ -++ -++/* Implement TARGET_EXCEPT_UNWIND_INFO. */ -++static enum unwind_info_type -++nds32_except_unwind_info (struct gcc_options *opts ATTRIBUTE_UNUSED) -++{ -++ if (TARGET_LINUX_ABI) -++ return UI_DWARF2; -++ -++ return UI_SJLJ; -++} -++ -++/* ------------------------------------------------------------------------ */ -++ -+ -+ /* Run-time Target Specification. */ -+ -+@@ -103,6 +133,7 @@ static const struct default_options nds32_option_optimization_table[] = -+ TARGET_EXT_PERF : Generate performance extention instrcution. -+ TARGET_EXT_PERF2 : Generate performance extention version 2 instrcution. -+ TARGET_EXT_STRING : Generate string extention instrcution. -++ TARGET_HW_ABS : Generate hardware abs instruction. -+ TARGET_CMOV : Generate conditional move instruction. */ -+ #undef TARGET_DEFAULT_TARGET_FLAGS -+ #define TARGET_DEFAULT_TARGET_FLAGS \ -+@@ -113,6 +144,7 @@ static const struct default_options nds32_option_optimization_table[] = -+ | MASK_EXT_PERF \ -+ | MASK_EXT_PERF2 \ -+ | MASK_EXT_STRING \ -++ | MASK_HW_ABS \ -+ | MASK_CMOV) -+ -+ #undef TARGET_HANDLE_OPTION -+@@ -125,7 +157,7 @@ static const struct default_options nds32_option_optimization_table[] = -+ /* Defining the Output Assembler Language. */ -+ -+ #undef TARGET_EXCEPT_UNWIND_INFO -+-#define TARGET_EXCEPT_UNWIND_INFO sjlj_except_unwind_info -++#define TARGET_EXCEPT_UNWIND_INFO nds32_except_unwind_info -+ -+ /* ------------------------------------------------------------------------ */ -+ -+diff --git a/gcc/config.gcc b/gcc/config.gcc -+index e58494c1c17..5ccf9e4ec72 100644 -+--- a/gcc/config.gcc -++++ b/gcc/config.gcc -+@@ -444,7 +444,17 @@ mips*-*-*) -+ ;; -+ nds32*) -+ cpu_type=nds32 -+- extra_headers="nds32_intrinsic.h" -++ extra_headers="nds32_intrinsic.h nds32_isr.h nds32_init.inc" -++ case ${target} in -++ nds32*-*-linux*) -++ extra_options="${extra_options} nds32/nds32-linux.opt" -++ ;; -++ nds32*-*-elf*) -++ extra_options="${extra_options} nds32/nds32-elf.opt" -++ ;; -++ *) -++ ;; -++ esac -+ extra_objs="nds32-cost.o nds32-intrinsic.o nds32-isr.o nds32-md-auxiliary.o nds32-pipelines-auxiliary.o nds32-predicates.o nds32-memory-manipulation.o nds32-fp-as-gp.o nds32-relax-opt.o nds32-utils.o" -+ ;; -+ nios2-*-*) -+@@ -2332,17 +2342,36 @@ msp430*-*-*) -+ tmake_file="${tmake_file} msp430/t-msp430" -+ extra_gcc_objs="driver-msp430.o" -+ ;; -+-nds32le-*-*) -++nds32*-*-*) -+ target_cpu_default="0" -+ tm_defines="${tm_defines}" -+- tm_file="dbxelf.h elfos.h newlib-stdint.h ${tm_file} nds32/nds32_intrinsic.h" -+- tmake_file="nds32/t-nds32 nds32/t-mlibs" -+- ;; -+-nds32be-*-*) -+- target_cpu_default="0|MASK_BIG_ENDIAN" -+- tm_defines="${tm_defines} TARGET_BIG_ENDIAN_DEFAULT=1" -+- tm_file="dbxelf.h elfos.h newlib-stdint.h ${tm_file} nds32/nds32_intrinsic.h" -+- tmake_file="nds32/t-nds32 nds32/t-mlibs" -++ case ${target} in -++ nds32le*-*-*) -++ ;; -++ nds32be-*-*) -++ target_cpu_default="${target_cpu_default}|MASK_BIG_ENDIAN" -++ tm_defines="${tm_defines} TARGET_BIG_ENDIAN_DEFAULT=1" -++ ;; -++ esac -++ case ${target} in -++ nds32*-*-elf*) -++ tm_file="dbxelf.h elfos.h newlib-stdint.h ${tm_file} nds32/elf.h nds32/nds32_intrinsic.h" -++ tmake_file="nds32/t-nds32 nds32/t-elf" -++ ;; -++ nds32*-*-linux*) -++ tm_file="dbxelf.h elfos.h ${tm_file} gnu-user.h linux.h glibc-stdint.h nds32/linux.h nds32/nds32_intrinsic.h" -++ tmake_file="${tmake_file} nds32/t-nds32 nds32/t-linux" -++ ;; -++ esac -++ -++ # Handle --enable-default-relax setting. -++ if test x${enable_default_relax} = xyes; then -++ tm_defines="${tm_defines} TARGET_DEFAULT_RELAX=1" -++ fi -++ # Handle --with-ext-dsp -++ if test x${with_ext_dsp} = xyes; then -++ tm_defines="${tm_defines} TARGET_DEFAULT_EXT_DSP=1" -++ fi -+ ;; -+ nios2-*-*) -+ tm_file="elfos.h ${tm_file}" -+@@ -4315,11 +4344,11 @@ case "${target}" in -+ "") -+ with_cpu=n9 -+ ;; -+- n6 | n7 | n8 | e8 | s8 | n9) -++ n6 | n7 |n8 | e8 | s8 | n9 | n10 | d10 | n12 | n13 | n15) -+ # OK -+ ;; -+ *) -+- echo "Cannot accept --with-cpu=$with_cpu, available values are: n6 n7 n8 e8 s8 n9" 1>&2 -++ echo "Cannot accept --with-cpu=$with_cpu, available values are: n6 n7 n8 e8 s8 n9 n10 d10 n12 n13 n15" 1>&2 -+ exit 1 -+ ;; -+ esac -+@@ -4329,15 +4358,30 @@ case "${target}" in -+ "") -+ # the default library is newlib -+ with_nds32_lib=newlib -++ tm_defines="${tm_defines} TARGET_DEFAULT_CTOR_DTOR=1" -+ ;; -+ newlib) -+ # OK -++ tm_defines="${tm_defines} TARGET_DEFAULT_CTOR_DTOR=1" -+ ;; -+ mculib) -+ # OK -++ # for the arch=v3f or arch=v3s under mculib toolchain, -++ # we would like to set -fno-math-errno as default -++ case "${with_arch}" in -++ v3f | v3s) -++ tm_defines="${tm_defines} TARGET_DEFAULT_NO_MATH_ERRNO=1" -++ ;; -++ esac -++ ;; -++ glibc) -++ # OK -++ tm_defines="${tm_defines}" -++ ;; -++ uclibc) -+ ;; -+ *) -+- echo "Cannot accept --with-nds32-lib=$with_nds32_lib, available values are: newlib mculib" 1>&2 -++ echo "Cannot accept --with-nds32-lib=$with_nds32_lib, available values are: newlib mculib glibc uclibc" 1>&2 -+ exit 1 -+ ;; -+ esac -+diff --git a/gcc/config/nds32/constants.md b/gcc/config/nds32/constants.md -+index 37c27049ef0..6d42f50c882 100644 -+--- a/gcc/config/nds32/constants.md -++++ b/gcc/config/nds32/constants.md -+@@ -23,6 +23,7 @@ -+ (define_constants -+ [(R8_REGNUM 8) -+ (TA_REGNUM 15) -++ (TP_REGNUM 25) -+ (FP_REGNUM 28) -+ (GP_REGNUM 29) -+ (LP_REGNUM 30) -+@@ -49,6 +50,16 @@ -+ UNSPEC_FFB -+ UNSPEC_FFMISM -+ UNSPEC_FLMISM -++ UNSPEC_KDMBB -++ UNSPEC_KDMBT -++ UNSPEC_KDMTB -++ UNSPEC_KDMTT -++ UNSPEC_KHMBB -++ UNSPEC_KHMBT -++ UNSPEC_KHMTB -++ UNSPEC_KHMTT -++ UNSPEC_KSLRAW -++ UNSPEC_KSLRAWU -+ UNSPEC_SVA -+ UNSPEC_SVS -+ UNSPEC_WSBH -+@@ -62,6 +73,29 @@ -+ UNSPEC_UASTORE_HW -+ UNSPEC_UASTORE_W -+ UNSPEC_UASTORE_DW -++ UNSPEC_GOTINIT -++ UNSPEC_GOT -++ UNSPEC_GOTOFF -++ UNSPEC_PLT -++ UNSPEC_TLSGD -++ UNSPEC_TLSLD -++ UNSPEC_TLSIE -++ UNSPEC_TLSLE -++ UNSPEC_ROUND -++ UNSPEC_VEC_COMPARE -++ UNSPEC_KHM -++ UNSPEC_KHMX -++ UNSPEC_CLIP_OV -++ UNSPEC_CLIPS_OV -++ UNSPEC_BITREV -++ UNSPEC_KABS -++ UNSPEC_LOOP_END -++ UNSPEC_TLS_DESC -++ UNSPEC_TLS_IE -++ UNSPEC_ADD32 -++ UNSPEC_ICT -++ UNSPEC_KADDH -++ UNSPEC_KSUBH -+ ]) -+ -+ ;; The unspec_volatile operation index. -+@@ -135,10 +169,14 @@ -+ UNSPEC_VOLATILE_SET_TRIG_EDGE -+ UNSPEC_VOLATILE_GET_TRIG_TYPE -+ UNSPEC_VOLATILE_RELAX_GROUP -++ UNSPEC_VOLATILE_OMIT_FP_BEGIN -++ UNSPEC_VOLATILE_OMIT_FP_END -+ UNSPEC_VOLATILE_POP25_RETURN -+ UNSPEC_VOLATILE_UNALIGNED_FEATURE -+ UNSPEC_VOLATILE_ENABLE_UNALIGNED -+ UNSPEC_VOLATILE_DISABLE_UNALIGNED -++ UNSPEC_VOLATILE_RDOV -++ UNSPEC_VOLATILE_CLROV -+ ]) -+ -+ ;; ------------------------------------------------------------------------ -+diff --git a/gcc/config/nds32/constraints.md b/gcc/config/nds32/constraints.md -+index 7af7769fcbf..315c60313e5 100644 -+--- a/gcc/config/nds32/constraints.md -++++ b/gcc/config/nds32/constraints.md -+@@ -127,6 +127,11 @@ -+ (and (match_code "const_int") -+ (match_test "IN_RANGE (ival, -31, 0)"))) -+ -++(define_constraint "Iu06" -++ "Unsigned immediate 6-bit value" -++ (and (match_code "const_int") -++ (match_test "ival < (1 << 6) && ival >= 0"))) -++ -+ ;; Ip05 is special and dedicated for v3 movpi45 instruction. -+ ;; movpi45 has imm5u field but the range is 16 ~ 47. -+ (define_constraint "Ip05" -+@@ -136,10 +141,10 @@ -+ && ival >= (0 + 16) -+ && (TARGET_ISA_V3 || TARGET_ISA_V3M)"))) -+ -+-(define_constraint "Iu06" -++(define_constraint "IU06" -+ "Unsigned immediate 6-bit value constraint for addri36.sp instruction" -+ (and (match_code "const_int") -+- (match_test "ival < (1 << 6) -++ (match_test "ival < (1 << 8) -+ && ival >= 0 -+ && (ival % 4 == 0) -+ && (TARGET_ISA_V3 || TARGET_ISA_V3M)"))) -+@@ -302,6 +307,25 @@ -+ (match_test "(TARGET_ISA_V3 || TARGET_ISA_V3M) -+ && (IN_RANGE (exact_log2 (ival + 1), 1, 8))"))) -+ -++(define_constraint "CVp5" -++ "Unsigned immediate 5-bit value for movpi45 instruction with range 16-47" -++ (and (match_code "const_vector") -++ (match_test "nds32_valid_CVp5_p (op)"))) -++ -++(define_constraint "CVs5" -++ "Signed immediate 5-bit value" -++ (and (match_code "const_vector") -++ (match_test "nds32_valid_CVs5_p (op)"))) -++ -++(define_constraint "CVs2" -++ "Signed immediate 20-bit value" -++ (and (match_code "const_vector") -++ (match_test "nds32_valid_CVs2_p (op)"))) -++ -++(define_constraint "CVhi" -++ "The immediate value that can be simply set high 20-bit" -++ (and (match_code "const_vector") -++ (match_test "nds32_valid_CVhi_p (op)"))) -+ -+ (define_memory_constraint "U33" -+ "Memory constraint for 333 format" -+@@ -349,4 +373,9 @@ -+ (match_test "(TARGET_FPU_SINGLE || TARGET_FPU_DOUBLE) -+ && nds32_float_mem_operand_p (op)"))) -+ -++(define_constraint "S" -++ "@internal -++ A constant call address." -++ (match_operand 0 "nds32_symbolic_operand")) -++ -+ ;; ------------------------------------------------------------------------ -+diff --git a/gcc/config/nds32/elf.h b/gcc/config/nds32/elf.h -+new file mode 100644 -+index 00000000000..66397ac2e30 -+--- /dev/null -++++ b/gcc/config/nds32/elf.h -+@@ -0,0 +1,81 @@ -++/* Definitions of target machine of Andes NDS32 cpu for GNU compiler -++ Copyright (C) 2012-2014 Free Software Foundation, Inc. -++ Contributed by Andes Technology Corporation. -++ -++ This file is part of GCC. -++ -++ GCC is free software; you can redistribute it and/or modify it -++ under the terms of the GNU General Public License as published -++ by the Free Software Foundation; either version 3, or (at your -++ option) any later version. -++ -++ GCC is distributed in the hope that it will be useful, but WITHOUT -++ ANY WARRANTY; without even the implied warranty of MERCHANTABILITY -++ or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public -++ License for more details. -++ -++ You should have received a copy of the GNU General Public License -++ along with GCC; see the file COPYING3. If not see -++ . */ -++ -++ -++/* ------------------------------------------------------------------------ */ -++ -++#define TARGET_LINUX_ABI 0 -++ -++/* In the configure stage we may use options --enable-default-relax, -++ --enable-Os-default-ifc and --enable-Os-default-ex9. They effect -++ the default spec of passing --relax, --mifc, and --mex9 to linker. -++ We use NDS32_RELAX_SPEC, NDS32_IFC_SPEC, and NDS32_EX9_SPEC -++ so that we can customize them conveniently. */ -++#define LINK_SPEC \ -++ " %{G*}" \ -++ " %{mbig-endian:-EB} %{mlittle-endian:-EL}" \ -++ " %{shared:-shared}" \ -++ NDS32_RELAX_SPEC -++ -++#define LIB_SPEC \ -++ " -lc -lgloss" -++ -++#define LIBGCC_SPEC \ -++ " -lgcc" -++ -++/* The option -mno-ctor-dtor can disable constructor/destructor feature -++ by applying different crt stuff. In the convention, crt0.o is the -++ startup file without constructor/destructor; -++ crt1.o, crti.o, crtbegin.o, crtend.o, and crtn.o are the -++ startup files with constructor/destructor. -++ Note that crt0.o, crt1.o, crti.o, and crtn.o are provided -++ by newlib/mculib/glibc/ublic, while crtbegin.o and crtend.o are -++ currently provided by GCC for nds32 target. -++ -++ For nds32 target so far: -++ If -mno-ctor-dtor, we are going to link -++ "crt0.o [user objects]". -++ If -mctor-dtor, we are going to link -++ "crt1.o crtbegin1.o [user objects] crtend1.o". -++ -++ Note that the TARGET_DEFAULT_CTOR_DTOR would effect the -++ default behavior. Check gcc/config.gcc for more information. */ -++#ifdef TARGET_DEFAULT_CTOR_DTOR -++ #define STARTFILE_SPEC \ -++ " %{!mno-ctor-dtor:crt1.o%s;:crt0.o%s}" \ -++ " %{!mno-ctor-dtor:crtbegin1.o%s}" \ -++ " %{mcrt-arg:crtarg.o%s}" -++ #define ENDFILE_SPEC \ -++ " %{!mno-ctor-dtor:crtend1.o%s}" -++#else -++ #define STARTFILE_SPEC \ -++ " %{mctor-dtor|coverage:crt1.o%s;:crt0.o%s}" \ -++ " %{mctor-dtor|coverage:crtbegin1.o%s}" \ -++ " %{mcrt-arg:crtarg.o%s}" -++ #define ENDFILE_SPEC \ -++ " %{mctor-dtor|coverage:crtend1.o%s}" -++#endif -++ -++#define STARTFILE_CXX_SPEC \ -++ " %{!mno-ctor-dtor:crt1.o%s;:crt0.o%s}" \ -++ " %{!mno-ctor-dtor:crtbegin1.o%s}" \ -++ " %{mcrt-arg:crtarg.o%s}" -++#define ENDFILE_CXX_SPEC \ -++ " %{!mno-ctor-dtor:crtend1.o%s}" -+diff --git a/gcc/config/nds32/iterators.md b/gcc/config/nds32/iterators.md -+index c2062de2e97..f4fb58181b1 100644 -+--- a/gcc/config/nds32/iterators.md -++++ b/gcc/config/nds32/iterators.md -+@@ -68,6 +68,28 @@ -+ ;; shifts -+ (define_code_iterator shift_rotate [ashift ashiftrt lshiftrt rotatert]) -+ -++(define_code_iterator shifts [ashift ashiftrt lshiftrt]) -++ -++(define_code_iterator shiftrt [ashiftrt lshiftrt]) -++ -++(define_code_iterator sat_plus [ss_plus us_plus]) -++ -++(define_code_iterator all_plus [plus ss_plus us_plus]) -++ -++(define_code_iterator sat_minus [ss_minus us_minus]) -++ -++(define_code_iterator all_minus [minus ss_minus us_minus]) -++ -++(define_code_iterator plus_minus [plus minus]) -++ -++(define_code_iterator extend [sign_extend zero_extend]) -++ -++(define_code_iterator sumax [smax umax]) -++ -++(define_code_iterator sumin [smin umin]) -++ -++(define_code_iterator sumin_max [smax umax smin umin]) -++ -+ ;;---------------------------------------------------------------------------- -+ ;; Code attributes. -+ ;;---------------------------------------------------------------------------- -+@@ -76,5 +98,23 @@ -+ (define_code_attr shift -+ [(ashift "ashl") (ashiftrt "ashr") (lshiftrt "lshr") (rotatert "rotr")]) -+ -++(define_code_attr su -++ [(ashiftrt "") (lshiftrt "u") (sign_extend "s") (zero_extend "u")]) -++ -++(define_code_attr zs -++ [(sign_extend "s") (zero_extend "z")]) -++ -++(define_code_attr uk -++ [(plus "") (ss_plus "k") (us_plus "uk") -++ (minus "") (ss_minus "k") (us_minus "uk")]) -++ -++(define_code_attr opcode -++ [(plus "add") (minus "sub") (smax "smax") (umax "umax") (smin "smin") (umin "umin")]) -++ -++(define_code_attr add_rsub -++ [(plus "a") (minus "rs")]) -++ -++(define_code_attr add_sub -++ [(plus "a") (minus "s")]) -+ -+ ;;---------------------------------------------------------------------------- -+diff --git a/gcc/config/nds32/linux.h b/gcc/config/nds32/linux.h -+new file mode 100644 -+index 00000000000..f66f9076baf -+--- /dev/null -++++ b/gcc/config/nds32/linux.h -+@@ -0,0 +1,86 @@ -++/* Definitions of target machine of Andes NDS32 cpu for GNU compiler -++ Copyright (C) 2012-2014 Free Software Foundation, Inc. -++ Contributed by Andes Technology Corporation. -++ -++ This file is part of GCC. -++ -++ GCC is free software; you can redistribute it and/or modify it -++ under the terms of the GNU General Public License as published -++ by the Free Software Foundation; either version 3, or (at your -++ option) any later version. -++ -++ GCC is distributed in the hope that it will be useful, but WITHOUT -++ ANY WARRANTY; without even the implied warranty of MERCHANTABILITY -++ or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public -++ License for more details. -++ -++ You should have received a copy of the GNU General Public License -++ along with GCC; see the file COPYING3. If not see -++ . */ -++ -++ -++/* ------------------------------------------------------------------------ */ -++ -++#define TARGET_LINUX_ABI 1 -++ -++#undef SIZE_TYPE -++#define SIZE_TYPE "unsigned int" -++ -++#undef PTRDIFF_TYPE -++#define PTRDIFF_TYPE "int" -++ -++#define TARGET_OS_CPP_BUILTINS() \ -++ do \ -++ { \ -++ GNU_USER_TARGET_OS_CPP_BUILTINS(); \ -++ } \ -++ while (0) -++ -++#ifdef TARGET_BIG_ENDIAN_DEFAULT -++#define LD_SO_ENDIAN_SPEC "%{mlittle-endian:le}%{!mlittle-endian:be}" -++#else -++#define LD_SO_ENDIAN_SPEC "%{mbig-endian:be}%{!mbig-endian:le}" -++#endif -++ -++/* Record arch version in TARGET_ARCH_DEFAULT. 0 means soft ABI, -++ 1 means hard ABI and using full floating-point instruction, -++ 2 means hard ABI and only using single-precision floating-point -++ instruction */ -++#if TARGET_ARCH_DEFAULT -++#define LD_SO_ABI_SPEC "%{!mabi=2:f}" -++#else -++#define LD_SO_ABI_SPEC "%{mabi=2fp+:f}" -++#endif -++ -++#define GLIBC_DYNAMIC_LINKER \ -++ "/lib/ld-linux-nds32" LD_SO_ENDIAN_SPEC LD_SO_ABI_SPEC ".so.1" -++ -++/* In the configure stage we may use options --enable-default-relax, -++ --enable-Os-default-ifc and --enable-Os-default-ex9. They effect -++ the default spec of passing --relax, --mifc, and --mex9 to linker. -++ We use NDS32_RELAX_SPEC, NDS32_IFC_SPEC, and NDS32_EX9_SPEC -++ so that we can customize them conveniently. */ -++#define LINK_SPEC \ -++ " %{G*}" \ -++ " %{mbig-endian:-EB} %{mlittle-endian:-EL}" \ -++ " %{shared:-shared} \ -++ %{!shared: \ -++ %{!static: \ -++ %{rdynamic:-export-dynamic} \ -++ -dynamic-linker " GNU_USER_DYNAMIC_LINKER "} \ -++ %{static:-static}}" \ -++ NDS32_RELAX_SPEC -++ -++#define LINK_PIE_SPEC "%{pie:%{!fno-pie:%{!fno-PIE:%{!static:-pie}}}} " -++ -++#define CPP_SPEC "%{pthread:-D_REENTRANT}" -++ -++/* The SYNC operations are implemented as library functions, not -++ INSN patterns. As a result, the HAVE defines for the patterns are -++ not defined. We need to define them to generate the corresponding -++ __GCC_HAVE_SYNC_COMPARE_AND_SWAP_* and __GCC_ATOMIC_*_LOCK_FREE -++ defines. -++ Ref: https://sourceware.org/ml/libc-alpha/2014-09/msg00322.html */ -++#define HAVE_sync_compare_and_swapqi 1 -++#define HAVE_sync_compare_and_swaphi 1 -++#define HAVE_sync_compare_and_swapsi 1 -+diff --git a/gcc/config/nds32/nds32-cost.c b/gcc/config/nds32/nds32-cost.c -+index 8d01e8afee2..979000fcc45 100644 -+--- a/gcc/config/nds32/nds32-cost.c -++++ b/gcc/config/nds32/nds32-cost.c -+@@ -34,66 +34,379 @@ -+ #include "optabs.h" /* For GEN_FCN. */ -+ #include "recog.h" -+ #include "tm-constrs.h" -++#include "tree-pass.h" -+ -+ /* ------------------------------------------------------------------------ */ -+ -+-bool -+-nds32_rtx_costs_impl (rtx x, -+- machine_mode mode ATTRIBUTE_UNUSED, -+- int outer_code, -+- int opno ATTRIBUTE_UNUSED, -+- int *total, -+- bool speed) -+-{ -+- int code = GET_CODE (x); -++typedef bool (*rtx_cost_func) (rtx, int, int, int, int*); -+ -+- /* According to 'speed', goto suitable cost model section. */ -+- if (speed) -+- goto performance_cost; -+- else -+- goto size_cost; -++struct rtx_cost_model_t { -++ rtx_cost_func speed_prefer; -++ rtx_cost_func size_prefer; -++}; -+ -++static rtx_cost_model_t rtx_cost_model; -+ -+-performance_cost: -+- /* This is section for performance cost model. */ -++static int insn_size_16bit; /* Initial at nds32_init_rtx_costs. */ -++static const int insn_size_32bit = 4; -++ -++static bool -++nds32_rtx_costs_speed_prefer (rtx x ATTRIBUTE_UNUSED, -++ int code, -++ int outer_code ATTRIBUTE_UNUSED, -++ int opno ATTRIBUTE_UNUSED, -++ int *total) -++{ -++ rtx op0; -++ rtx op1; -++ machine_mode mode = GET_MODE (x); -++ /* Scale cost by mode size. */ -++ int cost = COSTS_N_INSNS (GET_MODE_SIZE (mode) / GET_MODE_SIZE (SImode)); -+ -+- /* In gcc/rtl.h, the default value of COSTS_N_INSNS(N) is N*4. -+- We treat it as 4-cycle cost for each instruction -+- under performance consideration. */ -+ switch (code) -+ { -+- case SET: -+- /* For 'SET' rtx, we need to return false -+- so that it can recursively calculate costs. */ -+- return false; -+- -+ case USE: -+ /* Used in combine.c as a marker. */ -+ *total = 0; -+- break; -++ return true; -++ -++ case CONST_INT: -++ /* When not optimizing for size, we care more about the cost -++ of hot code, and hot code is often in a loop. If a constant -++ operand needs to be forced into a register, we will often be -++ able to hoist the constant load out of the loop, so the load -++ should not contribute to the cost. */ -++ if (outer_code == SET || outer_code == PLUS) -++ *total = satisfies_constraint_Is20 (x) ? 0 : 4; -++ else if (outer_code == AND || outer_code == IOR || outer_code == XOR -++ || outer_code == MINUS) -++ *total = satisfies_constraint_Iu15 (x) ? 0 : 4; -++ else if (outer_code == ASHIFT || outer_code == ASHIFTRT -++ || outer_code == LSHIFTRT) -++ *total = satisfies_constraint_Iu05 (x) ? 0 : 4; -++ else if (GET_RTX_CLASS (outer_code) == RTX_COMPARE -++ || GET_RTX_CLASS (outer_code) == RTX_COMM_COMPARE) -++ *total = satisfies_constraint_Is16 (x) ? 0 : 4; -++ else -++ *total = COSTS_N_INSNS (1); -++ return true; -++ -++ case CONST: -++ case LO_SUM: -++ case HIGH: -++ case SYMBOL_REF: -++ *total = COSTS_N_INSNS (1); -++ return true; -++ -++ case MEM: -++ *total = COSTS_N_INSNS (1); -++ return true; -++ -++ case SET: -++ op0 = SET_DEST (x); -++ op1 = SET_SRC (x); -++ mode = GET_MODE (op0); -++ /* Scale cost by mode size. */ -++ cost = COSTS_N_INSNS (GET_MODE_SIZE (mode) / GET_MODE_SIZE (SImode)); -++ -++ switch (GET_CODE (op1)) -++ { -++ case REG: -++ case SUBREG: -++ /* Register move and Store instructions. */ -++ if ((REG_P (op0) || MEM_P (op0)) -++ && GET_MODE_SIZE (mode) <= GET_MODE_SIZE (DImode)) -++ *total = COSTS_N_INSNS (1); -++ else -++ *total = cost; -++ return true; -++ -++ case MEM: -++ /* Load instructions. */ -++ if (REG_P (op0) && GET_MODE_SIZE (mode) <= GET_MODE_SIZE (DImode)) -++ *total = COSTS_N_INSNS (1); -++ else -++ *total = cost; -++ return true; -++ -++ case CONST_INT: -++ /* movi instruction. */ -++ if (REG_P (op0) && GET_MODE_SIZE (mode) < GET_MODE_SIZE (DImode)) -++ { -++ if (satisfies_constraint_Is20 (op1)) -++ *total = COSTS_N_INSNS (1) - 1; -++ else -++ *total = COSTS_N_INSNS (2); -++ } -++ else -++ *total = cost; -++ return true; -++ -++ case CONST: -++ case SYMBOL_REF: -++ case LABEL_REF: -++ /* la instruction. */ -++ if (REG_P (op0) && GET_MODE_SIZE (mode) < GET_MODE_SIZE (DImode)) -++ *total = COSTS_N_INSNS (1) - 1; -++ else -++ *total = cost; -++ return true; -++ case VEC_SELECT: -++ *total = cost; -++ return true; -++ -++ default: -++ *total = cost; -++ return true; -++ } -++ -++ case PLUS: -++ op0 = XEXP (x, 0); -++ op1 = XEXP (x, 1); -++ -++ if (GET_MODE_SIZE (mode) >= GET_MODE_SIZE (DImode)) -++ *total = cost; -++ else if (GET_CODE (op0) == MULT || GET_CODE (op0) == LSHIFTRT -++ || GET_CODE (op1) == MULT || GET_CODE (op1) == LSHIFTRT) -++ /* ALU_SHIFT */ -++ *total = COSTS_N_INSNS (2); -++ -++ else if ((GET_CODE (op1) == CONST_INT -++ && satisfies_constraint_Is15 (op1)) -++ || REG_P (op1)) -++ /* ADD instructions */ -++ *total = COSTS_N_INSNS (1); -++ else -++ /* ADD instructions: IMM out of range. */ -++ *total = COSTS_N_INSNS (2); -++ return true; -++ -++ case MINUS: -++ op0 = XEXP (x, 0); -++ op1 = XEXP (x, 1); -++ -++ if (GET_MODE_SIZE (mode) >= GET_MODE_SIZE (DImode)) -++ *total = cost; -++ else if (GET_CODE (op0) == MULT || GET_CODE (op0) == LSHIFTRT -++ || GET_CODE (op1) == MULT || GET_CODE (op1) == LSHIFTRT) -++ /* ALU_SHIFT */ -++ *total = COSTS_N_INSNS (2); -++ else if ((GET_CODE (op0) == CONST_INT -++ && satisfies_constraint_Is15 (op0)) -++ || REG_P (op0)) -++ /* SUB instructions */ -++ *total = COSTS_N_INSNS (1); -++ else -++ /* SUB instructions: IMM out of range. */ -++ *total = COSTS_N_INSNS (2); -++ return true; -++ -++ case TRUNCATE: -++ /* TRUNCATE and AND behavior is same. */ -++ *total = COSTS_N_INSNS (1); -++ return true; -++ -++ case AND: -++ case IOR: -++ case XOR: -++ op0 = XEXP (x, 0); -++ op1 = XEXP (x, 1); -++ -++ if (NDS32_EXT_DSP_P ()) -++ { -++ /* We prefer (and (ior) (ior)) than (ior (and) (and)) for -++ synthetize pk** and insb instruction. */ -++ if (code == AND && GET_CODE (op0) == IOR && GET_CODE (op1) == IOR) -++ return COSTS_N_INSNS (1); -++ -++ if (code == IOR && GET_CODE (op0) == AND && GET_CODE (op1) == AND) -++ return COSTS_N_INSNS (10); -++ } -++ -++ if (GET_MODE_SIZE (mode) >= GET_MODE_SIZE (DImode)) -++ *total = cost; -++ else if (GET_CODE (op0) == ASHIFT || GET_CODE (op0) == LSHIFTRT) -++ *total = COSTS_N_INSNS (2); -++ else if ((GET_CODE (op1) == CONST_INT -++ && satisfies_constraint_Iu15 (op1)) -++ || REG_P (op1)) -++ /* AND, OR, XOR instructions */ -++ *total = COSTS_N_INSNS (1); -++ else if (code == AND || GET_CODE (op0) == NOT) -++ /* BITC instruction */ -++ *total = COSTS_N_INSNS (1); -++ else -++ /* AND, OR, XOR instructions: IMM out of range. */ -++ *total = COSTS_N_INSNS (2); -++ return true; -+ -+ case MULT: -++ if (GET_MODE (x) == DImode -++ || GET_CODE (XEXP (x, 1)) == SIGN_EXTEND -++ || GET_CODE (XEXP (x, 1)) == ZERO_EXTEND) -++ /* MUL instructions */ -++ *total = COSTS_N_INSNS (1); -++ else if (GET_MODE_SIZE (mode) >= GET_MODE_SIZE (DImode)) -++ *total = cost; -++ else if (outer_code == PLUS || outer_code == MINUS) -++ *total = COSTS_N_INSNS (2); -++ else if ((GET_CODE (XEXP (x, 1)) == CONST_INT -++ && satisfies_constraint_Iu05 (XEXP (x, 1))) -++ || REG_P (XEXP (x, 1))) -++ /* MUL instructions */ -++ *total = COSTS_N_INSNS (1); -++ else -++ /* MUL instructions: IMM out of range. */ -++ *total = COSTS_N_INSNS (2); -++ -++ if (TARGET_MUL_SLOW) -++ *total += COSTS_N_INSNS (4); -++ -++ return true; -++ -++ case LSHIFTRT: -++ if (GET_MODE_SIZE (mode) >= GET_MODE_SIZE (DImode)) -++ *total = cost; -++ else if (outer_code == PLUS || outer_code == MINUS -++ || outer_code == AND || outer_code == IOR -++ || outer_code == XOR) -++ *total = COSTS_N_INSNS (2); -++ else if ((GET_CODE (XEXP (x, 1)) == CONST_INT -++ && satisfies_constraint_Iu05 (XEXP (x, 1))) -++ || REG_P (XEXP (x, 1))) -++ /* SRL instructions */ -++ *total = COSTS_N_INSNS (1); -++ else -++ /* SRL instructions: IMM out of range. */ -++ *total = COSTS_N_INSNS (2); -++ return true; -++ -++ case ASHIFT: -++ if (GET_MODE_SIZE (mode) >= GET_MODE_SIZE (DImode)) -++ *total = cost; -++ else if (outer_code == AND || outer_code == IOR -++ || outer_code == XOR) -++ *total = COSTS_N_INSNS (2); -++ else if ((GET_CODE (XEXP (x, 1)) == CONST_INT -++ && satisfies_constraint_Iu05 (XEXP (x, 1))) -++ || REG_P (XEXP (x, 1))) -++ /* SLL instructions */ -++ *total = COSTS_N_INSNS (1); -++ else -++ /* SLL instructions: IMM out of range. */ -++ *total = COSTS_N_INSNS (2); -++ return true; -++ -++ case ASHIFTRT: -++ case ROTATERT: -++ if (GET_MODE_SIZE (mode) >= GET_MODE_SIZE (DImode)) -++ *total = cost; -++ else if ((GET_CODE (XEXP (x, 1)) == CONST_INT -++ && satisfies_constraint_Iu05 (XEXP (x, 1))) -++ || REG_P (XEXP (x, 1))) -++ /* ROTR, SLL instructions */ -++ *total = COSTS_N_INSNS (1); -++ else -++ /* ROTR, SLL instructions: IMM out of range. */ -++ *total = COSTS_N_INSNS (2); -++ return true; -++ -++ case LT: -++ case LTU: -++ if (outer_code == SET) -++ { -++ if ((GET_CODE (XEXP (x, 1)) == CONST_INT -++ && satisfies_constraint_Iu15 (XEXP (x, 1))) -++ || REG_P (XEXP (x, 1))) -++ /* SLT, SLTI instructions */ -++ *total = COSTS_N_INSNS (1); -++ else -++ /* SLT, SLT instructions: IMM out of range. */ -++ *total = COSTS_N_INSNS (2); -++ } -++ else -++ /* branch */ -++ *total = COSTS_N_INSNS (2); -++ return true; -++ -++ case EQ: -++ case NE: -++ case GE: -++ case LE: -++ case GT: -++ /* branch */ -++ *total = COSTS_N_INSNS (2); -++ return true; -++ -++ case IF_THEN_ELSE: -++ if (GET_CODE (XEXP (x, 1)) == LABEL_REF) -++ /* branch */ -++ *total = COSTS_N_INSNS (2); -++ else -++ /* cmovz, cmovn instructions */ -++ *total = COSTS_N_INSNS (1); -++ return true; -++ -++ case LABEL_REF: -++ if (outer_code == IF_THEN_ELSE) -++ /* branch */ -++ *total = COSTS_N_INSNS (2); -++ else -++ *total = COSTS_N_INSNS (1); -++ return true; -++ -++ case ZERO_EXTEND: -++ case SIGN_EXTEND: -++ if (MEM_P (XEXP (x, 0))) -++ /* Using memory access. */ -++ *total = COSTS_N_INSNS (1); -++ else -++ /* Zero extend and sign extend instructions. */ -++ *total = COSTS_N_INSNS (1); -++ return true; -++ -++ case NEG: -++ case NOT: -+ *total = COSTS_N_INSNS (1); -+- break; -++ return true; -+ -+ case DIV: -+ case UDIV: -+ case MOD: -+ case UMOD: -+- *total = COSTS_N_INSNS (7); -+- break; -++ *total = COSTS_N_INSNS (20); -++ return true; -+ -+- default: -++ case CALL: -++ *total = COSTS_N_INSNS (2); -++ return true; -++ -++ case CLZ: -++ case SMIN: -++ case SMAX: -++ case ZERO_EXTRACT: -++ if (TARGET_EXT_PERF) -++ *total = COSTS_N_INSNS (1); -++ else -++ *total = COSTS_N_INSNS (3); -++ return true; -++ case VEC_SELECT: -+ *total = COSTS_N_INSNS (1); -+- break; -+- } -+- -+- return true; -++ return true; -+ -++ default: -++ *total = COSTS_N_INSNS (3); -++ return true; -++ } -++} -+ -+-size_cost: -+- /* This is section for size cost model. */ -+- -++static bool -++nds32_rtx_costs_size_prefer (rtx x, -++ int code, -++ int outer_code, -++ int opno ATTRIBUTE_UNUSED, -++ int *total) -++{ -+ /* In gcc/rtl.h, the default value of COSTS_N_INSNS(N) is N*4. -+ We treat it as 4-byte cost for each instruction -+ under code size consideration. */ -+@@ -118,85 +431,162 @@ nds32_rtx_costs_impl (rtx x, -+ (set X imm20s), use movi, 4-byte cost. -+ (set X BIG_INT), use sethi/ori, 8-byte cost. */ -+ if (satisfies_constraint_Is05 (x)) -+- *total = COSTS_N_INSNS (1) - 2; -++ *total = insn_size_16bit; -+ else if (satisfies_constraint_Is20 (x)) -+- *total = COSTS_N_INSNS (1); -++ *total = insn_size_32bit; -+ else -+- *total = COSTS_N_INSNS (2); -++ *total = insn_size_32bit * 2; -+ } -+ else if (outer_code == PLUS || outer_code == MINUS) -+ { -+ /* Possible addi333/subi333 or subi45/addi45, 2-byte cost. -+ General case, cost 1 instruction with 4-byte. */ -+ if (satisfies_constraint_Iu05 (x)) -+- *total = COSTS_N_INSNS (1) - 2; -++ *total = insn_size_16bit; -+ else -+- *total = COSTS_N_INSNS (1); -++ *total = insn_size_32bit; -+ } -+ else if (outer_code == ASHIFT) -+ { -+ /* Possible slli333, 2-byte cost. -+ General case, cost 1 instruction with 4-byte. */ -+ if (satisfies_constraint_Iu03 (x)) -+- *total = COSTS_N_INSNS (1) - 2; -++ *total = insn_size_16bit; -+ else -+- *total = COSTS_N_INSNS (1); -++ *total = insn_size_32bit; -+ } -+ else if (outer_code == ASHIFTRT || outer_code == LSHIFTRT) -+ { -+ /* Possible srai45 or srli45, 2-byte cost. -+ General case, cost 1 instruction with 4-byte. */ -+ if (satisfies_constraint_Iu05 (x)) -+- *total = COSTS_N_INSNS (1) - 2; -++ *total = insn_size_16bit; -+ else -+- *total = COSTS_N_INSNS (1); -++ *total = insn_size_32bit; -+ } -+ else -+ { -+ /* For other cases, simply set it 4-byte cost. */ -+- *total = COSTS_N_INSNS (1); -++ *total = insn_size_32bit; -+ } -+ break; -+ -+ case CONST_DOUBLE: -+ /* It requires high part and low part processing, set it 8-byte cost. */ -+- *total = COSTS_N_INSNS (2); -++ *total = insn_size_32bit * 2; -++ break; -++ -++ case CONST: -++ case SYMBOL_REF: -++ *total = insn_size_32bit * 2; -+ break; -+ -+ default: -+ /* For other cases, generally we set it 4-byte cost -+- and stop resurively traversing. */ -+- *total = COSTS_N_INSNS (1); -++ and stop resurively traversing. */ -++ *total = insn_size_32bit; -+ break; -+ } -+ -+ return true; -+ } -+ -+-int -+-nds32_address_cost_impl (rtx address, -+- machine_mode mode ATTRIBUTE_UNUSED, -+- addr_space_t as ATTRIBUTE_UNUSED, -+- bool speed) -++void -++nds32_init_rtx_costs (void) -++{ -++ rtx_cost_model.speed_prefer = nds32_rtx_costs_speed_prefer; -++ rtx_cost_model.size_prefer = nds32_rtx_costs_size_prefer; -++ -++ if (TARGET_16_BIT) -++ insn_size_16bit = 2; -++ else -++ insn_size_16bit = 4; -++} -++ -++/* This target hook describes the relative costs of RTL expressions. -++ Return 'true' when all subexpressions of x have been processed. -++ Return 'false' to sum the costs of sub-rtx, plus cost of this operation. -++ Refer to gcc/rtlanal.c for more information. */ -++bool -++nds32_rtx_costs_impl (rtx x, -++ machine_mode mode ATTRIBUTE_UNUSED, -++ int outer_code, -++ int opno, -++ int *total, -++ bool speed) -++{ -++ int code = GET_CODE (x); -++ -++ /* According to 'speed', use suitable cost model section. */ -++ if (speed) -++ return rtx_cost_model.speed_prefer(x, code, outer_code, opno, total); -++ else -++ return rtx_cost_model.size_prefer(x, code, outer_code, opno, total); -++} -++ -++ -++int nds32_address_cost_speed_prefer (rtx address) -+ { -+ rtx plus0, plus1; -+ enum rtx_code code; -+ -+ code = GET_CODE (address); -+ -+- /* According to 'speed', goto suitable cost model section. */ -+- if (speed) -+- goto performance_cost; -+- else -+- goto size_cost; -++ switch (code) -++ { -++ case POST_MODIFY: -++ case POST_INC: -++ case POST_DEC: -++ /* We encourage that rtx contains -++ POST_MODIFY/POST_INC/POST_DEC behavior. */ -++ return COSTS_N_INSNS (1) - 2; -++ -++ case SYMBOL_REF: -++ /* We can have gp-relative load/store for symbol_ref. -++ Have it 4-byte cost. */ -++ return COSTS_N_INSNS (2); -++ -++ case CONST: -++ /* It is supposed to be the pattern (const (plus symbol_ref const_int)). -++ Have it 4-byte cost. */ -++ return COSTS_N_INSNS (2); -++ -++ case REG: -++ /* Simply return 4-byte costs. */ -++ return COSTS_N_INSNS (1) - 2; -++ -++ case PLUS: -++ /* We do not need to check if the address is a legitimate address, -++ because this hook is never called with an invalid address. -++ But we better check the range of -++ const_int value for cost, if it exists. */ -++ plus0 = XEXP (address, 0); -++ plus1 = XEXP (address, 1); -++ -++ if (REG_P (plus0) && CONST_INT_P (plus1)) -++ return COSTS_N_INSNS (1) - 2; -++ else if (ARITHMETIC_P (plus0) || ARITHMETIC_P (plus1)) -++ return COSTS_N_INSNS (1) - 1; -++ else if (REG_P (plus0) && REG_P (plus1)) -++ return COSTS_N_INSNS (1); -++ -++ /* For other 'plus' situation, make it cost 4-byte. */ -++ return COSTS_N_INSNS (1); -++ -++ default: -++ break; -++ } -++ -++ return COSTS_N_INSNS (4); -+ -+-performance_cost: -+- /* This is section for performance cost model. */ -++} -+ -+- /* FALLTHRU, currently we use same cost model as size_cost. */ -++int nds32_address_cost_speed_fwprop (rtx address) -++{ -++ rtx plus0, plus1; -++ enum rtx_code code; -+ -+-size_cost: -+- /* This is section for size cost model. */ -++ code = GET_CODE (address); -+ -+ switch (code) -+ { -+@@ -210,12 +600,12 @@ nds32_address_cost_impl (rtx address, -+ case SYMBOL_REF: -+ /* We can have gp-relative load/store for symbol_ref. -+ Have it 4-byte cost. */ -+- return COSTS_N_INSNS (1); -++ return COSTS_N_INSNS (2); -+ -+ case CONST: -+ /* It is supposed to be the pattern (const (plus symbol_ref const_int)). -+ Have it 4-byte cost. */ -+- return COSTS_N_INSNS (1); -++ return COSTS_N_INSNS (2); -+ -+ case REG: -+ /* Simply return 4-byte costs. */ -+@@ -233,11 +623,15 @@ nds32_address_cost_impl (rtx address, -+ { -+ /* If it is possible to be lwi333/swi333 form, -+ make it 2-byte cost. */ -+- if (satisfies_constraint_Iu05 (plus1)) -++ if (satisfies_constraint_Iu03 (plus1)) -+ return (COSTS_N_INSNS (1) - 2); -+ else -+ return COSTS_N_INSNS (1); -+ } -++ if (ARITHMETIC_P (plus0) || ARITHMETIC_P (plus1)) -++ return COSTS_N_INSNS (1) - 2; -++ else if (REG_P (plus0) && REG_P (plus1)) -++ return COSTS_N_INSNS (1); -+ -+ /* For other 'plus' situation, make it cost 4-byte. */ -+ return COSTS_N_INSNS (1); -+@@ -249,4 +643,84 @@ nds32_address_cost_impl (rtx address, -+ return COSTS_N_INSNS (4); -+ } -+ -++ -++int nds32_address_cost_size_prefer (rtx address) -++{ -++ rtx plus0, plus1; -++ enum rtx_code code; -++ -++ code = GET_CODE (address); -++ -++ switch (code) -++ { -++ case POST_MODIFY: -++ case POST_INC: -++ case POST_DEC: -++ /* We encourage that rtx contains -++ POST_MODIFY/POST_INC/POST_DEC behavior. */ -++ return 0; -++ -++ case SYMBOL_REF: -++ /* We can have gp-relative load/store for symbol_ref. -++ Have it 4-byte cost. */ -++ return COSTS_N_INSNS (2); -++ -++ case CONST: -++ /* It is supposed to be the pattern (const (plus symbol_ref const_int)). -++ Have it 4-byte cost. */ -++ return COSTS_N_INSNS (2); -++ -++ case REG: -++ /* Simply return 4-byte costs. */ -++ return COSTS_N_INSNS (1) - 1; -++ -++ case PLUS: -++ /* We do not need to check if the address is a legitimate address, -++ because this hook is never called with an invalid address. -++ But we better check the range of -++ const_int value for cost, if it exists. */ -++ plus0 = XEXP (address, 0); -++ plus1 = XEXP (address, 1); -++ -++ if (REG_P (plus0) && CONST_INT_P (plus1)) -++ { -++ /* If it is possible to be lwi333/swi333 form, -++ make it 2-byte cost. */ -++ if (satisfies_constraint_Iu03 (plus1)) -++ return (COSTS_N_INSNS (1) - 2); -++ else -++ return COSTS_N_INSNS (1) - 1; -++ } -++ -++ /* (plus (reg) (mult (reg) (const))) */ -++ if (ARITHMETIC_P (plus0) || ARITHMETIC_P (plus1)) -++ return (COSTS_N_INSNS (1) - 1); -++ -++ /* For other 'plus' situation, make it cost 4-byte. */ -++ return COSTS_N_INSNS (1); -++ -++ default: -++ break; -++ } -++ -++ return COSTS_N_INSNS (4); -++ -++} -++ -++int nds32_address_cost_impl (rtx address, -++ machine_mode mode ATTRIBUTE_UNUSED, -++ addr_space_t as ATTRIBUTE_UNUSED, -++ bool speed_p) -++{ -++ if (speed_p) -++ { -++ if (current_pass->tv_id == TV_FWPROP) -++ return nds32_address_cost_speed_fwprop (address); -++ else -++ return nds32_address_cost_speed_prefer (address); -++ } -++ else -++ return nds32_address_cost_size_prefer (address); -++} -++ -+ /* ------------------------------------------------------------------------ */ -+diff --git a/gcc/config/nds32/nds32-doubleword.md b/gcc/config/nds32/nds32-doubleword.md -+index 7df715a771f..7ee6489d034 100644 -+--- a/gcc/config/nds32/nds32-doubleword.md -++++ b/gcc/config/nds32/nds32-doubleword.md -+@@ -118,10 +118,28 @@ -+ ]) -+ (set_attr "feature" " v1, v1, v1, v1, v1, v1, fpu, fpu, fpu, fpu, fpu")]) -+ -++;; Split move_di pattern when the hard register is odd. -++(define_split -++ [(set (match_operand:DIDF 0 "register_operand" "") -++ (match_operand:DIDF 1 "register_operand" ""))] -++ "(NDS32_IS_GPR_REGNUM (REGNO (operands[0])) -++ && ((REGNO (operands[0]) & 0x1) == 1)) -++ || (NDS32_IS_GPR_REGNUM (REGNO (operands[1])) -++ && ((REGNO (operands[1]) & 0x1) == 1))" -++ [(set (match_dup 2) (match_dup 3)) -++ (set (match_dup 4) (match_dup 5))] -++ { -++ operands[2] = gen_lowpart (SImode, operands[0]); -++ operands[4] = gen_highpart (SImode, operands[0]); -++ operands[3] = gen_lowpart (SImode, operands[1]); -++ operands[5] = gen_highpart (SImode, operands[1]); -++ } -++) -++ -+ (define_split -+ [(set (match_operand:DIDF 0 "register_operand" "") -+ (match_operand:DIDF 1 "const_double_operand" ""))] -+- "reload_completed" -++ "flag_pic || reload_completed" -+ [(set (match_dup 2) (match_dup 3)) -+ (set (match_dup 4) (match_dup 5))] -+ { -+diff --git a/gcc/config/nds32/nds32-dspext.md b/gcc/config/nds32/nds32-dspext.md -+new file mode 100644 -+index 00000000000..4c643a7528f -+--- /dev/null -++++ b/gcc/config/nds32/nds32-dspext.md -+@@ -0,0 +1,5278 @@ -++;; Machine description of Andes NDS32 cpu for GNU compiler -++;; Copyright (C) 2012-2018 Free Software Foundation, Inc. -++;; Contributed by Andes Technology Corporation. -++;; -++;; This file is part of GCC. -++;; -++;; GCC is free software; you can redistribute it and/or modify it -++;; under the terms of the GNU General Public License as published -++;; by the Free Software Foundation; either version 3, or (at your -++;; option) any later version. -++;; -++;; GCC is distributed in the hope that it will be useful, but WITHOUT -++;; ANY WARRANTY; without even the implied warranty of MERCHANTABILITY -++;; or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public -++;; License for more details. -++;; -++;; You should have received a copy of the GNU General Public License -++;; along with GCC; see the file COPYING3. If not see -++;; . -++ -++(define_expand "mov" -++ [(set (match_operand:VQIHI 0 "general_operand" "") -++ (match_operand:VQIHI 1 "general_operand" ""))] -++ "NDS32_EXT_DSP_P ()" -++{ -++ /* Need to force register if mem <- !reg. */ -++ if (MEM_P (operands[0]) && !REG_P (operands[1])) -++ operands[1] = force_reg (mode, operands[1]); -++ -++ /* If operands[1] is a large constant and cannot be performed -++ by a single instruction, we need to split it. */ -++ if (GET_CODE (operands[1]) == CONST_VECTOR -++ && !satisfies_constraint_CVs2 (operands[1]) -++ && !satisfies_constraint_CVhi (operands[1])) -++ { -++ HOST_WIDE_INT ival = const_vector_to_hwint (operands[1]); -++ rtx tmp_rtx; -++ -++ tmp_rtx = can_create_pseudo_p () -++ ? gen_reg_rtx (SImode) -++ : simplify_gen_subreg (SImode, operands[0], mode, 0); -++ -++ emit_move_insn (tmp_rtx, gen_int_mode (ival, SImode)); -++ convert_move (operands[0], tmp_rtx, false); -++ DONE; -++ } -++ -++ if (REG_P (operands[0]) && SYMBOLIC_CONST_P (operands[1])) -++ { -++ if (nds32_tls_referenced_p (operands [1])) -++ { -++ nds32_expand_tls_move (operands); -++ DONE; -++ } -++ else if (flag_pic) -++ { -++ nds32_expand_pic_move (operands); -++ DONE; -++ } -++ } -++}) -++ -++(define_insn "*mov" -++ [(set (match_operand:VQIHI 0 "nonimmediate_operand" "=r, r,$U45,$U33,$U37,$U45, m,$ l,$ l,$ l,$ d, d, r,$ d, r, r, r, *f, *f, r, *f, Q") -++ (match_operand:VQIHI 1 "nds32_vmove_operand" " r, r, l, l, l, d, r, U45, U33, U37, U45,Ufe, m, CVp5, CVs5, CVs2, CVhi, *f, r, *f, Q, *f"))] -++ "NDS32_EXT_DSP_P () -++ && (register_operand(operands[0], mode) -++ || register_operand(operands[1], mode))" -++{ -++ switch (which_alternative) -++ { -++ case 0: -++ return "mov55\t%0, %1"; -++ case 1: -++ return "ori\t%0, %1, 0"; -++ case 2: -++ case 3: -++ case 4: -++ case 5: -++ return nds32_output_16bit_store (operands, ); -++ case 6: -++ return nds32_output_32bit_store (operands, ); -++ case 7: -++ case 8: -++ case 9: -++ case 10: -++ case 11: -++ return nds32_output_16bit_load (operands, ); -++ case 12: -++ return nds32_output_32bit_load (operands, ); -++ case 13: -++ return "movpi45\t%0, %1"; -++ case 14: -++ return "movi55\t%0, %1"; -++ case 15: -++ return "movi\t%0, %1"; -++ case 16: -++ return "sethi\t%0, hi20(%1)"; -++ case 17: -++ if (TARGET_FPU_SINGLE) -++ return "fcpyss\t%0, %1, %1"; -++ else -++ return "#"; -++ case 18: -++ return "fmtsr\t%1, %0"; -++ case 19: -++ return "fmfsr\t%0, %1"; -++ case 20: -++ return nds32_output_float_load (operands); -++ case 21: -++ return nds32_output_float_store (operands); -++ default: -++ gcc_unreachable (); -++ } -++} -++ [(set_attr "type" "alu,alu,store,store,store,store,store,load,load,load,load,load,load,alu,alu,alu,alu,fcpy,fmtsr,fmfsr,fload,fstore") -++ (set_attr "length" " 2, 4, 2, 2, 2, 2, 4, 2, 2, 2, 2, 2, 4, 2, 2, 4, 4, 4, 4, 4, 4, 4") -++ (set_attr "feature" " v1, v1, v1, v1, v1, v1, v1, v1, v1, v1, v1, v3m, v1, v1, v1, v1, v1, fpu, fpu, fpu, fpu, fpu")]) -++ -++(define_expand "movv2si" -++ [(set (match_operand:V2SI 0 "general_operand" "") -++ (match_operand:V2SI 1 "general_operand" ""))] -++ "NDS32_EXT_DSP_P ()" -++{ -++ /* Need to force register if mem <- !reg. */ -++ if (MEM_P (operands[0]) && !REG_P (operands[1])) -++ operands[1] = force_reg (V2SImode, operands[1]); -++}) -++ -++(define_insn "*movv2si" -++ [(set (match_operand:V2SI 0 "nonimmediate_operand" "=r, r, r, r, Da, m, f, Q, f, r, f") -++ (match_operand:V2SI 1 "general_operand" " r, i, Da, m, r, r, Q, f, f, f, r"))] -++ "NDS32_EXT_DSP_P () -++ && (register_operand(operands[0], V2SImode) -++ || register_operand(operands[1], V2SImode))" -++{ -++ switch (which_alternative) -++ { -++ case 0: -++ return "movd44\t%0, %1"; -++ case 1: -++ /* reg <- const_int, we ask gcc to split instruction. */ -++ return "#"; -++ case 2: -++ /* The memory format is (mem (reg)), -++ we can generate 'lmw.bi' instruction. */ -++ return nds32_output_double (operands, true); -++ case 3: -++ /* We haven't 64-bit load instruction, -++ we split this pattern to two SImode pattern. */ -++ return "#"; -++ case 4: -++ /* The memory format is (mem (reg)), -++ we can generate 'smw.bi' instruction. */ -++ return nds32_output_double (operands, false); -++ case 5: -++ /* We haven't 64-bit store instruction, -++ we split this pattern to two SImode pattern. */ -++ return "#"; -++ case 6: -++ return nds32_output_float_load (operands); -++ case 7: -++ return nds32_output_float_store (operands); -++ case 8: -++ return "fcpysd\t%0, %1, %1"; -++ case 9: -++ return "fmfdr\t%0, %1"; -++ case 10: -++ return "fmtdr\t%1, %0"; -++ default: -++ gcc_unreachable (); -++ } -++} -++ [(set_attr "type" "alu,alu,load,load,store,store,unknown,unknown,unknown,unknown,unknown") -++ (set_attr_alternative "length" -++ [ -++ ;; Alternative 0 -++ (if_then_else (match_test "!TARGET_16_BIT") -++ (const_int 4) -++ (const_int 2)) -++ ;; Alternative 1 -++ (const_int 16) -++ ;; Alternative 2 -++ (const_int 4) -++ ;; Alternative 3 -++ (const_int 8) -++ ;; Alternative 4 -++ (const_int 4) -++ ;; Alternative 5 -++ (const_int 8) -++ ;; Alternative 6 -++ (const_int 4) -++ ;; Alternative 7 -++ (const_int 4) -++ ;; Alternative 8 -++ (const_int 4) -++ ;; Alternative 9 -++ (const_int 4) -++ ;; Alternative 10 -++ (const_int 4) -++ ]) -++ (set_attr "feature" " v1, v1, v1, v1, v1, v1, fpu, fpu, fpu, fpu, fpu")]) -++ -++(define_expand "movmisalign" -++ [(set (match_operand:VQIHI 0 "general_operand" "") -++ (match_operand:VQIHI 1 "general_operand" ""))] -++ "NDS32_EXT_DSP_P ()" -++{ -++ rtx addr; -++ if (MEM_P (operands[0]) && !REG_P (operands[1])) -++ operands[1] = force_reg (mode, operands[1]); -++ -++ if (MEM_P (operands[0])) -++ { -++ addr = force_reg (Pmode, XEXP (operands[0], 0)); -++ emit_insn (gen_unaligned_store (addr, operands[1])); -++ } -++ else -++ { -++ addr = force_reg (Pmode, XEXP (operands[1], 0)); -++ emit_insn (gen_unaligned_load (operands[0], addr)); -++ } -++ DONE; -++}) -++ -++(define_expand "unaligned_load" -++ [(set (match_operand:VQIHI 0 "register_operand" "=r") -++ (unspec:VQIHI [(mem:VQIHI (match_operand:SI 1 "register_operand" "r"))] UNSPEC_UALOAD_W))] -++ "NDS32_EXT_DSP_P ()" -++{ -++ if (TARGET_ISA_V3M) -++ nds32_expand_unaligned_load (operands, mode); -++ else -++ emit_insn (gen_unaligned_load_w (operands[0], gen_rtx_MEM (mode, operands[1]))); -++ DONE; -++}) -++ -++(define_insn "unaligned_load_w" -++ [(set (match_operand:VQIHI 0 "register_operand" "= r") -++ (unspec:VQIHI [(match_operand:VQIHI 1 "nds32_lmw_smw_base_operand" " Umw")] UNSPEC_UALOAD_W))] -++ "NDS32_EXT_DSP_P ()" -++{ -++ return nds32_output_lmw_single_word (operands); -++} -++ [(set_attr "type" "load") -++ (set_attr "length" "4")] -++) -++ -++(define_expand "unaligned_store" -++ [(set (mem:VQIHI (match_operand:SI 0 "register_operand" "r")) -++ (unspec:VQIHI [(match_operand:VQIHI 1 "register_operand" "r")] UNSPEC_UASTORE_W))] -++ "NDS32_EXT_DSP_P ()" -++{ -++ if (TARGET_ISA_V3M) -++ nds32_expand_unaligned_store (operands, mode); -++ else -++ emit_insn (gen_unaligned_store_w (gen_rtx_MEM (mode, operands[0]), operands[1])); -++ DONE; -++}) -++ -++(define_insn "unaligned_store_w" -++ [(set (match_operand:VQIHI 0 "nds32_lmw_smw_base_operand" "=Umw") -++ (unspec:VQIHI [(match_operand:VQIHI 1 "register_operand" " r")] UNSPEC_UASTORE_W))] -++ "NDS32_EXT_DSP_P ()" -++{ -++ return nds32_output_smw_single_word (operands); -++} -++ [(set_attr "type" "store") -++ (set_attr "length" "4")] -++) -++ -++(define_insn "add3" -++ [(set (match_operand:VQIHI 0 "register_operand" "=r") -++ (all_plus:VQIHI (match_operand:VQIHI 1 "register_operand" " r") -++ (match_operand:VQIHI 2 "register_operand" " r")))] -++ "NDS32_EXT_DSP_P ()" -++ "add %0, %1, %2" -++ [(set_attr "type" "dalu") -++ (set_attr "length" "4") -++ (set_attr "feature" "v1")]) -++ -++(define_insn "adddi3" -++ [(set (match_operand:DI 0 "register_operand" "=r") -++ (all_plus:DI (match_operand:DI 1 "register_operand" " r") -++ (match_operand:DI 2 "register_operand" " r")))] -++ "NDS32_EXT_DSP_P ()" -++ "add64 %0, %1, %2" -++ [(set_attr "type" "dalu64") -++ (set_attr "length" "4") -++ (set_attr "feature" "v1")]) -++ -++(define_insn "raddv4qi3" -++ [(set (match_operand:V4QI 0 "register_operand" "=r") -++ (truncate:V4QI -++ (ashiftrt:V4HI -++ (plus:V4HI (sign_extend:V4HI (match_operand:V4QI 1 "register_operand" " r")) -++ (sign_extend:V4HI (match_operand:V4QI 2 "register_operand" " r"))) -++ (const_int 1))))] -++ "NDS32_EXT_DSP_P ()" -++ "radd8\t%0, %1, %2" -++ [(set_attr "type" "dalu") -++ (set_attr "length" "4") -++ (set_attr "feature" "v1")]) -++ -++ -++(define_insn "uraddv4qi3" -++ [(set (match_operand:V4QI 0 "register_operand" "=r") -++ (truncate:V4QI -++ (lshiftrt:V4HI -++ (plus:V4HI (zero_extend:V4HI (match_operand:V4QI 1 "register_operand" " r")) -++ (zero_extend:V4HI (match_operand:V4QI 2 "register_operand" " r"))) -++ (const_int 1))))] -++ "NDS32_EXT_DSP_P ()" -++ "uradd8\t%0, %1, %2" -++ [(set_attr "type" "dalu") -++ (set_attr "length" "4") -++ (set_attr "feature" "v1")]) -++ -++(define_insn "raddv2hi3" -++ [(set (match_operand:V2HI 0 "register_operand" "=r") -++ (truncate:V2HI -++ (ashiftrt:V2SI -++ (plus:V2SI (sign_extend:V2SI (match_operand:V2HI 1 "register_operand" " r")) -++ (sign_extend:V2SI (match_operand:V2HI 2 "register_operand" " r"))) -++ (const_int 1))))] -++ "NDS32_EXT_DSP_P ()" -++ "radd16\t%0, %1, %2" -++ [(set_attr "type" "dalu") -++ (set_attr "length" "4") -++ (set_attr "feature" "v1")]) -++ -++(define_insn "uraddv2hi3" -++ [(set (match_operand:V2HI 0 "register_operand" "=r") -++ (truncate:V2HI -++ (lshiftrt:V2SI -++ (plus:V2SI (zero_extend:V2SI (match_operand:V2HI 1 "register_operand" " r")) -++ (zero_extend:V2SI (match_operand:V2HI 2 "register_operand" " r"))) -++ (const_int 1))))] -++ "NDS32_EXT_DSP_P ()" -++ "uradd16\t%0, %1, %2" -++ [(set_attr "type" "dalu") -++ (set_attr "length" "4") -++ (set_attr "feature" "v1")]) -++ -++(define_insn "radddi3" -++ [(set (match_operand:DI 0 "register_operand" "=r") -++ (truncate:DI -++ (ashiftrt:TI -++ (plus:TI (sign_extend:TI (match_operand:DI 1 "register_operand" " r")) -++ (sign_extend:TI (match_operand:DI 2 "register_operand" " r"))) -++ (const_int 1))))] -++ "NDS32_EXT_DSP_P ()" -++ "radd64\t%0, %1, %2" -++ [(set_attr "type" "dalu64") -++ (set_attr "length" "4") -++ (set_attr "feature" "v1")]) -++ -++ -++(define_insn "uradddi3" -++ [(set (match_operand:DI 0 "register_operand" "=r") -++ (truncate:DI -++ (lshiftrt:TI -++ (plus:TI (zero_extend:TI (match_operand:DI 1 "register_operand" " r")) -++ (zero_extend:TI (match_operand:DI 2 "register_operand" " r"))) -++ (const_int 1))))] -++ "NDS32_EXT_DSP_P ()" -++ "uradd64\t%0, %1, %2" -++ [(set_attr "type" "dalu64") -++ (set_attr "length" "4") -++ (set_attr "feature" "v1")]) -++ -++(define_insn "sub3" -++ [(set (match_operand:VQIHI 0 "register_operand" "=r") -++ (all_minus:VQIHI (match_operand:VQIHI 1 "register_operand" " r") -++ (match_operand:VQIHI 2 "register_operand" " r")))] -++ "NDS32_EXT_DSP_P ()" -++ "sub %0, %1, %2" -++ [(set_attr "type" "dalu") -++ (set_attr "length" "4") -++ (set_attr "feature" "v1")]) -++ -++(define_insn "subdi3" -++ [(set (match_operand:DI 0 "register_operand" "=r") -++ (all_minus:DI (match_operand:DI 1 "register_operand" " r") -++ (match_operand:DI 2 "register_operand" " r")))] -++ "NDS32_EXT_DSP_P ()" -++ "sub64 %0, %1, %2" -++ [(set_attr "type" "dalu64") -++ (set_attr "length" "4") -++ (set_attr "feature" "v1")]) -++ -++(define_insn "rsubv4qi3" -++ [(set (match_operand:V4QI 0 "register_operand" "=r") -++ (truncate:V4QI -++ (ashiftrt:V4HI -++ (minus:V4HI (sign_extend:V4HI (match_operand:V4QI 1 "register_operand" " r")) -++ (sign_extend:V4HI (match_operand:V4QI 2 "register_operand" " r"))) -++ (const_int 1))))] -++ "NDS32_EXT_DSP_P ()" -++ "rsub8\t%0, %1, %2" -++ [(set_attr "type" "dalu") -++ (set_attr "length" "4")]) -++ -++(define_insn "ursubv4qi3" -++ [(set (match_operand:V4QI 0 "register_operand" "=r") -++ (truncate:V4QI -++ (lshiftrt:V4HI -++ (minus:V4HI (zero_extend:V4HI (match_operand:V4QI 1 "register_operand" " r")) -++ (zero_extend:V4HI (match_operand:V4QI 2 "register_operand" " r"))) -++ (const_int 1))))] -++ "NDS32_EXT_DSP_P ()" -++ "ursub8\t%0, %1, %2" -++ [(set_attr "type" "dalu") -++ (set_attr "length" "4")]) -++ -++(define_insn "rsubv2hi3" -++ [(set (match_operand:V2HI 0 "register_operand" "=r") -++ (truncate:V2HI -++ (ashiftrt:V2SI -++ (minus:V2SI (sign_extend:V2SI (match_operand:V2HI 1 "register_operand" " r")) -++ (sign_extend:V2SI (match_operand:V2HI 2 "register_operand" " r"))) -++ (const_int 1))))] -++ "NDS32_EXT_DSP_P ()" -++ "rsub16\t%0, %1, %2" -++ [(set_attr "type" "dalu") -++ (set_attr "length" "4")]) -++ -++(define_insn "ursubv2hi3" -++ [(set (match_operand:V2HI 0 "register_operand" "=r") -++ (truncate:V2HI -++ (lshiftrt:V2SI -++ (minus:V2SI (zero_extend:V2SI (match_operand:V2HI 1 "register_operand" " r")) -++ (zero_extend:V2SI (match_operand:V2HI 2 "register_operand" " r"))) -++ (const_int 1))))] -++ "NDS32_EXT_DSP_P ()" -++ "ursub16\t%0, %1, %2" -++ [(set_attr "type" "dalu") -++ (set_attr "length" "4")]) -++ -++(define_insn "rsubdi3" -++ [(set (match_operand:DI 0 "register_operand" "=r") -++ (truncate:DI -++ (ashiftrt:TI -++ (minus:TI (sign_extend:TI (match_operand:DI 1 "register_operand" " r")) -++ (sign_extend:TI (match_operand:DI 2 "register_operand" " r"))) -++ (const_int 1))))] -++ "NDS32_EXT_DSP_P ()" -++ "rsub64\t%0, %1, %2" -++ [(set_attr "type" "dalu64") -++ (set_attr "length" "4")]) -++ -++ -++(define_insn "ursubdi3" -++ [(set (match_operand:DI 0 "register_operand" "=r") -++ (truncate:DI -++ (lshiftrt:TI -++ (minus:TI (zero_extend:TI (match_operand:DI 1 "register_operand" " r")) -++ (zero_extend:TI (match_operand:DI 2 "register_operand" " r"))) -++ (const_int 1))))] -++ "NDS32_EXT_DSP_P ()" -++ "ursub64\t%0, %1, %2" -++ [(set_attr "type" "dalu64") -++ (set_attr "length" "4")]) -++ -++(define_expand "cras16_1" -++ [(match_operand:V2HI 0 "register_operand" "") -++ (match_operand:V2HI 1 "register_operand" "") -++ (match_operand:V2HI 2 "register_operand" "")] -++ "NDS32_EXT_DSP_P ()" -++{ -++ if (TARGET_BIG_ENDIAN) -++ emit_insn (gen_cras16_1_be (operands[0], operands[1], operands[2])); -++ else -++ emit_insn (gen_cras16_1_le (operands[0], operands[1], operands[2])); -++ DONE; -++}) -++ -++(define_insn "cras16_1_le" -++ [(set (match_operand:V2HI 0 "register_operand" "=r") -++ (vec_merge:V2HI -++ (vec_duplicate:V2HI -++ (minus:HI -++ (vec_select:HI -++ (match_operand:V2HI 1 "register_operand" " r") -++ (parallel [(const_int 0)])) -++ (vec_select:HI -++ (match_operand:V2HI 2 "register_operand" " r") -++ (parallel [(const_int 1)])))) -++ (vec_duplicate:V2HI -++ (plus:HI -++ (vec_select:HI -++ (match_dup 2) -++ (parallel [(const_int 0)])) -++ (vec_select:HI -++ (match_dup 1) -++ (parallel [(const_int 1)])))) -++ (const_int 1)))] -++ "NDS32_EXT_DSP_P () && !TARGET_BIG_ENDIAN" -++ "cras16\t%0, %1, %2" -++ [(set_attr "type" "dalu")] -++) -++ -++(define_insn "cras16_1_be" -++ [(set (match_operand:V2HI 0 "register_operand" "=r") -++ (vec_merge:V2HI -++ (vec_duplicate:V2HI -++ (minus:HI -++ (vec_select:HI -++ (match_operand:V2HI 1 "register_operand" " r") -++ (parallel [(const_int 1)])) -++ (vec_select:HI -++ (match_operand:V2HI 2 "register_operand" " r") -++ (parallel [(const_int 0)])))) -++ (vec_duplicate:V2HI -++ (plus:HI -++ (vec_select:HI -++ (match_dup 2) -++ (parallel [(const_int 1)])) -++ (vec_select:HI -++ (match_dup 1) -++ (parallel [(const_int 0)])))) -++ (const_int 2)))] -++ "NDS32_EXT_DSP_P () && TARGET_BIG_ENDIAN" -++ "cras16\t%0, %1, %2" -++ [(set_attr "type" "dalu")] -++) -++ -++(define_expand "kcras16_1" -++ [(match_operand:V2HI 0 "register_operand" "") -++ (match_operand:V2HI 1 "register_operand" "") -++ (match_operand:V2HI 2 "register_operand" "")] -++ "NDS32_EXT_DSP_P ()" -++{ -++ if (TARGET_BIG_ENDIAN) -++ emit_insn (gen_kcras16_1_be (operands[0], operands[1], operands[2])); -++ else -++ emit_insn (gen_kcras16_1_le (operands[0], operands[1], operands[2])); -++ DONE; -++}) -++ -++(define_insn "kcras16_1_le" -++ [(set (match_operand:V2HI 0 "register_operand" "=r") -++ (vec_merge:V2HI -++ (vec_duplicate:V2HI -++ (ss_minus:HI -++ (vec_select:HI -++ (match_operand:V2HI 1 "register_operand" " r") -++ (parallel [(const_int 0)])) -++ (vec_select:HI -++ (match_operand:V2HI 2 "register_operand" " r") -++ (parallel [(const_int 1)])))) -++ (vec_duplicate:V2HI -++ (ss_plus:HI -++ (vec_select:HI -++ (match_dup 2) -++ (parallel [(const_int 0)])) -++ (vec_select:HI -++ (match_dup 1) -++ (parallel [(const_int 1)])))) -++ (const_int 1)))] -++ "NDS32_EXT_DSP_P () && !TARGET_BIG_ENDIAN" -++ "kcras16\t%0, %1, %2" -++ [(set_attr "type" "dalu")] -++) -++ -++(define_insn "kcras16_1_be" -++ [(set (match_operand:V2HI 0 "register_operand" "=r") -++ (vec_merge:V2HI -++ (vec_duplicate:V2HI -++ (ss_minus:HI -++ (vec_select:HI -++ (match_operand:V2HI 1 "register_operand" " r") -++ (parallel [(const_int 1)])) -++ (vec_select:HI -++ (match_operand:V2HI 2 "register_operand" " r") -++ (parallel [(const_int 0)])))) -++ (vec_duplicate:V2HI -++ (ss_plus:HI -++ (vec_select:HI -++ (match_dup 2) -++ (parallel [(const_int 1)])) -++ (vec_select:HI -++ (match_dup 1) -++ (parallel [(const_int 0)])))) -++ (const_int 2)))] -++ "NDS32_EXT_DSP_P () && TARGET_BIG_ENDIAN" -++ "kcras16\t%0, %1, %2" -++ [(set_attr "type" "dalu")] -++) -++ -++(define_expand "ukcras16_1" -++ [(match_operand:V2HI 0 "register_operand" "") -++ (match_operand:V2HI 1 "register_operand" "") -++ (match_operand:V2HI 2 "register_operand" "")] -++ "NDS32_EXT_DSP_P ()" -++{ -++ if (TARGET_BIG_ENDIAN) -++ emit_insn (gen_ukcras16_1_be (operands[0], operands[1], operands[2])); -++ else -++ emit_insn (gen_ukcras16_1_le (operands[0], operands[1], operands[2])); -++ DONE; -++}) -++ -++(define_insn "ukcras16_1_le" -++ [(set (match_operand:V2HI 0 "register_operand" "=r") -++ (vec_merge:V2HI -++ (vec_duplicate:V2HI -++ (us_minus:HI -++ (vec_select:HI -++ (match_operand:V2HI 1 "register_operand" " r") -++ (parallel [(const_int 0)])) -++ (vec_select:HI -++ (match_operand:V2HI 2 "register_operand" " r") -++ (parallel [(const_int 1)])))) -++ (vec_duplicate:V2HI -++ (us_plus:HI -++ (vec_select:HI -++ (match_dup 2) -++ (parallel [(const_int 0)])) -++ (vec_select:HI -++ (match_dup 1) -++ (parallel [(const_int 1)])))) -++ (const_int 1)))] -++ "NDS32_EXT_DSP_P () && !TARGET_BIG_ENDIAN" -++ "ukcras16\t%0, %1, %2" -++ [(set_attr "type" "dalu")] -++) -++ -++(define_insn "ukcras16_1_be" -++ [(set (match_operand:V2HI 0 "register_operand" "=r") -++ (vec_merge:V2HI -++ (vec_duplicate:V2HI -++ (us_minus:HI -++ (vec_select:HI -++ (match_operand:V2HI 1 "register_operand" " r") -++ (parallel [(const_int 1)])) -++ (vec_select:HI -++ (match_operand:V2HI 2 "register_operand" " r") -++ (parallel [(const_int 0)])))) -++ (vec_duplicate:V2HI -++ (us_plus:HI -++ (vec_select:HI -++ (match_dup 2) -++ (parallel [(const_int 1)])) -++ (vec_select:HI -++ (match_dup 1) -++ (parallel [(const_int 0)])))) -++ (const_int 2)))] -++ "NDS32_EXT_DSP_P () && TARGET_BIG_ENDIAN" -++ "ukcras16\t%0, %1, %2" -++ [(set_attr "type" "dalu")] -++) -++ -++(define_expand "crsa16_1" -++ [(match_operand:V2HI 0 "register_operand" "") -++ (match_operand:V2HI 1 "register_operand" "") -++ (match_operand:V2HI 2 "register_operand" "")] -++ "NDS32_EXT_DSP_P ()" -++{ -++ if (TARGET_BIG_ENDIAN) -++ emit_insn (gen_crsa16_1_be (operands[0], operands[1], operands[2])); -++ else -++ emit_insn (gen_crsa16_1_le (operands[0], operands[1], operands[2])); -++ DONE; -++}) -++ -++(define_insn "crsa16_1_le" -++ [(set (match_operand:V2HI 0 "register_operand" "=r") -++ (vec_merge:V2HI -++ (vec_duplicate:V2HI -++ (minus:HI -++ (vec_select:HI -++ (match_operand:V2HI 1 "register_operand" " r") -++ (parallel [(const_int 1)])) -++ (vec_select:HI -++ (match_operand:V2HI 2 "register_operand" " r") -++ (parallel [(const_int 0)])))) -++ (vec_duplicate:V2HI -++ (plus:HI -++ (vec_select:HI -++ (match_dup 1) -++ (parallel [(const_int 0)])) -++ (vec_select:HI -++ (match_dup 2) -++ (parallel [(const_int 1)])))) -++ (const_int 2)))] -++ "NDS32_EXT_DSP_P () && !TARGET_BIG_ENDIAN" -++ "crsa16\t%0, %1, %2" -++ [(set_attr "type" "dalu")] -++) -++ -++(define_insn "crsa16_1_be" -++ [(set (match_operand:V2HI 0 "register_operand" "=r") -++ (vec_merge:V2HI -++ (vec_duplicate:V2HI -++ (minus:HI -++ (vec_select:HI -++ (match_operand:V2HI 1 "register_operand" " r") -++ (parallel [(const_int 0)])) -++ (vec_select:HI -++ (match_operand:V2HI 2 "register_operand" " r") -++ (parallel [(const_int 1)])))) -++ (vec_duplicate:V2HI -++ (plus:HI -++ (vec_select:HI -++ (match_dup 1) -++ (parallel [(const_int 1)])) -++ (vec_select:HI -++ (match_dup 2) -++ (parallel [(const_int 0)])))) -++ (const_int 1)))] -++ "NDS32_EXT_DSP_P () && TARGET_BIG_ENDIAN" -++ "crsa16\t%0, %1, %2" -++ [(set_attr "type" "dalu")] -++) -++ -++(define_expand "kcrsa16_1" -++ [(match_operand:V2HI 0 "register_operand" "") -++ (match_operand:V2HI 1 "register_operand" "") -++ (match_operand:V2HI 2 "register_operand" "")] -++ "NDS32_EXT_DSP_P ()" -++{ -++ if (TARGET_BIG_ENDIAN) -++ emit_insn (gen_kcrsa16_1_be (operands[0], operands[1], operands[2])); -++ else -++ emit_insn (gen_kcrsa16_1_le (operands[0], operands[1], operands[2])); -++ DONE; -++}) -++ -++(define_insn "kcrsa16_1_le" -++ [(set (match_operand:V2HI 0 "register_operand" "=r") -++ (vec_merge:V2HI -++ (vec_duplicate:V2HI -++ (ss_minus:HI -++ (vec_select:HI -++ (match_operand:V2HI 1 "register_operand" " r") -++ (parallel [(const_int 1)])) -++ (vec_select:HI -++ (match_operand:V2HI 2 "register_operand" " r") -++ (parallel [(const_int 0)])))) -++ (vec_duplicate:V2HI -++ (ss_plus:HI -++ (vec_select:HI -++ (match_dup 1) -++ (parallel [(const_int 0)])) -++ (vec_select:HI -++ (match_dup 2) -++ (parallel [(const_int 1)])))) -++ (const_int 2)))] -++ "NDS32_EXT_DSP_P () && !TARGET_BIG_ENDIAN" -++ "kcrsa16\t%0, %1, %2" -++ [(set_attr "type" "dalu")] -++) -++ -++(define_insn "kcrsa16_1_be" -++ [(set (match_operand:V2HI 0 "register_operand" "=r") -++ (vec_merge:V2HI -++ (vec_duplicate:V2HI -++ (ss_minus:HI -++ (vec_select:HI -++ (match_operand:V2HI 1 "register_operand" " r") -++ (parallel [(const_int 0)])) -++ (vec_select:HI -++ (match_operand:V2HI 2 "register_operand" " r") -++ (parallel [(const_int 1)])))) -++ (vec_duplicate:V2HI -++ (ss_plus:HI -++ (vec_select:HI -++ (match_dup 1) -++ (parallel [(const_int 1)])) -++ (vec_select:HI -++ (match_dup 2) -++ (parallel [(const_int 0)])))) -++ (const_int 1)))] -++ "NDS32_EXT_DSP_P () && TARGET_BIG_ENDIAN" -++ "kcrsa16\t%0, %1, %2" -++ [(set_attr "type" "dalu")] -++) -++ -++(define_expand "ukcrsa16_1" -++ [(match_operand:V2HI 0 "register_operand" "") -++ (match_operand:V2HI 1 "register_operand" "") -++ (match_operand:V2HI 2 "register_operand" "")] -++ "NDS32_EXT_DSP_P ()" -++{ -++ if (TARGET_BIG_ENDIAN) -++ emit_insn (gen_ukcrsa16_1_be (operands[0], operands[1], operands[2])); -++ else -++ emit_insn (gen_ukcrsa16_1_le (operands[0], operands[1], operands[2])); -++ DONE; -++}) -++ -++(define_insn "ukcrsa16_1_le" -++ [(set (match_operand:V2HI 0 "register_operand" "=r") -++ (vec_merge:V2HI -++ (vec_duplicate:V2HI -++ (us_minus:HI -++ (vec_select:HI -++ (match_operand:V2HI 1 "register_operand" " r") -++ (parallel [(const_int 1)])) -++ (vec_select:HI -++ (match_operand:V2HI 2 "register_operand" " r") -++ (parallel [(const_int 0)])))) -++ (vec_duplicate:V2HI -++ (us_plus:HI -++ (vec_select:HI -++ (match_dup 1) -++ (parallel [(const_int 0)])) -++ (vec_select:HI -++ (match_dup 2) -++ (parallel [(const_int 1)])))) -++ (const_int 2)))] -++ "NDS32_EXT_DSP_P () && !TARGET_BIG_ENDIAN" -++ "ukcrsa16\t%0, %1, %2" -++ [(set_attr "type" "dalu")] -++) -++ -++(define_insn "ukcrsa16_1_be" -++ [(set (match_operand:V2HI 0 "register_operand" "=r") -++ (vec_merge:V2HI -++ (vec_duplicate:V2HI -++ (us_minus:HI -++ (vec_select:HI -++ (match_operand:V2HI 1 "register_operand" " r") -++ (parallel [(const_int 0)])) -++ (vec_select:HI -++ (match_operand:V2HI 2 "register_operand" " r") -++ (parallel [(const_int 1)])))) -++ (vec_duplicate:V2HI -++ (us_plus:HI -++ (vec_select:HI -++ (match_dup 1) -++ (parallel [(const_int 1)])) -++ (vec_select:HI -++ (match_dup 2) -++ (parallel [(const_int 0)])))) -++ (const_int 1)))] -++ "NDS32_EXT_DSP_P () && TARGET_BIG_ENDIAN" -++ "ukcrsa16\t%0, %1, %2" -++ [(set_attr "type" "dalu")] -++) -++ -++(define_expand "rcras16_1" -++ [(match_operand:V2HI 0 "register_operand" "") -++ (match_operand:V2HI 1 "register_operand" "") -++ (match_operand:V2HI 2 "register_operand" "")] -++ "NDS32_EXT_DSP_P ()" -++{ -++ if (TARGET_BIG_ENDIAN) -++ emit_insn (gen_rcras16_1_be (operands[0], operands[1], operands[2])); -++ else -++ emit_insn (gen_rcras16_1_le (operands[0], operands[1], operands[2])); -++ DONE; -++}) -++ -++(define_insn "rcras16_1_le" -++ [(set (match_operand:V2HI 0 "register_operand" "=r") -++ (vec_merge:V2HI -++ (vec_duplicate:V2HI -++ (truncate:HI -++ (ashiftrt:SI -++ (minus:SI -++ (sign_extend:SI -++ (vec_select:HI -++ (match_operand:V2HI 1 "register_operand" " r") -++ (parallel [(const_int 0)]))) -++ (sign_extend:SI -++ (vec_select:HI -++ (match_operand:V2HI 2 "register_operand" " r") -++ (parallel [(const_int 1)])))) -++ (const_int 1)))) -++ (vec_duplicate:V2HI -++ (truncate:HI -++ (ashiftrt:SI -++ (plus:SI -++ (sign_extend:SI -++ (vec_select:HI -++ (match_dup 2) -++ (parallel [(const_int 0)]))) -++ (sign_extend:SI -++ (vec_select:HI -++ (match_dup 1) -++ (parallel [(const_int 1)])))) -++ (const_int 1)))) -++ (const_int 1)))] -++ "NDS32_EXT_DSP_P () && !TARGET_BIG_ENDIAN" -++ "rcras16\t%0, %1, %2" -++ [(set_attr "type" "dalu")] -++) -++ -++(define_insn "rcras16_1_be" -++ [(set (match_operand:V2HI 0 "register_operand" "=r") -++ (vec_merge:V2HI -++ (vec_duplicate:V2HI -++ (truncate:HI -++ (ashiftrt:SI -++ (minus:SI -++ (sign_extend:SI -++ (vec_select:HI -++ (match_operand:V2HI 1 "register_operand" " r") -++ (parallel [(const_int 1)]))) -++ (sign_extend:SI -++ (vec_select:HI -++ (match_operand:V2HI 2 "register_operand" " r") -++ (parallel [(const_int 0)])))) -++ (const_int 1)))) -++ (vec_duplicate:V2HI -++ (truncate:HI -++ (ashiftrt:SI -++ (plus:SI -++ (sign_extend:SI -++ (vec_select:HI -++ (match_dup 2) -++ (parallel [(const_int 1)]))) -++ (sign_extend:SI -++ (vec_select:HI -++ (match_dup 1) -++ (parallel [(const_int 0)])))) -++ (const_int 1)))) -++ (const_int 2)))] -++ "NDS32_EXT_DSP_P () && TARGET_BIG_ENDIAN" -++ "rcras16\t%0, %1, %2" -++ [(set_attr "type" "dalu")] -++) -++ -++(define_expand "urcras16_1" -++ [(match_operand:V2HI 0 "register_operand" "") -++ (match_operand:V2HI 1 "register_operand" "") -++ (match_operand:V2HI 2 "register_operand" "")] -++ "NDS32_EXT_DSP_P ()" -++{ -++ if (TARGET_BIG_ENDIAN) -++ emit_insn (gen_urcras16_1_be (operands[0], operands[1], operands[2])); -++ else -++ emit_insn (gen_urcras16_1_le (operands[0], operands[1], operands[2])); -++ DONE; -++}) -++ -++(define_insn "urcras16_1_le" -++ [(set (match_operand:V2HI 0 "register_operand" "=r") -++ (vec_merge:V2HI -++ (vec_duplicate:V2HI -++ (truncate:HI -++ (lshiftrt:SI -++ (minus:SI -++ (zero_extend:SI -++ (vec_select:HI -++ (match_operand:V2HI 1 "register_operand" " r") -++ (parallel [(const_int 0)]))) -++ (zero_extend:SI -++ (vec_select:HI -++ (match_operand:V2HI 2 "register_operand" " r") -++ (parallel [(const_int 1)])))) -++ (const_int 1)))) -++ (vec_duplicate:V2HI -++ (truncate:HI -++ (lshiftrt:SI -++ (plus:SI -++ (zero_extend:SI -++ (vec_select:HI -++ (match_dup 2) -++ (parallel [(const_int 0)]))) -++ (zero_extend:SI -++ (vec_select:HI -++ (match_dup 1) -++ (parallel [(const_int 1)])))) -++ (const_int 1)))) -++ (const_int 1)))] -++ "NDS32_EXT_DSP_P () && !TARGET_BIG_ENDIAN" -++ "urcras16\t%0, %1, %2" -++ [(set_attr "type" "dalu")] -++) -++ -++(define_insn "urcras16_1_be" -++ [(set (match_operand:V2HI 0 "register_operand" "=r") -++ (vec_merge:V2HI -++ (vec_duplicate:V2HI -++ (truncate:HI -++ (lshiftrt:SI -++ (minus:SI -++ (zero_extend:SI -++ (vec_select:HI -++ (match_operand:V2HI 1 "register_operand" " r") -++ (parallel [(const_int 1)]))) -++ (zero_extend:SI -++ (vec_select:HI -++ (match_operand:V2HI 2 "register_operand" " r") -++ (parallel [(const_int 0)])))) -++ (const_int 1)))) -++ (vec_duplicate:V2HI -++ (truncate:HI -++ (lshiftrt:SI -++ (plus:SI -++ (zero_extend:SI -++ (vec_select:HI -++ (match_dup 2) -++ (parallel [(const_int 1)]))) -++ (zero_extend:SI -++ (vec_select:HI -++ (match_dup 1) -++ (parallel [(const_int 0)])))) -++ (const_int 1)))) -++ (const_int 2)))] -++ "NDS32_EXT_DSP_P () && TARGET_BIG_ENDIAN" -++ "urcras16\t%0, %1, %2" -++ [(set_attr "type" "dalu")] -++) -++ -++(define_expand "rcrsa16_1" -++ [(match_operand:V2HI 0 "register_operand" "") -++ (match_operand:V2HI 1 "register_operand" "") -++ (match_operand:V2HI 2 "register_operand" "")] -++ "NDS32_EXT_DSP_P ()" -++{ -++ if (TARGET_BIG_ENDIAN) -++ emit_insn (gen_rcrsa16_1_be (operands[0], operands[1], operands[2])); -++ else -++ emit_insn (gen_rcrsa16_1_le (operands[0], operands[1], operands[2])); -++ DONE; -++}) -++ -++(define_insn "rcrsa16_1_le" -++ [(set (match_operand:V2HI 0 "register_operand" "=r") -++ (vec_merge:V2HI -++ (vec_duplicate:V2HI -++ (truncate:HI -++ (ashiftrt:SI -++ (minus:SI -++ (sign_extend:SI -++ (vec_select:HI -++ (match_operand:V2HI 1 "register_operand" " r") -++ (parallel [(const_int 1)]))) -++ (sign_extend:SI -++ (vec_select:HI -++ (match_operand:V2HI 2 "register_operand" " r") -++ (parallel [(const_int 0)])))) -++ (const_int 1)))) -++ (vec_duplicate:V2HI -++ (truncate:HI -++ (ashiftrt:SI -++ (plus:SI -++ (sign_extend:SI -++ (vec_select:HI -++ (match_dup 1) -++ (parallel [(const_int 0)]))) -++ (sign_extend:SI -++ (vec_select:HI -++ (match_dup 2) -++ (parallel [(const_int 1)])))) -++ (const_int 1)))) -++ (const_int 2)))] -++ "NDS32_EXT_DSP_P () && !TARGET_BIG_ENDIAN" -++ "rcrsa16\t%0, %1, %2" -++ [(set_attr "type" "dalu")] -++) -++ -++(define_insn "rcrsa16_1_be" -++ [(set (match_operand:V2HI 0 "register_operand" "=r") -++ (vec_merge:V2HI -++ (vec_duplicate:V2HI -++ (truncate:HI -++ (ashiftrt:SI -++ (minus:SI -++ (sign_extend:SI -++ (vec_select:HI -++ (match_operand:V2HI 1 "register_operand" " r") -++ (parallel [(const_int 0)]))) -++ (sign_extend:SI -++ (vec_select:HI -++ (match_operand:V2HI 2 "register_operand" " r") -++ (parallel [(const_int 1)])))) -++ (const_int 1)))) -++ (vec_duplicate:V2HI -++ (truncate:HI -++ (ashiftrt:SI -++ (plus:SI -++ (sign_extend:SI -++ (vec_select:HI -++ (match_dup 1) -++ (parallel [(const_int 1)]))) -++ (sign_extend:SI -++ (vec_select:HI -++ (match_dup 2) -++ (parallel [(const_int 0)])))) -++ (const_int 1)))) -++ (const_int 1)))] -++ "NDS32_EXT_DSP_P () && TARGET_BIG_ENDIAN" -++ "rcrsa16\t%0, %1, %2" -++ [(set_attr "type" "dalu")] -++) -++ -++(define_expand "urcrsa16_1" -++ [(match_operand:V2HI 0 "register_operand" "") -++ (match_operand:V2HI 1 "register_operand" "") -++ (match_operand:V2HI 2 "register_operand" "")] -++ "NDS32_EXT_DSP_P ()" -++{ -++ if (TARGET_BIG_ENDIAN) -++ emit_insn (gen_urcrsa16_1_be (operands[0], operands[1], operands[2])); -++ else -++ emit_insn (gen_urcrsa16_1_le (operands[0], operands[1], operands[2])); -++ DONE; -++}) -++ -++(define_insn "urcrsa16_1_le" -++ [(set (match_operand:V2HI 0 "register_operand" "=r") -++ (vec_merge:V2HI -++ (vec_duplicate:V2HI -++ (truncate:HI -++ (lshiftrt:SI -++ (minus:SI -++ (zero_extend:SI -++ (vec_select:HI -++ (match_operand:V2HI 1 "register_operand" " r") -++ (parallel [(const_int 1)]))) -++ (zero_extend:SI -++ (vec_select:HI -++ (match_operand:V2HI 2 "register_operand" " r") -++ (parallel [(const_int 0)])))) -++ (const_int 1)))) -++ (vec_duplicate:V2HI -++ (truncate:HI -++ (lshiftrt:SI -++ (plus:SI -++ (zero_extend:SI -++ (vec_select:HI -++ (match_dup 1) -++ (parallel [(const_int 0)]))) -++ (zero_extend:SI -++ (vec_select:HI -++ (match_dup 2) -++ (parallel [(const_int 1)])))) -++ (const_int 1)))) -++ (const_int 2)))] -++ "NDS32_EXT_DSP_P () && !TARGET_BIG_ENDIAN" -++ "urcrsa16\t%0, %1, %2" -++ [(set_attr "type" "dalu")] -++) -++ -++(define_insn "urcrsa16_1_be" -++ [(set (match_operand:V2HI 0 "register_operand" "=r") -++ (vec_merge:V2HI -++ (vec_duplicate:V2HI -++ (truncate:HI -++ (lshiftrt:SI -++ (minus:SI -++ (zero_extend:SI -++ (vec_select:HI -++ (match_operand:V2HI 1 "register_operand" " r") -++ (parallel [(const_int 0)]))) -++ (zero_extend:SI -++ (vec_select:HI -++ (match_operand:V2HI 2 "register_operand" " r") -++ (parallel [(const_int 1)])))) -++ (const_int 1)))) -++ (vec_duplicate:V2HI -++ (truncate:HI -++ (lshiftrt:SI -++ (plus:SI -++ (zero_extend:SI -++ (vec_select:HI -++ (match_dup 1) -++ (parallel [(const_int 1)]))) -++ (zero_extend:SI -++ (vec_select:HI -++ (match_dup 2) -++ (parallel [(const_int 0)])))) -++ (const_int 1)))) -++ (const_int 1)))] -++ "NDS32_EXT_DSP_P () && TARGET_BIG_ENDIAN" -++ "urcrsa16\t%0, %1, %2" -++ [(set_attr "type" "dalu")] -++) -++ -++(define_expand "v2hi3" -++ [(set (match_operand:V2HI 0 "register_operand" "") -++ (shifts:V2HI (match_operand:V2HI 1 "register_operand" "") -++ (match_operand:SI 2 "nds32_rimm4u_operand" "")))] -++ "NDS32_EXT_DSP_P ()" -++{ -++ if (operands[2] == const0_rtx) -++ { -++ emit_move_insn (operands[0], operands[1]); -++ DONE; -++ } -++}) -++ -++(define_insn "*ashlv2hi3" -++ [(set (match_operand:V2HI 0 "register_operand" "= r, r") -++ (ashift:V2HI (match_operand:V2HI 1 "register_operand" " r, r") -++ (match_operand:SI 2 "nds32_rimm4u_operand" " Iu04, r")))] -++ "NDS32_EXT_DSP_P ()" -++ "@ -++ slli16\t%0, %1, %2 -++ sll16\t%0, %1, %2" -++ [(set_attr "type" "dalu,dalu") -++ (set_attr "length" " 4, 4")]) -++ -++(define_insn "kslli16" -++ [(set (match_operand:V2HI 0 "register_operand" "= r, r") -++ (ss_ashift:V2HI (match_operand:V2HI 1 "register_operand" " r, r") -++ (match_operand:SI 2 "nds32_rimm4u_operand" " Iu04, r")))] -++ "NDS32_EXT_DSP_P ()" -++ "@ -++ kslli16\t%0, %1, %2 -++ ksll16\t%0, %1, %2" -++ [(set_attr "type" "dalu,dalu") -++ (set_attr "length" " 4, 4")]) -++ -++(define_insn "*ashrv2hi3" -++ [(set (match_operand:V2HI 0 "register_operand" "= r, r") -++ (ashiftrt:V2HI (match_operand:V2HI 1 "register_operand" " r, r") -++ (match_operand:SI 2 "nds32_rimm4u_operand" " Iu04, r")))] -++ "NDS32_EXT_DSP_P ()" -++ "@ -++ srai16\t%0, %1, %2 -++ sra16\t%0, %1, %2" -++ [(set_attr "type" "dalu,dalu") -++ (set_attr "length" " 4, 4")]) -++ -++(define_insn "sra16_round" -++ [(set (match_operand:V2HI 0 "register_operand" "= r, r") -++ (unspec:V2HI [(ashiftrt:V2HI (match_operand:V2HI 1 "register_operand" " r, r") -++ (match_operand:SI 2 "nds32_rimm4u_operand" " Iu04, r"))] -++ UNSPEC_ROUND))] -++ "NDS32_EXT_DSP_P ()" -++ "@ -++ srai16.u\t%0, %1, %2 -++ sra16.u\t%0, %1, %2" -++ [(set_attr "type" "daluround,daluround") -++ (set_attr "length" " 4, 4")]) -++ -++(define_insn "*lshrv2hi3" -++ [(set (match_operand:V2HI 0 "register_operand" "= r, r") -++ (lshiftrt:V2HI (match_operand:V2HI 1 "register_operand" " r, r") -++ (match_operand:SI 2 "nds32_rimm4u_operand" " Iu04, r")))] -++ "NDS32_EXT_DSP_P ()" -++ "@ -++ srli16\t%0, %1, %2 -++ srl16\t%0, %1, %2" -++ [(set_attr "type" "dalu,dalu") -++ (set_attr "length" " 4, 4")]) -++ -++(define_insn "srl16_round" -++ [(set (match_operand:V2HI 0 "register_operand" "= r, r") -++ (unspec:V2HI [(lshiftrt:V2HI (match_operand:V2HI 1 "register_operand" " r, r") -++ (match_operand:SI 2 "nds32_rimm4u_operand" " Iu04, r"))] -++ UNSPEC_ROUND))] -++ "NDS32_EXT_DSP_P ()" -++ "@ -++ srli16.u\t%0, %1, %2 -++ srl16.u\t%0, %1, %2" -++ [(set_attr "type" "daluround,daluround") -++ (set_attr "length" " 4, 4")]) -++ -++(define_insn "kslra16" -++ [(set (match_operand:V2HI 0 "register_operand" "=r") -++ (if_then_else:V2HI -++ (lt:SI (match_operand:SI 2 "register_operand" " r") -++ (const_int 0)) -++ (ashiftrt:V2HI (match_operand:V2HI 1 "register_operand" " r") -++ (neg:SI (match_dup 2))) -++ (ashift:V2HI (match_dup 1) -++ (match_dup 2))))] -++ "NDS32_EXT_DSP_P ()" -++ "kslra16\t%0, %1, %2" -++ [(set_attr "type" "dalu") -++ (set_attr "length" "4")]) -++ -++(define_insn "kslra16_round" -++ [(set (match_operand:V2HI 0 "register_operand" "=r") -++ (if_then_else:V2HI -++ (lt:SI (match_operand:SI 2 "register_operand" " r") -++ (const_int 0)) -++ (unspec:V2HI [(ashiftrt:V2HI (match_operand:V2HI 1 "register_operand" " r") -++ (neg:SI (match_dup 2)))] -++ UNSPEC_ROUND) -++ (ashift:V2HI (match_dup 1) -++ (match_dup 2))))] -++ "NDS32_EXT_DSP_P ()" -++ "kslra16.u\t%0, %1, %2" -++ [(set_attr "type" "daluround") -++ (set_attr "length" "4")]) -++ -++(define_insn "cmpeq" -++ [(set (match_operand:SI 0 "register_operand" "=r") -++ (unspec:SI [(eq:SI (match_operand:VQIHI 1 "register_operand" " r") -++ (match_operand:VQIHI 2 "register_operand" " r"))] -++ UNSPEC_VEC_COMPARE))] -++ "NDS32_EXT_DSP_P ()" -++ "cmpeq\t%0, %1, %2" -++ [(set_attr "type" "dcmp") -++ (set_attr "length" "4")]) -++ -++(define_insn "scmplt" -++ [(set (match_operand:SI 0 "register_operand" "=r") -++ (unspec:SI [(lt:SI (match_operand:VQIHI 1 "register_operand" " r") -++ (match_operand:VQIHI 2 "register_operand" " r"))] -++ UNSPEC_VEC_COMPARE))] -++ "NDS32_EXT_DSP_P ()" -++ "scmplt\t%0, %1, %2" -++ [(set_attr "type" "dcmp") -++ (set_attr "length" "4")]) -++ -++(define_insn "scmple" -++ [(set (match_operand:SI 0 "register_operand" "=r") -++ (unspec:SI [(le:SI (match_operand:VQIHI 1 "register_operand" " r") -++ (match_operand:VQIHI 2 "register_operand" " r"))] -++ UNSPEC_VEC_COMPARE))] -++ "NDS32_EXT_DSP_P ()" -++ "scmple\t%0, %1, %2" -++ [(set_attr "type" "dcmp") -++ (set_attr "length" "4")]) -++ -++(define_insn "ucmplt" -++ [(set (match_operand:SI 0 "register_operand" "=r") -++ (unspec:SI [(ltu:SI (match_operand:VQIHI 1 "register_operand" " r") -++ (match_operand:VQIHI 2 "register_operand" " r"))] -++ UNSPEC_VEC_COMPARE))] -++ "NDS32_EXT_DSP_P ()" -++ "ucmplt\t%0, %1, %2" -++ [(set_attr "type" "dcmp") -++ (set_attr "length" "4")]) -++ -++(define_insn "ucmple" -++ [(set (match_operand:SI 0 "register_operand" "=r") -++ (unspec:SI [(leu:SI (match_operand:VQIHI 1 "register_operand" " r") -++ (match_operand:VQIHI 2 "register_operand" " r"))] -++ UNSPEC_VEC_COMPARE))] -++ "NDS32_EXT_DSP_P ()" -++ "ucmple\t%0, %1, %2" -++ [(set_attr "type" "dcmp") -++ (set_attr "length" "4")]) -++ -++(define_insn "sclip16" -++ [(set (match_operand:V2HI 0 "register_operand" "= r") -++ (unspec:V2HI [(match_operand:V2HI 1 "register_operand" " r") -++ (match_operand:SI 2 "nds32_imm4u_operand" " Iu04")] -++ UNSPEC_CLIPS))] -++ "NDS32_EXT_DSP_P ()" -++ "sclip16\t%0, %1, %2" -++ [(set_attr "type" "dclip") -++ (set_attr "length" "4")]) -++ -++(define_insn "uclip16" -++ [(set (match_operand:V2HI 0 "register_operand" "= r") -++ (unspec:V2HI [(match_operand:V2HI 1 "register_operand" " r") -++ (match_operand:SI 2 "nds32_imm4u_operand" " Iu04")] -++ UNSPEC_CLIP))] -++ "NDS32_EXT_DSP_P ()" -++ "uclip16\t%0, %1, %2" -++ [(set_attr "type" "dclip") -++ (set_attr "length" "4")]) -++ -++(define_insn "khm16" -++ [(set (match_operand:V2HI 0 "register_operand" "=r") -++ (unspec:V2HI [(match_operand:V2HI 1 "register_operand" " r") -++ (match_operand:V2HI 2 "register_operand" " r")] -++ UNSPEC_KHM))] -++ "NDS32_EXT_DSP_P ()" -++ "khm16\t%0, %1, %2" -++ [(set_attr "type" "dmul") -++ (set_attr "length" "4")]) -++ -++(define_insn "khmx16" -++ [(set (match_operand:V2HI 0 "register_operand" "=r") -++ (unspec:V2HI [(match_operand:V2HI 1 "register_operand" " r") -++ (match_operand:V2HI 2 "register_operand" " r")] -++ UNSPEC_KHMX))] -++ "NDS32_EXT_DSP_P ()" -++ "khmx16\t%0, %1, %2" -++ [(set_attr "type" "dmul") -++ (set_attr "length" "4")]) -++ -++(define_expand "vec_setv4qi" -++ [(match_operand:V4QI 0 "register_operand" "") -++ (match_operand:QI 1 "register_operand" "") -++ (match_operand:SI 2 "immediate_operand" "")] -++ "NDS32_EXT_DSP_P ()" -++{ -++ HOST_WIDE_INT pos = INTVAL (operands[2]); -++ if (pos > 4) -++ gcc_unreachable (); -++ HOST_WIDE_INT elem = (HOST_WIDE_INT) 1 << pos; -++ emit_insn (gen_vec_setv4qi_internal (operands[0], operands[1], -++ operands[0], GEN_INT (elem))); -++ DONE; -++}) -++ -++(define_expand "insb" -++ [(match_operand:V4QI 0 "register_operand" "") -++ (match_operand:V4QI 1 "register_operand" "") -++ (match_operand:SI 2 "register_operand" "") -++ (match_operand:SI 3 "const_int_operand" "")] -++ "NDS32_EXT_DSP_P ()" -++{ -++ if (INTVAL (operands[3]) > 3 || INTVAL (operands[3]) < 0) -++ gcc_unreachable (); -++ -++ rtx src = gen_reg_rtx (QImode); -++ -++ convert_move (src, operands[2], false); -++ -++ HOST_WIDE_INT selector_index; -++ /* Big endian need reverse index. */ -++ if (TARGET_BIG_ENDIAN) -++ selector_index = 4 - INTVAL (operands[3]) - 1; -++ else -++ selector_index = INTVAL (operands[3]); -++ rtx selector = gen_int_mode (1 << selector_index, SImode); -++ emit_insn (gen_vec_setv4qi_internal (operands[0], src, -++ operands[1], selector)); -++ DONE; -++}) -++ -++(define_expand "insvsi" -++ [(set (zero_extract:SI (match_operand:SI 0 "register_operand" "") -++ (match_operand:SI 1 "const_int_operand" "") -++ (match_operand:SI 2 "nds32_insv_operand" "")) -++ (match_operand:SI 3 "register_operand" ""))] -++ "NDS32_EXT_DSP_P ()" -++{ -++ if (INTVAL (operands[1]) != 8) -++ FAIL; -++} -++ [(set_attr "type" "dinsb") -++ (set_attr "length" "4")]) -++ -++ -++(define_insn "insvsi_internal" -++ [(set (zero_extract:SI (match_operand:SI 0 "register_operand" "+r") -++ (const_int 8) -++ (match_operand:SI 1 "nds32_insv_operand" "i")) -++ (match_operand:SI 2 "register_operand" "r"))] -++ "NDS32_EXT_DSP_P ()" -++ "insb\t%0, %2, %v1" -++ [(set_attr "type" "dinsb") -++ (set_attr "length" "4")]) -++ -++(define_insn "insvsiqi_internal" -++ [(set (zero_extract:SI (match_operand:SI 0 "register_operand" "+r") -++ (const_int 8) -++ (match_operand:SI 1 "nds32_insv_operand" "i")) -++ (zero_extend:SI (match_operand:QI 2 "register_operand" "r")))] -++ "NDS32_EXT_DSP_P ()" -++ "insb\t%0, %2, %v1" -++ [(set_attr "type" "dinsb") -++ (set_attr "length" "4")]) -++ -++;; Intermedium pattern for synthetize insvsiqi_internal -++;; v0 = ((v1 & 0xff) << 8) -++(define_insn_and_split "and0xff_s8" -++ [(set (match_operand:SI 0 "register_operand" "=r") -++ (and:SI (ashift:SI (match_operand:SI 1 "register_operand" "r") -++ (const_int 8)) -++ (const_int 65280)))] -++ "NDS32_EXT_DSP_P () && !reload_completed" -++ "#" -++ "NDS32_EXT_DSP_P () && !reload_completed" -++ [(const_int 1)] -++{ -++ rtx tmp = gen_reg_rtx (SImode); -++ emit_insn (gen_ashlsi3 (tmp, operands[1], gen_int_mode (8, SImode))); -++ emit_insn (gen_andsi3 (operands[0], tmp, gen_int_mode (0xffff, SImode))); -++ DONE; -++}) -++ -++;; v0 = (v1 & 0xff00ffff) | ((v2 << 16) | 0xff0000) -++(define_insn_and_split "insbsi2" -++ [(set (match_operand:SI 0 "register_operand" "=r") -++ (ior:SI (and:SI (match_operand:SI 1 "register_operand" "0") -++ (const_int -16711681)) -++ (and:SI (ashift:SI (match_operand:SI 2 "register_operand" "r") -++ (const_int 16)) -++ (const_int 16711680))))] -++ "NDS32_EXT_DSP_P () && !reload_completed" -++ "#" -++ "NDS32_EXT_DSP_P () && !reload_completed" -++ [(const_int 1)] -++{ -++ rtx tmp = gen_reg_rtx (SImode); -++ emit_move_insn (tmp, operands[1]); -++ emit_insn (gen_insvsi_internal (tmp, gen_int_mode(16, SImode), operands[2])); -++ emit_move_insn (operands[0], tmp); -++ DONE; -++}) -++ -++;; v0 = (v1 & 0xff00ffff) | v2 -++(define_insn_and_split "ior_and0xff00ffff_reg" -++ [(set (match_operand:SI 0 "register_operand" "=r") -++ (ior:SI (and:SI (match_operand:SI 1 "register_operand" "r") -++ (const_int -16711681)) -++ (match_operand:SI 2 "register_operand" "r")))] -++ "NDS32_EXT_DSP_P () && !reload_completed" -++ "#" -++ "NDS32_EXT_DSP_P () && !reload_completed" -++ [(const_int 1)] -++{ -++ rtx tmp = gen_reg_rtx (SImode); -++ emit_insn (gen_andsi3 (tmp, operands[1], gen_int_mode (0xff00ffff, SImode))); -++ emit_insn (gen_iorsi3 (operands[0], tmp, operands[2])); -++ DONE; -++}) -++ -++(define_insn "vec_setv4qi_internal" -++ [(set (match_operand:V4QI 0 "register_operand" "= r, r, r, r") -++ (vec_merge:V4QI -++ (vec_duplicate:V4QI -++ (match_operand:QI 1 "register_operand" " r, r, r, r")) -++ (match_operand:V4QI 2 "register_operand" " 0, 0, 0, 0") -++ (match_operand:SI 3 "nds32_imm_1_2_4_8_operand" " Iv01, Iv02, Iv04, Iv08")))] -++ "NDS32_EXT_DSP_P ()" -++{ -++ if (TARGET_BIG_ENDIAN) -++ { -++ const char *pats[] = { "insb\t%0, %1, 3", -++ "insb\t%0, %1, 2", -++ "insb\t%0, %1, 1", -++ "insb\t%0, %1, 0" }; -++ return pats[which_alternative]; -++ } -++ else -++ { -++ const char *pats[] = { "insb\t%0, %1, 0", -++ "insb\t%0, %1, 1", -++ "insb\t%0, %1, 2", -++ "insb\t%0, %1, 3" }; -++ return pats[which_alternative]; -++ } -++} -++ [(set_attr "type" "dinsb") -++ (set_attr "length" "4")]) -++ -++(define_insn "vec_setv4qi_internal_vec" -++ [(set (match_operand:V4QI 0 "register_operand" "= r, r, r, r") -++ (vec_merge:V4QI -++ (vec_duplicate:V4QI -++ (vec_select:QI -++ (match_operand:V4QI 1 "register_operand" " r, r, r, r") -++ (parallel [(const_int 0)]))) -++ (match_operand:V4QI 2 "register_operand" " 0, 0, 0, 0") -++ (match_operand:SI 3 "nds32_imm_1_2_4_8_operand" " Iv01, Iv02, Iv04, Iv08")))] -++ "NDS32_EXT_DSP_P () && !TARGET_BIG_ENDIAN" -++ "@ -++ insb\t%0, %1, 0 -++ insb\t%0, %1, 1 -++ insb\t%0, %1, 2 -++ insb\t%0, %1, 3" -++ [(set_attr "type" "dinsb") -++ (set_attr "length" "4")]) -++ -++(define_insn "vec_mergev4qi_and_cv0_1" -++ [(set (match_operand:V4QI 0 "register_operand" "=$l,r") -++ (vec_merge:V4QI -++ (vec_duplicate:V4QI -++ (vec_select:QI -++ (match_operand:V4QI 1 "register_operand" " l,r") -++ (parallel [(const_int 0)]))) -++ (const_vector:V4QI [ -++ (const_int 0) -++ (const_int 0) -++ (const_int 0) -++ (const_int 0)]) -++ (const_int 1)))] -++ "NDS32_EXT_DSP_P () && !TARGET_BIG_ENDIAN" -++ "@ -++ zeb33\t%0, %1 -++ zeb\t%0, %1" -++ [(set_attr "type" "alu,alu") -++ (set_attr "length" " 2, 4")]) -++ -++(define_insn "vec_mergev4qi_and_cv0_2" -++ [(set (match_operand:V4QI 0 "register_operand" "=$l,r") -++ (vec_merge:V4QI -++ (const_vector:V4QI [ -++ (const_int 0) -++ (const_int 0) -++ (const_int 0) -++ (const_int 0)]) -++ (vec_duplicate:V4QI -++ (vec_select:QI -++ (match_operand:V4QI 1 "register_operand" " l,r") -++ (parallel [(const_int 0)]))) -++ (const_int 2)))] -++ "NDS32_EXT_DSP_P () && !TARGET_BIG_ENDIAN" -++ "@ -++ zeb33\t%0, %1 -++ zeb\t%0, %1" -++ [(set_attr "type" "alu,alu") -++ (set_attr "length" " 2, 4")]) -++ -++(define_insn "vec_mergeqi_and_cv0_1" -++ [(set (match_operand:V4QI 0 "register_operand" "=$l,r") -++ (vec_merge:V4QI -++ (vec_duplicate:V4QI (match_operand:QI 1 "register_operand" " l,r")) -++ (const_vector:V4QI [ -++ (const_int 0) -++ (const_int 0) -++ (const_int 0) -++ (const_int 0)]) -++ (const_int 1)))] -++ "NDS32_EXT_DSP_P () && !TARGET_BIG_ENDIAN" -++ "@ -++ zeb33\t%0, %1 -++ zeb\t%0, %1" -++ [(set_attr "type" "alu,alu") -++ (set_attr "length" " 2, 4")]) -++ -++(define_insn "vec_mergeqi_and_cv0_2" -++ [(set (match_operand:V4QI 0 "register_operand" "=$l,r") -++ (vec_merge:V4QI -++ (const_vector:V4QI [ -++ (const_int 0) -++ (const_int 0) -++ (const_int 0) -++ (const_int 0)]) -++ (vec_duplicate:V4QI (match_operand:QI 1 "register_operand" " l,r")) -++ (const_int 2)))] -++ "NDS32_EXT_DSP_P () && !TARGET_BIG_ENDIAN" -++ "@ -++ zeb33\t%0, %1 -++ zeb\t%0, %1" -++ [(set_attr "type" "alu,alu") -++ (set_attr "length" " 2, 4")]) -++ -++(define_expand "vec_setv2hi" -++ [(match_operand:V2HI 0 "register_operand" "") -++ (match_operand:HI 1 "register_operand" "") -++ (match_operand:SI 2 "immediate_operand" "")] -++ "NDS32_EXT_DSP_P ()" -++{ -++ HOST_WIDE_INT pos = INTVAL (operands[2]); -++ if (pos > 2) -++ gcc_unreachable (); -++ HOST_WIDE_INT elem = (HOST_WIDE_INT) 1 << pos; -++ emit_insn (gen_vec_setv2hi_internal (operands[0], operands[1], -++ operands[0], GEN_INT (elem))); -++ DONE; -++}) -++ -++(define_insn "vec_setv2hi_internal" -++ [(set (match_operand:V2HI 0 "register_operand" "= r, r") -++ (vec_merge:V2HI -++ (vec_duplicate:V2HI -++ (match_operand:HI 1 "register_operand" " r, r")) -++ (match_operand:V2HI 2 "register_operand" " r, r") -++ (match_operand:SI 3 "nds32_imm_1_2_operand" " Iv01, Iv02")))] -++ "NDS32_EXT_DSP_P ()" -++{ -++ if (TARGET_BIG_ENDIAN) -++ { -++ const char *pats[] = { "pkbb16\t%0, %1, %2", -++ "pktb16\t%0, %2, %1" }; -++ return pats[which_alternative]; -++ } -++ else -++ { -++ const char *pats[] = { "pktb16\t%0, %2, %1", -++ "pkbb16\t%0, %1, %2" }; -++ return pats[which_alternative]; -++ } -++} -++ [(set_attr "type" "dpack") -++ (set_attr "length" "4")]) -++ -++(define_insn "vec_mergev2hi_and_cv0_1" -++ [(set (match_operand:V2HI 0 "register_operand" "=$l,r") -++ (vec_merge:V2HI -++ (vec_duplicate:V2HI -++ (vec_select:HI -++ (match_operand:V2HI 1 "register_operand" " l,r") -++ (parallel [(const_int 0)]))) -++ (const_vector:V2HI [ -++ (const_int 0) -++ (const_int 0)]) -++ (const_int 1)))] -++ "NDS32_EXT_DSP_P () && !TARGET_BIG_ENDIAN" -++ "@ -++ zeh33\t%0, %1 -++ zeh\t%0, %1" -++ [(set_attr "type" "alu,alu") -++ (set_attr "length" " 2, 4")]) -++ -++(define_insn "vec_mergev2hi_and_cv0_2" -++ [(set (match_operand:V2HI 0 "register_operand" "=$l,r") -++ (vec_merge:V2HI -++ (const_vector:V2HI [ -++ (const_int 0) -++ (const_int 0)]) -++ (vec_duplicate:V2HI -++ (vec_select:HI -++ (match_operand:V2HI 1 "register_operand" " l,r") -++ (parallel [(const_int 0)]))) -++ (const_int 2)))] -++ "NDS32_EXT_DSP_P () && !TARGET_BIG_ENDIAN" -++ "@ -++ zeh33\t%0, %1 -++ zeh\t%0, %1" -++ [(set_attr "type" "alu,alu") -++ (set_attr "length" " 2, 4")]) -++ -++(define_insn "vec_mergehi_and_cv0_1" -++ [(set (match_operand:V2HI 0 "register_operand" "=$l,r") -++ (vec_merge:V2HI -++ (vec_duplicate:V2HI (match_operand:HI 1 "register_operand" " l,r")) -++ (const_vector:V2HI [ -++ (const_int 0) -++ (const_int 0)]) -++ (const_int 1)))] -++ "NDS32_EXT_DSP_P () && !TARGET_BIG_ENDIAN" -++ "@ -++ zeh33\t%0, %1 -++ zeh\t%0, %1" -++ [(set_attr "type" "alu,alu") -++ (set_attr "length" " 2, 4")]) -++ -++(define_insn "vec_mergehi_and_cv0_2" -++ [(set (match_operand:V2HI 0 "register_operand" "=$l,r") -++ (vec_merge:V2HI -++ (const_vector:V2HI [ -++ (const_int 0) -++ (const_int 0)]) -++ (vec_duplicate:V2HI (match_operand:HI 1 "register_operand" " l,r")) -++ (const_int 2)))] -++ "NDS32_EXT_DSP_P () && !TARGET_BIG_ENDIAN" -++ "@ -++ zeh33\t%0, %1 -++ zeh\t%0, %1" -++ [(set_attr "type" "alu,alu") -++ (set_attr "length" " 2, 4")]) -++ -++(define_expand "pkbb" -++ [(match_operand:V2HI 0 "register_operand") -++ (match_operand:V2HI 1 "register_operand") -++ (match_operand:V2HI 2 "register_operand")] -++ "NDS32_EXT_DSP_P ()" -++{ -++ if (TARGET_BIG_ENDIAN) -++ { -++ emit_insn (gen_vec_mergevv (operands[0], operands[1], operands[2], -++ GEN_INT (1), GEN_INT (1), GEN_INT (1))); -++ } -++ else -++ { -++ emit_insn (gen_vec_mergevv (operands[0], operands[1], operands[2], -++ GEN_INT (2), GEN_INT (0), GEN_INT (0))); -++ } -++ DONE; -++}) -++ -++(define_insn "pkbbsi_1" -++ [(set (match_operand:SI 0 "register_operand" "=r") -++ (ior:SI (and:SI (match_operand:SI 1 "register_operand" "r") -++ (const_int 65535)) -++ (ashift:SI (match_operand:SI 2 "register_operand" "r") -++ (const_int 16))))] -++ "NDS32_EXT_DSP_P ()" -++ "pkbb16\t%0, %2, %1" -++ [(set_attr "type" "dpack") -++ (set_attr "length" "4")]) -++ -++(define_insn "pkbbsi_2" -++ [(set (match_operand:SI 0 "register_operand" "=r") -++ (ior:SI (ashift:SI (match_operand:SI 2 "register_operand" "r") -++ (const_int 16)) -++ (and:SI (match_operand:SI 1 "register_operand" "r") -++ (const_int 65535))))] -++ "NDS32_EXT_DSP_P ()" -++ "pkbb16\t%0, %2, %1" -++ [(set_attr "type" "dpack") -++ (set_attr "length" "4")]) -++ -++(define_insn "pkbbsi_3" -++ [(set (match_operand:SI 0 "register_operand" "=r") -++ (ior:SI (zero_extend:SI (match_operand:HI 1 "register_operand" "r")) -++ (ashift:SI (match_operand:SI 2 "register_operand" "r") -++ (const_int 16))))] -++ "NDS32_EXT_DSP_P ()" -++ "pkbb16\t%0, %2, %1" -++ [(set_attr "type" "dpack") -++ (set_attr "length" "4")]) -++ -++(define_insn "pkbbsi_4" -++ [(set (match_operand:SI 0 "register_operand" "=r") -++ (ior:SI (ashift:SI (match_operand:SI 2 "register_operand" "r") -++ (const_int 16)) -++ (zero_extend:SI (match_operand:HI 1 "register_operand" "r"))))] -++ "NDS32_EXT_DSP_P ()" -++ "pkbb16\t%0, %2, %1" -++ [(set_attr "type" "dpack") -++ (set_attr "length" "4")]) -++ -++;; v0 = (v1 & 0xffff0000) | (v2 & 0xffff) -++(define_insn "pktbsi_1" -++ [(set (match_operand:SI 0 "register_operand" "=r") -++ (ior:SI (and:SI (match_operand:SI 1 "register_operand" "r") -++ (const_int -65536)) -++ (zero_extend:SI (match_operand:HI 2 "register_operand" "r"))))] -++ "NDS32_EXT_DSP_P ()" -++ "pktb16\t%0, %1, %2" -++ [(set_attr "type" "dpack") -++ (set_attr "length" "4")]) -++ -++(define_insn "pktbsi_2" -++ [(set (match_operand:SI 0 "register_operand" "=r") -++ (ior:SI (and:SI (match_operand:SI 1 "register_operand" "r") -++ (const_int -65536)) -++ (and:SI (match_operand:SI 2 "register_operand" "r") -++ (const_int 65535))))] -++ "NDS32_EXT_DSP_P ()" -++ "pktb16\t%0, %1, %2" -++ [(set_attr "type" "alu") -++ (set_attr "length" "4")]) -++ -++(define_insn "pktbsi_3" -++ [(set (zero_extract:SI (match_operand:SI 0 "register_operand" "+r") -++ (const_int 16 ) -++ (const_int 0)) -++ (match_operand:SI 1 "register_operand" " r"))] -++ "NDS32_EXT_DSP_P ()" -++ "pktb16\t%0, %0, %1" -++ [(set_attr "type" "dpack") -++ (set_attr "length" "4")]) -++ -++(define_insn "pktbsi_4" -++ [(set (zero_extract:SI (match_operand:SI 0 "register_operand" "+r") -++ (const_int 16 ) -++ (const_int 0)) -++ (zero_extend:SI (match_operand:HI 1 "register_operand" " r")))] -++ "NDS32_EXT_DSP_P ()" -++ "pktb16\t%0, %0, %1" -++ [(set_attr "type" "dpack") -++ (set_attr "length" "4")]) -++ -++(define_insn "pkttsi" -++ [(set (match_operand:SI 0 "register_operand" "=r") -++ (ior:SI (and:SI (match_operand:SI 1 "register_operand" " r") -++ (const_int -65536)) -++ (lshiftrt:SI (match_operand:SI 2 "register_operand" " r") -++ (const_int 16))))] -++ "NDS32_EXT_DSP_P ()" -++ "pktt16\t%0, %1, %2" -++ [(set_attr "type" "dpack") -++ (set_attr "length" "4")]) -++ -++(define_expand "pkbt" -++ [(match_operand:V2HI 0 "register_operand") -++ (match_operand:V2HI 1 "register_operand") -++ (match_operand:V2HI 2 "register_operand")] -++ "NDS32_EXT_DSP_P ()" -++{ -++ if (TARGET_BIG_ENDIAN) -++ { -++ emit_insn (gen_vec_mergevv (operands[0], operands[1], operands[2], -++ GEN_INT (1), GEN_INT (1), GEN_INT (0))); -++ } -++ else -++ { -++ emit_insn (gen_vec_mergevv (operands[0], operands[1], operands[2], -++ GEN_INT (2), GEN_INT (0), GEN_INT (1))); -++ } -++ DONE; -++}) -++ -++(define_expand "pktt" -++ [(match_operand:V2HI 0 "register_operand") -++ (match_operand:V2HI 1 "register_operand") -++ (match_operand:V2HI 2 "register_operand")] -++ "NDS32_EXT_DSP_P ()" -++{ -++ if (TARGET_BIG_ENDIAN) -++ { -++ emit_insn (gen_vec_mergevv (operands[0], operands[1], operands[2], -++ GEN_INT (1), GEN_INT (0), GEN_INT (0))); -++ } -++ else -++ { -++ emit_insn (gen_vec_mergevv (operands[0], operands[1], operands[2], -++ GEN_INT (2), GEN_INT (1), GEN_INT (1))); -++ } -++ DONE; -++}) -++ -++(define_expand "pktb" -++ [(match_operand:V2HI 0 "register_operand") -++ (match_operand:V2HI 1 "register_operand") -++ (match_operand:V2HI 2 "register_operand")] -++ "NDS32_EXT_DSP_P ()" -++{ -++ if (TARGET_BIG_ENDIAN) -++ { -++ emit_insn (gen_vec_mergevv (operands[0], operands[1], operands[2], -++ GEN_INT (1), GEN_INT (0), GEN_INT (1))); -++ } -++ else -++ { -++ emit_insn (gen_vec_mergevv (operands[0], operands[1], operands[2], -++ GEN_INT (2), GEN_INT (1), GEN_INT (0))); -++ } -++ DONE; -++}) -++ -++(define_insn "vec_mergerr" -++ [(set (match_operand:V2HI 0 "register_operand" "= r, r") -++ (vec_merge:V2HI -++ (vec_duplicate:V2HI -++ (match_operand:HI 1 "register_operand" " r, r")) -++ (vec_duplicate:V2HI -++ (match_operand:HI 2 "register_operand" " r, r")) -++ (match_operand:SI 3 "nds32_imm_1_2_operand" " Iv01, Iv02")))] -++ "NDS32_EXT_DSP_P () && !TARGET_BIG_ENDIAN" -++ "@ -++ pkbb16\t%0, %2, %1 -++ pkbb16\t%0, %1, %2" -++ [(set_attr "type" "dpack") -++ (set_attr "length" "4")]) -++ -++ -++(define_insn "vec_merge" -++ [(set (match_operand:V2HI 0 "register_operand" "= r, r") -++ (vec_merge:V2HI -++ (match_operand:V2HI 1 "register_operand" " r, r") -++ (match_operand:V2HI 2 "register_operand" " r, r") -++ (match_operand:SI 3 "nds32_imm_1_2_operand" " Iv01, Iv02")))] -++ "NDS32_EXT_DSP_P ()" -++{ -++ if (TARGET_BIG_ENDIAN) -++ { -++ const char *pats[] = { "pktb16\t%0, %1, %2", -++ "pktb16\t%0, %2, %1" }; -++ return pats[which_alternative]; -++ } -++ else -++ { -++ const char *pats[] = { "pktb16\t%0, %2, %1", -++ "pktb16\t%0, %1, %2" }; -++ return pats[which_alternative]; -++ } -++} -++ [(set_attr "type" "dpack") -++ (set_attr "length" "4")]) -++ -++(define_insn "vec_mergerv" -++ [(set (match_operand:V2HI 0 "register_operand" "= r, r, r, r") -++ (vec_merge:V2HI -++ (vec_duplicate:V2HI -++ (match_operand:HI 1 "register_operand" " r, r, r, r")) -++ (vec_duplicate:V2HI -++ (vec_select:HI -++ (match_operand:V2HI 2 "register_operand" " r, r, r, r") -++ (parallel [(match_operand:SI 4 "nds32_imm_0_1_operand" " Iv00, Iv01, Iv00, Iv01")]))) -++ (match_operand:SI 3 "nds32_imm_1_2_operand" " Iv01, Iv01, Iv02, Iv02")))] -++ "NDS32_EXT_DSP_P () && !TARGET_BIG_ENDIAN" -++ "@ -++ pkbb16\t%0, %2, %1 -++ pktb16\t%0, %2, %1 -++ pkbb16\t%0, %1, %2 -++ pkbt16\t%0, %1, %2" -++ [(set_attr "type" "dpack") -++ (set_attr "length" "4")]) -++ -++(define_insn "vec_mergevr" -++ [(set (match_operand:V2HI 0 "register_operand" "= r, r, r, r") -++ (vec_merge:V2HI -++ (vec_duplicate:V2HI -++ (vec_select:HI -++ (match_operand:V2HI 1 "register_operand" " r, r, r, r") -++ (parallel [(match_operand:SI 4 "nds32_imm_0_1_operand" " Iv00, Iv01, Iv00, Iv01")]))) -++ (vec_duplicate:V2HI -++ (match_operand:HI 2 "register_operand" " r, r, r, r")) -++ (match_operand:SI 3 "nds32_imm_1_2_operand" " Iv01, Iv01, Iv02, Iv02")))] -++ "NDS32_EXT_DSP_P () && !TARGET_BIG_ENDIAN" -++ "@ -++ pkbb16\t%0, %2, %1 -++ pkbt16\t%0, %2, %1 -++ pkbb16\t%0, %1, %2 -++ pktb16\t%0, %1, %2" -++ [(set_attr "type" "dpack") -++ (set_attr "length" "4")]) -++ -++(define_insn "vec_mergevv" -++ [(set (match_operand:V2HI 0 "register_operand" "= r, r, r, r, r, r, r, r") -++ (vec_merge:V2HI -++ (vec_duplicate:V2HI -++ (vec_select:HI -++ (match_operand:V2HI 1 "register_operand" " r, r, r, r, r, r, r, r") -++ (parallel [(match_operand:SI 4 "nds32_imm_0_1_operand" " Iv00, Iv00, Iv01, Iv01, Iv00, Iv00, Iv01, Iv01")]))) -++ (vec_duplicate:V2HI -++ (vec_select:HI -++ (match_operand:V2HI 2 "register_operand" " r, r, r, r, r, r, r, r") -++ (parallel [(match_operand:SI 5 "nds32_imm_0_1_operand" " Iv00, Iv01, Iv01, Iv00, Iv00, Iv01, Iv01, Iv00")]))) -++ (match_operand:SI 3 "nds32_imm_1_2_operand" " Iv01, Iv01, Iv01, Iv01, Iv02, Iv02, Iv02, Iv02")))] -++ "NDS32_EXT_DSP_P ()" -++{ -++ if (TARGET_BIG_ENDIAN) -++ { -++ const char *pats[] = { "pktt16\t%0, %1, %2", -++ "pktb16\t%0, %1, %2", -++ "pkbb16\t%0, %1, %2", -++ "pkbt16\t%0, %1, %2", -++ "pktt16\t%0, %2, %1", -++ "pkbt16\t%0, %2, %1", -++ "pkbb16\t%0, %2, %1", -++ "pktb16\t%0, %2, %1" }; -++ return pats[which_alternative]; -++ } -++ else -++ { -++ const char *pats[] = { "pkbb16\t%0, %2, %1", -++ "pktb16\t%0, %2, %1", -++ "pktt16\t%0, %2, %1", -++ "pkbt16\t%0, %2, %1", -++ "pkbb16\t%0, %1, %2", -++ "pkbt16\t%0, %1, %2", -++ "pktt16\t%0, %1, %2", -++ "pktb16\t%0, %1, %2" }; -++ return pats[which_alternative]; -++ } -++} -++ [(set_attr "type" "dpack") -++ (set_attr "length" "4")]) -++ -++(define_expand "vec_extractv4qi" -++ [(set (match_operand:QI 0 "register_operand" "") -++ (vec_select:QI -++ (match_operand:V4QI 1 "nonimmediate_operand" "") -++ (parallel [(match_operand:SI 2 "const_int_operand" "")])))] -++ "NDS32_EXT_DSP_P () && !TARGET_BIG_ENDIAN" -++{ -++ if (INTVAL (operands[2]) != 0 -++ && INTVAL (operands[2]) != 1 -++ && INTVAL (operands[2]) != 2 -++ && INTVAL (operands[2]) != 3) -++ gcc_unreachable (); -++ -++ if (INTVAL (operands[2]) != 0 && MEM_P (operands[0])) -++ FAIL; -++}) -++ -++(define_insn "vec_extractv4qi0" -++ [(set (match_operand:QI 0 "register_operand" "=l,r,r") -++ (vec_select:QI -++ (match_operand:V4QI 1 "nonimmediate_operand" " l,r,m") -++ (parallel [(const_int 0)])))] -++ "NDS32_EXT_DSP_P () && !TARGET_BIG_ENDIAN" -++{ -++ switch (which_alternative) -++ { -++ case 0: -++ return "zeb33\t%0, %1"; -++ case 1: -++ return "zeb\t%0, %1"; -++ case 2: -++ return nds32_output_32bit_load (operands, 1); -++ default: -++ gcc_unreachable (); -++ } -++} -++ [(set_attr "type" "alu") -++ (set_attr "length" "4")]) -++ -++(define_insn "vec_extractv4qi0_ze" -++ [(set (match_operand:SI 0 "register_operand" "=l,r,r") -++ (zero_extend:SI -++ (vec_select:QI -++ (match_operand:V4QI 1 "nonimmediate_operand" " l,r,m") -++ (parallel [(const_int 0)]))))] -++ "NDS32_EXT_DSP_P () && !TARGET_BIG_ENDIAN" -++{ -++ switch (which_alternative) -++ { -++ case 0: -++ return "zeb33\t%0, %1"; -++ case 1: -++ return "zeb\t%0, %1"; -++ case 2: -++ return nds32_output_32bit_load (operands, 1); -++ default: -++ gcc_unreachable (); -++ } -++} -++ [(set_attr "type" "alu") -++ (set_attr "length" "4")]) -++ -++(define_insn "vec_extractv4qi0_se" -++ [(set (match_operand:SI 0 "register_operand" "=l,r,r") -++ (sign_extend:SI -++ (vec_select:QI -++ (match_operand:V4QI 1 "nonimmediate_operand" " l,r,m") -++ (parallel [(const_int 0)]))))] -++ "NDS32_EXT_DSP_P () && !TARGET_BIG_ENDIAN" -++{ -++ switch (which_alternative) -++ { -++ case 0: -++ return "seb33\t%0, %1"; -++ case 1: -++ return "seb\t%0, %1"; -++ case 2: -++ return nds32_output_32bit_load_s (operands, 1); -++ default: -++ gcc_unreachable (); -++ } -++} -++ [(set_attr "type" "alu") -++ (set_attr "length" "4")]) -++ -++(define_insn_and_split "vec_extractv4qi1" -++ [(set (match_operand:QI 0 "register_operand" "=r") -++ (vec_select:QI -++ (match_operand:V4QI 1 "register_operand" " r") -++ (parallel [(const_int 1)])))] -++ "NDS32_EXT_DSP_P () && !reload_completed && !TARGET_BIG_ENDIAN" -++ "#" -++ "NDS32_EXT_DSP_P () && !reload_completed" -++ [(const_int 1)] -++{ -++ rtx tmp = gen_reg_rtx (V4QImode); -++ emit_insn (gen_rotrv4qi_1 (tmp, operands[1])); -++ emit_insn (gen_vec_extractv4qi0 (operands[0], tmp)); -++ DONE; -++} -++ [(set_attr "type" "alu") -++ (set_attr "length" "4")]) -++ -++(define_insn_and_split "vec_extractv4qi2" -++ [(set (match_operand:QI 0 "register_operand" "=r") -++ (vec_select:QI -++ (match_operand:V4QI 1 "register_operand" " r") -++ (parallel [(const_int 2)])))] -++ "NDS32_EXT_DSP_P () && !reload_completed && !TARGET_BIG_ENDIAN" -++ "#" -++ "NDS32_EXT_DSP_P () && !reload_completed" -++ [(const_int 1)] -++{ -++ rtx tmp = gen_reg_rtx (V4QImode); -++ emit_insn (gen_rotrv4qi_2 (tmp, operands[1])); -++ emit_insn (gen_vec_extractv4qi0 (operands[0], tmp)); -++ DONE; -++} -++ [(set_attr "type" "alu") -++ (set_attr "length" "4")]) -++ -++(define_insn_and_split "vec_extractv4qi3" -++ [(set (match_operand:QI 0 "register_operand" "=r") -++ (vec_select:QI -++ (match_operand:V4QI 1 "register_operand" " r") -++ (parallel [(const_int 3)])))] -++ "NDS32_EXT_DSP_P () && !reload_completed && !TARGET_BIG_ENDIAN" -++ "#" -++ "NDS32_EXT_DSP_P () && !reload_completed" -++ [(const_int 1)] -++{ -++ rtx tmp = gen_reg_rtx (V4QImode); -++ emit_insn (gen_rotrv4qi_3 (tmp, operands[1])); -++ emit_insn (gen_vec_extractv4qi0 (operands[0], tmp)); -++ DONE; -++} -++ [(set_attr "type" "alu") -++ (set_attr "length" "4")]) -++ -++(define_insn "vec_extractv4qi3_se" -++ [(set (match_operand:SI 0 "register_operand" "=$d,r") -++ (sign_extend:SI -++ (vec_select:QI -++ (match_operand:V4QI 1 "register_operand" " 0,r") -++ (parallel [(const_int 3)]))))] -++ "NDS32_EXT_DSP_P () && !TARGET_BIG_ENDIAN" -++ "@ -++ srai45\t%0, 24 -++ srai\t%0, %1, 24" -++ [(set_attr "type" "alu,alu") -++ (set_attr "length" " 2, 4")]) -++ -++(define_insn "vec_extractv4qi3_ze" -++ [(set (match_operand:SI 0 "register_operand" "=$d,r") -++ (zero_extend:SI -++ (vec_select:QI -++ (match_operand:V4QI 1 "register_operand" " 0,r") -++ (parallel [(const_int 3)]))))] -++ "NDS32_EXT_DSP_P () && !TARGET_BIG_ENDIAN" -++ "@ -++ srli45\t%0, 24 -++ srli\t%0, %1, 24" -++ [(set_attr "type" "alu,alu") -++ (set_attr "length" " 2, 4")]) -++ -++(define_insn_and_split "vec_extractv4qihi0" -++ [(set (match_operand:HI 0 "register_operand" "=r") -++ (sign_extend:HI -++ (vec_select:QI -++ (match_operand:V4QI 1 "register_operand" " r") -++ (parallel [(const_int 0)]))))] -++ "NDS32_EXT_DSP_P () && !reload_completed && !TARGET_BIG_ENDIAN" -++ "#" -++ "NDS32_EXT_DSP_P () && !reload_completed" -++ [(const_int 1)] -++{ -++ rtx tmp = gen_reg_rtx (QImode); -++ emit_insn (gen_vec_extractv4qi0 (tmp, operands[1])); -++ emit_insn (gen_extendqihi2 (operands[0], tmp)); -++ DONE; -++} -++ [(set_attr "type" "alu") -++ (set_attr "length" "4")]) -++ -++(define_insn_and_split "vec_extractv4qihi1" -++ [(set (match_operand:HI 0 "register_operand" "=r") -++ (sign_extend:HI -++ (vec_select:QI -++ (match_operand:V4QI 1 "register_operand" " r") -++ (parallel [(const_int 1)]))))] -++ "NDS32_EXT_DSP_P () && !reload_completed && !TARGET_BIG_ENDIAN" -++ "#" -++ "NDS32_EXT_DSP_P () && !reload_completed" -++ [(const_int 1)] -++{ -++ rtx tmp = gen_reg_rtx (QImode); -++ emit_insn (gen_vec_extractv4qi1 (tmp, operands[1])); -++ emit_insn (gen_extendqihi2 (operands[0], tmp)); -++ DONE; -++} -++ [(set_attr "type" "alu") -++ (set_attr "length" "4")]) -++ -++(define_insn_and_split "vec_extractv4qihi2" -++ [(set (match_operand:HI 0 "register_operand" "=r") -++ (sign_extend:HI -++ (vec_select:QI -++ (match_operand:V4QI 1 "register_operand" " r") -++ (parallel [(const_int 2)]))))] -++ "NDS32_EXT_DSP_P () && !reload_completed && !TARGET_BIG_ENDIAN" -++ "#" -++ "NDS32_EXT_DSP_P () && !reload_completed" -++ [(const_int 1)] -++{ -++ rtx tmp = gen_reg_rtx (QImode); -++ emit_insn (gen_vec_extractv4qi2 (tmp, operands[1])); -++ emit_insn (gen_extendqihi2 (operands[0], tmp)); -++ DONE; -++} -++ [(set_attr "type" "alu") -++ (set_attr "length" "4")]) -++ -++(define_insn_and_split "vec_extractv4qihi3" -++ [(set (match_operand:HI 0 "register_operand" "=r") -++ (sign_extend:HI -++ (vec_select:QI -++ (match_operand:V4QI 1 "register_operand" " r") -++ (parallel [(const_int 3)]))))] -++ "NDS32_EXT_DSP_P () && !reload_completed && !TARGET_BIG_ENDIAN" -++ "#" -++ "NDS32_EXT_DSP_P () && !reload_completed" -++ [(const_int 1)] -++{ -++ rtx tmp = gen_reg_rtx (QImode); -++ emit_insn (gen_vec_extractv4qi3 (tmp, operands[1])); -++ emit_insn (gen_extendqihi2 (operands[0], tmp)); -++ DONE; -++} -++ [(set_attr "type" "alu") -++ (set_attr "length" "4")]) -++ -++(define_expand "vec_extractv2hi" -++ [(set (match_operand:HI 0 "register_operand" "") -++ (vec_select:HI -++ (match_operand:V2HI 1 "nonimmediate_operand" "") -++ (parallel [(match_operand:SI 2 "const_int_operand" "")])))] -++ "NDS32_EXT_DSP_P ()" -++{ -++ if (INTVAL (operands[2]) != 0 -++ && INTVAL (operands[2]) != 1) -++ gcc_unreachable (); -++ -++ if (INTVAL (operands[2]) != 0 && MEM_P (operands[0])) -++ FAIL; -++}) -++ -++(define_insn "vec_extractv2hi0" -++ [(set (match_operand:HI 0 "register_operand" "=$l,r,r") -++ (vec_select:HI -++ (match_operand:V2HI 1 "nonimmediate_operand" " l,r,m") -++ (parallel [(const_int 0)])))] -++ "NDS32_EXT_DSP_P () && !TARGET_BIG_ENDIAN" -++{ -++ switch (which_alternative) -++ { -++ case 0: -++ return "seh33\t%0, %1"; -++ case 1: -++ return "seh\t%0, %1"; -++ case 2: -++ return nds32_output_32bit_load_s (operands, 2); -++ -++ default: -++ gcc_unreachable (); -++ } -++} -++ [(set_attr "type" "alu,alu,load") -++ (set_attr "length" " 2, 4, 4")]) -++ -++(define_insn "vec_extractv2hi0_ze" -++ [(set (match_operand:SI 0 "register_operand" "=$l, r,$ l, *r") -++ (zero_extend:SI -++ (vec_select:HI -++ (match_operand:V2HI 1 "nonimmediate_operand" " l, r, U33, m") -++ (parallel [(const_int 0)]))))] -++ "NDS32_EXT_DSP_P () && !TARGET_BIG_ENDIAN" -++{ -++ switch (which_alternative) -++ { -++ case 0: -++ return "zeh33\t%0, %1"; -++ case 1: -++ return "zeh\t%0, %1"; -++ case 2: -++ return nds32_output_16bit_load (operands, 2); -++ case 3: -++ return nds32_output_32bit_load (operands, 2); -++ -++ default: -++ gcc_unreachable (); -++ } -++} -++ [(set_attr "type" "alu,alu,load,load") -++ (set_attr "length" " 2, 4, 2, 4")]) -++ -++(define_insn "vec_extractv2hi0_se" -++ [(set (match_operand:SI 0 "register_operand" "=$l, r, r") -++ (sign_extend:SI -++ (vec_select:HI -++ (match_operand:V2HI 1 "nonimmediate_operand" " l,r,m") -++ (parallel [(const_int 0)]))))] -++ "NDS32_EXT_DSP_P () && !TARGET_BIG_ENDIAN" -++{ -++ switch (which_alternative) -++ { -++ case 0: -++ return "seh33\t%0, %1"; -++ case 1: -++ return "seh\t%0, %1"; -++ case 2: -++ return nds32_output_32bit_load_s (operands, 2); -++ -++ default: -++ gcc_unreachable (); -++ } -++} -++ [(set_attr "type" "alu,alu,load") -++ (set_attr "length" " 2, 4, 4")]) -++ -++(define_insn "vec_extractv2hi0_be" -++ [(set (match_operand:HI 0 "register_operand" "=$d,r") -++ (vec_select:HI -++ (match_operand:V2HI 1 "register_operand" " 0,r") -++ (parallel [(const_int 0)])))] -++ "NDS32_EXT_DSP_P () && TARGET_BIG_ENDIAN" -++ "@ -++ srai45\t%0, 16 -++ srai\t%0, %1, 16" -++ [(set_attr "type" "alu,alu") -++ (set_attr "length" " 2, 4")]) -++ -++(define_insn "vec_extractv2hi1" -++ [(set (match_operand:HI 0 "register_operand" "=$d,r") -++ (vec_select:HI -++ (match_operand:V2HI 1 "register_operand" " 0,r") -++ (parallel [(const_int 1)])))] -++ "NDS32_EXT_DSP_P () && !TARGET_BIG_ENDIAN" -++ "@ -++ srai45\t%0, 16 -++ srai\t%0, %1, 16" -++ [(set_attr "type" "alu,alu") -++ (set_attr "length" " 2, 4")]) -++ -++(define_insn "vec_extractv2hi1_se" -++ [(set (match_operand:SI 0 "register_operand" "=$d,r") -++ (sign_extend:SI -++ (vec_select:HI -++ (match_operand:V2HI 1 "register_operand" " 0,r") -++ (parallel [(const_int 1)]))))] -++ "NDS32_EXT_DSP_P () && !TARGET_BIG_ENDIAN" -++ "@ -++ srai45\t%0, 16 -++ srai\t%0, %1, 16" -++ [(set_attr "type" "alu,alu") -++ (set_attr "length" " 2, 4")]) -++ -++(define_insn "vec_extractv2hi1_ze" -++ [(set (match_operand:SI 0 "register_operand" "=$d,r") -++ (zero_extend:SI -++ (vec_select:HI -++ (match_operand:V2HI 1 "register_operand" " 0,r") -++ (parallel [(const_int 1)]))))] -++ "NDS32_EXT_DSP_P () && !TARGET_BIG_ENDIAN" -++ "@ -++ srli45\t%0, 16 -++ srli\t%0, %1, 16" -++ [(set_attr "type" "alu,alu") -++ (set_attr "length" " 2, 4")]) -++ -++(define_insn "vec_extractv2hi1_be" -++ [(set (match_operand:HI 0 "register_operand" "=$l,r,r") -++ (vec_select:HI -++ (match_operand:V2HI 1 "nonimmediate_operand" " l,r,m") -++ (parallel [(const_int 1)])))] -++ "NDS32_EXT_DSP_P () && TARGET_BIG_ENDIAN" -++{ -++ switch (which_alternative) -++ { -++ case 0: -++ return "seh33\t%0, %1"; -++ case 1: -++ return "seh\t%0, %1"; -++ case 2: -++ return nds32_output_32bit_load_s (operands, 2); -++ -++ default: -++ gcc_unreachable (); -++ } -++} -++ [(set_attr "type" "alu,alu,load") -++ (set_attr "length" " 2, 4, 4")]) -++ -++(define_insn "mul16" -++ [(set (match_operand:V2SI 0 "register_operand" "=r") -++ (mult:V2SI (extend:V2SI (match_operand:V2HI 1 "register_operand" "%r")) -++ (extend:V2SI (match_operand:V2HI 2 "register_operand" " r"))))] -++ "NDS32_EXT_DSP_P ()" -++ "mul16\t%0, %1, %2" -++ [(set_attr "type" "dmul") -++ (set_attr "length" "4")]) -++ -++(define_insn "mulx16" -++ [(set (match_operand:V2SI 0 "register_operand" "=r") -++ (vec_merge:V2SI -++ (vec_duplicate:V2SI -++ (mult:SI -++ (extend:SI -++ (vec_select:HI -++ (match_operand:V2HI 1 "register_operand" " r") -++ (parallel [(const_int 0)]))) -++ (extend:SI -++ (vec_select:HI -++ (match_operand:V2HI 2 "register_operand" " r") -++ (parallel [(const_int 1)]))))) -++ (vec_duplicate:V2SI -++ (mult:SI -++ (extend:SI -++ (vec_select:HI -++ (match_dup 1) -++ (parallel [(const_int 1)]))) -++ (extend:SI -++ (vec_select:HI -++ (match_dup 2) -++ (parallel [(const_int 0)]))))) -++ (const_int 1)))] -++ "NDS32_EXT_DSP_P ()" -++ "mulx16\t%0, %1, %2" -++ [(set_attr "type" "dmul") -++ (set_attr "length" "4")]) -++ -++(define_insn "rotrv2hi_1" -++ [(set (match_operand:V2HI 0 "register_operand" "=r") -++ (vec_select:V2HI -++ (match_operand:V2HI 1 "register_operand" " r") -++ (parallel [(const_int 1) (const_int 0)])))] -++ "NDS32_EXT_DSP_P () && !TARGET_BIG_ENDIAN" -++ "rotri\t%0, %1, 16" -++ [(set_attr "type" "alu") -++ (set_attr "length" "4")]) -++ -++(define_insn "rotrv2hi_1_be" -++ [(set (match_operand:V2HI 0 "register_operand" "=r") -++ (vec_select:V2HI -++ (match_operand:V2HI 1 "register_operand" " r") -++ (parallel [(const_int 0) (const_int 1)])))] -++ "NDS32_EXT_DSP_P () && TARGET_BIG_ENDIAN" -++ "rotri\t%0, %1, 16" -++ [(set_attr "type" "alu") -++ (set_attr "length" "4")]) -++ -++(define_insn "rotrv4qi_1" -++ [(set (match_operand:V4QI 0 "register_operand" "=r") -++ (vec_select:V4QI -++ (match_operand:V4QI 1 "register_operand" " r") -++ (parallel [(const_int 1) (const_int 2) (const_int 3) (const_int 0)])))] -++ "NDS32_EXT_DSP_P () && !TARGET_BIG_ENDIAN" -++ "rotri\t%0, %1, 8" -++ [(set_attr "type" "alu") -++ (set_attr "length" "4")]) -++ -++(define_insn "rotrv4qi_1_be" -++ [(set (match_operand:V4QI 0 "register_operand" "=r") -++ (vec_select:V4QI -++ (match_operand:V4QI 1 "register_operand" " r") -++ (parallel [(const_int 2) (const_int 1) (const_int 0) (const_int 3)])))] -++ "NDS32_EXT_DSP_P () && TARGET_BIG_ENDIAN" -++ "rotri\t%0, %1, 8" -++ [(set_attr "type" "alu") -++ (set_attr "length" "4")]) -++ -++(define_insn "rotrv4qi_2" -++ [(set (match_operand:V4QI 0 "register_operand" "=r") -++ (vec_select:V4QI -++ (match_operand:V4QI 1 "register_operand" " r") -++ (parallel [(const_int 2) (const_int 3) (const_int 0) (const_int 1)])))] -++ "NDS32_EXT_DSP_P () && !TARGET_BIG_ENDIAN" -++ "rotri\t%0, %1, 16" -++ [(set_attr "type" "alu") -++ (set_attr "length" "4")]) -++ -++(define_insn "rotrv4qi_2_be" -++ [(set (match_operand:V4QI 0 "register_operand" "=r") -++ (vec_select:V4QI -++ (match_operand:V4QI 1 "register_operand" " r") -++ (parallel [(const_int 1) (const_int 0) (const_int 3) (const_int 2)])))] -++ "NDS32_EXT_DSP_P () && TARGET_BIG_ENDIAN" -++ "rotri\t%0, %1, 16" -++ [(set_attr "type" "alu") -++ (set_attr "length" "4")]) -++ -++(define_insn "rotrv4qi_3" -++ [(set (match_operand:V4QI 0 "register_operand" "=r") -++ (vec_select:V4QI -++ (match_operand:V4QI 1 "register_operand" " r") -++ (parallel [(const_int 3) (const_int 0) (const_int 1) (const_int 2)])))] -++ "NDS32_EXT_DSP_P () && !TARGET_BIG_ENDIAN" -++ "rotri\t%0, %1, 24" -++ [(set_attr "type" "alu") -++ (set_attr "length" "4")]) -++ -++(define_insn "rotrv4qi_3_be" -++ [(set (match_operand:V4QI 0 "register_operand" "=r") -++ (vec_select:V4QI -++ (match_operand:V4QI 1 "register_operand" " r") -++ (parallel [(const_int 0) (const_int 3) (const_int 2) (const_int 1)])))] -++ "NDS32_EXT_DSP_P () && TARGET_BIG_ENDIAN" -++ "rotri\t%0, %1, 24" -++ [(set_attr "type" "alu") -++ (set_attr "length" "4")]) -++ -++(define_insn "v4qi_dup_10" -++ [(set (match_operand:V4QI 0 "register_operand" "=r") -++ (vec_select:V4QI -++ (match_operand:V4QI 1 "register_operand" " r") -++ (parallel [(const_int 0) (const_int 1) (const_int 0) (const_int 1)])))] -++ "NDS32_EXT_DSP_P () && !TARGET_BIG_ENDIAN" -++ "pkbb\t%0, %1, %1" -++ [(set_attr "type" "dpack") -++ (set_attr "length" "4")]) -++ -++(define_insn "v4qi_dup_32" -++ [(set (match_operand:V4QI 0 "register_operand" "=r") -++ (vec_select:V4QI -++ (match_operand:V4QI 1 "register_operand" " r") -++ (parallel [(const_int 2) (const_int 3) (const_int 2) (const_int 3)])))] -++ "NDS32_EXT_DSP_P () && !TARGET_BIG_ENDIAN" -++ "pktt\t%0, %1, %1" -++ [(set_attr "type" "dpack") -++ (set_attr "length" "4")]) -++ -++(define_expand "vec_unpacks_lo_v4qi" -++ [(match_operand:V2HI 0 "register_operand" "=r") -++ (match_operand:V4QI 1 "register_operand" " r")] -++ "NDS32_EXT_DSP_P () && !TARGET_BIG_ENDIAN" -++{ -++ emit_insn (gen_sunpkd810 (operands[0], operands[1])); -++ DONE; -++}) -++ -++(define_expand "sunpkd810" -++ [(match_operand:V2HI 0 "register_operand") -++ (match_operand:V4QI 1 "register_operand")] -++ "NDS32_EXT_DSP_P ()" -++{ -++ if (TARGET_BIG_ENDIAN) -++ emit_insn (gen_sunpkd810_imp_be (operands[0], operands[1])); -++ else -++ emit_insn (gen_sunpkd810_imp (operands[0], operands[1])); -++ DONE; -++}) -++ -++(define_insn "unpkd810_imp" -++ [(set (match_operand:V2HI 0 "register_operand" "=r") -++ (vec_merge:V2HI -++ (vec_duplicate:V2HI -++ (extend:HI -++ (vec_select:QI -++ (match_operand:V4QI 1 "register_operand" " r") -++ (parallel [(const_int 1)])))) -++ (vec_duplicate:V2HI -++ (extend:HI -++ (vec_select:QI -++ (match_dup 1) -++ (parallel [(const_int 0)])))) -++ (const_int 2)))] -++ "NDS32_EXT_DSP_P () && !TARGET_BIG_ENDIAN" -++ "unpkd810\t%0, %1" -++ [(set_attr "type" "dpack") -++ (set_attr "length" "4")]) -++ -++(define_insn "unpkd810_imp_inv" -++ [(set (match_operand:V2HI 0 "register_operand" "=r") -++ (vec_merge:V2HI -++ (vec_duplicate:V2HI -++ (extend:HI -++ (vec_select:QI -++ (match_operand:V4QI 1 "register_operand" " r") -++ (parallel [(const_int 0)])))) -++ (vec_duplicate:V2HI -++ (extend:HI -++ (vec_select:QI -++ (match_dup 1) -++ (parallel [(const_int 1)])))) -++ (const_int 1)))] -++ "NDS32_EXT_DSP_P () && !TARGET_BIG_ENDIAN" -++ "unpkd810\t%0, %1" -++ [(set_attr "type" "dpack") -++ (set_attr "length" "4")]) -++ -++(define_insn "unpkd810_imp_be" -++ [(set (match_operand:V2HI 0 "register_operand" "=r") -++ (vec_merge:V2HI -++ (vec_duplicate:V2HI -++ (extend:HI -++ (vec_select:QI -++ (match_operand:V4QI 1 "register_operand" " r") -++ (parallel [(const_int 2)])))) -++ (vec_duplicate:V2HI -++ (extend:HI -++ (vec_select:QI -++ (match_dup 1) -++ (parallel [(const_int 3)])))) -++ (const_int 1)))] -++ "NDS32_EXT_DSP_P () && TARGET_BIG_ENDIAN" -++ "unpkd810\t%0, %1" -++ [(set_attr "type" "dpack") -++ (set_attr "length" "4")]) -++ -++(define_insn "unpkd810_imp_inv_be" -++ [(set (match_operand:V2HI 0 "register_operand" "=r") -++ (vec_merge:V2HI -++ (vec_duplicate:V2HI -++ (extend:HI -++ (vec_select:QI -++ (match_operand:V4QI 1 "register_operand" " r") -++ (parallel [(const_int 3)])))) -++ (vec_duplicate:V2HI -++ (extend:HI -++ (vec_select:QI -++ (match_dup 1) -++ (parallel [(const_int 2)])))) -++ (const_int 2)))] -++ "NDS32_EXT_DSP_P () && TARGET_BIG_ENDIAN" -++ "unpkd810\t%0, %1" -++ [(set_attr "type" "dpack") -++ (set_attr "length" "4")]) -++ -++(define_expand "sunpkd820" -++ [(match_operand:V2HI 0 "register_operand") -++ (match_operand:V4QI 1 "register_operand")] -++ "NDS32_EXT_DSP_P ()" -++{ -++ if (TARGET_BIG_ENDIAN) -++ emit_insn (gen_sunpkd820_imp_be (operands[0], operands[1])); -++ else -++ emit_insn (gen_sunpkd820_imp (operands[0], operands[1])); -++ DONE; -++}) -++ -++(define_insn "unpkd820_imp" -++ [(set (match_operand:V2HI 0 "register_operand" "=r") -++ (vec_merge:V2HI -++ (vec_duplicate:V2HI -++ (extend:HI -++ (vec_select:QI -++ (match_operand:V4QI 1 "register_operand" " r") -++ (parallel [(const_int 2)])))) -++ (vec_duplicate:V2HI -++ (extend:HI -++ (vec_select:QI -++ (match_dup 1) -++ (parallel [(const_int 0)])))) -++ (const_int 2)))] -++ "NDS32_EXT_DSP_P () && !TARGET_BIG_ENDIAN" -++ "unpkd820\t%0, %1" -++ [(set_attr "type" "dpack") -++ (set_attr "length" "4")]) -++ -++(define_insn "unpkd820_imp_inv" -++ [(set (match_operand:V2HI 0 "register_operand" "=r") -++ (vec_merge:V2HI -++ (vec_duplicate:V2HI -++ (extend:HI -++ (vec_select:QI -++ (match_operand:V4QI 1 "register_operand" " r") -++ (parallel [(const_int 0)])))) -++ (vec_duplicate:V2HI -++ (extend:HI -++ (vec_select:QI -++ (match_dup 1) -++ (parallel [(const_int 2)])))) -++ (const_int 1)))] -++ "NDS32_EXT_DSP_P () && !TARGET_BIG_ENDIAN" -++ "unpkd820\t%0, %1" -++ [(set_attr "type" "dpack") -++ (set_attr "length" "4")]) -++ -++(define_insn "unpkd820_imp_be" -++ [(set (match_operand:V2HI 0 "register_operand" "=r") -++ (vec_merge:V2HI -++ (vec_duplicate:V2HI -++ (extend:HI -++ (vec_select:QI -++ (match_operand:V4QI 1 "register_operand" " r") -++ (parallel [(const_int 1)])))) -++ (vec_duplicate:V2HI -++ (extend:HI -++ (vec_select:QI -++ (match_dup 1) -++ (parallel [(const_int 3)])))) -++ (const_int 1)))] -++ "NDS32_EXT_DSP_P () && TARGET_BIG_ENDIAN" -++ "unpkd820\t%0, %1" -++ [(set_attr "type" "dpack") -++ (set_attr "length" "4")]) -++ -++(define_insn "unpkd820_imp_inv_be" -++ [(set (match_operand:V2HI 0 "register_operand" "=r") -++ (vec_merge:V2HI -++ (vec_duplicate:V2HI -++ (extend:HI -++ (vec_select:QI -++ (match_operand:V4QI 1 "register_operand" " r") -++ (parallel [(const_int 3)])))) -++ (vec_duplicate:V2HI -++ (extend:HI -++ (vec_select:QI -++ (match_dup 1) -++ (parallel [(const_int 1)])))) -++ (const_int 2)))] -++ "NDS32_EXT_DSP_P () && TARGET_BIG_ENDIAN" -++ "unpkd820\t%0, %1" -++ [(set_attr "type" "dpack") -++ (set_attr "length" "4")]) -++ -++(define_expand "sunpkd830" -++ [(match_operand:V2HI 0 "register_operand") -++ (match_operand:V4QI 1 "register_operand")] -++ "NDS32_EXT_DSP_P ()" -++{ -++ if (TARGET_BIG_ENDIAN) -++ emit_insn (gen_sunpkd830_imp_be (operands[0], operands[1])); -++ else -++ emit_insn (gen_sunpkd830_imp (operands[0], operands[1])); -++ DONE; -++}) -++ -++(define_insn "unpkd830_imp" -++ [(set (match_operand:V2HI 0 "register_operand" "=r") -++ (vec_merge:V2HI -++ (vec_duplicate:V2HI -++ (extend:HI -++ (vec_select:QI -++ (match_operand:V4QI 1 "register_operand" " r") -++ (parallel [(const_int 3)])))) -++ (vec_duplicate:V2HI -++ (extend:HI -++ (vec_select:QI -++ (match_dup 1) -++ (parallel [(const_int 0)])))) -++ (const_int 2)))] -++ "NDS32_EXT_DSP_P () && !TARGET_BIG_ENDIAN" -++ "unpkd830\t%0, %1" -++ [(set_attr "type" "dpack") -++ (set_attr "length" "4")]) -++ -++(define_insn "unpkd830_imp_inv" -++ [(set (match_operand:V2HI 0 "register_operand" "=r") -++ (vec_merge:V2HI -++ (vec_duplicate:V2HI -++ (extend:HI -++ (vec_select:QI -++ (match_operand:V4QI 1 "register_operand" " r") -++ (parallel [(const_int 0)])))) -++ (vec_duplicate:V2HI -++ (extend:HI -++ (vec_select:QI -++ (match_dup 1) -++ (parallel [(const_int 3)])))) -++ (const_int 1)))] -++ "NDS32_EXT_DSP_P () && !TARGET_BIG_ENDIAN" -++ "unpkd830\t%0, %1" -++ [(set_attr "type" "dpack") -++ (set_attr "length" "4")]) -++ -++(define_insn "unpkd830_imp_be" -++ [(set (match_operand:V2HI 0 "register_operand" "=r") -++ (vec_merge:V2HI -++ (vec_duplicate:V2HI -++ (extend:HI -++ (vec_select:QI -++ (match_operand:V4QI 1 "register_operand" " r") -++ (parallel [(const_int 0)])))) -++ (vec_duplicate:V2HI -++ (extend:HI -++ (vec_select:QI -++ (match_dup 1) -++ (parallel [(const_int 3)])))) -++ (const_int 1)))] -++ "NDS32_EXT_DSP_P () && TARGET_BIG_ENDIAN" -++ "unpkd830\t%0, %1" -++ [(set_attr "type" "dpack") -++ (set_attr "length" "4")]) -++ -++(define_insn "unpkd830_imp_inv_be" -++ [(set (match_operand:V2HI 0 "register_operand" "=r") -++ (vec_merge:V2HI -++ (vec_duplicate:V2HI -++ (extend:HI -++ (vec_select:QI -++ (match_operand:V4QI 1 "register_operand" " r") -++ (parallel [(const_int 3)])))) -++ (vec_duplicate:V2HI -++ (extend:HI -++ (vec_select:QI -++ (match_dup 1) -++ (parallel [(const_int 0)])))) -++ (const_int 2)))] -++ "NDS32_EXT_DSP_P () && TARGET_BIG_ENDIAN" -++ "unpkd830\t%0, %1" -++ [(set_attr "type" "dpack") -++ (set_attr "length" "4")]) -++ -++(define_expand "sunpkd831" -++ [(match_operand:V2HI 0 "register_operand") -++ (match_operand:V4QI 1 "register_operand")] -++ "NDS32_EXT_DSP_P ()" -++{ -++ if (TARGET_BIG_ENDIAN) -++ emit_insn (gen_sunpkd831_imp_be (operands[0], operands[1])); -++ else -++ emit_insn (gen_sunpkd831_imp (operands[0], operands[1])); -++ DONE; -++}) -++ -++(define_insn "unpkd831_imp" -++ [(set (match_operand:V2HI 0 "register_operand" "=r") -++ (vec_merge:V2HI -++ (vec_duplicate:V2HI -++ (extend:HI -++ (vec_select:QI -++ (match_operand:V4QI 1 "register_operand" " r") -++ (parallel [(const_int 3)])))) -++ (vec_duplicate:V2HI -++ (extend:HI -++ (vec_select:QI -++ (match_dup 1) -++ (parallel [(const_int 1)])))) -++ (const_int 2)))] -++ "NDS32_EXT_DSP_P () && !TARGET_BIG_ENDIAN" -++ "unpkd831\t%0, %1" -++ [(set_attr "type" "dpack") -++ (set_attr "length" "4")]) -++ -++(define_insn "unpkd831_imp_inv" -++ [(set (match_operand:V2HI 0 "register_operand" "=r") -++ (vec_merge:V2HI -++ (vec_duplicate:V2HI -++ (extend:HI -++ (vec_select:QI -++ (match_operand:V4QI 1 "register_operand" " r") -++ (parallel [(const_int 1)])))) -++ (vec_duplicate:V2HI -++ (extend:HI -++ (vec_select:QI -++ (match_dup 1) -++ (parallel [(const_int 3)])))) -++ (const_int 1)))] -++ "NDS32_EXT_DSP_P () && !TARGET_BIG_ENDIAN" -++ "unpkd831\t%0, %1" -++ [(set_attr "type" "dpack") -++ (set_attr "length" "4")]) -++ -++(define_insn "unpkd831_imp_be" -++ [(set (match_operand:V2HI 0 "register_operand" "=r") -++ (vec_merge:V2HI -++ (vec_duplicate:V2HI -++ (extend:HI -++ (vec_select:QI -++ (match_operand:V4QI 1 "register_operand" " r") -++ (parallel [(const_int 0)])))) -++ (vec_duplicate:V2HI -++ (extend:HI -++ (vec_select:QI -++ (match_dup 1) -++ (parallel [(const_int 2)])))) -++ (const_int 1)))] -++ "NDS32_EXT_DSP_P () && TARGET_BIG_ENDIAN" -++ "unpkd831\t%0, %1" -++ [(set_attr "type" "dpack") -++ (set_attr "length" "4")]) -++ -++(define_insn "unpkd831_imp_inv_be" -++ [(set (match_operand:V2HI 0 "register_operand" "=r") -++ (vec_merge:V2HI -++ (vec_duplicate:V2HI -++ (extend:HI -++ (vec_select:QI -++ (match_operand:V4QI 1 "register_operand" " r") -++ (parallel [(const_int 2)])))) -++ (vec_duplicate:V2HI -++ (extend:HI -++ (vec_select:QI -++ (match_dup 1) -++ (parallel [(const_int 0)])))) -++ (const_int 2)))] -++ "NDS32_EXT_DSP_P () && TARGET_BIG_ENDIAN" -++ "unpkd831\t%0, %1" -++ [(set_attr "type" "dpack") -++ (set_attr "length" "4")]) -++ -++(define_expand "zunpkd810" -++ [(match_operand:V2HI 0 "register_operand") -++ (match_operand:V4QI 1 "register_operand")] -++ "NDS32_EXT_DSP_P ()" -++{ -++ if (TARGET_BIG_ENDIAN) -++ emit_insn (gen_zunpkd810_imp_be (operands[0], operands[1])); -++ else -++ emit_insn (gen_zunpkd810_imp (operands[0], operands[1])); -++ DONE; -++}) -++ -++(define_expand "zunpkd820" -++ [(match_operand:V2HI 0 "register_operand") -++ (match_operand:V4QI 1 "register_operand")] -++ "NDS32_EXT_DSP_P ()" -++{ -++ if (TARGET_BIG_ENDIAN) -++ emit_insn (gen_zunpkd820_imp_be (operands[0], operands[1])); -++ else -++ emit_insn (gen_zunpkd820_imp (operands[0], operands[1])); -++ DONE; -++}) -++ -++(define_expand "zunpkd830" -++ [(match_operand:V2HI 0 "register_operand") -++ (match_operand:V4QI 1 "register_operand")] -++ "NDS32_EXT_DSP_P ()" -++{ -++ if (TARGET_BIG_ENDIAN) -++ emit_insn (gen_zunpkd830_imp_be (operands[0], operands[1])); -++ else -++ emit_insn (gen_zunpkd830_imp (operands[0], operands[1])); -++ DONE; -++}) -++ -++(define_expand "zunpkd831" -++ [(match_operand:V2HI 0 "register_operand") -++ (match_operand:V4QI 1 "register_operand")] -++ "NDS32_EXT_DSP_P ()" -++{ -++ if (TARGET_BIG_ENDIAN) -++ emit_insn (gen_zunpkd831_imp_be (operands[0], operands[1])); -++ else -++ emit_insn (gen_zunpkd831_imp (operands[0], operands[1])); -++ DONE; -++}) -++ -++(define_expand "smbb" -++ [(match_operand:SI 0 "register_operand" "") -++ (match_operand:V2HI 1 "register_operand" "") -++ (match_operand:V2HI 2 "register_operand" "")] -++ "NDS32_EXT_DSP_P ()" -++{ -++ if (TARGET_BIG_ENDIAN) -++ emit_insn (gen_mulhisi3v (operands[0], operands[1], operands[2], -++ GEN_INT (1), GEN_INT (1))); -++ else -++ emit_insn (gen_mulhisi3v (operands[0], operands[1], operands[2], -++ GEN_INT (0), GEN_INT (0))); -++ DONE; -++}) -++ -++(define_expand "smbt" -++ [(match_operand:SI 0 "register_operand" "") -++ (match_operand:V2HI 1 "register_operand" "") -++ (match_operand:V2HI 2 "register_operand" "")] -++ "NDS32_EXT_DSP_P ()" -++{ -++ if (TARGET_BIG_ENDIAN) -++ emit_insn (gen_mulhisi3v (operands[0], operands[1], operands[2], -++ GEN_INT (1), GEN_INT (0))); -++ else -++ emit_insn (gen_mulhisi3v (operands[0], operands[1], operands[2], -++ GEN_INT (0), GEN_INT (1))); -++ DONE; -++}) -++ -++(define_expand "smtt" -++ [(match_operand:SI 0 "register_operand" "") -++ (match_operand:V2HI 1 "register_operand" "") -++ (match_operand:V2HI 2 "register_operand" "")] -++ "NDS32_EXT_DSP_P ()" -++{ -++ if (TARGET_BIG_ENDIAN) -++ emit_insn (gen_mulhisi3v (operands[0], operands[1], operands[2], -++ GEN_INT (0), GEN_INT (0))); -++ else -++ emit_insn (gen_mulhisi3v (operands[0], operands[1], operands[2], -++ GEN_INT (1), GEN_INT (1))); -++ DONE; -++}) -++ -++(define_insn "mulhisi3v" -++ [(set (match_operand:SI 0 "register_operand" "= r, r, r, r") -++ (mult:SI -++ (sign_extend:SI -++ (vec_select:HI -++ (match_operand:V2HI 1 "register_operand" " r, r, r, r") -++ (parallel [(match_operand:SI 3 "nds32_imm_0_1_operand" " Iv00, Iv00, Iv01, Iv01")]))) -++ (sign_extend:SI (vec_select:HI -++ (match_operand:V2HI 2 "register_operand" " r, r, r, r") -++ (parallel [(match_operand:SI 4 "nds32_imm_0_1_operand" " Iv00, Iv01, Iv01, Iv00")])))))] -++ "NDS32_EXT_DSP_P ()" -++{ -++ if (TARGET_BIG_ENDIAN) -++ { -++ const char *pats[] = { "smtt\t%0, %1, %2", -++ "smbt\t%0, %2, %1", -++ "smbb\t%0, %1, %2", -++ "smbt\t%0, %1, %2" }; -++ return pats[which_alternative]; -++ } -++ else -++ { -++ const char *pats[] = { "smbb\t%0, %1, %2", -++ "smbt\t%0, %1, %2", -++ "smtt\t%0, %1, %2", -++ "smbt\t%0, %2, %1" }; -++ return pats[which_alternative]; -++ } -++} -++ [(set_attr "type" "dmul") -++ (set_attr "length" "4")]) -++ -++(define_expand "kmabb" -++ [(match_operand:SI 0 "register_operand" "") -++ (match_operand:SI 1 "register_operand" "") -++ (match_operand:V2HI 2 "register_operand" "") -++ (match_operand:V2HI 3 "register_operand" "")] -++ "NDS32_EXT_DSP_P ()" -++{ -++ if (TARGET_BIG_ENDIAN) -++ emit_insn (gen_kma_internal (operands[0], operands[2], operands[3], -++ GEN_INT (1), GEN_INT (1), -++ operands[1])); -++ else -++ emit_insn (gen_kma_internal (operands[0], operands[2], operands[3], -++ GEN_INT (0), GEN_INT (0), -++ operands[1])); -++ DONE; -++}) -++ -++(define_expand "kmabt" -++ [(match_operand:SI 0 "register_operand" "") -++ (match_operand:SI 1 "register_operand" "") -++ (match_operand:V2HI 2 "register_operand" "") -++ (match_operand:V2HI 3 "register_operand" "")] -++ "NDS32_EXT_DSP_P ()" -++{ -++ if (TARGET_BIG_ENDIAN) -++ emit_insn (gen_kma_internal (operands[0], operands[2], operands[3], -++ GEN_INT (1), GEN_INT (0), -++ operands[1])); -++ else -++ emit_insn (gen_kma_internal (operands[0], operands[2], operands[3], -++ GEN_INT (0), GEN_INT (1), -++ operands[1])); -++ DONE; -++}) -++ -++(define_expand "kmatt" -++ [(match_operand:SI 0 "register_operand" "") -++ (match_operand:SI 1 "register_operand" "") -++ (match_operand:V2HI 2 "register_operand" "") -++ (match_operand:V2HI 3 "register_operand" "")] -++ "NDS32_EXT_DSP_P ()" -++{ -++ if (TARGET_BIG_ENDIAN) -++ emit_insn (gen_kma_internal (operands[0], operands[2], operands[3], -++ GEN_INT (0), GEN_INT (0), -++ operands[1])); -++ else -++ emit_insn (gen_kma_internal (operands[0], operands[2], operands[3], -++ GEN_INT (1), GEN_INT (1), -++ operands[1])); -++ DONE; -++}) -++ -++(define_insn "kma_internal" -++ [(set (match_operand:SI 0 "register_operand" "= r, r, r, r") -++ (ss_plus:SI -++ (mult:SI -++ (sign_extend:SI -++ (vec_select:HI -++ (match_operand:V2HI 1 "register_operand" " r, r, r, r") -++ (parallel [(match_operand:SI 3 "nds32_imm_0_1_operand" " Iv00, Iv00, Iv01, Iv01")]))) -++ (sign_extend:SI -++ (vec_select:HI -++ (match_operand:V2HI 2 "register_operand" " r, r, r, r") -++ (parallel [(match_operand:SI 4 "nds32_imm_0_1_operand" " Iv00, Iv01, Iv01, Iv00")])))) -++ (match_operand:SI 5 "register_operand" " 0, 0, 0, 0")))] -++ "NDS32_EXT_DSP_P ()" -++{ -++ if (TARGET_BIG_ENDIAN) -++ { -++ const char *pats[] = { "kmatt\t%0, %1, %2", -++ "kmabt\t%0, %2, %1", -++ "kmabb\t%0, %1, %2", -++ "kmabt\t%0, %1, %2" }; -++ return pats[which_alternative]; -++ } -++ else -++ { -++ const char *pats[] = { "kmabb\t%0, %1, %2", -++ "kmabt\t%0, %1, %2", -++ "kmatt\t%0, %1, %2", -++ "kmabt\t%0, %2, %1" }; -++ return pats[which_alternative]; -++ } -++} -++ [(set_attr "type" "dmac") -++ (set_attr "length" "4")]) -++ -++(define_expand "smds" -++ [(match_operand:SI 0 "register_operand" "") -++ (match_operand:V2HI 1 "register_operand" "") -++ (match_operand:V2HI 2 "register_operand" "")] -++ "NDS32_EXT_DSP_P ()" -++{ -++ if (TARGET_BIG_ENDIAN) -++ emit_insn (gen_smds_be (operands[0], operands[1], operands[2])); -++ else -++ emit_insn (gen_smds_le (operands[0], operands[1], operands[2])); -++ DONE; -++}) -++ -++(define_expand "smds_le" -++ [(set (match_operand:SI 0 "register_operand" "=r") -++ (minus:SI -++ (mult:SI -++ (sign_extend:SI (vec_select:HI -++ (match_operand:V2HI 1 "register_operand" " r") -++ (parallel [(const_int 1)]))) -++ (sign_extend:SI (vec_select:HI -++ (match_operand:V2HI 2 "register_operand" " r") -++ (parallel [(const_int 1)])))) -++ (mult:SI -++ (sign_extend:SI (vec_select:HI -++ (match_dup 1) -++ (parallel [(const_int 0)]))) -++ (sign_extend:SI (vec_select:HI -++ (match_dup 2) -++ (parallel [(const_int 0)]))))))] -++ "NDS32_EXT_DSP_P ()" -++{ -++}) -++ -++(define_expand "smds_be" -++ [(set (match_operand:SI 0 "register_operand" "=r") -++ (minus:SI -++ (mult:SI -++ (sign_extend:SI (vec_select:HI -++ (match_operand:V2HI 1 "register_operand" " r") -++ (parallel [(const_int 0)]))) -++ (sign_extend:SI (vec_select:HI -++ (match_operand:V2HI 2 "register_operand" " r") -++ (parallel [(const_int 0)])))) -++ (mult:SI -++ (sign_extend:SI (vec_select:HI -++ (match_dup 1) -++ (parallel [(const_int 1)]))) -++ (sign_extend:SI (vec_select:HI -++ (match_dup 2) -++ (parallel [(const_int 1)]))))))] -++ "NDS32_EXT_DSP_P ()" -++{ -++}) -++ -++(define_expand "smdrs" -++ [(match_operand:SI 0 "register_operand" "") -++ (match_operand:V2HI 1 "register_operand" "") -++ (match_operand:V2HI 2 "register_operand" "")] -++ "NDS32_EXT_DSP_P ()" -++{ -++ if (TARGET_BIG_ENDIAN) -++ emit_insn (gen_smdrs_be (operands[0], operands[1], operands[2])); -++ else -++ emit_insn (gen_smdrs_le (operands[0], operands[1], operands[2])); -++ DONE; -++}) -++ -++(define_expand "smdrs_le" -++ [(set (match_operand:SI 0 "register_operand" "=r") -++ (minus:SI -++ (mult:SI -++ (sign_extend:SI (vec_select:HI -++ (match_operand:V2HI 1 "register_operand" " r") -++ (parallel [(const_int 0)]))) -++ (sign_extend:SI (vec_select:HI -++ (match_operand:V2HI 2 "register_operand" " r") -++ (parallel [(const_int 0)])))) -++ (mult:SI -++ (sign_extend:SI (vec_select:HI -++ (match_dup 1) -++ (parallel [(const_int 1)]))) -++ (sign_extend:SI (vec_select:HI -++ (match_dup 2) -++ (parallel [(const_int 1)]))))))] -++ "NDS32_EXT_DSP_P ()" -++{ -++}) -++ -++(define_expand "smdrs_be" -++ [(set (match_operand:SI 0 "register_operand" "=r") -++ (minus:SI -++ (mult:SI -++ (sign_extend:SI (vec_select:HI -++ (match_operand:V2HI 1 "register_operand" " r") -++ (parallel [(const_int 1)]))) -++ (sign_extend:SI (vec_select:HI -++ (match_operand:V2HI 2 "register_operand" " r") -++ (parallel [(const_int 1)])))) -++ (mult:SI -++ (sign_extend:SI (vec_select:HI -++ (match_dup 1) -++ (parallel [(const_int 0)]))) -++ (sign_extend:SI (vec_select:HI -++ (match_dup 2) -++ (parallel [(const_int 0)]))))))] -++ "NDS32_EXT_DSP_P ()" -++{ -++}) -++ -++(define_expand "smxdsv" -++ [(match_operand:SI 0 "register_operand" "") -++ (match_operand:V2HI 1 "register_operand" "") -++ (match_operand:V2HI 2 "register_operand" "")] -++ "NDS32_EXT_DSP_P ()" -++{ -++ if (TARGET_BIG_ENDIAN) -++ emit_insn (gen_smxdsv_be (operands[0], operands[1], operands[2])); -++ else -++ emit_insn (gen_smxdsv_le (operands[0], operands[1], operands[2])); -++ DONE; -++}) -++ -++ -++(define_expand "smxdsv_le" -++ [(set (match_operand:SI 0 "register_operand" "=r") -++ (minus:SI -++ (mult:SI -++ (sign_extend:SI (vec_select:HI -++ (match_operand:V2HI 1 "register_operand" " r") -++ (parallel [(const_int 1)]))) -++ (sign_extend:SI (vec_select:HI -++ (match_operand:V2HI 2 "register_operand" " r") -++ (parallel [(const_int 0)])))) -++ (mult:SI -++ (sign_extend:SI (vec_select:HI -++ (match_dup 1) -++ (parallel [(const_int 0)]))) -++ (sign_extend:SI (vec_select:HI -++ (match_dup 2) -++ (parallel [(const_int 1)]))))))] -++ "NDS32_EXT_DSP_P ()" -++{ -++}) -++ -++(define_expand "smxdsv_be" -++ [(set (match_operand:SI 0 "register_operand" "=r") -++ (minus:SI -++ (mult:SI -++ (sign_extend:SI (vec_select:HI -++ (match_operand:V2HI 1 "register_operand" " r") -++ (parallel [(const_int 0)]))) -++ (sign_extend:SI (vec_select:HI -++ (match_operand:V2HI 2 "register_operand" " r") -++ (parallel [(const_int 1)])))) -++ (mult:SI -++ (sign_extend:SI (vec_select:HI -++ (match_dup 1) -++ (parallel [(const_int 1)]))) -++ (sign_extend:SI (vec_select:HI -++ (match_dup 2) -++ (parallel [(const_int 0)]))))))] -++ "NDS32_EXT_DSP_P ()" -++{ -++}) -++ -++(define_insn "smal1" -++ [(set (match_operand:DI 0 "register_operand" "=r") -++ (plus:DI (match_operand:DI 1 "register_operand" " r") -++ (sign_extend:DI -++ (mult:SI -++ (sign_extend:SI -++ (vec_select:HI -++ (match_operand:V2HI 2 "register_operand" " r") -++ (parallel [(const_int 0)]))) -++ (sign_extend:SI -++ (vec_select:HI -++ (match_dup 2) -++ (parallel [(const_int 1)])))))))] -++ "NDS32_EXT_DSP_P ()" -++ "smal\t%0, %1, %2" -++ [(set_attr "type" "dmac") -++ (set_attr "length" "4")]) -++ -++(define_insn "smal2" -++ [(set (match_operand:DI 0 "register_operand" "=r") -++ (plus:DI (match_operand:DI 1 "register_operand" " r") -++ (mult:DI -++ (sign_extend:DI -++ (vec_select:HI -++ (match_operand:V2HI 2 "register_operand" " r") -++ (parallel [(const_int 0)]))) -++ (sign_extend:DI -++ (vec_select:HI -++ (match_dup 2) -++ (parallel [(const_int 1)]))))))] -++ "NDS32_EXT_DSP_P ()" -++ "smal\t%0, %1, %2" -++ [(set_attr "type" "dmac") -++ (set_attr "length" "4")]) -++ -++(define_insn "smal3" -++ [(set (match_operand:DI 0 "register_operand" "=r") -++ (plus:DI (match_operand:DI 1 "register_operand" " r") -++ (sign_extend:DI -++ (mult:SI -++ (sign_extend:SI -++ (vec_select:HI -++ (match_operand:V2HI 2 "register_operand" " r") -++ (parallel [(const_int 1)]))) -++ (sign_extend:SI -++ (vec_select:HI -++ (match_dup 2) -++ (parallel [(const_int 0)])))))))] -++ "NDS32_EXT_DSP_P ()" -++ "smal\t%0, %1, %2" -++ [(set_attr "type" "dmac") -++ (set_attr "length" "4")]) -++ -++(define_insn "smal4" -++ [(set (match_operand:DI 0 "register_operand" "=r") -++ (plus:DI (match_operand:DI 1 "register_operand" " r") -++ (mult:DI -++ (sign_extend:DI -++ (vec_select:HI -++ (match_operand:V2HI 2 "register_operand" " r") -++ (parallel [(const_int 1)]))) -++ (sign_extend:DI -++ (vec_select:HI -++ (match_dup 2) -++ (parallel [(const_int 0)]))))))] -++ "NDS32_EXT_DSP_P ()" -++ "smal\t%0, %1, %2" -++ [(set_attr "type" "dmac") -++ (set_attr "length" "4")]) -++ -++(define_insn "smal5" -++ [(set (match_operand:DI 0 "register_operand" "=r") -++ (plus:DI -++ (sign_extend:DI -++ (mult:SI -++ (sign_extend:SI -++ (vec_select:HI -++ (match_operand:V2HI 2 "register_operand" " r") -++ (parallel [(const_int 0)]))) -++ (sign_extend:SI -++ (vec_select:HI -++ (match_dup 2) -++ (parallel [(const_int 1)]))))) -++ (match_operand:DI 1 "register_operand" " r")))] -++ "NDS32_EXT_DSP_P ()" -++ "smal\t%0, %1, %2" -++ [(set_attr "type" "dmac") -++ (set_attr "length" "4")]) -++ -++(define_insn "smal6" -++ [(set (match_operand:DI 0 "register_operand" "=r") -++ (plus:DI -++ (mult:DI -++ (sign_extend:DI -++ (vec_select:HI -++ (match_operand:V2HI 2 "register_operand" " r") -++ (parallel [(const_int 0)]))) -++ (sign_extend:DI -++ (vec_select:HI -++ (match_dup 2) -++ (parallel [(const_int 1)])))) -++ (match_operand:DI 1 "register_operand" " r")))] -++ "NDS32_EXT_DSP_P ()" -++ "smal\t%0, %1, %2" -++ [(set_attr "type" "dmac") -++ (set_attr "length" "4")]) -++ -++(define_insn "smal7" -++ [(set (match_operand:DI 0 "register_operand" "=r") -++ (plus:DI -++ (sign_extend:DI -++ (mult:SI -++ (sign_extend:SI -++ (vec_select:HI -++ (match_operand:V2HI 2 "register_operand" " r") -++ (parallel [(const_int 1)]))) -++ (sign_extend:SI -++ (vec_select:HI -++ (match_dup 2) -++ (parallel [(const_int 0)]))))) -++ (match_operand:DI 1 "register_operand" " r")))] -++ "NDS32_EXT_DSP_P ()" -++ "smal\t%0, %1, %2" -++ [(set_attr "type" "dmac") -++ (set_attr "length" "4")]) -++ -++(define_insn "smal8" -++ [(set (match_operand:DI 0 "register_operand" "=r") -++ (plus:DI -++ (mult:DI -++ (sign_extend:DI -++ (vec_select:HI -++ (match_operand:V2HI 2 "register_operand" " r") -++ (parallel [(const_int 1)]))) -++ (sign_extend:DI -++ (vec_select:HI -++ (match_dup 2) -++ (parallel [(const_int 0)])))) -++ (match_operand:DI 1 "register_operand" " r")))] -++ "NDS32_EXT_DSP_P ()" -++ "smal\t%0, %1, %2" -++ [(set_attr "type" "dmac") -++ (set_attr "length" "4")]) -++ -++;; We need this dummy pattern for smal -++(define_insn_and_split "extendsidi2" -++ [(set (match_operand:DI 0 "register_operand" "") -++ (sign_extend:DI (match_operand:SI 1 "nds32_move_operand" "")))] -++ "NDS32_EXT_DSP_P ()" -++ "#" -++ "NDS32_EXT_DSP_P ()" -++ [(const_int 0)] -++{ -++ rtx high_part_dst, low_part_dst; -++ -++ low_part_dst = nds32_di_low_part_subreg (operands[0]); -++ high_part_dst = nds32_di_high_part_subreg (operands[0]); -++ -++ emit_move_insn (low_part_dst, operands[1]); -++ emit_insn (gen_ashrsi3 (high_part_dst, low_part_dst, GEN_INT (31))); -++ DONE; -++} -++ [(set_attr "type" "alu") -++ (set_attr "length" "4")]) -++ -++;; We need this dummy pattern for usmar64/usmsr64 -++(define_insn_and_split "zero_extendsidi2" -++ [(set (match_operand:DI 0 "register_operand" "") -++ (zero_extend:DI (match_operand:SI 1 "nds32_move_operand" "")))] -++ "NDS32_EXT_DSP_P ()" -++ "#" -++ "NDS32_EXT_DSP_P ()" -++ [(const_int 0)] -++{ -++ rtx high_part_dst, low_part_dst; -++ -++ low_part_dst = nds32_di_low_part_subreg (operands[0]); -++ high_part_dst = nds32_di_high_part_subreg (operands[0]); -++ -++ emit_move_insn (low_part_dst, operands[1]); -++ emit_move_insn (high_part_dst, const0_rtx); -++ DONE; -++} -++ [(set_attr "type" "alu") -++ (set_attr "length" "4")]) -++ -++(define_insn_and_split "extendhidi2" -++ [(set (match_operand:DI 0 "register_operand" "") -++ (sign_extend:DI (match_operand:HI 1 "nonimmediate_operand" "")))] -++ "NDS32_EXT_DSP_P ()" -++ "#" -++ "NDS32_EXT_DSP_P ()" -++ [(const_int 0)] -++{ -++ rtx high_part_dst, low_part_dst; -++ -++ low_part_dst = nds32_di_low_part_subreg (operands[0]); -++ high_part_dst = nds32_di_high_part_subreg (operands[0]); -++ -++ -++ emit_insn (gen_extendhisi2 (low_part_dst, operands[1])); -++ emit_insn (gen_ashrsi3 (high_part_dst, low_part_dst, GEN_INT (31))); -++ DONE; -++} -++ [(set_attr "type" "alu") -++ (set_attr "length" "4")]) -++ -++(define_insn "extendqihi2" -++ [(set (match_operand:HI 0 "register_operand" "=r") -++ (sign_extend:HI (match_operand:QI 1 "register_operand" " r")))] -++ "NDS32_EXT_DSP_P ()" -++ "sunpkd820\t%0, %1" -++ [(set_attr "type" "dpack") -++ (set_attr "length" "4")]) -++ -++(define_insn "smulsi3_highpart" -++ [(set (match_operand:SI 0 "register_operand" "=r") -++ (truncate:SI -++ (lshiftrt:DI -++ (mult:DI -++ (sign_extend:DI (match_operand:SI 1 "register_operand" " r")) -++ (sign_extend:DI (match_operand:SI 2 "register_operand" " r"))) -++ (const_int 32))))] -++ "NDS32_EXT_DSP_P ()" -++ "smmul\t%0, %1, %2" -++ [(set_attr "type" "dmul") -++ (set_attr "length" "4")]) -++ -++(define_insn "smmul_round" -++ [(set (match_operand:SI 0 "register_operand" "=r") -++ (truncate:SI -++ (lshiftrt:DI -++ (unspec:DI [(mult:DI -++ (sign_extend:DI (match_operand:SI 1 "register_operand" " r")) -++ (sign_extend:DI (match_operand:SI 2 "register_operand" " r")))] -++ UNSPEC_ROUND) -++ (const_int 32))))] -++ "NDS32_EXT_DSP_P ()" -++ "smmul.u\t%0, %1, %2" -++ [(set_attr "type" "dmul") -++ (set_attr "length" "4")]) -++ -++(define_insn "kmmac" -++ [(set (match_operand:SI 0 "register_operand" "=r") -++ (ss_plus:SI (match_operand:SI 1 "register_operand" " 0") -++ (truncate:SI -++ (lshiftrt:DI -++ (mult:DI -++ (sign_extend:DI (match_operand:SI 2 "register_operand" " r")) -++ (sign_extend:DI (match_operand:SI 3 "register_operand" " r"))) -++ (const_int 32)))))] -++ "NDS32_EXT_DSP_P ()" -++ "kmmac\t%0, %2, %3" -++ [(set_attr "type" "dmac") -++ (set_attr "length" "4")]) -++ -++(define_insn "kmmac_round" -++ [(set (match_operand:SI 0 "register_operand" "=r") -++ (ss_plus:SI (match_operand:SI 1 "register_operand" " 0") -++ (truncate:SI -++ (lshiftrt:DI -++ (unspec:DI [(mult:DI -++ (sign_extend:DI (match_operand:SI 2 "register_operand" " r")) -++ (sign_extend:DI (match_operand:SI 3 "register_operand" " r")))] -++ UNSPEC_ROUND) -++ (const_int 32)))))] -++ "NDS32_EXT_DSP_P ()" -++ "kmmac.u\t%0, %2, %3" -++ [(set_attr "type" "dmac") -++ (set_attr "length" "4")]) -++ -++(define_insn "kmmsb" -++ [(set (match_operand:SI 0 "register_operand" "=r") -++ (ss_minus:SI (match_operand:SI 1 "register_operand" " 0") -++ (truncate:SI -++ (lshiftrt:DI -++ (mult:DI -++ (sign_extend:DI (match_operand:SI 2 "register_operand" " r")) -++ (sign_extend:DI (match_operand:SI 3 "register_operand" " r"))) -++ (const_int 32)))))] -++ "NDS32_EXT_DSP_P ()" -++ "kmmsb\t%0, %2, %3" -++ [(set_attr "type" "dmac") -++ (set_attr "length" "4")]) -++ -++(define_insn "kmmsb_round" -++ [(set (match_operand:SI 0 "register_operand" "=r") -++ (ss_minus:SI (match_operand:SI 1 "register_operand" " 0") -++ (truncate:SI -++ (lshiftrt:DI -++ (unspec:DI [(mult:DI -++ (sign_extend:DI (match_operand:SI 2 "register_operand" " r")) -++ (sign_extend:DI (match_operand:SI 3 "register_operand" " r")))] -++ UNSPEC_ROUND) -++ (const_int 32)))))] -++ "NDS32_EXT_DSP_P ()" -++ "kmmsb.u\t%0, %2, %3" -++ [(set_attr "type" "dmac") -++ (set_attr "length" "4")]) -++ -++(define_insn "kwmmul" -++ [(set (match_operand:SI 0 "register_operand" "=r") -++ (truncate:SI -++ (lshiftrt:DI -++ (ss_mult:DI -++ (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" " r")) (const_int 2)) -++ (mult:DI (sign_extend:DI (match_operand:SI 2 "register_operand" " r")) (const_int 2))) -++ (const_int 32))))] -++ "NDS32_EXT_DSP_P ()" -++ "kwmmul\t%0, %1, %2" -++ [(set_attr "type" "dmul") -++ (set_attr "length" "4")]) -++ -++(define_insn "kwmmul_round" -++ [(set (match_operand:SI 0 "register_operand" "=r") -++ (truncate:SI -++ (lshiftrt:DI -++ (unspec:DI [ -++ (ss_mult:DI -++ (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" " r")) (const_int 2)) -++ (mult:DI (sign_extend:DI (match_operand:SI 2 "register_operand" " r")) (const_int 2)))] -++ UNSPEC_ROUND) -++ (const_int 32))))] -++ "NDS32_EXT_DSP_P ()" -++ "kwmmul.u\t%0, %1, %2" -++ [(set_attr "type" "dmul") -++ (set_attr "length" "4")]) -++ -++(define_expand "smmwb" -++ [(match_operand:SI 0 "register_operand" "") -++ (match_operand:SI 1 "register_operand" "") -++ (match_operand:V2HI 2 "register_operand" "")] -++ "NDS32_EXT_DSP_P ()" -++{ -++ if (TARGET_BIG_ENDIAN) -++ emit_insn (gen_smulhisi3_highpart_1 (operands[0], operands[1], operands[2], GEN_INT (1))); -++ else -++ emit_insn (gen_smulhisi3_highpart_1 (operands[0], operands[1], operands[2], GEN_INT (0))); -++ DONE; -++}) -++ -++(define_expand "smmwt" -++ [(match_operand:SI 0 "register_operand" "") -++ (match_operand:SI 1 "register_operand" "") -++ (match_operand:V2HI 2 "register_operand" "")] -++ "NDS32_EXT_DSP_P ()" -++{ -++ if (TARGET_BIG_ENDIAN) -++ emit_insn (gen_smulhisi3_highpart_1 (operands[0], operands[1], operands[2], GEN_INT (0))); -++ else -++ emit_insn (gen_smulhisi3_highpart_1 (operands[0], operands[1], operands[2], GEN_INT (1))); -++ DONE; -++}) -++ -++(define_insn "smulhisi3_highpart_1" -++ [(set (match_operand:SI 0 "register_operand" "= r, r") -++ (truncate:SI -++ (lshiftrt:DI -++ (mult:DI -++ (sign_extend:DI (match_operand:SI 1 "register_operand" " r, r")) -++ (sign_extend:DI -++ (vec_select:HI -++ (match_operand:V2HI 2 "register_operand" " r, r") -++ (parallel [(match_operand:SI 3 "nds32_imm_0_1_operand" " Iv00, Iv01")])))) -++ (const_int 16))))] -++ "NDS32_EXT_DSP_P ()" -++{ -++ if (TARGET_BIG_ENDIAN) -++ { -++ const char *pats[] = { "smmwt\t%0, %1, %2", -++ "smmwb\t%0, %1, %2" }; -++ return pats[which_alternative]; -++ } -++ else -++ { -++ const char *pats[] = { "smmwb\t%0, %1, %2", -++ "smmwt\t%0, %1, %2" }; -++ return pats[which_alternative]; -++ } -++} -++ [(set_attr "type" "dmul") -++ (set_attr "length" "4")]) -++ -++(define_insn "smulhisi3_highpart_2" -++ [(set (match_operand:SI 0 "register_operand" "= r, r") -++ (truncate:SI -++ (lshiftrt:DI -++ (mult:DI -++ (sign_extend:DI -++ (vec_select:HI -++ (match_operand:V2HI 1 "register_operand" " r, r") -++ (parallel [(match_operand:SI 3 "nds32_imm_0_1_operand" " Iv00, Iv01")]))) -++ (sign_extend:DI (match_operand:SI 2 "register_operand" " r, r"))) -++ (const_int 16))))] -++ "NDS32_EXT_DSP_P ()" -++{ -++ if (TARGET_BIG_ENDIAN) -++ { -++ const char *pats[] = { "smmwt\t%0, %1, %2", -++ "smmwb\t%0, %1, %2" }; -++ return pats[which_alternative]; -++ } -++ else -++ { -++ const char *pats[] = { "smmwb\t%0, %1, %2", -++ "smmwt\t%0, %1, %2" }; -++ return pats[which_alternative]; -++ } -++} -++ [(set_attr "type" "dmul") -++ (set_attr "length" "4")]) -++ -++(define_expand "smmwb_round" -++ [(match_operand:SI 0 "register_operand" "") -++ (match_operand:SI 1 "register_operand" "") -++ (match_operand:V2HI 2 "register_operand" "")] -++ "NDS32_EXT_DSP_P ()" -++{ -++ if (TARGET_BIG_ENDIAN) -++ emit_insn (gen_smmw_round_internal (operands[0], operands[1], operands[2], GEN_INT (1))); -++ else -++ emit_insn (gen_smmw_round_internal (operands[0], operands[1], operands[2], GEN_INT (0))); -++ DONE; -++}) -++ -++(define_expand "smmwt_round" -++ [(match_operand:SI 0 "register_operand" "") -++ (match_operand:SI 1 "register_operand" "") -++ (match_operand:V2HI 2 "register_operand" "")] -++ "NDS32_EXT_DSP_P ()" -++{ -++ if (TARGET_BIG_ENDIAN) -++ emit_insn (gen_smmw_round_internal (operands[0], operands[1], operands[2], GEN_INT (0))); -++ else -++ emit_insn (gen_smmw_round_internal (operands[0], operands[1], operands[2], GEN_INT (1))); -++ DONE; -++}) -++ -++(define_insn "smmw_round_internal" -++ [(set (match_operand:SI 0 "register_operand" "= r, r") -++ (truncate:SI -++ (lshiftrt:DI -++ (unspec:DI -++ [(mult:DI -++ (sign_extend:DI (match_operand:SI 1 "register_operand" " r, r")) -++ (sign_extend:DI -++ (vec_select:HI -++ (match_operand:V2HI 2 "register_operand" " r, r") -++ (parallel [(match_operand:SI 3 "nds32_imm_0_1_operand" " Iv00, Iv01")]))))] -++ UNSPEC_ROUND) -++ (const_int 16))))] -++ "NDS32_EXT_DSP_P ()" -++{ -++ if (TARGET_BIG_ENDIAN) -++ { -++ const char *pats[] = { "smmwt.u\t%0, %1, %2", -++ "smmwb.u\t%0, %1, %2" }; -++ return pats[which_alternative]; -++ } -++ else -++ { -++ const char *pats[] = { "smmwb.u\t%0, %1, %2", -++ "smmwt.u\t%0, %1, %2" }; -++ return pats[which_alternative]; -++ } -++} -++ [(set_attr "type" "dmul") -++ (set_attr "length" "4")]) -++ -++(define_expand "kmmawb" -++ [(match_operand:SI 0 "register_operand" "") -++ (match_operand:SI 1 "register_operand" "") -++ (match_operand:SI 2 "register_operand" "") -++ (match_operand:V2HI 3 "register_operand" "")] -++ "NDS32_EXT_DSP_P ()" -++{ -++ if (TARGET_BIG_ENDIAN) -++ emit_insn (gen_kmmaw_internal (operands[0], operands[2], operands[3], GEN_INT (1), operands[1])); -++ else -++ emit_insn (gen_kmmaw_internal (operands[0], operands[2], operands[3], GEN_INT (0), operands[1])); -++ DONE; -++}) -++ -++(define_expand "kmmawt" -++ [(match_operand:SI 0 "register_operand" "") -++ (match_operand:SI 1 "register_operand" "") -++ (match_operand:SI 2 "register_operand" "") -++ (match_operand:V2HI 3 "register_operand" "")] -++ "NDS32_EXT_DSP_P ()" -++{ -++ if (TARGET_BIG_ENDIAN) -++ emit_insn (gen_kmmaw_internal (operands[0], operands[2], operands[3], GEN_INT (0), operands[1])); -++ else -++ emit_insn (gen_kmmaw_internal (operands[0], operands[2], operands[3], GEN_INT (1), operands[1])); -++ DONE; -++}) -++ -++(define_insn "kmmaw_internal" -++ [(set (match_operand:SI 0 "register_operand" "= r, r") -++ (ss_plus:SI -++ (match_operand:SI 4 "register_operand" " 0, 0") -++ (truncate:SI -++ (lshiftrt:DI -++ (mult:DI -++ (sign_extend:DI (match_operand:SI 1 "register_operand" " r, r")) -++ (sign_extend:DI -++ (vec_select:HI -++ (match_operand:V2HI 2 "register_operand" " r, r") -++ (parallel [(match_operand:SI 3 "nds32_imm_0_1_operand" " Iv00, Iv01")])))) -++ (const_int 16)))))] -++ "NDS32_EXT_DSP_P ()" -++{ -++ if (TARGET_BIG_ENDIAN) -++ { -++ const char *pats[] = { "kmmawt\t%0, %1, %2", -++ "kmmawb\t%0, %1, %2" }; -++ return pats[which_alternative]; -++ } -++ else -++ { -++ const char *pats[] = { "kmmawb\t%0, %1, %2", -++ "kmmawt\t%0, %1, %2" }; -++ return pats[which_alternative]; -++ } -++} -++ [(set_attr "type" "dmac") -++ (set_attr "length" "4")]) -++ -++(define_expand "kmmawb_round" -++ [(match_operand:SI 0 "register_operand" "") -++ (match_operand:SI 1 "register_operand" "") -++ (match_operand:SI 2 "register_operand" "") -++ (match_operand:V2HI 3 "register_operand" "")] -++ "NDS32_EXT_DSP_P ()" -++{ -++ if (TARGET_BIG_ENDIAN) -++ emit_insn (gen_kmmaw_round_internal (operands[0], operands[2], operands[3], GEN_INT (1), operands[1])); -++ else -++ emit_insn (gen_kmmaw_round_internal (operands[0], operands[2], operands[3], GEN_INT (0), operands[1])); -++ DONE; -++} -++ [(set_attr "type" "alu") -++ (set_attr "length" "4")]) -++ -++(define_expand "kmmawt_round" -++ [(match_operand:SI 0 "register_operand" "") -++ (match_operand:SI 1 "register_operand" "") -++ (match_operand:SI 2 "register_operand" "") -++ (match_operand:V2HI 3 "register_operand" "")] -++ "NDS32_EXT_DSP_P ()" -++{ -++ if (TARGET_BIG_ENDIAN) -++ emit_insn (gen_kmmaw_round_internal (operands[0], operands[2], operands[3], GEN_INT (0), operands[1])); -++ else -++ emit_insn (gen_kmmaw_round_internal (operands[0], operands[2], operands[3], GEN_INT (1), operands[1])); -++ DONE; -++} -++ [(set_attr "type" "dmac") -++ (set_attr "length" "4")]) -++ -++ -++(define_insn "kmmaw_round_internal" -++ [(set (match_operand:SI 0 "register_operand" "= r, r") -++ (ss_plus:SI -++ (match_operand:SI 4 "register_operand" " 0, 0") -++ (truncate:SI -++ (lshiftrt:DI -++ (unspec:DI -++ [(mult:DI -++ (sign_extend:DI (match_operand:SI 1 "register_operand" " r, r")) -++ (sign_extend:DI -++ (vec_select:HI -++ (match_operand:V2HI 2 "register_operand" " r, r") -++ (parallel [(match_operand:SI 3 "nds32_imm_0_1_operand" " Iv00, Iv01")]))))] -++ UNSPEC_ROUND) -++ (const_int 16)))))] -++ "NDS32_EXT_DSP_P ()" -++{ -++ if (TARGET_BIG_ENDIAN) -++ { -++ const char *pats[] = { "kmmawt.u\t%0, %1, %2", -++ "kmmawb.u\t%0, %1, %2" }; -++ return pats[which_alternative]; -++ } -++ else -++ { -++ const char *pats[] = { "kmmawb.u\t%0, %1, %2", -++ "kmmawt.u\t%0, %1, %2" }; -++ return pats[which_alternative]; -++ } -++} -++ [(set_attr "type" "dmac") -++ (set_attr "length" "4")]) -++ -++(define_expand "smalbb" -++ [(match_operand:DI 0 "register_operand" "") -++ (match_operand:DI 1 "register_operand" "") -++ (match_operand:V2HI 2 "register_operand" "") -++ (match_operand:V2HI 3 "register_operand" "")] -++ "NDS32_EXT_DSP_P ()" -++{ -++ if (TARGET_BIG_ENDIAN) -++ emit_insn (gen_smaddhidi (operands[0], operands[2], -++ operands[3], operands[1], -++ GEN_INT (1), GEN_INT (1))); -++ else -++ emit_insn (gen_smaddhidi (operands[0], operands[2], -++ operands[3], operands[1], -++ GEN_INT (0), GEN_INT (0))); -++ DONE; -++}) -++ -++(define_expand "smalbt" -++ [(match_operand:DI 0 "register_operand" "") -++ (match_operand:DI 1 "register_operand" "") -++ (match_operand:V2HI 2 "register_operand" "") -++ (match_operand:V2HI 3 "register_operand" "")] -++ "NDS32_EXT_DSP_P ()" -++{ -++ if (TARGET_BIG_ENDIAN) -++ emit_insn (gen_smaddhidi (operands[0], operands[2], -++ operands[3], operands[1], -++ GEN_INT (1), GEN_INT (0))); -++ else -++ emit_insn (gen_smaddhidi (operands[0], operands[2], -++ operands[3], operands[1], -++ GEN_INT (0), GEN_INT (1))); -++ DONE; -++}) -++ -++(define_expand "smaltt" -++ [(match_operand:DI 0 "register_operand" "") -++ (match_operand:DI 1 "register_operand" "") -++ (match_operand:V2HI 2 "register_operand" "") -++ (match_operand:V2HI 3 "register_operand" "")] -++ "NDS32_EXT_DSP_P ()" -++{ -++ if (TARGET_BIG_ENDIAN) -++ emit_insn (gen_smaddhidi (operands[0], operands[2], -++ operands[3], operands[1], -++ GEN_INT (0), GEN_INT (0))); -++ else -++ emit_insn (gen_smaddhidi (operands[0], operands[2], -++ operands[3], operands[1], -++ GEN_INT (1), GEN_INT (1))); -++ DONE; -++}) -++ -++(define_insn "smaddhidi" -++ [(set (match_operand:DI 0 "register_operand" "= r, r, r, r") -++ (plus:DI -++ (match_operand:DI 3 "register_operand" " 0, 0, 0, 0") -++ (mult:DI -++ (sign_extend:DI -++ (vec_select:HI -++ (match_operand:V2HI 1 "register_operand" " r, r, r, r") -++ (parallel [(match_operand:SI 4 "nds32_imm_0_1_operand" " Iv00, Iv00, Iv01, Iv01")]))) -++ (sign_extend:DI -++ (vec_select:HI -++ (match_operand:V2HI 2 "register_operand" " r, r, r, r") -++ (parallel [(match_operand:SI 5 "nds32_imm_0_1_operand" " Iv00, Iv01, Iv01, Iv00")]))))))] -++ "NDS32_EXT_DSP_P ()" -++{ -++ if (TARGET_BIG_ENDIAN) -++ { -++ const char *pats[] = { "smaltt\t%0, %1, %2", -++ "smalbt\t%0, %2, %1", -++ "smalbb\t%0, %1, %2", -++ "smalbt\t%0, %1, %2" }; -++ return pats[which_alternative]; -++ } -++ else -++ { -++ const char *pats[] = { "smalbb\t%0, %1, %2", -++ "smalbt\t%0, %1, %2", -++ "smaltt\t%0, %1, %2", -++ "smalbt\t%0, %2, %1" }; -++ return pats[which_alternative]; -++ } -++} -++ [(set_attr "type" "dmac") -++ (set_attr "length" "4")]) -++ -++(define_insn "smaddhidi2" -++ [(set (match_operand:DI 0 "register_operand" "= r, r, r, r") -++ (plus:DI -++ (mult:DI -++ (sign_extend:DI -++ (vec_select:HI -++ (match_operand:V2HI 1 "register_operand" " r, r, r, r") -++ (parallel [(match_operand:SI 4 "nds32_imm_0_1_operand" " Iv00, Iv00, Iv01, Iv01")]))) -++ (sign_extend:DI -++ (vec_select:HI -++ (match_operand:V2HI 2 "register_operand" " r, r, r, r") -++ (parallel [(match_operand:SI 5 "nds32_imm_0_1_operand" " Iv00, Iv01, Iv01, Iv00")])))) -++ (match_operand:DI 3 "register_operand" " 0, 0, 0, 0")))] -++ "NDS32_EXT_DSP_P ()" -++{ -++ if (TARGET_BIG_ENDIAN) -++ { -++ const char *pats[] = { "smaltt\t%0, %1, %2", -++ "smalbt\t%0, %2, %1", -++ "smalbb\t%0, %1, %2", -++ "smalbt\t%0, %1, %2" }; -++ return pats[which_alternative]; -++ } -++ else -++ { -++ const char *pats[] = { "smalbb\t%0, %1, %2", -++ "smalbt\t%0, %1, %2", -++ "smaltt\t%0, %1, %2", -++ "smalbt\t%0, %2, %1" }; -++ return pats[which_alternative]; -++ } -++} -++ [(set_attr "type" "dmac") -++ (set_attr "length" "4")]) -++ -++(define_expand "smalda1" -++ [(match_operand:DI 0 "register_operand" "") -++ (match_operand:DI 1 "register_operand" "") -++ (match_operand:V2HI 2 "register_operand" " r") -++ (match_operand:V2HI 3 "register_operand" " r")] -++ "NDS32_EXT_DSP_P ()" -++{ -++ if (TARGET_BIG_ENDIAN) -++ emit_insn (gen_smalda1_be (operands[0], operands[1], operands[2], operands[3])); -++ else -++ emit_insn (gen_smalda1_le (operands[0], operands[1], operands[2], operands[3])); -++ DONE; -++}) -++ -++(define_expand "smalds1" -++ [(match_operand:DI 0 "register_operand" "") -++ (match_operand:DI 1 "register_operand" "") -++ (match_operand:V2HI 2 "register_operand" " r") -++ (match_operand:V2HI 3 "register_operand" " r")] -++ "NDS32_EXT_DSP_P ()" -++{ -++ if (TARGET_BIG_ENDIAN) -++ emit_insn (gen_smalds1_be (operands[0], operands[1], operands[2], operands[3])); -++ else -++ emit_insn (gen_smalds1_le (operands[0], operands[1], operands[2], operands[3])); -++ DONE; -++}) -++ -++(define_insn "smalda1_le" -++ [(set (match_operand:DI 0 "register_operand" "=r") -++ (plus:DI -++ (match_operand:DI 1 "register_operand" " 0") -++ (sign_extend:DI -++ (plus:SI -++ (mult:SI -++ (sign_extend:SI (vec_select:HI -++ (match_operand:V2HI 2 "register_operand" " r") -++ (parallel [(const_int 1)]))) -++ (sign_extend:SI (vec_select:HI -++ (match_operand:V2HI 3 "register_operand" " r") -++ (parallel [(const_int 1)])))) -++ (mult:SI -++ (sign_extend:SI (vec_select:HI -++ (match_dup 2) -++ (parallel [(const_int 0)]))) -++ (sign_extend:SI (vec_select:HI -++ (match_dup 3) -++ (parallel [(const_int 0)]))))))))] -++ "NDS32_EXT_DSP_P () && !TARGET_BIG_ENDIAN" -++ "smalda\t%0, %2, %3" -++ [(set_attr "type" "dmac") -++ (set_attr "length" "4")]) -++ -++(define_insn "smalds1_le" -++ [(set (match_operand:DI 0 "register_operand" "=r") -++ (plus:DI -++ (match_operand:DI 1 "register_operand" " 0") -++ (sign_extend:DI -++ (minus:SI -++ (mult:SI -++ (sign_extend:SI (vec_select:HI -++ (match_operand:V2HI 2 "register_operand" " r") -++ (parallel [(const_int 1)]))) -++ (sign_extend:SI (vec_select:HI -++ (match_operand:V2HI 3 "register_operand" " r") -++ (parallel [(const_int 1)])))) -++ (mult:SI -++ (sign_extend:SI (vec_select:HI -++ (match_dup 2) -++ (parallel [(const_int 0)]))) -++ (sign_extend:SI (vec_select:HI -++ (match_dup 3) -++ (parallel [(const_int 0)]))))))))] -++ "NDS32_EXT_DSP_P () && !TARGET_BIG_ENDIAN" -++ "smalds\t%0, %2, %3" -++ [(set_attr "type" "dmac") -++ (set_attr "length" "4")]) -++ -++(define_insn "smalda1_be" -++ [(set (match_operand:DI 0 "register_operand" "=r") -++ (plus:DI -++ (match_operand:DI 1 "register_operand" " 0") -++ (sign_extend:DI -++ (plus:SI -++ (mult:SI -++ (sign_extend:SI (vec_select:HI -++ (match_operand:V2HI 2 "register_operand" " r") -++ (parallel [(const_int 0)]))) -++ (sign_extend:SI (vec_select:HI -++ (match_operand:V2HI 3 "register_operand" " r") -++ (parallel [(const_int 0)])))) -++ (mult:SI -++ (sign_extend:SI (vec_select:HI -++ (match_dup 2) -++ (parallel [(const_int 1)]))) -++ (sign_extend:SI (vec_select:HI -++ (match_dup 3) -++ (parallel [(const_int 1)]))))))))] -++ "NDS32_EXT_DSP_P () && TARGET_BIG_ENDIAN" -++ "smalda\t%0, %2, %3" -++ [(set_attr "type" "dmac") -++ (set_attr "length" "4")]) -++ -++(define_insn "smalds1_be" -++ [(set (match_operand:DI 0 "register_operand" "=r") -++ (plus:DI -++ (match_operand:DI 1 "register_operand" " 0") -++ (sign_extend:DI -++ (minus:SI -++ (mult:SI -++ (sign_extend:SI (vec_select:HI -++ (match_operand:V2HI 2 "register_operand" " r") -++ (parallel [(const_int 0)]))) -++ (sign_extend:SI (vec_select:HI -++ (match_operand:V2HI 3 "register_operand" " r") -++ (parallel [(const_int 0)])))) -++ (mult:SI -++ (sign_extend:SI (vec_select:HI -++ (match_dup 2) -++ (parallel [(const_int 1)]))) -++ (sign_extend:SI (vec_select:HI -++ (match_dup 3) -++ (parallel [(const_int 1)]))))))))] -++ "NDS32_EXT_DSP_P () && TARGET_BIG_ENDIAN" -++ "smalds\t%0, %2, %3" -++ [(set_attr "type" "dmac") -++ (set_attr "length" "4")]) -++ -++(define_expand "smaldrs3" -++ [(match_operand:DI 0 "register_operand" "") -++ (match_operand:DI 1 "register_operand" "") -++ (match_operand:V2HI 2 "register_operand" " r") -++ (match_operand:V2HI 3 "register_operand" " r")] -++ "NDS32_EXT_DSP_P ()" -++{ -++ if (TARGET_BIG_ENDIAN) -++ emit_insn (gen_smaldrs3_be (operands[0], operands[1], operands[2], operands[3])); -++ else -++ emit_insn (gen_smaldrs3_le (operands[0], operands[1], operands[2], operands[3])); -++ DONE; -++}) -++ -++(define_insn "smaldrs3_le" -++ [(set (match_operand:DI 0 "register_operand" "=r") -++ (plus:DI -++ (match_operand:DI 1 "register_operand" " 0") -++ (sign_extend:DI -++ (minus:SI -++ (mult:SI -++ (sign_extend:SI (vec_select:HI -++ (match_operand:V2HI 2 "register_operand" " r") -++ (parallel [(const_int 0)]))) -++ (sign_extend:SI (vec_select:HI -++ (match_operand:V2HI 3 "register_operand" " r") -++ (parallel [(const_int 0)])))) -++ (mult:SI -++ (sign_extend:SI (vec_select:HI -++ (match_dup 2) -++ (parallel [(const_int 1)]))) -++ (sign_extend:SI (vec_select:HI -++ (match_dup 3) -++ (parallel [(const_int 1)]))))))))] -++ "NDS32_EXT_DSP_P () && !TARGET_BIG_ENDIAN" -++ "smaldrs\t%0, %2, %3" -++ [(set_attr "type" "dmac") -++ (set_attr "length" "4")]) -++ -++(define_insn "smaldrs3_be" -++ [(set (match_operand:DI 0 "register_operand" "=r") -++ (plus:DI -++ (match_operand:DI 1 "register_operand" " 0") -++ (sign_extend:DI -++ (minus:SI -++ (mult:SI -++ (sign_extend:SI (vec_select:HI -++ (match_operand:V2HI 2 "register_operand" " r") -++ (parallel [(const_int 1)]))) -++ (sign_extend:SI (vec_select:HI -++ (match_operand:V2HI 3 "register_operand" " r") -++ (parallel [(const_int 1)])))) -++ (mult:SI -++ (sign_extend:SI (vec_select:HI -++ (match_dup 2) -++ (parallel [(const_int 0)]))) -++ (sign_extend:SI (vec_select:HI -++ (match_dup 3) -++ (parallel [(const_int 0)]))))))))] -++ "NDS32_EXT_DSP_P () && TARGET_BIG_ENDIAN" -++ "smaldrs\t%0, %2, %3" -++ [(set_attr "type" "dmac") -++ (set_attr "length" "4")]) -++ -++(define_expand "smalxda1" -++ [(match_operand:DI 0 "register_operand" "") -++ (match_operand:DI 1 "register_operand" "") -++ (match_operand:V2HI 2 "register_operand" " r") -++ (match_operand:V2HI 3 "register_operand" " r")] -++ "NDS32_EXT_DSP_P ()" -++{ -++ if (TARGET_BIG_ENDIAN) -++ emit_insn (gen_smalxda1_be (operands[0], operands[1], operands[2], operands[3])); -++ else -++ emit_insn (gen_smalxda1_le (operands[0], operands[1], operands[2], operands[3])); -++ DONE; -++}) -++ -++(define_expand "smalxds1" -++ [(match_operand:DI 0 "register_operand" "") -++ (match_operand:DI 1 "register_operand" "") -++ (match_operand:V2HI 2 "register_operand" " r") -++ (match_operand:V2HI 3 "register_operand" " r")] -++ "NDS32_EXT_DSP_P ()" -++{ -++ if (TARGET_BIG_ENDIAN) -++ emit_insn (gen_smalxds1_be (operands[0], operands[1], operands[2], operands[3])); -++ else -++ emit_insn (gen_smalxds1_le (operands[0], operands[1], operands[2], operands[3])); -++ DONE; -++}) -++ -++(define_insn "smalxd1_le" -++ [(set (match_operand:DI 0 "register_operand" "=r") -++ (plus:DI -++ (match_operand:DI 1 "register_operand" " 0") -++ (sign_extend:DI -++ (plus_minus:SI -++ (mult:SI -++ (sign_extend:SI (vec_select:HI -++ (match_operand:V2HI 2 "register_operand" " r") -++ (parallel [(const_int 1)]))) -++ (sign_extend:SI (vec_select:HI -++ (match_operand:V2HI 3 "register_operand" " r") -++ (parallel [(const_int 0)])))) -++ (mult:SI -++ (sign_extend:SI (vec_select:HI -++ (match_dup 2) -++ (parallel [(const_int 0)]))) -++ (sign_extend:SI (vec_select:HI -++ (match_dup 3) -++ (parallel [(const_int 1)]))))))))] -++ "NDS32_EXT_DSP_P () && !TARGET_BIG_ENDIAN" -++ "smalxd\t%0, %2, %3" -++ [(set_attr "type" "dmac") -++ (set_attr "length" "4")]) -++ -++ -++(define_insn "smalxd1_be" -++ [(set (match_operand:DI 0 "register_operand" "=r") -++ (plus:DI -++ (match_operand:DI 1 "register_operand" " 0") -++ (sign_extend:DI -++ (plus_minus:SI -++ (mult:SI -++ (sign_extend:SI (vec_select:HI -++ (match_operand:V2HI 2 "register_operand" " r") -++ (parallel [(const_int 0)]))) -++ (sign_extend:SI (vec_select:HI -++ (match_operand:V2HI 3 "register_operand" " r") -++ (parallel [(const_int 1)])))) -++ (mult:SI -++ (sign_extend:SI (vec_select:HI -++ (match_dup 2) -++ (parallel [(const_int 1)]))) -++ (sign_extend:SI (vec_select:HI -++ (match_dup 3) -++ (parallel [(const_int 0)]))))))))] -++ "NDS32_EXT_DSP_P () && TARGET_BIG_ENDIAN" -++ "smalxd\t%0, %2, %3" -++ [(set_attr "type" "dmac") -++ (set_attr "length" "4")]) -++ -++(define_insn "smslda1" -++ [(set (match_operand:DI 0 "register_operand" "=r") -++ (minus:DI -++ (minus:DI -++ (match_operand:DI 1 "register_operand" " 0") -++ (sign_extend:DI -++ (mult:SI -++ (sign_extend:SI (vec_select:HI -++ (match_operand:V2HI 2 "register_operand" " r") -++ (parallel [(const_int 1)]))) -++ (sign_extend:SI (vec_select:HI -++ (match_operand:V2HI 3 "register_operand" " r") -++ (parallel [(const_int 1)])))))) -++ (sign_extend:DI -++ (mult:SI -++ (sign_extend:SI (vec_select:HI -++ (match_dup 2) -++ (parallel [(const_int 0)]))) -++ (sign_extend:SI (vec_select:HI -++ (match_dup 3) -++ (parallel [(const_int 0)])))))))] -++ "NDS32_EXT_DSP_P ()" -++ "smslda\t%0, %2, %3" -++ [(set_attr "type" "dmac") -++ (set_attr "length" "4")]) -++ -++(define_insn "smslxda1" -++ [(set (match_operand:DI 0 "register_operand" "=r") -++ (minus:DI -++ (minus:DI -++ (match_operand:DI 1 "register_operand" " 0") -++ (sign_extend:DI -++ (mult:SI -++ (sign_extend:SI (vec_select:HI -++ (match_operand:V2HI 2 "register_operand" " r") -++ (parallel [(const_int 1)]))) -++ (sign_extend:SI (vec_select:HI -++ (match_operand:V2HI 3 "register_operand" " r") -++ (parallel [(const_int 0)])))))) -++ (sign_extend:DI -++ (mult:SI -++ (sign_extend:SI (vec_select:HI -++ (match_dup 2) -++ (parallel [(const_int 0)]))) -++ (sign_extend:SI (vec_select:HI -++ (match_dup 3) -++ (parallel [(const_int 1)])))))))] -++ "NDS32_EXT_DSP_P ()" -++ "smslxda\t%0, %2, %3" -++ [(set_attr "type" "dmac") -++ (set_attr "length" "4")]) -++ -++;; mada for synthetize smalda -++(define_insn_and_split "mada1" -++ [(set (match_operand:SI 0 "register_operand" "=r") -++ (plus:SI -++ (mult:SI -++ (sign_extend:SI (vec_select:HI -++ (match_operand:V2HI 1 "register_operand" "r") -++ (parallel [(match_operand:SI 3 "nds32_imm_0_1_operand" " Iu01")]))) -++ (sign_extend:SI (vec_select:HI -++ (match_operand:V2HI 2 "register_operand" "r") -++ (parallel [(match_operand:SI 4 "nds32_imm_0_1_operand" " Iu01")])))) -++ (mult:SI -++ (sign_extend:SI (vec_select:HI -++ (match_dup 1) -++ (parallel [(match_operand:SI 5 "nds32_imm_0_1_operand" " Iu01")]))) -++ (sign_extend:SI (vec_select:HI -++ (match_dup 2) -++ (parallel [(match_operand:SI 6 "nds32_imm_0_1_operand" " Iu01")]))))))] -++ "NDS32_EXT_DSP_P () && !reload_completed" -++ "#" -++ "NDS32_EXT_DSP_P () && !reload_completed" -++ [(const_int 1)] -++{ -++ rtx result0 = gen_reg_rtx (SImode); -++ rtx result1 = gen_reg_rtx (SImode); -++ emit_insn (gen_mulhisi3v (result0, operands[1], operands[2], -++ operands[3], operands[4])); -++ emit_insn (gen_mulhisi3v (result1, operands[1], operands[2], -++ operands[5], operands[6])); -++ emit_insn (gen_addsi3 (operands[0], result0, result1)); -++ DONE; -++}) -++ -++(define_insn_and_split "mada2" -++ [(set (match_operand:SI 0 "register_operand" "=r") -++ (plus:SI -++ (mult:SI -++ (sign_extend:SI (vec_select:HI -++ (match_operand:V2HI 1 "register_operand" "r") -++ (parallel [(match_operand:SI 3 "nds32_imm_0_1_operand" " Iu01")]))) -++ (sign_extend:SI (vec_select:HI -++ (match_operand:V2HI 2 "register_operand" "r") -++ (parallel [(match_operand:SI 4 "nds32_imm_0_1_operand" " Iu01")])))) -++ (mult:SI -++ (sign_extend:SI (vec_select:HI -++ (match_dup 2) -++ (parallel [(match_operand:SI 5 "nds32_imm_0_1_operand" " Iu01")]))) -++ (sign_extend:SI (vec_select:HI -++ (match_dup 1) -++ (parallel [(match_operand:SI 6 "nds32_imm_0_1_operand" " Iu01")]))))))] -++ "NDS32_EXT_DSP_P () && !reload_completed" -++ "#" -++ "NDS32_EXT_DSP_P () && !reload_completed" -++ [(const_int 1)] -++{ -++ rtx result0 = gen_reg_rtx (SImode); -++ rtx result1 = gen_reg_rtx (SImode); -++ emit_insn (gen_mulhisi3v (result0, operands[1], operands[2], -++ operands[3], operands[4])); -++ emit_insn (gen_mulhisi3v (result1, operands[1], operands[2], -++ operands[6], operands[5])); -++ emit_insn (gen_addsi3 (operands[0], result0, result1)); -++ DONE; -++}) -++ -++;; sms for synthetize smalds -++(define_insn_and_split "sms1" -++ [(set (match_operand:SI 0 "register_operand" "= r") -++ (minus:SI -++ (mult:SI -++ (sign_extend:SI (vec_select:HI -++ (match_operand:V2HI 1 "register_operand" " r") -++ (parallel [(match_operand:SI 3 "nds32_imm_0_1_operand" " Iu01")]))) -++ (sign_extend:SI (vec_select:HI -++ (match_operand:V2HI 2 "register_operand" " r") -++ (parallel [(match_operand:SI 4 "nds32_imm_0_1_operand" " Iu01")])))) -++ (mult:SI -++ (sign_extend:SI (vec_select:HI -++ (match_dup 1) -++ (parallel [(match_operand:SI 5 "nds32_imm_0_1_operand" " Iu01")]))) -++ (sign_extend:SI (vec_select:HI -++ (match_dup 2) -++ (parallel [(match_operand:SI 6 "nds32_imm_0_1_operand" " Iu01")]))))))] -++ "NDS32_EXT_DSP_P () -++ && (!reload_completed -++ || !nds32_need_split_sms_p (operands[3], operands[4], -++ operands[5], operands[6]))" -++ -++{ -++ return nds32_output_sms (operands[3], operands[4], -++ operands[5], operands[6]); -++} -++ "NDS32_EXT_DSP_P () -++ && !reload_completed -++ && nds32_need_split_sms_p (operands[3], operands[4], -++ operands[5], operands[6])" -++ [(const_int 1)] -++{ -++ nds32_split_sms (operands[0], operands[1], operands[2], -++ operands[3], operands[4], -++ operands[5], operands[6]); -++ DONE; -++} -++ [(set_attr "type" "dmac") -++ (set_attr "length" "4")]) -++ -++(define_insn_and_split "sms2" -++ [(set (match_operand:SI 0 "register_operand" "= r") -++ (minus:SI -++ (mult:SI -++ (sign_extend:SI (vec_select:HI -++ (match_operand:V2HI 1 "register_operand" " r") -++ (parallel [(match_operand:SI 3 "nds32_imm_0_1_operand" " Iu01")]))) -++ (sign_extend:SI (vec_select:HI -++ (match_operand:V2HI 2 "register_operand" " r") -++ (parallel [(match_operand:SI 4 "nds32_imm_0_1_operand" " Iu01")])))) -++ (mult:SI -++ (sign_extend:SI (vec_select:HI -++ (match_dup 2) -++ (parallel [(match_operand:SI 5 "nds32_imm_0_1_operand" " Iu01")]))) -++ (sign_extend:SI (vec_select:HI -++ (match_dup 1) -++ (parallel [(match_operand:SI 6 "nds32_imm_0_1_operand" " Iu01")]))))))] -++ "NDS32_EXT_DSP_P () -++ && (!reload_completed -++ || !nds32_need_split_sms_p (operands[3], operands[4], -++ operands[6], operands[5]))" -++{ -++ return nds32_output_sms (operands[3], operands[4], -++ operands[6], operands[5]); -++} -++ "NDS32_EXT_DSP_P () -++ && !reload_completed -++ && nds32_need_split_sms_p (operands[3], operands[4], -++ operands[6], operands[5])" -++ [(const_int 1)] -++{ -++ nds32_split_sms (operands[0], operands[1], operands[2], -++ operands[3], operands[4], -++ operands[6], operands[5]); -++ DONE; -++} -++ [(set_attr "type" "dmac") -++ (set_attr "length" "4")]) -++ -++(define_insn "kmda" -++ [(set (match_operand:SI 0 "register_operand" "=r") -++ (ss_plus:SI -++ (mult:SI -++ (sign_extend:SI (vec_select:HI -++ (match_operand:V2HI 1 "register_operand" "r") -++ (parallel [(const_int 1)]))) -++ (sign_extend:SI (vec_select:HI -++ (match_operand:V2HI 2 "register_operand" "r") -++ (parallel [(const_int 1)])))) -++ (mult:SI -++ (sign_extend:SI (vec_select:HI -++ (match_dup 1) -++ (parallel [(const_int 0)]))) -++ (sign_extend:SI (vec_select:HI -++ (match_dup 2) -++ (parallel [(const_int 0)]))))))] -++ "NDS32_EXT_DSP_P ()" -++ "kmda\t%0, %1, %2" -++ [(set_attr "type" "dmac") -++ (set_attr "length" "4")]) -++ -++(define_insn "kmxda" -++ [(set (match_operand:SI 0 "register_operand" "=r") -++ (ss_plus:SI -++ (mult:SI -++ (sign_extend:SI (vec_select:HI -++ (match_operand:V2HI 1 "register_operand" "r") -++ (parallel [(const_int 1)]))) -++ (sign_extend:SI (vec_select:HI -++ (match_operand:V2HI 2 "register_operand" "r") -++ (parallel [(const_int 0)])))) -++ (mult:SI -++ (sign_extend:SI (vec_select:HI -++ (match_dup 1) -++ (parallel [(const_int 0)]))) -++ (sign_extend:SI (vec_select:HI -++ (match_dup 2) -++ (parallel [(const_int 1)]))))))] -++ "NDS32_EXT_DSP_P ()" -++ "kmxda\t%0, %1, %2" -++ [(set_attr "type" "dmac") -++ (set_attr "length" "4")]) -++ -++(define_insn "kmada" -++ [(set (match_operand:SI 0 "register_operand" "=r") -++ (ss_plus:SI -++ (match_operand:SI 1 "register_operand" " 0") -++ (ss_plus:SI -++ (mult:SI -++ (sign_extend:SI (vec_select:HI -++ (match_operand:V2HI 2 "register_operand" " r") -++ (parallel [(const_int 1)]))) -++ (sign_extend:SI (vec_select:HI -++ (match_operand:V2HI 3 "register_operand" " r") -++ (parallel [(const_int 1)])))) -++ (mult:SI -++ (sign_extend:SI (vec_select:HI -++ (match_dup 2) -++ (parallel [(const_int 0)]))) -++ (sign_extend:SI (vec_select:HI -++ (match_dup 3) -++ (parallel [(const_int 0)])))))))] -++ "NDS32_EXT_DSP_P ()" -++ "kmada\t%0, %2, %3" -++ [(set_attr "type" "dmac") -++ (set_attr "length" "4")]) -++ -++(define_insn "kmada2" -++ [(set (match_operand:SI 0 "register_operand" "=r") -++ (ss_plus:SI -++ (match_operand:SI 1 "register_operand" " 0") -++ (ss_plus:SI -++ (mult:SI -++ (sign_extend:SI (vec_select:HI -++ (match_operand:V2HI 2 "register_operand" " r") -++ (parallel [(const_int 0)]))) -++ (sign_extend:SI (vec_select:HI -++ (match_operand:V2HI 3 "register_operand" " r") -++ (parallel [(const_int 0)])))) -++ (mult:SI -++ (sign_extend:SI (vec_select:HI -++ (match_dup 2) -++ (parallel [(const_int 1)]))) -++ (sign_extend:SI (vec_select:HI -++ (match_dup 3) -++ (parallel [(const_int 1)])))))))] -++ "NDS32_EXT_DSP_P ()" -++ "kmada\t%0, %2, %3" -++ [(set_attr "type" "dmac") -++ (set_attr "length" "4")]) -++ -++(define_insn "kmaxda" -++ [(set (match_operand:SI 0 "register_operand" "=r") -++ (ss_plus:SI -++ (match_operand:SI 1 "register_operand" " 0") -++ (ss_plus:SI -++ (mult:SI -++ (sign_extend:SI (vec_select:HI -++ (match_operand:V2HI 2 "register_operand" " r") -++ (parallel [(const_int 1)]))) -++ (sign_extend:SI (vec_select:HI -++ (match_operand:V2HI 3 "register_operand" " r") -++ (parallel [(const_int 0)])))) -++ (mult:SI -++ (sign_extend:SI (vec_select:HI -++ (match_dup 2) -++ (parallel [(const_int 0)]))) -++ (sign_extend:SI (vec_select:HI -++ (match_dup 3) -++ (parallel [(const_int 1)])))))))] -++ "NDS32_EXT_DSP_P ()" -++ "kmaxda\t%0, %2, %3" -++ [(set_attr "type" "dmac") -++ (set_attr "length" "4")]) -++ -++(define_insn "kmads" -++ [(set (match_operand:SI 0 "register_operand" "=r") -++ (ss_plus:SI -++ (match_operand:SI 1 "register_operand" " 0") -++ (ss_minus:SI -++ (mult:SI -++ (sign_extend:SI (vec_select:HI -++ (match_operand:V2HI 2 "register_operand" " r") -++ (parallel [(const_int 1)]))) -++ (sign_extend:SI (vec_select:HI -++ (match_operand:V2HI 3 "register_operand" " r") -++ (parallel [(const_int 1)])))) -++ (mult:SI -++ (sign_extend:SI (vec_select:HI -++ (match_dup 2) -++ (parallel [(const_int 0)]))) -++ (sign_extend:SI (vec_select:HI -++ (match_dup 3) -++ (parallel [(const_int 0)])))))))] -++ "NDS32_EXT_DSP_P ()" -++ "kmads\t%0, %2, %3" -++ [(set_attr "type" "dmac") -++ (set_attr "length" "4")]) -++ -++(define_insn "kmadrs" -++ [(set (match_operand:SI 0 "register_operand" "=r") -++ (ss_plus:SI -++ (match_operand:SI 1 "register_operand" " 0") -++ (ss_minus:SI -++ (mult:SI -++ (sign_extend:SI (vec_select:HI -++ (match_operand:V2HI 2 "register_operand" " r") -++ (parallel [(const_int 0)]))) -++ (sign_extend:SI (vec_select:HI -++ (match_operand:V2HI 3 "register_operand" " r") -++ (parallel [(const_int 0)])))) -++ (mult:SI -++ (sign_extend:SI (vec_select:HI -++ (match_dup 2) -++ (parallel [(const_int 1)]))) -++ (sign_extend:SI (vec_select:HI -++ (match_dup 3) -++ (parallel [(const_int 1)])))))))] -++ "NDS32_EXT_DSP_P ()" -++ "kmadrs\t%0, %2, %3" -++ [(set_attr "type" "dmac") -++ (set_attr "length" "4")]) -++ -++(define_insn "kmaxds" -++ [(set (match_operand:SI 0 "register_operand" "=r") -++ (ss_plus:SI -++ (match_operand:SI 1 "register_operand" " 0") -++ (ss_minus:SI -++ (mult:SI -++ (sign_extend:SI (vec_select:HI -++ (match_operand:V2HI 2 "register_operand" " r") -++ (parallel [(const_int 1)]))) -++ (sign_extend:SI (vec_select:HI -++ (match_operand:V2HI 3 "register_operand" " r") -++ (parallel [(const_int 0)])))) -++ (mult:SI -++ (sign_extend:SI (vec_select:HI -++ (match_dup 2) -++ (parallel [(const_int 0)]))) -++ (sign_extend:SI (vec_select:HI -++ (match_dup 3) -++ (parallel [(const_int 1)])))))))] -++ "NDS32_EXT_DSP_P ()" -++ "kmaxds\t%0, %2, %3" -++ [(set_attr "type" "dmac") -++ (set_attr "length" "4")]) -++ -++(define_insn "kmsda" -++ [(set (match_operand:SI 0 "register_operand" "=r") -++ (ss_minus:SI -++ (match_operand:SI 1 "register_operand" " 0") -++ (ss_minus:SI -++ (mult:SI -++ (sign_extend:SI (vec_select:HI -++ (match_operand:V2HI 2 "register_operand" " r") -++ (parallel [(const_int 1)]))) -++ (sign_extend:SI (vec_select:HI -++ (match_operand:V2HI 3 "register_operand" " r") -++ (parallel [(const_int 1)])))) -++ (mult:SI -++ (sign_extend:SI (vec_select:HI -++ (match_dup 2) -++ (parallel [(const_int 0)]))) -++ (sign_extend:SI (vec_select:HI -++ (match_dup 3) -++ (parallel [(const_int 0)])))))))] -++ "NDS32_EXT_DSP_P ()" -++ "kmsda\t%0, %2, %3" -++ [(set_attr "type" "dmac") -++ (set_attr "length" "4")]) -++ -++(define_insn "kmsxda" -++ [(set (match_operand:SI 0 "register_operand" "=r") -++ (ss_minus:SI -++ (match_operand:SI 1 "register_operand" " 0") -++ (ss_minus:SI -++ (mult:SI -++ (sign_extend:SI (vec_select:HI -++ (match_operand:V2HI 2 "register_operand" " r") -++ (parallel [(const_int 1)]))) -++ (sign_extend:SI (vec_select:HI -++ (match_operand:V2HI 3 "register_operand" " r") -++ (parallel [(const_int 0)])))) -++ (mult:SI -++ (sign_extend:SI (vec_select:HI -++ (match_dup 2) -++ (parallel [(const_int 0)]))) -++ (sign_extend:SI (vec_select:HI -++ (match_dup 3) -++ (parallel [(const_int 1)])))))))] -++ "NDS32_EXT_DSP_P ()" -++ "kmsxda\t%0, %2, %3" -++ [(set_attr "type" "dmac") -++ (set_attr "length" "4")]) -++ -++;; smax[8|16] and umax[8|16] -++(define_insn "3" -++ [(set (match_operand:VQIHI 0 "register_operand" "=r") -++ (sumax:VQIHI (match_operand:VQIHI 1 "register_operand" " r") -++ (match_operand:VQIHI 2 "register_operand" " r")))] -++ "NDS32_EXT_DSP_P ()" -++ "\t%0, %1, %2" -++ [(set_attr "type" "dalu") -++ (set_attr "length" "4")]) -++ -++;; smin[8|16] and umin[8|16] -++(define_insn "3" -++ [(set (match_operand:VQIHI 0 "register_operand" "=r") -++ (sumin:VQIHI (match_operand:VQIHI 1 "register_operand" " r") -++ (match_operand:VQIHI 2 "register_operand" " r")))] -++ "NDS32_EXT_DSP_P ()" -++ "\t%0, %1, %2" -++ [(set_attr "type" "dalu") -++ (set_attr "length" "4")]) -++ -++(define_insn "3_bb" -++ [(set (match_operand: 0 "register_operand" "=r") -++ (sumin_max: (vec_select: -++ (match_operand:VQIHI 1 "register_operand" " r") -++ (parallel [(const_int 0)])) -++ (vec_select: -++ (match_operand:VQIHI 2 "register_operand" " r") -++ (parallel [(const_int 0)]))))] -++ "NDS32_EXT_DSP_P () && !TARGET_BIG_ENDIAN" -++ "\t%0, %1, %2" -++ [(set_attr "type" "dalu") -++ (set_attr "length" "4")]) -++ -++(define_insn_and_split "3_tt" -++ [(set (match_operand: 0 "register_operand" "=r") -++ (sumin_max: (vec_select: -++ (match_operand:VQIHI 1 "register_operand" " r") -++ (parallel [(const_int 1)])) -++ (vec_select: -++ (match_operand:VQIHI 2 "register_operand" " r") -++ (parallel [(const_int 1)]))))] -++ "NDS32_EXT_DSP_P () && !reload_completed && !TARGET_BIG_ENDIAN" -++ "#" -++ "NDS32_EXT_DSP_P () && !reload_completed" -++ [(const_int 0)] -++{ -++ rtx tmp = gen_reg_rtx (mode); -++ emit_insn (gen_3 (tmp, operands[1], operands[2])); -++ emit_insn (gen_rotr_1 (tmp, tmp)); -++ emit_move_insn (operands[0], simplify_gen_subreg (mode, tmp, mode, 0)); -++ DONE; -++} -++ [(set_attr "type" "dalu") -++ (set_attr "length" "4")]) -++ -++(define_insn_and_split "v4qi3_22" -++ [(set (match_operand:QI 0 "register_operand" "=r") -++ (sumin_max:QI (vec_select:QI -++ (match_operand:V4QI 1 "register_operand" " r") -++ (parallel [(const_int 2)])) -++ (vec_select:QI -++ (match_operand:V4QI 2 "register_operand" " r") -++ (parallel [(const_int 2)]))))] -++ "NDS32_EXT_DSP_P () && !reload_completed && !TARGET_BIG_ENDIAN" -++ "#" -++ "NDS32_EXT_DSP_P () && !reload_completed" -++ [(const_int 0)] -++{ -++ rtx tmp = gen_reg_rtx (V4QImode); -++ emit_insn (gen_v4qi3 (tmp, operands[1], operands[2])); -++ emit_insn (gen_rotrv4qi_2 (tmp, tmp)); -++ emit_move_insn (operands[0], simplify_gen_subreg (QImode, tmp, V4QImode, 0)); -++ DONE; -++} -++ [(set_attr "type" "dalu") -++ (set_attr "length" "4")]) -++ -++(define_insn_and_split "v4qi3_33" -++ [(set (match_operand:QI 0 "register_operand" "=r") -++ (sumin_max:QI (vec_select:QI -++ (match_operand:V4QI 1 "register_operand" " r") -++ (parallel [(const_int 3)])) -++ (vec_select:QI -++ (match_operand:V4QI 2 "register_operand" " r") -++ (parallel [(const_int 3)]))))] -++ "NDS32_EXT_DSP_P () && !reload_completed && !TARGET_BIG_ENDIAN" -++ "#" -++ "NDS32_EXT_DSP_P () && !reload_completed" -++ [(const_int 0)] -++{ -++ rtx tmp = gen_reg_rtx (V4QImode); -++ emit_insn (gen_v4qi3 (tmp, operands[1], operands[2])); -++ emit_insn (gen_rotrv4qi_3 (tmp, tmp)); -++ emit_move_insn (operands[0], simplify_gen_subreg (QImode, tmp, V4QImode, 0)); -++ DONE; -++} -++ [(set_attr "type" "dalu") -++ (set_attr "length" "4")]) -++ -++(define_insn_and_split "v2hi3_bbtt" -++ [(set (match_operand:V2HI 0 "register_operand" "=r") -++ (vec_merge:V2HI -++ (vec_duplicate:V2HI -++ (sumin_max:HI (vec_select:HI -++ (match_operand:V2HI 1 "register_operand" " r") -++ (parallel [(const_int 1)])) -++ (vec_select:HI -++ (match_operand:V2HI 2 "register_operand" " r") -++ (parallel [(const_int 1)])))) -++ (vec_duplicate:V2HI -++ (sumin_max:HI (vec_select:HI -++ (match_dup:V2HI 1) -++ (parallel [(const_int 0)])) -++ (vec_select:HI -++ (match_dup:V2HI 2) -++ (parallel [(const_int 0)])))) -++ (const_int 2)))] -++ "NDS32_EXT_DSP_P () && !TARGET_BIG_ENDIAN" -++ "#" -++ "NDS32_EXT_DSP_P ()" -++ [(const_int 0)] -++{ -++ emit_insn (gen_v2hi3 (operands[0], operands[1], operands[2])); -++ DONE; -++} -++ [(set_attr "type" "dalu") -++ (set_attr "length" "4")]) -++ -++(define_expand "abs2" -++ [(set (match_operand:VQIHI 0 "register_operand" "=r") -++ (ss_abs:VQIHI (match_operand:VQIHI 1 "register_operand" " r")))] -++ "NDS32_EXT_DSP_P () && TARGET_HW_ABS && !flag_wrapv" -++{ -++}) -++ -++(define_insn "kabs2" -++ [(set (match_operand:VQIHI 0 "register_operand" "=r") -++ (ss_abs:VQIHI (match_operand:VQIHI 1 "register_operand" " r")))] -++ "NDS32_EXT_DSP_P ()" -++ "kabs\t%0, %1" -++ [(set_attr "type" "dalu") -++ (set_attr "length" "4")]) -++ -++(define_insn "mar64_1" -++ [(set (match_operand:DI 0 "register_operand" "=r") -++ (plus:DI -++ (match_operand:DI 1 "register_operand" " 0") -++ (mult:DI -++ (extend:DI -++ (match_operand:SI 2 "register_operand" " r")) -++ (extend:DI -++ (match_operand:SI 3 "register_operand" " r")))))] -++ "NDS32_EXT_DSP_P ()" -++ "mar64\t%0, %2, %3" -++ [(set_attr "type" "dmac") -++ (set_attr "length" "4")]) -++ -++(define_insn "mar64_2" -++ [(set (match_operand:DI 0 "register_operand" "=r") -++ (plus:DI -++ (mult:DI -++ (extend:DI -++ (match_operand:SI 2 "register_operand" " r")) -++ (extend:DI -++ (match_operand:SI 3 "register_operand" " r"))) -++ (match_operand:DI 1 "register_operand" " 0")))] -++ "NDS32_EXT_DSP_P ()" -++ "mar64\t%0, %2, %3" -++ [(set_attr "type" "dmac") -++ (set_attr "length" "4")]) -++ -++(define_insn "mar64_3" -++ [(set (match_operand:DI 0 "register_operand" "=r") -++ (plus:DI -++ (match_operand:DI 1 "register_operand" " 0") -++ (extend:DI -++ (mult:SI -++ (match_operand:SI 2 "register_operand" " r") -++ (match_operand:SI 3 "register_operand" " r")))))] -++ "NDS32_EXT_DSP_P ()" -++ "mar64\t%0, %2, %3" -++ [(set_attr "type" "dmac") -++ (set_attr "length" "4")]) -++ -++(define_insn "mar64_4" -++ [(set (match_operand:DI 0 "register_operand" "=r") -++ (plus:DI -++ (extend:DI -++ (mult:SI -++ (match_operand:SI 2 "register_operand" " r") -++ (match_operand:SI 3 "register_operand" " r"))) -++ (match_operand:DI 1 "register_operand" " 0")))] -++ "NDS32_EXT_DSP_P ()" -++ "mar64\t%0, %2, %3" -++ [(set_attr "type" "dmac") -++ (set_attr "length" "4")]) -++ -++(define_insn "msr64" -++ [(set (match_operand:DI 0 "register_operand" "=r") -++ (minus:DI -++ (match_operand:DI 1 "register_operand" " 0") -++ (mult:DI -++ (extend:DI -++ (match_operand:SI 2 "register_operand" " r")) -++ (extend:DI -++ (match_operand:SI 3 "register_operand" " r")))))] -++ "NDS32_EXT_DSP_P ()" -++ "msr64\t%0, %2, %3" -++ [(set_attr "type" "dmac") -++ (set_attr "length" "4")]) -++ -++(define_insn "msr64_2" -++ [(set (match_operand:DI 0 "register_operand" "=r") -++ (minus:DI -++ (match_operand:DI 1 "register_operand" " 0") -++ (extend:DI -++ (mult:SI -++ (match_operand:SI 2 "register_operand" " r") -++ (match_operand:SI 3 "register_operand" " r")))))] -++ "NDS32_EXT_DSP_P ()" -++ "msr64\t%0, %2, %3" -++ [(set_attr "type" "dmac") -++ (set_attr "length" "4")]) -++ -++;; kmar64, kmsr64, ukmar64 and ukmsr64 -++(define_insn "kmar64_1" -++ [(set (match_operand:DI 0 "register_operand" "=r") -++ (ss_plus:DI -++ (match_operand:DI 1 "register_operand" " 0") -++ (mult:DI -++ (sign_extend:DI -++ (match_operand:SI 2 "register_operand" " r")) -++ (sign_extend:DI -++ (match_operand:SI 3 "register_operand" " r")))))] -++ "NDS32_EXT_DSP_P ()" -++ "kmar64\t%0, %2, %3" -++ [(set_attr "type" "dmac") -++ (set_attr "length" "4")]) -++ -++(define_insn "kmar64_2" -++ [(set (match_operand:DI 0 "register_operand" "=r") -++ (ss_plus:DI -++ (mult:DI -++ (sign_extend:DI -++ (match_operand:SI 2 "register_operand" " r")) -++ (sign_extend:DI -++ (match_operand:SI 3 "register_operand" " r"))) -++ (match_operand:DI 1 "register_operand" " 0")))] -++ "NDS32_EXT_DSP_P ()" -++ "kmar64\t%0, %2, %3" -++ [(set_attr "type" "dmac") -++ (set_attr "length" "4")]) -++ -++(define_insn "kmsr64" -++ [(set (match_operand:DI 0 "register_operand" "=r") -++ (ss_minus:DI -++ (match_operand:DI 1 "register_operand" " 0") -++ (mult:DI -++ (sign_extend:DI -++ (match_operand:SI 2 "register_operand" " r")) -++ (sign_extend:DI -++ (match_operand:SI 3 "register_operand" " r")))))] -++ "NDS32_EXT_DSP_P ()" -++ "kmsr64\t%0, %2, %3" -++ [(set_attr "type" "dmac") -++ (set_attr "length" "4")]) -++ -++(define_insn "ukmar64_1" -++ [(set (match_operand:DI 0 "register_operand" "=r") -++ (us_plus:DI -++ (match_operand:DI 1 "register_operand" " 0") -++ (mult:DI -++ (zero_extend:DI -++ (match_operand:SI 2 "register_operand" " r")) -++ (zero_extend:DI -++ (match_operand:SI 3 "register_operand" " r")))))] -++ "NDS32_EXT_DSP_P ()" -++ "ukmar64\t%0, %2, %3" -++ [(set_attr "type" "dmac") -++ (set_attr "length" "4")]) -++ -++(define_insn "ukmar64_2" -++ [(set (match_operand:DI 0 "register_operand" "=r") -++ (us_plus:DI -++ (mult:DI -++ (zero_extend:DI -++ (match_operand:SI 2 "register_operand" " r")) -++ (zero_extend:DI -++ (match_operand:SI 3 "register_operand" " r"))) -++ (match_operand:DI 1 "register_operand" " 0")))] -++ "NDS32_EXT_DSP_P ()" -++ "ukmar64\t%0, %2, %3" -++ [(set_attr "type" "dmac") -++ (set_attr "length" "4")]) -++ -++(define_insn "ukmsr64" -++ [(set (match_operand:DI 0 "register_operand" "=r") -++ (us_minus:DI -++ (match_operand:DI 1 "register_operand" " 0") -++ (mult:DI -++ (zero_extend:DI -++ (match_operand:SI 2 "register_operand" " r")) -++ (zero_extend:DI -++ (match_operand:SI 3 "register_operand" " r")))))] -++ "NDS32_EXT_DSP_P ()" -++ "ukmsr64\t%0, %2, %3" -++ [(set_attr "type" "dmac") -++ (set_attr "length" "4")]) -++ -++(define_insn "bpick1" -++ [(set (match_operand:SI 0 "register_operand" "=r") -++ (ior:SI -++ (and:SI -++ (match_operand:SI 1 "register_operand" " r") -++ (match_operand:SI 3 "register_operand" " r")) -++ (and:SI -++ (match_operand:SI 2 "register_operand" " r") -++ (not:SI (match_dup 3)))))] -++ "NDS32_EXT_DSP_P ()" -++ "bpick\t%0, %1, %2, %3" -++ [(set_attr "type" "dbpick") -++ (set_attr "length" "4")]) -++ -++(define_insn "bpick2" -++ [(set (match_operand:SI 0 "register_operand" "=r") -++ (ior:SI -++ (and:SI -++ (match_operand:SI 1 "register_operand" " r") -++ (match_operand:SI 2 "register_operand" " r")) -++ (and:SI -++ (not:SI (match_dup 2)) -++ (match_operand:SI 3 "register_operand" " r"))))] -++ "NDS32_EXT_DSP_P ()" -++ "bpick\t%0, %1, %3, %2" -++ [(set_attr "type" "dbpick") -++ (set_attr "length" "4")]) -++ -++(define_insn "bpick3" -++ [(set (match_operand:SI 0 "register_operand" "=r") -++ (ior:SI -++ (and:SI -++ (match_operand:SI 1 "register_operand" " r") -++ (match_operand:SI 2 "register_operand" " r")) -++ (and:SI -++ (match_operand:SI 3 "register_operand" " r") -++ (not:SI (match_dup 1)))))] -++ "NDS32_EXT_DSP_P ()" -++ "bpick\t%0, %2, %3, %1" -++ [(set_attr "type" "dbpick") -++ (set_attr "length" "4")]) -++ -++(define_insn "bpick4" -++ [(set (match_operand:SI 0 "register_operand" "=r") -++ (ior:SI -++ (and:SI -++ (match_operand:SI 1 "register_operand" " r") -++ (match_operand:SI 2 "register_operand" " r")) -++ (and:SI -++ (not:SI (match_dup 1)) -++ (match_operand:SI 3 "register_operand" " r"))))] -++ "NDS32_EXT_DSP_P ()" -++ "bpick\t%0, %2, %3, %1" -++ [(set_attr "type" "dbpick") -++ (set_attr "length" "4")]) -++ -++(define_insn "bpick5" -++ [(set (match_operand:SI 0 "register_operand" "=r") -++ (ior:SI -++ (and:SI -++ (match_operand:SI 1 "register_operand" " r") -++ (not:SI (match_operand:SI 2 "register_operand" " r"))) -++ (and:SI -++ (match_operand:SI 3 "register_operand" " r") -++ (match_dup 2))))] -++ "NDS32_EXT_DSP_P ()" -++ "bpick\t%0, %3, %1, %2" -++ [(set_attr "type" "dbpick") -++ (set_attr "length" "4")]) -++ -++(define_insn "bpick6" -++ [(set (match_operand:SI 0 "register_operand" "=r") -++ (ior:SI -++ (and:SI -++ (not:SI (match_operand:SI 1 "register_operand" " r")) -++ (match_operand:SI 2 "register_operand" " r")) -++ (and:SI -++ (match_operand:SI 3 "register_operand" " r") -++ (match_dup 1))))] -++ "NDS32_EXT_DSP_P ()" -++ "bpick\t%0, %3, %2, %1" -++ [(set_attr "type" "dbpick") -++ (set_attr "length" "4")]) -++ -++(define_insn "bpick7" -++ [(set (match_operand:SI 0 "register_operand" "=r") -++ (ior:SI -++ (and:SI -++ (match_operand:SI 1 "register_operand" " r") -++ (not:SI (match_operand:SI 2 "register_operand" " r"))) -++ (and:SI -++ (match_dup 2) -++ (match_operand:SI 3 "register_operand" " r"))))] -++ "NDS32_EXT_DSP_P ()" -++ "bpick\t%0, %3, %1, %2" -++ [(set_attr "type" "dbpick") -++ (set_attr "length" "4")]) -++ -++(define_insn "bpick8" -++ [(set (match_operand:SI 0 "register_operand" "=r") -++ (ior:SI -++ (and:SI -++ (not:SI (match_operand:SI 1 "register_operand" " r")) -++ (match_operand:SI 2 "register_operand" " r")) -++ (and:SI -++ (match_dup 1) -++ (match_operand:SI 3 "register_operand" " r"))))] -++ "NDS32_EXT_DSP_P ()" -++ "bpick\t%0, %3, %2, %1" -++ [(set_attr "type" "dbpick") -++ (set_attr "length" "4")]) -++ -++(define_insn "sraiu" -++ [(set (match_operand:SI 0 "register_operand" "= r, r") -++ (unspec:SI [(ashiftrt:SI (match_operand:SI 1 "register_operand" " r, r") -++ (match_operand:SI 2 "nds32_rimm5u_operand" " Iu05, r"))] -++ UNSPEC_ROUND))] -++ "NDS32_EXT_DSP_P ()" -++ "@ -++ srai.u\t%0, %1, %2 -++ sra.u\t%0, %1, %2" -++ [(set_attr "type" "daluround") -++ (set_attr "length" "4")]) -++ -++(define_insn "kssl" -++ [(set (match_operand:SI 0 "register_operand" "= r, r") -++ (ss_ashift:SI (match_operand:SI 1 "register_operand" " r, r") -++ (match_operand:SI 2 "nds32_rimm5u_operand" " Iu05, r")))] -++ "NDS32_EXT_DSP_P ()" -++ "@ -++ kslli\t%0, %1, %2 -++ ksll\t%0, %1, %2" -++ [(set_attr "type" "dalu") -++ (set_attr "length" "4")]) -++ -++(define_insn "kslraw_round" -++ [(set (match_operand:SI 0 "register_operand" "=r") -++ (if_then_else:SI -++ (lt:SI (match_operand:SI 2 "register_operand" " r") -++ (const_int 0)) -++ (unspec:SI [(ashiftrt:SI (match_operand:SI 1 "register_operand" " r") -++ (neg:SI (match_dup 2)))] -++ UNSPEC_ROUND) -++ (ss_ashift:SI (match_dup 1) -++ (match_dup 2))))] -++ "NDS32_EXT_DSP_P ()" -++ "kslraw.u\t%0, %1, %2" -++ [(set_attr "type" "daluround") -++ (set_attr "length" "4")]) -++ -++(define_insn_and_split "di3" -++ [(set (match_operand:DI 0 "register_operand" "") -++ (shift_rotate:DI (match_operand:DI 1 "register_operand" "") -++ (match_operand:SI 2 "nds32_rimm6u_operand" "")))] -++ "NDS32_EXT_DSP_P () && !reload_completed" -++ "#" -++ "NDS32_EXT_DSP_P () && !reload_completed" -++ [(const_int 0)] -++{ -++ if (REGNO (operands[0]) == REGNO (operands[1])) -++ { -++ rtx tmp = gen_reg_rtx (DImode); -++ nds32_split_di3 (tmp, operands[1], operands[2]); -++ emit_move_insn (operands[0], tmp); -++ } -++ else -++ nds32_split_di3 (operands[0], operands[1], operands[2]); -++ DONE; -++}) -++ -++(define_insn "sclip32" -++ [(set (match_operand:SI 0 "register_operand" "=r") -++ (unspec:SI [(match_operand:SI 1 "register_operand" "r") -++ (match_operand:SI 2 "immediate_operand" "i")] UNSPEC_CLIPS_OV))] -++ "NDS32_EXT_DSP_P ()" -++ "sclip32\t%0, %1, %2" -++ [(set_attr "type" "dclip") -++ (set_attr "length" "4")] -++) -++ -++(define_insn "uclip32" -++ [(set (match_operand:SI 0 "register_operand" "=r") -++ (unspec:SI [(match_operand:SI 1 "register_operand" "r") -++ (match_operand:SI 2 "immediate_operand" "i")] UNSPEC_CLIP_OV))] -++ "NDS32_EXT_DSP_P ()" -++ "uclip32\t%0, %1, %2" -++ [(set_attr "type" "dclip") -++ (set_attr "length" "4")] -++) -++ -++(define_insn "bitrev" -++ [(set (match_operand:SI 0 "register_operand" "=r, r") -++ (unspec:SI [(match_operand:SI 1 "register_operand" " r, r") -++ (match_operand:SI 2 "nds32_rimm5u_operand" " r, Iu05")] -++ UNSPEC_BITREV))] -++ "" -++ "@ -++ bitrev\t%0, %1, %2 -++ bitrevi\t%0, %1, %2" -++ [(set_attr "type" "dalu") -++ (set_attr "length" "4")] -++) -++ -++;; wext, wexti -++(define_insn "wext" -++ [(set (match_operand:SI 0 "register_operand" "=r, r") -++ (truncate:SI -++ (shiftrt:DI -++ (match_operand:DI 1 "register_operand" " r, r") -++ (match_operand:SI 2 "nds32_rimm5u_operand" " r,Iu05"))))] -++ "NDS32_EXT_DSP_P ()" -++ "@ -++ wext\t%0, %1, %2 -++ wexti\t%0, %1, %2" -++ [(set_attr "type" "dwext") -++ (set_attr "length" "4")]) -++ -++;; 32-bit add/sub instruction: raddw and rsubw. -++(define_insn "rsi3" -++ [(set (match_operand:SI 0 "register_operand" "=r") -++ (truncate:SI -++ (ashiftrt:DI -++ (plus_minus:DI -++ (sign_extend:DI (match_operand:SI 1 "register_operand" " r")) -++ (sign_extend:DI (match_operand:SI 2 "register_operand" " r"))) -++ (const_int 1))))] -++ "NDS32_EXT_DSP_P ()" -++ "rw\t%0, %1, %2" -++ [(set_attr "type" "dalu") -++ (set_attr "length" "4")]) -++ -++;; 32-bit add/sub instruction: uraddw and ursubw. -++(define_insn "ursi3" -++ [(set (match_operand:SI 0 "register_operand" "=r") -++ (truncate:SI -++ (lshiftrt:DI -++ (plus_minus:DI -++ (zero_extend:DI (match_operand:SI 1 "register_operand" " r")) -++ (zero_extend:DI (match_operand:SI 2 "register_operand" " r"))) -++ (const_int 1))))] -++ "NDS32_EXT_DSP_P ()" -++ "urw\t%0, %1, %2" -++ [(set_attr "type" "dalu") -++ (set_attr "length" "4")]) -+diff --git a/gcc/config/nds32/nds32-elf.opt b/gcc/config/nds32/nds32-elf.opt -+new file mode 100644 -+index 00000000000..afe6aadd089 -+--- /dev/null -++++ b/gcc/config/nds32/nds32-elf.opt -+@@ -0,0 +1,16 @@ -++mcmodel= -++Target RejectNegative Joined Enum(nds32_cmodel_type) Var(nds32_cmodel_option) Init(CMODEL_MEDIUM) -++Specify the address generation strategy for code model. -++ -++Enum -++Name(nds32_cmodel_type) Type(enum nds32_cmodel_type) -++Known cmodel types (for use with the -mcmodel= option): -++ -++EnumValue -++Enum(nds32_cmodel_type) String(small) Value(CMODEL_SMALL) -++ -++EnumValue -++Enum(nds32_cmodel_type) String(medium) Value(CMODEL_MEDIUM) -++ -++EnumValue -++Enum(nds32_cmodel_type) String(large) Value(CMODEL_LARGE) -+diff --git a/gcc/config/nds32/nds32-fp-as-gp.c b/gcc/config/nds32/nds32-fp-as-gp.c -+index 95c9586c3b6..26d2865d450 100644 -+--- a/gcc/config/nds32/nds32-fp-as-gp.c -++++ b/gcc/config/nds32/nds32-fp-as-gp.c -+@@ -26,19 +26,256 @@ -+ #include "system.h" -+ #include "coretypes.h" -+ #include "backend.h" -++#include "hard-reg-set.h" -++#include "tm_p.h" -++#include "rtl.h" -++#include "memmodel.h" -++#include "emit-rtl.h" -++#include "insn-config.h" -++#include "regs.h" -++#include "hard-reg-set.h" -++#include "ira.h" -++#include "ira-int.h" -++#include "df.h" -++#include "tree-core.h" -++#include "tree-pass.h" -++#include "nds32-protos.h" -+ -+ /* ------------------------------------------------------------------------ */ -+ -++/* A helper function to check if this function should contain prologue. */ -++static bool -++nds32_have_prologue_p (void) -++{ -++ int i; -++ -++ for (i = 0; i < 28; i++) -++ if (NDS32_REQUIRED_CALLEE_SAVED_P (i)) -++ return true; -++ -++ return (flag_pic -++ || NDS32_REQUIRED_CALLEE_SAVED_P (FP_REGNUM) -++ || NDS32_REQUIRED_CALLEE_SAVED_P (LP_REGNUM)); -++} -++ -++static int -++nds32_get_symbol_count (void) -++{ -++ int symbol_count = 0; -++ rtx_insn *insn; -++ basic_block bb; -++ -++ FOR_EACH_BB_FN (bb, cfun) -++ { -++ FOR_BB_INSNS (bb, insn) -++ { -++ /* Counting the insn number which the addressing mode is symbol. */ -++ if (single_set (insn) && nds32_symbol_load_store_p (insn)) -++ { -++ rtx pattern = PATTERN (insn); -++ rtx mem; -++ gcc_assert (GET_CODE (pattern) == SET); -++ if (GET_CODE (SET_SRC (pattern)) == REG ) -++ mem = SET_DEST (pattern); -++ else -++ mem = SET_SRC (pattern); -++ -++ /* We have only lwi37 and swi37 for fp-as-gp optimization, -++ so don't count any other than SImode. -++ MEM for QImode and HImode will wrap by ZERO_EXTEND -++ or SIGN_EXTEND */ -++ if (GET_CODE (mem) == MEM) -++ symbol_count++; -++ } -++ } -++ } -++ -++ return symbol_count; -++} -++ -+ /* Function to determine whether it is worth to do fp_as_gp optimization. -+- Return 0: It is NOT worth to do fp_as_gp optimization. -+- Return 1: It is APPROXIMATELY worth to do fp_as_gp optimization. -++ Return false: It is NOT worth to do fp_as_gp optimization. -++ Return true: It is APPROXIMATELY worth to do fp_as_gp optimization. -+ Note that if it is worth to do fp_as_gp optimization, -+ we MUST set FP_REGNUM ever live in this function. */ -+-int -++static bool -+ nds32_fp_as_gp_check_available (void) -+ { -+- /* By default we return 0. */ -+- return 0; -++ basic_block bb; -++ basic_block exit_bb; -++ edge_iterator ei; -++ edge e; -++ bool first_exit_blocks_p; -++ -++ /* If there exists ANY of following conditions, -++ we DO NOT perform fp_as_gp optimization: -++ 1. TARGET_FORBID_FP_AS_GP is set -++ regardless of the TARGET_FORCE_FP_AS_GP. -++ 2. User explicitly uses 'naked'/'no_prologue' attribute. -++ We use nds32_naked_function_p() to help such checking. -++ 3. Not optimize for size. -++ 4. Need frame pointer. -++ 5. If $fp is already required to be saved, -++ it means $fp is already choosen by register allocator. -++ Thus we better not to use it for fp_as_gp optimization. -++ 6. This function is a vararg function. -++ DO NOT apply fp_as_gp optimization on this function -++ because it may change and break stack frame. -++ 7. The epilogue is empty. -++ This happens when the function uses exit() -++ or its attribute is no_return. -++ In that case, compiler will not expand epilogue -++ so that we have no chance to output .omit_fp_end directive. */ -++ if (TARGET_FORBID_FP_AS_GP -++ || nds32_naked_function_p (current_function_decl) -++ || !optimize_size -++ || frame_pointer_needed -++ || NDS32_REQUIRED_CALLEE_SAVED_P (FP_REGNUM) -++ || (cfun->stdarg == 1) -++ || (find_fallthru_edge (EXIT_BLOCK_PTR_FOR_FN (cfun)->preds) == NULL)) -++ return false; -++ -++ /* Disable fp_as_gp if there is any infinite loop since the fp may -++ reuse in infinite loops by register rename. -++ For check infinite loops we should make sure exit_bb is post dominate -++ all other basic blocks if there is no infinite loops. */ -++ first_exit_blocks_p = true; -++ exit_bb = NULL; -++ -++ FOR_EACH_EDGE (e, ei, EXIT_BLOCK_PTR_FOR_FN (cfun)->preds) -++ { -++ /* More than one exit block also do not perform fp_as_gp optimization. */ -++ if (!first_exit_blocks_p) -++ return false; -++ -++ exit_bb = e->src; -++ first_exit_blocks_p = false; -++ } -++ -++ /* Not found exit_bb? just abort fp_as_gp! */ -++ if (!exit_bb) -++ return false; -++ -++ /* Each bb should post dominate by exit_bb if there is no infinite loop! */ -++ FOR_EACH_BB_FN (bb, cfun) -++ { -++ if (!dominated_by_p (CDI_POST_DOMINATORS, -++ bb, -++ exit_bb)) -++ return false; -++ } -++ -++ /* Now we can check the possibility of using fp_as_gp optimization. */ -++ if (TARGET_FORCE_FP_AS_GP) -++ { -++ /* User explicitly issues -mforce-fp-as-gp option. */ -++ return true; -++ } -++ else -++ { -++ /* In the following we are going to evaluate whether -++ it is worth to do fp_as_gp optimization. */ -++ bool good_gain = false; -++ int symbol_count; -++ -++ int threshold; -++ -++ /* We check if there already requires prologue. -++ Note that $gp will be saved in prologue for PIC code generation. -++ After that, we can set threshold by the existence of prologue. -++ Each fp-implied instruction will gain 2-byte code size -++ from gp-aware instruction, so we have following heuristics. */ -++ if (flag_pic -++ || nds32_have_prologue_p ()) -++ { -++ /* Have-prologue: -++ Compiler already intends to generate prologue content, -++ so the fp_as_gp optimization will only insert -++ 'la $fp,_FP_BASE_' instruction, which will be -++ converted into 4-byte instruction at link time. -++ The threshold is "3" symbol accesses, 2 + 2 + 2 > 4. */ -++ threshold = 3; -++ } -++ else -++ { -++ /* None-prologue: -++ Compiler originally does not generate prologue content, -++ so the fp_as_gp optimization will NOT ONLY insert -++ 'la $fp,_FP_BASE' instruction, but also causes -++ push/pop instructions. -++ If we are using v3push (push25/pop25), -++ the threshold is "5" symbol accesses, 5*2 > 4 + 2 + 2; -++ If we are using normal push (smw/lmw), -++ the threshold is "5+2" symbol accesses 7*2 > 4 + 4 + 4. */ -++ threshold = 5 + (TARGET_V3PUSH ? 0 : 2); -++ } -++ -++ symbol_count = nds32_get_symbol_count (); -++ -++ if (symbol_count >= threshold) -++ good_gain = true; -++ -++ /* Enable fp_as_gp optimization when potential gain is good enough. */ -++ return good_gain; -++ } -++} -++ -++static unsigned int -++nds32_fp_as_gp (void) -++{ -++ bool fp_as_gp_p; -++ calculate_dominance_info (CDI_POST_DOMINATORS); -++ fp_as_gp_p = nds32_fp_as_gp_check_available (); -++ -++ /* Here is a hack to IRA for enable/disable a hard register per function. -++ We *MUST* review this way after migrate gcc 4.9! */ -++ if (fp_as_gp_p) { -++ SET_HARD_REG_BIT(this_target_ira_int->x_no_unit_alloc_regs, FP_REGNUM); -++ df_set_regs_ever_live (FP_REGNUM, 1); -++ } else { -++ CLEAR_HARD_REG_BIT(this_target_ira_int->x_no_unit_alloc_regs, FP_REGNUM); -++ } -++ -++ cfun->machine->fp_as_gp_p = fp_as_gp_p; -++ -++ free_dominance_info (CDI_POST_DOMINATORS); -++ return 1; -++} -++ -++const pass_data pass_data_nds32_fp_as_gp = -++{ -++ RTL_PASS, /* type */ -++ "fp_as_gp", /* name */ -++ OPTGROUP_NONE, /* optinfo_flags */ -++ TV_MACH_DEP, /* tv_id */ -++ 0, /* properties_required */ -++ 0, /* properties_provided */ -++ 0, /* properties_destroyed */ -++ 0, /* todo_flags_start */ -++ 0 /* todo_flags_finish */ -++}; -++ -++class pass_nds32_fp_as_gp : public rtl_opt_pass -++{ -++public: -++ pass_nds32_fp_as_gp (gcc::context *ctxt) -++ : rtl_opt_pass (pass_data_nds32_fp_as_gp, ctxt) -++ {} -++ -++ /* opt_pass methods: */ -++ bool gate (function *) -++ { -++ return !TARGET_LINUX_ABI -++ && TARGET_16_BIT -++ && optimize_size; -++ } -++ unsigned int execute (function *) { return nds32_fp_as_gp (); } -++}; -++ -++rtl_opt_pass * -++make_pass_nds32_fp_as_gp (gcc::context *ctxt) -++{ -++ return new pass_nds32_fp_as_gp (ctxt); -+ } -+ -+ /* ------------------------------------------------------------------------ */ -+diff --git a/gcc/config/nds32/nds32-fpu.md b/gcc/config/nds32/nds32-fpu.md -+index 719b0428ced..9b844021a24 100644 -+--- a/gcc/config/nds32/nds32-fpu.md -++++ b/gcc/config/nds32/nds32-fpu.md -+@@ -1,5 +1,5 @@ -+ ;; Machine description of Andes NDS32 cpu for GNU compiler -+-;; Copyright (C) 2012-2015 Free Software Foundation, Inc. -++;; Copyright (C) 2012-2018 Free Software Foundation, Inc. -+ ;; Contributed by Andes Technology Corporation. -+ ;; -+ ;; This file is part of GCC. -+diff --git a/gcc/config/nds32/nds32-graywolf.md b/gcc/config/nds32/nds32-graywolf.md -+new file mode 100644 -+index 00000000000..f0c98a6f75d -+--- /dev/null -++++ b/gcc/config/nds32/nds32-graywolf.md -+@@ -0,0 +1,471 @@ -++;; Pipeline descriptions of Andes NDS32 cpu for GNU compiler -++;; Copyright (C) 2012-2013 Free Software Foundation, Inc. -++;; Contributed by Andes Technology Corporation. -++;; -++;; This file is part of GCC. -++;; -++;; GCC is free software; you can redistribute it and/or modify it -++;; under the terms of the GNU General Public License as published -++;; by the Free Software Foundation; either version 3, or (at your -++;; option) any later version. -++;; -++;; GCC is distributed in the hope that it will be useful, but WITHOUT -++;; ANY WARRANTY; without even the implied warranty of MERCHANTABILITY -++;; or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public -++;; License for more details. -++;; -++;; You should have received a copy of the GNU General Public License -++;; along with GCC; see the file COPYING3. If not see -++;; . -++ -++;; ------------------------------------------------------------------------ -++;; Define Graywolf pipeline settings. -++;; ------------------------------------------------------------------------ -++ -++(define_automaton "nds32_graywolf_machine") -++ -++(define_cpu_unit "gw_ii_0" "nds32_graywolf_machine") -++(define_cpu_unit "gw_ii_1" "nds32_graywolf_machine") -++(define_cpu_unit "gw_ex_p0" "nds32_graywolf_machine") -++(define_cpu_unit "gw_mm_p0" "nds32_graywolf_machine") -++(define_cpu_unit "gw_wb_p0" "nds32_graywolf_machine") -++(define_cpu_unit "gw_ex_p1" "nds32_graywolf_machine") -++(define_cpu_unit "gw_mm_p1" "nds32_graywolf_machine") -++(define_cpu_unit "gw_wb_p1" "nds32_graywolf_machine") -++(define_cpu_unit "gw_iq_p2" "nds32_graywolf_machine") -++(define_cpu_unit "gw_rf_p2" "nds32_graywolf_machine") -++(define_cpu_unit "gw_e1_p2" "nds32_graywolf_machine") -++(define_cpu_unit "gw_e2_p2" "nds32_graywolf_machine") -++(define_cpu_unit "gw_e3_p2" "nds32_graywolf_machine") -++(define_cpu_unit "gw_e4_p2" "nds32_graywolf_machine") -++ -++(define_reservation "gw_ii" "gw_ii_0 | gw_ii_1") -++(define_reservation "gw_ex" "gw_ex_p0 | gw_ex_p1") -++(define_reservation "gw_mm" "gw_mm_p0 | gw_mm_p1") -++(define_reservation "gw_wb" "gw_wb_p0 | gw_wb_p1") -++ -++(define_reservation "gw_ii_all" "gw_ii_0 + gw_ii_1") -++ -++(define_insn_reservation "nds_gw_unknown" 1 -++ (and (eq_attr "type" "unknown") -++ (eq_attr "pipeline_model" "graywolf")) -++ "gw_ii, gw_ex, gw_mm, gw_wb") -++ -++(define_insn_reservation "nds_gw_misc" 1 -++ (and (eq_attr "type" "misc") -++ (eq_attr "pipeline_model" "graywolf")) -++ "gw_ii, gw_ex, gw_mm, gw_wb") -++ -++(define_insn_reservation "nds_gw_mmu" 1 -++ (and (eq_attr "type" "mmu") -++ (eq_attr "pipeline_model" "graywolf")) -++ "gw_ii, gw_ex, gw_mm, gw_wb") -++ -++(define_insn_reservation "nds_gw_alu" 1 -++ (and (and (eq_attr "type" "alu") -++ (match_test "!nds32::movd44_insn_p (insn)")) -++ (eq_attr "pipeline_model" "graywolf")) -++ "gw_ii, gw_ex, gw_mm, gw_wb") -++ -++(define_insn_reservation "nds_gw_movd44" 1 -++ (and (and (eq_attr "type" "alu") -++ (match_test "nds32::movd44_insn_p (insn)")) -++ (eq_attr "pipeline_model" "graywolf")) -++ "gw_ii_1, gw_ex, gw_mm, gw_wb") -++ -++(define_insn_reservation "nds_gw_alu_shift" 1 -++ (and (eq_attr "type" "alu_shift") -++ (eq_attr "pipeline_model" "graywolf")) -++ "gw_ii, gw_ex*2, gw_mm, gw_wb") -++ -++(define_insn_reservation "nds_gw_pbsad" 1 -++ (and (eq_attr "type" "pbsad") -++ (eq_attr "pipeline_model" "graywolf")) -++ "gw_ii, gw_ex*3, gw_mm, gw_wb") -++ -++(define_insn_reservation "nds_gw_pbsada" 1 -++ (and (eq_attr "type" "pbsada") -++ (eq_attr "pipeline_model" "graywolf")) -++ "gw_ii, gw_ex*3, gw_mm, gw_wb") -++ -++(define_insn_reservation "nds_gw_load" 1 -++ (and (and (eq_attr "type" "load") -++ (match_test "!nds32::post_update_insn_p (insn)")) -++ (eq_attr "pipeline_model" "graywolf")) -++ "gw_ii_1, gw_ex_p1, gw_mm_p1, gw_wb_p1") -++ -++(define_insn_reservation "nds_gw_load_2w" 1 -++ (and (and (eq_attr "type" "load") -++ (match_test "nds32::post_update_insn_p (insn)")) -++ (eq_attr "pipeline_model" "graywolf")) -++ "gw_ii_all, gw_ex_p1, gw_mm_p1, gw_wb_p1") -++ -++(define_insn_reservation "nds_gw_store" 1 -++ (and (and (eq_attr "type" "store") -++ (match_test "!nds32::store_offset_reg_p (insn)")) -++ (eq_attr "pipeline_model" "graywolf")) -++ "gw_ii_1, gw_ex_p1, gw_mm_p1, gw_wb_p1") -++ -++(define_insn_reservation "nds_gw_store_3r" 1 -++ (and (and (eq_attr "type" "store") -++ (match_test "nds32::store_offset_reg_p (insn)")) -++ (eq_attr "pipeline_model" "graywolf")) -++ "gw_ii_all, gw_ex_p1, gw_mm_p1, gw_wb_p1") -++ -++(define_insn_reservation "nds_gw_load_multiple_1" 1 -++ (and (and (eq_attr "type" "load_multiple") -++ (eq_attr "combo" "1")) -++ (eq_attr "pipeline_model" "graywolf")) -++ "gw_ii_1, gw_ex_p1, gw_mm_p1, gw_wb_p1") -++ -++(define_insn_reservation "nds_gw_load_multiple_2" 1 -++ (and (and (eq_attr "type" "load_multiple") -++ (eq_attr "combo" "2")) -++ (eq_attr "pipeline_model" "graywolf")) -++ "gw_ii_1, gw_ex_p1*2, gw_mm_p1, gw_wb_p1") -++ -++(define_insn_reservation "nds_gw_load_multiple_3" 1 -++ (and (and (eq_attr "type" "load_multiple") -++ (eq_attr "combo" "3")) -++ (eq_attr "pipeline_model" "graywolf")) -++ "gw_ii_1, gw_ex_p1*3, gw_mm_p1, gw_wb_p1") -++ -++(define_insn_reservation "nds_gw_load_multiple_4" 1 -++ (and (and (eq_attr "type" "load_multiple") -++ (eq_attr "combo" "4")) -++ (eq_attr "pipeline_model" "graywolf")) -++ "gw_ii_1, gw_ex_p1*4, gw_mm_p1, gw_wb_p1") -++ -++(define_insn_reservation "nds_gw_load_multiple_5" 1 -++ (and (and (eq_attr "type" "load_multiple") -++ (eq_attr "combo" "5")) -++ (eq_attr "pipeline_model" "graywolf")) -++ "gw_ii_1, gw_ex_p1*4, gw_mm_p1, gw_wb_p1") -++ -++(define_insn_reservation "nds_gw_load_multiple_6" 1 -++ (and (and (eq_attr "type" "load_multiple") -++ (eq_attr "combo" "6")) -++ (eq_attr "pipeline_model" "graywolf")) -++ "gw_ii_1, gw_ex_p1*4, gw_mm_p1, gw_wb_p1") -++ -++(define_insn_reservation "nds_gw_load_multiple_7" 1 -++ (and (and (eq_attr "type" "load_multiple") -++ (eq_attr "combo" "7")) -++ (eq_attr "pipeline_model" "graywolf")) -++ "gw_ii_1, gw_ex_p1*4, gw_mm_p1, gw_wb_p1") -++ -++(define_insn_reservation "nds_gw_load_multiple_8" 1 -++ (and (and (eq_attr "type" "load_multiple") -++ (eq_attr "combo" "8")) -++ (eq_attr "pipeline_model" "graywolf")) -++ "gw_ii_1, gw_ex_p1*4, gw_mm_p1, gw_wb_p1") -++ -++(define_insn_reservation "nds_gw_load_multiple_12" 1 -++ (and (and (eq_attr "type" "load_multiple") -++ (eq_attr "combo" "12")) -++ (eq_attr "pipeline_model" "graywolf")) -++ "gw_ii_1, gw_ex_p1*4, gw_mm_p1, gw_wb_p1") -++ -++(define_insn_reservation "nds_gw_store_multiple_1" 1 -++ (and (and (eq_attr "type" "store_multiple") -++ (eq_attr "combo" "1")) -++ (eq_attr "pipeline_model" "graywolf")) -++ "gw_ii_1, gw_ex_p1, gw_mm_p1, gw_wb_p1") -++ -++(define_insn_reservation "nds_gw_store_multiple_2" 1 -++ (and (and (eq_attr "type" "store_multiple") -++ (eq_attr "combo" "2")) -++ (eq_attr "pipeline_model" "graywolf")) -++ "gw_ii_1, gw_ex_p1*2, gw_mm_p1, gw_wb_p1") -++ -++(define_insn_reservation "nds_gw_store_multiple_3" 1 -++ (and (and (eq_attr "type" "store_multiple") -++ (eq_attr "combo" "3")) -++ (eq_attr "pipeline_model" "graywolf")) -++ "gw_ii_1, gw_ex_p1*3, gw_mm_p1, gw_wb_p1") -++ -++(define_insn_reservation "nds_gw_store_multiple_4" 1 -++ (and (and (eq_attr "type" "store_multiple") -++ (eq_attr "combo" "4")) -++ (eq_attr "pipeline_model" "graywolf")) -++ "gw_ii_1, gw_ex_p1*4, gw_mm_p1, gw_wb_p1") -++ -++(define_insn_reservation "nds_gw_store_multiple_5" 1 -++ (and (and (eq_attr "type" "store_multiple") -++ (eq_attr "combo" "5")) -++ (eq_attr "pipeline_model" "graywolf")) -++ "gw_ii_1, gw_ex_p1*4, gw_mm_p1, gw_wb_p1") -++ -++(define_insn_reservation "nds_gw_store_multiple_6" 1 -++ (and (and (eq_attr "type" "store_multiple") -++ (eq_attr "combo" "6")) -++ (eq_attr "pipeline_model" "graywolf")) -++ "gw_ii_1, gw_ex_p1*4, gw_mm_p1, gw_wb_p1") -++ -++(define_insn_reservation "nds_gw_store_multiple_7" 1 -++ (and (and (eq_attr "type" "store_multiple") -++ (eq_attr "combo" "7")) -++ (eq_attr "pipeline_model" "graywolf")) -++ "gw_ii_1, gw_ex_p1*4, gw_mm_p1, gw_wb_p1") -++ -++(define_insn_reservation "nds_gw_store_multiple_8" 1 -++ (and (and (eq_attr "type" "store_multiple") -++ (eq_attr "combo" "8")) -++ (eq_attr "pipeline_model" "graywolf")) -++ "gw_ii_1, gw_ex_p1*4, gw_mm_p1, gw_wb_p1") -++ -++(define_insn_reservation "nds_gw_store_multiple_12" 1 -++ (and (and (eq_attr "type" "store_multiple") -++ (eq_attr "combo" "12")) -++ (eq_attr "pipeline_model" "graywolf")) -++ "gw_ii_1, gw_ex_p1*4, gw_mm_p1, gw_wb_p1") -++ -++(define_insn_reservation "nds_gw_mul_fast1" 1 -++ (and (match_test "nds32_mul_config == MUL_TYPE_FAST_1") -++ (and (eq_attr "type" "mul") -++ (eq_attr "pipeline_model" "graywolf"))) -++ "gw_ii_0, gw_ex_p0, gw_mm_p0, gw_wb_p0") -++ -++(define_insn_reservation "nds_gw_mul_fast2" 1 -++ (and (match_test "nds32_mul_config == MUL_TYPE_FAST_2") -++ (and (eq_attr "type" "mul") -++ (eq_attr "pipeline_model" "graywolf"))) -++ "gw_ii_0, gw_ex_p0*2, gw_mm_p0, gw_wb_p0") -++ -++(define_insn_reservation "nds_gw_mul_slow" 1 -++ (and (match_test "nds32_mul_config == MUL_TYPE_SLOW") -++ (and (eq_attr "type" "mul") -++ (eq_attr "pipeline_model" "graywolf"))) -++ "gw_ii_0, gw_ex_p0*4, gw_mm_p0, gw_wb_p0") -++ -++(define_insn_reservation "nds_gw_mac_fast1" 1 -++ (and (match_test "nds32_mul_config == MUL_TYPE_FAST_1") -++ (and (eq_attr "type" "mac") -++ (eq_attr "pipeline_model" "graywolf"))) -++ "gw_ii_all, gw_ex_p0, gw_mm_p0, gw_wb_p0") -++ -++(define_insn_reservation "nds_gw_mac_fast2" 1 -++ (and (match_test "nds32_mul_config == MUL_TYPE_FAST_2") -++ (and (eq_attr "type" "mac") -++ (eq_attr "pipeline_model" "graywolf"))) -++ "gw_ii_all, gw_ex_p0*2, gw_mm_p0, gw_wb_p0") -++ -++(define_insn_reservation "nds_gw_mac_slow" 1 -++ (and (match_test "nds32_mul_config == MUL_TYPE_SLOW") -++ (and (eq_attr "type" "mac") -++ (eq_attr "pipeline_model" "graywolf"))) -++ "gw_ii_all, gw_ex_p0*4, gw_mm_p0, gw_wb_p0") -++ -++(define_insn_reservation "nds_gw_div" 1 -++ (and (and (eq_attr "type" "div") -++ (match_test "!nds32::divmod_p (insn)")) -++ (eq_attr "pipeline_model" "graywolf")) -++ "gw_ii_0, gw_ex_p0*4, gw_mm_p0, gw_wb_p0") -++ -++(define_insn_reservation "nds_gw_div_2w" 1 -++ (and (and (eq_attr "type" "div") -++ (match_test "nds32::divmod_p (insn)")) -++ (eq_attr "pipeline_model" "graywolf")) -++ "gw_ii_all, gw_ex_p0*4, gw_mm_p0, gw_wb_p0") -++ -++(define_insn_reservation "nds_gw_branch" 1 -++ (and (eq_attr "type" "branch") -++ (eq_attr "pipeline_model" "graywolf")) -++ "gw_ii_0, gw_ex_p0, gw_mm_p0, gw_wb_p0") -++ -++(define_insn_reservation "nds_gw_dsp_alu" 1 -++ (and (eq_attr "type" "dalu") -++ (eq_attr "pipeline_model" "graywolf")) -++ "gw_ii, gw_ex, gw_mm, gw_wb") -++ -++(define_insn_reservation "nds_gw_dsp_alu64" 1 -++ (and (eq_attr "type" "dalu64") -++ (eq_attr "pipeline_model" "graywolf")) -++ "gw_ii_all, gw_ex_p0, gw_mm_p0, gw_wb_p0") -++ -++(define_insn_reservation "nds_gw_dsp_alu_round" 1 -++ (and (eq_attr "type" "daluround") -++ (eq_attr "pipeline_model" "graywolf")) -++ "gw_ii_0, gw_ex_p0, gw_mm_p0, gw_wb_p0") -++ -++(define_insn_reservation "nds_gw_dsp_cmp" 1 -++ (and (eq_attr "type" "dcmp") -++ (eq_attr "pipeline_model" "graywolf")) -++ "gw_ii_0, gw_ex_p0, gw_mm_p0, gw_wb_p0") -++ -++(define_insn_reservation "nds_gw_dsp_clip" 1 -++ (and (eq_attr "type" "dclip") -++ (eq_attr "pipeline_model" "graywolf")) -++ "gw_ii_0, gw_ex_p0, gw_mm_p0, gw_wb_p0") -++ -++(define_insn_reservation "nds_gw_dsp_mul" 1 -++ (and (eq_attr "type" "dmul") -++ (eq_attr "pipeline_model" "graywolf")) -++ "gw_ii_0, gw_ex_p0, gw_mm_p0, gw_wb_p0") -++ -++(define_insn_reservation "nds_gw_dsp_mac" 1 -++ (and (eq_attr "type" "dmac") -++ (eq_attr "pipeline_model" "graywolf")) -++ "gw_ii_all, gw_ex_p0, gw_mm_p0, gw_wb_p0") -++ -++(define_insn_reservation "nds_gw_dsp_insb" 1 -++ (and (eq_attr "type" "dinsb") -++ (eq_attr "pipeline_model" "graywolf")) -++ "gw_ii_0, gw_ex_p0, gw_mm_p0, gw_wb_p0") -++ -++(define_insn_reservation "nds_gw_dsp_pack" 1 -++ (and (eq_attr "type" "dpack") -++ (eq_attr "pipeline_model" "graywolf")) -++ "gw_ii_0, gw_ex_p0, gw_mm_p0, gw_wb_p0") -++ -++(define_insn_reservation "nds_gw_dsp_bpick" 1 -++ (and (eq_attr "type" "dbpick") -++ (eq_attr "pipeline_model" "graywolf")) -++ "gw_ii_0, gw_ex_p0, gw_mm_p0, gw_wb_p0") -++ -++(define_insn_reservation "nds_gw_dsp_wext" 1 -++ (and (eq_attr "type" "dwext") -++ (eq_attr "pipeline_model" "graywolf")) -++ "gw_ii_all, gw_ex_p0, gw_mm_p0, gw_wb_p0") -++ -++(define_insn_reservation "nds_gw_fpu_alu" 4 -++ (and (eq_attr "type" "falu") -++ (eq_attr "pipeline_model" "graywolf")) -++ "gw_ii, gw_iq_p2, gw_rf_p2, gw_e1_p2, gw_e2_p2, gw_e3_p2, gw_e4_p2") -++ -++(define_insn_reservation "nds_gw_fpu_muls" 4 -++ (and (eq_attr "type" "fmuls") -++ (eq_attr "pipeline_model" "graywolf")) -++ "gw_ii, gw_iq_p2, gw_rf_p2, gw_e1_p2, gw_e2_p2, gw_e3_p2, gw_e4_p2") -++ -++(define_insn_reservation "nds_gw_fpu_muld" 4 -++ (and (eq_attr "type" "fmuld") -++ (eq_attr "pipeline_model" "graywolf")) -++ "gw_ii, gw_iq_p2, gw_rf_p2, gw_e1_p2, gw_e2_p2*2, gw_e3_p2, gw_e4_p2") -++ -++(define_insn_reservation "nds_gw_fpu_macs" 4 -++ (and (eq_attr "type" "fmacs") -++ (eq_attr "pipeline_model" "graywolf")) -++ "gw_ii, gw_iq_p2, gw_rf_p2, gw_e1_p2, gw_e2_p2*3, gw_e3_p2, gw_e4_p2") -++ -++(define_insn_reservation "nds_gw_fpu_macd" 4 -++ (and (eq_attr "type" "fmacd") -++ (eq_attr "pipeline_model" "graywolf")) -++ "gw_ii, gw_iq_p2, gw_rf_p2, gw_e1_p2, gw_e2_p2*4, gw_e3_p2, gw_e4_p2") -++ -++(define_insn_reservation "nds_gw_fpu_divs" 4 -++ (and (ior (eq_attr "type" "fdivs") -++ (eq_attr "type" "fsqrts")) -++ (eq_attr "pipeline_model" "graywolf")) -++ "gw_ii, gw_iq_p2, gw_rf_p2, gw_e1_p2, gw_e2_p2*14, gw_e3_p2, gw_e4_p2") -++ -++(define_insn_reservation "nds_gw_fpu_divd" 4 -++ (and (ior (eq_attr "type" "fdivd") -++ (eq_attr "type" "fsqrtd")) -++ (eq_attr "pipeline_model" "graywolf")) -++ "gw_ii, gw_iq_p2, gw_rf_p2, gw_e1_p2, gw_e2_p2*28, gw_e3_p2, gw_e4_p2") -++ -++(define_insn_reservation "nds_gw_fpu_fast_alu" 2 -++ (and (ior (eq_attr "type" "fcmp") -++ (ior (eq_attr "type" "fabs") -++ (ior (eq_attr "type" "fcpy") -++ (eq_attr "type" "fcmov")))) -++ (eq_attr "pipeline_model" "graywolf")) -++ "gw_ii, gw_iq_p2, gw_rf_p2, gw_e1_p2, gw_e2_p2, gw_e3_p2, gw_e4_p2") -++ -++(define_insn_reservation "nds_gw_fpu_fmtsr" 1 -++ (and (eq_attr "type" "fmtsr") -++ (eq_attr "pipeline_model" "graywolf")) -++ "gw_ii, gw_iq_p2, gw_rf_p2, gw_e1_p2, gw_e2_p2, gw_e3_p2, gw_e4_p2") -++ -++(define_insn_reservation "nds_gw_fpu_fmtdr" 1 -++ (and (eq_attr "type" "fmtdr") -++ (eq_attr "pipeline_model" "graywolf")) -++ "gw_ii, gw_ii+gw_iq_p2, gw_iq_p2+gw_rf_p2, gw_rf_p2+gw_e1_p2, gw_e1_p2+gw_e2_p2, gw_e2_p2+gw_e3_p2, gw_e3_p2+gw_e4_p2, gw_e4_p2") -++ -++(define_insn_reservation "nds_gw_fpu_fmfsr" 1 -++ (and (eq_attr "type" "fmfsr") -++ (eq_attr "pipeline_model" "graywolf")) -++ "gw_ii, gw_iq_p2, gw_rf_p2, gw_e1_p2, gw_e2_p2, gw_e3_p2, gw_e4_p2") -++ -++(define_insn_reservation "nds_gw_fpu_fmfdr" 1 -++ (and (eq_attr "type" "fmfdr") -++ (eq_attr "pipeline_model" "graywolf")) -++ "gw_ii, gw_ii+gw_iq_p2, gw_iq_p2+gw_rf_p2, gw_rf_p2+gw_e1_p2, gw_e1_p2+gw_e2_p2, gw_e2_p2+gw_e3_p2, gw_e3_p2+gw_e4_p2, gw_e4_p2") -++ -++(define_insn_reservation "nds_gw_fpu_load" 3 -++ (and (eq_attr "type" "fload") -++ (eq_attr "pipeline_model" "graywolf")) -++ "gw_ii, gw_iq_p2, gw_rf_p2, gw_e1_p2, gw_e2_p2, gw_e3_p2, gw_e4_p2") -++ -++(define_insn_reservation "nds_gw_fpu_store" 1 -++ (and (eq_attr "type" "fstore") -++ (eq_attr "pipeline_model" "graywolf")) -++ "gw_ii, gw_iq_p2, gw_rf_p2, gw_e1_p2, gw_e2_p2, gw_e3_p2, gw_e4_p2") -++ -++;; FPU_ADDR_OUT -> FPU_ADDR_IN -++;; Main pipeline rules don't need this because those default latency is 1. -++(define_bypass 1 -++ "nds_gw_fpu_load, nds_gw_fpu_store" -++ "nds_gw_fpu_load, nds_gw_fpu_store" -++ "nds32_gw_ex_to_ex_p" -++) -++ -++;; LD, MUL, MAC, DIV, DALU64, DMUL, DMAC, DALUROUND, DBPICK, DWEXT -++;; -> ALU, ALU_SHIFT_Rb, PBSAD, PBSADA_RaRb, MOVD44, MUL, MAC_RaRb, DIV, ADDR_IN, BR, MMU, -++;; DALU, DALUROUND, DMUL, DMAC_RaRb, DPACK, DINSB, DCMP, DCLIP, WEXT_O, BPICK_RaRb -++(define_bypass 2 -++ "nds_gw_load, nds_gw_load_2w,\ -++ nds_gw_mul_fast1, nds_gw_mul_fast2, nds_gw_mul_slow,\ -++ nds_gw_mac_fast1, nds_gw_mac_fast2, nds_gw_mac_slow,\ -++ nds_gw_div, nds_gw_div_2w,\ -++ nds_gw_dsp_alu64, nds_gw_dsp_mul, nds_gw_dsp_mac,\ -++ nds_gw_dsp_alu_round, nds_gw_dsp_bpick, nds_gw_dsp_wext" -++ "nds_gw_alu, nds_gw_movd44, nds_gw_alu_shift,\ -++ nds_gw_pbsad, nds_gw_pbsada,\ -++ nds_gw_mul_fast1, nds_gw_mul_fast2, nds_gw_mul_slow,\ -++ nds_gw_mac_fast1, nds_gw_mac_fast2, nds_gw_mac_slow,\ -++ nds_gw_branch,\ -++ nds_gw_div, nds_gw_div_2w,\ -++ nds_gw_load, nds_gw_load_2w, nds_gw_store, nds_gw_store_3r,\ -++ nds_gw_load_multiple_1,nds_gw_load_multiple_2, nds_gw_load_multiple_3,\ -++ nds_gw_load_multiple_4,nds_gw_load_multiple_5, nds_gw_load_multiple_6,\ -++ nds_gw_load_multiple_7,nds_gw_load_multiple_8, nds_gw_load_multiple_12,\ -++ nds_gw_store_multiple_1,nds_gw_store_multiple_2, nds_gw_store_multiple_3,\ -++ nds_gw_store_multiple_4,nds_gw_store_multiple_5, nds_gw_store_multiple_6,\ -++ nds_gw_store_multiple_7,nds_gw_store_multiple_8, nds_gw_store_multiple_12,\ -++ nds_gw_mmu,\ -++ nds_gw_dsp_alu, nds_gw_dsp_alu_round,\ -++ nds_gw_dsp_mul, nds_gw_dsp_mac, nds_gw_dsp_pack,\ -++ nds_gw_dsp_insb, nds_gw_dsp_cmp, nds_gw_dsp_clip,\ -++ nds_gw_dsp_wext, nds_gw_dsp_bpick" -++ "nds32_gw_mm_to_ex_p" -++) -++ -++;; LMW(N, N) -++;; -> ALU, ALU_SHIFT_Rb, PBSAD, PBSADA_RaRb, MOVD44, MUL, MAC_RaRb, DIV, ADDR_IN, BR, MMU -++;; DALU, DALUROUND, DMUL, DMAC_RaRb, DPACK, DINSB, DCMP, DCLIP, WEXT_O, BPICK_RaRb -++(define_bypass 2 -++ "nds_gw_load_multiple_1,nds_gw_load_multiple_2, nds_gw_load_multiple_3,\ -++ nds_gw_load_multiple_4,nds_gw_load_multiple_5, nds_gw_load_multiple_6,\ -++ nds_gw_load_multiple_7,nds_gw_load_multiple_8, nds_gw_load_multiple_12" -++ "nds_gw_alu, nds_gw_movd44, nds_gw_alu_shift,\ -++ nds_gw_pbsad, nds_gw_pbsada,\ -++ nds_gw_mul_fast1, nds_gw_mul_fast2, nds_gw_mul_slow,\ -++ nds_gw_mac_fast1, nds_gw_mac_fast2, nds_gw_mac_slow,\ -++ nds_gw_branch,\ -++ nds_gw_div, nds_gw_div_2w,\ -++ nds_gw_load, nds_gw_load_2w, nds_gw_store, nds_gw_store_3r,\ -++ nds_gw_load_multiple_1,nds_gw_load_multiple_2, nds_gw_load_multiple_3,\ -++ nds_gw_load_multiple_4,nds_gw_load_multiple_5, nds_gw_load_multiple_6,\ -++ nds_gw_load_multiple_7,nds_gw_load_multiple_8, nds_gw_load_multiple_12,\ -++ nds_gw_store_multiple_1,nds_gw_store_multiple_2, nds_gw_store_multiple_3,\ -++ nds_gw_store_multiple_4,nds_gw_store_multiple_5, nds_gw_store_multiple_6,\ -++ nds_gw_store_multiple_7,nds_gw_store_multiple_8, nds_gw_store_multiple_12,\ -++ nds_gw_mmu,\ -++ nds_gw_dsp_alu, nds_gw_dsp_alu_round,\ -++ nds_gw_dsp_mul, nds_gw_dsp_mac, nds_gw_dsp_pack,\ -++ nds_gw_dsp_insb, nds_gw_dsp_cmp, nds_gw_dsp_clip,\ -++ nds_gw_dsp_wext, nds_gw_dsp_bpick" -++ "nds32_gw_last_load_to_ex_p" -++) -+diff --git a/gcc/config/nds32/nds32-intrinsic.c b/gcc/config/nds32/nds32-intrinsic.c -+index b9bb2d995f7..c2ad927b05d 100644 -+--- a/gcc/config/nds32/nds32-intrinsic.c -++++ b/gcc/config/nds32/nds32-intrinsic.c -+@@ -519,6 +519,7 @@ static struct builtin_description bdesc_noarg[] = -+ { -+ NDS32_BUILTIN(unspec_fmfcfg, "fmfcfg", FMFCFG) -+ NDS32_BUILTIN(unspec_fmfcsr, "fmfcsr", FMFCSR) -++ NDS32_BUILTIN(unspec_volatile_rdov, "rdov", RDOV) -+ NDS32_BUILTIN(unspec_get_current_sp, "get_current_sp", GET_CURRENT_SP) -+ NDS32_BUILTIN(unspec_return_address, "return_address", RETURN_ADDRESS) -+ NDS32_BUILTIN(unspec_get_all_pending_int, "get_all_pending_int", -+@@ -558,6 +559,31 @@ static struct builtin_description bdesc_1arg[] = -+ NDS32_NO_TARGET_BUILTIN(unspec_ret_itoff, "ret_itoff", RET_ITOFF) -+ NDS32_NO_TARGET_BUILTIN(unspec_set_current_sp, -+ "set_current_sp", SET_CURRENT_SP) -++ NDS32_BUILTIN(kabsv2hi2, "kabs16", KABS16) -++ NDS32_BUILTIN(kabsv2hi2, "v_kabs16", V_KABS16) -++ NDS32_BUILTIN(kabsv4qi2, "kabs8", KABS8) -++ NDS32_BUILTIN(kabsv4qi2, "v_kabs8", V_KABS8) -++ NDS32_BUILTIN(sunpkd810, "sunpkd810", SUNPKD810) -++ NDS32_BUILTIN(sunpkd810, "v_sunpkd810", V_SUNPKD810) -++ NDS32_BUILTIN(sunpkd820, "sunpkd820", SUNPKD820) -++ NDS32_BUILTIN(sunpkd820, "v_sunpkd820", V_SUNPKD820) -++ NDS32_BUILTIN(sunpkd830, "sunpkd830", SUNPKD830) -++ NDS32_BUILTIN(sunpkd830, "v_sunpkd830", V_SUNPKD830) -++ NDS32_BUILTIN(sunpkd831, "sunpkd831", SUNPKD831) -++ NDS32_BUILTIN(sunpkd831, "v_sunpkd831", V_SUNPKD831) -++ NDS32_BUILTIN(zunpkd810, "zunpkd810", ZUNPKD810) -++ NDS32_BUILTIN(zunpkd810, "v_zunpkd810", V_ZUNPKD810) -++ NDS32_BUILTIN(zunpkd820, "zunpkd820", ZUNPKD820) -++ NDS32_BUILTIN(zunpkd820, "v_zunpkd820", V_ZUNPKD820) -++ NDS32_BUILTIN(zunpkd830, "zunpkd830", ZUNPKD830) -++ NDS32_BUILTIN(zunpkd830, "v_zunpkd830", V_ZUNPKD830) -++ NDS32_BUILTIN(zunpkd831, "zunpkd831", ZUNPKD831) -++ NDS32_BUILTIN(zunpkd831, "v_zunpkd831", V_ZUNPKD831) -++ NDS32_BUILTIN(unspec_kabs, "kabs", KABS) -++ NDS32_BUILTIN(unaligned_loadv2hi, "get_unaligned_u16x2", UALOAD_U16) -++ NDS32_BUILTIN(unaligned_loadv2hi, "get_unaligned_s16x2", UALOAD_S16) -++ NDS32_BUILTIN(unaligned_loadv4qi, "get_unaligned_u8x4", UALOAD_U8) -++ NDS32_BUILTIN(unaligned_loadv4qi, "get_unaligned_s8x4", UALOAD_S8) -+ }; -+ -+ /* Intrinsics that take just one argument. and the argument is immediate. */ -+@@ -593,6 +619,28 @@ static struct builtin_description bdesc_2arg[] = -+ NDS32_BUILTIN(unspec_ffb, "ffb", FFB) -+ NDS32_BUILTIN(unspec_ffmism, "ffmsim", FFMISM) -+ NDS32_BUILTIN(unspec_flmism, "flmism", FLMISM) -++ NDS32_BUILTIN(unspec_kaddw, "kaddw", KADDW) -++ NDS32_BUILTIN(unspec_kaddh, "kaddh", KADDH) -++ NDS32_BUILTIN(unspec_ksubw, "ksubw", KSUBW) -++ NDS32_BUILTIN(unspec_ksubh, "ksubh", KSUBH) -++ NDS32_BUILTIN(unspec_kdmbb, "kdmbb", KDMBB) -++ NDS32_BUILTIN(unspec_kdmbb, "v_kdmbb", V_KDMBB) -++ NDS32_BUILTIN(unspec_kdmbt, "kdmbt", KDMBT) -++ NDS32_BUILTIN(unspec_kdmbt, "v_kdmbt", V_KDMBT) -++ NDS32_BUILTIN(unspec_kdmtb, "kdmtb", KDMTB) -++ NDS32_BUILTIN(unspec_kdmtb, "v_kdmtb", V_KDMTB) -++ NDS32_BUILTIN(unspec_kdmtt, "kdmtt", KDMTT) -++ NDS32_BUILTIN(unspec_kdmtt, "v_kdmtt", V_KDMTT) -++ NDS32_BUILTIN(unspec_khmbb, "khmbb", KHMBB) -++ NDS32_BUILTIN(unspec_khmbb, "v_khmbb", V_KHMBB) -++ NDS32_BUILTIN(unspec_khmbt, "khmbt", KHMBT) -++ NDS32_BUILTIN(unspec_khmbt, "v_khmbt", V_KHMBT) -++ NDS32_BUILTIN(unspec_khmtb, "khmtb", KHMTB) -++ NDS32_BUILTIN(unspec_khmtb, "v_khmtb", V_KHMTB) -++ NDS32_BUILTIN(unspec_khmtt, "khmtt", KHMTT) -++ NDS32_BUILTIN(unspec_khmtt, "v_khmtt", V_KHMTT) -++ NDS32_BUILTIN(unspec_kslraw, "kslraw", KSLRAW) -++ NDS32_BUILTIN(unspec_kslrawu, "kslraw_u", KSLRAW_U) -+ NDS32_BUILTIN(rotrsi3, "rotr", ROTR) -+ NDS32_BUILTIN(unspec_sva, "sva", SVA) -+ NDS32_BUILTIN(unspec_svs, "svs", SVS) -+@@ -603,7 +651,202 @@ static struct builtin_description bdesc_2arg[] = -+ NDS32_NO_TARGET_BUILTIN(unaligned_store_hw, "unaligned_store_hw", UASTORE_HW) -+ NDS32_NO_TARGET_BUILTIN(unaligned_storesi, "unaligned_store_hw", UASTORE_W) -+ NDS32_NO_TARGET_BUILTIN(unaligned_storedi, "unaligned_store_hw", UASTORE_DW) -+- -++ NDS32_BUILTIN(addv2hi3, "add16", ADD16) -++ NDS32_BUILTIN(addv2hi3, "v_uadd16", V_UADD16) -++ NDS32_BUILTIN(addv2hi3, "v_sadd16", V_SADD16) -++ NDS32_BUILTIN(raddv2hi3, "radd16", RADD16) -++ NDS32_BUILTIN(raddv2hi3, "v_radd16", V_RADD16) -++ NDS32_BUILTIN(uraddv2hi3, "uradd16", URADD16) -++ NDS32_BUILTIN(uraddv2hi3, "v_uradd16", V_URADD16) -++ NDS32_BUILTIN(kaddv2hi3, "kadd16", KADD16) -++ NDS32_BUILTIN(kaddv2hi3, "v_kadd16", V_KADD16) -++ NDS32_BUILTIN(ukaddv2hi3, "ukadd16", UKADD16) -++ NDS32_BUILTIN(ukaddv2hi3, "v_ukadd16", V_UKADD16) -++ NDS32_BUILTIN(subv2hi3, "sub16", SUB16) -++ NDS32_BUILTIN(subv2hi3, "v_usub16", V_USUB16) -++ NDS32_BUILTIN(subv2hi3, "v_ssub16", V_SSUB16) -++ NDS32_BUILTIN(rsubv2hi3, "rsub16", RSUB16) -++ NDS32_BUILTIN(rsubv2hi3, "v_rsub16", V_RSUB16) -++ NDS32_BUILTIN(ursubv2hi3, "ursub16", URSUB16) -++ NDS32_BUILTIN(ursubv2hi3, "v_ursub16", V_URSUB16) -++ NDS32_BUILTIN(ksubv2hi3, "ksub16", KSUB16) -++ NDS32_BUILTIN(ksubv2hi3, "v_ksub16", V_KSUB16) -++ NDS32_BUILTIN(uksubv2hi3, "uksub16", UKSUB16) -++ NDS32_BUILTIN(uksubv2hi3, "v_uksub16", V_UKSUB16) -++ NDS32_BUILTIN(cras16_1, "cras16", CRAS16) -++ NDS32_BUILTIN(cras16_1, "v_ucras16", V_UCRAS16) -++ NDS32_BUILTIN(cras16_1, "v_scras16", V_SCRAS16) -++ NDS32_BUILTIN(rcras16_1, "rcras16", RCRAS16) -++ NDS32_BUILTIN(rcras16_1, "v_rcras16", V_RCRAS16) -++ NDS32_BUILTIN(urcras16_1, "urcras16", URCRAS16) -++ NDS32_BUILTIN(urcras16_1, "v_urcras16", V_URCRAS16) -++ NDS32_BUILTIN(kcras16_1, "kcras16", KCRAS16) -++ NDS32_BUILTIN(kcras16_1, "v_kcras16", V_KCRAS16) -++ NDS32_BUILTIN(ukcras16_1, "ukcras16", UKCRAS16) -++ NDS32_BUILTIN(ukcras16_1, "v_ukcras16", V_UKCRAS16) -++ NDS32_BUILTIN(crsa16_1, "crsa16", CRSA16) -++ NDS32_BUILTIN(crsa16_1, "v_ucrsa16", V_UCRSA16) -++ NDS32_BUILTIN(crsa16_1, "v_scrsa16", V_SCRSA16) -++ NDS32_BUILTIN(rcrsa16_1, "rcrsa16", RCRSA16) -++ NDS32_BUILTIN(rcrsa16_1, "v_rcrsa16", V_RCRSA16) -++ NDS32_BUILTIN(urcrsa16_1, "urcrsa16", URCRSA16) -++ NDS32_BUILTIN(urcrsa16_1, "v_urcrsa16", V_URCRSA16) -++ NDS32_BUILTIN(kcrsa16_1, "kcrsa16", KCRSA16) -++ NDS32_BUILTIN(kcrsa16_1, "v_kcrsa16", V_KCRSA16) -++ NDS32_BUILTIN(ukcrsa16_1, "ukcrsa16", UKCRSA16) -++ NDS32_BUILTIN(ukcrsa16_1, "v_ukcrsa16", V_UKCRSA16) -++ NDS32_BUILTIN(addv4qi3, "add8", ADD8) -++ NDS32_BUILTIN(addv4qi3, "v_uadd8", V_UADD8) -++ NDS32_BUILTIN(addv4qi3, "v_sadd8", V_SADD8) -++ NDS32_BUILTIN(raddv4qi3, "radd8", RADD8) -++ NDS32_BUILTIN(raddv4qi3, "v_radd8", V_RADD8) -++ NDS32_BUILTIN(uraddv4qi3, "uradd8", URADD8) -++ NDS32_BUILTIN(uraddv4qi3, "v_uradd8", V_URADD8) -++ NDS32_BUILTIN(kaddv4qi3, "kadd8", KADD8) -++ NDS32_BUILTIN(kaddv4qi3, "v_kadd8", V_KADD8) -++ NDS32_BUILTIN(ukaddv4qi3, "ukadd8", UKADD8) -++ NDS32_BUILTIN(ukaddv4qi3, "v_ukadd8", V_UKADD8) -++ NDS32_BUILTIN(subv4qi3, "sub8", SUB8) -++ NDS32_BUILTIN(subv4qi3, "v_usub8", V_USUB8) -++ NDS32_BUILTIN(subv4qi3, "v_ssub8", V_SSUB8) -++ NDS32_BUILTIN(rsubv4qi3, "rsub8", RSUB8) -++ NDS32_BUILTIN(rsubv4qi3, "v_rsub8", V_RSUB8) -++ NDS32_BUILTIN(ursubv4qi3, "ursub8", URSUB8) -++ NDS32_BUILTIN(ursubv4qi3, "v_ursub8", V_URSUB8) -++ NDS32_BUILTIN(ksubv4qi3, "ksub8", KSUB8) -++ NDS32_BUILTIN(ksubv4qi3, "v_ksub8", V_KSUB8) -++ NDS32_BUILTIN(uksubv4qi3, "uksub8", UKSUB8) -++ NDS32_BUILTIN(uksubv4qi3, "v_uksub8", V_UKSUB8) -++ NDS32_BUILTIN(ashrv2hi3, "sra16", SRA16) -++ NDS32_BUILTIN(ashrv2hi3, "v_sra16", V_SRA16) -++ NDS32_BUILTIN(sra16_round, "sra16_u", SRA16_U) -++ NDS32_BUILTIN(sra16_round, "v_sra16_u", V_SRA16_U) -++ NDS32_BUILTIN(lshrv2hi3, "srl16", SRL16) -++ NDS32_BUILTIN(lshrv2hi3, "v_srl16", V_SRL16) -++ NDS32_BUILTIN(srl16_round, "srl16_u", SRL16_U) -++ NDS32_BUILTIN(srl16_round, "v_srl16_u", V_SRL16_U) -++ NDS32_BUILTIN(ashlv2hi3, "sll16", SLL16) -++ NDS32_BUILTIN(ashlv2hi3, "v_sll16", V_SLL16) -++ NDS32_BUILTIN(kslli16, "ksll16", KSLL16) -++ NDS32_BUILTIN(kslli16, "v_ksll16", V_KSLL16) -++ NDS32_BUILTIN(kslra16, "kslra16", KSLRA16) -++ NDS32_BUILTIN(kslra16, "v_kslra16", V_KSLRA16) -++ NDS32_BUILTIN(kslra16_round, "kslra16_u", KSLRA16_U) -++ NDS32_BUILTIN(kslra16_round, "v_kslra16_u", V_KSLRA16_U) -++ NDS32_BUILTIN(cmpeq16, "cmpeq16", CMPEQ16) -++ NDS32_BUILTIN(cmpeq16, "v_scmpeq16", V_SCMPEQ16) -++ NDS32_BUILTIN(cmpeq16, "v_ucmpeq16", V_UCMPEQ16) -++ NDS32_BUILTIN(scmplt16, "scmplt16", SCMPLT16) -++ NDS32_BUILTIN(scmplt16, "v_scmplt16", V_SCMPLT16) -++ NDS32_BUILTIN(scmple16, "scmple16", SCMPLE16) -++ NDS32_BUILTIN(scmple16, "v_scmple16", V_SCMPLE16) -++ NDS32_BUILTIN(ucmplt16, "ucmplt16", UCMPLT16) -++ NDS32_BUILTIN(ucmplt16, "v_ucmplt16", V_UCMPLT16) -++ NDS32_BUILTIN(ucmplt16, "ucmple16", UCMPLE16) -++ NDS32_BUILTIN(ucmplt16, "v_ucmple16", V_UCMPLE16) -++ NDS32_BUILTIN(cmpeq8, "cmpeq8", CMPEQ8) -++ NDS32_BUILTIN(cmpeq8, "v_scmpeq8", V_SCMPEQ8) -++ NDS32_BUILTIN(cmpeq8, "v_ucmpeq8", V_UCMPEQ8) -++ NDS32_BUILTIN(scmplt8, "scmplt8", SCMPLT8) -++ NDS32_BUILTIN(scmplt8, "v_scmplt8", V_SCMPLT8) -++ NDS32_BUILTIN(scmple8, "scmple8", SCMPLE8) -++ NDS32_BUILTIN(scmple8, "v_scmple8", V_SCMPLE8) -++ NDS32_BUILTIN(ucmplt8, "ucmplt8", UCMPLT8) -++ NDS32_BUILTIN(ucmplt8, "v_ucmplt8", V_UCMPLT8) -++ NDS32_BUILTIN(ucmplt8, "ucmple8", UCMPLE8) -++ NDS32_BUILTIN(ucmplt8, "v_ucmple8", V_UCMPLE8) -++ NDS32_BUILTIN(sminv2hi3, "smin16", SMIN16) -++ NDS32_BUILTIN(sminv2hi3, "v_smin16", V_SMIN16) -++ NDS32_BUILTIN(uminv2hi3, "umin16", UMIN16) -++ NDS32_BUILTIN(uminv2hi3, "v_umin16", V_UMIN16) -++ NDS32_BUILTIN(smaxv2hi3, "smax16", SMAX16) -++ NDS32_BUILTIN(smaxv2hi3, "v_smax16", V_SMAX16) -++ NDS32_BUILTIN(umaxv2hi3, "umax16", UMAX16) -++ NDS32_BUILTIN(umaxv2hi3, "v_umax16", V_UMAX16) -++ NDS32_BUILTIN(khm16, "khm16", KHM16) -++ NDS32_BUILTIN(khm16, "v_khm16", V_KHM16) -++ NDS32_BUILTIN(khmx16, "khmx16", KHMX16) -++ NDS32_BUILTIN(khmx16, "v_khmx16", V_KHMX16) -++ NDS32_BUILTIN(sminv4qi3, "smin8", SMIN8) -++ NDS32_BUILTIN(sminv4qi3, "v_smin8", V_SMIN8) -++ NDS32_BUILTIN(uminv4qi3, "umin8", UMIN8) -++ NDS32_BUILTIN(uminv4qi3, "v_umin8", V_UMIN8) -++ NDS32_BUILTIN(smaxv4qi3, "smax8", SMAX8) -++ NDS32_BUILTIN(smaxv4qi3, "v_smax8", V_SMAX8) -++ NDS32_BUILTIN(umaxv4qi3, "umax8", UMAX8) -++ NDS32_BUILTIN(umaxv4qi3, "v_umax8", V_UMAX8) -++ NDS32_BUILTIN(raddsi3, "raddw", RADDW) -++ NDS32_BUILTIN(uraddsi3, "uraddw", URADDW) -++ NDS32_BUILTIN(rsubsi3, "rsubw", RSUBW) -++ NDS32_BUILTIN(ursubsi3, "ursubw", URSUBW) -++ NDS32_BUILTIN(sraiu, "sra_u", SRA_U) -++ NDS32_BUILTIN(kssl, "ksll", KSLL) -++ NDS32_BUILTIN(pkbb, "pkbb16", PKBB16) -++ NDS32_BUILTIN(pkbb, "v_pkbb16", V_PKBB16) -++ NDS32_BUILTIN(pkbt, "pkbt16", PKBT16) -++ NDS32_BUILTIN(pkbt, "v_pkbt16", V_PKBT16) -++ NDS32_BUILTIN(pktb, "pktb16", PKTB16) -++ NDS32_BUILTIN(pktb, "v_pktb16", V_PKTB16) -++ NDS32_BUILTIN(pktt, "pktt16", PKTT16) -++ NDS32_BUILTIN(pktt, "v_pktt16", V_PKTT16) -++ NDS32_BUILTIN(smulsi3_highpart, "smmul", SMMUL) -++ NDS32_BUILTIN(smmul_round, "smmul_u", SMMUL_U) -++ NDS32_BUILTIN(smmwb, "smmwb", SMMWB) -++ NDS32_BUILTIN(smmwb, "v_smmwb", V_SMMWB) -++ NDS32_BUILTIN(smmwb_round, "smmwb_u", SMMWB_U) -++ NDS32_BUILTIN(smmwb_round, "v_smmwb_u", V_SMMWB_U) -++ NDS32_BUILTIN(smmwt, "smmwt", SMMWT) -++ NDS32_BUILTIN(smmwt, "v_smmwt", V_SMMWT) -++ NDS32_BUILTIN(smmwt_round, "smmwt_u", SMMWT_U) -++ NDS32_BUILTIN(smmwt_round, "v_smmwt_u", V_SMMWT_U) -++ NDS32_BUILTIN(smbb, "smbb", SMBB) -++ NDS32_BUILTIN(smbb, "v_smbb", V_SMBB) -++ NDS32_BUILTIN(smbt, "smbt", SMBT) -++ NDS32_BUILTIN(smbt, "v_smbt", V_SMBT) -++ NDS32_BUILTIN(smtt, "smtt", SMTT) -++ NDS32_BUILTIN(smtt, "v_smtt", V_SMTT) -++ NDS32_BUILTIN(kmda, "kmda", KMDA) -++ NDS32_BUILTIN(kmda, "v_kmda", V_KMDA) -++ NDS32_BUILTIN(kmxda, "kmxda", KMXDA) -++ NDS32_BUILTIN(kmxda, "v_kmxda", V_KMXDA) -++ NDS32_BUILTIN(smds, "smds", SMDS) -++ NDS32_BUILTIN(smds, "v_smds", V_SMDS) -++ NDS32_BUILTIN(smdrs, "smdrs", SMDRS) -++ NDS32_BUILTIN(smdrs, "v_smdrs", V_SMDRS) -++ NDS32_BUILTIN(smxdsv, "smxds", SMXDS) -++ NDS32_BUILTIN(smxdsv, "v_smxds", V_SMXDS) -++ NDS32_BUILTIN(smal1, "smal", SMAL) -++ NDS32_BUILTIN(smal1, "v_smal", V_SMAL) -++ NDS32_BUILTIN(bitrev, "bitrev", BITREV) -++ NDS32_BUILTIN(wext, "wext", WEXT) -++ NDS32_BUILTIN(adddi3, "sadd64", SADD64) -++ NDS32_BUILTIN(adddi3, "uadd64", UADD64) -++ NDS32_BUILTIN(radddi3, "radd64", RADD64) -++ NDS32_BUILTIN(uradddi3, "uradd64", URADD64) -++ NDS32_BUILTIN(kadddi3, "kadd64", KADD64) -++ NDS32_BUILTIN(ukadddi3, "ukadd64", UKADD64) -++ NDS32_BUILTIN(subdi3, "ssub64", SSUB64) -++ NDS32_BUILTIN(subdi3, "usub64", USUB64) -++ NDS32_BUILTIN(rsubdi3, "rsub64", RSUB64) -++ NDS32_BUILTIN(ursubdi3, "ursub64", URSUB64) -++ NDS32_BUILTIN(ksubdi3, "ksub64", KSUB64) -++ NDS32_BUILTIN(uksubdi3, "uksub64", UKSUB64) -++ NDS32_BUILTIN(smul16, "smul16", SMUL16) -++ NDS32_BUILTIN(smul16, "v_smul16", V_SMUL16) -++ NDS32_BUILTIN(smulx16, "smulx16", SMULX16) -++ NDS32_BUILTIN(smulx16, "v_smulx16", V_SMULX16) -++ NDS32_BUILTIN(umul16, "umul16", UMUL16) -++ NDS32_BUILTIN(umul16, "v_umul16", V_UMUL16) -++ NDS32_BUILTIN(umulx16, "umulx16", UMULX16) -++ NDS32_BUILTIN(umulx16, "v_umulx16", V_UMULX16) -++ NDS32_BUILTIN(kwmmul, "kwmmul", KWMMUL) -++ NDS32_BUILTIN(kwmmul_round, "kwmmul_u", KWMMUL_U) -++ NDS32_NO_TARGET_BUILTIN(unaligned_storev2hi, -++ "put_unaligned_u16x2", UASTORE_U16) -++ NDS32_NO_TARGET_BUILTIN(unaligned_storev2hi, -++ "put_unaligned_s16x2", UASTORE_S16) -++ NDS32_NO_TARGET_BUILTIN(unaligned_storev4qi, "put_unaligned_u8x4", UASTORE_U8) -++ NDS32_NO_TARGET_BUILTIN(unaligned_storev4qi, "put_unaligned_s8x4", UASTORE_S8) -+ }; -+ -+ /* Two-argument intrinsics with an immediate second argument. */ -+@@ -617,6 +860,22 @@ static struct builtin_description bdesc_2argimm[] = -+ NDS32_BUILTIN(unspec_clips, "clips", CLIPS) -+ NDS32_NO_TARGET_BUILTIN(unspec_teqz, "teqz", TEQZ) -+ NDS32_NO_TARGET_BUILTIN(unspec_tnez, "tnez", TNEZ) -++ NDS32_BUILTIN(ashrv2hi3, "srl16", SRL16) -++ NDS32_BUILTIN(ashrv2hi3, "v_srl16", V_SRL16) -++ NDS32_BUILTIN(srl16_round, "srl16_u", SRL16_U) -++ NDS32_BUILTIN(srl16_round, "v_srl16_u", V_SRL16_U) -++ NDS32_BUILTIN(kslli16, "ksll16", KSLL16) -++ NDS32_BUILTIN(kslli16, "v_ksll16", V_KSLL16) -++ NDS32_BUILTIN(sclip16, "sclip16", SCLIP16) -++ NDS32_BUILTIN(sclip16, "v_sclip16", V_SCLIP16) -++ NDS32_BUILTIN(uclip16, "uclip16", UCLIP16) -++ NDS32_BUILTIN(uclip16, "v_uclip16", V_UCLIP16) -++ NDS32_BUILTIN(sraiu, "sra_u", SRA_U) -++ NDS32_BUILTIN(kssl, "ksll", KSLL) -++ NDS32_BUILTIN(bitrev, "bitrev", BITREV) -++ NDS32_BUILTIN(wext, "wext", WEXT) -++ NDS32_BUILTIN(uclip32, "uclip32", UCLIP32) -++ NDS32_BUILTIN(sclip32, "sclip32", SCLIP32) -+ }; -+ -+ /* Intrinsics that take three arguments. */ -+@@ -625,6 +884,67 @@ static struct builtin_description bdesc_3arg[] = -+ NDS32_BUILTIN(unspec_pbsada, "pbsada", PBSADA) -+ NDS32_NO_TARGET_BUILTIN(bse, "bse", BSE) -+ NDS32_NO_TARGET_BUILTIN(bsp, "bsp", BSP) -++ NDS32_BUILTIN(kmabb, "kmabb", KMABB) -++ NDS32_BUILTIN(kmabb, "v_kmabb", V_KMABB) -++ NDS32_BUILTIN(kmabt, "kmabt", KMABT) -++ NDS32_BUILTIN(kmabt, "v_kmabt", V_KMABT) -++ NDS32_BUILTIN(kmatt, "kmatt", KMATT) -++ NDS32_BUILTIN(kmatt, "v_kmatt", V_KMATT) -++ NDS32_BUILTIN(kmada, "kmada", KMADA) -++ NDS32_BUILTIN(kmada, "v_kmada", V_KMADA) -++ NDS32_BUILTIN(kmaxda, "kmaxda", KMAXDA) -++ NDS32_BUILTIN(kmaxda, "v_kmaxda", V_KMAXDA) -++ NDS32_BUILTIN(kmads, "kmads", KMADS) -++ NDS32_BUILTIN(kmads, "v_kmads", V_KMADS) -++ NDS32_BUILTIN(kmadrs, "kmadrs", KMADRS) -++ NDS32_BUILTIN(kmadrs, "v_kmadrs", V_KMADRS) -++ NDS32_BUILTIN(kmaxds, "kmaxds", KMAXDS) -++ NDS32_BUILTIN(kmaxds, "v_kmaxds", V_KMAXDS) -++ NDS32_BUILTIN(kmsda, "kmsda", KMSDA) -++ NDS32_BUILTIN(kmsda, "v_kmsda", V_KMSDA) -++ NDS32_BUILTIN(kmsxda, "kmsxda", KMSXDA) -++ NDS32_BUILTIN(kmsxda, "v_kmsxda", V_KMSXDA) -++ NDS32_BUILTIN(bpick1, "bpick", BPICK) -++ NDS32_BUILTIN(smar64_1, "smar64", SMAR64) -++ NDS32_BUILTIN(smsr64, "smsr64", SMSR64) -++ NDS32_BUILTIN(umar64_1, "umar64", UMAR64) -++ NDS32_BUILTIN(umsr64, "umsr64", UMSR64) -++ NDS32_BUILTIN(kmar64_1, "kmar64", KMAR64) -++ NDS32_BUILTIN(kmsr64, "kmsr64", KMSR64) -++ NDS32_BUILTIN(ukmar64_1, "ukmar64", UKMAR64) -++ NDS32_BUILTIN(ukmsr64, "ukmsr64", UKMSR64) -++ NDS32_BUILTIN(smalbb, "smalbb", SMALBB) -++ NDS32_BUILTIN(smalbb, "v_smalbb", V_SMALBB) -++ NDS32_BUILTIN(smalbt, "smalbt", SMALBT) -++ NDS32_BUILTIN(smalbt, "v_smalbt", V_SMALBT) -++ NDS32_BUILTIN(smaltt, "smaltt", SMALTT) -++ NDS32_BUILTIN(smaltt, "v_smaltt", V_SMALTT) -++ NDS32_BUILTIN(smalda1, "smalda", SMALDA) -++ NDS32_BUILTIN(smalda1, "v_smalda", V_SMALDA) -++ NDS32_BUILTIN(smalxda1, "smalxda", SMALXDA) -++ NDS32_BUILTIN(smalxda1, "v_smalxda", V_SMALXDA) -++ NDS32_BUILTIN(smalds1, "smalds", SMALDS) -++ NDS32_BUILTIN(smalds1, "v_smalds", V_SMALDS) -++ NDS32_BUILTIN(smaldrs3, "smaldrs", SMALDRS) -++ NDS32_BUILTIN(smaldrs3, "v_smaldrs", V_SMALDRS) -++ NDS32_BUILTIN(smalxds1, "smalxds", SMALXDS) -++ NDS32_BUILTIN(smalxds1, "v_smalxds", V_SMALXDS) -++ NDS32_BUILTIN(smslda1, "smslda", SMSLDA) -++ NDS32_BUILTIN(smslda1, "v_smslda", V_SMSLDA) -++ NDS32_BUILTIN(smslxda1, "smslxda", SMSLXDA) -++ NDS32_BUILTIN(smslxda1, "v_smslxda", V_SMSLXDA) -++ NDS32_BUILTIN(kmmawb, "kmmawb", KMMAWB) -++ NDS32_BUILTIN(kmmawb, "v_kmmawb", V_KMMAWB) -++ NDS32_BUILTIN(kmmawb_round, "kmmawb_u", KMMAWB_U) -++ NDS32_BUILTIN(kmmawb_round, "v_kmmawb_u", V_KMMAWB_U) -++ NDS32_BUILTIN(kmmawt, "kmmawt", KMMAWT) -++ NDS32_BUILTIN(kmmawt, "v_kmmawt", V_KMMAWT) -++ NDS32_BUILTIN(kmmawt_round, "kmmawt_u", KMMAWT_U) -++ NDS32_BUILTIN(kmmawt_round, "v_kmmawt_u", V_KMMAWT_U) -++ NDS32_BUILTIN(kmmac, "kmmac", KMMAC) -++ NDS32_BUILTIN(kmmac_round, "kmmac_u", KMMAC_U) -++ NDS32_BUILTIN(kmmsb, "kmmsb", KMMSB) -++ NDS32_BUILTIN(kmmsb_round, "kmmsb_u", KMMSB_U) -+ }; -+ -+ /* Three-argument intrinsics with an immediate third argument. */ -+@@ -634,6 +954,7 @@ static struct builtin_description bdesc_3argimm[] = -+ NDS32_NO_TARGET_BUILTIN(prefetch_hw, "prefetch_hw", DPREF_HW) -+ NDS32_NO_TARGET_BUILTIN(prefetch_w, "prefetch_w", DPREF_W) -+ NDS32_NO_TARGET_BUILTIN(prefetch_dw, "prefetch_dw", DPREF_DW) -++ NDS32_BUILTIN(insb, "insb", INSB) -+ }; -+ -+ /* Intrinsics that load a value. */ -+@@ -676,6 +997,11 @@ nds32_expand_builtin_impl (tree exp, -+ unsigned i; -+ struct builtin_description *d; -+ -++ if (!NDS32_EXT_DSP_P () -++ && fcode > NDS32_BUILTIN_DSP_BEGIN -++ && fcode < NDS32_BUILTIN_DSP_END) -++ error ("don't support DSP extension instructions"); -++ -+ switch (fcode) -+ { -+ /* FPU Register Transfer. */ -+@@ -812,6 +1138,9 @@ nds32_expand_builtin_impl (tree exp, -+ case NDS32_BUILTIN_CCTL_L1D_WBALL_ONE_LVL: -+ emit_insn (gen_cctl_l1d_wball_one_lvl()); -+ return target; -++ case NDS32_BUILTIN_CLROV: -++ emit_insn (gen_unspec_volatile_clrov ()); -++ return target; -+ case NDS32_BUILTIN_STANDBY_NO_WAKE_GRANT: -+ emit_insn (gen_unspec_standby_no_wake_grant ()); -+ return target; -+@@ -947,10 +1276,18 @@ nds32_init_builtins_impl (void) -+ NDS32_BUILTIN_ ## CODE, BUILT_IN_MD, NULL, NULL_TREE) -+ -+ /* Looking for return type and argument can be found in tree.h file. */ -++ tree ptr_char_type_node = build_pointer_type (char_type_node); -+ tree ptr_uchar_type_node = build_pointer_type (unsigned_char_type_node); -+ tree ptr_ushort_type_node = build_pointer_type (short_unsigned_type_node); -++ tree ptr_short_type_node = build_pointer_type (short_integer_type_node); -+ tree ptr_uint_type_node = build_pointer_type (unsigned_type_node); -+ tree ptr_ulong_type_node = build_pointer_type (long_long_unsigned_type_node); -++ tree v4qi_type_node = build_vector_type (intQI_type_node, 4); -++ tree u_v4qi_type_node = build_vector_type (unsigned_intQI_type_node, 4); -++ tree v2hi_type_node = build_vector_type (intHI_type_node, 2); -++ tree u_v2hi_type_node = build_vector_type (unsigned_intHI_type_node, 2); -++ tree v2si_type_node = build_vector_type (intSI_type_node, 2); -++ tree u_v2si_type_node = build_vector_type (unsigned_intSI_type_node, 2); -+ -+ /* Cache. */ -+ ADD_NDS32_BUILTIN1 ("isync", void, ptr_uint, ISYNC); -+@@ -1050,6 +1387,31 @@ nds32_init_builtins_impl (void) -+ ADD_NDS32_BUILTIN2 ("se_ffmism", integer, unsigned, unsigned, FFMISM); -+ ADD_NDS32_BUILTIN2 ("se_flmism", integer, unsigned, unsigned, FLMISM); -+ -++ /* SATURATION */ -++ ADD_NDS32_BUILTIN2 ("kaddw", integer, integer, integer, KADDW); -++ ADD_NDS32_BUILTIN2 ("ksubw", integer, integer, integer, KSUBW); -++ ADD_NDS32_BUILTIN2 ("kaddh", integer, integer, integer, KADDH); -++ ADD_NDS32_BUILTIN2 ("ksubh", integer, integer, integer, KSUBH); -++ ADD_NDS32_BUILTIN2 ("kdmbb", integer, unsigned, unsigned, KDMBB); -++ ADD_NDS32_BUILTIN2 ("v_kdmbb", integer, v2hi, v2hi, V_KDMBB); -++ ADD_NDS32_BUILTIN2 ("kdmbt", integer, unsigned, unsigned, KDMBT); -++ ADD_NDS32_BUILTIN2 ("v_kdmbt", integer, v2hi, v2hi, V_KDMBT); -++ ADD_NDS32_BUILTIN2 ("kdmtb", integer, unsigned, unsigned, KDMTB); -++ ADD_NDS32_BUILTIN2 ("v_kdmtb", integer, v2hi, v2hi, V_KDMTB); -++ ADD_NDS32_BUILTIN2 ("kdmtt", integer, unsigned, unsigned, KDMTT); -++ ADD_NDS32_BUILTIN2 ("v_kdmtt", integer, v2hi, v2hi, V_KDMTT); -++ ADD_NDS32_BUILTIN2 ("khmbb", integer, unsigned, unsigned, KHMBB); -++ ADD_NDS32_BUILTIN2 ("v_khmbb", integer, v2hi, v2hi, V_KHMBB); -++ ADD_NDS32_BUILTIN2 ("khmbt", integer, unsigned, unsigned, KHMBT); -++ ADD_NDS32_BUILTIN2 ("v_khmbt", integer, v2hi, v2hi, V_KHMBT); -++ ADD_NDS32_BUILTIN2 ("khmtb", integer, unsigned, unsigned, KHMTB); -++ ADD_NDS32_BUILTIN2 ("v_khmtb", integer, v2hi, v2hi, V_KHMTB); -++ ADD_NDS32_BUILTIN2 ("khmtt", integer, unsigned, unsigned, KHMTT); -++ ADD_NDS32_BUILTIN2 ("v_khmtt", integer, v2hi, v2hi, V_KHMTT); -++ ADD_NDS32_BUILTIN2 ("kslraw", integer, integer, integer, KSLRAW); -++ ADD_NDS32_BUILTIN2 ("kslraw_u", integer, integer, integer, KSLRAW_U); -++ ADD_NDS32_BUILTIN0 ("rdov", unsigned, RDOV); -++ ADD_NDS32_BUILTIN0 ("clrov", void, CLROV); -+ -+ /* ROTR */ -+ ADD_NDS32_BUILTIN2 ("rotr", unsigned, unsigned, unsigned, ROTR); -+@@ -1109,4 +1471,384 @@ nds32_init_builtins_impl (void) -+ ADD_NDS32_BUILTIN0 ("enable_unaligned", void, ENABLE_UNALIGNED); -+ ADD_NDS32_BUILTIN0 ("disable_unaligned", void, DISABLE_UNALIGNED); -+ -++ /* DSP Extension: SIMD 16bit Add and Subtract. */ -++ ADD_NDS32_BUILTIN2 ("add16", unsigned, unsigned, unsigned, ADD16); -++ ADD_NDS32_BUILTIN2 ("v_uadd16", u_v2hi, u_v2hi, u_v2hi, V_UADD16); -++ ADD_NDS32_BUILTIN2 ("v_sadd16", v2hi, v2hi, v2hi, V_SADD16); -++ ADD_NDS32_BUILTIN2 ("radd16", unsigned, unsigned, unsigned, RADD16); -++ ADD_NDS32_BUILTIN2 ("v_radd16", v2hi, v2hi, v2hi, V_RADD16); -++ ADD_NDS32_BUILTIN2 ("uradd16", unsigned, unsigned, unsigned, URADD16); -++ ADD_NDS32_BUILTIN2 ("v_uradd16", u_v2hi, u_v2hi, u_v2hi, V_URADD16); -++ ADD_NDS32_BUILTIN2 ("kadd16", unsigned, unsigned, unsigned, KADD16); -++ ADD_NDS32_BUILTIN2 ("v_kadd16", v2hi, v2hi, v2hi, V_KADD16); -++ ADD_NDS32_BUILTIN2 ("ukadd16", unsigned, unsigned, unsigned, UKADD16); -++ ADD_NDS32_BUILTIN2 ("v_ukadd16", u_v2hi, u_v2hi, u_v2hi, V_UKADD16); -++ ADD_NDS32_BUILTIN2 ("sub16", unsigned, unsigned, unsigned, SUB16); -++ ADD_NDS32_BUILTIN2 ("v_usub16", u_v2hi, u_v2hi, u_v2hi, V_USUB16); -++ ADD_NDS32_BUILTIN2 ("v_ssub16", v2hi, v2hi, v2hi, V_SSUB16); -++ ADD_NDS32_BUILTIN2 ("rsub16", unsigned, unsigned, unsigned, RSUB16); -++ ADD_NDS32_BUILTIN2 ("v_rsub16", v2hi, v2hi, v2hi, V_RSUB16); -++ ADD_NDS32_BUILTIN2 ("ursub16", unsigned, unsigned, unsigned, URSUB16); -++ ADD_NDS32_BUILTIN2 ("v_ursub16", u_v2hi, u_v2hi, u_v2hi, V_URSUB16); -++ ADD_NDS32_BUILTIN2 ("ksub16", unsigned, unsigned, unsigned, KSUB16); -++ ADD_NDS32_BUILTIN2 ("v_ksub16", v2hi, v2hi, v2hi, V_KSUB16); -++ ADD_NDS32_BUILTIN2 ("uksub16", unsigned, unsigned, unsigned, UKSUB16); -++ ADD_NDS32_BUILTIN2 ("v_uksub16", u_v2hi, u_v2hi, u_v2hi, V_UKSUB16); -++ ADD_NDS32_BUILTIN2 ("cras16", unsigned, unsigned, unsigned, CRAS16); -++ ADD_NDS32_BUILTIN2 ("v_ucras16", u_v2hi, u_v2hi, u_v2hi, V_UCRAS16); -++ ADD_NDS32_BUILTIN2 ("v_scras16", v2hi, v2hi, v2hi, V_SCRAS16); -++ ADD_NDS32_BUILTIN2 ("rcras16", unsigned, unsigned, unsigned, RCRAS16); -++ ADD_NDS32_BUILTIN2 ("v_rcras16", v2hi, v2hi, v2hi, V_RCRAS16); -++ ADD_NDS32_BUILTIN2 ("urcras16", unsigned, unsigned, unsigned, URCRAS16); -++ ADD_NDS32_BUILTIN2 ("v_urcras16", u_v2hi, u_v2hi, u_v2hi, V_URCRAS16); -++ ADD_NDS32_BUILTIN2 ("kcras16", unsigned, unsigned, unsigned, KCRAS16); -++ ADD_NDS32_BUILTIN2 ("v_kcras16", v2hi, v2hi, v2hi, V_KCRAS16); -++ ADD_NDS32_BUILTIN2 ("ukcras16", unsigned, unsigned, unsigned, UKCRAS16); -++ ADD_NDS32_BUILTIN2 ("v_ukcras16", u_v2hi, u_v2hi, u_v2hi, V_UKCRAS16); -++ ADD_NDS32_BUILTIN2 ("crsa16", unsigned, unsigned, unsigned, CRSA16); -++ ADD_NDS32_BUILTIN2 ("v_ucrsa16", u_v2hi, u_v2hi, u_v2hi, V_UCRSA16); -++ ADD_NDS32_BUILTIN2 ("v_scrsa16", v2hi, v2hi, v2hi, V_SCRSA16); -++ ADD_NDS32_BUILTIN2 ("rcrsa16", unsigned, unsigned, unsigned, RCRSA16); -++ ADD_NDS32_BUILTIN2 ("v_rcrsa16", v2hi, v2hi, v2hi, V_RCRSA16); -++ ADD_NDS32_BUILTIN2 ("urcrsa16", unsigned, unsigned, unsigned, URCRSA16); -++ ADD_NDS32_BUILTIN2 ("v_urcrsa16", u_v2hi, u_v2hi, u_v2hi, V_URCRSA16); -++ ADD_NDS32_BUILTIN2 ("kcrsa16", unsigned, unsigned, unsigned, KCRSA16); -++ ADD_NDS32_BUILTIN2 ("v_kcrsa16", v2hi, v2hi, v2hi, V_KCRSA16); -++ ADD_NDS32_BUILTIN2 ("ukcrsa16", unsigned, unsigned, unsigned, UKCRSA16); -++ ADD_NDS32_BUILTIN2 ("v_ukcrsa16", u_v2hi, u_v2hi, u_v2hi, V_UKCRSA16); -++ -++ /* DSP Extension: SIMD 8bit Add and Subtract. */ -++ ADD_NDS32_BUILTIN2 ("add8", integer, integer, integer, ADD8); -++ ADD_NDS32_BUILTIN2 ("v_uadd8", u_v4qi, u_v4qi, u_v4qi, V_UADD8); -++ ADD_NDS32_BUILTIN2 ("v_sadd8", v4qi, v4qi, v4qi, V_SADD8); -++ ADD_NDS32_BUILTIN2 ("radd8", unsigned, unsigned, unsigned, RADD8); -++ ADD_NDS32_BUILTIN2 ("v_radd8", v4qi, v4qi, v4qi, V_RADD8); -++ ADD_NDS32_BUILTIN2 ("uradd8", unsigned, unsigned, unsigned, URADD8); -++ ADD_NDS32_BUILTIN2 ("v_uradd8", u_v4qi, u_v4qi, u_v4qi, V_URADD8); -++ ADD_NDS32_BUILTIN2 ("kadd8", unsigned, unsigned, unsigned, KADD8); -++ ADD_NDS32_BUILTIN2 ("v_kadd8", v4qi, v4qi, v4qi, V_KADD8); -++ ADD_NDS32_BUILTIN2 ("ukadd8", unsigned, unsigned, unsigned, UKADD8); -++ ADD_NDS32_BUILTIN2 ("v_ukadd8", u_v4qi, u_v4qi, u_v4qi, V_UKADD8); -++ ADD_NDS32_BUILTIN2 ("sub8", integer, integer, integer, SUB8); -++ ADD_NDS32_BUILTIN2 ("v_usub8", u_v4qi, u_v4qi, u_v4qi, V_USUB8); -++ ADD_NDS32_BUILTIN2 ("v_ssub8", v4qi, v4qi, v4qi, V_SSUB8); -++ ADD_NDS32_BUILTIN2 ("rsub8", unsigned, unsigned, unsigned, RSUB8); -++ ADD_NDS32_BUILTIN2 ("v_rsub8", v4qi, v4qi, v4qi, V_RSUB8); -++ ADD_NDS32_BUILTIN2 ("ursub8", unsigned, unsigned, unsigned, URSUB8); -++ ADD_NDS32_BUILTIN2 ("v_ursub8", u_v4qi, u_v4qi, u_v4qi, V_URSUB8); -++ ADD_NDS32_BUILTIN2 ("ksub8", unsigned, unsigned, unsigned, KSUB8); -++ ADD_NDS32_BUILTIN2 ("v_ksub8", v4qi, v4qi, v4qi, V_KSUB8); -++ ADD_NDS32_BUILTIN2 ("uksub8", unsigned, unsigned, unsigned, UKSUB8); -++ ADD_NDS32_BUILTIN2 ("v_uksub8", u_v4qi, u_v4qi, u_v4qi, V_UKSUB8); -++ -++ /* DSP Extension: SIMD 16bit Shift. */ -++ ADD_NDS32_BUILTIN2 ("sra16", unsigned, unsigned, unsigned, SRA16); -++ ADD_NDS32_BUILTIN2 ("v_sra16", v2hi, v2hi, unsigned, V_SRA16); -++ ADD_NDS32_BUILTIN2 ("sra16_u", unsigned, unsigned, unsigned, SRA16_U); -++ ADD_NDS32_BUILTIN2 ("v_sra16_u", v2hi, v2hi, unsigned, V_SRA16_U); -++ ADD_NDS32_BUILTIN2 ("srl16", unsigned, unsigned, unsigned, SRL16); -++ ADD_NDS32_BUILTIN2 ("v_srl16", u_v2hi, u_v2hi, unsigned, V_SRL16); -++ ADD_NDS32_BUILTIN2 ("srl16_u", unsigned, unsigned, unsigned, SRL16_U); -++ ADD_NDS32_BUILTIN2 ("v_srl16_u", u_v2hi, u_v2hi, unsigned, V_SRL16_U); -++ ADD_NDS32_BUILTIN2 ("sll16", unsigned, unsigned, unsigned, SLL16); -++ ADD_NDS32_BUILTIN2 ("v_sll16", u_v2hi, u_v2hi, unsigned, V_SLL16); -++ ADD_NDS32_BUILTIN2 ("ksll16", unsigned, unsigned, unsigned, KSLL16); -++ ADD_NDS32_BUILTIN2 ("v_ksll16", v2hi, v2hi, unsigned, V_KSLL16); -++ ADD_NDS32_BUILTIN2 ("kslra16", unsigned, unsigned, unsigned, KSLRA16); -++ ADD_NDS32_BUILTIN2 ("v_kslra16", v2hi, v2hi, unsigned, V_KSLRA16); -++ ADD_NDS32_BUILTIN2 ("kslra16_u", unsigned, unsigned, unsigned, KSLRA16_U); -++ ADD_NDS32_BUILTIN2 ("v_kslra16_u", v2hi, v2hi, unsigned, V_KSLRA16_U); -++ -++ /* DSP Extension: 16bit Compare. */ -++ ADD_NDS32_BUILTIN2 ("cmpeq16", unsigned, unsigned, unsigned, CMPEQ16); -++ ADD_NDS32_BUILTIN2 ("v_scmpeq16", u_v2hi, v2hi, v2hi, V_SCMPEQ16); -++ ADD_NDS32_BUILTIN2 ("v_ucmpeq16", u_v2hi, u_v2hi, u_v2hi, V_UCMPEQ16); -++ ADD_NDS32_BUILTIN2 ("scmplt16", unsigned, unsigned, unsigned, SCMPLT16); -++ ADD_NDS32_BUILTIN2 ("v_scmplt16", u_v2hi, v2hi, v2hi, V_SCMPLT16); -++ ADD_NDS32_BUILTIN2 ("scmple16", unsigned, unsigned, unsigned, SCMPLE16); -++ ADD_NDS32_BUILTIN2 ("v_scmple16", u_v2hi, v2hi, v2hi, V_SCMPLE16); -++ ADD_NDS32_BUILTIN2 ("ucmplt16", unsigned, unsigned, unsigned, UCMPLT16); -++ ADD_NDS32_BUILTIN2 ("v_ucmplt16", u_v2hi, u_v2hi, u_v2hi, V_UCMPLT16); -++ ADD_NDS32_BUILTIN2 ("ucmple16", unsigned, unsigned, unsigned, UCMPLE16); -++ ADD_NDS32_BUILTIN2 ("v_ucmple16", u_v2hi, u_v2hi, u_v2hi, V_UCMPLE16); -++ -++ /* DSP Extension: 8bit Compare. */ -++ ADD_NDS32_BUILTIN2 ("cmpeq8", unsigned, unsigned, unsigned, CMPEQ8); -++ ADD_NDS32_BUILTIN2 ("v_scmpeq8", u_v4qi, v4qi, v4qi, V_SCMPEQ8); -++ ADD_NDS32_BUILTIN2 ("v_ucmpeq8", u_v4qi, u_v4qi, u_v4qi, V_UCMPEQ8); -++ ADD_NDS32_BUILTIN2 ("scmplt8", unsigned, unsigned, unsigned, SCMPLT8); -++ ADD_NDS32_BUILTIN2 ("v_scmplt8", u_v4qi, v4qi, v4qi, V_SCMPLT8); -++ ADD_NDS32_BUILTIN2 ("scmple8", unsigned, unsigned, unsigned, SCMPLE8); -++ ADD_NDS32_BUILTIN2 ("v_scmple8", u_v4qi, v4qi, v4qi, V_SCMPLE8); -++ ADD_NDS32_BUILTIN2 ("ucmplt8", unsigned, unsigned, unsigned, UCMPLT8); -++ ADD_NDS32_BUILTIN2 ("v_ucmplt8", u_v4qi, u_v4qi, u_v4qi, V_UCMPLT8); -++ ADD_NDS32_BUILTIN2 ("ucmple8", unsigned, unsigned, unsigned, UCMPLE8); -++ ADD_NDS32_BUILTIN2 ("v_ucmple8", u_v4qi, u_v4qi, u_v4qi, V_UCMPLE8); -++ -++ /* DSP Extension: SIMD 16bit MISC. */ -++ ADD_NDS32_BUILTIN2 ("smin16", unsigned, unsigned, unsigned, SMIN16); -++ ADD_NDS32_BUILTIN2 ("v_smin16", v2hi, v2hi, v2hi, V_SMIN16); -++ ADD_NDS32_BUILTIN2 ("umin16", unsigned, unsigned, unsigned, UMIN16); -++ ADD_NDS32_BUILTIN2 ("v_umin16", u_v2hi, u_v2hi, u_v2hi, V_UMIN16); -++ ADD_NDS32_BUILTIN2 ("smax16", unsigned, unsigned, unsigned, SMAX16); -++ ADD_NDS32_BUILTIN2 ("v_smax16", v2hi, v2hi, v2hi, V_SMAX16); -++ ADD_NDS32_BUILTIN2 ("umax16", unsigned, unsigned, unsigned, UMAX16); -++ ADD_NDS32_BUILTIN2 ("v_umax16", u_v2hi, u_v2hi, u_v2hi, V_UMAX16); -++ ADD_NDS32_BUILTIN2 ("sclip16", unsigned, unsigned, unsigned, SCLIP16); -++ ADD_NDS32_BUILTIN2 ("v_sclip16", v2hi, v2hi, unsigned, V_SCLIP16); -++ ADD_NDS32_BUILTIN2 ("uclip16", unsigned, unsigned, unsigned, UCLIP16); -++ ADD_NDS32_BUILTIN2 ("v_uclip16", v2hi, v2hi, unsigned, V_UCLIP16); -++ ADD_NDS32_BUILTIN2 ("khm16", unsigned, unsigned, unsigned, KHM16); -++ ADD_NDS32_BUILTIN2 ("v_khm16", v2hi, v2hi, v2hi, V_KHM16); -++ ADD_NDS32_BUILTIN2 ("khmx16", unsigned, unsigned, unsigned, KHMX16); -++ ADD_NDS32_BUILTIN2 ("v_khmx16", v2hi, v2hi, v2hi, V_KHMX16); -++ ADD_NDS32_BUILTIN1 ("kabs16", unsigned, unsigned, KABS16); -++ ADD_NDS32_BUILTIN1 ("v_kabs16", v2hi, v2hi, V_KABS16); -++ ADD_NDS32_BUILTIN2 ("smul16", long_long_unsigned, unsigned, unsigned, SMUL16); -++ ADD_NDS32_BUILTIN2 ("v_smul16", v2si, v2hi, v2hi, V_SMUL16); -++ ADD_NDS32_BUILTIN2 ("smulx16", -++ long_long_unsigned, unsigned, unsigned, SMULX16); -++ ADD_NDS32_BUILTIN2 ("v_smulx16", v2si, v2hi, v2hi, V_SMULX16); -++ ADD_NDS32_BUILTIN2 ("umul16", long_long_unsigned, unsigned, unsigned, UMUL16); -++ ADD_NDS32_BUILTIN2 ("v_umul16", u_v2si, u_v2hi, u_v2hi, V_UMUL16); -++ ADD_NDS32_BUILTIN2 ("umulx16", -++ long_long_unsigned, unsigned, unsigned, UMULX16); -++ ADD_NDS32_BUILTIN2 ("v_umulx16", u_v2si, u_v2hi, u_v2hi, V_UMULX16); -++ -++ /* DSP Extension: SIMD 8bit MISC. */ -++ ADD_NDS32_BUILTIN2 ("smin8", unsigned, unsigned, unsigned, SMIN8); -++ ADD_NDS32_BUILTIN2 ("v_smin8", v4qi, v4qi, v4qi, V_SMIN8); -++ ADD_NDS32_BUILTIN2 ("umin8", unsigned, unsigned, unsigned, UMIN8); -++ ADD_NDS32_BUILTIN2 ("v_umin8", u_v4qi, u_v4qi, u_v4qi, V_UMIN8); -++ ADD_NDS32_BUILTIN2 ("smax8", unsigned, unsigned, unsigned, SMAX8); -++ ADD_NDS32_BUILTIN2 ("v_smax8", v4qi, v4qi, v4qi, V_SMAX8); -++ ADD_NDS32_BUILTIN2 ("umax8", unsigned, unsigned, unsigned, UMAX8); -++ ADD_NDS32_BUILTIN2 ("v_umax8", u_v4qi, u_v4qi, u_v4qi, V_UMAX8); -++ ADD_NDS32_BUILTIN1 ("kabs8", unsigned, unsigned, KABS8); -++ ADD_NDS32_BUILTIN1 ("v_kabs8", v4qi, v4qi, V_KABS8); -++ -++ /* DSP Extension: 8bit Unpacking. */ -++ ADD_NDS32_BUILTIN1 ("sunpkd810", unsigned, unsigned, SUNPKD810); -++ ADD_NDS32_BUILTIN1 ("v_sunpkd810", v2hi, v4qi, V_SUNPKD810); -++ ADD_NDS32_BUILTIN1 ("sunpkd820", unsigned, unsigned, SUNPKD820); -++ ADD_NDS32_BUILTIN1 ("v_sunpkd820", v2hi, v4qi, V_SUNPKD820); -++ ADD_NDS32_BUILTIN1 ("sunpkd830", unsigned, unsigned, SUNPKD830); -++ ADD_NDS32_BUILTIN1 ("v_sunpkd830", v2hi, v4qi, V_SUNPKD830); -++ ADD_NDS32_BUILTIN1 ("sunpkd831", unsigned, unsigned, SUNPKD831); -++ ADD_NDS32_BUILTIN1 ("v_sunpkd831", v2hi, v4qi, V_SUNPKD831); -++ ADD_NDS32_BUILTIN1 ("zunpkd810", unsigned, unsigned, ZUNPKD810); -++ ADD_NDS32_BUILTIN1 ("v_zunpkd810", u_v2hi, u_v4qi, V_ZUNPKD810); -++ ADD_NDS32_BUILTIN1 ("zunpkd820", unsigned, unsigned, ZUNPKD820); -++ ADD_NDS32_BUILTIN1 ("v_zunpkd820", u_v2hi, u_v4qi, V_ZUNPKD820); -++ ADD_NDS32_BUILTIN1 ("zunpkd830", unsigned, unsigned, ZUNPKD830); -++ ADD_NDS32_BUILTIN1 ("v_zunpkd830", u_v2hi, u_v4qi, V_ZUNPKD830); -++ ADD_NDS32_BUILTIN1 ("zunpkd831", unsigned, unsigned, ZUNPKD831); -++ ADD_NDS32_BUILTIN1 ("v_zunpkd831", u_v2hi, u_v4qi, V_ZUNPKD831); -++ -++ /* DSP Extension: 32bit Add and Subtract. */ -++ ADD_NDS32_BUILTIN2 ("raddw", integer, integer, integer, RADDW); -++ ADD_NDS32_BUILTIN2 ("uraddw", unsigned, unsigned, unsigned, URADDW); -++ ADD_NDS32_BUILTIN2 ("rsubw", integer, integer, integer, RSUBW); -++ ADD_NDS32_BUILTIN2 ("ursubw", unsigned, unsigned, unsigned, URSUBW); -++ -++ /* DSP Extension: 32bit Shift. */ -++ ADD_NDS32_BUILTIN2 ("sra_u", integer, integer, unsigned, SRA_U); -++ ADD_NDS32_BUILTIN2 ("ksll", integer, integer, unsigned, KSLL); -++ -++ /* DSP Extension: 16bit Packing. */ -++ ADD_NDS32_BUILTIN2 ("pkbb16", unsigned, unsigned, unsigned, PKBB16); -++ ADD_NDS32_BUILTIN2 ("v_pkbb16", u_v2hi, u_v2hi, u_v2hi, V_PKBB16); -++ ADD_NDS32_BUILTIN2 ("pkbt16", unsigned, unsigned, unsigned, PKBT16); -++ ADD_NDS32_BUILTIN2 ("v_pkbt16", u_v2hi, u_v2hi, u_v2hi, V_PKBT16); -++ ADD_NDS32_BUILTIN2 ("pktb16", unsigned, unsigned, unsigned, PKTB16); -++ ADD_NDS32_BUILTIN2 ("v_pktb16", u_v2hi, u_v2hi, u_v2hi, V_PKTB16); -++ ADD_NDS32_BUILTIN2 ("pktt16", unsigned, unsigned, unsigned, PKTT16); -++ ADD_NDS32_BUILTIN2 ("v_pktt16", u_v2hi, u_v2hi, u_v2hi, V_PKTT16); -++ -++ /* DSP Extension: Signed MSW 32x32 Multiply and ADD. */ -++ ADD_NDS32_BUILTIN2 ("smmul", integer, integer, integer, SMMUL); -++ ADD_NDS32_BUILTIN2 ("smmul_u", integer, integer, integer, SMMUL_U); -++ ADD_NDS32_BUILTIN3 ("kmmac", integer, integer, integer, integer, KMMAC); -++ ADD_NDS32_BUILTIN3 ("kmmac_u", integer, integer, integer, integer, KMMAC_U); -++ ADD_NDS32_BUILTIN3 ("kmmsb", integer, integer, integer, integer, KMMSB); -++ ADD_NDS32_BUILTIN3 ("kmmsb_u", integer, integer, integer, integer, KMMSB_U); -++ ADD_NDS32_BUILTIN2 ("kwmmul", integer, integer, integer, KWMMUL); -++ ADD_NDS32_BUILTIN2 ("kwmmul_u", integer, integer, integer, KWMMUL_U); -++ -++ /* DSP Extension: Most Significant Word 32x16 Multiply and ADD. */ -++ ADD_NDS32_BUILTIN2 ("smmwb", integer, integer, unsigned, SMMWB); -++ ADD_NDS32_BUILTIN2 ("v_smmwb", integer, integer, v2hi, V_SMMWB); -++ ADD_NDS32_BUILTIN2 ("smmwb_u", integer, integer, unsigned, SMMWB_U); -++ ADD_NDS32_BUILTIN2 ("v_smmwb_u", integer, integer, v2hi, V_SMMWB_U); -++ ADD_NDS32_BUILTIN2 ("smmwt", integer, integer, unsigned, SMMWT); -++ ADD_NDS32_BUILTIN2 ("v_smmwt", integer, integer, v2hi, V_SMMWT); -++ ADD_NDS32_BUILTIN2 ("smmwt_u", integer, integer, unsigned, SMMWT_U); -++ ADD_NDS32_BUILTIN2 ("v_smmwt_u", integer, integer, v2hi, V_SMMWT_U); -++ ADD_NDS32_BUILTIN3 ("kmmawb", integer, integer, integer, unsigned, KMMAWB); -++ ADD_NDS32_BUILTIN3 ("v_kmmawb", integer, integer, integer, v2hi, V_KMMAWB); -++ ADD_NDS32_BUILTIN3 ("kmmawb_u", -++ integer, integer, integer, unsigned, KMMAWB_U); -++ ADD_NDS32_BUILTIN3 ("v_kmmawb_u", -++ integer, integer, integer, v2hi, V_KMMAWB_U); -++ ADD_NDS32_BUILTIN3 ("kmmawt", integer, integer, integer, unsigned, KMMAWT); -++ ADD_NDS32_BUILTIN3 ("v_kmmawt", integer, integer, integer, v2hi, V_KMMAWT); -++ ADD_NDS32_BUILTIN3 ("kmmawt_u", -++ integer, integer, integer, unsigned, KMMAWT_U); -++ ADD_NDS32_BUILTIN3 ("v_kmmawt_u", -++ integer, integer, integer, v2hi, V_KMMAWT_U); -++ -++ /* DSP Extension: Signed 16bit Multiply with ADD/Subtract. */ -++ ADD_NDS32_BUILTIN2 ("smbb", integer, unsigned, unsigned, SMBB); -++ ADD_NDS32_BUILTIN2 ("v_smbb", integer, v2hi, v2hi, V_SMBB); -++ ADD_NDS32_BUILTIN2 ("smbt", integer, unsigned, unsigned, SMBT); -++ ADD_NDS32_BUILTIN2 ("v_smbt", integer, v2hi, v2hi, V_SMBT); -++ ADD_NDS32_BUILTIN2 ("smtt", integer, unsigned, unsigned, SMTT); -++ ADD_NDS32_BUILTIN2 ("v_smtt", integer, v2hi, v2hi, V_SMTT); -++ ADD_NDS32_BUILTIN2 ("kmda", integer, unsigned, unsigned, KMDA); -++ ADD_NDS32_BUILTIN2 ("v_kmda", integer, v2hi, v2hi, V_KMDA); -++ ADD_NDS32_BUILTIN2 ("kmxda", integer, unsigned, unsigned, KMXDA); -++ ADD_NDS32_BUILTIN2 ("v_kmxda", integer, v2hi, v2hi, V_KMXDA); -++ ADD_NDS32_BUILTIN2 ("smds", integer, unsigned, unsigned, SMDS); -++ ADD_NDS32_BUILTIN2 ("v_smds", integer, v2hi, v2hi, V_SMDS); -++ ADD_NDS32_BUILTIN2 ("smdrs", integer, unsigned, unsigned, SMDRS); -++ ADD_NDS32_BUILTIN2 ("v_smdrs", integer, v2hi, v2hi, V_SMDRS); -++ ADD_NDS32_BUILTIN2 ("smxds", integer, unsigned, unsigned, SMXDS); -++ ADD_NDS32_BUILTIN2 ("v_smxds", integer, v2hi, v2hi, V_SMXDS); -++ ADD_NDS32_BUILTIN3 ("kmabb", integer, integer, unsigned, unsigned, KMABB); -++ ADD_NDS32_BUILTIN3 ("v_kmabb", integer, integer, v2hi, v2hi, V_KMABB); -++ ADD_NDS32_BUILTIN3 ("kmabt", integer, integer, unsigned, unsigned, KMABT); -++ ADD_NDS32_BUILTIN3 ("v_kmabt", integer, integer, v2hi, v2hi, V_KMABT); -++ ADD_NDS32_BUILTIN3 ("kmatt", integer, integer, unsigned, unsigned, KMATT); -++ ADD_NDS32_BUILTIN3 ("v_kmatt", integer, integer, v2hi, v2hi, V_KMATT); -++ ADD_NDS32_BUILTIN3 ("kmada", integer, integer, unsigned, unsigned, KMADA); -++ ADD_NDS32_BUILTIN3 ("v_kmada", integer, integer, v2hi, v2hi, V_KMADA); -++ ADD_NDS32_BUILTIN3 ("kmaxda", integer, integer, unsigned, unsigned, KMAXDA); -++ ADD_NDS32_BUILTIN3 ("v_kmaxda", integer, integer, v2hi, v2hi, V_KMAXDA); -++ ADD_NDS32_BUILTIN3 ("kmads", integer, integer, unsigned, unsigned, KMADS); -++ ADD_NDS32_BUILTIN3 ("v_kmads", integer, integer, v2hi, v2hi, V_KMADS); -++ ADD_NDS32_BUILTIN3 ("kmadrs", integer, integer, unsigned, unsigned, KMADRS); -++ ADD_NDS32_BUILTIN3 ("v_kmadrs", integer, integer, v2hi, v2hi, V_KMADRS); -++ ADD_NDS32_BUILTIN3 ("kmaxds", integer, integer, unsigned, unsigned, KMAXDS); -++ ADD_NDS32_BUILTIN3 ("v_kmaxds", integer, integer, v2hi, v2hi, V_KMAXDS); -++ ADD_NDS32_BUILTIN3 ("kmsda", integer, integer, unsigned, unsigned, KMSDA); -++ ADD_NDS32_BUILTIN3 ("v_kmsda", integer, integer, v2hi, v2hi, V_KMSDA); -++ ADD_NDS32_BUILTIN3 ("kmsxda", integer, integer, unsigned, unsigned, KMSXDA); -++ ADD_NDS32_BUILTIN3 ("v_kmsxda", integer, integer, v2hi, v2hi, V_KMSXDA); -++ -++ /* DSP Extension: Signed 16bit Multiply with 64bit ADD/Subtract. */ -++ ADD_NDS32_BUILTIN2 ("smal", long_long_integer, -++ long_long_integer, unsigned, SMAL); -++ ADD_NDS32_BUILTIN2 ("v_smal", long_long_integer, -++ long_long_integer, v2hi, V_SMAL); -++ -++ /* DSP Extension: 32bit MISC. */ -++ ADD_NDS32_BUILTIN2 ("bitrev", unsigned, unsigned, unsigned, BITREV); -++ ADD_NDS32_BUILTIN2 ("wext", unsigned, long_long_integer, unsigned, WEXT); -++ ADD_NDS32_BUILTIN3 ("bpick", unsigned, unsigned, unsigned, unsigned, BPICK); -++ ADD_NDS32_BUILTIN3 ("insb", unsigned, unsigned, unsigned, unsigned, INSB); -++ -++ /* DSP Extension: 64bit Add and Subtract. */ -++ ADD_NDS32_BUILTIN2 ("sadd64", long_long_integer, -++ long_long_integer, long_long_integer, SADD64); -++ ADD_NDS32_BUILTIN2 ("uadd64", long_long_unsigned, -++ long_long_unsigned, long_long_unsigned, UADD64); -++ ADD_NDS32_BUILTIN2 ("radd64", long_long_integer, -++ long_long_integer, long_long_integer, RADD64); -++ ADD_NDS32_BUILTIN2 ("uradd64", long_long_unsigned, -++ long_long_unsigned, long_long_unsigned, URADD64); -++ ADD_NDS32_BUILTIN2 ("kadd64", long_long_integer, -++ long_long_integer, long_long_integer, KADD64); -++ ADD_NDS32_BUILTIN2 ("ukadd64", long_long_unsigned, -++ long_long_unsigned, long_long_unsigned, UKADD64); -++ ADD_NDS32_BUILTIN2 ("ssub64", long_long_integer, -++ long_long_integer, long_long_integer, SSUB64); -++ ADD_NDS32_BUILTIN2 ("usub64", long_long_unsigned, -++ long_long_unsigned, long_long_unsigned, USUB64); -++ ADD_NDS32_BUILTIN2 ("rsub64", long_long_integer, -++ long_long_integer, long_long_integer, RSUB64); -++ ADD_NDS32_BUILTIN2 ("ursub64", long_long_unsigned, -++ long_long_unsigned, long_long_unsigned, URSUB64); -++ ADD_NDS32_BUILTIN2 ("ksub64", long_long_integer, -++ long_long_integer, long_long_integer, KSUB64); -++ ADD_NDS32_BUILTIN2 ("uksub64", long_long_unsigned, -++ long_long_unsigned, long_long_unsigned, UKSUB64); -++ -++ /* DSP Extension: 32bit Multiply with 64bit Add/Subtract. */ -++ ADD_NDS32_BUILTIN3 ("smar64", long_long_integer, -++ long_long_integer, integer, integer, SMAR64); -++ ADD_NDS32_BUILTIN3 ("smsr64", long_long_integer, -++ long_long_integer, integer, integer, SMSR64); -++ ADD_NDS32_BUILTIN3 ("umar64", long_long_unsigned, -++ long_long_unsigned, unsigned, unsigned, UMAR64); -++ ADD_NDS32_BUILTIN3 ("umsr64", long_long_unsigned, -++ long_long_unsigned, unsigned, unsigned, UMSR64); -++ ADD_NDS32_BUILTIN3 ("kmar64", long_long_integer, -++ long_long_integer, integer, integer, KMAR64); -++ ADD_NDS32_BUILTIN3 ("kmsr64", long_long_integer, -++ long_long_integer, integer, integer, KMSR64); -++ ADD_NDS32_BUILTIN3 ("ukmar64", long_long_unsigned, -++ long_long_unsigned, unsigned, unsigned, UKMAR64); -++ ADD_NDS32_BUILTIN3 ("ukmsr64", long_long_unsigned, -++ long_long_unsigned, unsigned, unsigned, UKMSR64); -++ -++ /* DSP Extension: Signed 16bit Multiply with 64bit Add/Subtract. */ -++ ADD_NDS32_BUILTIN3 ("smalbb", long_long_integer, -++ long_long_integer, unsigned, unsigned, SMALBB); -++ ADD_NDS32_BUILTIN3 ("v_smalbb", long_long_integer, -++ long_long_integer, v2hi, v2hi, V_SMALBB); -++ ADD_NDS32_BUILTIN3 ("smalbt", long_long_integer, -++ long_long_integer, unsigned, unsigned, SMALBT); -++ ADD_NDS32_BUILTIN3 ("v_smalbt", long_long_integer, -++ long_long_integer, v2hi, v2hi, V_SMALBT); -++ ADD_NDS32_BUILTIN3 ("smaltt", long_long_integer, -++ long_long_integer, unsigned, unsigned, SMALTT); -++ ADD_NDS32_BUILTIN3 ("v_smaltt", long_long_integer, -++ long_long_integer, v2hi, v2hi, V_SMALTT); -++ ADD_NDS32_BUILTIN3 ("smalda", long_long_integer, -++ long_long_integer, unsigned, unsigned, SMALDA); -++ ADD_NDS32_BUILTIN3 ("v_smalda", long_long_integer, -++ long_long_integer, v2hi, v2hi, V_SMALDA); -++ ADD_NDS32_BUILTIN3 ("smalxda", long_long_integer, -++ long_long_integer, unsigned, unsigned, SMALXDA); -++ ADD_NDS32_BUILTIN3 ("v_smalxda", long_long_integer, -++ long_long_integer, v2hi, v2hi, V_SMALXDA); -++ ADD_NDS32_BUILTIN3 ("smalds", long_long_integer, -++ long_long_integer, unsigned, unsigned, SMALDS); -++ ADD_NDS32_BUILTIN3 ("v_smalds", long_long_integer, -++ long_long_integer, v2hi, v2hi, V_SMALDS); -++ ADD_NDS32_BUILTIN3 ("smaldrs", long_long_integer, -++ long_long_integer, unsigned, unsigned, SMALDRS); -++ ADD_NDS32_BUILTIN3 ("v_smaldrs", long_long_integer, -++ long_long_integer, v2hi, v2hi, V_SMALDRS); -++ ADD_NDS32_BUILTIN3 ("smalxds", long_long_integer, -++ long_long_integer, unsigned, unsigned, SMALXDS); -++ ADD_NDS32_BUILTIN3 ("v_smalxds", long_long_integer, -++ long_long_integer, v2hi, v2hi, V_SMALXDS); -++ ADD_NDS32_BUILTIN3 ("smslda", long_long_integer, -++ long_long_integer, unsigned, unsigned, SMSLDA); -++ ADD_NDS32_BUILTIN3 ("v_smslda", long_long_integer, -++ long_long_integer, v2hi, v2hi, V_SMSLDA); -++ ADD_NDS32_BUILTIN3 ("smslxda", long_long_integer, -++ long_long_integer, unsigned, unsigned, SMSLXDA); -++ ADD_NDS32_BUILTIN3 ("v_smslxda", long_long_integer, -++ long_long_integer, v2hi, v2hi, V_SMSLXDA); -++ -++ /* DSP Extension: augmented baseline. */ -++ ADD_NDS32_BUILTIN2 ("uclip32", unsigned, integer, unsigned, UCLIP32); -++ ADD_NDS32_BUILTIN2 ("sclip32", integer, integer, unsigned, SCLIP32); -++ ADD_NDS32_BUILTIN1 ("kabs", integer, integer, KABS); -++ -++ /* DSP Extension: vector type unaligned Load/Store */ -++ ADD_NDS32_BUILTIN1 ("get_unaligned_u16x2", u_v2hi, ptr_ushort, UALOAD_U16); -++ ADD_NDS32_BUILTIN1 ("get_unaligned_s16x2", v2hi, ptr_short, UALOAD_S16); -++ ADD_NDS32_BUILTIN1 ("get_unaligned_u8x4", u_v4qi, ptr_uchar, UALOAD_U8); -++ ADD_NDS32_BUILTIN1 ("get_unaligned_s8x4", v4qi, ptr_char, UALOAD_S8); -++ ADD_NDS32_BUILTIN2 ("put_unaligned_u16x2", void, ptr_ushort, -++ u_v2hi, UASTORE_U16); -++ ADD_NDS32_BUILTIN2 ("put_unaligned_s16x2", void, ptr_short, -++ v2hi, UASTORE_S16); -++ ADD_NDS32_BUILTIN2 ("put_unaligned_u8x4", void, ptr_uchar, -++ u_v4qi, UASTORE_U8); -++ ADD_NDS32_BUILTIN2 ("put_unaligned_s8x4", void, ptr_char, -++ v4qi, UASTORE_S8); -+ } -+diff --git a/gcc/config/nds32/nds32-intrinsic.md b/gcc/config/nds32/nds32-intrinsic.md -+index 24e7c0bf4a1..c70a6fcc99b 100644 -+--- a/gcc/config/nds32/nds32-intrinsic.md -++++ b/gcc/config/nds32/nds32-intrinsic.md -+@@ -1037,6 +1037,187 @@ -+ (set_attr "length" "4")] -+ ) -+ -++;; SATURATION -++ -++(define_insn "unspec_kaddw" -++ [(set (match_operand:SI 0 "register_operand" "=r") -++ (ss_plus:SI (match_operand:SI 1 "register_operand" "r") -++ (match_operand:SI 2 "register_operand" "r")))] -++ "" -++ "kaddw\t%0, %1, %2" -++ [(set_attr "type" "alu") -++ (set_attr "length" "4")] -++) -++ -++(define_insn "unspec_ksubw" -++ [(set (match_operand:SI 0 "register_operand" "=r") -++ (ss_minus:SI (match_operand:SI 1 "register_operand" "r") -++ (match_operand:SI 2 "register_operand" "r")))] -++ "" -++ "ksubw\t%0, %1, %2" -++ [(set_attr "type" "alu") -++ (set_attr "length" "4")] -++) -++ -++(define_insn "unspec_kaddh" -++ [(set (match_operand:SI 0 "register_operand" "=r") -++ (unspec:SI [(match_operand:SI 1 "register_operand" "r") -++ (match_operand:SI 2 "register_operand" "r")] UNSPEC_KADDH))] -++ "" -++ "kaddh\t%0, %1, %2" -++ [(set_attr "type" "alu") -++ (set_attr "length" "4")] -++) -++ -++(define_insn "unspec_ksubh" -++ [(set (match_operand:SI 0 "register_operand" "=r") -++ (unspec:SI [(match_operand:SI 1 "register_operand" "r") -++ (match_operand:SI 2 "register_operand" "r")] UNSPEC_KSUBH))] -++ "" -++ "ksubh\t%0, %1, %2" -++ [(set_attr "type" "alu") -++ (set_attr "length" "4")] -++) -++ -++(define_insn "unspec_kaddh_dsp" -++ [(set (match_operand:SI 0 "register_operand" "=r") -++ (unspec:SI [(plus:SI (match_operand:SI 1 "register_operand" "r") -++ (match_operand:SI 2 "register_operand" "r")) -++ (const_int 15)] UNSPEC_CLIPS))] -++ "NDS32_EXT_DSP_P ()" -++ "kaddh\t%0, %1, %2" -++ [(set_attr "type" "alu") -++ (set_attr "length" "4")] -++) -++ -++(define_insn "unspec_ksubh_dsp" -++ [(set (match_operand:SI 0 "register_operand" "=r") -++ (unspec:SI [(minus:SI (match_operand:SI 1 "register_operand" "r") -++ (match_operand:SI 2 "register_operand" "r")) -++ (const_int 15)] UNSPEC_CLIPS))] -++ "NDS32_EXT_DSP_P ()" -++ "ksubh\t%0, %1, %2" -++ [(set_attr "type" "alu") -++ (set_attr "length" "4")] -++) -++ -++(define_insn "unspec_kdmbb" -++ [(set (match_operand:V2HI 0 "register_operand" "=r") -++ (unspec:V2HI [(match_operand:V2HI 1 "register_operand" "r") -++ (match_operand:V2HI 2 "register_operand" "r")] UNSPEC_KDMBB))] -++ "" -++ "kdmbb\t%0, %1, %2" -++ [(set_attr "type" "mul") -++ (set_attr "length" "4")] -++) -++ -++(define_insn "unspec_kdmbt" -++ [(set (match_operand:V2HI 0 "register_operand" "=r") -++ (unspec:V2HI [(match_operand:V2HI 1 "register_operand" "r") -++ (match_operand:V2HI 2 "register_operand" "r")] UNSPEC_KDMBT))] -++ "" -++ "kdmbt\t%0, %1, %2" -++ [(set_attr "type" "mul") -++ (set_attr "length" "4")] -++) -++ -++(define_insn "unspec_kdmtb" -++ [(set (match_operand:V2HI 0 "register_operand" "=r") -++ (unspec:V2HI [(match_operand:V2HI 1 "register_operand" "r") -++ (match_operand:V2HI 2 "register_operand" "r")] UNSPEC_KDMTB))] -++ "" -++ "kdmtb\t%0, %1, %2" -++ [(set_attr "type" "mul") -++ (set_attr "length" "4")] -++) -++ -++(define_insn "unspec_kdmtt" -++ [(set (match_operand:V2HI 0 "register_operand" "=r") -++ (unspec:V2HI [(match_operand:V2HI 1 "register_operand" "r") -++ (match_operand:V2HI 2 "register_operand" "r")] UNSPEC_KDMTT))] -++ "" -++ "kdmtt\t%0, %1, %2" -++ [(set_attr "type" "mul") -++ (set_attr "length" "4")] -++) -++ -++(define_insn "unspec_khmbb" -++ [(set (match_operand:V2HI 0 "register_operand" "=r") -++ (unspec:V2HI [(match_operand:V2HI 1 "register_operand" "r") -++ (match_operand:V2HI 2 "register_operand" "r")] UNSPEC_KHMBB))] -++ "" -++ "khmbb\t%0, %1, %2" -++ [(set_attr "type" "mul") -++ (set_attr "length" "4")] -++) -++ -++(define_insn "unspec_khmbt" -++ [(set (match_operand:V2HI 0 "register_operand" "=r") -++ (unspec:V2HI [(match_operand:V2HI 1 "register_operand" "r") -++ (match_operand:V2HI 2 "register_operand" "r")] UNSPEC_KHMBT))] -++ "" -++ "khmbt\t%0, %1, %2" -++ [(set_attr "type" "mul") -++ (set_attr "length" "4")] -++) -++ -++(define_insn "unspec_khmtb" -++ [(set (match_operand:V2HI 0 "register_operand" "=r") -++ (unspec:V2HI [(match_operand:V2HI 1 "register_operand" "r") -++ (match_operand:V2HI 2 "register_operand" "r")] UNSPEC_KHMTB))] -++ "" -++ "khmtb\t%0, %1, %2" -++ [(set_attr "type" "mul") -++ (set_attr "length" "4")] -++) -++ -++(define_insn "unspec_khmtt" -++ [(set (match_operand:V2HI 0 "register_operand" "=r") -++ (unspec:V2HI [(match_operand:V2HI 1 "register_operand" "r") -++ (match_operand:V2HI 2 "register_operand" "r")] UNSPEC_KHMTT))] -++ "" -++ "khmtt\t%0, %1, %2" -++ [(set_attr "type" "mul") -++ (set_attr "length" "4")] -++) -++ -++(define_insn "unspec_kslraw" -++ [(set (match_operand:SI 0 "register_operand" "=r") -++ (unspec:SI [(match_operand:SI 1 "register_operand" "r") -++ (match_operand:SI 2 "register_operand" "r")] UNSPEC_KSLRAW))] -++ "" -++ "kslraw\t%0, %1, %2" -++ [(set_attr "type" "alu") -++ (set_attr "length" "4")] -++) -++ -++(define_insn "unspec_kslrawu" -++ [(set (match_operand:SI 0 "register_operand" "=r") -++ (unspec:SI [(match_operand:SI 1 "register_operand" "r") -++ (match_operand:SI 2 "register_operand" "r")] UNSPEC_KSLRAWU))] -++ "" -++ "kslraw.u\t%0, %1, %2" -++ [(set_attr "type" "alu") -++ (set_attr "length" "4")] -++) -++ -++(define_insn "unspec_volatile_rdov" -++ [(set (match_operand:SI 0 "register_operand" "=r") -++ (unspec_volatile:SI [(const_int 0)] UNSPEC_VOLATILE_RDOV))] -++ "" -++ "rdov\t%0" -++ [(set_attr "type" "misc") -++ (set_attr "length" "4")] -++) -++ -++(define_insn "unspec_volatile_clrov" -++ [(unspec_volatile:SI [(const_int 0)] UNSPEC_VOLATILE_CLROV)] -++ "" -++ "clrov" -++ [(set_attr "type" "misc") -++ (set_attr "length" "4")] -++) -++ -+ ;; System -+ -+ (define_insn "unspec_sva" -+@@ -1415,22 +1596,17 @@ -+ if (TARGET_ISA_V3M) -+ nds32_expand_unaligned_store (operands, DImode); -+ else -+- emit_insn (gen_unaligned_store_dw (operands[0], operands[1])); -++ emit_insn (gen_unaligned_store_dw (gen_rtx_MEM (DImode, operands[0]), -++ operands[1])); -+ DONE; -+ }) -+ -+ (define_insn "unaligned_store_dw" -+- [(set (mem:DI (match_operand:SI 0 "register_operand" "r")) -+- (unspec:DI [(match_operand:DI 1 "register_operand" "r")] UNSPEC_UASTORE_DW))] -++ [(set (match_operand:DI 0 "nds32_lmw_smw_base_operand" "=Umw") -++ (unspec:DI [(match_operand:DI 1 "register_operand" " r")] UNSPEC_UASTORE_DW))] -+ "" -+ { -+- rtx otherops[3]; -+- otherops[0] = gen_rtx_REG (SImode, REGNO (operands[1])); -+- otherops[1] = gen_rtx_REG (SImode, REGNO (operands[1]) + 1); -+- otherops[2] = operands[0]; -+- -+- output_asm_insn ("smw.bi\t%0, [%2], %1, 0", otherops); -+- return ""; -++ return nds32_output_smw_double_word (operands); -+ } -+ [(set_attr "type" "store") -+ (set_attr "length" "4")] -+@@ -1495,4 +1671,15 @@ -+ DONE; -+ }) -+ -++;; abs alias kabs -++ -++(define_insn "unspec_kabs" -++ [(set (match_operand:SI 0 "register_operand" "=r") -++ (unspec:SI [(match_operand:SI 1 "register_operand" "r")] UNSPEC_KABS))] -++ "" -++ "kabs\t%0, %1" -++ [(set_attr "type" "alu") -++ (set_attr "length" "4")] -++) -++ -+ ;; ------------------------------------------------------------------------ -+diff --git a/gcc/config/nds32/nds32-isr.c b/gcc/config/nds32/nds32-isr.c -+index 2c3aac7a256..db67a0e3666 100644 -+--- a/gcc/config/nds32/nds32-isr.c -++++ b/gcc/config/nds32/nds32-isr.c -+@@ -43,7 +43,260 @@ -+ We use an array to record essential information for each vector. */ -+ static struct nds32_isr_info nds32_isr_vectors[NDS32_N_ISR_VECTORS]; -+ -+-/* ------------------------------------------------------------------------ */ -++/* ------------------------------------------------------------- */ -++/* FIXME: -++ FOR BACKWARD COMPATIBILITY, we need to support following patterns: -++ -++ __attribute__((interrupt("XXX;YYY;id=ZZZ"))) -++ __attribute__((exception("XXX;YYY;id=ZZZ"))) -++ __attribute__((reset("vectors=XXX;nmi_func=YYY;warm_func=ZZZ"))) -++ -++ We provide several functions to parse the strings. */ -++ -++static void -++nds32_interrupt_attribute_parse_string (const char *original_str, -++ const char *func_name, -++ unsigned int s_level) -++{ -++ char target_str[100]; -++ enum nds32_isr_save_reg save_reg; -++ enum nds32_isr_nested_type nested_type; -++ -++ char *save_all_regs_str, *save_caller_regs_str; -++ char *nested_str, *not_nested_str, *ready_nested_str, *critical_str; -++ char *id_str, *value_str; -++ -++ /* Copy original string into a character array so that -++ the string APIs can handle it. */ -++ strcpy (target_str, original_str); -++ -++ /* 1. Detect 'save_all_regs' : NDS32_SAVE_ALL -++ 'save_caller_regs' : NDS32_PARTIAL_SAVE */ -++ save_all_regs_str = strstr (target_str, "save_all_regs"); -++ save_caller_regs_str = strstr (target_str, "save_caller_regs"); -++ -++ /* Note that if no argument is found, -++ use NDS32_PARTIAL_SAVE by default. */ -++ if (save_all_regs_str) -++ save_reg = NDS32_SAVE_ALL; -++ else if (save_caller_regs_str) -++ save_reg = NDS32_PARTIAL_SAVE; -++ else -++ save_reg = NDS32_PARTIAL_SAVE; -++ -++ /* 2. Detect 'nested' : NDS32_NESTED -++ 'not_nested' : NDS32_NOT_NESTED -++ 'ready_nested' : NDS32_NESTED_READY -++ 'critical' : NDS32_CRITICAL */ -++ nested_str = strstr (target_str, "nested"); -++ not_nested_str = strstr (target_str, "not_nested"); -++ ready_nested_str = strstr (target_str, "ready_nested"); -++ critical_str = strstr (target_str, "critical"); -++ -++ /* Note that if no argument is found, -++ use NDS32_NOT_NESTED by default. -++ Also, since 'not_nested' and 'ready_nested' both contains -++ 'nested' string, we check 'nested' with lowest priority. */ -++ if (not_nested_str) -++ nested_type = NDS32_NOT_NESTED; -++ else if (ready_nested_str) -++ nested_type = NDS32_NESTED_READY; -++ else if (nested_str) -++ nested_type = NDS32_NESTED; -++ else if (critical_str) -++ nested_type = NDS32_CRITICAL; -++ else -++ nested_type = NDS32_NOT_NESTED; -++ -++ /* 3. Traverse each id value and set corresponding information. */ -++ id_str = strstr (target_str, "id="); -++ -++ /* If user forgets to assign 'id', issue an error message. */ -++ if (id_str == NULL) -++ error ("require id argument in the string"); -++ /* Extract the value_str first. */ -++ id_str = strtok (id_str, "="); -++ value_str = strtok (NULL, ";"); -++ -++ /* Pick up the first id value token. */ -++ value_str = strtok (value_str, ","); -++ while (value_str != NULL) -++ { -++ int i; -++ i = atoi (value_str); -++ -++ /* For interrupt(0..63), the actual vector number is (9..72). */ -++ i = i + 9; -++ if (i < 9 || i > 72) -++ error ("invalid id value for interrupt attribute"); -++ -++ /* Setup nds32_isr_vectors[] array. */ -++ nds32_isr_vectors[i].category = NDS32_ISR_INTERRUPT; -++ strcpy (nds32_isr_vectors[i].func_name, func_name); -++ nds32_isr_vectors[i].save_reg = save_reg; -++ nds32_isr_vectors[i].nested_type = nested_type; -++ nds32_isr_vectors[i].security_level = s_level; -++ -++ /* Fetch next token. */ -++ value_str = strtok (NULL, ","); -++ } -++ -++ return; -++} -++ -++static void -++nds32_exception_attribute_parse_string (const char *original_str, -++ const char *func_name, -++ unsigned int s_level) -++{ -++ char target_str[100]; -++ enum nds32_isr_save_reg save_reg; -++ enum nds32_isr_nested_type nested_type; -++ -++ char *save_all_regs_str, *save_caller_regs_str; -++ char *nested_str, *not_nested_str, *ready_nested_str, *critical_str; -++ char *id_str, *value_str; -++ -++ /* Copy original string into a character array so that -++ the string APIs can handle it. */ -++ strcpy (target_str, original_str); -++ -++ /* 1. Detect 'save_all_regs' : NDS32_SAVE_ALL -++ 'save_caller_regs' : NDS32_PARTIAL_SAVE */ -++ save_all_regs_str = strstr (target_str, "save_all_regs"); -++ save_caller_regs_str = strstr (target_str, "save_caller_regs"); -++ -++ /* Note that if no argument is found, -++ use NDS32_PARTIAL_SAVE by default. */ -++ if (save_all_regs_str) -++ save_reg = NDS32_SAVE_ALL; -++ else if (save_caller_regs_str) -++ save_reg = NDS32_PARTIAL_SAVE; -++ else -++ save_reg = NDS32_PARTIAL_SAVE; -++ -++ /* 2. Detect 'nested' : NDS32_NESTED -++ 'not_nested' : NDS32_NOT_NESTED -++ 'ready_nested' : NDS32_NESTED_READY -++ 'critical' : NDS32_CRITICAL */ -++ nested_str = strstr (target_str, "nested"); -++ not_nested_str = strstr (target_str, "not_nested"); -++ ready_nested_str = strstr (target_str, "ready_nested"); -++ critical_str = strstr (target_str, "critical"); -++ -++ /* Note that if no argument is found, -++ use NDS32_NOT_NESTED by default. -++ Also, since 'not_nested' and 'ready_nested' both contains -++ 'nested' string, we check 'nested' with lowest priority. */ -++ if (not_nested_str) -++ nested_type = NDS32_NOT_NESTED; -++ else if (ready_nested_str) -++ nested_type = NDS32_NESTED_READY; -++ else if (nested_str) -++ nested_type = NDS32_NESTED; -++ else if (critical_str) -++ nested_type = NDS32_CRITICAL; -++ else -++ nested_type = NDS32_NOT_NESTED; -++ -++ /* 3. Traverse each id value and set corresponding information. */ -++ id_str = strstr (target_str, "id="); -++ -++ /* If user forgets to assign 'id', issue an error message. */ -++ if (id_str == NULL) -++ error ("require id argument in the string"); -++ /* Extract the value_str first. */ -++ id_str = strtok (id_str, "="); -++ value_str = strtok (NULL, ";"); -++ -++ /* Pick up the first id value token. */ -++ value_str = strtok (value_str, ","); -++ while (value_str != NULL) -++ { -++ int i; -++ i = atoi (value_str); -++ -++ /* For exception(1..8), the actual vector number is (1..8). */ -++ if (i < 1 || i > 8) -++ error ("invalid id value for exception attribute"); -++ -++ /* Setup nds32_isr_vectors[] array. */ -++ nds32_isr_vectors[i].category = NDS32_ISR_EXCEPTION; -++ strcpy (nds32_isr_vectors[i].func_name, func_name); -++ nds32_isr_vectors[i].save_reg = save_reg; -++ nds32_isr_vectors[i].nested_type = nested_type; -++ nds32_isr_vectors[i].security_level = s_level; -++ -++ /* Fetch next token. */ -++ value_str = strtok (NULL, ","); -++ } -++ -++ return; -++} -++ -++static void -++nds32_reset_attribute_parse_string (const char *original_str, -++ const char *func_name) -++{ -++ char target_str[100]; -++ char *vectors_str, *nmi_str, *warm_str, *value_str; -++ -++ /* Deal with reset attribute. Its vector number is always 0. */ -++ nds32_isr_vectors[0].category = NDS32_ISR_RESET; -++ -++ -++ /* 1. Parse 'vectors=XXXX'. */ -++ -++ /* Copy original string into a character array so that -++ the string APIs can handle it. */ -++ strcpy (target_str, original_str); -++ vectors_str = strstr (target_str, "vectors="); -++ /* The total vectors = interrupt + exception numbers + reset. -++ There are 8 exception and 1 reset in nds32 architecture. -++ If user forgets to assign 'vectors', user default 16 interrupts. */ -++ if (vectors_str != NULL) -++ { -++ /* Extract the value_str. */ -++ vectors_str = strtok (vectors_str, "="); -++ value_str = strtok (NULL, ";"); -++ nds32_isr_vectors[0].total_n_vectors = atoi (value_str) + 8 + 1; -++ } -++ else -++ nds32_isr_vectors[0].total_n_vectors = 16 + 8 + 1; -++ strcpy (nds32_isr_vectors[0].func_name, func_name); -++ -++ -++ /* 2. Parse 'nmi_func=YYYY'. */ -++ -++ /* Copy original string into a character array so that -++ the string APIs can handle it. */ -++ strcpy (target_str, original_str); -++ nmi_str = strstr (target_str, "nmi_func="); -++ if (nmi_str != NULL) -++ { -++ /* Extract the value_str. */ -++ nmi_str = strtok (nmi_str, "="); -++ value_str = strtok (NULL, ";"); -++ strcpy (nds32_isr_vectors[0].nmi_name, value_str); -++ } -++ -++ /* 3. Parse 'warm_func=ZZZZ'. */ -++ -++ /* Copy original string into a character array so that -++ the string APIs can handle it. */ -++ strcpy (target_str, original_str); -++ warm_str = strstr (target_str, "warm_func="); -++ if (warm_str != NULL) -++ { -++ /* Extract the value_str. */ -++ warm_str = strtok (warm_str, "="); -++ value_str = strtok (NULL, ";"); -++ strcpy (nds32_isr_vectors[0].warm_name, value_str); -++ } -++ -++ return; -++} -++/* ------------------------------------------------------------- */ -+ -+ /* A helper function to emit section head template. */ -+ static void -+@@ -79,6 +332,15 @@ nds32_emit_isr_jmptbl_section (int vector_id) -+ char section_name[100]; -+ char symbol_name[100]; -+ -++ /* A critical isr does not need jump table section because -++ its behavior is not performed by two-level handler. */ -++ if (nds32_isr_vectors[vector_id].nested_type == NDS32_CRITICAL) -++ { -++ fprintf (asm_out_file, "\t! The vector %02d is a critical isr !\n", -++ vector_id); -++ return; -++ } -++ -+ /* Prepare jmptbl section and symbol name. */ -+ snprintf (section_name, sizeof (section_name), -+ ".nds32_jmptbl.%02d", vector_id); -+@@ -99,7 +361,6 @@ nds32_emit_isr_vector_section (int vector_id) -+ const char *c_str = "CATEGORY"; -+ const char *sr_str = "SR"; -+ const char *nt_str = "NT"; -+- const char *vs_str = "VS"; -+ char first_level_handler_name[100]; -+ char section_name[100]; -+ char symbol_name[100]; -+@@ -147,30 +408,47 @@ nds32_emit_isr_vector_section (int vector_id) -+ case NDS32_NESTED_READY: -+ nt_str = "nr"; -+ break; -++ case NDS32_CRITICAL: -++ /* The critical isr is not performed by two-level handler. */ -++ nt_str = ""; -++ break; -+ } -+ -+- /* Currently we have 4-byte or 16-byte size for each vector. -+- If it is 4-byte, the first level handler name has suffix string "_4b". */ -+- vs_str = (nds32_isr_vector_size == 4) ? "_4b" : ""; -+- -+ /* Now we can create first level handler name. */ -+- snprintf (first_level_handler_name, sizeof (first_level_handler_name), -+- "_nds32_%s_%s_%s%s", c_str, sr_str, nt_str, vs_str); -++ if (nds32_isr_vectors[vector_id].security_level == 0) -++ { -++ /* For security level 0, use normal first level handler name. */ -++ snprintf (first_level_handler_name, sizeof (first_level_handler_name), -++ "_nds32_%s_%s_%s", c_str, sr_str, nt_str); -++ } -++ else -++ { -++ /* For security level 1-3, use corresponding spl_1, spl_2, or spl_3. */ -++ snprintf (first_level_handler_name, sizeof (first_level_handler_name), -++ "_nds32_spl_%d", nds32_isr_vectors[vector_id].security_level); -++ } -+ -+ /* Prepare vector section and symbol name. */ -+ snprintf (section_name, sizeof (section_name), -+ ".nds32_vector.%02d", vector_id); -+ snprintf (symbol_name, sizeof (symbol_name), -+- "_nds32_vector_%02d%s", vector_id, vs_str); -++ "_nds32_vector_%02d", vector_id); -+ -+ -+ /* Everything is ready. We can start emit vector section content. */ -+ nds32_emit_section_head_template (section_name, symbol_name, -+ floor_log2 (nds32_isr_vector_size), false); -+ -+- /* According to the vector size, the instructions in the -+- vector section may be different. */ -+- if (nds32_isr_vector_size == 4) -++ /* First we check if it is a critical isr. -++ If so, jump to user handler directly; otherwise, the instructions -++ in the vector section may be different according to the vector size. */ -++ if (nds32_isr_vectors[vector_id].nested_type == NDS32_CRITICAL) -++ { -++ /* This block is for critical isr. Jump to user handler directly. */ -++ fprintf (asm_out_file, "\tj\t%s ! jump to user handler directly\n", -++ nds32_isr_vectors[vector_id].func_name); -++ } -++ else if (nds32_isr_vector_size == 4) -+ { -+ /* This block is for 4-byte vector size. -+ Hardware $VID support is necessary and only one instruction -+@@ -239,13 +517,11 @@ nds32_emit_isr_reset_content (void) -+ { -+ unsigned int i; -+ unsigned int total_n_vectors; -+- const char *vs_str; -+ char reset_handler_name[100]; -+ char section_name[100]; -+ char symbol_name[100]; -+ -+ total_n_vectors = nds32_isr_vectors[0].total_n_vectors; -+- vs_str = (nds32_isr_vector_size == 4) ? "_4b" : ""; -+ -+ fprintf (asm_out_file, "\t! RESET HANDLER CONTENT - BEGIN !\n"); -+ -+@@ -261,7 +537,7 @@ nds32_emit_isr_reset_content (void) -+ /* Emit vector references. */ -+ fprintf (asm_out_file, "\t ! references to vector section entries\n"); -+ for (i = 0; i < total_n_vectors; i++) -+- fprintf (asm_out_file, "\t.word\t_nds32_vector_%02d%s\n", i, vs_str); -++ fprintf (asm_out_file, "\t.word\t_nds32_vector_%02d\n", i); -+ -+ /* Emit jmptbl_00 section. */ -+ snprintf (section_name, sizeof (section_name), ".nds32_jmptbl.00"); -+@@ -275,9 +551,9 @@ nds32_emit_isr_reset_content (void) -+ -+ /* Emit vector_00 section. */ -+ snprintf (section_name, sizeof (section_name), ".nds32_vector.00"); -+- snprintf (symbol_name, sizeof (symbol_name), "_nds32_vector_00%s", vs_str); -++ snprintf (symbol_name, sizeof (symbol_name), "_nds32_vector_00"); -+ snprintf (reset_handler_name, sizeof (reset_handler_name), -+- "_nds32_reset%s", vs_str); -++ "_nds32_reset"); -+ -+ fprintf (asm_out_file, "\t! ....................................\n"); -+ nds32_emit_section_head_template (section_name, symbol_name, -+@@ -323,12 +599,12 @@ void -+ nds32_check_isr_attrs_conflict (tree func_decl, tree func_attrs) -+ { -+ int save_all_p, partial_save_p; -+- int nested_p, not_nested_p, nested_ready_p; -++ int nested_p, not_nested_p, nested_ready_p, critical_p; -+ int intr_p, excp_p, reset_p; -+ -+ /* Initialize variables. */ -+ save_all_p = partial_save_p = 0; -+- nested_p = not_nested_p = nested_ready_p = 0; -++ nested_p = not_nested_p = nested_ready_p = critical_p = 0; -+ intr_p = excp_p = reset_p = 0; -+ -+ /* We must check at MOST one attribute to set save-reg. */ -+@@ -347,8 +623,10 @@ nds32_check_isr_attrs_conflict (tree func_decl, tree func_attrs) -+ not_nested_p = 1; -+ if (lookup_attribute ("nested_ready", func_attrs)) -+ nested_ready_p = 1; -++ if (lookup_attribute ("critical", func_attrs)) -++ critical_p = 1; -+ -+- if ((nested_p + not_nested_p + nested_ready_p) > 1) -++ if ((nested_p + not_nested_p + nested_ready_p + critical_p) > 1) -+ error ("multiple nested types attributes to function %qD", func_decl); -+ -+ /* We must check at MOST one attribute to -+@@ -362,6 +640,17 @@ nds32_check_isr_attrs_conflict (tree func_decl, tree func_attrs) -+ -+ if ((intr_p + excp_p + reset_p) > 1) -+ error ("multiple interrupt attributes to function %qD", func_decl); -++ -++ /* Do not allow isr attributes under linux toolchain. */ -++ if (TARGET_LINUX_ABI && intr_p) -++ error ("cannot use interrupt attributes to function %qD " -++ "under linux toolchain", func_decl); -++ if (TARGET_LINUX_ABI && excp_p) -++ error ("cannot use exception attributes to function %qD " -++ "under linux toolchain", func_decl); -++ if (TARGET_LINUX_ABI && reset_p) -++ error ("cannot use reset attributes to function %qD " -++ "under linux toolchain", func_decl); -+ } -+ -+ /* Function to construct isr vectors information array. -+@@ -373,15 +662,21 @@ nds32_construct_isr_vectors_information (tree func_attrs, -+ const char *func_name) -+ { -+ tree save_all, partial_save; -+- tree nested, not_nested, nested_ready; -++ tree nested, not_nested, nested_ready, critical; -+ tree intr, excp, reset; -+ -++ tree secure; -++ tree security_level_list; -++ tree security_level; -++ unsigned int s_level; -++ -+ save_all = lookup_attribute ("save_all", func_attrs); -+ partial_save = lookup_attribute ("partial_save", func_attrs); -+ -+ nested = lookup_attribute ("nested", func_attrs); -+ not_nested = lookup_attribute ("not_nested", func_attrs); -+ nested_ready = lookup_attribute ("nested_ready", func_attrs); -++ critical = lookup_attribute ("critical", func_attrs); -+ -+ intr = lookup_attribute ("interrupt", func_attrs); -+ excp = lookup_attribute ("exception", func_attrs); -+@@ -391,6 +686,63 @@ nds32_construct_isr_vectors_information (tree func_attrs, -+ if (!intr && !excp && !reset) -+ return; -+ -++ /* At first, we need to retrieve security level. */ -++ secure = lookup_attribute ("secure", func_attrs); -++ if (secure != NULL) -++ { -++ security_level_list = TREE_VALUE (secure); -++ security_level = TREE_VALUE (security_level_list); -++ s_level = TREE_INT_CST_LOW (security_level); -++ } -++ else -++ { -++ /* If there is no secure attribute, the security level is set by -++ nds32_isr_secure_level, which is controlled by -misr-secure=X option. -++ By default nds32_isr_secure_level should be 0. */ -++ s_level = nds32_isr_secure_level; -++ } -++ -++ /* ------------------------------------------------------------- */ -++ /* FIXME: -++ FOR BACKWARD COMPATIBILITY, we need to support following patterns: -++ -++ __attribute__((interrupt("XXX;YYY;id=ZZZ"))) -++ __attribute__((exception("XXX;YYY;id=ZZZ"))) -++ __attribute__((reset("vectors=XXX;nmi_func=YYY;warm_func=ZZZ"))) -++ -++ If interrupt/exception/reset appears and its argument is a -++ STRING_CST, we will parse string with some auxiliary functions -++ which set necessary isr information in the nds32_isr_vectors[] array. -++ After that, we can return immediately to avoid new-syntax isr -++ information construction. */ -++ if (intr != NULL_TREE -++ && TREE_CODE (TREE_VALUE (TREE_VALUE (intr))) == STRING_CST) -++ { -++ tree string_arg = TREE_VALUE (TREE_VALUE (intr)); -++ nds32_interrupt_attribute_parse_string (TREE_STRING_POINTER (string_arg), -++ func_name, -++ s_level); -++ return; -++ } -++ if (excp != NULL_TREE -++ && TREE_CODE (TREE_VALUE (TREE_VALUE (excp))) == STRING_CST) -++ { -++ tree string_arg = TREE_VALUE (TREE_VALUE (excp)); -++ nds32_exception_attribute_parse_string (TREE_STRING_POINTER (string_arg), -++ func_name, -++ s_level); -++ return; -++ } -++ if (reset != NULL_TREE -++ && TREE_CODE (TREE_VALUE (TREE_VALUE (reset))) == STRING_CST) -++ { -++ tree string_arg = TREE_VALUE (TREE_VALUE (reset)); -++ nds32_reset_attribute_parse_string (TREE_STRING_POINTER (string_arg), -++ func_name); -++ return; -++ } -++ /* ------------------------------------------------------------- */ -++ -+ /* If we are here, either we have interrupt/exception, -+ or reset attribute. */ -+ if (intr || excp) -+@@ -417,6 +769,9 @@ nds32_construct_isr_vectors_information (tree func_attrs, -+ /* Add vector_number_offset to get actual vector number. */ -+ vector_id = TREE_INT_CST_LOW (id) + vector_number_offset; -+ -++ /* Set security level. */ -++ nds32_isr_vectors[vector_id].security_level = s_level; -++ -+ /* Enable corresponding vector and set function name. */ -+ nds32_isr_vectors[vector_id].category = (intr) -+ ? (NDS32_ISR_INTERRUPT) -+@@ -436,6 +791,8 @@ nds32_construct_isr_vectors_information (tree func_attrs, -+ nds32_isr_vectors[vector_id].nested_type = NDS32_NOT_NESTED; -+ else if (nested_ready) -+ nds32_isr_vectors[vector_id].nested_type = NDS32_NESTED_READY; -++ else if (critical) -++ nds32_isr_vectors[vector_id].nested_type = NDS32_CRITICAL; -+ -+ /* Advance to next id. */ -+ id_list = TREE_CHAIN (id_list); -+@@ -492,7 +849,6 @@ nds32_construct_isr_vectors_information (tree func_attrs, -+ } -+ } -+ -+-/* A helper function to handle isr stuff at the beginning of asm file. */ -+ void -+ nds32_asm_file_start_for_isr (void) -+ { -+@@ -505,15 +861,14 @@ nds32_asm_file_start_for_isr (void) -+ strcpy (nds32_isr_vectors[i].func_name, ""); -+ nds32_isr_vectors[i].save_reg = NDS32_PARTIAL_SAVE; -+ nds32_isr_vectors[i].nested_type = NDS32_NOT_NESTED; -++ nds32_isr_vectors[i].security_level = 0; -+ nds32_isr_vectors[i].total_n_vectors = 0; -+ strcpy (nds32_isr_vectors[i].nmi_name, ""); -+ strcpy (nds32_isr_vectors[i].warm_name, ""); -+ } -+ } -+ -+-/* A helper function to handle isr stuff at the end of asm file. */ -+-void -+-nds32_asm_file_end_for_isr (void) -++void nds32_asm_file_end_for_isr (void) -+ { -+ int i; -+ -+@@ -547,6 +902,8 @@ nds32_asm_file_end_for_isr (void) -+ /* Found one vector which is interupt or exception. -+ Output its jmptbl and vector section content. */ -+ fprintf (asm_out_file, "\t! interrupt/exception vector %02d\n", i); -++ fprintf (asm_out_file, "\t! security level: %d\n", -++ nds32_isr_vectors[i].security_level); -+ fprintf (asm_out_file, "\t! ------------------------------------\n"); -+ nds32_emit_isr_jmptbl_section (i); -+ fprintf (asm_out_file, "\t! ....................................\n"); -+@@ -580,4 +937,65 @@ nds32_isr_function_p (tree func) -+ || (t_reset != NULL_TREE)); -+ } -+ -+-/* ------------------------------------------------------------------------ */ -++/* Return true if FUNC is a isr function with critical attribute. */ -++bool -++nds32_isr_function_critical_p (tree func) -++{ -++ tree t_intr; -++ tree t_excp; -++ tree t_critical; -++ -++ tree attrs; -++ -++ if (TREE_CODE (func) != FUNCTION_DECL) -++ abort (); -++ -++ attrs = DECL_ATTRIBUTES (func); -++ -++ t_intr = lookup_attribute ("interrupt", attrs); -++ t_excp = lookup_attribute ("exception", attrs); -++ -++ t_critical = lookup_attribute ("critical", attrs); -++ -++ /* If both interrupt and exception attribute does not appear, -++ we can return false immediately. */ -++ if ((t_intr == NULL_TREE) && (t_excp == NULL_TREE)) -++ return false; -++ -++ /* Here we can guarantee either interrupt or ecxception attribute -++ does exist, so further check critical attribute. -++ If it also appears, we can return true. */ -++ if (t_critical != NULL_TREE) -++ return true; -++ -++ /* ------------------------------------------------------------- */ -++ /* FIXME: -++ FOR BACKWARD COMPATIBILITY, we need to handle string type. -++ If the string 'critical' appears in the interrupt/exception -++ string argument, we can return true. */ -++ if (t_intr != NULL_TREE || t_excp != NULL_TREE) -++ { -++ char target_str[100]; -++ char *critical_str; -++ tree t_check; -++ tree string_arg; -++ -++ t_check = t_intr ? t_intr : t_excp; -++ if (TREE_CODE (TREE_VALUE (TREE_VALUE (t_check))) == STRING_CST) -++ { -++ string_arg = TREE_VALUE (TREE_VALUE (t_check)); -++ strcpy (target_str, TREE_STRING_POINTER (string_arg)); -++ critical_str = strstr (target_str, "critical"); -++ -++ /* Found 'critical' string, so return true. */ -++ if (critical_str) -++ return true; -++ } -++ } -++ /* ------------------------------------------------------------- */ -++ -++ /* Other cases, this isr function is not critical type. */ -++ return false; -++} -++ -++/* ------------------------------------------------------------- */ -+diff --git a/gcc/config/nds32/nds32-linux.opt b/gcc/config/nds32/nds32-linux.opt -+new file mode 100644 -+index 00000000000..75ccd7625a2 -+--- /dev/null -++++ b/gcc/config/nds32/nds32-linux.opt -+@@ -0,0 +1,16 @@ -++mcmodel= -++Target RejectNegative Joined Enum(nds32_cmodel_type) Var(nds32_cmodel_option) Init(CMODEL_LARGE) -++Specify the address generation strategy for code model. -++ -++Enum -++Name(nds32_cmodel_type) Type(enum nds32_cmodel_type) -++Known cmodel types (for use with the -mcmodel= option): -++ -++EnumValue -++Enum(nds32_cmodel_type) String(small) Value(CMODEL_SMALL) -++ -++EnumValue -++Enum(nds32_cmodel_type) String(medium) Value(CMODEL_MEDIUM) -++ -++EnumValue -++Enum(nds32_cmodel_type) String(large) Value(CMODEL_LARGE) -+diff --git a/gcc/config/nds32/nds32-md-auxiliary.c b/gcc/config/nds32/nds32-md-auxiliary.c -+index 720e85a20eb..f157dce3366 100644 -+--- a/gcc/config/nds32/nds32-md-auxiliary.c -++++ b/gcc/config/nds32/nds32-md-auxiliary.c -+@@ -39,6 +39,9 @@ -+ #include "expr.h" -+ #include "emit-rtl.h" -+ #include "explow.h" -++#include "stringpool.h" -++#include "attribs.h" -++ -+ -+ /* ------------------------------------------------------------------------ */ -+ -+@@ -261,6 +264,118 @@ output_cond_branch_compare_zero (int code, const char *suffix, -+ output_asm_insn (pattern, operands); -+ } -+ -++static void -++nds32_split_shiftrtdi3 (rtx dst, rtx src, rtx shiftamount, bool logic_shift_p) -++{ -++ rtx src_high_part; -++ rtx dst_high_part, dst_low_part; -++ -++ dst_high_part = nds32_di_high_part_subreg (dst); -++ src_high_part = nds32_di_high_part_subreg (src); -++ dst_low_part = nds32_di_low_part_subreg (dst); -++ -++ if (CONST_INT_P (shiftamount)) -++ { -++ if (INTVAL (shiftamount) < 32) -++ { -++ if (logic_shift_p) -++ { -++ emit_insn (gen_uwext (dst_low_part, src, -++ shiftamount)); -++ emit_insn (gen_lshrsi3 (dst_high_part, src_high_part, -++ shiftamount)); -++ } -++ else -++ { -++ emit_insn (gen_wext (dst_low_part, src, -++ shiftamount)); -++ emit_insn (gen_ashrsi3 (dst_high_part, src_high_part, -++ shiftamount)); -++ } -++ } -++ else -++ { -++ rtx new_shift_amout = gen_int_mode(INTVAL (shiftamount) - 32, SImode); -++ -++ if (logic_shift_p) -++ { -++ emit_insn (gen_lshrsi3 (dst_low_part, src_high_part, -++ new_shift_amout)); -++ emit_move_insn (dst_high_part, const0_rtx); -++ } -++ else -++ { -++ emit_insn (gen_ashrsi3 (dst_low_part, src_high_part, -++ new_shift_amout)); -++ emit_insn (gen_ashrsi3 (dst_high_part, src_high_part, -++ GEN_INT (31))); -++ } -++ } -++ } -++ else -++ { -++ rtx dst_low_part_l32, dst_high_part_l32; -++ rtx dst_low_part_g32, dst_high_part_g32; -++ rtx new_shift_amout, select_reg; -++ dst_low_part_l32 = gen_reg_rtx (SImode); -++ dst_high_part_l32 = gen_reg_rtx (SImode); -++ dst_low_part_g32 = gen_reg_rtx (SImode); -++ dst_high_part_g32 = gen_reg_rtx (SImode); -++ new_shift_amout = gen_reg_rtx (SImode); -++ select_reg = gen_reg_rtx (SImode); -++ -++ emit_insn (gen_andsi3 (shiftamount, shiftamount, GEN_INT (0x3f))); -++ -++ if (logic_shift_p) -++ { -++ /* -++ if (shiftamount < 32) -++ dst_low_part = wext (src, shiftamount) -++ dst_high_part = src_high_part >> shiftamount -++ else -++ dst_low_part = src_high_part >> (shiftamount & 0x1f) -++ dst_high_part = 0 -++ */ -++ emit_insn (gen_uwext (dst_low_part_l32, src, shiftamount)); -++ emit_insn (gen_lshrsi3 (dst_high_part_l32, src_high_part, -++ shiftamount)); -++ -++ emit_insn (gen_andsi3 (new_shift_amout, shiftamount, GEN_INT (0x1f))); -++ emit_insn (gen_lshrsi3 (dst_low_part_g32, src_high_part, -++ new_shift_amout)); -++ emit_move_insn (dst_high_part_g32, const0_rtx); -++ } -++ else -++ { -++ /* -++ if (shiftamount < 32) -++ dst_low_part = wext (src, shiftamount) -++ dst_high_part = src_high_part >> shiftamount -++ else -++ dst_low_part = src_high_part >> (shiftamount & 0x1f) -++ # shift 31 for sign extend -++ dst_high_part = src_high_part >> 31 -++ */ -++ emit_insn (gen_wext (dst_low_part_l32, src, shiftamount)); -++ emit_insn (gen_ashrsi3 (dst_high_part_l32, src_high_part, -++ shiftamount)); -++ -++ emit_insn (gen_andsi3 (new_shift_amout, shiftamount, GEN_INT (0x1f))); -++ emit_insn (gen_ashrsi3 (dst_low_part_g32, src_high_part, -++ new_shift_amout)); -++ emit_insn (gen_ashrsi3 (dst_high_part_g32, src_high_part, -++ GEN_INT (31))); -++ } -++ -++ emit_insn (gen_slt_compare (select_reg, shiftamount, GEN_INT (32))); -++ -++ emit_insn (gen_cmovnsi (dst_low_part, select_reg, -++ dst_low_part_l32, dst_low_part_g32)); -++ emit_insn (gen_cmovnsi (dst_high_part, select_reg, -++ dst_high_part_l32, dst_high_part_g32)); -++ } -++} -++ -+ /* ------------------------------------------------------------------------ */ -+ -+ /* Auxiliary function for expand RTL pattern. */ -+@@ -1195,8 +1310,166 @@ nds32_emit_v3pop_fpr_callee_saved (int base) -+ } -+ } -+ -++enum nds32_expand_result_type -++nds32_expand_extv (rtx *operands) -++{ -++ gcc_assert (CONST_INT_P (operands[2]) && CONST_INT_P (operands[3])); -++ HOST_WIDE_INT width = INTVAL (operands[2]); -++ HOST_WIDE_INT bitpos = INTVAL (operands[3]); -++ rtx dst = operands[0]; -++ rtx src = operands[1]; -++ -++ if (MEM_P (src) -++ && width == 32 -++ && (bitpos % BITS_PER_UNIT) == 0 -++ && GET_MODE_BITSIZE (GET_MODE (dst)) == width) -++ { -++ rtx newmem = adjust_address (src, GET_MODE (dst), -++ bitpos / BITS_PER_UNIT); -++ -++ rtx base_addr = force_reg (Pmode, XEXP (newmem, 0)); -++ -++ emit_insn (gen_unaligned_loadsi (dst, base_addr)); -++ -++ return EXPAND_DONE; -++ } -++ return EXPAND_FAIL; -++} -++ -++enum nds32_expand_result_type -++nds32_expand_insv (rtx *operands) -++{ -++ gcc_assert (CONST_INT_P (operands[1]) && CONST_INT_P (operands[2])); -++ HOST_WIDE_INT width = INTVAL (operands[1]); -++ HOST_WIDE_INT bitpos = INTVAL (operands[2]); -++ rtx dst = operands[0]; -++ rtx src = operands[3]; -++ -++ if (MEM_P (dst) -++ && width == 32 -++ && (bitpos % BITS_PER_UNIT) == 0 -++ && GET_MODE_BITSIZE (GET_MODE (src)) == width) -++ { -++ rtx newmem = adjust_address (dst, GET_MODE (src), -++ bitpos / BITS_PER_UNIT); -++ -++ rtx base_addr = force_reg (Pmode, XEXP (newmem, 0)); -++ -++ emit_insn (gen_unaligned_storesi (base_addr, src)); -++ -++ return EXPAND_DONE; -++ } -++ return EXPAND_FAIL; -++} -++ -+ /* ------------------------------------------------------------------------ */ -+ -++/* Function to generate PC relative jump table. -++ Refer to nds32.md for more details. -++ -++ The following is the sample for the case that diff value -++ can be presented in '.short' size. -++ -++ addi $r1, $r1, -(case_lower_bound) -++ slti $ta, $r1, (case_number) -++ beqz $ta, .L_skip_label -++ -++ la $ta, .L35 ! get jump table address -++ lh $r1, [$ta + $r1 << 1] ! load symbol diff from jump table entry -++ addi $ta, $r1, $ta -++ jr5 $ta -++ -++ ! jump table entry -++ L35: -++ .short .L25-.L35 -++ .short .L26-.L35 -++ .short .L27-.L35 -++ .short .L28-.L35 -++ .short .L29-.L35 -++ .short .L30-.L35 -++ .short .L31-.L35 -++ .short .L32-.L35 -++ .short .L33-.L35 -++ .short .L34-.L35 */ -++const char * -++nds32_output_casesi_pc_relative (rtx *operands) -++{ -++ machine_mode mode; -++ rtx diff_vec; -++ -++ diff_vec = PATTERN (NEXT_INSN (as_a (operands[1]))); -++ -++ gcc_assert (GET_CODE (diff_vec) == ADDR_DIFF_VEC); -++ -++ /* Step C: "t <-- operands[1]". */ -++ if (flag_pic) -++ { -++ output_asm_insn ("sethi\t$ta, hi20(%l1@GOTOFF)", operands); -++ output_asm_insn ("ori\t$ta, $ta, lo12(%l1@GOTOFF)", operands); -++ output_asm_insn ("add\t$ta, $ta, $gp", operands); -++ } -++ else -++ output_asm_insn ("la\t$ta, %l1", operands); -++ -++ /* Get the mode of each element in the difference vector. */ -++ mode = GET_MODE (diff_vec); -++ -++ /* Step D: "z <-- (mem (plus (operands[0] << m) t))", -++ where m is 0, 1, or 2 to load address-diff value from table. */ -++ switch (mode) -++ { -++ case E_QImode: -++ output_asm_insn ("lb\t%2, [$ta + %0 << 0]", operands); -++ break; -++ case E_HImode: -++ output_asm_insn ("lh\t%2, [$ta + %0 << 1]", operands); -++ break; -++ case E_SImode: -++ output_asm_insn ("lw\t%2, [$ta + %0 << 2]", operands); -++ break; -++ default: -++ gcc_unreachable (); -++ } -++ -++ /* Step E: "t <-- z + t". -++ Add table label_ref with address-diff value to -++ obtain target case address. */ -++ output_asm_insn ("add\t$ta, %2, $ta", operands); -++ -++ /* Step F: jump to target with register t. */ -++ if (TARGET_16_BIT) -++ return "jr5\t$ta"; -++ else -++ return "jr\t$ta"; -++} -++ -++/* Function to generate normal jump table. */ -++const char * -++nds32_output_casesi (rtx *operands) -++{ -++ /* Step C: "t <-- operands[1]". */ -++ if (flag_pic) -++ { -++ output_asm_insn ("sethi\t$ta, hi20(%l1@GOTOFF)", operands); -++ output_asm_insn ("ori\t$ta, $ta, lo12(%l1@GOTOFF)", operands); -++ output_asm_insn ("add\t$ta, $ta, $gp", operands); -++ } -++ else -++ output_asm_insn ("la\t$ta, %l1", operands); -++ -++ /* Step D: "z <-- (mem (plus (operands[0] << 2) t))". */ -++ output_asm_insn ("lw\t%2, [$ta + %0 << 2]", operands); -++ -++ /* No need to perform Step E, which is only used for -++ pc relative jump table. */ -++ -++ /* Step F: jump to target with register z. */ -++ if (TARGET_16_BIT) -++ return "jr5\t%2"; -++ else -++ return "jr\t%2"; -++} -++ -+ /* Function to return memory format. */ -+ enum nds32_16bit_address_type -+ nds32_mem_format (rtx op) -+@@ -1757,11 +2030,8 @@ nds32_output_stack_push (rtx par_rtx) -+ -+ /* If we step here, we are going to do v3push or multiple push operation. */ -+ -+- /* The v3push/v3pop instruction should only be applied on -+- none-isr and none-variadic function. */ -+- if (TARGET_V3PUSH -+- && !nds32_isr_function_p (current_function_decl) -+- && (cfun->machine->va_args_size == 0)) -++ /* Refer to nds32.h, where we comment when push25/pop25 are available. */ -++ if (NDS32_V3PUSH_AVAILABLE_P) -+ { -+ /* For stack v3push: -+ operands[0]: Re -+@@ -1881,11 +2151,8 @@ nds32_output_stack_pop (rtx par_rtx ATTRIBUTE_UNUSED) -+ -+ /* If we step here, we are going to do v3pop or multiple pop operation. */ -+ -+- /* The v3push/v3pop instruction should only be applied on -+- none-isr and none-variadic function. */ -+- if (TARGET_V3PUSH -+- && !nds32_isr_function_p (current_function_decl) -+- && (cfun->machine->va_args_size == 0)) -++ /* Refer to nds32.h, where we comment when push25/pop25 are available. */ -++ if (NDS32_V3PUSH_AVAILABLE_P) -+ { -+ /* For stack v3pop: -+ operands[0]: Re -+@@ -2022,77 +2289,6 @@ nds32_output_return (void) -+ return ""; -+ } -+ -+-/* Function to generate PC relative jump table. -+- Refer to nds32.md for more details. -+- -+- The following is the sample for the case that diff value -+- can be presented in '.short' size. -+- -+- addi $r1, $r1, -(case_lower_bound) -+- slti $ta, $r1, (case_number) -+- beqz $ta, .L_skip_label -+- -+- la $ta, .L35 ! get jump table address -+- lh $r1, [$ta + $r1 << 1] ! load symbol diff from jump table entry -+- addi $ta, $r1, $ta -+- jr5 $ta -+- -+- ! jump table entry -+- L35: -+- .short .L25-.L35 -+- .short .L26-.L35 -+- .short .L27-.L35 -+- .short .L28-.L35 -+- .short .L29-.L35 -+- .short .L30-.L35 -+- .short .L31-.L35 -+- .short .L32-.L35 -+- .short .L33-.L35 -+- .short .L34-.L35 */ -+-const char * -+-nds32_output_casesi_pc_relative (rtx *operands) -+-{ -+- machine_mode mode; -+- rtx diff_vec; -+- -+- diff_vec = PATTERN (NEXT_INSN (as_a (operands[1]))); -+- -+- gcc_assert (GET_CODE (diff_vec) == ADDR_DIFF_VEC); -+- -+- /* Step C: "t <-- operands[1]". */ -+- output_asm_insn ("la\t$ta, %l1", operands); -+- -+- /* Get the mode of each element in the difference vector. */ -+- mode = GET_MODE (diff_vec); -+- -+- /* Step D: "z <-- (mem (plus (operands[0] << m) t))", -+- where m is 0, 1, or 2 to load address-diff value from table. */ -+- switch (mode) -+- { -+- case E_QImode: -+- output_asm_insn ("lb\t%2, [$ta + %0 << 0]", operands); -+- break; -+- case E_HImode: -+- output_asm_insn ("lh\t%2, [$ta + %0 << 1]", operands); -+- break; -+- case E_SImode: -+- output_asm_insn ("lw\t%2, [$ta + %0 << 2]", operands); -+- break; -+- default: -+- gcc_unreachable (); -+- } -+- -+- /* Step E: "t <-- z + t". -+- Add table label_ref with address-diff value to -+- obtain target case address. */ -+- output_asm_insn ("add\t$ta, %2, $ta", operands); -+- -+- /* Step F: jump to target with register t. */ -+- if (TARGET_16_BIT) -+- return "jr5\t$ta"; -+- else -+- return "jr\t$ta"; -+-} -+ -+ /* output a float load instruction */ -+ const char * -+@@ -2250,52 +2446,51 @@ nds32_output_float_store (rtx *operands) -+ return ""; -+ } -+ -+-/* Function to generate normal jump table. */ -+ const char * -+-nds32_output_casesi (rtx *operands) -++nds32_output_smw_single_word (rtx *operands) -+ { -+- /* Step C: "t <-- operands[1]". */ -+- output_asm_insn ("la\t$ta, %l1", operands); -+- -+- /* Step D: "z <-- (mem (plus (operands[0] << 2) t))". */ -+- output_asm_insn ("lw\t%2, [$ta + %0 << 2]", operands); -+- -+- /* No need to perform Step E, which is only used for -+- pc relative jump table. */ -++ char buff[100]; -++ unsigned regno; -++ int enable4; -++ bool update_base_p; -++ rtx base_addr = operands[0]; -++ rtx base_reg; -++ rtx otherops[2]; -+ -+- /* Step F: jump to target with register z. */ -+- if (TARGET_16_BIT) -+- return "jr5\t%2"; -++ if (REG_P (XEXP (base_addr, 0))) -++ { -++ update_base_p = false; -++ base_reg = XEXP (base_addr, 0); -++ } -+ else -+- return "jr\t%2"; -+-} -++ { -++ update_base_p = true; -++ base_reg = XEXP (XEXP (base_addr, 0), 0); -++ } -+ -+-/* Auxiliary functions for lwm/smw. */ -+-bool -+-nds32_valid_smw_lwm_base_p (rtx op) -+-{ -+- rtx base_addr; -++ const char *update_base = update_base_p ? "m" : ""; -+ -+- if (!MEM_P (op)) -+- return false; -++ regno = REGNO (operands[1]); -+ -+- base_addr = XEXP (op, 0); -++ otherops[0] = base_reg; -++ otherops[1] = operands[1]; -+ -+- if (REG_P (base_addr)) -+- return true; -++ if (regno >= 28) -++ { -++ enable4 = nds32_regno_to_enable4 (regno); -++ sprintf (buff, "smw.bi%s\t$sp, [%%0], $sp, %x", update_base, enable4); -++ } -+ else -+ { -+- if (GET_CODE (base_addr) == POST_INC -+- && REG_P (XEXP (base_addr, 0))) -+- return true; -++ sprintf (buff, "smw.bi%s\t%%1, [%%0], %%1", update_base); -+ } -+- -+- return false; -++ output_asm_insn (buff, otherops); -++ return ""; -+ } -+ -+ /* ------------------------------------------------------------------------ */ -+ const char * -+-nds32_output_smw_single_word (rtx *operands) -++nds32_output_smw_double_word (rtx *operands) -+ { -+ char buff[100]; -+ unsigned regno; -+@@ -2303,7 +2498,7 @@ nds32_output_smw_single_word (rtx *operands) -+ bool update_base_p; -+ rtx base_addr = operands[0]; -+ rtx base_reg; -+- rtx otherops[2]; -++ rtx otherops[3]; -+ -+ if (REG_P (XEXP (base_addr, 0))) -+ { -+@@ -2322,15 +2517,22 @@ nds32_output_smw_single_word (rtx *operands) -+ -+ otherops[0] = base_reg; -+ otherops[1] = operands[1]; -++ otherops[2] = gen_rtx_REG (SImode, REGNO (operands[1]) + 1);; -+ -+ if (regno >= 28) -+ { -+- enable4 = nds32_regno_to_enable4 (regno); -++ enable4 = nds32_regno_to_enable4 (regno) -++ | nds32_regno_to_enable4 (regno + 1); -+ sprintf (buff, "smw.bi%s\t$sp, [%%0], $sp, %x", update_base, enable4); -+ } -++ else if (regno == 27) -++ { -++ enable4 = nds32_regno_to_enable4 (regno + 1); -++ sprintf (buff, "smw.bi%s\t%%1, [%%0], %%1, %x", update_base, enable4); -++ } -+ else -+ { -+- sprintf (buff, "smw.bi%s\t%%1, [%%0], %%1", update_base); -++ sprintf (buff, "smw.bi%s\t%%1, [%%0], %%2", update_base); -+ } -+ output_asm_insn (buff, otherops); -+ return ""; -+@@ -2415,16 +2617,17 @@ nds32_expand_unaligned_load (rtx *operands, enum machine_mode mode) -+ if (mode == DImode) -+ { -+ /* Load doubleword, we need two registers to access. */ -+- reg[0] = simplify_gen_subreg (SImode, operands[0], -+- GET_MODE (operands[0]), 0); -+- reg[1] = simplify_gen_subreg (SImode, operands[0], -+- GET_MODE (operands[0]), 4); -++ reg[0] = nds32_di_low_part_subreg (operands[0]); -++ reg[1] = nds32_di_high_part_subreg (operands[0]); -+ /* A register only store 4 byte. */ -+ width = GET_MODE_SIZE (SImode) - 1; -+ } -+ else -+ { -+- reg[0] = operands[0]; -++ if (VECTOR_MODE_P (mode)) -++ reg[0] = gen_reg_rtx (SImode); -++ else -++ reg[0] = operands[0]; -+ } -+ -+ for (num_reg = (mode == DImode) ? 2 : 1; num_reg > 0; num_reg--) -+@@ -2466,6 +2669,8 @@ nds32_expand_unaligned_load (rtx *operands, enum machine_mode mode) -+ offset = offset + offset_adj; -+ } -+ } -++ if (VECTOR_MODE_P (mode)) -++ convert_move (operands[0], reg[0], false); -+ } -+ -+ void -+@@ -2499,16 +2704,20 @@ nds32_expand_unaligned_store (rtx *operands, enum machine_mode mode) -+ if (mode == DImode) -+ { -+ /* Load doubleword, we need two registers to access. */ -+- reg[0] = simplify_gen_subreg (SImode, operands[1], -+- GET_MODE (operands[1]), 0); -+- reg[1] = simplify_gen_subreg (SImode, operands[1], -+- GET_MODE (operands[1]), 4); -++ reg[0] = nds32_di_low_part_subreg (operands[1]); -++ reg[1] = nds32_di_high_part_subreg (operands[1]); -+ /* A register only store 4 byte. */ -+ width = GET_MODE_SIZE (SImode) - 1; -+ } -+ else -+ { -+- reg[0] = operands[1]; -++ if (VECTOR_MODE_P (mode)) -++ { -++ reg[0] = gen_reg_rtx (SImode); -++ convert_move (reg[0], operands[1], false); -++ } -++ else -++ reg[0] = operands[1]; -+ } -+ -+ for (num_reg = (mode == DImode) ? 2 : 1; num_reg > 0; num_reg--) -+@@ -2765,6 +2974,36 @@ nds32_output_cbranchsi4_greater_less_zero (rtx_insn *insn, rtx *operands) -+ return ""; -+ } -+ -++const char * -++nds32_output_unpkd8 (rtx output, rtx input, -++ rtx high_idx_rtx, rtx low_idx_rtx, -++ bool signed_p) -++{ -++ char pattern[100]; -++ rtx output_operands[2]; -++ HOST_WIDE_INT high_idx, low_idx; -++ high_idx = INTVAL (high_idx_rtx); -++ low_idx = INTVAL (low_idx_rtx); -++ -++ gcc_assert (high_idx >= 0 && high_idx <= 3); -++ gcc_assert (low_idx >= 0 && low_idx <= 3); -++ -++ /* We only have 10, 20, 30 and 31. */ -++ if ((low_idx != 0 || high_idx == 0) && -++ !(low_idx == 1 && high_idx == 3)) -++ return "#"; -++ -++ char sign_char = signed_p ? 's' : 'z'; -++ -++ sprintf (pattern, -++ "%cunpkd8" HOST_WIDE_INT_PRINT_DEC HOST_WIDE_INT_PRINT_DEC "\t%%0, %%1", -++ sign_char, high_idx, low_idx); -++ output_operands[0] = output; -++ output_operands[1] = input; -++ output_asm_insn (pattern, output_operands); -++ return ""; -++} -++ -+ /* Return true if SYMBOL_REF X binds locally. */ -+ -+ static bool -+@@ -2782,22 +3021,15 @@ nds32_output_call (rtx insn, rtx *operands, rtx symbol, const char *long_call, -+ char pattern[100]; -+ bool noreturn_p; -+ -+- if (GET_CODE (symbol) == CONST) -+- { -+- symbol= XEXP (symbol, 0); -+- -+- if (GET_CODE (symbol) == PLUS) -+- symbol = XEXP (symbol, 0); -+- } -+- -+- gcc_assert (GET_CODE (symbol) == SYMBOL_REF -+- || REG_P (symbol)); -+- -+ if (nds32_long_call_p (symbol)) -+ strcpy (pattern, long_call); -+ else -+ strcpy (pattern, call); -+ -++ if (flag_pic && CONSTANT_P (symbol) -++ && !nds32_symbol_binds_local_p (symbol)) -++ strcat (pattern, "@PLT"); -++ -+ if (align_p) -+ strcat (pattern, "\n\t.align 2"); -+ -+@@ -2815,6 +3047,91 @@ nds32_output_call (rtx insn, rtx *operands, rtx symbol, const char *long_call, -+ return ""; -+ } -+ -++bool -++nds32_need_split_sms_p (rtx in0_idx0, rtx in1_idx0, -++ rtx in0_idx1, rtx in1_idx1) -++{ -++ /* smds or smdrs. */ -++ if (INTVAL (in0_idx0) == INTVAL (in1_idx0) -++ && INTVAL (in0_idx1) == INTVAL (in1_idx1) -++ && INTVAL (in0_idx0) != INTVAL (in0_idx1)) -++ return false; -++ -++ /* smxds. */ -++ if (INTVAL (in0_idx0) != INTVAL (in0_idx1) -++ && INTVAL (in1_idx0) != INTVAL (in1_idx1)) -++ return false; -++ -++ return true; -++} -++ -++const char * -++nds32_output_sms (rtx in0_idx0, rtx in1_idx0, -++ rtx in0_idx1, rtx in1_idx1) -++{ -++ if (nds32_need_split_sms_p (in0_idx0, in1_idx0, -++ in0_idx1, in1_idx1)) -++ return "#"; -++ /* out = in0[in0_idx0] * in1[in1_idx0] - in0[in0_idx1] * in1[in1_idx1] */ -++ -++ /* smds or smdrs. */ -++ if (INTVAL (in0_idx0) == INTVAL (in1_idx0) -++ && INTVAL (in0_idx1) == INTVAL (in1_idx1) -++ && INTVAL (in0_idx0) != INTVAL (in0_idx1)) -++ { -++ if (INTVAL (in0_idx0) == 0) -++ { -++ if (TARGET_BIG_ENDIAN) -++ return "smds\t%0, %1, %2"; -++ else -++ return "smdrs\t%0, %1, %2"; -++ } -++ else -++ { -++ if (TARGET_BIG_ENDIAN) -++ return "smdrs\t%0, %1, %2"; -++ else -++ return "smds\t%0, %1, %2"; -++ } -++ } -++ -++ if (INTVAL (in0_idx0) != INTVAL (in0_idx1) -++ && INTVAL (in1_idx0) != INTVAL (in1_idx1)) -++ { -++ if (INTVAL (in0_idx0) == 1) -++ { -++ if (TARGET_BIG_ENDIAN) -++ return "smxds\t%0, %2, %1"; -++ else -++ return "smxds\t%0, %1, %2"; -++ } -++ else -++ { -++ if (TARGET_BIG_ENDIAN) -++ return "smxds\t%0, %1, %2"; -++ else -++ return "smxds\t%0, %2, %1"; -++ } -++ } -++ -++ gcc_unreachable (); -++ return ""; -++} -++ -++void -++nds32_split_sms (rtx out, rtx in0, rtx in1, -++ rtx in0_idx0, rtx in1_idx0, -++ rtx in0_idx1, rtx in1_idx1) -++{ -++ rtx result0 = gen_reg_rtx (SImode); -++ rtx result1 = gen_reg_rtx (SImode); -++ emit_insn (gen_mulhisi3v (result0, in0, in1, -++ in0_idx0, in1_idx0)); -++ emit_insn (gen_mulhisi3v (result1, in0, in1, -++ in0_idx1, in1_idx1)); -++ emit_insn (gen_subsi3 (out, result0, result1)); -++} -++ -+ /* Spilt a doubleword instrucion to two single word instructions. */ -+ void -+ nds32_spilt_doubleword (rtx *operands, bool load_p) -+@@ -2846,16 +3163,30 @@ nds32_spilt_doubleword (rtx *operands, bool load_p) -+ /* generate low_part and high_part memory format: -+ low_part: (post_modify ((reg) (plus (reg) (const 4))) -+ high_part: (post_modify ((reg) (plus (reg) (const -12))) */ -+- low_part[mem] = gen_frame_mem (SImode, -+- gen_rtx_POST_MODIFY (Pmode, sub_mem, -+- gen_rtx_PLUS (Pmode, -+- sub_mem, -+- GEN_INT (4)))); -+- high_part[mem] = gen_frame_mem (SImode, -+- gen_rtx_POST_MODIFY (Pmode, sub_mem, -+- gen_rtx_PLUS (Pmode, -+- sub_mem, -+- GEN_INT (-12)))); -++ low_part[mem] = gen_rtx_MEM (SImode, -++ gen_rtx_POST_MODIFY (Pmode, sub_mem, -++ gen_rtx_PLUS (Pmode, -++ sub_mem, -++ GEN_INT (4)))); -++ high_part[mem] = gen_rtx_MEM (SImode, -++ gen_rtx_POST_MODIFY (Pmode, sub_mem, -++ gen_rtx_PLUS (Pmode, -++ sub_mem, -++ GEN_INT (-12)))); -++ } -++ else if (GET_CODE (sub_mem) == POST_INC) -++ { -++ /* memory format is (post_inc (reg)), -++ so that extract (reg) from the (post_inc (reg)) pattern. */ -++ sub_mem = XEXP (sub_mem, 0); -++ -++ /* generate low_part and high_part memory format: -++ low_part: (post_inc (reg)) -++ high_part: (post_inc (reg)) */ -++ low_part[mem] = gen_rtx_MEM (SImode, -++ gen_rtx_POST_INC (Pmode, sub_mem)); -++ high_part[mem] = gen_rtx_MEM (SImode, -++ gen_rtx_POST_INC (Pmode, sub_mem)); -+ } -+ else if (GET_CODE (sub_mem) == POST_MODIFY) -+ { -+@@ -2872,14 +3203,14 @@ nds32_spilt_doubleword (rtx *operands, bool load_p) -+ /* Generate low_part and high_part memory format: -+ low_part: (post_modify ((reg) (plus (reg) (const))) -+ high_part: ((plus (reg) (const 4))) */ -+- low_part[mem] = gen_frame_mem (SImode, -+- gen_rtx_POST_MODIFY (Pmode, post_mem, -+- gen_rtx_PLUS (Pmode, -+- post_mem, -+- post_val))); -+- high_part[mem] = gen_frame_mem (SImode, plus_constant (Pmode, -+- post_mem, -+- 4)); -++ low_part[mem] = gen_rtx_MEM (SImode, -++ gen_rtx_POST_MODIFY (Pmode, post_mem, -++ gen_rtx_PLUS (Pmode, -++ post_mem, -++ post_val))); -++ high_part[mem] = gen_rtx_MEM (SImode, plus_constant (Pmode, -++ post_mem, -++ 4)); -+ } -+ else -+ { -+@@ -2924,11 +3255,516 @@ nds32_spilt_doubleword (rtx *operands, bool load_p) -+ } -+ } -+ -++void -++nds32_split_ashiftdi3 (rtx dst, rtx src, rtx shiftamount) -++{ -++ rtx src_high_part, src_low_part; -++ rtx dst_high_part, dst_low_part; -++ -++ dst_high_part = nds32_di_high_part_subreg (dst); -++ dst_low_part = nds32_di_low_part_subreg (dst); -++ -++ src_high_part = nds32_di_high_part_subreg (src); -++ src_low_part = nds32_di_low_part_subreg (src); -++ -++ /* We need to handle shift more than 32 bit!!!! */ -++ if (CONST_INT_P (shiftamount)) -++ { -++ if (INTVAL (shiftamount) < 32) -++ { -++ rtx ext_start; -++ ext_start = gen_int_mode(32 - INTVAL (shiftamount), SImode); -++ -++ emit_insn (gen_wext (dst_high_part, src, ext_start)); -++ emit_insn (gen_ashlsi3 (dst_low_part, src_low_part, shiftamount)); -++ } -++ else -++ { -++ rtx new_shift_amout = gen_int_mode(INTVAL (shiftamount) - 32, SImode); -++ -++ emit_insn (gen_ashlsi3 (dst_high_part, src_low_part, -++ new_shift_amout)); -++ -++ emit_move_insn (dst_low_part, GEN_INT (0)); -++ } -++ } -++ else -++ { -++ rtx dst_low_part_l32, dst_high_part_l32; -++ rtx dst_low_part_g32, dst_high_part_g32; -++ rtx new_shift_amout, select_reg; -++ dst_low_part_l32 = gen_reg_rtx (SImode); -++ dst_high_part_l32 = gen_reg_rtx (SImode); -++ dst_low_part_g32 = gen_reg_rtx (SImode); -++ dst_high_part_g32 = gen_reg_rtx (SImode); -++ new_shift_amout = gen_reg_rtx (SImode); -++ select_reg = gen_reg_rtx (SImode); -++ -++ rtx ext_start; -++ ext_start = gen_reg_rtx (SImode); -++ -++ /* -++ if (shiftamount < 32) -++ dst_low_part = src_low_part << shiftamout -++ dst_high_part = wext (src, 32 - shiftamount) -++ # wext can't handle wext (src, 32) since it's only take rb[0:4] -++ # for extract. -++ dst_high_part = shiftamount == 0 ? src_high_part : dst_high_part -++ else -++ dst_low_part = 0 -++ dst_high_part = src_low_part << shiftamount & 0x1f -++ */ -++ -++ emit_insn (gen_subsi3 (ext_start, -++ gen_int_mode (32, SImode), -++ shiftamount)); -++ emit_insn (gen_wext (dst_high_part_l32, src, ext_start)); -++ -++ /* Handle for shiftamout == 0. */ -++ emit_insn (gen_cmovzsi (dst_high_part_l32, shiftamount, -++ src_high_part, dst_high_part_l32)); -++ -++ emit_insn (gen_ashlsi3 (dst_low_part_l32, src_low_part, shiftamount)); -++ -++ emit_move_insn (dst_low_part_g32, const0_rtx); -++ emit_insn (gen_andsi3 (new_shift_amout, shiftamount, GEN_INT (0x1f))); -++ emit_insn (gen_ashlsi3 (dst_high_part_g32, src_low_part, -++ new_shift_amout)); -++ -++ emit_insn (gen_slt_compare (select_reg, shiftamount, GEN_INT (32))); -++ -++ emit_insn (gen_cmovnsi (dst_low_part, select_reg, -++ dst_low_part_l32, dst_low_part_g32)); -++ emit_insn (gen_cmovnsi (dst_high_part, select_reg, -++ dst_high_part_l32, dst_high_part_g32)); -++ } -++} -++ -++void -++nds32_split_ashiftrtdi3 (rtx dst, rtx src, rtx shiftamount) -++{ -++ nds32_split_shiftrtdi3 (dst, src, shiftamount, false); -++} -++ -++void -++nds32_split_lshiftrtdi3 (rtx dst, rtx src, rtx shiftamount) -++{ -++ nds32_split_shiftrtdi3 (dst, src, shiftamount, true); -++} -++ -++void -++nds32_split_rotatertdi3 (rtx dst, rtx src, rtx shiftamount) -++{ -++ rtx dst_low_part_l32, dst_high_part_l32; -++ rtx dst_low_part_g32, dst_high_part_g32; -++ rtx select_reg, low5bit, low5bit_inv, minus32sa; -++ rtx dst_low_part_g32_tmph; -++ rtx dst_low_part_g32_tmpl; -++ rtx dst_high_part_l32_tmph; -++ rtx dst_high_part_l32_tmpl; -++ -++ rtx src_low_part, src_high_part; -++ rtx dst_high_part, dst_low_part; -++ -++ shiftamount = force_reg (SImode, shiftamount); -++ -++ emit_insn (gen_andsi3 (shiftamount, -++ shiftamount, -++ gen_int_mode (0x3f, SImode))); -++ -++ dst_high_part = nds32_di_high_part_subreg (dst); -++ dst_low_part = nds32_di_low_part_subreg (dst); -++ -++ src_high_part = nds32_di_high_part_subreg (src); -++ src_low_part = nds32_di_low_part_subreg (src); -++ -++ dst_low_part_l32 = gen_reg_rtx (SImode); -++ dst_high_part_l32 = gen_reg_rtx (SImode); -++ dst_low_part_g32 = gen_reg_rtx (SImode); -++ dst_high_part_g32 = gen_reg_rtx (SImode); -++ low5bit = gen_reg_rtx (SImode); -++ low5bit_inv = gen_reg_rtx (SImode); -++ minus32sa = gen_reg_rtx (SImode); -++ select_reg = gen_reg_rtx (SImode); -++ -++ dst_low_part_g32_tmph = gen_reg_rtx (SImode); -++ dst_low_part_g32_tmpl = gen_reg_rtx (SImode); -++ -++ dst_high_part_l32_tmph = gen_reg_rtx (SImode); -++ dst_high_part_l32_tmpl = gen_reg_rtx (SImode); -++ -++ emit_insn (gen_slt_compare (select_reg, shiftamount, GEN_INT (32))); -++ -++ /* if shiftamount < 32 -++ dst_low_part = wext(src, shiftamount) -++ else -++ dst_low_part = ((src_high_part >> (shiftamount & 0x1f)) -++ | (src_low_part << (32 - (shiftamount & 0x1f)))) -++ */ -++ emit_insn (gen_andsi3 (low5bit, shiftamount, gen_int_mode (0x1f, SImode))); -++ emit_insn (gen_subsi3 (low5bit_inv, gen_int_mode (32, SImode), low5bit)); -++ -++ emit_insn (gen_wext (dst_low_part_l32, src, shiftamount)); -++ -++ emit_insn (gen_lshrsi3 (dst_low_part_g32_tmpl, src_high_part, low5bit)); -++ emit_insn (gen_ashlsi3 (dst_low_part_g32_tmph, src_low_part, low5bit_inv)); -++ -++ emit_insn (gen_iorsi3 (dst_low_part_g32, -++ dst_low_part_g32_tmpl, -++ dst_low_part_g32_tmph)); -++ -++ emit_insn (gen_cmovnsi (dst_low_part, select_reg, -++ dst_low_part_l32, dst_low_part_g32)); -++ -++ /* if shiftamount < 32 -++ dst_high_part = ((src_high_part >> shiftamount) -++ | (src_low_part << (32 - shiftamount))) -++ dst_high_part = shiftamount == 0 ? src_high_part : dst_high_part -++ else -++ dst_high_part = wext(src, shiftamount & 0x1f) -++ */ -++ -++ emit_insn (gen_subsi3 (minus32sa, gen_int_mode (32, SImode), shiftamount)); -++ -++ emit_insn (gen_lshrsi3 (dst_high_part_l32_tmpl, src_high_part, shiftamount)); -++ emit_insn (gen_ashlsi3 (dst_high_part_l32_tmph, src_low_part, minus32sa)); -++ -++ emit_insn (gen_iorsi3 (dst_high_part_l32, -++ dst_high_part_l32_tmpl, -++ dst_high_part_l32_tmph)); -++ -++ emit_insn (gen_cmovzsi (dst_high_part_l32, shiftamount, -++ src_high_part, dst_high_part_l32)); -++ -++ emit_insn (gen_wext (dst_high_part_g32, src, low5bit)); -++ -++ emit_insn (gen_cmovnsi (dst_high_part, select_reg, -++ dst_high_part_l32, dst_high_part_g32)); -++} -++ -++/* Return true if OP contains a symbol reference. */ -++bool -++symbolic_reference_mentioned_p (rtx op) -++{ -++ const char *fmt; -++ int i; -++ -++ if (GET_CODE (op) == SYMBOL_REF || GET_CODE (op) == LABEL_REF) -++ return true; -++ -++ fmt = GET_RTX_FORMAT (GET_CODE (op)); -++ for (i = GET_RTX_LENGTH (GET_CODE (op)) - 1; i >= 0; i--) -++ { -++ if (fmt[i] == 'E') -++ { -++ int j; -++ -++ for (j = XVECLEN (op, i) - 1; j >= 0; j--) -++ if (symbolic_reference_mentioned_p (XVECEXP (op, i, j))) -++ return true; -++ } -++ -++ else if (fmt[i] == 'e' && symbolic_reference_mentioned_p (XEXP (op, i))) -++ return true; -++ } -++ -++ return false; -++} -++ -++/* Expand PIC code for @GOTOFF and @GOT. -++ -++ Example for @GOTOFF: -++ -++ la $r0, symbol@GOTOFF -++ -> sethi $ta, hi20(symbol@GOTOFF) -++ ori $ta, $ta, lo12(symbol@GOTOFF) -++ add $r0, $ta, $gp -++ -++ Example for @GOT: -++ -++ la $r0, symbol@GOT -++ -> sethi $ta, hi20(symbol@GOT) -++ ori $ta, $ta, lo12(symbol@GOT) -++ lw $r0, [$ta + $gp] -++*/ -++rtx -++nds32_legitimize_pic_address (rtx x) -++{ -++ rtx addr = x; -++ rtx reg = gen_reg_rtx (Pmode); -++ rtx pat; -++ -++ if (GET_CODE (x) == LABEL_REF -++ || (GET_CODE (x) == SYMBOL_REF -++ && (CONSTANT_POOL_ADDRESS_P (x) -++ || SYMBOL_REF_LOCAL_P (x)))) -++ { -++ addr = gen_rtx_UNSPEC (SImode, gen_rtvec (1, x), UNSPEC_GOTOFF); -++ addr = gen_rtx_CONST (SImode, addr); -++ emit_insn (gen_sethi (reg, addr)); -++ emit_insn (gen_lo_sum (reg, reg, addr)); -++ x = gen_rtx_PLUS (Pmode, reg, pic_offset_table_rtx); -++ } -++ else if (GET_CODE (x) == SYMBOL_REF) -++ { -++ addr = gen_rtx_UNSPEC (SImode, gen_rtvec (1, x), UNSPEC_GOT); -++ addr = gen_rtx_CONST (SImode, addr); -++ emit_insn (gen_sethi (reg, addr)); -++ emit_insn (gen_lo_sum (reg, reg, addr)); -++ -++ x = gen_const_mem (SImode, gen_rtx_PLUS (Pmode, pic_offset_table_rtx, -++ reg)); -++ } -++ else if (GET_CODE (x) == CONST) -++ { -++ /* We don't split constant in expand_pic_move because GOTOFF can combine -++ the addend with the symbol. */ -++ addr = XEXP (x, 0); -++ gcc_assert (GET_CODE (addr) == PLUS); -++ -++ rtx op0 = XEXP (addr, 0); -++ rtx op1 = XEXP (addr, 1); -++ -++ if ((GET_CODE (op0) == LABEL_REF -++ || (GET_CODE (op0) == SYMBOL_REF -++ && (CONSTANT_POOL_ADDRESS_P (op0) -++ || SYMBOL_REF_LOCAL_P (op0)))) -++ && GET_CODE (op1) == CONST_INT) -++ { -++ pat = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, op0), UNSPEC_GOTOFF); -++ pat = gen_rtx_PLUS (Pmode, pat, op1); -++ pat = gen_rtx_CONST (Pmode, pat); -++ emit_insn (gen_sethi (reg, pat)); -++ emit_insn (gen_lo_sum (reg, reg, pat)); -++ x = gen_rtx_PLUS (Pmode, reg, pic_offset_table_rtx); -++ } -++ else if (GET_CODE (op0) == SYMBOL_REF -++ && GET_CODE (op1) == CONST_INT) -++ { -++ /* This is a constant offset from a @GOT symbol reference. */ -++ addr = gen_rtx_UNSPEC (SImode, gen_rtvec (1, op0), UNSPEC_GOT); -++ addr = gen_rtx_CONST (SImode, addr); -++ emit_insn (gen_sethi (reg, addr)); -++ emit_insn (gen_lo_sum (reg, reg, addr)); -++ addr = gen_const_mem (SImode, gen_rtx_PLUS (Pmode, -++ pic_offset_table_rtx, -++ reg)); -++ emit_move_insn (reg, addr); -++ if (satisfies_constraint_Is15 (op1)) -++ x = gen_rtx_PLUS (Pmode, reg, op1); -++ else -++ { -++ rtx tmp_reg = gen_reg_rtx (SImode); -++ emit_insn (gen_movsi (tmp_reg, op1)); -++ x = gen_rtx_PLUS (Pmode, reg, tmp_reg); -++ } -++ } -++ else -++ { -++ /* Don't handle this pattern. */ -++ debug_rtx (x); -++ gcc_unreachable (); -++ } -++ } -++ return x; -++} -++ -++void -++nds32_expand_pic_move (rtx *operands) -++{ -++ rtx src; -++ -++ src = nds32_legitimize_pic_address (operands[1]); -++ emit_move_insn (operands[0], src); -++} -++ -++/* Expand ICT symbol. -++ Example for @ICT and ICT model=large: -++ -++ la $r0, symbol@ICT -++ -> sethi $rt, hi20(symbol@ICT) -++ lwi $r0, [$rt + lo12(symbol@ICT)] -++ -++*/ -++rtx -++nds32_legitimize_ict_address (rtx x) -++{ -++ rtx symbol = x; -++ rtx addr = x; -++ rtx reg = gen_reg_rtx (Pmode); -++ gcc_assert (GET_CODE (x) == SYMBOL_REF -++ && nds32_indirect_call_referenced_p (x)); -++ -++ addr = gen_rtx_UNSPEC (SImode, gen_rtvec (1, symbol), UNSPEC_ICT); -++ addr = gen_rtx_CONST (SImode, addr); -++ emit_insn (gen_sethi (reg, addr)); -++ -++ x = gen_const_mem (SImode, gen_rtx_LO_SUM (Pmode, reg, addr)); -++ -++ return x; -++} -++ -++void -++nds32_expand_ict_move (rtx *operands) -++{ -++ rtx src = operands[1]; -++ -++ src = nds32_legitimize_ict_address (src); -++ -++ emit_move_insn (operands[0], src); -++} -++ -++/* Return true X is a indirect call symbol. */ -++bool -++nds32_indirect_call_referenced_p (rtx x) -++{ -++ if (GET_CODE (x) == UNSPEC && XINT (x, 1) == UNSPEC_ICT) -++ x = XVECEXP (x, 0, 0); -++ -++ if (GET_CODE (x) == SYMBOL_REF) -++ { -++ tree decl = SYMBOL_REF_DECL (x); -++ -++ return decl -++ && (lookup_attribute("indirect_call", -++ DECL_ATTRIBUTES(decl)) -++ != NULL); -++ } -++ -++ return false; -++} -++ -+ /* Return true X is need use long call. */ -+ bool -+ nds32_long_call_p (rtx symbol) -+ { -+- return TARGET_CMODEL_LARGE; -++ if (nds32_indirect_call_referenced_p (symbol)) -++ return TARGET_ICT_MODEL_LARGE; -++ else -++ return TARGET_CMODEL_LARGE; -++} -++ -++/* Return true if X contains a thread-local symbol. */ -++bool -++nds32_tls_referenced_p (rtx x) -++{ -++ if (!targetm.have_tls) -++ return false; -++ -++ if (GET_CODE (x) == CONST && GET_CODE (XEXP (x, 0)) == PLUS) -++ x = XEXP (XEXP (x, 0), 0); -++ -++ if (GET_CODE (x) == SYMBOL_REF && SYMBOL_REF_TLS_MODEL (x)) -++ return true; -++ -++ return false; -++} -++ -++/* ADDR contains a thread-local SYMBOL_REF. Generate code to compute -++ this (thread-local) address. */ -++rtx -++nds32_legitimize_tls_address (rtx x) -++{ -++ rtx tmp_reg; -++ rtx tp_reg = gen_rtx_REG (Pmode, TP_REGNUM); -++ rtx pat, insns, reg0; -++ -++ if (GET_CODE (x) == SYMBOL_REF) -++ switch (SYMBOL_REF_TLS_MODEL (x)) -++ { -++ case TLS_MODEL_GLOBAL_DYNAMIC: -++ case TLS_MODEL_LOCAL_DYNAMIC: -++ /* Emit UNSPEC_TLS_DESC rather than expand rtl directly because spill -++ may destroy the define-use chain anylysis to insert relax_hint. */ -++ if (SYMBOL_REF_TLS_MODEL (x) == TLS_MODEL_GLOBAL_DYNAMIC) -++ pat = gen_rtx_UNSPEC (SImode, gen_rtvec (1, x), UNSPEC_TLSGD); -++ else -++ pat = gen_rtx_UNSPEC (SImode, gen_rtvec (1, x), UNSPEC_TLSLD); -++ -++ pat = gen_rtx_CONST (SImode, pat); -++ reg0 = gen_rtx_REG (Pmode, 0); -++ /* If we can confirm all clobber reigsters, it doesn't have to use call -++ instruction. */ -++ insns = emit_call_insn (gen_tls_desc (pat, GEN_INT (0))); -++ use_reg (&CALL_INSN_FUNCTION_USAGE (insns), pic_offset_table_rtx); -++ RTL_CONST_CALL_P (insns) = 1; -++ tmp_reg = gen_reg_rtx (SImode); -++ emit_move_insn (tmp_reg, reg0); -++ x = tmp_reg; -++ break; -++ -++ case TLS_MODEL_INITIAL_EXEC: -++ pat = gen_rtx_UNSPEC (SImode, gen_rtvec (1, x), UNSPEC_TLSIE); -++ tmp_reg = gen_reg_rtx (SImode); -++ pat = gen_rtx_CONST (SImode, pat); -++ emit_insn (gen_tls_ie (tmp_reg, pat, GEN_INT (0))); -++ if (flag_pic) -++ emit_use (pic_offset_table_rtx); -++ x = gen_rtx_PLUS (Pmode, tmp_reg, tp_reg); -++ break; -++ -++ case TLS_MODEL_LOCAL_EXEC: -++ /* Expand symbol_ref@TPOFF': -++ sethi $ta, hi20(symbol_ref@TPOFF) -++ ori $ta, $ta, lo12(symbol_ref@TPOFF) -++ add $r0, $ta, $tp */ -++ tmp_reg = gen_reg_rtx (SImode); -++ pat = gen_rtx_UNSPEC (SImode, gen_rtvec (1, x), UNSPEC_TLSLE); -++ pat = gen_rtx_CONST (SImode, pat); -++ emit_insn (gen_sethi (tmp_reg, pat)); -++ emit_insn (gen_lo_sum (tmp_reg, tmp_reg, pat)); -++ x = gen_rtx_PLUS (Pmode, tmp_reg, tp_reg); -++ break; -++ -++ default: -++ gcc_unreachable (); -++ } -++ else if (GET_CODE (x) == CONST) -++ { -++ rtx base, addend; -++ split_const (x, &base, &addend); -++ -++ if (SYMBOL_REF_TLS_MODEL (base) == TLS_MODEL_LOCAL_EXEC) -++ { -++ /* Expand symbol_ref@TPOFF': -++ sethi $ta, hi20(symbol_ref@TPOFF + addend) -++ ori $ta, $ta, lo12(symbol_ref@TPOFF + addend) -++ add $r0, $ta, $tp */ -++ tmp_reg = gen_reg_rtx (SImode); -++ pat = gen_rtx_UNSPEC (SImode, gen_rtvec (1, base), UNSPEC_TLSLE); -++ pat = gen_rtx_PLUS (SImode, pat, addend); -++ pat = gen_rtx_CONST (SImode, pat); -++ emit_insn (gen_sethi (tmp_reg, pat)); -++ emit_insn (gen_lo_sum (tmp_reg, tmp_reg, pat)); -++ x = gen_rtx_PLUS (Pmode, tmp_reg, tp_reg); -++ } -++ } -++ -++ return x; -++} -++ -++void -++nds32_expand_tls_move (rtx *operands) -++{ -++ rtx src = operands[1]; -++ rtx base, addend; -++ -++ if (CONSTANT_P (src)) -++ split_const (src, &base, &addend); -++ -++ if (SYMBOL_REF_TLS_MODEL (base) == TLS_MODEL_LOCAL_EXEC) -++ src = nds32_legitimize_tls_address (src); -++ else -++ { -++ src = nds32_legitimize_tls_address (base); -++ if (addend != const0_rtx) -++ { -++ src = gen_rtx_PLUS (SImode, src, addend); -++ src = force_operand (src, operands[0]); -++ } -++ } -++ -++ emit_move_insn (operands[0], src); -+ } -+ -+ void -+@@ -2976,3 +3812,105 @@ nds32_expand_constant (machine_mode mode, HOST_WIDE_INT val, -+ emit_move_insn (target, gen_rtx_fmt_ee (AND, mode, source, temp)); -+ } -+ } -++ -++/* Auxiliary functions for lwm/smw. */ -++bool -++nds32_valid_smw_lwm_base_p (rtx op) -++{ -++ rtx base_addr; -++ -++ if (!MEM_P (op)) -++ return false; -++ -++ base_addr = XEXP (op, 0); -++ -++ if (REG_P (base_addr)) -++ return true; -++ else -++ { -++ if (GET_CODE (base_addr) == POST_INC -++ && REG_P (XEXP (base_addr, 0))) -++ return true; -++ } -++ -++ return false; -++} -++ -++/* Auxiliary functions for manipulation DI mode. */ -++rtx nds32_di_high_part_subreg(rtx reg) -++{ -++ unsigned high_part_offset = subreg_highpart_offset (SImode, DImode); -++ -++ return simplify_gen_subreg ( -++ SImode, reg, -++ DImode, high_part_offset); -++} -++ -++rtx nds32_di_low_part_subreg(rtx reg) -++{ -++ unsigned low_part_offset = subreg_lowpart_offset (SImode, DImode); -++ -++ return simplify_gen_subreg ( -++ SImode, reg, -++ DImode, low_part_offset); -++} -++ -++/* ------------------------------------------------------------------------ */ -++ -++/* Auxiliary function for output TLS patterns. */ -++ -++const char * -++nds32_output_tls_desc (rtx *operands) -++{ -++ char pattern[1000]; -++ -++ if (TARGET_RELAX_HINT) -++ snprintf (pattern, sizeof (pattern), -++ ".relax_hint %%1\n\tsethi $r0, hi20(%%0)\n\t" -++ ".relax_hint %%1\n\tori $r0, $r0, lo12(%%0)\n\t" -++ ".relax_hint %%1\n\tlw $r15, [$r0 + $gp]\n\t" -++ ".relax_hint %%1\n\tadd $r0, $r0, $gp\n\t" -++ ".relax_hint %%1\n\tjral $r15"); -++ else -++ snprintf (pattern, sizeof (pattern), -++ "sethi $r0, hi20(%%0)\n\t" -++ "ori $r0, $r0, lo12(%%0)\n\t" -++ "lw $r15, [$r0 + $gp]\n\t" -++ "add $r0, $r0, $gp\n\t" -++ "jral $r15"); -++ output_asm_insn (pattern, operands); -++ return ""; -++} -++ -++const char * -++nds32_output_tls_ie (rtx *operands) -++{ -++ char pattern[1000]; -++ -++ if (flag_pic) -++ { -++ if (TARGET_RELAX_HINT) -++ snprintf (pattern, sizeof (pattern), -++ ".relax_hint %%2\n\tsethi %%0, hi20(%%1)\n\t" -++ ".relax_hint %%2\n\tori %%0, %%0, lo12(%%1)\n\t" -++ ".relax_hint %%2\n\tlw %%0, [%%0 + $gp]"); -++ else -++ snprintf (pattern, sizeof (pattern), -++ "sethi %%0, hi20(%%1)\n\t" -++ "ori %%0, %%0, lo12(%%1)\n\t" -++ "lw %%0, [%%0 + $gp]"); -++ } -++ else -++ { -++ if (TARGET_RELAX_HINT) -++ snprintf (pattern, sizeof (pattern), -++ ".relax_hint %%2\n\tsethi %%0, hi20(%%1)\n\t" -++ ".relax_hint %%2\n\tlwi %%0, [%%0 + lo12(%%1)]"); -++ else -++ snprintf (pattern, sizeof (pattern), -++ "sethi %%0, hi20(%%1)\n\t" -++ "lwi %%0, [%%0 + lo12(%%1)]"); -++ } -++ output_asm_insn (pattern, operands); -++ return ""; -++} -+diff --git a/gcc/config/nds32/nds32-memory-manipulation.c b/gcc/config/nds32/nds32-memory-manipulation.c -+index 8dea13047b6..f6140e65130 100644 -+--- a/gcc/config/nds32/nds32-memory-manipulation.c -++++ b/gcc/config/nds32/nds32-memory-manipulation.c -+@@ -257,8 +257,124 @@ static bool -+ nds32_expand_movmemsi_loop_known_size (rtx dstmem, rtx srcmem, -+ rtx size, rtx alignment) -+ { -+- return nds32_expand_movmemsi_loop_unknown_size (dstmem, srcmem, -+- size, alignment); -++ rtx dst_base_reg, src_base_reg; -++ rtx dst_itr, src_itr; -++ rtx dstmem_m, srcmem_m, dst_itr_m, src_itr_m; -++ rtx dst_end; -++ rtx double_word_mode_loop, byte_mode_loop; -++ rtx tmp; -++ int start_regno; -++ bool align_to_4_bytes = (INTVAL (alignment) & 3) == 0; -++ unsigned HOST_WIDE_INT total_bytes = UINTVAL (size); -++ -++ if (TARGET_ISA_V3M && !align_to_4_bytes) -++ return 0; -++ -++ if (TARGET_REDUCED_REGS) -++ start_regno = 2; -++ else -++ start_regno = 16; -++ -++ dst_itr = gen_reg_rtx (Pmode); -++ src_itr = gen_reg_rtx (Pmode); -++ dst_end = gen_reg_rtx (Pmode); -++ tmp = gen_reg_rtx (QImode); -++ -++ double_word_mode_loop = gen_label_rtx (); -++ byte_mode_loop = gen_label_rtx (); -++ -++ dst_base_reg = copy_to_mode_reg (Pmode, XEXP (dstmem, 0)); -++ src_base_reg = copy_to_mode_reg (Pmode, XEXP (srcmem, 0)); -++ -++ if (total_bytes < 8) -++ { -++ /* Emit total_bytes less than 8 loop version of movmem. -++ add $dst_end, $dst, $size -++ move $dst_itr, $dst -++ .Lbyte_mode_loop: -++ lbi.bi $tmp, [$src_itr], #1 -++ sbi.bi $tmp, [$dst_itr], #1 -++ ! Not readch upper bound. Loop. -++ bne $dst_itr, $dst_end, .Lbyte_mode_loop */ -++ -++ /* add $dst_end, $dst, $size */ -++ dst_end = expand_binop (Pmode, add_optab, dst_base_reg, size, -++ NULL_RTX, 0, OPTAB_WIDEN); -++ /* move $dst_itr, $dst -++ move $src_itr, $src */ -++ emit_move_insn (dst_itr, dst_base_reg); -++ emit_move_insn (src_itr, src_base_reg); -++ -++ /* .Lbyte_mode_loop: */ -++ emit_label (byte_mode_loop); -++ -++ /* lbi.bi $tmp, [$src_itr], #1 */ -++ nds32_emit_post_inc_load_store (tmp, src_itr, QImode, true); -++ -++ /* sbi.bi $tmp, [$dst_itr], #1 */ -++ nds32_emit_post_inc_load_store (tmp, dst_itr, QImode, false); -++ /* ! Not readch upper bound. Loop. -++ bne $dst_itr, $dst_end, .Lbyte_mode_loop */ -++ emit_cmp_and_jump_insns (dst_itr, dst_end, NE, NULL, -++ SImode, 1, byte_mode_loop); -++ return true; -++ } -++ else if (total_bytes % 8 == 0) -++ { -++ /* Emit multiple of 8 loop version of movmem. -++ -++ add $dst_end, $dst, $size -++ move $dst_itr, $dst -++ move $src_itr, $src -++ -++ .Ldouble_word_mode_loop: -++ lmw.bim $tmp-begin, [$src_itr], $tmp-end, #0 ! $src_itr' = $src_itr -++ smw.bim $tmp-begin, [$dst_itr], $tmp-end, #0 ! $dst_itr' = $dst_itr -++ ! move will delete after register allocation -++ move $src_itr, $src_itr' -++ move $dst_itr, $dst_itr' -++ ! Not readch upper bound. Loop. -++ bne $double_word_end, $dst_itr, .Ldouble_word_mode_loop */ -++ -++ /* add $dst_end, $dst, $size */ -++ dst_end = expand_binop (Pmode, add_optab, dst_base_reg, size, -++ NULL_RTX, 0, OPTAB_WIDEN); -++ -++ /* move $dst_itr, $dst -++ move $src_itr, $src */ -++ emit_move_insn (dst_itr, dst_base_reg); -++ emit_move_insn (src_itr, src_base_reg); -++ -++ /* .Ldouble_word_mode_loop: */ -++ emit_label (double_word_mode_loop); -++ /* lmw.bim $tmp-begin, [$src_itr], $tmp-end, #0 ! $src_itr' = $src_itr -++ smw.bim $tmp-begin, [$dst_itr], $tmp-end, #0 ! $dst_itr' = $dst_itr */ -++ src_itr_m = src_itr; -++ dst_itr_m = dst_itr; -++ srcmem_m = srcmem; -++ dstmem_m = dstmem; -++ nds32_emit_mem_move_block (start_regno, 2, -++ &dst_itr_m, &dstmem_m, -++ &src_itr_m, &srcmem_m, -++ true); -++ /* move $src_itr, $src_itr' -++ move $dst_itr, $dst_itr' */ -++ emit_move_insn (dst_itr, dst_itr_m); -++ emit_move_insn (src_itr, src_itr_m); -++ -++ /* ! Not readch upper bound. Loop. -++ bne $double_word_end, $dst_itr, .Ldouble_word_mode_loop */ -++ emit_cmp_and_jump_insns (dst_end, dst_itr, NE, NULL, -++ Pmode, 1, double_word_mode_loop); -++ } -++ else -++ { -++ /* Handle size greater than 8, and not a multiple of 8. */ -++ return nds32_expand_movmemsi_loop_unknown_size (dstmem, srcmem, -++ size, alignment); -++ } -++ -++ return true; -+ } -+ -+ static bool -+@@ -433,10 +549,8 @@ nds32_expand_movmemsi (rtx dstmem, rtx srcmem, rtx total_bytes, rtx alignment) -+ /* Auxiliary function for expand setmem pattern. */ -+ -+ static rtx -+-nds32_gen_dup_4_byte_to_word_value (rtx value) -++nds32_gen_dup_4_byte_to_word_value_aux (rtx value, rtx value4word) -+ { -+- rtx value4word = gen_reg_rtx (SImode); -+- -+ gcc_assert (GET_MODE (value) == QImode || CONST_INT_P (value)); -+ -+ if (CONST_INT_P (value)) -+@@ -449,36 +563,74 @@ nds32_gen_dup_4_byte_to_word_value (rtx value) -+ } -+ else -+ { -+- /* ! prepare word -+- andi $tmp1, $value, 0xff ! $tmp1 <- 0x000000ab -+- slli $tmp2, $tmp1, 8 ! $tmp2 <- 0x0000ab00 -+- or $tmp3, $tmp1, $tmp2 ! $tmp3 <- 0x0000abab -+- slli $tmp4, $tmp3, 16 ! $tmp4 <- 0xabab0000 -+- or $val4word, $tmp3, $tmp4 ! $value4word <- 0xabababab */ -+- -+- rtx tmp1, tmp2, tmp3, tmp4, final_value; -+- tmp1 = expand_binop (SImode, and_optab, value, -+- gen_int_mode (0xff, SImode), -+- NULL_RTX, 0, OPTAB_WIDEN); -+- tmp2 = expand_binop (SImode, ashl_optab, tmp1, -+- gen_int_mode (8, SImode), -+- NULL_RTX, 0, OPTAB_WIDEN); -+- tmp3 = expand_binop (SImode, ior_optab, tmp1, tmp2, -+- NULL_RTX, 0, OPTAB_WIDEN); -+- tmp4 = expand_binop (SImode, ashl_optab, tmp3, -+- gen_int_mode (16, SImode), -+- NULL_RTX, 0, OPTAB_WIDEN); -+- -+- final_value = expand_binop (SImode, ior_optab, tmp3, tmp4, -+- NULL_RTX, 0, OPTAB_WIDEN); -+- emit_move_insn (value4word, final_value); -++ if (NDS32_EXT_DSP_P ()) -++ { -++ /* ! prepare word -++ insb $tmp, $value, 1 ! $tmp <- 0x0000abab -++ pkbb16 $tmp6, $tmp2, $tmp2 ! $value4word <- 0xabababab */ -++ rtx tmp = gen_reg_rtx (SImode); -++ -++ convert_move (tmp, value, true); -++ -++ emit_insn ( -++ gen_insvsi_internal (tmp, gen_int_mode (0x8, SImode), tmp)); -++ -++ emit_insn (gen_pkbbsi_1 (value4word, tmp, tmp)); -++ } -++ else -++ { -++ /* ! prepare word -++ andi $tmp1, $value, 0xff ! $tmp1 <- 0x000000ab -++ slli $tmp2, $tmp1, 8 ! $tmp2 <- 0x0000ab00 -++ or $tmp3, $tmp1, $tmp2 ! $tmp3 <- 0x0000abab -++ slli $tmp4, $tmp3, 16 ! $tmp4 <- 0xabab0000 -++ or $val4word, $tmp3, $tmp4 ! $value4word <- 0xabababab */ -++ -++ rtx tmp1, tmp2, tmp3, tmp4; -++ tmp1 = expand_binop (SImode, and_optab, value, -++ gen_int_mode (0xff, SImode), -++ NULL_RTX, 0, OPTAB_WIDEN); -++ tmp2 = expand_binop (SImode, ashl_optab, tmp1, -++ gen_int_mode (8, SImode), -++ NULL_RTX, 0, OPTAB_WIDEN); -++ tmp3 = expand_binop (SImode, ior_optab, tmp1, tmp2, -++ NULL_RTX, 0, OPTAB_WIDEN); -++ tmp4 = expand_binop (SImode, ashl_optab, tmp3, -++ gen_int_mode (16, SImode), -++ NULL_RTX, 0, OPTAB_WIDEN); -++ -++ emit_insn (gen_iorsi3 (value4word, tmp3, tmp4)); -++ } -+ } -+ -+ return value4word; -+ } -+ -+ static rtx -+-emit_setmem_word_loop (rtx itr, rtx size, rtx value) -++nds32_gen_dup_4_byte_to_word_value (rtx value) -++{ -++ rtx value4word = gen_reg_rtx (SImode); -++ nds32_gen_dup_4_byte_to_word_value_aux (value, value4word); -++ -++ return value4word; -++} -++ -++static rtx -++nds32_gen_dup_8_byte_to_double_word_value (rtx value) -++{ -++ rtx value4doubleword = gen_reg_rtx (DImode); -++ -++ nds32_gen_dup_4_byte_to_word_value_aux ( -++ value, nds32_di_low_part_subreg(value4doubleword)); -++ -++ emit_move_insn (nds32_di_high_part_subreg(value4doubleword), -++ nds32_di_low_part_subreg(value4doubleword)); -++ return value4doubleword; -++} -++ -++ -++static rtx -++emit_setmem_doubleword_loop (rtx itr, rtx size, rtx value) -+ { -+ rtx word_mode_label = gen_label_rtx (); -+ rtx word_mode_end_label = gen_label_rtx (); -+@@ -487,9 +639,9 @@ emit_setmem_word_loop (rtx itr, rtx size, rtx value) -+ rtx word_mode_end = gen_reg_rtx (SImode); -+ rtx size_for_word = gen_reg_rtx (SImode); -+ -+- /* and $size_for_word, $size, #~3 */ -++ /* and $size_for_word, $size, #~0x7 */ -+ size_for_word = expand_binop (SImode, and_optab, size, -+- gen_int_mode (~3, SImode), -++ gen_int_mode (~0x7, SImode), -+ NULL_RTX, 0, OPTAB_WIDEN); -+ -+ emit_move_insn (byte_mode_size, size); -+@@ -501,8 +653,8 @@ emit_setmem_word_loop (rtx itr, rtx size, rtx value) -+ word_mode_end = expand_binop (Pmode, add_optab, itr, size_for_word, -+ NULL_RTX, 0, OPTAB_WIDEN); -+ -+- /* andi $byte_mode_size, $size, 3 */ -+- byte_mode_size_tmp = expand_binop (SImode, and_optab, size, GEN_INT (3), -++ /* andi $byte_mode_size, $size, 0x7 */ -++ byte_mode_size_tmp = expand_binop (SImode, and_optab, size, GEN_INT (0x7), -+ NULL_RTX, 0, OPTAB_WIDEN); -+ -+ emit_move_insn (byte_mode_size, byte_mode_size_tmp); -+@@ -512,9 +664,9 @@ emit_setmem_word_loop (rtx itr, rtx size, rtx value) -+ /* ! word-mode set loop -+ smw.bim $value4word, [$dst_itr], $value4word, 0 -+ bne $word_mode_end, $dst_itr, .Lword_mode */ -+- emit_insn (gen_unaligned_store_update_base_w (itr, -+- itr, -+- value)); -++ emit_insn (gen_unaligned_store_update_base_dw (itr, -++ itr, -++ value)); -+ emit_cmp_and_jump_insns (word_mode_end, itr, NE, NULL, -+ Pmode, 1, word_mode_label); -+ -+@@ -566,7 +718,7 @@ emit_setmem_byte_loop (rtx itr, rtx size, rtx value, bool need_end) -+ static bool -+ nds32_expand_setmem_loop (rtx dstmem, rtx size, rtx value) -+ { -+- rtx value4word; -++ rtx value4doubleword; -+ rtx value4byte; -+ rtx dst; -+ rtx byte_mode_size; -+@@ -609,7 +761,7 @@ nds32_expand_setmem_loop (rtx dstmem, rtx size, rtx value) -+ or $tmp3, $tmp1, $tmp2 ! $tmp3 <- 0x0000abab -+ slli $tmp4, $tmp3, 16 ! $tmp4 <- 0xabab0000 -+ or $val4word, $tmp3, $tmp4 ! $value4word <- 0xabababab */ -+- value4word = nds32_gen_dup_4_byte_to_word_value (value); -++ value4doubleword = nds32_gen_dup_8_byte_to_double_word_value (value); -+ -+ /* and $size_for_word, $size, #-4 -+ beqz $size_for_word, .Lword_mode_end -+@@ -622,7 +774,7 @@ nds32_expand_setmem_loop (rtx dstmem, rtx size, rtx value) -+ smw.bim $value4word, [$dst], $value4word, 0 -+ bne $word_mode_end, $dst, .Lword_mode -+ .Lword_mode_end: */ -+- byte_mode_size = emit_setmem_word_loop (dst, size, value4word); -++ byte_mode_size = emit_setmem_doubleword_loop (dst, size, value4doubleword); -+ -+ /* beqz $byte_mode_size, .Lend -+ add $byte_mode_end, $dst, $byte_mode_size -+@@ -633,8 +785,8 @@ nds32_expand_setmem_loop (rtx dstmem, rtx size, rtx value) -+ bne $byte_mode_end, $dst, .Lbyte_mode -+ .Lend: */ -+ -+- value4byte = simplify_gen_subreg (QImode, value4word, SImode, -+- subreg_lowpart_offset (QImode, SImode)); -++ value4byte = simplify_gen_subreg (QImode, value4doubleword, DImode, -++ subreg_lowpart_offset (QImode, DImode)); -+ -+ emit_setmem_byte_loop (dst, byte_mode_size, value4byte, false); -+ -+@@ -651,14 +803,15 @@ nds32_expand_setmem_loop_v3m (rtx dstmem, rtx size, rtx value) -+ rtx byte_loop_size = gen_reg_rtx (SImode); -+ rtx remain_size = gen_reg_rtx (SImode); -+ rtx new_base_reg; -+- rtx value4byte, value4word; -++ rtx value4byte, value4doubleword; -+ rtx byte_mode_size; -+ rtx last_byte_loop_label = gen_label_rtx (); -+ -+ size = force_reg (SImode, size); -+ -+- value4word = nds32_gen_dup_4_byte_to_word_value (value); -+- value4byte = simplify_gen_subreg (QImode, value4word, SImode, 0); -++ value4doubleword = nds32_gen_dup_8_byte_to_double_word_value (value); -++ value4byte = simplify_gen_subreg (QImode, value4doubleword, DImode, -++ subreg_lowpart_offset (QImode, DImode)); -+ -+ emit_move_insn (byte_loop_size, size); -+ emit_move_insn (byte_loop_base, base_reg); -+@@ -686,9 +839,9 @@ nds32_expand_setmem_loop_v3m (rtx dstmem, rtx size, rtx value) -+ emit_insn (gen_subsi3 (remain_size, size, need_align_bytes)); -+ -+ /* Set memory word by word. */ -+- byte_mode_size = emit_setmem_word_loop (new_base_reg, -+- remain_size, -+- value4word); -++ byte_mode_size = emit_setmem_doubleword_loop (new_base_reg, -++ remain_size, -++ value4doubleword); -+ -+ emit_move_insn (byte_loop_base, new_base_reg); -+ emit_move_insn (byte_loop_size, byte_mode_size); -+diff --git a/gcc/config/nds32/nds32-multiple.md b/gcc/config/nds32/nds32-multiple.md -+index a8f77175927..80746b19323 100644 -+--- a/gcc/config/nds32/nds32-multiple.md -++++ b/gcc/config/nds32/nds32-multiple.md -+@@ -2854,6 +2854,25 @@ -+ (set_attr "length" "4")] -+ ) -+ -++(define_expand "unaligned_store_update_base_dw" -++ [(parallel [(set (match_operand:SI 0 "register_operand" "=r") -++ (plus:SI (match_operand:SI 1 "register_operand" "0") (const_int 8))) -++ (set (mem:DI (match_dup 1)) -++ (unspec:DI [(match_operand:DI 2 "register_operand" "r")] UNSPEC_UASTORE_DW))])] -++ "" -++{ -++ /* DO NOT emit unaligned_store_w_m immediately since web pass don't -++ recognize post_inc, try it again after GCC 5.0. -++ REF: https://gcc.gnu.org/bugzilla/show_bug.cgi?id=63156 */ -++ emit_insn (gen_unaligned_store_dw (gen_rtx_MEM (DImode, operands[1]), operands[2])); -++ emit_insn (gen_addsi3 (operands[0], operands[1], gen_int_mode (8, Pmode))); -++ DONE; -++} -++ [(set_attr "type" "store_multiple") -++ (set_attr "combo" "2") -++ (set_attr "length" "4")] -++) -++ -+ (define_insn "*stmsi25" -+ [(match_parallel 0 "nds32_store_multiple_operation" -+ [(set (mem:SI (match_operand:SI 1 "register_operand" "r")) -+diff --git a/gcc/config/nds32/nds32-n10.md b/gcc/config/nds32/nds32-n10.md -+new file mode 100644 -+index 00000000000..0dd76da1ef8 -+--- /dev/null -++++ b/gcc/config/nds32/nds32-n10.md -+@@ -0,0 +1,439 @@ -++;; Pipeline descriptions of Andes NDS32 cpu for GNU compiler -++;; Copyright (C) 2012-2018 Free Software Foundation, Inc. -++;; Contributed by Andes Technology Corporation. -++;; -++;; This file is part of GCC. -++;; -++;; GCC is free software; you can redistribute it and/or modify it -++;; under the terms of the GNU General Public License as published -++;; by the Free Software Foundation; either version 3, or (at your -++;; option) any later version. -++;; -++;; GCC is distributed in the hope that it will be useful, but WITHOUT -++;; ANY WARRANTY; without even the implied warranty of MERCHANTABILITY -++;; or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public -++;; License for more details. -++;; -++;; You should have received a copy of the GNU General Public License -++;; along with GCC; see the file COPYING3. If not see -++;; . -++ -++ -++;; ------------------------------------------------------------------------ -++;; Define N10 pipeline settings. -++;; ------------------------------------------------------------------------ -++ -++(define_automaton "nds32_n10_machine") -++ -++;; ------------------------------------------------------------------------ -++;; Pipeline Stages -++;; ------------------------------------------------------------------------ -++;; IF - Instruction Fetch -++;; II - Instruction Issue / Instruction Decode -++;; EX - Instruction Execution -++;; MM - Memory Execution -++;; WB - Instruction Retire / Result Write-Back -++ -++(define_cpu_unit "n10_ii" "nds32_n10_machine") -++(define_cpu_unit "n10_ex" "nds32_n10_machine") -++(define_cpu_unit "n10_mm" "nds32_n10_machine") -++(define_cpu_unit "n10_wb" "nds32_n10_machine") -++(define_cpu_unit "n10f_iq" "nds32_n10_machine") -++(define_cpu_unit "n10f_rf" "nds32_n10_machine") -++(define_cpu_unit "n10f_e1" "nds32_n10_machine") -++(define_cpu_unit "n10f_e2" "nds32_n10_machine") -++(define_cpu_unit "n10f_e3" "nds32_n10_machine") -++(define_cpu_unit "n10f_e4" "nds32_n10_machine") -++ -++(define_insn_reservation "nds_n10_unknown" 1 -++ (and (eq_attr "type" "unknown") -++ (eq_attr "pipeline_model" "n10")) -++ "n10_ii, n10_ex, n10_mm, n10_wb") -++ -++(define_insn_reservation "nds_n10_misc" 1 -++ (and (eq_attr "type" "misc") -++ (eq_attr "pipeline_model" "n10")) -++ "n10_ii, n10_ex, n10_mm, n10_wb") -++ -++(define_insn_reservation "nds_n10_mmu" 1 -++ (and (eq_attr "type" "mmu") -++ (eq_attr "pipeline_model" "n10")) -++ "n10_ii, n10_ex, n10_mm, n10_wb") -++ -++(define_insn_reservation "nds_n10_alu" 1 -++ (and (eq_attr "type" "alu") -++ (eq_attr "pipeline_model" "n10")) -++ "n10_ii, n10_ex, n10_mm, n10_wb") -++ -++(define_insn_reservation "nds_n10_alu_shift" 1 -++ (and (eq_attr "type" "alu_shift") -++ (eq_attr "pipeline_model" "n10")) -++ "n10_ii, n10_ii+n10_ex, n10_ex+n10_mm, n10_mm+n10_wb, n10_wb") -++ -++(define_insn_reservation "nds_n10_pbsad" 1 -++ (and (eq_attr "type" "pbsad") -++ (eq_attr "pipeline_model" "n10")) -++ "n10_ii, n10_ex*3, n10_mm, n10_wb") -++ -++(define_insn_reservation "nds_n10_pbsada" 1 -++ (and (eq_attr "type" "pbsada") -++ (eq_attr "pipeline_model" "n10")) -++ "n10_ii, n10_ex*3, n10_mm, n10_wb") -++ -++(define_insn_reservation "nds_n10_load" 1 -++ (and (match_test "nds32::load_single_p (insn)") -++ (eq_attr "pipeline_model" "n10")) -++ "n10_ii, n10_ex, n10_mm, n10_wb") -++ -++(define_insn_reservation "nds_n10_store" 1 -++ (and (match_test "nds32::store_single_p (insn)") -++ (eq_attr "pipeline_model" "n10")) -++ "n10_ii, n10_ex, n10_mm, n10_wb") -++ -++(define_insn_reservation "nds_n10_load_multiple_1" 1 -++ (and (eq_attr "pipeline_model" "n10") -++ (and (eq_attr "type" "load_multiple") -++ (eq_attr "combo" "1"))) -++ "n10_ii, n10_ex, n10_mm, n10_wb") -++ -++(define_insn_reservation "nds_n10_load_multiple_2" 1 -++ (and (eq_attr "pipeline_model" "n10") -++ (ior (and (eq_attr "type" "load_multiple") -++ (eq_attr "combo" "2")) -++ (match_test "nds32::load_double_p (insn)"))) -++ "n10_ii, n10_ii+n10_ex, n10_ex+n10_mm, n10_mm+n10_wb, n10_wb") -++ -++(define_insn_reservation "nds_n10_load_multiple_3" 1 -++ (and (eq_attr "pipeline_model" "n10") -++ (and (eq_attr "type" "load_multiple") -++ (eq_attr "combo" "3"))) -++ "n10_ii, n10_ii+n10_ex, n10_ii+n10_ex+n10_mm, n10_ex+n10_mm+n10_wb, n10_mm+n10_wb, n10_wb") -++ -++(define_insn_reservation "nds_n10_load_multiple_4" 1 -++ (and (eq_attr "pipeline_model" "n10") -++ (and (eq_attr "type" "load_multiple") -++ (eq_attr "combo" "4"))) -++ "n10_ii, n10_ii+n10_ex, n10_ii+n10_ex+n10_mm, n10_ii+n10_ex+n10_mm+n10_wb, n10_ex+n10_mm+n10_wb, n10_mm+n10_wb, n10_wb") -++ -++(define_insn_reservation "nds_n10_load_multiple_5" 1 -++ (and (eq_attr "pipeline_model" "n10") -++ (and (eq_attr "type" "load_multiple") -++ (eq_attr "combo" "5"))) -++ "n10_ii, n10_ii+n10_ex, n10_ii+n10_ex+n10_mm, (n10_ii+n10_ex+n10_mm+n10_wb)*2, n10_ex+n10_mm+n10_wb, n10_mm+n10_wb, n10_wb") -++ -++(define_insn_reservation "nds_n10_load_multiple_6" 1 -++ (and (eq_attr "pipeline_model" "n10") -++ (and (eq_attr "type" "load_multiple") -++ (eq_attr "combo" "6"))) -++ "n10_ii, n10_ii+n10_ex, n10_ii+n10_ex+n10_mm, (n10_ii+n10_ex+n10_mm+n10_wb)*3, n10_ex+n10_mm+n10_wb, n10_mm+n10_wb, n10_wb") -++ -++(define_insn_reservation "nds_n10_load_multiple_7" 1 -++ (and (eq_attr "pipeline_model" "n10") -++ (and (eq_attr "type" "load_multiple") -++ (eq_attr "combo" "7"))) -++ "n10_ii, n10_ii+n10_ex, n10_ii+n10_ex+n10_mm, (n10_ii+n10_ex+n10_mm+n10_wb)*4, n10_ex+n10_mm+n10_wb, n10_mm+n10_wb, n10_wb") -++ -++(define_insn_reservation "nds_n10_load_multiple_N" 1 -++ (and (eq_attr "pipeline_model" "n10") -++ (and (eq_attr "type" "load_multiple") -++ (match_test "get_attr_combo (insn) >= 8"))) -++ "n10_ii, n10_ii+n10_ex, n10_ii+n10_ex+n10_mm, (n10_ii+n10_ex+n10_mm+n10_wb)*5, n10_ex+n10_mm+n10_wb, n10_mm+n10_wb, n10_wb") -++ -++(define_insn_reservation "nds_n10_store_multiple_1" 1 -++ (and (eq_attr "pipeline_model" "n10") -++ (and (eq_attr "type" "store_multiple") -++ (eq_attr "combo" "1"))) -++ "n10_ii, n10_ex, n10_mm, n10_wb") -++ -++(define_insn_reservation "nds_n10_store_multiple_2" 1 -++ (and (eq_attr "pipeline_model" "n10") -++ (ior (and (eq_attr "type" "store_multiple") -++ (eq_attr "combo" "2")) -++ (match_test "nds32::store_double_p (insn)"))) -++ "n10_ii, n10_ii+n10_ex, n10_ex+n10_mm, n10_mm+n10_wb, n10_wb") -++ -++(define_insn_reservation "nds_n10_store_multiple_3" 1 -++ (and (eq_attr "pipeline_model" "n10") -++ (and (eq_attr "type" "store_multiple") -++ (eq_attr "combo" "3"))) -++ "n10_ii, n10_ii+n10_ex, n10_ii+n10_ex+n10_mm, n10_ex+n10_mm+n10_wb, n10_mm+n10_wb, n10_wb") -++ -++(define_insn_reservation "nds_n10_store_multiple_4" 1 -++ (and (eq_attr "pipeline_model" "n10") -++ (and (eq_attr "type" "store_multiple") -++ (eq_attr "combo" "4"))) -++ "n10_ii, n10_ii+n10_ex, n10_ii+n10_ex+n10_mm, n10_ii+n10_ex+n10_mm+n10_wb, n10_ex+n10_mm+n10_wb, n10_mm+n10_wb, n10_wb") -++ -++(define_insn_reservation "nds_n10_store_multiple_5" 1 -++ (and (eq_attr "pipeline_model" "n10") -++ (and (eq_attr "type" "store_multiple") -++ (eq_attr "combo" "5"))) -++ "n10_ii, n10_ii+n10_ex, n10_ii+n10_ex+n10_mm, (n10_ii+n10_ex+n10_mm+n10_wb)*2, n10_ex+n10_mm+n10_wb, n10_mm+n10_wb, n10_wb") -++ -++(define_insn_reservation "nds_n10_store_multiple_6" 1 -++ (and (eq_attr "pipeline_model" "n10") -++ (and (eq_attr "type" "store_multiple") -++ (eq_attr "combo" "6"))) -++ "n10_ii, n10_ii+n10_ex, n10_ii+n10_ex+n10_mm, (n10_ii+n10_ex+n10_mm+n10_wb)*3, n10_ex+n10_mm+n10_wb, n10_mm+n10_wb, n10_wb") -++ -++(define_insn_reservation "nds_n10_store_multiple_7" 1 -++ (and (eq_attr "pipeline_model" "n10") -++ (and (eq_attr "type" "store_multiple") -++ (eq_attr "combo" "7"))) -++ "n10_ii, n10_ii+n10_ex, n10_ii+n10_ex+n10_mm, (n10_ii+n10_ex+n10_mm+n10_wb)*4, n10_ex+n10_mm+n10_wb, n10_mm+n10_wb, n10_wb") -++ -++(define_insn_reservation "nds_n10_store_multiple_N" 1 -++ (and (eq_attr "pipeline_model" "n10") -++ (and (eq_attr "type" "store_multiple") -++ (match_test "get_attr_combo (insn) >= 8"))) -++ "n10_ii, n10_ii+n10_ex, n10_ii+n10_ex+n10_mm, (n10_ii+n10_ex+n10_mm+n10_wb)*5, n10_ex+n10_mm+n10_wb, n10_mm+n10_wb, n10_wb") -++ -++(define_insn_reservation "nds_n10_mul" 1 -++ (and (eq_attr "type" "mul") -++ (eq_attr "pipeline_model" "n10")) -++ "n10_ii, n10_ex, n10_mm, n10_wb") -++ -++(define_insn_reservation "nds_n10_mac" 1 -++ (and (eq_attr "type" "mac") -++ (eq_attr "pipeline_model" "n10")) -++ "n10_ii, n10_ex, n10_mm, n10_wb") -++ -++(define_insn_reservation "nds_n10_div" 1 -++ (and (eq_attr "type" "div") -++ (eq_attr "pipeline_model" "n10")) -++ "n10_ii, n10_ex*34, n10_mm, n10_wb") -++ -++(define_insn_reservation "nds_n10_branch" 1 -++ (and (eq_attr "type" "branch") -++ (eq_attr "pipeline_model" "n10")) -++ "n10_ii, n10_ex, n10_mm, n10_wb") -++ -++(define_insn_reservation "nds_n10_dsp_alu" 1 -++ (and (eq_attr "type" "dalu") -++ (eq_attr "pipeline_model" "n10")) -++ "n10_ii, n10_ex, n10_mm, n10_wb") -++ -++(define_insn_reservation "nds_n10_dsp_alu64" 1 -++ (and (eq_attr "type" "dalu64") -++ (eq_attr "pipeline_model" "n10")) -++ "n10_ii, n10_ex, n10_mm, n10_wb") -++ -++(define_insn_reservation "nds_n10_dsp_alu_round" 1 -++ (and (eq_attr "type" "daluround") -++ (eq_attr "pipeline_model" "n10")) -++ "n10_ii, n10_ex, n10_mm, n10_wb") -++ -++(define_insn_reservation "nds_n10_dsp_cmp" 1 -++ (and (eq_attr "type" "dcmp") -++ (eq_attr "pipeline_model" "n10")) -++ "n10_ii, n10_ex, n10_mm, n10_wb") -++ -++(define_insn_reservation "nds_n10_dsp_clip" 1 -++ (and (eq_attr "type" "dclip") -++ (eq_attr "pipeline_model" "n10")) -++ "n10_ii, n10_ex, n10_mm, n10_wb") -++ -++(define_insn_reservation "nds_n10_dsp_mul" 1 -++ (and (eq_attr "type" "dmul") -++ (eq_attr "pipeline_model" "n10")) -++ "n10_ii, n10_ex, n10_mm, n10_wb") -++ -++(define_insn_reservation "nds_n10_dsp_mac" 1 -++ (and (eq_attr "type" "dmac") -++ (eq_attr "pipeline_model" "n10")) -++ "n10_ii, n10_ex, n10_mm, n10_wb") -++ -++(define_insn_reservation "nds_n10_dsp_insb" 1 -++ (and (eq_attr "type" "dinsb") -++ (eq_attr "pipeline_model" "n10")) -++ "n10_ii, n10_ex, n10_mm, n10_wb") -++ -++(define_insn_reservation "nds_n10_dsp_pack" 1 -++ (and (eq_attr "type" "dpack") -++ (eq_attr "pipeline_model" "n10")) -++ "n10_ii, n10_ex, n10_mm, n10_wb") -++ -++(define_insn_reservation "nds_n10_dsp_bpick" 1 -++ (and (eq_attr "type" "dbpick") -++ (eq_attr "pipeline_model" "n10")) -++ "n10_ii, n10_ex, n10_mm, n10_wb") -++ -++(define_insn_reservation "nds_n10_dsp_wext" 1 -++ (and (eq_attr "type" "dwext") -++ (eq_attr "pipeline_model" "n10")) -++ "n10_ii, n10_ex, n10_mm, n10_wb") -++ -++(define_insn_reservation "nds_n10_fpu_alu" 4 -++ (and (eq_attr "type" "falu") -++ (eq_attr "pipeline_model" "n10")) -++ "n10_ii, n10f_iq, n10f_rf, n10f_e1, n10f_e2, n10f_e3, n10f_e4") -++ -++(define_insn_reservation "nds_n10_fpu_muls" 4 -++ (and (eq_attr "type" "fmuls") -++ (eq_attr "pipeline_model" "n10")) -++ "n10_ii, n10f_iq, n10f_rf, n10f_e1, n10f_e2, n10f_e3, n10f_e4") -++ -++(define_insn_reservation "nds_n10_fpu_muld" 4 -++ (and (eq_attr "type" "fmuld") -++ (eq_attr "pipeline_model" "n10")) -++ "n10_ii, n10f_iq, n10f_rf, n10f_e1, n10f_e2*2, n10f_e3, n10f_e4") -++ -++(define_insn_reservation "nds_n10_fpu_macs" 4 -++ (and (eq_attr "type" "fmacs") -++ (eq_attr "pipeline_model" "n10")) -++ "n10_ii, n10f_iq, n10f_rf, n10f_e1, n10f_e2*3, n10f_e3, n10f_e4") -++ -++(define_insn_reservation "nds_n10_fpu_macd" 4 -++ (and (eq_attr "type" "fmacd") -++ (eq_attr "pipeline_model" "n10")) -++ "n10_ii, n10f_iq, n10f_rf, n10f_e1, n10f_e2*4, n10f_e3, n10f_e4") -++ -++(define_insn_reservation "nds_n10_fpu_divs" 4 -++ (and (ior (eq_attr "type" "fdivs") -++ (eq_attr "type" "fsqrts")) -++ (eq_attr "pipeline_model" "n10")) -++ "n10_ii, n10f_iq, n10f_rf, n10f_e1, n10f_e2*14, n10f_e3, n10f_e4") -++ -++(define_insn_reservation "nds_n10_fpu_divd" 4 -++ (and (ior (eq_attr "type" "fdivd") -++ (eq_attr "type" "fsqrtd")) -++ (eq_attr "pipeline_model" "n10")) -++ "n10_ii, n10f_iq, n10f_rf, n10f_e1, n10f_e2*28, n10f_e3, n10f_e4") -++ -++(define_insn_reservation "nds_n10_fpu_fast_alu" 2 -++ (and (ior (eq_attr "type" "fcmp") -++ (ior (eq_attr "type" "fabs") -++ (ior (eq_attr "type" "fcpy") -++ (eq_attr "type" "fcmov")))) -++ (eq_attr "pipeline_model" "n10")) -++ "n10_ii, n10f_iq, n10f_rf, n10f_e1, n10f_e2, n10f_e3, n10f_e4") -++ -++(define_insn_reservation "nds_n10_fpu_fmtsr" 4 -++ (and (eq_attr "type" "fmtsr") -++ (eq_attr "pipeline_model" "n10")) -++ "n10_ii, n10f_iq, n10f_rf, n10f_e1, n10f_e2, n10f_e3, n10f_e4") -++ -++(define_insn_reservation "nds_n10_fpu_fmtdr" 4 -++ (and (eq_attr "type" "fmtdr") -++ (eq_attr "pipeline_model" "n10")) -++ "n10_ii, n10_ii+n10f_iq, n10f_iq+n10f_rf, n10f_rf+n10f_e1, n10f_e1+n10f_e2, n10f_e2+n10f_e3, n10f_e3+n10f_e4, n10f_e4") -++ -++(define_insn_reservation "nds_n10_fpu_fmfsr" 2 -++ (and (eq_attr "type" "fmfsr") -++ (eq_attr "pipeline_model" "n10")) -++ "n10_ii, n10f_iq, n10f_rf, n10f_e1, n10f_e2, n10f_e3, n10f_e4") -++ -++(define_insn_reservation "nds_n10_fpu_fmfdr" 2 -++ (and (eq_attr "type" "fmfdr") -++ (eq_attr "pipeline_model" "n10")) -++ "n10_ii, n10_ii+n10f_iq, n10f_iq+n10f_rf, n10f_rf+n10f_e1, n10f_e1+n10f_e2, n10f_e2+n10f_e3, n10f_e3+n10f_e4, n10f_e4") -++ -++(define_insn_reservation "nds_n10_fpu_load" 3 -++ (and (eq_attr "type" "fload") -++ (eq_attr "pipeline_model" "n10")) -++ "n10_ii, n10f_iq, n10f_rf, n10f_e1, n10f_e2, n10f_e3, n10f_e4") -++ -++(define_insn_reservation "nds_n10_fpu_store" 1 -++ (and (eq_attr "type" "fstore") -++ (eq_attr "pipeline_model" "n10")) -++ "n10_ii, n10f_iq, n10f_rf, n10f_e1, n10f_e2, n10f_e3, n10f_e4") -++ -++;; ------------------------------------------------------------------------ -++;; Comment Notations and Bypass Rules -++;; ------------------------------------------------------------------------ -++;; Producers (LHS) -++;; LD -++;; Load data from the memory and produce the loaded data. The result is -++;; ready at MM. -++;; LMW(N, M) -++;; There are N micro-operations within an instruction that loads multiple -++;; words. The result produced by the M-th micro-operation is sent to -++;; consumers. The result is ready at MM. -++;; MUL, MAC -++;; Compute data in the multiply-adder and produce the data. The result -++;; is ready at MM. -++;; DIV -++;; Compute data in the divider and produce the data. The result is ready -++;; at MM. -++;; -++;; Consumers (RHS) -++;; ALU, MOVD44, PBSAD, PBSADA_RaRb, MUL, MAC, DIV, MMU -++;; Require operands at EX. -++;; ALU_SHIFT_Rb -++;; An ALU-SHIFT instruction consists of a shift micro-operation followed -++;; by an arithmetic micro-operation. The operand Rb is used by the first -++;; micro-operation, and there are some latencies if data dependency occurs. -++;; MAC_RaRb -++;; A MAC instruction does multiplication at EX and does accumulation at MM, -++;; so the operand Rt is required at MM, and operands Ra and Rb are required -++;; at EX. -++;; ADDR_IN -++;; If an instruction requires an address as its input operand, the address -++;; is required at EX. -++;; ST -++;; A store instruction requires its data at MM. -++;; SMW(N, M) -++;; There are N micro-operations within an instruction that stores multiple -++;; words. Each M-th micro-operation requires its data at MM. -++;; BR -++;; If a branch instruction is conditional, its input data is required at EX. -++ -++;; FPU_ADDR_OUT -> FPU_ADDR_IN -++;; Main pipeline rules don't need this because those default latency is 1. -++(define_bypass 1 -++ "nds_n10_fpu_load, nds_n10_fpu_store" -++ "nds_n10_fpu_load, nds_n10_fpu_store" -++ "nds32_n10_ex_to_ex_p" -++) -++ -++;; LD, MUL, MAC, DIV, DALU64, DMUL, DMAC, DALUROUND, DBPICK, DWEXT -++;; -> ALU, ALU_SHIFT_Rb, PBSAD, PBSADA_RaRb, MOVD44, MUL, MAC_RaRb, DIV, ADDR_IN, BR, MMU, -++;; DALU, DALUROUND, DMUL, DMAC_RaRb, DPACK, DINSB, DCMP, DCLIP, WEXT_O, BPICK_RaRb -++(define_bypass 2 -++ "nds_n10_load, nds_n10_mul, nds_n10_mac, nds_n10_div,\ -++ nds_n10_dsp_alu64, nds_n10_dsp_mul, nds_n10_dsp_mac,\ -++ nds_n10_dsp_alu_round, nds_n10_dsp_bpick, nds_n10_dsp_wext" -++ "nds_n10_alu, nds_n10_alu_shift,\ -++ nds_n10_pbsad, nds_n10_pbsada,\ -++ nds_n10_mul, nds_n10_mac, nds_n10_div,\ -++ nds_n10_branch,\ -++ nds_n10_load, nds_n10_store,\ -++ nds_n10_load_multiple_1, nds_n10_load_multiple_2, nds_n10_load_multiple_3,\ -++ nds_n10_load_multiple_4, nds_n10_load_multiple_5, nds_n10_load_multiple_6,\ -++ nds_n10_load_multiple_7, nds_n10_load_multiple_N,\ -++ nds_n10_store_multiple_1, nds_n10_store_multiple_2, nds_n10_store_multiple_3,\ -++ nds_n10_store_multiple_4, nds_n10_store_multiple_5, nds_n10_store_multiple_6,\ -++ nds_n10_store_multiple_7, nds_n10_store_multiple_N,\ -++ nds_n10_mmu,\ -++ nds_n10_dsp_alu, nds_n10_dsp_alu_round,\ -++ nds_n10_dsp_mul, nds_n10_dsp_mac, nds_n10_dsp_pack,\ -++ nds_n10_dsp_insb, nds_n10_dsp_cmp, nds_n10_dsp_clip,\ -++ nds_n10_dsp_wext, nds_n10_dsp_bpick" -++ "nds32_n10_mm_to_ex_p" -++) -++ -++;; LMW(N, N) -++;; -> ALU, ALU_SHIFT_Rb, PBSAD, PBSADA_RaRb, MOVD44, MUL, MAC_RaRb, DIV, ADDR_IN, BR, MMU -++;; DALU, DALUROUND, DMUL, DMAC_RaRb, DPACK, DINSB, DCMP, DCLIP, WEXT_O, BPICK_RaRb -++(define_bypass 2 -++ "nds_n10_load_multiple_1, nds_n10_load_multiple_2, nds_n10_load_multiple_3,\ -++ nds_n10_load_multiple_4, nds_n10_load_multiple_5, nds_n10_load_multiple_6,\ -++ nds_n10_load_multiple_7, nds_n10_load_multiple_N" -++ "nds_n10_alu, nds_n10_alu_shift,\ -++ nds_n10_pbsad, nds_n10_pbsada,\ -++ nds_n10_mul, nds_n10_mac, nds_n10_div,\ -++ nds_n10_branch,\ -++ nds_n10_load, nds_n10_store,\ -++ nds_n10_load_multiple_1, nds_n10_load_multiple_2, nds_n10_load_multiple_3,\ -++ nds_n10_load_multiple_4, nds_n10_load_multiple_5, nds_n10_load_multiple_6,\ -++ nds_n10_load_multiple_7, nds_n10_load_multiple_N,\ -++ nds_n10_store_multiple_1, nds_n10_store_multiple_2, nds_n10_store_multiple_3,\ -++ nds_n10_store_multiple_4, nds_n10_store_multiple_5, nds_n10_store_multiple_6,\ -++ nds_n10_store_multiple_7, nds_n10_store_multiple_N,\ -++ nds_n10_mmu,\ -++ nds_n10_dsp_alu, nds_n10_dsp_alu_round,\ -++ nds_n10_dsp_mul, nds_n10_dsp_mac, nds_n10_dsp_pack,\ -++ nds_n10_dsp_insb, nds_n10_dsp_cmp, nds_n10_dsp_clip,\ -++ nds_n10_dsp_wext, nds_n10_dsp_bpick" -++ "nds32_n10_last_load_to_ex_p" -++) -+diff --git a/gcc/config/nds32/nds32-n13.md b/gcc/config/nds32/nds32-n13.md -+new file mode 100644 -+index 00000000000..ca7546bc2a7 -+--- /dev/null -++++ b/gcc/config/nds32/nds32-n13.md -+@@ -0,0 +1,401 @@ -++;; Pipeline descriptions of Andes NDS32 cpu for GNU compiler -++;; Copyright (C) 2012-2018 Free Software Foundation, Inc. -++;; Contributed by Andes Technology Corporation. -++;; -++;; This file is part of GCC. -++;; -++;; GCC is free software; you can redistribute it and/or modify it -++;; under the terms of the GNU General Public License as published -++;; by the Free Software Foundation; either version 3, or (at your -++;; option) any later version. -++;; -++;; GCC is distributed in the hope that it will be useful, but WITHOUT -++;; ANY WARRANTY; without even the implied warranty of MERCHANTABILITY -++;; or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public -++;; License for more details. -++;; -++;; You should have received a copy of the GNU General Public License -++;; along with GCC; see the file COPYING3. If not see -++;; . -++ -++ -++;; ------------------------------------------------------------------------ -++;; Define N13 pipeline settings. -++;; ------------------------------------------------------------------------ -++ -++(define_automaton "nds32_n13_machine") -++ -++;; ------------------------------------------------------------------------ -++;; Pipeline Stages -++;; ------------------------------------------------------------------------ -++;; F1 - Instruction Fetch First -++;; Instruction Tag/Data Arrays -++;; ITLB Address Translation -++;; Branch Target Buffer Prediction -++;; F2 - Instruction Fetch Second -++;; Instruction Cache Hit Detection -++;; Cache Way Selection -++;; Inustruction Alignment -++;; I1 - Instruction Issue First / Instruction Decode -++;; Instruction Cache Replay Triggering -++;; 32/16-Bit Instruction Decode -++;; Return Address Stack Prediction -++;; I2 - Instruction Issue Second / Register File Access -++;; Instruction Issue Logic -++;; Register File Access -++;; E1 - Instruction Execute First / Address Generation / MAC First -++;; Data Access Address generation -++;; Multiply Operation -++;; E2 - Instruction Execute Second / Data Access First / MAC Second / -++;; ALU Execute -++;; Skewed ALU -++;; Branch/Jump/Return Resolution -++;; Data Tag/Data arrays -++;; DTLB address translation -++;; Accumulation Operation -++;; E3 - Instruction Execute Third / Data Access Second -++;; Data Cache Hit Detection -++;; Cache Way Selection -++;; Data Alignment -++;; E4 - Instruction Execute Fourth / Write Back -++;; Interruption Resolution -++;; Instruction Retire -++;; Register File Write Back -++ -++(define_cpu_unit "n13_i1" "nds32_n13_machine") -++(define_cpu_unit "n13_i2" "nds32_n13_machine") -++(define_cpu_unit "n13_e1" "nds32_n13_machine") -++(define_cpu_unit "n13_e2" "nds32_n13_machine") -++(define_cpu_unit "n13_e3" "nds32_n13_machine") -++(define_cpu_unit "n13_e4" "nds32_n13_machine") -++ -++(define_insn_reservation "nds_n13_unknown" 1 -++ (and (eq_attr "type" "unknown") -++ (eq_attr "pipeline_model" "n13")) -++ "n13_i1, n13_i2, n13_e1, n13_e2, n13_e3, n13_e4") -++ -++(define_insn_reservation "nds_n13_misc" 1 -++ (and (eq_attr "type" "misc") -++ (eq_attr "pipeline_model" "n13")) -++ "n13_i1, n13_i2, n13_e1, n13_e2, n13_e3, n13_e4") -++ -++(define_insn_reservation "nds_n13_mmu" 1 -++ (and (eq_attr "type" "mmu") -++ (eq_attr "pipeline_model" "n13")) -++ "n13_i1, n13_i2, n13_e1, n13_e2, n13_e3, n13_e4") -++ -++(define_insn_reservation "nds_n13_alu" 1 -++ (and (eq_attr "type" "alu") -++ (eq_attr "pipeline_model" "n13")) -++ "n13_i1, n13_i2, n13_e1, n13_e2, n13_e3, n13_e4") -++ -++(define_insn_reservation "nds_n13_alu_shift" 1 -++ (and (eq_attr "type" "alu_shift") -++ (eq_attr "pipeline_model" "n13")) -++ "n13_i1, n13_i1+n13_i2, n13_i2+n13_e1, n13_e1+n13_e2, n13_e2+n13_e3, n13_e3+n13_e4, n13_e4") -++ -++(define_insn_reservation "nds_n13_pbsad" 1 -++ (and (eq_attr "type" "pbsad") -++ (eq_attr "pipeline_model" "n13")) -++ "n13_i1, n13_i2, n13_e1, n13_e2*2, n13_e3, n13_e4") -++ -++(define_insn_reservation "nds_n13_pbsada" 1 -++ (and (eq_attr "type" "pbsada") -++ (eq_attr "pipeline_model" "n13")) -++ "n13_i1, n13_i2, n13_e1, n13_e2*3, n13_e3, n13_e4") -++ -++(define_insn_reservation "nds_n13_load" 1 -++ (and (match_test "nds32::load_single_p (insn)") -++ (eq_attr "pipeline_model" "n13")) -++ "n13_i1, n13_i2, n13_e1, n13_e2, n13_e3, n13_e4") -++ -++(define_insn_reservation "nds_n13_store" 1 -++ (and (match_test "nds32::store_single_p (insn)") -++ (eq_attr "pipeline_model" "n13")) -++ "n13_i1, n13_i2, n13_e1, n13_e2, n13_e3, n13_e4") -++ -++(define_insn_reservation "nds_n13_load_multiple_1" 1 -++ (and (and (eq_attr "type" "load_multiple") -++ (eq_attr "combo" "1")) -++ (eq_attr "pipeline_model" "n13")) -++ "n13_i1, n13_i2, n13_e1, n13_e2, n13_e3, n13_e4") -++ -++(define_insn_reservation "nds_n13_load_multiple_2" 1 -++ (and (ior (and (eq_attr "type" "load_multiple") -++ (eq_attr "combo" "2")) -++ (match_test "nds32::load_double_p (insn)")) -++ (eq_attr "pipeline_model" "n13")) -++ "n13_i1, n13_i1+n13_i2, n13_i2+n13_e1, n13_e1+n13_e2, n13_e2+n13_e3, n13_e3+n13_e4, n13_e4") -++ -++(define_insn_reservation "nds_n13_load_multiple_3" 1 -++ (and (and (eq_attr "type" "load_multiple") -++ (eq_attr "combo" "3")) -++ (eq_attr "pipeline_model" "n13")) -++ "n13_i1, n13_i2+n13_i2, n13_i1+n13_i2+n13_e1, n13_i2+n13_e1+n13_e2, n13_e1+n13_e2+n13_e3, n13_e2+n13_e3+n13_e4, n13_e3+n13_e4, n13_e4") -++ -++(define_insn_reservation "nds_n13_load_multiple_4" 1 -++ (and (and (eq_attr "type" "load_multiple") -++ (eq_attr "combo" "4")) -++ (eq_attr "pipeline_model" "n13")) -++ "n13_i1, n13_i1+n13_i2, n13_i1+n13_i2+n13_e1, n13_i1+n13_i2+n13_e1+n13_e2, n13_i2+n13_e1+n13_e2+n13_e3, n13_e1+n13_e2+n13_e3+n13_e4, n13_e2+n13_e3+n13_e4, n13_e3+n13_e4, n13_e4") -++ -++(define_insn_reservation "nds_n13_load_multiple_5" 1 -++ (and (and (eq_attr "type" "load_multiple") -++ (eq_attr "combo" "5")) -++ (eq_attr "pipeline_model" "n13")) -++ "n13_i1, n13_i1+n13_i2, n13_i1+n13_i2+n13_e1, n13_i1+n13_i2+n13_e1+n13_e2, n13_i1+n13_i2+n13_e1+n13_e2+n13_e3, n13_i2+n13_e1+n13_e2+n13_e3+n13_e4, n13_e1+n13_e2+n13_e3+n13_e4, n13_e2+n13_e3+n13_e4, n13_e3+n13_e4, n13_e4") -++ -++(define_insn_reservation "nds_n13_load_multiple_6" 1 -++ (and (and (eq_attr "type" "load_multiple") -++ (eq_attr "combo" "6")) -++ (eq_attr "pipeline_model" "n13")) -++ "n13_i1, n13_i1+n13_i2, n13_i1+n13_i2+n13_e1, n13_i1+n13_i2+n13_e1+n13_e2, n13_i1+n13_i2+n13_e1+n13_e2+n13_e3, n13_i1+n13_i2+n13_e1+n13_e2+n13_e3+n13_e4, n13_i2+n13_e1+n13_e2+n13_e3+n13_e4, n13_e1+n13_e2+n13_e3+n13_e4, n13_e2+n13_e3+n13_e4, n13_e3+n13_e4, n13_e4") -++ -++(define_insn_reservation "nds_n13_load_multiple_7" 1 -++ (and (and (eq_attr "type" "load_multiple") -++ (eq_attr "combo" "7")) -++ (eq_attr "pipeline_model" "n13")) -++ "n13_i1, n13_i1+n13_i2, n13_i1+n13_i2+n13_e1, n13_i1+n13_i2+n13_e1+n13_e2, n13_i1+n13_i2+n13_e1+n13_e2+n13_e3, (n13_i1+n13_i2+n13_e1+n13_e2+n13_e3+n13_e4)*2, n13_i2+n13_e1+n13_e2+n13_e3+n13_e4, n13_e1+n13_e2+n13_e3+n13_e4, n13_e2+n13_e3+n13_e4, n13_e3+n13_e4, n13_e4") -++ -++(define_insn_reservation "nds_n13_load_multiple_8" 1 -++ (and (and (eq_attr "type" "load_multiple") -++ (eq_attr "combo" "8")) -++ (eq_attr "pipeline_model" "n13")) -++ "n13_i1, n13_i1+n13_i2, n13_i1+n13_i2+n13_e1, n13_i1+n13_i2+n13_e1+n13_e2, n13_i1+n13_i2+n13_e1+n13_e2+n13_e3, (n13_i1+n13_i2+n13_e1+n13_e2+n13_e3+n13_e4)*3, n13_i2+n13_e1+n13_e2+n13_e3+n13_e4, n13_e1+n13_e2+n13_e3+n13_e4, n13_e2+n13_e3+n13_e4, n13_e3+n13_e4, n13_e4") -++ -++(define_insn_reservation "nds_n13_load_multiple_12" 1 -++ (and (and (eq_attr "type" "load_multiple") -++ (eq_attr "combo" "12")) -++ (eq_attr "pipeline_model" "n13")) -++ "n13_i1, n13_i1+n13_i2, n13_i1+n13_i2+n13_e1, n13_i1+n13_i2+n13_e1+n13_e2, n13_i1+n13_i2+n13_e1+n13_e2+n13_e3, (n13_i1+n13_i2+n13_e1+n13_e2+n13_e3+n13_e4)*7, n13_i2+n13_e1+n13_e2+n13_e3+n13_e4, n13_e1+n13_e2+n13_e3+n13_e4, n13_e2+n13_e3+n13_e4, n13_e3+n13_e4, n13_e4") -++ -++(define_insn_reservation "nds_n13_store_multiple_1" 1 -++ (and (and (eq_attr "type" "store_multiple") -++ (eq_attr "combo" "1")) -++ (eq_attr "pipeline_model" "n13")) -++ "n13_i1, n13_i2, n13_e1, n13_e2, n13_e3, n13_e4") -++ -++(define_insn_reservation "nds_n13_store_multiple_2" 1 -++ (and (ior (and (eq_attr "type" "store_multiple") -++ (eq_attr "combo" "2")) -++ (match_test "nds32::store_double_p (insn)")) -++ (eq_attr "pipeline_model" "n13")) -++ "n13_i1, n13_i1+n13_i2, n13_i2+n13_e1, n13_e1+n13_e2, n13_e2+n13_e3, n13_e3+n13_e4, n13_e4") -++ -++(define_insn_reservation "nds_n13_store_multiple_3" 1 -++ (and (and (eq_attr "type" "store_multiple") -++ (eq_attr "combo" "3")) -++ (eq_attr "pipeline_model" "n13")) -++ "n13_i1, n13_i2+n13_i2, n13_i1+n13_i2+n13_e1, n13_i2+n13_e1+n13_e2, n13_e1+n13_e2+n13_e3, n13_e2+n13_e3+n13_e4, n13_e3+n13_e4, n13_e4") -++ -++(define_insn_reservation "nds_n13_store_multiple_4" 1 -++ (and (and (eq_attr "type" "store_multiple") -++ (eq_attr "combo" "4")) -++ (eq_attr "pipeline_model" "n13")) -++ "n13_i1, n13_i1+n13_i2, n13_i1+n13_i2+n13_e1, n13_i1+n13_i2+n13_e1+n13_e2, n13_i2+n13_e1+n13_e2+n13_e3, n13_e1+n13_e2+n13_e3+n13_e4, n13_e2+n13_e3+n13_e4, n13_e3+n13_e4, n13_e4") -++ -++(define_insn_reservation "nds_n13_store_multiple_5" 1 -++ (and (and (eq_attr "type" "store_multiple") -++ (eq_attr "combo" "5")) -++ (eq_attr "pipeline_model" "n13")) -++ "n13_i1, n13_i1+n13_i2, n13_i1+n13_i2+n13_e1, n13_i1+n13_i2+n13_e1+n13_e2, n13_i1+n13_i2+n13_e1+n13_e2+n13_e3, n13_i2+n13_e1+n13_e2+n13_e3+n13_e4, n13_e1+n13_e2+n13_e3+n13_e4, n13_e2+n13_e3+n13_e4, n13_e3+n13_e4, n13_e4") -++ -++(define_insn_reservation "nds_n13_store_multiple_6" 1 -++ (and (and (eq_attr "type" "store_multiple") -++ (eq_attr "combo" "6")) -++ (eq_attr "pipeline_model" "n13")) -++ "n13_i1, n13_i1+n13_i2, n13_i1+n13_i2+n13_e1, n13_i1+n13_i2+n13_e1+n13_e2, n13_i1+n13_i2+n13_e1+n13_e2+n13_e3, n13_i1+n13_i2+n13_e1+n13_e2+n13_e3+n13_e4, n13_i2+n13_e1+n13_e2+n13_e3+n13_e4, n13_e1+n13_e2+n13_e3+n13_e4, n13_e2+n13_e3+n13_e4, n13_e3+n13_e4, n13_e4") -++ -++(define_insn_reservation "nds_n13_store_multiple_7" 1 -++ (and (and (eq_attr "type" "store_multiple") -++ (eq_attr "combo" "7")) -++ (eq_attr "pipeline_model" "n13")) -++ "n13_i1, n13_i1+n13_i2, n13_i1+n13_i2+n13_e1, n13_i1+n13_i2+n13_e1+n13_e2, n13_i1+n13_i2+n13_e1+n13_e2+n13_e3, (n13_i1+n13_i2+n13_e1+n13_e2+n13_e3+n13_e4)*2, n13_i2+n13_e1+n13_e2+n13_e3+n13_e4, n13_e1+n13_e2+n13_e3+n13_e4, n13_e2+n13_e3+n13_e4, n13_e3+n13_e4, n13_e4") -++ -++(define_insn_reservation "nds_n13_store_multiple_8" 1 -++ (and (and (eq_attr "type" "store_multiple") -++ (eq_attr "combo" "8")) -++ (eq_attr "pipeline_model" "n13")) -++ "n13_i1, n13_i1+n13_i2, n13_i1+n13_i2+n13_e1, n13_i1+n13_i2+n13_e1+n13_e2, n13_i1+n13_i2+n13_e1+n13_e2+n13_e3, (n13_i1+n13_i2+n13_e1+n13_e2+n13_e3+n13_e4)*3, n13_i2+n13_e1+n13_e2+n13_e3+n13_e4, n13_e1+n13_e2+n13_e3+n13_e4, n13_e2+n13_e3+n13_e4, n13_e3+n13_e4, n13_e4") -++ -++(define_insn_reservation "nds_n13_store_multiple_12" 1 -++ (and (and (eq_attr "type" "store_multiple") -++ (eq_attr "combo" "12")) -++ (eq_attr "pipeline_model" "n13")) -++ "n13_i1, n13_i1+n13_i2, n13_i1+n13_i2+n13_e1, n13_i1+n13_i2+n13_e1+n13_e2, n13_i1+n13_i2+n13_e1+n13_e2+n13_e3, (n13_i1+n13_i2+n13_e1+n13_e2+n13_e3+n13_e4)*7, n13_i2+n13_e1+n13_e2+n13_e3+n13_e4, n13_e1+n13_e2+n13_e3+n13_e4, n13_e2+n13_e3+n13_e4, n13_e3+n13_e4, n13_e4") -++ -++;; The multiplier at E1 takes two cycles. -++(define_insn_reservation "nds_n13_mul" 1 -++ (and (eq_attr "type" "mul") -++ (eq_attr "pipeline_model" "n13")) -++ "n13_i1, n13_i2, n13_e1*2, n13_e2, n13_e3, n13_e4") -++ -++(define_insn_reservation "nds_n13_mac" 1 -++ (and (eq_attr "type" "mac") -++ (eq_attr "pipeline_model" "n13")) -++ "n13_i1, n13_i2, n13_e1*2, n13_e2, n13_e3, n13_e4") -++ -++;; The cycles consumed at E2 are 32 - CLZ(abs(Ra)) + 2, -++;; so the worst case is 34. -++(define_insn_reservation "nds_n13_div" 1 -++ (and (eq_attr "type" "div") -++ (eq_attr "pipeline_model" "n13")) -++ "n13_i1, n13_i2, n13_e1, n13_e2*34, n13_e3, n13_e4") -++ -++(define_insn_reservation "nds_n13_branch" 1 -++ (and (eq_attr "type" "branch") -++ (eq_attr "pipeline_model" "n13")) -++ "n13_i1, n13_i2, n13_e1, n13_e2, n13_e3, n13_e4") -++ -++;; ------------------------------------------------------------------------ -++;; Comment Notations and Bypass Rules -++;; ------------------------------------------------------------------------ -++;; Producers (LHS) -++;; LD -++;; Load data from the memory and produce the loaded data. The result is -++;; ready at E3. -++;; LMW(N, M) -++;; There are N micro-operations within an instruction that loads multiple -++;; words. The result produced by the M-th micro-operation is sent to -++;; consumers. The result is ready at E3. -++;; ADDR_OUT -++;; Most load/store instructions can produce an address output if updating -++;; the base register is required. The result is ready at E2, which is -++;; produced by ALU. -++;; ALU, ALU_SHIFT, SIMD -++;; Compute data in ALU and produce the data. The result is ready at E2. -++;; MUL, MAC -++;; Compute data in the multiply-adder and produce the data. The result -++;; is ready at E2. -++;; DIV -++;; Compute data in the divider and produce the data. The result is ready -++;; at E2. -++;; BR -++;; Branch-with-link instructions produces a result containing the return -++;; address. The result is ready at E2. -++;; -++;; Consumers (RHS) -++;; ALU -++;; General ALU instructions require operands at E2. -++;; ALU_E1 -++;; Some special ALU instructions, such as BSE, BSP and MOVD44, require -++;; operand at E1. -++;; MUL, DIV, PBSAD, MMU -++;; Operands are required at E1. -++;; PBSADA_Rt, PBSADA_RaRb -++;; Operands Ra and Rb are required at E1, and the operand Rt is required -++;; at E2. -++;; ALU_SHIFT_Rb -++;; An ALU-SHIFT instruction consists of a shift micro-operation followed -++;; by an arithmetic micro-operation. The operand Rb is used by the first -++;; micro-operation, and there are some latencies if data dependency occurs. -++;; MAC_RaRb -++;; A MAC instruction does multiplication at E1 and does accumulation at E2, -++;; so the operand Rt is required at E2, and operands Ra and Rb are required -++;; at E1. -++;; ADDR_IN -++;; If an instruction requires an address as its input operand, the address -++;; is required at E1. -++;; ST -++;; A store instruction requires its data at E2. -++;; SMW(N, M) -++;; There are N micro-operations within an instruction that stores multiple -++;; words. Each M-th micro-operation requires its data at E2. -++;; BR -++;; If a branch instruction is conditional, its input data is required at E2. -++ -++;; LD -> ALU_E1, PBSAD, PBSADA_RaRb, MUL, MAC_RaRb, DIV, MMU, ADDR_IN -++(define_bypass 3 -++ "nds_n13_load" -++ "nds_n13_alu, nds_n13_pbsad, nds_n13_pbsada,\ -++ nds_n13_mul, nds_n13_mac, nds_n13_div,\ -++ nds_n13_mmu,\ -++ nds_n13_load, nds_n13_store,\ -++ nds_n13_load_multiple_1,nds_n13_load_multiple_2, nds_n13_load_multiple_3,\ -++ nds_n13_load_multiple_4,nds_n13_load_multiple_5, nds_n13_load_multiple_6,\ -++ nds_n13_load_multiple_7,nds_n13_load_multiple_8, nds_n13_load_multiple_12,\ -++ nds_n13_store_multiple_1,nds_n13_store_multiple_2, nds_n13_store_multiple_3,\ -++ nds_n13_store_multiple_4,nds_n13_store_multiple_5, nds_n13_store_multiple_6,\ -++ nds_n13_store_multiple_7,nds_n13_store_multiple_8, nds_n13_store_multiple_12" -++ "nds32_n13_load_to_e1_p" -++) -++ -++;; LD -> ALU, ALU_SHIFT_Rb, PBSADA_Rt, BR, ST, SMW(N, 1) -++(define_bypass 2 -++ "nds_n13_load" -++ "nds_n13_alu, nds_n13_alu_shift, nds_n13_pbsada, nds_n13_branch, nds_n13_store,\ -++ nds_n13_store_multiple_1,nds_n13_store_multiple_2, nds_n13_store_multiple_3,\ -++ nds_n13_store_multiple_4,nds_n13_store_multiple_5, nds_n13_store_multiple_6,\ -++ nds_n13_store_multiple_7,nds_n13_store_multiple_8, nds_n13_store_multiple_12" -++ "nds32_n13_load_to_e2_p" -++) -++ -++;; LMW(N, N) -> ALU_E1, PBSAD, PBSADA_RaRb, MUL, MAC_RaRb, DIV, MMU, ADDR_IN -++(define_bypass 3 -++ "nds_n13_load_multiple_1,nds_n13_load_multiple_2, nds_n13_load_multiple_3,\ -++ nds_n13_load_multiple_4,nds_n13_load_multiple_5, nds_n13_load_multiple_6,\ -++ nds_n13_load_multiple_7,nds_n13_load_multiple_8, nds_n13_load_multiple_12" -++ "nds_n13_alu, nds_n13_pbsad, nds_n13_pbsada,\ -++ nds_n13_mul, nds_n13_mac, nds_n13_div,\ -++ nds_n13_mmu,\ -++ nds_n13_load, nds_n13_store,\ -++ nds_n13_load_multiple_1,nds_n13_load_multiple_2, nds_n13_load_multiple_3,\ -++ nds_n13_load_multiple_4,nds_n13_load_multiple_5, nds_n13_load_multiple_6,\ -++ nds_n13_load_multiple_7,nds_n13_load_multiple_8, nds_n13_load_multiple_12,\ -++ nds_n13_store_multiple_1,nds_n13_store_multiple_2, nds_n13_store_multiple_3,\ -++ nds_n13_store_multiple_4,nds_n13_store_multiple_5, nds_n13_store_multiple_6,\ -++ nds_n13_store_multiple_7,nds_n13_store_multiple_8, nds_n13_store_multiple_12" -++ "nds32_n13_last_load_to_e1_p") -++ -++;; LMW(N, N) -> ALU, ALU_SHIFT_Rb, PBSADA_Rt, BR, ST, SMW(N, 1) -++(define_bypass 2 -++ "nds_n13_load_multiple_1,nds_n13_load_multiple_2, nds_n13_load_multiple_3,\ -++ nds_n13_load_multiple_4,nds_n13_load_multiple_5, nds_n13_load_multiple_6,\ -++ nds_n13_load_multiple_7,nds_n13_load_multiple_8, nds_n13_load_multiple_12" -++ "nds_n13_alu, nds_n13_alu_shift, nds_n13_pbsada, nds_n13_branch, nds_n13_store,\ -++ nds_n13_store_multiple_1,nds_n13_store_multiple_2, nds_n13_store_multiple_3,\ -++ nds_n13_store_multiple_4,nds_n13_store_multiple_5, nds_n13_store_multiple_6,\ -++ nds_n13_store_multiple_7,nds_n13_store_multiple_8, nds_n13_store_multiple_12" -++ "nds32_n13_last_load_to_e2_p" -++) -++ -++;; LMW(N, N - 1) -> ALU_E1, PBSAD, PBSADA_RaRb, MUL, MAC_RaRb, DIV, MMU, ADDR_IN -++(define_bypass 2 -++ "nds_n13_load_multiple_1,nds_n13_load_multiple_2, nds_n13_load_multiple_3,\ -++ nds_n13_load_multiple_4,nds_n13_load_multiple_5, nds_n13_load_multiple_6,\ -++ nds_n13_load_multiple_7,nds_n13_load_multiple_8, nds_n13_load_multiple_12" -++ "nds_n13_alu, nds_n13_pbsad, nds_n13_pbsada,\ -++ nds_n13_mul, nds_n13_mac, nds_n13_div,\ -++ nds_n13_mmu,\ -++ nds_n13_load, nds_n13_store,\ -++ nds_n13_load_multiple_1,nds_n13_load_multiple_2, nds_n13_load_multiple_3,\ -++ nds_n13_load_multiple_4,nds_n13_load_multiple_5, nds_n13_load_multiple_6,\ -++ nds_n13_load_multiple_7,nds_n13_load_multiple_8, nds_n13_load_multiple_12,\ -++ nds_n13_store_multiple_1,nds_n13_store_multiple_2, nds_n13_store_multiple_3,\ -++ nds_n13_store_multiple_4,nds_n13_store_multiple_5, nds_n13_store_multiple_6,\ -++ nds_n13_store_multiple_7,nds_n13_store_multiple_8, nds_n13_store_multiple_12" -++ "nds32_n13_last_two_load_to_e1_p") -++ -++;; ALU, ALU_SHIFT, SIMD, BR, MUL, MAC, DIV, ADDR_OUT -++;; -> ALU_E1, PBSAD, PBSADA_RaRb, MUL, MAC_RaRb, DIV, MMU, ADDR_IN -++(define_bypass 2 -++ "nds_n13_alu, nds_n13_alu_shift, nds_n13_pbsad, nds_n13_pbsada, nds_n13_branch,\ -++ nds_n13_mul, nds_n13_mac, nds_n13_div,\ -++ nds_n13_load, nds_n13_store,\ -++ nds_n13_load_multiple_1,nds_n13_load_multiple_2, nds_n13_load_multiple_3,\ -++ nds_n13_load_multiple_4,nds_n13_load_multiple_5, nds_n13_load_multiple_6,\ -++ nds_n13_load_multiple_7,nds_n13_load_multiple_8, nds_n13_load_multiple_12,\ -++ nds_n13_store_multiple_1,nds_n13_store_multiple_2, nds_n13_store_multiple_3,\ -++ nds_n13_store_multiple_4,nds_n13_store_multiple_5, nds_n13_store_multiple_6,\ -++ nds_n13_store_multiple_7,nds_n13_store_multiple_8, nds_n13_store_multiple_12" -++ "nds_n13_alu, nds_n13_pbsad, nds_n13_pbsada,\ -++ nds_n13_mul, nds_n13_mac, nds_n13_div,\ -++ nds_n13_mmu,\ -++ nds_n13_load, nds_n13_store,\ -++ nds_n13_load_multiple_1,nds_n13_load_multiple_2, nds_n13_load_multiple_3,\ -++ nds_n13_load_multiple_4,nds_n13_load_multiple_5, nds_n13_load_multiple_6,\ -++ nds_n13_load_multiple_7,nds_n13_load_multiple_8, nds_n13_load_multiple_12,\ -++ nds_n13_store_multiple_1,nds_n13_store_multiple_2, nds_n13_store_multiple_3,\ -++ nds_n13_store_multiple_4,nds_n13_store_multiple_5, nds_n13_store_multiple_6,\ -++ nds_n13_store_multiple_7,nds_n13_store_multiple_8, nds_n13_store_multiple_12" -++ "nds32_n13_e2_to_e1_p") -+diff --git a/gcc/config/nds32/nds32-opts.h b/gcc/config/nds32/nds32-opts.h -+index 5d7e1652749..8d761964439 100644 -+--- a/gcc/config/nds32/nds32-opts.h -++++ b/gcc/config/nds32/nds32-opts.h -+@@ -29,6 +29,7 @@ enum nds32_arch_type -+ { -+ ARCH_V2, -+ ARCH_V3, -++ ARCH_V3J, -+ ARCH_V3M, -+ ARCH_V3F, -+ ARCH_V3S -+@@ -42,6 +43,10 @@ enum nds32_cpu_type -+ CPU_N8, -+ CPU_E8, -+ CPU_N9, -++ CPU_N10, -++ CPU_GRAYWOLF, -++ CPU_N12, -++ CPU_N13, -+ CPU_SIMPLE -+ }; -+ -+@@ -53,6 +58,13 @@ enum nds32_cmodel_type -+ CMODEL_LARGE -+ }; -+ -++/* The code model defines the address generation strategy. */ -++enum nds32_ict_model_type -++{ -++ ICT_MODEL_SMALL, -++ ICT_MODEL_LARGE -++}; -++ -+ /* Multiply instruction configuration. */ -+ enum nds32_mul_type -+ { -+diff --git a/gcc/config/nds32/nds32-peephole2.md b/gcc/config/nds32/nds32-peephole2.md -+index a5e77b1dcc7..033f62bae5a 100644 -+--- a/gcc/config/nds32/nds32-peephole2.md -++++ b/gcc/config/nds32/nds32-peephole2.md -+@@ -22,3 +22,139 @@ -+ ;; Use define_peephole2 to handle possible target-specific optimization. -+ -+ ;; ------------------------------------------------------------------------ -++;; Try to utilize 16-bit instruction by swap operand if possible. -++;; ------------------------------------------------------------------------ -++ -++;; Try to make add as add45. -++(define_peephole2 -++ [(set (match_operand:QIHISI 0 "register_operand" "") -++ (plus:QIHISI (match_operand:QIHISI 1 "register_operand" "") -++ (match_operand:QIHISI 2 "register_operand" "")))] -++ "reload_completed -++ && TARGET_16_BIT -++ && REGNO (operands[0]) == REGNO (operands[2]) -++ && REGNO (operands[0]) != REGNO (operands[1]) -++ && TEST_HARD_REG_BIT (reg_class_contents[MIDDLE_REGS], REGNO (operands[0]))" -++ [(set (match_dup 0) (plus:QIHISI (match_dup 2) (match_dup 1)))]) -++ -++;; Try to make xor/ior/and/mult as xor33/ior33/and33/mult33. -++(define_peephole2 -++ [(set (match_operand:SI 0 "register_operand" "") -++ (match_operator:SI 1 "nds32_have_33_inst_operator" -++ [(match_operand:SI 2 "register_operand" "") -++ (match_operand:SI 3 "register_operand" "")]))] -++ "reload_completed -++ && TARGET_16_BIT -++ && REGNO (operands[0]) == REGNO (operands[3]) -++ && REGNO (operands[0]) != REGNO (operands[2]) -++ && TEST_HARD_REG_BIT (reg_class_contents[LOW_REGS], REGNO (operands[0])) -++ && TEST_HARD_REG_BIT (reg_class_contents[LOW_REGS], REGNO (operands[2]))" -++ [(set (match_dup 0) (match_op_dup 1 [(match_dup 3) (match_dup 2)]))]) -++ -++(define_peephole -++ [(set (match_operand:SI 0 "register_operand" "") -++ (match_operand:SI 1 "register_operand" "")) -++ (set (match_operand:SI 2 "register_operand" "") -++ (match_operand:SI 3 "register_operand" ""))] -++ "TARGET_16_BIT -++ && !TARGET_ISA_V2 -++ && NDS32_IS_GPR_REGNUM (REGNO (operands[0])) -++ && NDS32_IS_GPR_REGNUM (REGNO (operands[1])) -++ && ((REGNO (operands[0]) & 0x1) == 0) -++ && ((REGNO (operands[1]) & 0x1) == 0) -++ && (REGNO (operands[0]) + 1) == REGNO (operands[2]) -++ && (REGNO (operands[1]) + 1) == REGNO (operands[3])" -++ "movd44\t%0, %1" -++ [(set_attr "type" "alu") -++ (set_attr "length" "2")]) -++ -++;; Merge two fcpyss to fcpysd. -++(define_peephole2 -++ [(set (match_operand:SF 0 "float_even_register_operand" "") -++ (match_operand:SF 1 "float_even_register_operand" "")) -++ (set (match_operand:SF 2 "float_odd_register_operand" "") -++ (match_operand:SF 3 "float_odd_register_operand" ""))] -++ "(TARGET_FPU_SINGLE || TARGET_FPU_DOUBLE) -++ && REGNO (operands[0]) == REGNO (operands[2]) - 1 -++ && REGNO (operands[1]) == REGNO (operands[3]) - 1" -++ [(set (match_dup 4) (match_dup 5))] -++ { -++ operands[4] = gen_rtx_REG (DFmode, REGNO (operands[0])); -++ operands[5] = gen_rtx_REG (DFmode, REGNO (operands[1])); -++ }) -++ -++(define_peephole2 -++ [(set (match_operand:SF 0 "float_odd_register_operand" "") -++ (match_operand:SF 1 "float_odd_register_operand" "")) -++ (set (match_operand:SF 2 "float_even_register_operand" "") -++ (match_operand:SF 3 "float_even_register_operand" ""))] -++ "(TARGET_FPU_SINGLE || TARGET_FPU_DOUBLE) -++ && REGNO (operands[2]) == REGNO (operands[0]) - 1 -++ && REGNO (operands[3]) == REGNO (operands[1]) - 1" -++ [(set (match_dup 4) (match_dup 5))] -++ { -++ operands[4] = gen_rtx_REG (DFmode, REGNO (operands[2])); -++ operands[5] = gen_rtx_REG (DFmode, REGNO (operands[3])); -++ }) -++ -++;; ------------------------------------------------------------------------ -++;; GCC will prefer [u]divmodsi3 rather than [u]divsi3 even remainder is -++;; unused, so we use split to drop mod operation for lower register pressure. -++ -++(define_split -++ [(set (match_operand:SI 0 "register_operand") -++ (div:SI (match_operand:SI 1 "register_operand") -++ (match_operand:SI 2 "register_operand"))) -++ (set (match_operand:SI 3 "register_operand") -++ (mod:SI (match_dup 1) (match_dup 2)))] -++ "find_regno_note (insn, REG_UNUSED, REGNO (operands[3])) != NULL -++ && can_create_pseudo_p ()" -++ [(set (match_dup 0) -++ (div:SI (match_dup 1) -++ (match_dup 2)))]) -++ -++(define_split -++ [(set (match_operand:SI 0 "register_operand") -++ (udiv:SI (match_operand:SI 1 "register_operand") -++ (match_operand:SI 2 "register_operand"))) -++ (set (match_operand:SI 3 "register_operand") -++ (umod:SI (match_dup 1) (match_dup 2)))] -++ "find_regno_note (insn, REG_UNUSED, REGNO (operands[3])) != NULL -++ && can_create_pseudo_p ()" -++ [(set (match_dup 0) -++ (udiv:SI (match_dup 1) -++ (match_dup 2)))]) -++ -++(define_peephole2 -++ [(set (match_operand:DI 0 "register_operand") -++ (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand")) -++ (sign_extend:DI (match_operand:SI 2 "register_operand"))))] -++ "NDS32_EXT_DSP_P () -++ && peep2_regno_dead_p (1, WORDS_BIG_ENDIAN ? REGNO (operands[0]) + 1 : REGNO (operands[0]))" -++ [(const_int 1)] -++{ -++ rtx highpart = nds32_di_high_part_subreg (operands[0]); -++ emit_insn (gen_smulsi3_highpart (highpart, operands[1], operands[2])); -++ DONE; -++}) -++ -++(define_split -++ [(set (match_operand:DI 0 "nds32_general_register_operand" "") -++ (match_operand:DI 1 "nds32_general_register_operand" ""))] -++ "find_regno_note (insn, REG_UNUSED, REGNO (operands[0])) != NULL -++ || find_regno_note (insn, REG_UNUSED, REGNO (operands[0]) + 1) != NULL" -++ [(set (match_dup 0) (match_dup 1))] -++{ -++ rtx dead_note = find_regno_note (curr_insn, REG_UNUSED, REGNO (operands[0])); -++ HOST_WIDE_INT offset; -++ if (dead_note == NULL_RTX) -++ offset = 0; -++ else -++ offset = 4; -++ operands[0] = simplify_gen_subreg ( -++ SImode, operands[0], -++ DImode, offset); -++ operands[1] = simplify_gen_subreg ( -++ SImode, operands[1], -++ DImode, offset); -++}) -+diff --git a/gcc/config/nds32/nds32-pipelines-auxiliary.c b/gcc/config/nds32/nds32-pipelines-auxiliary.c -+index a983238cdbb..53619d22510 100644 -+--- a/gcc/config/nds32/nds32-pipelines-auxiliary.c -++++ b/gcc/config/nds32/nds32-pipelines-auxiliary.c -+@@ -306,6 +306,19 @@ pbsada_insn_ra_rb_dep_reg_p (rtx pbsada_insn, rtx def_reg) -+ return false; -+ } -+ -++/* Determine if the latency is occured when the consumer PBSADA_INSN uses the -++ value of DEF_REG in its Rt field. */ -++bool -++pbsada_insn_rt_dep_reg_p (rtx pbsada_insn, rtx def_reg) -++{ -++ rtx pbsada_rt = SET_DEST (PATTERN (pbsada_insn)); -++ -++ if (rtx_equal_p (def_reg, pbsada_rt)) -++ return true; -++ -++ return false; -++} -++ -+ /* Check if INSN is a movd44 insn consuming DEF_REG. */ -+ bool -+ movd44_even_dep_p (rtx_insn *insn, rtx def_reg) -+@@ -335,6 +348,103 @@ movd44_even_dep_p (rtx_insn *insn, rtx def_reg) -+ return false; -+ } -+ -++/* Check if INSN is a wext insn consuming DEF_REG. */ -++bool -++wext_odd_dep_p (rtx insn, rtx def_reg) -++{ -++ rtx shift_rtx = XEXP (SET_SRC (PATTERN (insn)), 0); -++ rtx use_reg = XEXP (shift_rtx, 0); -++ rtx pos_rtx = XEXP (shift_rtx, 1); -++ -++ if (REG_P (pos_rtx) && reg_overlap_p (def_reg, pos_rtx)) -++ return true; -++ -++ if (GET_MODE (def_reg) == DImode) -++ return reg_overlap_p (def_reg, use_reg); -++ -++ gcc_assert (REG_P (def_reg) || GET_CODE (def_reg) == SUBREG); -++ gcc_assert (REG_P (use_reg)); -++ -++ if (REG_P (def_reg)) -++ { -++ if (!TARGET_BIG_ENDIAN) -++ return REGNO (def_reg) == REGNO (use_reg) + 1; -++ else -++ return REGNO (def_reg) == REGNO (use_reg); -++ } -++ -++ if (GET_CODE (def_reg) == SUBREG) -++ { -++ if (!reg_overlap_p (def_reg, use_reg)) -++ return false; -++ -++ if (!TARGET_BIG_ENDIAN) -++ return SUBREG_BYTE (def_reg) == 4; -++ else -++ return SUBREG_BYTE (def_reg) == 0; -++ } -++ -++ return false; -++} -++ -++/* Check if INSN is a bpick insn consuming DEF_REG. */ -++bool -++bpick_ra_rb_dep_p (rtx insn, rtx def_reg) -++{ -++ rtx ior_rtx = SET_SRC (PATTERN (insn)); -++ rtx and1_rtx = XEXP (ior_rtx, 0); -++ rtx and2_rtx = XEXP (ior_rtx, 1); -++ rtx reg1_0 = XEXP (and1_rtx, 0); -++ rtx reg1_1 = XEXP (and1_rtx, 1); -++ rtx reg2_0 = XEXP (and2_rtx, 0); -++ rtx reg2_1 = XEXP (and2_rtx, 1); -++ -++ if (GET_CODE (reg1_0) == NOT) -++ { -++ if (rtx_equal_p (reg1_0, reg2_0)) -++ return reg_overlap_p (def_reg, reg1_1) -++ || reg_overlap_p (def_reg, reg2_1); -++ -++ if (rtx_equal_p (reg1_0, reg2_1)) -++ return reg_overlap_p (def_reg, reg1_1) -++ || reg_overlap_p (def_reg, reg2_0); -++ } -++ -++ if (GET_CODE (reg1_1) == NOT) -++ { -++ if (rtx_equal_p (reg1_1, reg2_0)) -++ return reg_overlap_p (def_reg, reg1_0) -++ || reg_overlap_p (def_reg, reg2_1); -++ -++ if (rtx_equal_p (reg1_1, reg2_1)) -++ return reg_overlap_p (def_reg, reg1_0) -++ || reg_overlap_p (def_reg, reg2_0); -++ } -++ -++ if (GET_CODE (reg2_0) == NOT) -++ { -++ if (rtx_equal_p (reg2_0, reg1_0)) -++ return reg_overlap_p (def_reg, reg2_1) -++ || reg_overlap_p (def_reg, reg1_1); -++ -++ if (rtx_equal_p (reg2_0, reg1_1)) -++ return reg_overlap_p (def_reg, reg2_1) -++ || reg_overlap_p (def_reg, reg1_0); -++ } -++ -++ if (GET_CODE (reg2_1) == NOT) -++ { -++ if (rtx_equal_p (reg2_1, reg1_0)) -++ return reg_overlap_p (def_reg, reg2_0) -++ || reg_overlap_p (def_reg, reg1_1); -++ -++ if (rtx_equal_p (reg2_1, reg1_1)) -++ return reg_overlap_p (def_reg, reg2_0) -++ || reg_overlap_p (def_reg, reg1_0); -++ } -++ -++ gcc_unreachable (); -++} -+ } // namespace scheduling -+ } // namespace nds32 -+ -+@@ -375,8 +485,7 @@ n7_consumed_by_ii_dep_p (rtx_insn *consumer, rtx def_reg) -+ operations in order to write two registers. We have to check the -+ dependency from the producer to the first micro-operation. */ -+ case TYPE_DIV: -+- if (INSN_CODE (consumer) == CODE_FOR_divmodsi4 -+- || INSN_CODE (consumer) == CODE_FOR_udivmodsi4) -++ if (divmod_p (consumer)) -+ use_rtx = SET_SRC (parallel_element (consumer, 0)); -+ else -+ use_rtx = SET_SRC (PATTERN (consumer)); -+@@ -506,8 +615,7 @@ n8_consumed_by_ex_p (rtx_insn *consumer, rtx def_reg) -+ operations in order to write two registers. We have to check the -+ dependency from the producer to the first micro-operation. */ -+ case TYPE_DIV: -+- if (INSN_CODE (consumer) == CODE_FOR_divmodsi4 -+- || INSN_CODE (consumer) == CODE_FOR_udivmodsi4) -++ if (divmod_p (consumer)) -+ use_rtx = SET_SRC (parallel_element (consumer, 0)); -+ else -+ use_rtx = SET_SRC (PATTERN (consumer)); -+@@ -606,8 +714,7 @@ n9_2r1w_consumed_by_ex_dep_p (rtx_insn *consumer, rtx def_reg) -+ break; -+ -+ case TYPE_DIV: -+- if (INSN_CODE (consumer) == CODE_FOR_divmodsi4 -+- || INSN_CODE (consumer) == CODE_FOR_udivmodsi4) -++ if (divmod_p (consumer)) -+ use_rtx = SET_SRC (parallel_element (consumer, 0)); -+ else -+ use_rtx = SET_SRC (PATTERN (consumer)); -+@@ -706,8 +813,7 @@ n9_3r2w_consumed_by_ex_dep_p (rtx_insn *consumer, rtx def_reg) -+ We have to check the dependency from the producer to the first -+ micro-operation. */ -+ case TYPE_DIV: -+- if (INSN_CODE (consumer) == CODE_FOR_divmodsi4 -+- || INSN_CODE (consumer) == CODE_FOR_udivmodsi4) -++ if (divmod_p (consumer)) -+ use_rtx = SET_SRC (parallel_element (consumer, 0)); -+ else -+ use_rtx = SET_SRC (PATTERN (consumer)); -+@@ -744,7 +850,316 @@ n9_3r2w_consumed_by_ex_dep_p (rtx_insn *consumer, rtx def_reg) -+ return false; -+ } -+ -++/* Check the dependency between the producer defining DEF_REG and CONSUMER -++ requiring input operand at EX. */ -++bool -++n10_consumed_by_ex_dep_p (rtx_insn *consumer, rtx def_reg) -++{ -++ rtx use_rtx; -++ -++ switch (get_attr_type (consumer)) -++ { -++ case TYPE_ALU: -++ case TYPE_PBSAD: -++ case TYPE_MUL: -++ case TYPE_DALU: -++ case TYPE_DALU64: -++ case TYPE_DMUL: -++ case TYPE_DPACK: -++ case TYPE_DINSB: -++ case TYPE_DCMP: -++ case TYPE_DCLIP: -++ case TYPE_DALUROUND: -++ use_rtx = SET_SRC (PATTERN (consumer)); -++ break; -++ -++ case TYPE_ALU_SHIFT: -++ use_rtx = extract_shift_reg (consumer); -++ break; -++ -++ case TYPE_PBSADA: -++ return pbsada_insn_ra_rb_dep_reg_p (consumer, def_reg); -++ -++ case TYPE_MAC: -++ case TYPE_DMAC: -++ use_rtx = extract_mac_non_acc_rtx (consumer); -++ break; -++ -++ /* Some special instructions, divmodsi4 and udivmodsi4, produce two -++ results, the quotient and the remainder. */ -++ case TYPE_DIV: -++ if (divmod_p (consumer)) -++ use_rtx = SET_SRC (parallel_element (consumer, 0)); -++ else -++ use_rtx = SET_SRC (PATTERN (consumer)); -++ break; -++ -++ case TYPE_DWEXT: -++ return wext_odd_dep_p (consumer, def_reg); -++ -++ case TYPE_DBPICK: -++ return bpick_ra_rb_dep_p (consumer, def_reg); -++ -++ case TYPE_MMU: -++ if (GET_CODE (PATTERN (consumer)) == SET) -++ use_rtx = SET_SRC (PATTERN (consumer)); -++ else -++ return true; -++ break; -++ -++ case TYPE_LOAD: -++ case TYPE_STORE: -++ use_rtx = extract_mem_rtx (consumer); -++ break; -++ -++ case TYPE_LOAD_MULTIPLE: -++ case TYPE_STORE_MULTIPLE: -++ use_rtx = extract_base_reg (consumer); -++ break; -++ -++ case TYPE_BRANCH: -++ use_rtx = PATTERN (consumer); -++ break; -++ -++ default: -++ gcc_unreachable (); -++ } -++ -++ if (reg_overlap_p (def_reg, use_rtx)) -++ return true; -++ -++ return false; -++} -++ -++/* Check the dependency between the producer defining DEF_REG and CONSUMER -++ requiring input operand at EX. */ -++bool -++gw_consumed_by_ex_dep_p (rtx_insn *consumer, rtx def_reg) -++{ -++ rtx use_rtx; -++ -++ switch (get_attr_type (consumer)) -++ { -++ case TYPE_ALU: -++ case TYPE_PBSAD: -++ case TYPE_MUL: -++ case TYPE_DALU: -++ case TYPE_DALU64: -++ case TYPE_DMUL: -++ case TYPE_DPACK: -++ case TYPE_DINSB: -++ case TYPE_DCMP: -++ case TYPE_DCLIP: -++ case TYPE_DALUROUND: -++ use_rtx = SET_SRC (PATTERN (consumer)); -++ break; -++ -++ case TYPE_ALU_SHIFT: -++ use_rtx = extract_shift_reg (consumer); -++ break; -++ -++ case TYPE_PBSADA: -++ return pbsada_insn_ra_rb_dep_reg_p (consumer, def_reg); -++ -++ case TYPE_MAC: -++ case TYPE_DMAC: -++ use_rtx = extract_mac_non_acc_rtx (consumer); -++ break; -++ -++ /* Some special instructions, divmodsi4 and udivmodsi4, produce two -++ results, the quotient and the remainder. We have to check the -++ dependency from the producer to the first micro-operation. */ -++ case TYPE_DIV: -++ if (divmod_p (consumer)) -++ use_rtx = SET_SRC (parallel_element (consumer, 0)); -++ else -++ use_rtx = SET_SRC (PATTERN (consumer)); -++ break; -++ -++ case TYPE_DWEXT: -++ return wext_odd_dep_p (consumer, def_reg); -++ -++ case TYPE_DBPICK: -++ return bpick_ra_rb_dep_p (consumer, def_reg); -++ -++ case TYPE_MMU: -++ if (GET_CODE (PATTERN (consumer)) == SET) -++ use_rtx = SET_SRC (PATTERN (consumer)); -++ else -++ return true; -++ break; -++ -++ case TYPE_LOAD: -++ case TYPE_STORE: -++ use_rtx = extract_mem_rtx (consumer); -++ break; -++ -++ case TYPE_LOAD_MULTIPLE: -++ case TYPE_STORE_MULTIPLE: -++ use_rtx = extract_base_reg (consumer); -++ break; -++ -++ case TYPE_BRANCH: -++ use_rtx = PATTERN (consumer); -++ break; -++ -++ default: -++ gcc_unreachable (); -++ } -++ -++ if (reg_overlap_p (def_reg, use_rtx)) -++ return true; -++ -++ return false; -++} -++ -++/* Check dependencies from any stages to ALU_E1 (E1). This is a helper -++ function of n13_consumed_by_e1_dep_p (). */ -++bool -++n13_alu_e1_insn_dep_reg_p (rtx_insn *alu_e1_insn, rtx def_reg) -++{ -++ rtx unspec_rtx, operand_ra, operand_rb; -++ rtx src_rtx, dst_rtx; -++ -++ switch (INSN_CODE (alu_e1_insn)) -++ { -++ /* BSP and BSE are supported by built-in functions, the corresponding -++ patterns are formed by UNSPEC RTXs. We have to handle them -++ individually. */ -++ case CODE_FOR_unspec_bsp: -++ case CODE_FOR_unspec_bse: -++ unspec_rtx = SET_SRC (parallel_element (alu_e1_insn, 0)); -++ gcc_assert (GET_CODE (unspec_rtx) == UNSPEC); -++ -++ operand_ra = XVECEXP (unspec_rtx, 0, 0); -++ operand_rb = XVECEXP (unspec_rtx, 0, 1); -++ -++ if (rtx_equal_p (def_reg, operand_ra) -++ || rtx_equal_p (def_reg, operand_rb)) -++ return true; -++ -++ return false; -++ -++ /* Unlink general ALU instructions, MOVD44 requires operands at E1. */ -++ case CODE_FOR_move_di: -++ case CODE_FOR_move_df: -++ src_rtx = SET_SRC (PATTERN (alu_e1_insn)); -++ dst_rtx = SET_DEST (PATTERN (alu_e1_insn)); -++ -++ if (REG_P (dst_rtx) && REG_P (src_rtx) -++ && rtx_equal_p (src_rtx, def_reg)) -++ return true; -++ -++ return false; -++ -++ default: -++ return false; -++ } -++} -++ -++/* Check the dependency between the producer defining DEF_REG and CONSUMER -++ requiring input operand at E1. Because the address generation unti is -++ at E1, the address input should be ready at E1. Note that the branch -++ target is also a kind of addresses, so we have to check it. */ -++bool -++n13_consumed_by_e1_dep_p (rtx_insn *consumer, rtx def_reg) -++{ -++ rtx use_rtx; -++ -++ switch (get_attr_type (consumer)) -++ { -++ /* ALU_E1 */ -++ case TYPE_ALU: -++ return n13_alu_e1_insn_dep_reg_p (consumer, def_reg); -++ -++ case TYPE_PBSADA: -++ return pbsada_insn_ra_rb_dep_reg_p (consumer, def_reg); -++ -++ case TYPE_PBSAD: -++ case TYPE_MUL: -++ use_rtx = SET_SRC (PATTERN (consumer)); -++ break; -++ -++ case TYPE_MAC: -++ use_rtx = extract_mac_non_acc_rtx (consumer); -++ break; -++ -++ case TYPE_DIV: -++ if (divmod_p (consumer)) -++ use_rtx = SET_SRC (parallel_element (consumer, 0)); -++ else -++ use_rtx = SET_SRC (PATTERN (consumer)); -++ break; -++ -++ case TYPE_MMU: -++ if (GET_CODE (PATTERN (consumer)) == SET) -++ use_rtx = SET_SRC (PATTERN (consumer)); -++ else -++ return true; -++ break; -++ -++ case TYPE_BRANCH: -++ use_rtx = extract_branch_target_rtx (consumer); -++ break; -++ -++ case TYPE_LOAD: -++ case TYPE_STORE: -++ use_rtx = extract_mem_rtx (consumer); -++ break; -++ -++ case TYPE_LOAD_MULTIPLE: -++ case TYPE_STORE_MULTIPLE: -++ use_rtx = extract_base_reg (consumer); -++ break; -++ -++ default: -++ return false; -++ } -++ -++ if (reg_overlap_p (def_reg, use_rtx)) -++ return true; -++ -++ return false; -++} -++ -++/* Check the dependency between the producer defining DEF_REG and CONSUMER -++ requiring input operand at E2. */ -++bool -++n13_consumed_by_e2_dep_p (rtx_insn *consumer, rtx def_reg) -++{ -++ rtx use_rtx; -++ -++ switch (get_attr_type (consumer)) -++ { -++ case TYPE_ALU: -++ case TYPE_STORE: -++ use_rtx = SET_SRC (PATTERN (consumer)); -++ break; -++ -++ case TYPE_ALU_SHIFT: -++ use_rtx = extract_shift_reg (consumer); -++ break; -++ -++ case TYPE_PBSADA: -++ return pbsada_insn_rt_dep_reg_p (consumer, def_reg); -++ -++ case TYPE_STORE_MULTIPLE: -++ use_rtx = extract_nth_access_rtx (consumer, 0); -++ break; -++ -++ case TYPE_BRANCH: -++ use_rtx = extract_branch_condition_rtx (consumer); -++ break; -++ -++ default: -++ gcc_unreachable(); -++ } -++ -++ if (reg_overlap_p (def_reg, use_rtx)) -++ return true; -+ -++ return false; -++} -+ } // anonymous namespace -+ -+ /* ------------------------------------------------------------------------ */ -+@@ -837,8 +1252,7 @@ nds32_n8_ex_to_ii_p (rtx_insn *producer, rtx_insn *consumer) -+ break; -+ -+ case TYPE_DIV: -+- if (INSN_CODE (producer) == CODE_FOR_divmodsi4 -+- || INSN_CODE (producer) == CODE_FOR_udivmodsi4) -++ if (divmod_p (producer)) -+ def_reg = SET_DEST (parallel_element (producer, 1)); -+ else -+ def_reg = SET_DEST (PATTERN (producer)); -+@@ -969,8 +1383,7 @@ nds32_e8_ex_to_ii_p (rtx_insn *producer, rtx_insn *consumer) -+ break; -+ -+ case TYPE_DIV: -+- if (INSN_CODE (producer) == CODE_FOR_divmodsi4 -+- || INSN_CODE (producer) == CODE_FOR_udivmodsi4) -++ if (divmod_p (producer)) -+ { -+ rtx def_reg1 = SET_DEST (parallel_element (producer, 0)); -+ rtx def_reg2 = SET_DEST (parallel_element (producer, 1)); -+@@ -1073,8 +1486,7 @@ nds32_n9_3r2w_mm_to_ex_p (rtx_insn *producer, rtx_insn *consumer) -+ results, the quotient and the remainder. We have to handle them -+ individually. */ -+ case TYPE_DIV: -+- if (INSN_CODE (producer) == CODE_FOR_divmodsi4 -+- || INSN_CODE (producer) == CODE_FOR_udivmodsi4) -++ if (divmod_p (producer)) -+ { -+ rtx def_reg1 = SET_DEST (parallel_element (producer, 0)); -+ rtx def_reg2 = SET_DEST (parallel_element (producer, 1)); -+@@ -1132,4 +1544,245 @@ nds32_n9_last_load_to_ex_p (rtx_insn *producer, rtx_insn *consumer) -+ return n9_3r2w_consumed_by_ex_dep_p (consumer, last_def_reg); -+ } -+ -++/* Guard functions for N10 cores. */ -++ -++/* Check dependencies from EX to EX (ADDR_OUT -> ADDR_IN). */ -++bool -++nds32_n10_ex_to_ex_p (rtx_insn *producer, rtx_insn *consumer) -++{ -++ gcc_assert (get_attr_type (producer) == TYPE_FLOAD -++ || get_attr_type (producer) == TYPE_FSTORE); -++ gcc_assert (get_attr_type (consumer) == TYPE_FLOAD -++ || get_attr_type (consumer) == TYPE_FSTORE); -++ -++ if (!post_update_insn_p (producer)) -++ return false; -++ -++ return reg_overlap_p (extract_base_reg (producer), -++ extract_mem_rtx (consumer)); -++} -++ -++/* Check dependencies from MM to EX. */ -++bool -++nds32_n10_mm_to_ex_p (rtx_insn *producer, rtx_insn *consumer) -++{ -++ rtx def_reg; -++ -++ switch (get_attr_type (producer)) -++ { -++ case TYPE_LOAD: -++ case TYPE_MUL: -++ case TYPE_MAC: -++ case TYPE_DALU64: -++ case TYPE_DMUL: -++ case TYPE_DMAC: -++ case TYPE_DALUROUND: -++ case TYPE_DBPICK: -++ case TYPE_DWEXT: -++ def_reg = SET_DEST (PATTERN (producer)); -++ break; -++ -++ /* Some special instructions, divmodsi4 and udivmodsi4, produce two -++ results, the quotient and the remainder. We have to handle them -++ individually. */ -++ case TYPE_DIV: -++ if (divmod_p (producer)) -++ { -++ rtx def_reg1 = SET_DEST (parallel_element (producer, 0)); -++ rtx def_reg2 = SET_DEST (parallel_element (producer, 1)); -++ -++ return (n10_consumed_by_ex_dep_p (consumer, def_reg1) -++ || n10_consumed_by_ex_dep_p (consumer, def_reg2)); -++ } -++ -++ def_reg = SET_DEST (PATTERN (producer)); -++ break; -++ -++ default: -++ gcc_unreachable (); -++ } -++ -++ return n10_consumed_by_ex_dep_p (consumer, def_reg); -++} -++ -++/* Check dependencies from LMW(N, N) to EX. */ -++bool -++nds32_n10_last_load_to_ex_p (rtx_insn *producer, rtx_insn *consumer) -++{ -++ rtx last_def_reg = extract_nth_access_reg (producer, -1); -++ -++ return n10_consumed_by_ex_dep_p (consumer, last_def_reg); -++} -++ -++/* Guard functions for Graywolf cores. */ -++ -++/* Check dependencies from EX to EX (ADDR_OUT -> ADDR_IN). */ -++bool -++nds32_gw_ex_to_ex_p (rtx_insn *producer, rtx_insn *consumer) -++{ -++ return nds32_n10_ex_to_ex_p (producer, consumer); -++} -++ -++/* Check dependencies from MM to EX. */ -++bool -++nds32_gw_mm_to_ex_p (rtx_insn *producer, rtx_insn *consumer) -++{ -++ rtx def_reg; -++ -++ switch (get_attr_type (producer)) -++ { -++ case TYPE_LOAD: -++ case TYPE_MUL: -++ case TYPE_MAC: -++ case TYPE_DALU64: -++ case TYPE_DMUL: -++ case TYPE_DMAC: -++ case TYPE_DALUROUND: -++ case TYPE_DBPICK: -++ case TYPE_DWEXT: -++ def_reg = SET_DEST (PATTERN (producer)); -++ break; -++ -++ /* Some special instructions, divmodsi4 and udivmodsi4, produce two -++ results, the quotient and the remainder. We have to handle them -++ individually. */ -++ case TYPE_DIV: -++ if (divmod_p (producer)) -++ { -++ rtx def_reg1 = SET_DEST (parallel_element (producer, 0)); -++ rtx def_reg2 = SET_DEST (parallel_element (producer, 1)); -++ -++ return (gw_consumed_by_ex_dep_p (consumer, def_reg1) -++ || gw_consumed_by_ex_dep_p (consumer, def_reg2)); -++ } -++ -++ def_reg = SET_DEST (PATTERN (producer)); -++ break; -++ -++ default: -++ gcc_unreachable (); -++ } -++ -++ return gw_consumed_by_ex_dep_p (consumer, def_reg); -++} -++ -++/* Check dependencies from LMW(N, N) to EX. */ -++bool -++nds32_gw_last_load_to_ex_p (rtx_insn *producer, rtx_insn *consumer) -++{ -++ rtx last_def_reg = extract_nth_access_reg (producer, -1); -++ -++ return gw_consumed_by_ex_dep_p (consumer, last_def_reg); -++} -++ -++/* Guard functions for N12/N13 cores. */ -++ -++/* Check dependencies from E2 to E1. */ -++bool -++nds32_n13_e2_to_e1_p (rtx_insn *producer, rtx_insn *consumer) -++{ -++ rtx def_reg; -++ -++ switch (get_attr_type (producer)) -++ { -++ /* Only post-update load/store instructions are considered. These -++ instructions produces address output at E2. */ -++ case TYPE_LOAD: -++ case TYPE_STORE: -++ case TYPE_LOAD_MULTIPLE: -++ case TYPE_STORE_MULTIPLE: -++ if (!post_update_insn_p (producer)) -++ return false; -++ -++ def_reg = extract_base_reg (producer); -++ break; -++ -++ case TYPE_ALU: -++ case TYPE_ALU_SHIFT: -++ case TYPE_PBSAD: -++ case TYPE_PBSADA: -++ case TYPE_MUL: -++ case TYPE_MAC: -++ def_reg = SET_DEST (PATTERN (producer)); -++ break; -++ -++ case TYPE_BRANCH: -++ return true; -++ -++ case TYPE_DIV: -++ /* Some special instructions, divmodsi4 and udivmodsi4, produce two -++ results, the quotient and the remainder. We have to handle them -++ individually. */ -++ if (divmod_p (producer)) -++ { -++ rtx def_reg1 = SET_DEST (parallel_element (producer, 0)); -++ rtx def_reg2 = SET_DEST (parallel_element (producer, 1)); -++ -++ return (n13_consumed_by_e1_dep_p (consumer, def_reg1) -++ || n13_consumed_by_e1_dep_p (consumer, def_reg2)); -++ } -++ -++ def_reg = SET_DEST (PATTERN (producer)); -++ break; -++ -++ default: -++ gcc_unreachable (); -++ } -++ -++ return n13_consumed_by_e1_dep_p (consumer, def_reg); -++} -++ -++/* Check dependencies from Load-Store Unit (E3) to E1. */ -++bool -++nds32_n13_load_to_e1_p (rtx_insn *producer, rtx_insn *consumer) -++{ -++ rtx def_reg = SET_DEST (PATTERN (producer)); -++ -++ gcc_assert (get_attr_type (producer) == TYPE_LOAD); -++ gcc_assert (REG_P (def_reg) || GET_CODE (def_reg) == SUBREG); -++ -++ return n13_consumed_by_e1_dep_p (consumer, def_reg); -++} -++ -++/* Check dependencies from Load-Store Unit (E3) to E2. */ -++bool -++nds32_n13_load_to_e2_p (rtx_insn *producer, rtx_insn *consumer) -++{ -++ rtx def_reg = SET_DEST (PATTERN (producer)); -++ -++ gcc_assert (get_attr_type (producer) == TYPE_LOAD); -++ gcc_assert (REG_P (def_reg) || GET_CODE (def_reg) == SUBREG); -++ -++ return n13_consumed_by_e2_dep_p (consumer, def_reg); -++} -++ -++/* Check dependencies from LMW(N, N) to E1. */ -++bool -++nds32_n13_last_load_to_e1_p (rtx_insn *producer, rtx_insn *consumer) -++{ -++ rtx last_def_reg = extract_nth_access_reg (producer, -1); -++ -++ return n13_consumed_by_e1_dep_p (consumer, last_def_reg); -++} -++ -++/* Check dependencies from LMW(N, N) to E2. */ -++bool -++nds32_n13_last_load_to_e2_p (rtx_insn *producer, rtx_insn *consumer) -++{ -++ rtx last_def_reg = extract_nth_access_reg (producer, -1); -++ -++ return n13_consumed_by_e2_dep_p (consumer, last_def_reg); -++} -++ -++/* Check dependencies from LMW(N, N-1) to E2. */ -++bool -++nds32_n13_last_two_load_to_e1_p (rtx_insn *producer, rtx_insn *consumer) -++{ -++ rtx last_two_def_reg = extract_nth_access_reg (producer, -2); -++ -++ if (last_two_def_reg == NULL_RTX) -++ return false; -++ -++ return n13_consumed_by_e1_dep_p (consumer, last_two_def_reg); -++} -+ /* ------------------------------------------------------------------------ */ -+diff --git a/gcc/config/nds32/nds32-predicates.c b/gcc/config/nds32/nds32-predicates.c -+index 5e01430c8e3..b41b6c7f438 100644 -+--- a/gcc/config/nds32/nds32-predicates.c -++++ b/gcc/config/nds32/nds32-predicates.c -+@@ -356,54 +356,57 @@ nds32_valid_stack_push_pop_p (rtx op, bool push_p) -+ } -+ -+ /* Function to check if 'bclr' instruction can be used with IVAL. */ -+-int -+-nds32_can_use_bclr_p (int ival) -++bool -++nds32_can_use_bclr_p (HOST_WIDE_INT ival) -+ { -+ int one_bit_count; -++ unsigned HOST_WIDE_INT mask = GET_MODE_MASK (SImode); -+ -+ /* Calculate the number of 1-bit of (~ival), if there is only one 1-bit, -+ it means the original ival has only one 0-bit, -+ So it is ok to perform 'bclr' operation. */ -+ -+- one_bit_count = popcount_hwi ((unsigned HOST_WIDE_INT) (~ival)); -++ one_bit_count = popcount_hwi ((unsigned HOST_WIDE_INT) (~ival) & mask); -+ -+ /* 'bclr' is a performance extension instruction. */ -+ return (TARGET_EXT_PERF && (one_bit_count == 1)); -+ } -+ -+ /* Function to check if 'bset' instruction can be used with IVAL. */ -+-int -+-nds32_can_use_bset_p (int ival) -++bool -++nds32_can_use_bset_p (HOST_WIDE_INT ival) -+ { -+ int one_bit_count; -++ unsigned HOST_WIDE_INT mask = GET_MODE_MASK (SImode); -+ -+ /* Caculate the number of 1-bit of ival, if there is only one 1-bit, -+ it is ok to perform 'bset' operation. */ -+ -+- one_bit_count = popcount_hwi ((unsigned HOST_WIDE_INT) (ival)); -++ one_bit_count = popcount_hwi ((unsigned HOST_WIDE_INT) (ival) & mask); -+ -+ /* 'bset' is a performance extension instruction. */ -+ return (TARGET_EXT_PERF && (one_bit_count == 1)); -+ } -+ -+ /* Function to check if 'btgl' instruction can be used with IVAL. */ -+-int -+-nds32_can_use_btgl_p (int ival) -++bool -++nds32_can_use_btgl_p (HOST_WIDE_INT ival) -+ { -+ int one_bit_count; -++ unsigned HOST_WIDE_INT mask = GET_MODE_MASK (SImode); -+ -+ /* Caculate the number of 1-bit of ival, if there is only one 1-bit, -+ it is ok to perform 'btgl' operation. */ -+ -+- one_bit_count = popcount_hwi ((unsigned HOST_WIDE_INT) (ival)); -++ one_bit_count = popcount_hwi ((unsigned HOST_WIDE_INT) (ival) & mask); -+ -+ /* 'btgl' is a performance extension instruction. */ -+ return (TARGET_EXT_PERF && (one_bit_count == 1)); -+ } -+ -+ /* Function to check if 'bitci' instruction can be used with IVAL. */ -+-int -+-nds32_can_use_bitci_p (int ival) -++bool -++nds32_can_use_bitci_p (HOST_WIDE_INT ival) -+ { -+ /* If we are using V3 ISA, we have 'bitci' instruction. -+ Try to see if we can present 'andi' semantic with -+@@ -515,4 +518,117 @@ nds32_const_double_range_ok_p (rtx op, machine_mode mode, -+ -+ return val >= lower && val < upper; -+ } -++ -++bool -++nds32_const_unspec_p (rtx x) -++{ -++ if (GET_CODE (x) == CONST) -++ { -++ x = XEXP (x, 0); -++ -++ if (GET_CODE (x) == PLUS) -++ x = XEXP (x, 0); -++ -++ if (GET_CODE (x) == UNSPEC) -++ { -++ switch (XINT (x, 1)) -++ { -++ case UNSPEC_GOTINIT: -++ case UNSPEC_GOT: -++ case UNSPEC_GOTOFF: -++ case UNSPEC_PLT: -++ case UNSPEC_TLSGD: -++ case UNSPEC_TLSLD: -++ case UNSPEC_TLSIE: -++ case UNSPEC_TLSLE: -++ return false; -++ default: -++ return true; -++ } -++ } -++ } -++ -++ if (GET_CODE (x) == SYMBOL_REF -++ && SYMBOL_REF_TLS_MODEL (x)) -++ return false; -++ -++ return true; -++} -++ -++HOST_WIDE_INT -++const_vector_to_hwint (rtx op) -++{ -++ HOST_WIDE_INT hwint = 0; -++ HOST_WIDE_INT mask; -++ int i; -++ int shift_adv; -++ int shift = 0; -++ int nelem; -++ -++ switch (GET_MODE (op)) -++ { -++ case E_V2HImode: -++ mask = 0xffff; -++ shift_adv = 16; -++ nelem = 2; -++ break; -++ case E_V4QImode: -++ mask = 0xff; -++ shift_adv = 8; -++ nelem = 4; -++ break; -++ default: -++ gcc_unreachable (); -++ } -++ -++ if (TARGET_BIG_ENDIAN) -++ { -++ for (i = 0; i < nelem; ++i) -++ { -++ HOST_WIDE_INT val = XINT (XVECEXP (op, 0, nelem - i - 1), 0); -++ hwint |= (val & mask) << shift; -++ shift = shift + shift_adv; -++ } -++ } -++ else -++ { -++ for (i = 0; i < nelem; ++i) -++ { -++ HOST_WIDE_INT val = XINT (XVECEXP (op, 0, i), 0); -++ hwint |= (val & mask) << shift; -++ shift = shift + shift_adv; -++ } -++ } -++ -++ return hwint; -++} -++ -++bool -++nds32_valid_CVp5_p (rtx op) -++{ -++ HOST_WIDE_INT ival = const_vector_to_hwint (op); -++ return (ival < ((1 << 5) + 16)) && (ival >= (0 + 16)); -++} -++ -++bool -++nds32_valid_CVs5_p (rtx op) -++{ -++ HOST_WIDE_INT ival = const_vector_to_hwint (op); -++ return (ival < (1 << 4)) && (ival >= -(1 << 4)); -++} -++ -++bool -++nds32_valid_CVs2_p (rtx op) -++{ -++ HOST_WIDE_INT ival = const_vector_to_hwint (op); -++ return (ival < (1 << 19)) && (ival >= -(1 << 19)); -++} -++ -++bool -++nds32_valid_CVhi_p (rtx op) -++{ -++ HOST_WIDE_INT ival = const_vector_to_hwint (op); -++ return (ival != 0) && ((ival & 0xfff) == 0); -++} -++ -+ /* ------------------------------------------------------------------------ */ -+diff --git a/gcc/config/nds32/nds32-protos.h b/gcc/config/nds32/nds32-protos.h -+index e7b7d4170cc..7fb2315d0ff 100644 -+--- a/gcc/config/nds32/nds32-protos.h -++++ b/gcc/config/nds32/nds32-protos.h -+@@ -69,9 +69,10 @@ extern unsigned int nds32_dbx_register_number (unsigned int); -+ -+ /* ------------------------------------------------------------------------ */ -+ -+-/* Auxiliary functions for lwm/smw. */ -++/* Auxiliary functions for manipulation DI mode. */ -+ -+-extern bool nds32_valid_smw_lwm_base_p (rtx); -++extern rtx nds32_di_high_part_subreg(rtx); -++extern rtx nds32_di_low_part_subreg(rtx); -+ -+ /* Auxiliary functions for expanding rtl used in nds32-multiple.md. */ -+ -+@@ -116,6 +117,20 @@ extern bool nds32_n9_2r1w_mm_to_ex_p (rtx_insn *, rtx_insn *); -+ extern bool nds32_n9_3r2w_mm_to_ex_p (rtx_insn *, rtx_insn *); -+ extern bool nds32_n9_last_load_to_ex_p (rtx_insn *, rtx_insn *); -+ -++extern bool nds32_n10_ex_to_ex_p (rtx_insn *, rtx_insn *); -++extern bool nds32_n10_mm_to_ex_p (rtx_insn *, rtx_insn *); -++extern bool nds32_n10_last_load_to_ex_p (rtx_insn *, rtx_insn *); -++ -++extern bool nds32_gw_ex_to_ex_p (rtx_insn *, rtx_insn *); -++extern bool nds32_gw_mm_to_ex_p (rtx_insn *, rtx_insn *); -++extern bool nds32_gw_last_load_to_ex_p (rtx_insn *, rtx_insn *); -++ -++extern bool nds32_n13_e2_to_e1_p (rtx_insn *, rtx_insn *); -++extern bool nds32_n13_load_to_e1_p (rtx_insn *, rtx_insn *); -++extern bool nds32_n13_load_to_e2_p (rtx_insn *, rtx_insn *); -++extern bool nds32_n13_last_load_to_e1_p (rtx_insn *, rtx_insn *); -++extern bool nds32_n13_last_load_to_e2_p (rtx_insn *, rtx_insn *); -++extern bool nds32_n13_last_two_load_to_e1_p (rtx_insn *, rtx_insn *); -+ -+ /* Auxiliary functions for stack operation predicate checking. */ -+ -+@@ -123,24 +138,25 @@ extern bool nds32_valid_stack_push_pop_p (rtx, bool); -+ -+ /* Auxiliary functions for bit operation detection. */ -+ -+-extern int nds32_can_use_bclr_p (int); -+-extern int nds32_can_use_bset_p (int); -+-extern int nds32_can_use_btgl_p (int); -++extern bool nds32_can_use_bclr_p (HOST_WIDE_INT); -++extern bool nds32_can_use_bset_p (HOST_WIDE_INT); -++extern bool nds32_can_use_btgl_p (HOST_WIDE_INT); -+ -+-extern int nds32_can_use_bitci_p (int); -++extern bool nds32_can_use_bitci_p (HOST_WIDE_INT); -+ -+ extern bool nds32_const_double_range_ok_p (rtx, machine_mode, -+ HOST_WIDE_INT, HOST_WIDE_INT); -+ -++extern bool nds32_const_unspec_p (rtx x); -++ -+ /* Auxiliary function for 'Computing the Length of an Insn'. */ -+ -+ extern int nds32_adjust_insn_length (rtx_insn *, int); -+ -+ /* Auxiliary functions for FP_AS_GP detection. */ -+ -+-extern int nds32_fp_as_gp_check_available (void); -+- -+ extern bool nds32_symbol_load_store_p (rtx_insn *); -++extern bool nds32_naked_function_p (tree); -+ -+ /* Auxiliary functions for jump table generation. */ -+ -+@@ -159,10 +175,50 @@ extern void nds32_expand_float_cstore (rtx *); -+ extern enum nds32_expand_result_type nds32_expand_movcc (rtx *); -+ extern void nds32_expand_float_movcc (rtx *); -+ -++/* Auxiliary functions for expand extv/insv instruction. */ -++ -++extern enum nds32_expand_result_type nds32_expand_extv (rtx *); -++extern enum nds32_expand_result_type nds32_expand_insv (rtx *); -++ -++/* Auxiliary functions for expand PIC instruction. */ -++ -++extern void nds32_expand_pic_move (rtx *); -++ -++/* Auxiliary functions to legitimize PIC address. */ -++ -++extern rtx nds32_legitimize_pic_address (rtx); -++ -++/* Auxiliary functions for expand TLS instruction. */ -++ -++extern void nds32_expand_tls_move (rtx *); -++ -++/* Auxiliary functions to legitimize TLS address. */ -++ -++extern rtx nds32_legitimize_tls_address (rtx); -++ -++/* Auxiliary functions to identify thread-local symbol. */ -++ -++extern bool nds32_tls_referenced_p (rtx); -++ -++/* Auxiliary functions for expand ICT instruction. */ -++ -++extern void nds32_expand_ict_move (rtx *); -++ -++/* Auxiliary functions to legitimize address for indirect-call symbol. */ -++ -++extern rtx nds32_legitimize_ict_address (rtx); -++ -++/* Auxiliary functions to identify indirect-call symbol. */ -++ -++extern bool nds32_indirect_call_referenced_p (rtx); -+ -+ /* Auxiliary functions to identify long-call symbol. */ -+ extern bool nds32_long_call_p (rtx); -+ -++/* Auxiliary functions to identify SYMBOL_REF and LABEL_REF pattern. */ -++ -++extern bool symbolic_reference_mentioned_p (rtx); -++ -+ /* Auxiliary functions to identify conditional move comparison operand. */ -+ -+ extern int nds32_cond_move_p (rtx); -+@@ -185,6 +241,7 @@ extern const char *nds32_output_32bit_load_s (rtx *, int); -+ extern const char *nds32_output_float_load(rtx *); -+ extern const char *nds32_output_float_store(rtx *); -+ extern const char *nds32_output_smw_single_word (rtx *); -++extern const char *nds32_output_smw_double_word (rtx *); -+ extern const char *nds32_output_lmw_single_word (rtx *); -+ extern const char *nds32_output_double (rtx *, bool); -+ extern const char *nds32_output_cbranchsi4_equality_zero (rtx_insn *, rtx *); -+@@ -193,9 +250,12 @@ extern const char *nds32_output_cbranchsi4_equality_reg_or_const_int (rtx_insn * -+ rtx *); -+ extern const char *nds32_output_cbranchsi4_greater_less_zero (rtx_insn *, rtx *); -+ -++extern const char *nds32_output_unpkd8 (rtx, rtx, rtx, rtx, bool); -++ -+ extern const char *nds32_output_call (rtx, rtx *, rtx, -+ const char *, const char *, bool); -+- -++extern const char *nds32_output_tls_desc (rtx *); -++extern const char *nds32_output_tls_ie (rtx *); -+ -+ /* Auxiliary functions to output stack push/pop instruction. */ -+ -+@@ -203,9 +263,19 @@ extern const char *nds32_output_stack_push (rtx); -+ extern const char *nds32_output_stack_pop (rtx); -+ extern const char *nds32_output_return (void); -+ -++ -++/* Auxiliary functions to split/output sms pattern. */ -++extern bool nds32_need_split_sms_p (rtx, rtx, rtx, rtx); -++extern const char *nds32_output_sms (rtx, rtx, rtx, rtx); -++extern void nds32_split_sms (rtx, rtx, rtx, rtx, rtx, rtx, rtx); -++ -+ /* Auxiliary functions to split double word RTX pattern. */ -+ -+ extern void nds32_spilt_doubleword (rtx *, bool); -++extern void nds32_split_ashiftdi3 (rtx, rtx, rtx); -++extern void nds32_split_ashiftrtdi3 (rtx, rtx, rtx); -++extern void nds32_split_lshiftrtdi3 (rtx, rtx, rtx); -++extern void nds32_split_rotatertdi3 (rtx, rtx, rtx); -+ -+ /* Auxiliary functions to split large constant RTX pattern. */ -+ -+@@ -237,15 +307,29 @@ extern void nds32_construct_isr_vectors_information (tree, const char *); -+ extern void nds32_asm_file_start_for_isr (void); -+ extern void nds32_asm_file_end_for_isr (void); -+ extern bool nds32_isr_function_p (tree); -++extern bool nds32_isr_function_critical_p (tree); -+ -+ /* Auxiliary functions for cost calculation. */ -+ -++extern void nds32_init_rtx_costs (void); -+ extern bool nds32_rtx_costs_impl (rtx, machine_mode, int, int, int *, bool); -+ extern int nds32_address_cost_impl (rtx, machine_mode, addr_space_t, bool); -+ -+ /* Auxiliary functions for pre-define marco. */ -+ extern void nds32_cpu_cpp_builtins(struct cpp_reader *); -+ -++/* Auxiliary functions for const_vector's constraints. */ -++ -++extern HOST_WIDE_INT const_vector_to_hwint (rtx); -++extern bool nds32_valid_CVp5_p (rtx); -++extern bool nds32_valid_CVs5_p (rtx); -++extern bool nds32_valid_CVs2_p (rtx); -++extern bool nds32_valid_CVhi_p (rtx); -++ -++/* Auxiliary functions for lwm/smw. */ -++ -++extern bool nds32_valid_smw_lwm_base_p (rtx); -++ -+ extern bool nds32_split_double_word_load_store_p (rtx *,bool); -+ -+ namespace nds32 { -+@@ -258,11 +342,13 @@ bool load_single_p (rtx_insn *); -+ bool store_single_p (rtx_insn *); -+ bool load_double_p (rtx_insn *); -+ bool store_double_p (rtx_insn *); -++bool store_offset_reg_p (rtx_insn *); -+ bool post_update_insn_p (rtx_insn *); -+ bool immed_offset_p (rtx); -+ int find_post_update_rtx (rtx_insn *); -+ rtx extract_mem_rtx (rtx_insn *); -+ rtx extract_base_reg (rtx_insn *); -++rtx extract_offset_rtx (rtx_insn *); -+ -+ rtx extract_shift_reg (rtx); -+ -+@@ -271,6 +357,8 @@ rtx extract_movd44_odd_reg (rtx_insn *); -+ -+ rtx extract_mac_non_acc_rtx (rtx_insn *); -+ -++bool divmod_p (rtx_insn *); -++ -+ rtx extract_branch_target_rtx (rtx_insn *); -+ rtx extract_branch_condition_rtx (rtx_insn *); -+ } // namespace nds32 -+@@ -279,5 +367,6 @@ extern bool nds32_use_load_post_increment(machine_mode); -+ -+ /* Functions for create nds32 specific optimization pass. */ -+ extern rtl_opt_pass *make_pass_nds32_relax_opt (gcc::context *); -++extern rtl_opt_pass *make_pass_nds32_fp_as_gp (gcc::context *); -+ -+ /* ------------------------------------------------------------------------ */ -+diff --git a/gcc/config/nds32/nds32-relax-opt.c b/gcc/config/nds32/nds32-relax-opt.c -+index 0349be4725d..e54bd978c2e 100644 -+--- a/gcc/config/nds32/nds32-relax-opt.c -++++ b/gcc/config/nds32/nds32-relax-opt.c -+@@ -52,6 +52,8 @@ -+ #include "cfgrtl.h" -+ #include "tree-pass.h" -+ -++using namespace nds32; -++ -+ /* This is used to create unique relax hint id value. -+ The initial value is 0. */ -+ static int relax_group_id = 0; -+@@ -185,6 +187,121 @@ nds32_plus_reg_load_store_p (rtx_insn *insn) -+ return false; -+ } -+ -++/* Return true if x is const and the referance is ict symbol. */ -++static bool -++nds32_ict_const_p (rtx x) -++{ -++ if (GET_CODE (x) == CONST) -++ { -++ x = XEXP (x, 0); -++ return nds32_indirect_call_referenced_p (x); -++ } -++ return FALSE; -++} -++ -++/* Group the following pattern as relax candidates: -++ -++ GOT: -++ sethi $ra, hi20(sym) -++ ori $ra, $ra, lo12(sym) -++ lw $rb, [$ra + $gp] -++ -++ GOTOFF, TLSLE: -++ sethi $ra, hi20(sym) -++ ori $ra, $ra, lo12(sym) -++ LS $rb, [$ra + $gp] -++ -++ GOTOFF, TLSLE: -++ sethi $ra, hi20(sym) -++ ori $ra, $ra, lo12(sym) -++ add $rb, $ra, $gp($tp) -++ -++ Initial GOT table: -++ sethi $gp,hi20(sym) -++ ori $gp, $gp, lo12(sym) -++ add5.pc $gp */ -++ -++static auto_vec nds32_group_infos; -++/* Group the PIC and TLS relax candidate instructions for linker. */ -++static bool -++nds32_pic_tls_group (rtx_insn *def_insn, -++ enum nds32_relax_insn_type relax_type, -++ int sym_type) -++{ -++ df_ref def_record; -++ df_link *link; -++ rtx_insn *use_insn = NULL; -++ rtx pat, new_pat; -++ def_record = DF_INSN_DEFS (def_insn); -++ for (link = DF_REF_CHAIN (def_record); link; link = link->next) -++ { -++ if (!DF_REF_INSN_INFO (link->ref)) -++ continue; -++ -++ use_insn = DF_REF_INSN (link->ref); -++ -++ /* Skip if define insn and use insn not in the same basic block. */ -++ if (!dominated_by_p (CDI_DOMINATORS, -++ BLOCK_FOR_INSN (use_insn), -++ BLOCK_FOR_INSN (def_insn))) -++ return FALSE; -++ -++ /* Skip if use_insn not active insn. */ -++ if (!active_insn_p (use_insn)) -++ return FALSE; -++ -++ switch (relax_type) -++ { -++ case RELAX_ORI: -++ -++ /* GOTOFF, TLSLE: -++ sethi $ra, hi20(sym) -++ ori $ra, $ra, lo12(sym) -++ add $rb, $ra, $gp($tp) */ -++ if ((sym_type == UNSPEC_TLSLE -++ || sym_type == UNSPEC_GOTOFF) -++ && (recog_memoized (use_insn) == CODE_FOR_addsi3)) -++ { -++ pat = XEXP (PATTERN (use_insn), 1); -++ new_pat = -++ gen_rtx_UNSPEC (SImode, -++ gen_rtvec (2, XEXP (pat, 0), XEXP (pat, 1)), -++ UNSPEC_ADD32); -++ validate_replace_rtx (pat, new_pat, use_insn); -++ nds32_group_infos.safe_push (use_insn); -++ } -++ else if (nds32_plus_reg_load_store_p (use_insn) -++ && !nds32_sp_base_or_plus_load_store_p (use_insn)) -++ nds32_group_infos.safe_push (use_insn); -++ else -++ return FALSE; -++ break; -++ -++ default: -++ return FALSE; -++ } -++ } -++ return TRUE; -++} -++ -++static int -++nds32_pic_tls_symbol_type (rtx x) -++{ -++ x = XEXP (SET_SRC (PATTERN (x)), 1); -++ -++ if (GET_CODE (x) == CONST) -++ { -++ x = XEXP (x, 0); -++ -++ if (GET_CODE (x) == PLUS) -++ x = XEXP (x, 0); -++ -++ return XINT (x, 1); -++ } -++ -++ return XINT (x, 1); -++} -++ -+ /* Group the relax candidates with group id. */ -+ static void -+ nds32_group_insns (rtx sethi) -+@@ -193,6 +310,7 @@ nds32_group_insns (rtx sethi) -+ df_link *link; -+ rtx_insn *use_insn = NULL; -+ rtx group_id; -++ bool valid; -+ -+ def_record = DF_INSN_DEFS (sethi); -+ -+@@ -242,6 +360,132 @@ nds32_group_insns (rtx sethi) -+ /* Insert .relax_* directive. */ -+ if (active_insn_p (use_insn)) -+ emit_insn_before (gen_relax_group (group_id), use_insn); -++ -++ /* Find ori ra, ra, unspec(symbol) instruction. */ -++ if (use_insn != NULL -++ && recog_memoized (use_insn) == CODE_FOR_lo_sum -++ && !nds32_const_unspec_p (XEXP (SET_SRC (PATTERN (use_insn)), 1))) -++ { -++ int sym_type = nds32_pic_tls_symbol_type (use_insn); -++ valid = nds32_pic_tls_group (use_insn, RELAX_ORI, sym_type); -++ -++ /* Insert .relax_* directive. */ -++ while (!nds32_group_infos.is_empty ()) -++ { -++ use_insn = nds32_group_infos.pop (); -++ if (valid) -++ emit_insn_before (gen_relax_group (group_id), use_insn); -++ } -++ } -++ } -++ -++ relax_group_id++; -++} -++ -++/* Convert relax group id in rtl. */ -++ -++static void -++nds32_group_tls_insn (rtx insn) -++{ -++ rtx pat = PATTERN (insn); -++ rtx unspec_relax_group = XEXP (XVECEXP (pat, 0, 1), 0); -++ -++ while (GET_CODE (pat) != SET && GET_CODE (pat) == PARALLEL) -++ { -++ pat = XVECEXP (pat, 0, 0); -++ } -++ -++ if (GET_CODE (unspec_relax_group) == UNSPEC -++ && XINT (unspec_relax_group, 1) == UNSPEC_VOLATILE_RELAX_GROUP) -++ { -++ XVECEXP (unspec_relax_group, 0, 0) = GEN_INT (relax_group_id); -++ } -++ -++ relax_group_id++; -++} -++ -++static bool -++nds32_float_reg_load_store_p (rtx_insn *insn) -++{ -++ rtx pat = PATTERN (insn); -++ -++ if (get_attr_type (insn) == TYPE_FLOAD -++ && GET_CODE (pat) == SET -++ && (GET_MODE (XEXP (pat, 0)) == SFmode -++ || GET_MODE (XEXP (pat, 0)) == DFmode) -++ && MEM_P (XEXP (pat, 1))) -++ { -++ rtx addr = XEXP (XEXP (pat, 1), 0); -++ -++ /* [$ra] */ -++ if (REG_P (addr)) -++ return true; -++ /* [$ra + offset] */ -++ if (GET_CODE (addr) == PLUS -++ && REG_P (XEXP (addr, 0)) -++ && CONST_INT_P (XEXP (addr, 1))) -++ return true; -++ } -++ return false; -++} -++ -++ -++/* Group float load-store instructions: -++ la $ra, symbol -++ flsi $rt, [$ra + offset] */ -++ -++static void -++nds32_group_float_insns (rtx insn) -++{ -++ df_ref def_record, use_record; -++ df_link *link; -++ rtx_insn *use_insn = NULL; -++ rtx group_id; -++ -++ def_record = DF_INSN_DEFS (insn); -++ -++ for (link = DF_REF_CHAIN (def_record); link; link = link->next) -++ { -++ if (!DF_REF_INSN_INFO (link->ref)) -++ continue; -++ -++ use_insn = DF_REF_INSN (link->ref); -++ -++ /* Skip if define insn and use insn not in the same basic block. */ -++ if (!dominated_by_p (CDI_DOMINATORS, -++ BLOCK_FOR_INSN (use_insn), -++ BLOCK_FOR_INSN (insn))) -++ return; -++ -++ /* Skip if the low-part used register is from different high-part -++ instructions. */ -++ use_record = DF_INSN_USES (use_insn); -++ if (DF_REF_CHAIN (use_record) && DF_REF_CHAIN (use_record)->next) -++ return; -++ -++ /* Skip if use_insn not active insn. */ -++ if (!active_insn_p (use_insn)) -++ return; -++ -++ if (!nds32_float_reg_load_store_p (use_insn) -++ || find_post_update_rtx (use_insn) != -1) -++ return; -++ } -++ -++ group_id = GEN_INT (relax_group_id); -++ /* Insert .relax_* directive for insn. */ -++ emit_insn_before (gen_relax_group (group_id), insn); -++ -++ /* Scan the use insns and insert the directive. */ -++ for (link = DF_REF_CHAIN (def_record); link; link = link->next) -++ { -++ if (!DF_REF_INSN_INFO (link->ref)) -++ continue; -++ -++ use_insn = DF_REF_INSN (link->ref); -++ -++ /* Insert .relax_* directive. */ -++ emit_insn_before (gen_relax_group (group_id), use_insn); -+ } -+ -+ relax_group_id++; -+@@ -271,8 +515,21 @@ nds32_relax_group (void) -+ /* Find sethi ra, symbol instruction. */ -+ if (recog_memoized (insn) == CODE_FOR_sethi -+ && nds32_symbolic_operand (XEXP (SET_SRC (PATTERN (insn)), 0), -+- SImode)) -++ SImode) -++ && !nds32_ict_const_p (XEXP (SET_SRC (PATTERN (insn)), 0))) -+ nds32_group_insns (insn); -++ else if (recog_memoized (insn) == CODE_FOR_tls_ie) -++ nds32_group_tls_insn (insn); -++ else if (TARGET_FPU_SINGLE -++ && recog_memoized (insn) == CODE_FOR_move_addr -++ && !nds32_ict_const_p (XEXP (SET_SRC (PATTERN (insn)), 0))) -++ { -++ nds32_group_float_insns (insn); -++ } -++ } -++ else if (CALL_P (insn) && recog_memoized (insn) == CODE_FOR_tls_desc) -++ { -++ nds32_group_tls_insn (insn); -+ } -+ } -+ -+diff --git a/gcc/config/nds32/nds32-utils.c b/gcc/config/nds32/nds32-utils.c -+index b0151be39dc..7c93cd2edd0 100644 -+--- a/gcc/config/nds32/nds32-utils.c -++++ b/gcc/config/nds32/nds32-utils.c -+@@ -142,6 +142,23 @@ store_double_p (rtx_insn *insn) -+ return true; -+ } -+ -++bool -++store_offset_reg_p (rtx_insn *insn) -++{ -++ if (get_attr_type (insn) != TYPE_STORE) -++ return false; -++ -++ rtx offset_rtx = extract_offset_rtx (insn); -++ -++ if (offset_rtx == NULL_RTX) -++ return false; -++ -++ if (REG_P (offset_rtx)) -++ return true; -++ -++ return false; -++} -++ -+ /* Determine if INSN is a post update insn. */ -+ bool -+ post_update_insn_p (rtx_insn *insn) -+@@ -316,22 +333,114 @@ extract_base_reg (rtx_insn *insn) -+ if (REG_P (XEXP (mem_rtx, 0))) -+ return XEXP (mem_rtx, 0); -+ -++ /* (mem (lo_sum (reg) (symbol_ref)) */ -++ if (GET_CODE (XEXP (mem_rtx, 0)) == LO_SUM) -++ return XEXP (XEXP (mem_rtx, 0), 0); -++ -+ plus_rtx = XEXP (mem_rtx, 0); -+ -+ if (GET_CODE (plus_rtx) == SYMBOL_REF -+ || GET_CODE (plus_rtx) == CONST) -+ return NULL_RTX; -+ -+- gcc_assert (GET_CODE (plus_rtx) == PLUS -+- || GET_CODE (plus_rtx) == POST_INC -+- || GET_CODE (plus_rtx) == POST_DEC -+- || GET_CODE (plus_rtx) == POST_MODIFY); -+- gcc_assert (REG_P (XEXP (plus_rtx, 0))); -+ /* (mem (plus (reg) (const_int))) or -++ (mem (plus (mult (reg) (const_int 4)) (reg))) or -+ (mem (post_inc (reg))) or -+ (mem (post_dec (reg))) or -+ (mem (post_modify (reg) (plus (reg) (reg)))) */ -+- return XEXP (plus_rtx, 0); -++ gcc_assert (GET_CODE (plus_rtx) == PLUS -++ || GET_CODE (plus_rtx) == POST_INC -++ || GET_CODE (plus_rtx) == POST_DEC -++ || GET_CODE (plus_rtx) == POST_MODIFY); -++ -++ if (REG_P (XEXP (plus_rtx, 0))) -++ return XEXP (plus_rtx, 0); -++ -++ gcc_assert (REG_P (XEXP (plus_rtx, 1))); -++ return XEXP (plus_rtx, 1); -++} -++ -++/* Extract the offset rtx from load/store insns. The function returns -++ NULL_RTX if offset is absent. */ -++rtx -++extract_offset_rtx (rtx_insn *insn) -++{ -++ rtx mem_rtx; -++ rtx plus_rtx; -++ rtx offset_rtx; -++ -++ /* Find the MEM rtx. The multiple load/store insns doens't have -++ the offset field so we can return NULL_RTX here. */ -++ switch (get_attr_type (insn)) -++ { -++ case TYPE_LOAD_MULTIPLE: -++ case TYPE_STORE_MULTIPLE: -++ return NULL_RTX; -++ -++ case TYPE_LOAD: -++ case TYPE_FLOAD: -++ case TYPE_STORE: -++ case TYPE_FSTORE: -++ mem_rtx = extract_mem_rtx (insn); -++ break; -++ -++ default: -++ gcc_unreachable (); -++ } -++ -++ gcc_assert (MEM_P (mem_rtx)); -++ -++ /* (mem (reg)) */ -++ if (REG_P (XEXP (mem_rtx, 0))) -++ return NULL_RTX; -++ -++ plus_rtx = XEXP (mem_rtx, 0); -++ -++ switch (GET_CODE (plus_rtx)) -++ { -++ case SYMBOL_REF: -++ case CONST: -++ case POST_INC: -++ case POST_DEC: -++ return NULL_RTX; -++ -++ case PLUS: -++ /* (mem (plus (reg) (const_int))) or -++ (mem (plus (mult (reg) (const_int 4)) (reg))) */ -++ if (REG_P (XEXP (plus_rtx, 0))) -++ offset_rtx = XEXP (plus_rtx, 1); -++ else -++ { -++ gcc_assert (REG_P (XEXP (plus_rtx, 1))); -++ offset_rtx = XEXP (plus_rtx, 0); -++ } -++ -++ if (ARITHMETIC_P (offset_rtx)) -++ { -++ gcc_assert (GET_CODE (offset_rtx) == MULT); -++ gcc_assert (REG_P (XEXP (offset_rtx, 0))); -++ offset_rtx = XEXP (offset_rtx, 0); -++ } -++ break; -++ -++ case LO_SUM: -++ /* (mem (lo_sum (reg) (symbol_ref)) */ -++ offset_rtx = XEXP (plus_rtx, 1); -++ break; -++ -++ case POST_MODIFY: -++ /* (mem (post_modify (reg) (plus (reg) (reg / const_int)))) */ -++ gcc_assert (REG_P (XEXP (plus_rtx, 0))); -++ plus_rtx = XEXP (plus_rtx, 1); -++ gcc_assert (GET_CODE (plus_rtx) == PLUS); -++ offset_rtx = XEXP (plus_rtx, 0); -++ break; -++ -++ default: -++ gcc_unreachable (); -++ } -++ -++ return offset_rtx; -+ } -+ -+ /* Extract the register of the shift operand from an ALU_SHIFT rtx. */ -+@@ -413,6 +522,7 @@ extract_mac_non_acc_rtx (rtx_insn *insn) -+ switch (get_attr_type (insn)) -+ { -+ case TYPE_MAC: -++ case TYPE_DMAC: -+ if (REG_P (XEXP (exp, 0))) -+ return XEXP (exp, 1); -+ else -+@@ -423,6 +533,19 @@ extract_mac_non_acc_rtx (rtx_insn *insn) -+ } -+ } -+ -++/* Check if the DIV insn needs two write ports. */ -++bool -++divmod_p (rtx_insn *insn) -++{ -++ gcc_assert (get_attr_type (insn) == TYPE_DIV); -++ -++ if (INSN_CODE (insn) == CODE_FOR_divmodsi4 -++ || INSN_CODE (insn) == CODE_FOR_udivmodsi4) -++ return true; -++ -++ return false; -++} -++ -+ /* Extract the rtx representing the branch target to help recognize -+ data hazards. */ -+ rtx -+diff --git a/gcc/config/nds32/nds32.c b/gcc/config/nds32/nds32.c -+index 8994c13d7b0..1d23ec3fb9a 100644 -+--- a/gcc/config/nds32/nds32.c -++++ b/gcc/config/nds32/nds32.c -+@@ -305,6 +305,7 @@ static const struct attribute_spec nds32_attribute_table[] = -+ { "nested", 0, 0, false, false, false, false, NULL, NULL }, -+ { "not_nested", 0, 0, false, false, false, false, NULL, NULL }, -+ { "nested_ready", 0, 0, false, false, false, false, NULL, NULL }, -++ { "critical", 0, 0, false, false, false, false, NULL, NULL }, -+ -+ /* The attributes describing isr register save scheme. */ -+ { "save_all", 0, 0, false, false, false, false, NULL, NULL }, -+@@ -314,9 +315,19 @@ static const struct attribute_spec nds32_attribute_table[] = -+ { "nmi", 1, 1, false, false, false, false, NULL, NULL }, -+ { "warm", 1, 1, false, false, false, false, NULL, NULL }, -+ -++ /* The attributes describing isr security level. */ -++ { "secure", 1, 1, false, false, false, false, NULL, NULL }, -++ -+ /* The attribute telling no prologue/epilogue. */ -+ { "naked", 0, 0, false, false, false, false, NULL, NULL }, -+ -++ /* The attribute is used to tell this function to be ROM patch. */ -++ { "indirect_call",0, 0, false, false, false, false, NULL, NULL }, -++ -++ /* FOR BACKWARD COMPATIBILITY, -++ this attribute also tells no prologue/epilogue. */ -++ { "no_prologue", 0, 0, false, false, false, false, NULL, NULL }, -++ -+ /* The last attribute spec is set to be NULL. */ -+ { NULL, 0, 0, false, false, false, false, NULL, NULL } -+ }; -+@@ -345,6 +356,10 @@ nds32_init_machine_status (void) -+ /* Initially this function is not under strictly aligned situation. */ -+ machine->strict_aligned_p = 0; -+ -++ /* Initially this function has no naked and no_prologue attributes. */ -++ machine->attr_naked_p = 0; -++ machine->attr_no_prologue_p = 0; -++ -+ return machine; -+ } -+ -+@@ -362,6 +377,15 @@ nds32_compute_stack_frame (void) -+ needs prologue/epilogue. */ -+ cfun->machine->naked_p = 0; -+ -++ /* We need to mark whether this function has naked and no_prologue -++ attribute so that we can distinguish the difference if users applies -++ -mret-in-naked-func option. */ -++ cfun->machine->attr_naked_p -++ = lookup_attribute ("naked", DECL_ATTRIBUTES (current_function_decl)) -++ ? 1 : 0; -++ cfun->machine->attr_no_prologue_p -++ = lookup_attribute ("no_prologue", DECL_ATTRIBUTES (current_function_decl)) -++ ? 1 : 0; -+ -+ /* If __builtin_eh_return is used, we better have frame pointer needed -+ so that we can easily locate the stack slot of return address. */ -+@@ -432,7 +456,8 @@ nds32_compute_stack_frame (void) -+ -+ /* If $gp value is required to be saved on stack, it needs 4 bytes space. -+ Check whether we are using PIC code genration. */ -+- cfun->machine->gp_size = (flag_pic) ? 4 : 0; -++ cfun->machine->gp_size = -++ (flag_pic && df_regs_ever_live_p (PIC_OFFSET_TABLE_REGNUM)) ? 4 : 0; -+ -+ /* If $lp value is required to be saved on stack, it needs 4 bytes space. -+ Check whether $lp is ever live. */ -+@@ -497,7 +522,7 @@ nds32_compute_stack_frame (void) -+ } -+ -+ /* Check if this function can omit prologue/epilogue code fragment. -+- If there is 'naked' attribute in this function, -++ If there is 'no_prologue'/'naked'/'secure' attribute in this function, -+ we can set 'naked_p' flag to indicate that -+ we do not have to generate prologue/epilogue. -+ Or, if all the following conditions succeed, -+@@ -510,14 +535,17 @@ nds32_compute_stack_frame (void) -+ is no outgoing size. -+ condition 3: There is no local_size, which means -+ we do not need to adjust $sp. */ -+- if (lookup_attribute ("naked", DECL_ATTRIBUTES (current_function_decl)) -++ if (lookup_attribute ("no_prologue", DECL_ATTRIBUTES (current_function_decl)) -++ || lookup_attribute ("naked", DECL_ATTRIBUTES (current_function_decl)) -++ || lookup_attribute ("secure", DECL_ATTRIBUTES (current_function_decl)) -+ || (cfun->machine->callee_saved_first_gpr_regno == SP_REGNUM -+ && cfun->machine->callee_saved_last_gpr_regno == SP_REGNUM -+ && cfun->machine->callee_saved_first_fpr_regno == SP_REGNUM -+ && cfun->machine->callee_saved_last_fpr_regno == SP_REGNUM -+ && !df_regs_ever_live_p (FP_REGNUM) -+ && !df_regs_ever_live_p (LP_REGNUM) -+- && cfun->machine->local_size == 0)) -++ && cfun->machine->local_size == 0 -++ && !flag_pic)) -+ { -+ /* Set this function 'naked_p' and other functions can check this flag. -+ Note that in nds32 port, the 'naked_p = 1' JUST means there is no -+@@ -1259,6 +1287,32 @@ nds32_emit_stack_v3pop (unsigned Rb, -+ REG_NOTES (parallel_insn) = dwarf; -+ } -+ -++static void -++nds32_emit_load_gp (void) -++{ -++ rtx got_symbol, pat; -++ -++ /* Initial GLOBAL OFFSET TABLE don't do the scheduling. */ -++ emit_insn (gen_blockage ()); -++ -++ got_symbol = gen_rtx_SYMBOL_REF (Pmode, "_GLOBAL_OFFSET_TABLE_"); -++ /* sethi $gp, _GLOBAL_OFFSET_TABLE_ -8 */ -++ pat = gen_rtx_UNSPEC (SImode, gen_rtvec (1, got_symbol), UNSPEC_GOTINIT); -++ pat = gen_rtx_CONST (SImode, gen_rtx_PLUS (Pmode, pat, GEN_INT (-8))); -++ emit_insn (gen_sethi (pic_offset_table_rtx,pat)); -++ -++ /* ori $gp, $gp, _GLOBAL_OFFSET_TABLE_ -4 */ -++ pat = gen_rtx_UNSPEC (SImode, gen_rtvec (1, got_symbol), UNSPEC_GOTINIT); -++ pat = gen_rtx_CONST (SImode, gen_rtx_PLUS (Pmode, pat, GEN_INT (-4))); -++ emit_insn (gen_lo_sum (pic_offset_table_rtx, pic_offset_table_rtx, pat)); -++ -++ /* add5.pc $gp */ -++ emit_insn (gen_add_pc (pic_offset_table_rtx, pic_offset_table_rtx)); -++ -++ /* Initial GLOBAL OFFSET TABLE don't do the scheduling. */ -++ emit_insn (gen_blockage ()); -++} -++ -+ /* Function that may creates more instructions -+ for large value on adjusting stack pointer. -+ -+@@ -1342,17 +1396,25 @@ nds32_needs_double_word_align (machine_mode mode, const_tree type) -+ } -+ -+ /* Return true if FUNC is a naked function. */ -+-static bool -++bool -+ nds32_naked_function_p (tree func) -+ { -+- tree t; -++ /* FOR BACKWARD COMPATIBILITY, -++ we need to support 'no_prologue' attribute as well. */ -++ tree t_naked; -++ tree t_no_prologue; -+ -+ if (TREE_CODE (func) != FUNCTION_DECL) -+ abort (); -+ -+- t = lookup_attribute ("naked", DECL_ATTRIBUTES (func)); -++ /* We have to use lookup_attribute() to check attributes. -++ Because attr_naked_p and attr_no_prologue_p are set in -++ nds32_compute_stack_frame() and the function has not been -++ invoked yet. */ -++ t_naked = lookup_attribute ("naked", DECL_ATTRIBUTES (func)); -++ t_no_prologue = lookup_attribute ("no_prologue", DECL_ATTRIBUTES (func)); -+ -+- return (t != NULL_TREE); -++ return ((t_naked != NULL_TREE) || (t_no_prologue != NULL_TREE)); -+ } -+ -+ /* Function that determine whether a load postincrement is a good thing to use -+@@ -1569,6 +1631,11 @@ nds32_register_pass ( -+ static void -+ nds32_register_passes (void) -+ { -++ nds32_register_pass ( -++ make_pass_nds32_fp_as_gp, -++ PASS_POS_INSERT_BEFORE, -++ "ira"); -++ -+ nds32_register_pass ( -+ make_pass_nds32_relax_opt, -+ PASS_POS_INSERT_AFTER, -+@@ -1636,6 +1703,9 @@ nds32_conditional_register_usage (void) -+ { -+ int regno; -+ -++ if (TARGET_LINUX_ABI) -++ fixed_regs[TP_REGNUM] = 1; -++ -+ if (TARGET_HARD_FLOAT) -+ { -+ for (regno = NDS32_FIRST_FPR_REGNUM; -+@@ -1987,6 +2057,16 @@ nds32_function_arg_boundary (machine_mode mode, const_tree type) -+ : PARM_BOUNDARY); -+ } -+ -++bool -++nds32_vector_mode_supported_p (machine_mode mode) -++{ -++ if (mode == V4QImode -++ || mode == V2HImode) -++ return NDS32_EXT_DSP_P (); -++ -++ return false; -++} -++ -+ /* -- How Scalar Function Values Are Returned. */ -+ -+ static rtx -+@@ -2124,56 +2204,12 @@ static void -+ nds32_asm_function_end_prologue (FILE *file) -+ { -+ fprintf (file, "\t! END PROLOGUE\n"); -+- -+- /* If frame pointer is NOT needed and -mfp-as-gp is issued, -+- we can generate special directive: ".omit_fp_begin" -+- to guide linker doing fp-as-gp optimization. -+- However, for a naked function, which means -+- it should not have prologue/epilogue, -+- using fp-as-gp still requires saving $fp by push/pop behavior and -+- there is no benefit to use fp-as-gp on such small function. -+- So we need to make sure this function is NOT naked as well. */ -+- if (!frame_pointer_needed -+- && !cfun->machine->naked_p -+- && cfun->machine->fp_as_gp_p) -+- { -+- fprintf (file, "\t! ----------------------------------------\n"); -+- fprintf (file, "\t! Guide linker to do " -+- "link time optimization: fp-as-gp\n"); -+- fprintf (file, "\t! We add one more instruction to " -+- "initialize $fp near to $gp location.\n"); -+- fprintf (file, "\t! If linker fails to use fp-as-gp transformation,\n"); -+- fprintf (file, "\t! this extra instruction should be " -+- "eliminated at link stage.\n"); -+- fprintf (file, "\t.omit_fp_begin\n"); -+- fprintf (file, "\tla\t$fp,_FP_BASE_\n"); -+- fprintf (file, "\t! ----------------------------------------\n"); -+- } -+ } -+ -+ /* Before rtl epilogue has been expanded, this function is used. */ -+ static void -+ nds32_asm_function_begin_epilogue (FILE *file) -+ { -+- /* If frame pointer is NOT needed and -mfp-as-gp is issued, -+- we can generate special directive: ".omit_fp_end" -+- to claim fp-as-gp optimization range. -+- However, for a naked function, -+- which means it should not have prologue/epilogue, -+- using fp-as-gp still requires saving $fp by push/pop behavior and -+- there is no benefit to use fp-as-gp on such small function. -+- So we need to make sure this function is NOT naked as well. */ -+- if (!frame_pointer_needed -+- && !cfun->machine->naked_p -+- && cfun->machine->fp_as_gp_p) -+- { -+- fprintf (file, "\t! ----------------------------------------\n"); -+- fprintf (file, "\t! Claim the range of fp-as-gp " -+- "link time optimization\n"); -+- fprintf (file, "\t.omit_fp_end\n"); -+- fprintf (file, "\t! ----------------------------------------\n"); -+- } -+- -+ fprintf (file, "\t! BEGIN EPILOGUE\n"); -+ } -+ -+@@ -2200,6 +2236,26 @@ nds32_asm_output_mi_thunk (FILE *file, tree thunk ATTRIBUTE_UNUSED, -+ ? 1 -+ : 0); -+ -++ if (flag_pic) -++ { -++ fprintf (file, "\tsmw.adm\t$r31, [$r31], $r31, 4\n"); -++ fprintf (file, "\tsethi\t%s, hi20(_GLOBAL_OFFSET_TABLE_-8)\n", -++ reg_names [PIC_OFFSET_TABLE_REGNUM]); -++ fprintf (file, "\tori\t%s, %s, lo12(_GLOBAL_OFFSET_TABLE_-4)\n", -++ reg_names [PIC_OFFSET_TABLE_REGNUM], -++ reg_names [PIC_OFFSET_TABLE_REGNUM]); -++ -++ if (TARGET_ISA_V3) -++ fprintf (file, "\tadd5.pc\t$gp\n"); -++ else -++ { -++ fprintf (file, "\tmfusr\t$ta, $pc\n"); -++ fprintf (file, "\tadd\t%s, $ta, %s\n", -++ reg_names [PIC_OFFSET_TABLE_REGNUM], -++ reg_names [PIC_OFFSET_TABLE_REGNUM]); -++ } -++ } -++ -+ if (delta != 0) -+ { -+ if (satisfies_constraint_Is15 (GEN_INT (delta))) -+@@ -2224,9 +2280,23 @@ nds32_asm_output_mi_thunk (FILE *file, tree thunk ATTRIBUTE_UNUSED, -+ } -+ } -+ -+- fprintf (file, "\tb\t"); -+- assemble_name (file, XSTR (XEXP (DECL_RTL (function), 0), 0)); -+- fprintf (file, "\n"); -++ if (flag_pic) -++ { -++ fprintf (file, "\tla\t$ta, "); -++ assemble_name (file, XSTR (XEXP (DECL_RTL (function), 0), 0)); -++ fprintf (file, "@PLT\n"); -++ fprintf (file, "\t! epilogue\n"); -++ fprintf (file, "\tlwi.bi\t%s, [%s], 4\n", -++ reg_names[PIC_OFFSET_TABLE_REGNUM], -++ reg_names[STACK_POINTER_REGNUM]); -++ fprintf (file, "\tbr\t$ta\n"); -++ } -++ else -++ { -++ fprintf (file, "\tb\t"); -++ assemble_name (file, XSTR (XEXP (DECL_RTL (function), 0), 0)); -++ fprintf (file, "\n"); -++ } -+ -+ final_end_function (); -+ } -+@@ -2242,15 +2312,20 @@ nds32_function_ok_for_sibcall (tree decl, -+ -+ /* 1. Do not apply sibling call if -mv3push is enabled, -+ because pop25 instruction also represents return behavior. -+- 2. If this function is a variadic function, do not apply sibling call -++ 2. If this function is a isr function, do not apply sibling call -++ because it may perform the behavior that user does not expect. -++ 3. If this function is a variadic function, do not apply sibling call -+ because the stack layout may be a mess. -+- 3. We don't want to apply sibling call optimization for indirect -++ 4. We don't want to apply sibling call optimization for indirect -+ sibcall because the pop behavior in epilogue may pollute the -+ content of caller-saved regsiter when the register is used for -+- indirect sibcall. */ -++ indirect sibcall. -++ 5. In pic mode, it may use some registers for PLT call. */ -+ return (!TARGET_V3PUSH -++ && !nds32_isr_function_p (current_function_decl) -+ && (cfun->machine->va_args_size == 0) -+- && decl); -++ && decl -++ && !flag_pic); -+ } -+ -+ /* Determine whether we need to enable warning for function return check. */ -+@@ -2566,6 +2641,13 @@ nds32_legitimate_address_p (machine_mode mode, rtx x, bool strict) -+ -+ case SYMBOL_REF: -+ /* (mem (symbol_ref A)) => [symbol_ref] */ -++ -++ if (flag_pic || SYMBOL_REF_TLS_MODEL (x)) -++ return false; -++ -++ if (TARGET_ICT_MODEL_LARGE && nds32_indirect_call_referenced_p (x)) -++ return false; -++ -+ /* If -mcmodel=large, the 'symbol_ref' is not a valid address -+ during or after LRA/reload phase. */ -+ if (TARGET_CMODEL_LARGE -+@@ -2577,7 +2659,8 @@ nds32_legitimate_address_p (machine_mode mode, rtx x, bool strict) -+ the 'symbol_ref' is not a valid address during or after -+ LRA/reload phase. */ -+ if (TARGET_CMODEL_MEDIUM -+- && NDS32_SYMBOL_REF_RODATA_P (x) -++ && (NDS32_SYMBOL_REF_RODATA_P (x) -++ || CONSTANT_POOL_ADDRESS_P (x)) -+ && (reload_completed -+ || reload_in_progress -+ || lra_in_progress)) -+@@ -2599,6 +2682,10 @@ nds32_legitimate_address_p (machine_mode mode, rtx x, bool strict) -+ { -+ /* Now we see the [ + const_addr ] pattern, but we need -+ some further checking. */ -++ -++ if (flag_pic || SYMBOL_REF_TLS_MODEL (op0)) -++ return false; -++ -+ /* If -mcmodel=large, the 'const_addr' is not a valid address -+ during or after LRA/reload phase. */ -+ if (TARGET_CMODEL_LARGE -+@@ -2675,17 +2762,202 @@ nds32_legitimate_address_p (machine_mode mode, rtx x, bool strict) -+ -+ case LO_SUM: -+ /* (mem (lo_sum (reg) (symbol_ref))) */ -+- /* (mem (lo_sum (reg) (const))) */ -+- gcc_assert (REG_P (XEXP (x, 0))); -+- if (GET_CODE (XEXP (x, 1)) == SYMBOL_REF -+- || GET_CODE (XEXP (x, 1)) == CONST) -+- return nds32_legitimate_address_p (mode, XEXP (x, 1), strict); -+- else -++ /* (mem (lo_sum (reg) (const (plus (symbol_ref) (reg)))) */ -++ /* TLS case: (mem (lo_sum (reg) (const (unspec symbol_ref X)))) */ -++ /* The LO_SUM is a valid address if and only if we would like to -++ generate 32-bit full address memory access with any of following -++ circumstance: -++ 1. -mcmodel=large. -++ 2. -mcmodel=medium and the symbol_ref references to rodata. */ -++ { -++ rtx sym = NULL_RTX; -++ -++ if (flag_pic) -++ return false; -++ -++ if (!REG_P (XEXP (x, 0))) -++ return false; -++ -++ if (GET_CODE (XEXP (x, 1)) == SYMBOL_REF) -++ sym = XEXP (x, 1); -++ else if (GET_CODE (XEXP (x, 1)) == CONST) -++ { -++ rtx plus = XEXP(XEXP (x, 1), 0); -++ if (GET_CODE (plus) == PLUS) -++ sym = XEXP (plus, 0); -++ else if (GET_CODE (plus) == UNSPEC) -++ sym = XVECEXP (plus, 0, 0); -++ } -++ else -++ return false; -++ -++ gcc_assert (GET_CODE (sym) == SYMBOL_REF); -++ -++ if (TARGET_ICT_MODEL_LARGE -++ && nds32_indirect_call_referenced_p (sym)) -++ return true; -++ -++ if (TARGET_CMODEL_LARGE) -++ return true; -++ else if (TARGET_CMODEL_MEDIUM -++ && NDS32_SYMBOL_REF_RODATA_P (sym)) -++ return true; -++ else -++ return false; -++ } -++ -++ default: -++ return false; -++ } -++} -++ -++static rtx -++nds32_legitimize_address (rtx x, -++ rtx oldx ATTRIBUTE_UNUSED, -++ machine_mode mode ATTRIBUTE_UNUSED) -++{ -++ if (nds32_tls_referenced_p (x)) -++ x = nds32_legitimize_tls_address (x); -++ else if (flag_pic && SYMBOLIC_CONST_P (x)) -++ x = nds32_legitimize_pic_address (x); -++ else if (TARGET_ICT_MODEL_LARGE && nds32_indirect_call_referenced_p (x)) -++ x = nds32_legitimize_ict_address (x); -++ -++ return x; -++} -++ -++static bool -++nds32_legitimate_constant_p (machine_mode mode, rtx x) -++{ -++ switch (GET_CODE (x)) -++ { -++ case CONST_DOUBLE: -++ if ((TARGET_FPU_SINGLE || TARGET_FPU_DOUBLE) -++ && (mode == DFmode || mode == SFmode)) -+ return false; -++ break; -++ case CONST: -++ x = XEXP (x, 0); -++ -++ if (GET_CODE (x) == PLUS) -++ { -++ if (!CONST_INT_P (XEXP (x, 1))) -++ return false; -++ x = XEXP (x, 0); -++ } -++ -++ if (GET_CODE (x) == UNSPEC) -++ { -++ switch (XINT (x, 1)) -++ { -++ case UNSPEC_GOT: -++ case UNSPEC_GOTOFF: -++ case UNSPEC_PLT: -++ case UNSPEC_TLSGD: -++ case UNSPEC_TLSLD: -++ case UNSPEC_TLSIE: -++ case UNSPEC_TLSLE: -++ case UNSPEC_ICT: -++ return false; -++ default: -++ return true; -++ } -++ } -++ break; -++ case SYMBOL_REF: -++ /* TLS symbols need a call to resolve in -++ precompute_register_parameters. */ -++ if (SYMBOL_REF_TLS_MODEL (x)) -++ return false; -++ break; -++ default: -++ return true; -++ } -++ -++ return true; -++} -+ -++/* Reorgnize the UNSPEC CONST and return its direct symbol. */ -++static rtx -++nds32_delegitimize_address (rtx x) -++{ -++ x = delegitimize_mem_from_attrs (x); -++ -++ if (GET_CODE(x) == CONST) -++ { -++ rtx inner = XEXP (x, 0); -++ -++ /* Handle for GOTOFF. */ -++ if (GET_CODE (inner) == PLUS) -++ inner = XEXP (inner, 0); -++ -++ if (GET_CODE (inner) == UNSPEC) -++ { -++ switch (XINT (inner, 1)) -++ { -++ case UNSPEC_GOTINIT: -++ case UNSPEC_GOT: -++ case UNSPEC_GOTOFF: -++ case UNSPEC_PLT: -++ case UNSPEC_TLSGD: -++ case UNSPEC_TLSLD: -++ case UNSPEC_TLSIE: -++ case UNSPEC_TLSLE: -++ case UNSPEC_ICT: -++ x = XVECEXP (inner, 0, 0); -++ break; -++ default: -++ break; -++ } -++ } -++ } -++ return x; -++} -++ -++static machine_mode -++nds32_vectorize_preferred_simd_mode (scalar_mode mode) -++{ -++ if (!NDS32_EXT_DSP_P ()) -++ return word_mode; -++ -++ switch (mode) -++ { -++ case E_QImode: -++ return V4QImode; -++ case E_HImode: -++ return V2HImode; -++ default: -++ return word_mode; -++ } -++} -++ -++static bool -++nds32_cannot_force_const_mem (machine_mode mode ATTRIBUTE_UNUSED, rtx x) -++{ -++ switch (GET_CODE (x)) -++ { -++ case CONST: -++ return !nds32_legitimate_constant_p (mode, x); -++ case SYMBOL_REF: -++ /* All symbols have to be accessed through gp-relative in PIC mode. */ -++ /* We don't want to force symbol as constant pool in .text section, -++ because we use the gp-relatived instruction to load in small -++ or medium model. */ -++ if (flag_pic -++ || SYMBOL_REF_TLS_MODEL (x) -++ || TARGET_CMODEL_SMALL -++ || TARGET_CMODEL_MEDIUM) -++ return true; -++ break; -++ case CONST_INT: -++ case CONST_DOUBLE: -++ if (flag_pic && (lra_in_progress || reload_completed)) -++ return true; -++ break; -+ default: -+ return false; -+ } -++ return false; -+ } -+ -+ -+@@ -2731,13 +3003,33 @@ nds32_canonicalize_comparison (int *code, -+ /* Describing Relative Costs of Operations. */ -+ -+ static int -+-nds32_register_move_cost (machine_mode mode ATTRIBUTE_UNUSED, -++nds32_register_move_cost (machine_mode mode, -+ reg_class_t from, -+ reg_class_t to) -+ { -++ /* In garywolf cpu, FPR to GPR is chaper than other cpu. */ -++ if (TARGET_PIPELINE_GRAYWOLF) -++ { -++ if (GET_MODE_SIZE (mode) == 8) -++ { -++ /* DPR to GPR. */ -++ if (from == FP_REGS && to != FP_REGS) -++ return 3; -++ /* GPR to DPR. */ -++ if (from != FP_REGS && to == FP_REGS) -++ return 2; -++ } -++ else -++ { -++ if ((from == FP_REGS && to != FP_REGS) -++ || (from != FP_REGS && to == FP_REGS)) -++ return 2; -++ } -++ } -++ -+ if ((from == FP_REGS && to != FP_REGS) -+ || (from != FP_REGS && to == FP_REGS)) -+- return 9; -++ return 3; -+ else if (from == HIGH_REGS || to == HIGH_REGS) -+ return optimize_size ? 6 : 2; -+ else -+@@ -2825,6 +3117,9 @@ nds32_asm_file_start (void) -+ { -+ default_file_start (); -+ -++ if (flag_pic) -++ fprintf (asm_out_file, "\t.pic\n"); -++ -+ /* Tell assembler which ABI we are using. */ -+ fprintf (asm_out_file, "\t! ABI version\n"); -+ if (TARGET_HARD_FLOAT) -+@@ -2835,10 +3130,36 @@ nds32_asm_file_start (void) -+ /* Tell assembler that this asm code is generated by compiler. */ -+ fprintf (asm_out_file, "\t! This asm file is generated by compiler\n"); -+ fprintf (asm_out_file, "\t.flag\tverbatim\n"); -+- /* Give assembler the size of each vector for interrupt handler. */ -+- fprintf (asm_out_file, "\t! This vector size directive is required " -+- "for checking inconsistency on interrupt handler\n"); -+- fprintf (asm_out_file, "\t.vec_size\t%d\n", nds32_isr_vector_size); -++ -++ /* Insert directive for linker to distinguish object's ict flag. */ -++ if (!TARGET_LINUX_ABI) -++ { -++ if (TARGET_ICT_MODEL_LARGE) -++ fprintf (asm_out_file, "\t.ict_model\tlarge\n"); -++ else -++ fprintf (asm_out_file, "\t.ict_model\tsmall\n"); -++ } -++ -++ /* We need to provide the size of each vector for interrupt handler -++ under elf toolchain. */ -++ if (!TARGET_LINUX_ABI) -++ { -++ fprintf (asm_out_file, "\t! This vector size directive is required " -++ "for checking inconsistency on interrupt handler\n"); -++ fprintf (asm_out_file, "\t.vec_size\t%d\n", nds32_isr_vector_size); -++ } -++ -++ /* If user enables '-mforce-fp-as-gp' or compiles programs with -Os, -++ the compiler may produce 'la $fp,_FP_BASE_' instruction -++ at prologue for fp-as-gp optimization. -++ We should emit weak reference of _FP_BASE_ to avoid undefined reference -++ in case user does not pass '--relax' option to linker. */ -++ if (!TARGET_LINUX_ABI && (TARGET_FORCE_FP_AS_GP || optimize_size)) -++ { -++ fprintf (asm_out_file, "\t! This weak reference is required to do " -++ "fp-as-gp link time optimization\n"); -++ fprintf (asm_out_file, "\t.weak\t_FP_BASE_\n"); -++ } -+ -+ fprintf (asm_out_file, "\t! ------------------------------------\n"); -+ -+@@ -2849,6 +3170,49 @@ nds32_asm_file_start (void) -+ if (TARGET_ISA_V3M) -+ fprintf (asm_out_file, "\t! ISA family\t\t: %s\n", "V3M"); -+ -++ switch (nds32_cpu_option) -++ { -++ case CPU_N6: -++ fprintf (asm_out_file, "\t! Pipeline model\t: %s\n", "N6"); -++ break; -++ -++ case CPU_N7: -++ fprintf (asm_out_file, "\t! Pipeline model\t: %s\n", "N7"); -++ break; -++ -++ case CPU_N8: -++ fprintf (asm_out_file, "\t! Pipeline model\t: %s\n", "N8"); -++ break; -++ -++ case CPU_E8: -++ fprintf (asm_out_file, "\t! Pipeline model\t: %s\n", "E8"); -++ break; -++ -++ case CPU_N9: -++ fprintf (asm_out_file, "\t! Pipeline model\t: %s\n", "N9"); -++ break; -++ -++ case CPU_N10: -++ fprintf (asm_out_file, "\t! Pipeline model\t: %s\n", "N10"); -++ break; -++ -++ case CPU_GRAYWOLF: -++ fprintf (asm_out_file, "\t! Pipeline model\t: %s\n", "Graywolf"); -++ break; -++ -++ case CPU_N12: -++ case CPU_N13: -++ fprintf (asm_out_file, "\t! Pipeline model\t: %s\n", "N13"); -++ break; -++ -++ case CPU_SIMPLE: -++ fprintf (asm_out_file, "\t! Pipeline model\t: %s\n", "SIMPLE"); -++ break; -++ -++ default: -++ gcc_unreachable (); -++ } -++ -+ if (TARGET_CMODEL_SMALL) -+ fprintf (asm_out_file, "\t! Code model\t\t: %s\n", "SMALL"); -+ if (TARGET_CMODEL_MEDIUM) -+@@ -2926,9 +3290,65 @@ nds32_asm_file_end (void) -+ { -+ nds32_asm_file_end_for_isr (); -+ -++ /* The NDS32 Linux stack is mapped non-executable by default, so add a -++ .note.GNU-stack section. */ -++ if (TARGET_LINUX_ABI) -++ file_end_indicate_exec_stack (); -++ -+ fprintf (asm_out_file, "\t! ------------------------------------\n"); -+ } -+ -++static bool -++nds32_asm_output_addr_const_extra (FILE *file, rtx x) -++{ -++ if (GET_CODE (x) == UNSPEC) -++ { -++ switch (XINT (x, 1)) -++ { -++ case UNSPEC_GOTINIT: -++ output_addr_const (file, XVECEXP (x, 0, 0)); -++ break; -++ case UNSPEC_GOTOFF: -++ output_addr_const (file, XVECEXP (x, 0, 0)); -++ fputs ("@GOTOFF", file); -++ break; -++ case UNSPEC_GOT: -++ output_addr_const (file, XVECEXP (x, 0, 0)); -++ fputs ("@GOT", file); -++ break; -++ case UNSPEC_PLT: -++ output_addr_const (file, XVECEXP (x, 0, 0)); -++ fputs ("@PLT", file); -++ break; -++ case UNSPEC_TLSGD: -++ output_addr_const (file, XVECEXP (x, 0, 0)); -++ fputs ("@TLSDESC", file); -++ break; -++ case UNSPEC_TLSLD: -++ output_addr_const (file, XVECEXP (x, 0, 0)); -++ fputs ("@TLSDESC", file); -++ break; -++ case UNSPEC_TLSIE: -++ output_addr_const (file, XVECEXP (x, 0, 0)); -++ fputs ("@GOTTPOFF", file); -++ break; -++ case UNSPEC_TLSLE: -++ output_addr_const (file, XVECEXP (x, 0, 0)); -++ fputs ("@TPOFF", file); -++ break; -++ case UNSPEC_ICT: -++ output_addr_const (file, XVECEXP (x, 0, 0)); -++ fputs ("@ICT", file); -++ break; -++ default: -++ return false; -++ } -++ return true; -++ } -++ else -++ return false; -++} -++ -+ /* -- Output and Generation of Labels. */ -+ -+ static void -+@@ -2944,13 +3364,15 @@ nds32_asm_globalize_label (FILE *stream, const char *name) -+ static void -+ nds32_print_operand (FILE *stream, rtx x, int code) -+ { -++ HOST_WIDE_INT op_value = 0; -+ HOST_WIDE_INT one_position; -+ HOST_WIDE_INT zero_position; -+ bool pick_lsb_p = false; -+ bool pick_msb_p = false; -+ int regno; -+ -+- int op_value; -++ if (CONST_INT_P (x)) -++ op_value = INTVAL (x); -+ -+ switch (code) -+ { -+@@ -2976,6 +3398,18 @@ nds32_print_operand (FILE *stream, rtx x, int code) -+ -+ /* No need to handle following process, so return immediately. */ -+ return; -++ -++ case 'v': -++ gcc_assert (CONST_INT_P (x) -++ && (INTVAL (x) == 0 -++ || INTVAL (x) == 8 -++ || INTVAL (x) == 16 -++ || INTVAL (x) == 24)); -++ fprintf (stream, HOST_WIDE_INT_PRINT_DEC, INTVAL (x) / 8); -++ -++ /* No need to handle following process, so return immediately. */ -++ return; -++ -+ case 'B': -+ /* Use exact_log2() to search the 1-bit position. */ -+ gcc_assert (CONST_INT_P (x)); -+@@ -3003,7 +3437,6 @@ nds32_print_operand (FILE *stream, rtx x, int code) -+ case 'V': -+ /* 'x' is supposed to be CONST_INT, get the value. */ -+ gcc_assert (CONST_INT_P (x)); -+- op_value = INTVAL (x); -+ -+ /* According to the Andes architecture, -+ the system/user register index range is 0 ~ 1023. -+@@ -3083,8 +3516,15 @@ nds32_print_operand (FILE *stream, rtx x, int code) -+ switch (GET_CODE (x)) -+ { -+ case LABEL_REF: -++ output_addr_const (stream, x); -++ break; -++ -+ case SYMBOL_REF: -+ output_addr_const (stream, x); -++ -++ if (!TARGET_LINUX_ABI && nds32_indirect_call_referenced_p (x)) -++ fprintf (stream, "@ICT"); -++ -+ break; -+ -+ case REG: -+@@ -3167,6 +3607,17 @@ nds32_print_operand (FILE *stream, rtx x, int code) -+ output_addr_const (stream, x); -+ break; -+ -++ case CONST_VECTOR: -++ fprintf (stream, HOST_WIDE_INT_PRINT_HEX, const_vector_to_hwint (x)); -++ break; -++ -++ case LO_SUM: -++ /* This is a special case for inline assembly using memory address 'p'. -++ The inline assembly code is expected to use pesudo instruction -++ for the operand. EX: la */ -++ output_addr_const (stream, XEXP(x, 1)); -++ break; -++ -+ default: -+ /* Generally, output_addr_const () is able to handle most cases. -+ We want to see what CODE could appear, -+@@ -3178,7 +3629,9 @@ nds32_print_operand (FILE *stream, rtx x, int code) -+ } -+ -+ static void -+-nds32_print_operand_address (FILE *stream, machine_mode /*mode*/, rtx x) -++nds32_print_operand_address (FILE *stream, -++ machine_mode mode ATTRIBUTE_UNUSED, -++ rtx x) -+ { -+ rtx op0, op1; -+ -+@@ -3193,6 +3646,16 @@ nds32_print_operand_address (FILE *stream, machine_mode /*mode*/, rtx x) -+ fputs ("]", stream); -+ break; -+ -++ case LO_SUM: -++ /* This is a special case for inline assembly using memory operand 'm'. -++ The inline assembly code is expected to use pesudo instruction -++ for the operand. EX: [ls].[bhw] */ -++ fputs ("[ + ", stream); -++ op1 = XEXP (x, 1); -++ output_addr_const (stream, op1); -++ fputs ("]", stream); -++ break; -++ -+ case REG: -+ /* Forbid using static chain register ($r16) -+ on reduced-set registers configuration. */ -+@@ -3259,6 +3722,20 @@ nds32_print_operand_address (FILE *stream, machine_mode /*mode*/, rtx x) -+ reg_names[REGNO (XEXP (op0, 0))], -+ sv); -+ } -++ else if (GET_CODE (op0) == ASHIFT && REG_P (op1)) -++ { -++ /* [Ra + Rb << sv] -++ In normal, ASHIFT can be converted to MULT like above case. -++ But when the address rtx does not go through canonicalize_address -++ defined in fwprop, we'll need this case. */ -++ int sv = INTVAL (XEXP (op0, 1)); -++ gcc_assert (sv <= 3 && sv >=0); -++ -++ fprintf (stream, "[%s + %s << %d]", -++ reg_names[REGNO (op1)], -++ reg_names[REGNO (XEXP (op0, 0))], -++ sv); -++ } -+ else -+ { -+ /* The control flow is not supposed to be here. */ -+@@ -3453,6 +3930,27 @@ nds32_merge_decl_attributes (tree olddecl, tree newdecl) -+ static void -+ nds32_insert_attributes (tree decl, tree *attributes) -+ { -++ /* A "indirect_call" function attribute implies "noinline" and "noclone" -++ for elf toolchain to support ROM patch mechanism. */ -++ if (TREE_CODE (decl) == FUNCTION_DECL -++ && lookup_attribute ("indirect_call", *attributes) != NULL) -++ { -++ tree new_attrs = *attributes; -++ -++ if (TARGET_LINUX_ABI) -++ error("cannot use indirect_call attribute under linux toolchain"); -++ -++ if (lookup_attribute ("noinline", new_attrs) == NULL) -++ new_attrs = tree_cons (get_identifier ("noinline"), NULL, new_attrs); -++ if (lookup_attribute ("noclone", new_attrs) == NULL) -++ new_attrs = tree_cons (get_identifier ("noclone"), NULL, new_attrs); -++ -++ if (!TREE_PUBLIC (decl)) -++ error("indirect_call attribute can't apply for static function"); -++ -++ *attributes = new_attrs; -++ } -++ -+ /* For function declaration, we need to check isr-specific attributes: -+ 1. Call nds32_check_isr_attrs_conflict() to check any conflict. -+ 2. Check valid integer value for interrupt/exception. -+@@ -3478,6 +3976,38 @@ nds32_insert_attributes (tree decl, tree *attributes) -+ excp = lookup_attribute ("exception", func_attrs); -+ reset = lookup_attribute ("reset", func_attrs); -+ -++ /* The following code may use attribute arguments. If there is no -++ argument from source code, it will cause segmentation fault. -++ Therefore, return dircetly and report error message later. */ -++ if ((intr && TREE_VALUE (intr) == NULL) -++ || (excp && TREE_VALUE (excp) == NULL) -++ || (reset && TREE_VALUE (reset) == NULL)) -++ return; -++ -++ /* ------------------------------------------------------------- */ -++ /* FIXME: -++ FOR BACKWARD COMPATIBILITY, we need to support following patterns: -++ -++ __attribute__((interrupt("XXX;YYY;id=ZZZ"))) -++ __attribute__((exception("XXX;YYY;id=ZZZ"))) -++ __attribute__((reset("vectors=XXX;nmi_func=YYY;warm_func=ZZZ"))) -++ -++ If interrupt/exception/reset appears and its argument is a -++ STRING_CST, we will use other functions to parse string in the -++ nds32_construct_isr_vectors_information() and then set necessary -++ isr information in the nds32_isr_vectors[] array. Here we can -++ just return immediately to avoid new-syntax checking. */ -++ if (intr != NULL_TREE -++ && TREE_CODE (TREE_VALUE (TREE_VALUE (intr))) == STRING_CST) -++ return; -++ if (excp != NULL_TREE -++ && TREE_CODE (TREE_VALUE (TREE_VALUE (excp))) == STRING_CST) -++ return; -++ if (reset != NULL_TREE -++ && TREE_CODE (TREE_VALUE (TREE_VALUE (reset))) == STRING_CST) -++ return; -++ /* ------------------------------------------------------------- */ -++ -+ if (intr || excp) -+ { -+ /* Deal with interrupt/exception. */ -+@@ -3597,7 +4127,9 @@ nds32_option_override (void) -+ } -+ if (TARGET_ISA_V3) -+ { -+- /* Under V3 ISA, currently nothing should be strictly set. */ -++ /* If this is ARCH_V3J, we need to enable TARGET_REDUCED_REGS. */ -++ if (nds32_arch_option == ARCH_V3J) -++ target_flags |= MASK_REDUCED_REGS; -+ } -+ if (TARGET_ISA_V3M) -+ { -+@@ -3609,6 +4141,9 @@ nds32_option_override (void) -+ target_flags &= ~MASK_EXT_PERF2; -+ /* Under V3M ISA, we need to strictly disable TARGET_EXT_STRING. */ -+ target_flags &= ~MASK_EXT_STRING; -++ -++ if (flag_pic) -++ error ("not support -fpic option for v3m toolchain"); -+ } -+ -+ /* See if we are using reduced-set registers: -+@@ -3626,6 +4161,12 @@ nds32_option_override (void) -+ fixed_regs[r] = call_used_regs[r] = 1; -+ } -+ -++ /* See if user explicitly would like to use fp-as-gp optimization. -++ If so, we must prevent $fp from being allocated -++ during register allocation. */ -++ if (TARGET_FORCE_FP_AS_GP) -++ fixed_regs[FP_REGNUM] = call_used_regs[FP_REGNUM] = 1; -++ -+ if (!TARGET_16_BIT) -+ { -+ /* Under no 16 bit ISA, we need to strictly disable TARGET_V3PUSH. */ -+@@ -3642,9 +4183,7 @@ nds32_option_override (void) -+ "must be enable '-mext-fpu-sp' or '-mext-fpu-dp'"); -+ } -+ -+- /* Currently, we don't support PIC code generation yet. */ -+- if (flag_pic) -+- sorry ("position-independent code not supported"); -++ nds32_init_rtx_costs (); -+ -+ nds32_register_passes (); -+ } -+@@ -3658,8 +4197,11 @@ nds32_md_asm_adjust (vec &outputs ATTRIBUTE_UNUSED, -+ vec &constraints ATTRIBUTE_UNUSED, -+ vec &clobbers, HARD_REG_SET &clobbered_regs) -+ { -+- clobbers.safe_push (gen_rtx_REG (SImode, TA_REGNUM)); -+- SET_HARD_REG_BIT (clobbered_regs, TA_REGNUM); -++ if (!flag_inline_asm_r15) -++ { -++ clobbers.safe_push (gen_rtx_REG (SImode, TA_REGNUM)); -++ SET_HARD_REG_BIT (clobbered_regs, TA_REGNUM); -++ } -+ return NULL; -+ } -+ -+@@ -3686,6 +4228,13 @@ nds32_expand_builtin (tree exp, -+ return nds32_expand_builtin_impl (exp, target, subtarget, mode, ignore); -+ } -+ -++/* Implement TARGET_INIT_LIBFUNCS. */ -++static void -++nds32_init_libfuncs (void) -++{ -++ if (TARGET_LINUX_ABI) -++ init_sync_libfuncs (UNITS_PER_WORD); -++} -+ -+ /* ------------------------------------------------------------------------ */ -+ -+@@ -3702,6 +4251,16 @@ nds32_cpu_cpp_builtins(struct cpp_reader *pfile) -+ builtin_define ("__nds32__"); -+ builtin_define ("__NDS32__"); -+ -++ /* We need to provide builtin macro to describe the size of -++ each vector for interrupt handler under elf toolchain. */ -++ if (!TARGET_LINUX_ABI) -++ { -++ if (TARGET_ISR_VECTOR_SIZE_4_BYTE) -++ builtin_define ("__NDS32_ISR_VECTOR_SIZE_4__"); -++ else -++ builtin_define ("__NDS32_ISR_VECTOR_SIZE_16__"); -++ } -++ -+ if (TARGET_HARD_FLOAT) -+ builtin_define ("__NDS32_ABI_2FP_PLUS__"); -+ else -+@@ -3769,6 +4328,8 @@ nds32_cpu_cpp_builtins(struct cpp_reader *pfile) -+ builtin_define ("__NDS32_GP_DIRECT__"); -+ if (TARGET_VH) -+ builtin_define ("__NDS32_VH__"); -++ if (NDS32_EXT_DSP_P ()) -++ builtin_define ("__NDS32_EXT_DSP__"); -+ -+ if (TARGET_BIG_ENDIAN) -+ builtin_define ("__big_endian__"); -+@@ -4041,6 +4602,10 @@ nds32_expand_prologue (void) -+ The result will be in cfun->machine. */ -+ nds32_compute_stack_frame (); -+ -++ /* Check frame_pointer_needed again to prevent fp is need after reload. */ -++ if (frame_pointer_needed) -++ cfun->machine->fp_as_gp_p = false; -++ -+ /* If this is a variadic function, first we need to push argument -+ registers that hold the unnamed argument value. */ -+ if (cfun->machine->va_args_size != 0) -+@@ -4065,7 +4630,7 @@ nds32_expand_prologue (void) -+ -+ /* If the function is 'naked', -+ we do not have to generate prologue code fragment. */ -+- if (cfun->machine->naked_p) -++ if (cfun->machine->naked_p && !flag_pic) -+ return; -+ -+ /* Get callee_first_regno and callee_last_regno. */ -+@@ -4194,9 +4759,15 @@ nds32_expand_prologue (void) -+ -1 * sp_adjust); -+ } -+ -+- /* Prevent the instruction scheduler from -+- moving instructions across the boundary. */ -+- emit_insn (gen_blockage ()); -++ /* Emit gp setup instructions for -fpic. */ -++ if (flag_pic && df_regs_ever_live_p (PIC_OFFSET_TABLE_REGNUM)) -++ nds32_emit_load_gp (); -++ -++ /* If user applies -mno-sched-prolog-epilog option, -++ we need to prevent instructions of function body from being -++ scheduled with stack adjustment in prologue. */ -++ if (!flag_sched_prolog_epilog) -++ emit_insn (gen_blockage ()); -+ } -+ -+ /* Function for normal multiple pop epilogue. */ -+@@ -4210,9 +4781,11 @@ nds32_expand_epilogue (bool sibcall_p) -+ The result will be in cfun->machine. */ -+ nds32_compute_stack_frame (); -+ -+- /* Prevent the instruction scheduler from -+- moving instructions across the boundary. */ -+- emit_insn (gen_blockage ()); -++ /* If user applies -mno-sched-prolog-epilog option, -++ we need to prevent instructions of function body from being -++ scheduled with stack adjustment in epilogue. */ -++ if (!flag_sched_prolog_epilog) -++ emit_insn (gen_blockage ()); -+ -+ /* If the function is 'naked', we do not have to generate -+ epilogue code fragment BUT 'ret' instruction. -+@@ -4238,7 +4811,16 @@ nds32_expand_epilogue (bool sibcall_p) -+ /* Generate return instruction by using 'return_internal' pattern. -+ Make sure this instruction is after gen_blockage(). */ -+ if (!sibcall_p) -+- emit_jump_insn (gen_return_internal ()); -++ { -++ /* We need to further check attributes to determine whether -++ there should be return instruction at epilogue. -++ If the attribute naked exists but -mno-ret-in-naked-func -++ is issued, there is NO need to generate return instruction. */ -++ if (cfun->machine->attr_naked_p && !flag_ret_in_naked_func) -++ return; -++ -++ emit_jump_insn (gen_return_internal ()); -++ } -+ return; -+ } -+ -+@@ -4435,9 +5017,13 @@ nds32_expand_prologue_v3push (void) -+ if (cfun->machine->callee_saved_gpr_regs_size > 0) -+ df_set_regs_ever_live (FP_REGNUM, 1); -+ -++ /* Check frame_pointer_needed again to prevent fp is need after reload. */ -++ if (frame_pointer_needed) -++ cfun->machine->fp_as_gp_p = false; -++ -+ /* If the function is 'naked', -+ we do not have to generate prologue code fragment. */ -+- if (cfun->machine->naked_p) -++ if (cfun->machine->naked_p && !flag_pic) -+ return; -+ -+ /* Get callee_first_regno and callee_last_regno. */ -+@@ -4565,6 +5151,10 @@ nds32_expand_prologue_v3push (void) -+ -1 * sp_adjust); -+ } -+ -++ /* Emit gp setup instructions for -fpic. */ -++ if (flag_pic && df_regs_ever_live_p (PIC_OFFSET_TABLE_REGNUM)) -++ nds32_emit_load_gp (); -++ -+ /* Prevent the instruction scheduler from -+ moving instructions across the boundary. */ -+ emit_insn (gen_blockage ()); -+@@ -4590,9 +5180,19 @@ nds32_expand_epilogue_v3pop (bool sibcall_p) -+ if (cfun->machine->naked_p) -+ { -+ /* Generate return instruction by using 'return_internal' pattern. -+- Make sure this instruction is after gen_blockage(). */ -++ Make sure this instruction is after gen_blockage(). -++ First we need to check this is a function without sibling call. */ -+ if (!sibcall_p) -+- emit_jump_insn (gen_return_internal ()); -++ { -++ /* We need to further check attributes to determine whether -++ there should be return instruction at epilogue. -++ If the attribute naked exists but -mno-ret-in-naked-func -++ is issued, there is NO need to generate return instruction. */ -++ if (cfun->machine->attr_naked_p && !flag_ret_in_naked_func) -++ return; -++ -++ emit_jump_insn (gen_return_internal ()); -++ } -+ return; -+ } -+ -+@@ -4756,6 +5356,11 @@ nds32_can_use_return_insn (void) -+ if (!reload_completed) -+ return 0; -+ -++ /* If attribute 'naked' appears but -mno-ret-in-naked-func is used, -++ we cannot use return instruction. */ -++ if (cfun->machine->attr_naked_p && !flag_ret_in_naked_func) -++ return 0; -++ -+ sp_adjust = cfun->machine->local_size -+ + cfun->machine->out_args_size -+ + cfun->machine->callee_saved_area_gpr_padding_bytes -+@@ -5009,6 +5614,9 @@ nds32_use_blocks_for_constant_p (machine_mode mode, -+ #undef TARGET_FUNCTION_ARG_BOUNDARY -+ #define TARGET_FUNCTION_ARG_BOUNDARY nds32_function_arg_boundary -+ -++#undef TARGET_VECTOR_MODE_SUPPORTED_P -++#define TARGET_VECTOR_MODE_SUPPORTED_P nds32_vector_mode_supported_p -++ -+ /* -- How Scalar Function Values Are Returned. */ -+ -+ #undef TARGET_FUNCTION_VALUE -+@@ -5086,6 +5694,21 @@ nds32_use_blocks_for_constant_p (machine_mode mode, -+ #undef TARGET_LEGITIMATE_ADDRESS_P -+ #define TARGET_LEGITIMATE_ADDRESS_P nds32_legitimate_address_p -+ -++#undef TARGET_LEGITIMIZE_ADDRESS -++#define TARGET_LEGITIMIZE_ADDRESS nds32_legitimize_address -++ -++#undef TARGET_LEGITIMATE_CONSTANT_P -++#define TARGET_LEGITIMATE_CONSTANT_P nds32_legitimate_constant_p -++ -++#undef TARGET_VECTORIZE_PREFERRED_SIMD_MODE -++#define TARGET_VECTORIZE_PREFERRED_SIMD_MODE nds32_vectorize_preferred_simd_mode -++ -++#undef TARGET_CANNOT_FORCE_CONST_MEM -++#define TARGET_CANNOT_FORCE_CONST_MEM nds32_cannot_force_const_mem -++ -++#undef TARGET_DELEGITIMIZE_ADDRESS -++#define TARGET_DELEGITIMIZE_ADDRESS nds32_delegitimize_address -++ -+ -+ /* Anchored Addresses. */ -+ -+@@ -5146,6 +5769,9 @@ nds32_use_blocks_for_constant_p (machine_mode mode, -+ #undef TARGET_ASM_ALIGNED_SI_OP -+ #define TARGET_ASM_ALIGNED_SI_OP "\t.word\t" -+ -++#undef TARGET_ASM_OUTPUT_ADDR_CONST_EXTRA -++#define TARGET_ASM_OUTPUT_ADDR_CONST_EXTRA nds32_asm_output_addr_const_extra -++ -+ /* -- Output of Uninitialized Variables. */ -+ -+ /* -- Output and Generation of Labels. */ -+@@ -5215,6 +5841,9 @@ nds32_use_blocks_for_constant_p (machine_mode mode, -+ -+ /* Emulating TLS. */ -+ -++#undef TARGET_HAVE_TLS -++#define TARGET_HAVE_TLS TARGET_LINUX_ABI -++ -+ -+ /* Defining coprocessor specifics for MIPS targets. */ -+ -+@@ -5242,6 +5871,8 @@ nds32_use_blocks_for_constant_p (machine_mode mode, -+ #undef TARGET_EXPAND_BUILTIN -+ #define TARGET_EXPAND_BUILTIN nds32_expand_builtin -+ -++#undef TARGET_INIT_LIBFUNCS -++#define TARGET_INIT_LIBFUNCS nds32_init_libfuncs -+ -+ #undef TARGET_USE_BLOCKS_FOR_CONSTANT_P -+ #define TARGET_USE_BLOCKS_FOR_CONSTANT_P nds32_use_blocks_for_constant_p -+diff --git a/gcc/config/nds32/nds32.h b/gcc/config/nds32/nds32.h -+index 29edccdd040..e3ceb632ebd 100644 -+--- a/gcc/config/nds32/nds32.h -++++ b/gcc/config/nds32/nds32.h -+@@ -36,6 +36,16 @@ -+ #define NDS32_SYMBOL_REF_RODATA_P(x) \ -+ ((SYMBOL_REF_FLAGS (x) & NDS32_SYMBOL_FLAG_RODATA) != 0) -+ -++enum nds32_relax_insn_type -++{ -++ RELAX_ORI, -++ RELAX_PLT_ADD, -++ RELAX_TLS_ADD_or_LW, -++ RELAX_TLS_ADD_LW, -++ RELAX_TLS_LW_JRAL, -++ RELAX_DONE -++}; -++ -+ /* Classifies expand result for expand helper function. */ -+ enum nds32_expand_result_type -+ { -+@@ -140,6 +150,9 @@ enum nds32_16bit_address_type -+ Check gcc/common/config/nds32/nds32-common.c for the optimizations that -+ apply -malways-align. */ -+ #define NDS32_ALIGN_P() (TARGET_ALWAYS_ALIGN) -++ -++#define NDS32_EXT_DSP_P() (TARGET_EXT_DSP && !TARGET_FORCE_NO_EXT_DSP) -++ -+ /* Get alignment according to mode or type information. -+ When 'type' is nonnull, there is no need to look at 'mode'. */ -+ #define NDS32_MODE_TYPE_ALIGN(mode, type) \ -+@@ -305,6 +318,10 @@ struct GTY(()) machine_function -+ 2. The rtl lowering and optimization are close to target code. -+ For this case we need address to be strictly aligned. */ -+ int strict_aligned_p; -++ -++ /* Record two similar attributes status. */ -++ int attr_naked_p; -++ int attr_no_prologue_p; -+ }; -+ -+ /* A C structure that contains the arguments information. */ -+@@ -350,7 +367,8 @@ enum nds32_isr_nested_type -+ { -+ NDS32_NESTED, -+ NDS32_NOT_NESTED, -+- NDS32_NESTED_READY -++ NDS32_NESTED_READY, -++ NDS32_CRITICAL -+ }; -+ -+ /* Define structure to record isr information. -+@@ -378,6 +396,13 @@ struct nds32_isr_info -+ unless user specifies attribute to change it. */ -+ enum nds32_isr_nested_type nested_type; -+ -++ /* Secure isr level. -++ Currently we have 0-3 security level. -++ It should be set to 0 by default. -++ For security processors, this is determined by secure -++ attribute or compiler options. */ -++ unsigned int security_level; -++ -+ /* Total vectors. -+ The total vectors = interrupt + exception numbers + reset. -+ It should be set to 0 by default. -+@@ -439,7 +464,30 @@ enum nds32_builtins -+ NDS32_BUILTIN_FFB, -+ NDS32_BUILTIN_FFMISM, -+ NDS32_BUILTIN_FLMISM, -+- -++ NDS32_BUILTIN_KADDW, -++ NDS32_BUILTIN_KSUBW, -++ NDS32_BUILTIN_KADDH, -++ NDS32_BUILTIN_KSUBH, -++ NDS32_BUILTIN_KDMBB, -++ NDS32_BUILTIN_V_KDMBB, -++ NDS32_BUILTIN_KDMBT, -++ NDS32_BUILTIN_V_KDMBT, -++ NDS32_BUILTIN_KDMTB, -++ NDS32_BUILTIN_V_KDMTB, -++ NDS32_BUILTIN_KDMTT, -++ NDS32_BUILTIN_V_KDMTT, -++ NDS32_BUILTIN_KHMBB, -++ NDS32_BUILTIN_V_KHMBB, -++ NDS32_BUILTIN_KHMBT, -++ NDS32_BUILTIN_V_KHMBT, -++ NDS32_BUILTIN_KHMTB, -++ NDS32_BUILTIN_V_KHMTB, -++ NDS32_BUILTIN_KHMTT, -++ NDS32_BUILTIN_V_KHMTT, -++ NDS32_BUILTIN_KSLRAW, -++ NDS32_BUILTIN_KSLRAW_U, -++ NDS32_BUILTIN_RDOV, -++ NDS32_BUILTIN_CLROV, -+ NDS32_BUILTIN_ROTR, -+ NDS32_BUILTIN_SVA, -+ NDS32_BUILTIN_SVS, -+@@ -512,7 +560,295 @@ enum nds32_builtins -+ NDS32_BUILTIN_SET_TRIG_LEVEL, -+ NDS32_BUILTIN_SET_TRIG_EDGE, -+ NDS32_BUILTIN_GET_TRIG_TYPE, -+- -++ NDS32_BUILTIN_DSP_BEGIN, -++ NDS32_BUILTIN_ADD16, -++ NDS32_BUILTIN_V_UADD16, -++ NDS32_BUILTIN_V_SADD16, -++ NDS32_BUILTIN_RADD16, -++ NDS32_BUILTIN_V_RADD16, -++ NDS32_BUILTIN_URADD16, -++ NDS32_BUILTIN_V_URADD16, -++ NDS32_BUILTIN_KADD16, -++ NDS32_BUILTIN_V_KADD16, -++ NDS32_BUILTIN_UKADD16, -++ NDS32_BUILTIN_V_UKADD16, -++ NDS32_BUILTIN_SUB16, -++ NDS32_BUILTIN_V_USUB16, -++ NDS32_BUILTIN_V_SSUB16, -++ NDS32_BUILTIN_RSUB16, -++ NDS32_BUILTIN_V_RSUB16, -++ NDS32_BUILTIN_URSUB16, -++ NDS32_BUILTIN_V_URSUB16, -++ NDS32_BUILTIN_KSUB16, -++ NDS32_BUILTIN_V_KSUB16, -++ NDS32_BUILTIN_UKSUB16, -++ NDS32_BUILTIN_V_UKSUB16, -++ NDS32_BUILTIN_CRAS16, -++ NDS32_BUILTIN_V_UCRAS16, -++ NDS32_BUILTIN_V_SCRAS16, -++ NDS32_BUILTIN_RCRAS16, -++ NDS32_BUILTIN_V_RCRAS16, -++ NDS32_BUILTIN_URCRAS16, -++ NDS32_BUILTIN_V_URCRAS16, -++ NDS32_BUILTIN_KCRAS16, -++ NDS32_BUILTIN_V_KCRAS16, -++ NDS32_BUILTIN_UKCRAS16, -++ NDS32_BUILTIN_V_UKCRAS16, -++ NDS32_BUILTIN_CRSA16, -++ NDS32_BUILTIN_V_UCRSA16, -++ NDS32_BUILTIN_V_SCRSA16, -++ NDS32_BUILTIN_RCRSA16, -++ NDS32_BUILTIN_V_RCRSA16, -++ NDS32_BUILTIN_URCRSA16, -++ NDS32_BUILTIN_V_URCRSA16, -++ NDS32_BUILTIN_KCRSA16, -++ NDS32_BUILTIN_V_KCRSA16, -++ NDS32_BUILTIN_UKCRSA16, -++ NDS32_BUILTIN_V_UKCRSA16, -++ NDS32_BUILTIN_ADD8, -++ NDS32_BUILTIN_V_UADD8, -++ NDS32_BUILTIN_V_SADD8, -++ NDS32_BUILTIN_RADD8, -++ NDS32_BUILTIN_V_RADD8, -++ NDS32_BUILTIN_URADD8, -++ NDS32_BUILTIN_V_URADD8, -++ NDS32_BUILTIN_KADD8, -++ NDS32_BUILTIN_V_KADD8, -++ NDS32_BUILTIN_UKADD8, -++ NDS32_BUILTIN_V_UKADD8, -++ NDS32_BUILTIN_SUB8, -++ NDS32_BUILTIN_V_USUB8, -++ NDS32_BUILTIN_V_SSUB8, -++ NDS32_BUILTIN_RSUB8, -++ NDS32_BUILTIN_V_RSUB8, -++ NDS32_BUILTIN_URSUB8, -++ NDS32_BUILTIN_V_URSUB8, -++ NDS32_BUILTIN_KSUB8, -++ NDS32_BUILTIN_V_KSUB8, -++ NDS32_BUILTIN_UKSUB8, -++ NDS32_BUILTIN_V_UKSUB8, -++ NDS32_BUILTIN_SRA16, -++ NDS32_BUILTIN_V_SRA16, -++ NDS32_BUILTIN_SRA16_U, -++ NDS32_BUILTIN_V_SRA16_U, -++ NDS32_BUILTIN_SRL16, -++ NDS32_BUILTIN_V_SRL16, -++ NDS32_BUILTIN_SRL16_U, -++ NDS32_BUILTIN_V_SRL16_U, -++ NDS32_BUILTIN_SLL16, -++ NDS32_BUILTIN_V_SLL16, -++ NDS32_BUILTIN_KSLL16, -++ NDS32_BUILTIN_V_KSLL16, -++ NDS32_BUILTIN_KSLRA16, -++ NDS32_BUILTIN_V_KSLRA16, -++ NDS32_BUILTIN_KSLRA16_U, -++ NDS32_BUILTIN_V_KSLRA16_U, -++ NDS32_BUILTIN_CMPEQ16, -++ NDS32_BUILTIN_V_SCMPEQ16, -++ NDS32_BUILTIN_V_UCMPEQ16, -++ NDS32_BUILTIN_SCMPLT16, -++ NDS32_BUILTIN_V_SCMPLT16, -++ NDS32_BUILTIN_SCMPLE16, -++ NDS32_BUILTIN_V_SCMPLE16, -++ NDS32_BUILTIN_UCMPLT16, -++ NDS32_BUILTIN_V_UCMPLT16, -++ NDS32_BUILTIN_UCMPLE16, -++ NDS32_BUILTIN_V_UCMPLE16, -++ NDS32_BUILTIN_CMPEQ8, -++ NDS32_BUILTIN_V_SCMPEQ8, -++ NDS32_BUILTIN_V_UCMPEQ8, -++ NDS32_BUILTIN_SCMPLT8, -++ NDS32_BUILTIN_V_SCMPLT8, -++ NDS32_BUILTIN_SCMPLE8, -++ NDS32_BUILTIN_V_SCMPLE8, -++ NDS32_BUILTIN_UCMPLT8, -++ NDS32_BUILTIN_V_UCMPLT8, -++ NDS32_BUILTIN_UCMPLE8, -++ NDS32_BUILTIN_V_UCMPLE8, -++ NDS32_BUILTIN_SMIN16, -++ NDS32_BUILTIN_V_SMIN16, -++ NDS32_BUILTIN_UMIN16, -++ NDS32_BUILTIN_V_UMIN16, -++ NDS32_BUILTIN_SMAX16, -++ NDS32_BUILTIN_V_SMAX16, -++ NDS32_BUILTIN_UMAX16, -++ NDS32_BUILTIN_V_UMAX16, -++ NDS32_BUILTIN_SCLIP16, -++ NDS32_BUILTIN_V_SCLIP16, -++ NDS32_BUILTIN_UCLIP16, -++ NDS32_BUILTIN_V_UCLIP16, -++ NDS32_BUILTIN_KHM16, -++ NDS32_BUILTIN_V_KHM16, -++ NDS32_BUILTIN_KHMX16, -++ NDS32_BUILTIN_V_KHMX16, -++ NDS32_BUILTIN_KABS16, -++ NDS32_BUILTIN_V_KABS16, -++ NDS32_BUILTIN_SMIN8, -++ NDS32_BUILTIN_V_SMIN8, -++ NDS32_BUILTIN_UMIN8, -++ NDS32_BUILTIN_V_UMIN8, -++ NDS32_BUILTIN_SMAX8, -++ NDS32_BUILTIN_V_SMAX8, -++ NDS32_BUILTIN_UMAX8, -++ NDS32_BUILTIN_V_UMAX8, -++ NDS32_BUILTIN_KABS8, -++ NDS32_BUILTIN_V_KABS8, -++ NDS32_BUILTIN_SUNPKD810, -++ NDS32_BUILTIN_V_SUNPKD810, -++ NDS32_BUILTIN_SUNPKD820, -++ NDS32_BUILTIN_V_SUNPKD820, -++ NDS32_BUILTIN_SUNPKD830, -++ NDS32_BUILTIN_V_SUNPKD830, -++ NDS32_BUILTIN_SUNPKD831, -++ NDS32_BUILTIN_V_SUNPKD831, -++ NDS32_BUILTIN_ZUNPKD810, -++ NDS32_BUILTIN_V_ZUNPKD810, -++ NDS32_BUILTIN_ZUNPKD820, -++ NDS32_BUILTIN_V_ZUNPKD820, -++ NDS32_BUILTIN_ZUNPKD830, -++ NDS32_BUILTIN_V_ZUNPKD830, -++ NDS32_BUILTIN_ZUNPKD831, -++ NDS32_BUILTIN_V_ZUNPKD831, -++ NDS32_BUILTIN_RADDW, -++ NDS32_BUILTIN_URADDW, -++ NDS32_BUILTIN_RSUBW, -++ NDS32_BUILTIN_URSUBW, -++ NDS32_BUILTIN_SRA_U, -++ NDS32_BUILTIN_KSLL, -++ NDS32_BUILTIN_PKBB16, -++ NDS32_BUILTIN_V_PKBB16, -++ NDS32_BUILTIN_PKBT16, -++ NDS32_BUILTIN_V_PKBT16, -++ NDS32_BUILTIN_PKTB16, -++ NDS32_BUILTIN_V_PKTB16, -++ NDS32_BUILTIN_PKTT16, -++ NDS32_BUILTIN_V_PKTT16, -++ NDS32_BUILTIN_SMMUL, -++ NDS32_BUILTIN_SMMUL_U, -++ NDS32_BUILTIN_KMMAC, -++ NDS32_BUILTIN_KMMAC_U, -++ NDS32_BUILTIN_KMMSB, -++ NDS32_BUILTIN_KMMSB_U, -++ NDS32_BUILTIN_KWMMUL, -++ NDS32_BUILTIN_KWMMUL_U, -++ NDS32_BUILTIN_SMMWB, -++ NDS32_BUILTIN_V_SMMWB, -++ NDS32_BUILTIN_SMMWB_U, -++ NDS32_BUILTIN_V_SMMWB_U, -++ NDS32_BUILTIN_SMMWT, -++ NDS32_BUILTIN_V_SMMWT, -++ NDS32_BUILTIN_SMMWT_U, -++ NDS32_BUILTIN_V_SMMWT_U, -++ NDS32_BUILTIN_KMMAWB, -++ NDS32_BUILTIN_V_KMMAWB, -++ NDS32_BUILTIN_KMMAWB_U, -++ NDS32_BUILTIN_V_KMMAWB_U, -++ NDS32_BUILTIN_KMMAWT, -++ NDS32_BUILTIN_V_KMMAWT, -++ NDS32_BUILTIN_KMMAWT_U, -++ NDS32_BUILTIN_V_KMMAWT_U, -++ NDS32_BUILTIN_SMBB, -++ NDS32_BUILTIN_V_SMBB, -++ NDS32_BUILTIN_SMBT, -++ NDS32_BUILTIN_V_SMBT, -++ NDS32_BUILTIN_SMTT, -++ NDS32_BUILTIN_V_SMTT, -++ NDS32_BUILTIN_KMDA, -++ NDS32_BUILTIN_V_KMDA, -++ NDS32_BUILTIN_KMXDA, -++ NDS32_BUILTIN_V_KMXDA, -++ NDS32_BUILTIN_SMDS, -++ NDS32_BUILTIN_V_SMDS, -++ NDS32_BUILTIN_SMDRS, -++ NDS32_BUILTIN_V_SMDRS, -++ NDS32_BUILTIN_SMXDS, -++ NDS32_BUILTIN_V_SMXDS, -++ NDS32_BUILTIN_KMABB, -++ NDS32_BUILTIN_V_KMABB, -++ NDS32_BUILTIN_KMABT, -++ NDS32_BUILTIN_V_KMABT, -++ NDS32_BUILTIN_KMATT, -++ NDS32_BUILTIN_V_KMATT, -++ NDS32_BUILTIN_KMADA, -++ NDS32_BUILTIN_V_KMADA, -++ NDS32_BUILTIN_KMAXDA, -++ NDS32_BUILTIN_V_KMAXDA, -++ NDS32_BUILTIN_KMADS, -++ NDS32_BUILTIN_V_KMADS, -++ NDS32_BUILTIN_KMADRS, -++ NDS32_BUILTIN_V_KMADRS, -++ NDS32_BUILTIN_KMAXDS, -++ NDS32_BUILTIN_V_KMAXDS, -++ NDS32_BUILTIN_KMSDA, -++ NDS32_BUILTIN_V_KMSDA, -++ NDS32_BUILTIN_KMSXDA, -++ NDS32_BUILTIN_V_KMSXDA, -++ NDS32_BUILTIN_SMAL, -++ NDS32_BUILTIN_V_SMAL, -++ NDS32_BUILTIN_BITREV, -++ NDS32_BUILTIN_WEXT, -++ NDS32_BUILTIN_BPICK, -++ NDS32_BUILTIN_INSB, -++ NDS32_BUILTIN_SADD64, -++ NDS32_BUILTIN_UADD64, -++ NDS32_BUILTIN_RADD64, -++ NDS32_BUILTIN_URADD64, -++ NDS32_BUILTIN_KADD64, -++ NDS32_BUILTIN_UKADD64, -++ NDS32_BUILTIN_SSUB64, -++ NDS32_BUILTIN_USUB64, -++ NDS32_BUILTIN_RSUB64, -++ NDS32_BUILTIN_URSUB64, -++ NDS32_BUILTIN_KSUB64, -++ NDS32_BUILTIN_UKSUB64, -++ NDS32_BUILTIN_SMAR64, -++ NDS32_BUILTIN_SMSR64, -++ NDS32_BUILTIN_UMAR64, -++ NDS32_BUILTIN_UMSR64, -++ NDS32_BUILTIN_KMAR64, -++ NDS32_BUILTIN_KMSR64, -++ NDS32_BUILTIN_UKMAR64, -++ NDS32_BUILTIN_UKMSR64, -++ NDS32_BUILTIN_SMALBB, -++ NDS32_BUILTIN_V_SMALBB, -++ NDS32_BUILTIN_SMALBT, -++ NDS32_BUILTIN_V_SMALBT, -++ NDS32_BUILTIN_SMALTT, -++ NDS32_BUILTIN_V_SMALTT, -++ NDS32_BUILTIN_SMALDA, -++ NDS32_BUILTIN_V_SMALDA, -++ NDS32_BUILTIN_SMALXDA, -++ NDS32_BUILTIN_V_SMALXDA, -++ NDS32_BUILTIN_SMALDS, -++ NDS32_BUILTIN_V_SMALDS, -++ NDS32_BUILTIN_SMALDRS, -++ NDS32_BUILTIN_V_SMALDRS, -++ NDS32_BUILTIN_SMALXDS, -++ NDS32_BUILTIN_V_SMALXDS, -++ NDS32_BUILTIN_SMUL16, -++ NDS32_BUILTIN_V_SMUL16, -++ NDS32_BUILTIN_SMULX16, -++ NDS32_BUILTIN_V_SMULX16, -++ NDS32_BUILTIN_UMUL16, -++ NDS32_BUILTIN_V_UMUL16, -++ NDS32_BUILTIN_UMULX16, -++ NDS32_BUILTIN_V_UMULX16, -++ NDS32_BUILTIN_SMSLDA, -++ NDS32_BUILTIN_V_SMSLDA, -++ NDS32_BUILTIN_SMSLXDA, -++ NDS32_BUILTIN_V_SMSLXDA, -++ NDS32_BUILTIN_UCLIP32, -++ NDS32_BUILTIN_SCLIP32, -++ NDS32_BUILTIN_KABS, -++ NDS32_BUILTIN_UALOAD_U16, -++ NDS32_BUILTIN_UALOAD_S16, -++ NDS32_BUILTIN_UALOAD_U8, -++ NDS32_BUILTIN_UALOAD_S8, -++ NDS32_BUILTIN_UASTORE_U16, -++ NDS32_BUILTIN_UASTORE_S16, -++ NDS32_BUILTIN_UASTORE_U8, -++ NDS32_BUILTIN_UASTORE_S8, -++ NDS32_BUILTIN_DSP_END, -+ NDS32_BUILTIN_UNALIGNED_FEATURE, -+ NDS32_BUILTIN_ENABLE_UNALIGNED, -+ NDS32_BUILTIN_DISABLE_UNALIGNED, -+@@ -521,16 +857,30 @@ enum nds32_builtins -+ -+ /* ------------------------------------------------------------------------ */ -+ -+-#define TARGET_ISA_V2 (nds32_arch_option == ARCH_V2) -++#define TARGET_ISR_VECTOR_SIZE_4_BYTE \ -++ (nds32_isr_vector_size == 4) -+ -++#define TARGET_ISA_V2 (nds32_arch_option == ARCH_V2) -+ #define TARGET_ISA_V3 \ -+ (nds32_arch_option == ARCH_V3 \ -++ || nds32_arch_option == ARCH_V3J \ -+ || nds32_arch_option == ARCH_V3F \ -+ || nds32_arch_option == ARCH_V3S) -+ #define TARGET_ISA_V3M (nds32_arch_option == ARCH_V3M) -+ -++#define TARGET_PIPELINE_N7 \ -++ (nds32_cpu_option == CPU_N7) -++#define TARGET_PIPELINE_N8 \ -++ (nds32_cpu_option == CPU_N6 \ -++ || nds32_cpu_option == CPU_N8) -+ #define TARGET_PIPELINE_N9 \ -+ (nds32_cpu_option == CPU_N9) -++#define TARGET_PIPELINE_N10 \ -++ (nds32_cpu_option == CPU_N10) -++#define TARGET_PIPELINE_N13 \ -++ (nds32_cpu_option == CPU_N12 || nds32_cpu_option == CPU_N13) -++#define TARGET_PIPELINE_GRAYWOLF \ -++ (nds32_cpu_option == CPU_GRAYWOLF) -+ #define TARGET_PIPELINE_SIMPLE \ -+ (nds32_cpu_option == CPU_SIMPLE) -+ -+@@ -541,6 +891,12 @@ enum nds32_builtins -+ #define TARGET_CMODEL_LARGE \ -+ (nds32_cmodel_option == CMODEL_LARGE) -+ -++#define TARGET_ICT_MODEL_SMALL \ -++ (nds32_ict_model == ICT_MODEL_SMALL) -++ -++#define TARGET_ICT_MODEL_LARGE \ -++ (nds32_ict_model == ICT_MODEL_LARGE) -++ -+ /* When -mcmodel=small or -mcmodel=medium, -+ compiler may generate gp-base instruction directly. */ -+ #define TARGET_GP_DIRECT \ -+@@ -576,6 +932,21 @@ enum nds32_builtins -+ #endif -+ -+ #define TARGET_CONFIG_FPU_DEFAULT NDS32_CONFIG_FPU_2 -++ -++/* ------------------------------------------------------------------------ */ -++ -++#ifdef TARGET_DEFAULT_RELAX -++# define NDS32_RELAX_SPEC " %{!mno-relax:--relax}" -++#else -++# define NDS32_RELAX_SPEC " %{mrelax:--relax}" -++#endif -++ -++#ifdef TARGET_DEFAULT_EXT_DSP -++# define NDS32_EXT_DSP_SPEC " %{!mno-ext-dsp:-mext-dsp}" -++#else -++# define NDS32_EXT_DSP_SPEC "" -++#endif -++ -+ /* ------------------------------------------------------------------------ */ -+ -+ /* Controlling the Compilation Driver. */ -+@@ -591,11 +962,15 @@ enum nds32_builtins -+ {"float", "%{!mfloat-abi=*:-mfloat-abi=%(VALUE)}" } -+ -+ #define CC1_SPEC \ -+- "" -++ NDS32_EXT_DSP_SPEC -+ -+ #define ASM_SPEC \ -+ " %{mbig-endian:-EB} %{mlittle-endian:-EL}" \ -+ " %{march=*:-march=%*}" \ -++ " %{mno-16-bit|mno-16bit:-mno-16bit-ext}" \ -++ " %{march=v3m:%{!mfull-regs:%{!mreduced-regs:-mreduced-regs}}}" \ -++ " %{mfull-regs:-mno-reduced-regs}" \ -++ " %{mreduced-regs:-mreduced-regs}" \ -+ " %{mabi=*:-mabi=v%*}" \ -+ " %{mconfig-fpu=*:-mfpu-freg=%*}" \ -+ " %{mext-fpu-mac:-mmac}" \ -+@@ -603,35 +978,9 @@ enum nds32_builtins -+ " %{mext-fpu-sp:-mfpu-sp-ext}" \ -+ " %{mno-ext-fpu-sp:-mno-fpu-sp-ext}" \ -+ " %{mext-fpu-dp:-mfpu-dp-ext}" \ -+- " %{mno-ext-fpu-sp:-mno-fpu-dp-ext}" -+- -+-/* If user issues -mrelax, we need to pass '--relax' to linker. */ -+-#define LINK_SPEC \ -+- " %{mbig-endian:-EB} %{mlittle-endian:-EL}" \ -+- " %{mrelax:--relax}" -+- -+-#define LIB_SPEC \ -+- " -lc -lgloss" -+- -+-/* The option -mno-ctor-dtor can disable constructor/destructor feature -+- by applying different crt stuff. In the convention, crt0.o is the -+- startup file without constructor/destructor; -+- crt1.o, crti.o, crtbegin.o, crtend.o, and crtn.o are the -+- startup files with constructor/destructor. -+- Note that crt0.o, crt1.o, crti.o, and crtn.o are provided -+- by newlib/mculib/glibc/ublic, while crtbegin.o and crtend.o are -+- currently provided by GCC for nds32 target. -+- -+- For nds32 target so far: -+- If -mno-ctor-dtor, we are going to link -+- "crt0.o [user objects]". -+- If general cases, we are going to link -+- "crt1.o crtbegin1.o [user objects] crtend1.o". */ -+-#define STARTFILE_SPEC \ -+- " %{!mno-ctor-dtor:crt1.o%s;:crt0.o%s}" \ -+- " %{!mno-ctor-dtor:crtbegin1.o%s}" -+-#define ENDFILE_SPEC \ -+- " %{!mno-ctor-dtor:crtend1.o%s}" -++ " %{mno-ext-fpu-sp:-mno-fpu-dp-ext}" \ -++ " %{mext-dsp:-mdsp-ext}" \ -++ " %{O|O1|O2|O3|Ofast:-O1;:-Os}" -+ -+ /* The TARGET_BIG_ENDIAN_DEFAULT is defined if we -+ configure gcc with --target=nds32be-* setting. -+@@ -642,9 +991,11 @@ enum nds32_builtins -+ # define NDS32_ENDIAN_DEFAULT "mlittle-endian" -+ #endif -+ -+-/* Currently we only have elf toolchain, -+- where -mcmodel=medium is always the default. */ -+-#define NDS32_CMODEL_DEFAULT "mcmodel=medium" -++#if TARGET_ELF -++# define NDS32_CMODEL_DEFAULT "mcmodel=medium" -++#else -++# define NDS32_CMODEL_DEFAULT "mcmodel=large" -++#endif -+ -+ #define MULTILIB_DEFAULTS \ -+ { NDS32_ENDIAN_DEFAULT, NDS32_CMODEL_DEFAULT } -+@@ -1139,12 +1490,17 @@ enum reg_class -+ -+ #define PIC_OFFSET_TABLE_REGNUM GP_REGNUM -+ -++#define SYMBOLIC_CONST_P(X) \ -++(GET_CODE (X) == SYMBOL_REF \ -++ || GET_CODE (X) == LABEL_REF \ -++ || (GET_CODE (X) == CONST && symbolic_reference_mentioned_p (X))) -++ -+ -+ /* Defining the Output Assembler Language. */ -+ -+ #define ASM_COMMENT_START "!" -+ -+-#define ASM_APP_ON "! #APP" -++#define ASM_APP_ON "! #APP\n" -+ -+ #define ASM_APP_OFF "! #NO_APP\n" -+ -+diff --git a/gcc/config/nds32/nds32.md b/gcc/config/nds32/nds32.md -+index 3b8107e8fbf..f5349d7cc76 100644 -+--- a/gcc/config/nds32/nds32.md -++++ b/gcc/config/nds32/nds32.md -+@@ -56,24 +56,29 @@ -+ ;; ------------------------------------------------------------------------ -+ -+ ;; CPU pipeline model. -+-(define_attr "pipeline_model" "n7,n8,e8,n9,simple" -++(define_attr "pipeline_model" "n7,n8,e8,n9,n10,graywolf,n13,simple" -+ (const -+ (cond [(match_test "nds32_cpu_option == CPU_N7") (const_string "n7") -+ (match_test "nds32_cpu_option == CPU_E8") (const_string "e8") -+ (match_test "nds32_cpu_option == CPU_N6 || nds32_cpu_option == CPU_N8") (const_string "n8") -+ (match_test "nds32_cpu_option == CPU_N9") (const_string "n9") -++ (match_test "nds32_cpu_option == CPU_N10") (const_string "n10") -++ (match_test "nds32_cpu_option == CPU_GRAYWOLF") (const_string "graywolf") -++ (match_test "nds32_cpu_option == CPU_N12") (const_string "n13") -++ (match_test "nds32_cpu_option == CPU_N13") (const_string "n13") -+ (match_test "nds32_cpu_option == CPU_SIMPLE") (const_string "simple")] -+ (const_string "n9")))) -+ -+ ;; Insn type, it is used to default other attribute values. -+ (define_attr "type" -+ "unknown,load,store,load_multiple,store_multiple,alu,alu_shift,pbsad,pbsada,mul,mac,div,branch,mmu,misc,\ -+- falu,fmuls,fmuld,fmacs,fmacd,fdivs,fdivd,fsqrts,fsqrtd,fcmp,fabs,fcpy,fcmov,fmfsr,fmfdr,fmtsr,fmtdr,fload,fstore" -++ falu,fmuls,fmuld,fmacs,fmacd,fdivs,fdivd,fsqrts,fsqrtd,fcmp,fabs,fcpy,fcmov,fmfsr,fmfdr,fmtsr,fmtdr,fload,fstore,\ -++ dalu,dalu64,daluround,dcmp,dclip,dmul,dmac,dinsb,dpack,dbpick,dwext" -+ (const_string "unknown")) -+ -+ ;; Insn sub-type -+ (define_attr "subtype" -+- "simple,shift" -++ "simple,shift,saturation" -+ (const_string "simple")) -+ -+ ;; Length, in bytes, default is 4-bytes. -+@@ -133,6 +138,7 @@ -+ -+ ;; ---------------------------------------------------------------------------- -+ -++(include "nds32-dspext.md") -+ -+ ;; Move instructions. -+ -+@@ -209,6 +215,27 @@ -+ low12_int)); -+ DONE; -+ } -++ -++ if ((REG_P (operands[0]) || GET_CODE (operands[0]) == SUBREG) -++ && SYMBOLIC_CONST_P (operands[1])) -++ { -++ if (TARGET_ICT_MODEL_LARGE -++ && nds32_indirect_call_referenced_p (operands[1])) -++ { -++ nds32_expand_ict_move (operands); -++ DONE; -++ } -++ else if (nds32_tls_referenced_p (operands [1])) -++ { -++ nds32_expand_tls_move (operands); -++ DONE; -++ } -++ else if (flag_pic) -++ { -++ nds32_expand_pic_move (operands); -++ DONE; -++ } -++ } -+ }) -+ -+ (define_insn "*mov" -+@@ -271,8 +298,8 @@ -+ ;; We use nds32_symbolic_operand to limit that only CONST/SYMBOL_REF/LABEL_REF -+ ;; are able to match such instruction template. -+ (define_insn "move_addr" -+- [(set (match_operand:SI 0 "register_operand" "=l, r") -+- (match_operand:SI 1 "nds32_symbolic_operand" " i, i"))] -++ [(set (match_operand:SI 0 "nds32_general_register_operand" "=l, r") -++ (match_operand:SI 1 "nds32_nonunspec_symbolic_operand" " i, i"))] -+ "" -+ "la\t%0, %1" -+ [(set_attr "type" "alu") -+@@ -351,13 +378,58 @@ -+ -+ -+ ;; ---------------------------------------------------------------------------- -++(define_expand "extv" -++ [(set (match_operand 0 "register_operand" "") -++ (sign_extract (match_operand 1 "nonimmediate_operand" "") -++ (match_operand 2 "const_int_operand" "") -++ (match_operand 3 "const_int_operand" "")))] -++ "" -++{ -++ enum nds32_expand_result_type result = nds32_expand_extv (operands); -++ switch (result) -++ { -++ case EXPAND_DONE: -++ DONE; -++ break; -++ case EXPAND_FAIL: -++ FAIL; -++ break; -++ case EXPAND_CREATE_TEMPLATE: -++ break; -++ default: -++ gcc_unreachable (); -++ } -++}) -++ -++(define_expand "insv" -++ [(set (zero_extract (match_operand 0 "nonimmediate_operand" "") -++ (match_operand 1 "const_int_operand" "") -++ (match_operand 2 "const_int_operand" "")) -++ (match_operand 3 "register_operand" ""))] -++ "" -++{ -++ enum nds32_expand_result_type result = nds32_expand_insv (operands); -++ switch (result) -++ { -++ case EXPAND_DONE: -++ DONE; -++ break; -++ case EXPAND_FAIL: -++ FAIL; -++ break; -++ case EXPAND_CREATE_TEMPLATE: -++ break; -++ default: -++ gcc_unreachable (); -++ } -++}) -+ -+ ;; Arithmetic instructions. -+ -+ (define_insn "addsi3" -+ [(set (match_operand:SI 0 "register_operand" "= d, l, d, l, d, l, k, l, r, r") -+ (plus:SI (match_operand:SI 1 "register_operand" "% 0, l, 0, l, 0, l, 0, k, r, r") -+- (match_operand:SI 2 "nds32_rimm15s_operand" " In05,In03,Iu05,Iu03, r, l,Is10,Iu06, Is15, r")))] -++ (match_operand:SI 2 "nds32_rimm15s_operand" " In05,In03,Iu05,Iu03, r, l,Is10,IU06, Is15, r")))] -+ "" -+ { -+ switch (which_alternative) -+@@ -1428,11 +1500,30 @@ -+ (clobber (reg:SI LP_REGNUM)) -+ (clobber (reg:SI TA_REGNUM))])] -+ "" -+- "" -++ { -++ rtx insn; -++ rtx sym = XEXP (operands[0], 0); -++ -++ if (TARGET_ICT_MODEL_LARGE -++ && nds32_indirect_call_referenced_p (sym)) -++ { -++ rtx reg = gen_reg_rtx (Pmode); -++ emit_move_insn (reg, sym); -++ operands[0] = gen_const_mem (Pmode, reg); -++ } -++ -++ if (flag_pic) -++ { -++ insn = emit_call_insn (gen_call_internal -++ (XEXP (operands[0], 0), GEN_INT (0))); -++ use_reg (&CALL_INSN_FUNCTION_USAGE (insn), pic_offset_table_rtx); -++ DONE; -++ } -++ } -+ ) -+ -+ (define_insn "call_internal" -+- [(parallel [(call (mem (match_operand:SI 0 "nds32_call_address_operand" "r, i")) -++ [(parallel [(call (mem (match_operand:SI 0 "nds32_call_address_operand" "r, S")) -+ (match_operand 1)) -+ (clobber (reg:SI LP_REGNUM)) -+ (clobber (reg:SI TA_REGNUM))])] -+@@ -1474,9 +1565,11 @@ -+ (const_int 2) -+ (const_int 4)) -+ ;; Alternative 1 -+- (if_then_else (match_test "nds32_long_call_p (operands[0])") -+- (const_int 12) -+- (const_int 4)) -++ (if_then_else (match_test "flag_pic") -++ (const_int 16) -++ (if_then_else (match_test "nds32_long_call_p (operands[0])") -++ (const_int 12) -++ (const_int 4))) -+ ])] -+ ) -+ -+@@ -1492,11 +1585,33 @@ -+ (match_operand 2))) -+ (clobber (reg:SI LP_REGNUM)) -+ (clobber (reg:SI TA_REGNUM))])] -+- "") -++ "" -++ { -++ rtx insn; -++ rtx sym = XEXP (operands[1], 0); -++ -++ if (TARGET_ICT_MODEL_LARGE -++ && nds32_indirect_call_referenced_p (sym)) -++ { -++ rtx reg = gen_reg_rtx (Pmode); -++ emit_move_insn (reg, sym); -++ operands[1] = gen_const_mem (Pmode, reg); -++ } -++ -++ if (flag_pic) -++ { -++ insn = -++ emit_call_insn (gen_call_value_internal -++ (operands[0], XEXP (operands[1], 0), GEN_INT (0))); -++ use_reg (&CALL_INSN_FUNCTION_USAGE (insn), pic_offset_table_rtx); -++ DONE; -++ } -++ } -++) -+ -+ (define_insn "call_value_internal" -+ [(parallel [(set (match_operand 0) -+- (call (mem (match_operand:SI 1 "nds32_call_address_operand" "r, i")) -++ (call (mem (match_operand:SI 1 "nds32_call_address_operand" "r, S")) -+ (match_operand 2))) -+ (clobber (reg:SI LP_REGNUM)) -+ (clobber (reg:SI TA_REGNUM))])] -+@@ -1538,9 +1653,11 @@ -+ (const_int 2) -+ (const_int 4)) -+ ;; Alternative 1 -+- (if_then_else (match_test "nds32_long_call_p (operands[1])") -+- (const_int 12) -+- (const_int 4)) -++ (if_then_else (match_test "flag_pic") -++ (const_int 16) -++ (if_then_else (match_test "nds32_long_call_p (operands[1])") -++ (const_int 12) -++ (const_int 4))) -+ ])] -+ ) -+ -+@@ -1583,10 +1700,21 @@ -+ (const_int 0)) -+ (clobber (reg:SI TA_REGNUM)) -+ (return)])] -+- "") -++ "" -++{ -++ rtx sym = XEXP (operands[0], 0); -++ -++ if (TARGET_ICT_MODEL_LARGE -++ && nds32_indirect_call_referenced_p (sym)) -++ { -++ rtx reg = gen_reg_rtx (Pmode); -++ emit_move_insn (reg, sym); -++ operands[0] = gen_const_mem (Pmode, reg); -++ } -++}) -+ -+ (define_insn "sibcall_internal" -+- [(parallel [(call (mem (match_operand:SI 0 "nds32_call_address_operand" "r, i")) -++ [(parallel [(call (mem (match_operand:SI 0 "nds32_call_address_operand" "r, S")) -+ (match_operand 1)) -+ (clobber (reg:SI TA_REGNUM)) -+ (return)])] -+@@ -1617,9 +1745,11 @@ -+ (const_int 2) -+ (const_int 4)) -+ ;; Alternative 1 -+- (if_then_else (match_test "nds32_long_call_p (operands[0])") -+- (const_int 12) -+- (const_int 4)) -++ (if_then_else (match_test "flag_pic") -++ (const_int 16) -++ (if_then_else (match_test "nds32_long_call_p (operands[0])") -++ (const_int 12) -++ (const_int 4))) -+ ])] -+ ) -+ -+@@ -1633,11 +1763,22 @@ -+ (const_int 0))) -+ (clobber (reg:SI TA_REGNUM)) -+ (return)])] -+- "") -++ "" -++{ -++ rtx sym = XEXP (operands[1], 0); -++ -++ if (TARGET_ICT_MODEL_LARGE -++ && nds32_indirect_call_referenced_p (sym)) -++ { -++ rtx reg = gen_reg_rtx (Pmode); -++ emit_move_insn (reg, sym); -++ operands[1] = gen_const_mem (Pmode, reg); -++ } -++}) -+ -+ (define_insn "sibcall_value_internal" -+ [(parallel [(set (match_operand 0) -+- (call (mem (match_operand:SI 1 "nds32_call_address_operand" "r, i")) -++ (call (mem (match_operand:SI 1 "nds32_call_address_operand" "r, S")) -+ (match_operand 2))) -+ (clobber (reg:SI TA_REGNUM)) -+ (return)])] -+@@ -1668,9 +1809,11 @@ -+ (const_int 2) -+ (const_int 4)) -+ ;; Alternative 1 -+- (if_then_else (match_test "nds32_long_call_p (operands[1])") -+- (const_int 12) -+- (const_int 4)) -++ (if_then_else (match_test "flag_pic") -++ (const_int 16) -++ (if_then_else (match_test "nds32_long_call_p (operands[1])") -++ (const_int 12) -++ (const_int 4))) -+ ])] -+ ) -+ -+@@ -1687,12 +1830,33 @@ -+ nds32_expand_prologue_v3push (); -+ else -+ nds32_expand_prologue (); -++ -++ /* If cfun->machine->fp_as_gp_p is true, we can generate special -++ directive to guide linker doing fp-as-gp optimization. -++ However, for a naked function, which means -++ it should not have prologue/epilogue, -++ using fp-as-gp still requires saving $fp by push/pop behavior and -++ there is no benefit to use fp-as-gp on such small function. -++ So we need to make sure this function is NOT naked as well. */ -++ if (cfun->machine->fp_as_gp_p && !cfun->machine->naked_p) -++ emit_insn (gen_omit_fp_begin (gen_rtx_REG (SImode, FP_REGNUM))); -++ -+ DONE; -+ }) -+ -+ (define_expand "epilogue" [(const_int 0)] -+ "" -+ { -++ /* If cfun->machine->fp_as_gp_p is true, we can generate special -++ directive to guide linker doing fp-as-gp optimization. -++ However, for a naked function, which means -++ it should not have prologue/epilogue, -++ using fp-as-gp still requires saving $fp by push/pop behavior and -++ there is no benefit to use fp-as-gp on such small function. -++ So we need to make sure this function is NOT naked as well. */ -++ if (cfun->machine->fp_as_gp_p && !cfun->machine->naked_p) -++ emit_insn (gen_omit_fp_end (gen_rtx_REG (SImode, FP_REGNUM))); -++ -+ /* Note that only under V3/V3M ISA, we could use v3pop epilogue. -+ In addition, we need to check if v3push is indeed available. */ -+ if (NDS32_V3PUSH_AVAILABLE_P) -+@@ -1792,7 +1956,8 @@ -+ "nds32_can_use_return_insn ()" -+ { -+ /* Emit as the simple return. */ -+- if (cfun->machine->naked_p -++ if (!cfun->machine->fp_as_gp_p -++ && cfun->machine->naked_p -+ && (cfun->machine->va_args_size == 0)) -+ { -+ emit_jump_insn (gen_return_internal ()); -+@@ -1802,9 +1967,14 @@ -+ -+ ;; This pattern is expanded only by the shrink-wrapping optimization -+ ;; on paths where the function prologue has not been executed. -++;; However, such optimization may reorder the prologue/epilogue blocks -++;; together with basic blocks within function body. -++;; So we must disable this pattern if we have already decided -++;; to perform fp_as_gp optimization, which requires prologue to be -++;; first block and epilogue to be last block. -+ (define_expand "simple_return" -+ [(simple_return)] -+- "" -++ "!cfun->machine->fp_as_gp_p" -+ "" -+ ) -+ -+@@ -1823,6 +1993,9 @@ -+ [(simple_return)] -+ "" -+ { -++ if (nds32_isr_function_critical_p (current_function_decl)) -++ return "iret"; -++ -+ if (TARGET_16_BIT) -+ return "ret5"; -+ else -+@@ -1831,9 +2004,11 @@ -+ [(set_attr "type" "branch") -+ (set_attr "enabled" "yes") -+ (set (attr "length") -+- (if_then_else (match_test "TARGET_16_BIT") -+- (const_int 2) -+- (const_int 4)))]) -++ (if_then_else (match_test "nds32_isr_function_critical_p (current_function_decl)") -++ (const_int 4) -++ (if_then_else (match_test "TARGET_16_BIT") -++ (const_int 2) -++ (const_int 4))))]) -+ -+ -+ ;; ---------------------------------------------------------------------------- -+@@ -1868,6 +2043,7 @@ -+ { -+ rtx add_tmp; -+ rtx reg, test; -++ rtx tmp_reg; -+ -+ /* Step A: "k <-- (plus (operands[0]) (-operands[1]))". */ -+ if (operands[1] != const0_rtx) -+@@ -1889,9 +2065,14 @@ -+ emit_jump_insn (gen_cbranchsi4 (test, operands[0], operands[2], -+ operands[4])); -+ -+- /* Step C, D, E, and F, using another temporary register. */ -+- rtx tmp = gen_reg_rtx (SImode); -+- emit_jump_insn (gen_casesi_internal (operands[0], operands[3], tmp)); -++ tmp_reg = gen_reg_rtx (SImode); -++ /* Step C, D, E, and F, using another temporary register tmp_reg. */ -++ if (flag_pic) -++ emit_use (pic_offset_table_rtx); -++ -++ emit_jump_insn (gen_casesi_internal (operands[0], -++ operands[3], -++ tmp_reg)); -+ DONE; -+ }) -+ -+@@ -1927,13 +2108,30 @@ -+ else -+ return nds32_output_casesi (operands); -+ } -+- [(set_attr "length" "20") -+- (set_attr "type" "branch")]) -++ [(set_attr "type" "branch") -++ (set (attr "length") -++ (if_then_else (match_test "flag_pic") -++ (const_int 28) -++ (const_int 20)))]) -+ -+ ;; ---------------------------------------------------------------------------- -+ -+ ;; Performance Extension -+ -++; If -fwrapv option is issued, GCC expects there will be -++; signed overflow situation. So the ABS(INT_MIN) is still INT_MIN -++; (e.g. ABS(0x80000000)=0x80000000). -++; However, the hardware ABS instruction of nds32 target -++; always performs saturation: abs 0x80000000 -> 0x7fffffff. -++; So that we can only enable abssi2 pattern if flag_wrapv is NOT presented. -++(define_insn "abssi2" -++ [(set (match_operand:SI 0 "register_operand" "=r") -++ (abs:SI (match_operand:SI 1 "register_operand" " r")))] -++ "TARGET_EXT_PERF && TARGET_HW_ABS && !flag_wrapv" -++ "abs\t%0, %1" -++ [(set_attr "type" "alu") -++ (set_attr "length" "4")]) -++ -+ (define_insn "clzsi2" -+ [(set (match_operand:SI 0 "register_operand" "=r") -+ (clz:SI (match_operand:SI 1 "register_operand" " r")))] -+@@ -1996,6 +2194,25 @@ -+ [(set_attr "length" "0")] -+ ) -+ -++;; Output .omit_fp_begin for fp-as-gp optimization. -++;; Also we have to set $fp register. -++(define_insn "omit_fp_begin" -++ [(set (match_operand:SI 0 "register_operand" "=x") -++ (unspec_volatile:SI [(const_int 0)] UNSPEC_VOLATILE_OMIT_FP_BEGIN))] -++ "" -++ "! -----\;.omit_fp_begin\;la\t$fp,_FP_BASE_\;! -----" -++ [(set_attr "length" "8")] -++) -++ -++;; Output .omit_fp_end for fp-as-gp optimization. -++;; Claim that we have to use $fp register. -++(define_insn "omit_fp_end" -++ [(unspec_volatile:SI [(match_operand:SI 0 "register_operand" "x")] UNSPEC_VOLATILE_OMIT_FP_END)] -++ "" -++ "! -----\;.omit_fp_end\;! -----" -++ [(set_attr "length" "0")] -++) -++ -+ (define_insn "pop25return" -+ [(return) -+ (unspec_volatile:SI [(reg:SI LP_REGNUM)] UNSPEC_VOLATILE_POP25_RETURN)] -+@@ -2004,6 +2221,36 @@ -+ [(set_attr "length" "0")] -+ ) -+ -++;; Add pc -++(define_insn "add_pc" -++ [(set (match_operand:SI 0 "register_operand" "=r") -++ (plus:SI (match_operand:SI 1 "register_operand" "0") -++ (pc)))] -++ "TARGET_LINUX_ABI || flag_pic" -++ "add5.pc\t%0" -++ [(set_attr "type" "alu") -++ (set_attr "length" "4")] -++) -++ -++(define_expand "bswapsi2" -++ [(set (match_operand:SI 0 "register_operand" "=r") -++ (bswap:SI (match_operand:SI 1 "register_operand" "r")))] -++ "" -++{ -++ emit_insn (gen_unspec_wsbh (operands[0], operands[1])); -++ emit_insn (gen_rotrsi3 (operands[0], operands[0], GEN_INT (16))); -++ DONE; -++}) -++ -++(define_insn "bswaphi2" -++ [(set (match_operand:HI 0 "register_operand" "=r") -++ (bswap:HI (match_operand:HI 1 "register_operand" "r")))] -++ "" -++ "wsbh\t%0, %1" -++ [(set_attr "type" "alu") -++ (set_attr "length" "4")] -++) -++ -+ ;; ---------------------------------------------------------------------------- -+ -+ ;; Patterns for exception handling -+@@ -2068,3 +2315,57 @@ -+ }) -+ -+ ;; ---------------------------------------------------------------------------- -++ -++;; Patterns for TLS. -++;; The following two tls patterns don't be expanded directly because the -++;; intermediate value may be spilled into the stack. As a result, it is -++;; hard to analyze the define-use chain in the relax_opt pass. -++ -++ -++;; There is a unspec operand to record RELAX_GROUP number because each -++;; emitted instruction need a relax_hint above it. -++(define_insn "tls_desc" -++ [(set (reg:SI 0) -++ (call (unspec_volatile:SI [(match_operand:SI 0 "nds32_symbolic_operand" "i")] UNSPEC_TLS_DESC) -++ (const_int 1))) -++ (use (unspec [(match_operand:SI 1 "immediate_operand" "i")] UNSPEC_VOLATILE_RELAX_GROUP)) -++ (use (reg:SI GP_REGNUM)) -++ (clobber (reg:SI LP_REGNUM)) -++ (clobber (reg:SI TA_REGNUM))] -++ "" -++ { -++ return nds32_output_tls_desc (operands); -++ } -++ [(set_attr "length" "20") -++ (set_attr "type" "branch")] -++) -++ -++;; There is a unspec operand to record RELAX_GROUP number because each -++;; emitted instruction need a relax_hint above it. -++(define_insn "tls_ie" -++ [(set (match_operand:SI 0 "register_operand" "=r") -++ (unspec:SI [(match_operand:SI 1 "nds32_symbolic_operand" "i")] UNSPEC_TLS_IE)) -++ (use (unspec [(match_operand:SI 2 "immediate_operand" "i")] UNSPEC_VOLATILE_RELAX_GROUP)) -++ (use (reg:SI GP_REGNUM))] -++ "" -++ { -++ return nds32_output_tls_ie (operands); -++ } -++ [(set (attr "length") (if_then_else (match_test "flag_pic") -++ (const_int 12) -++ (const_int 8))) -++ (set_attr "type" "misc")] -++) -++ -++;; The pattern is for some relaxation groups that have to keep addsi3 in 32-bit mode. -++(define_insn "addsi3_32bit" -++ [(set (match_operand:SI 0 "register_operand" "=r") -++ (unspec:SI [(match_operand:SI 1 "register_operand" "%r") -++ (match_operand:SI 2 "register_operand" " r")] UNSPEC_ADD32))] -++ "" -++ "add\t%0, %1, %2"; -++ [(set_attr "type" "alu") -++ (set_attr "length" "4") -++ (set_attr "feature" "v1")]) -++ -++;; ---------------------------------------------------------------------------- -+diff --git a/gcc/config/nds32/nds32.opt b/gcc/config/nds32/nds32.opt -+index dcf6d396bc3..0e50c991aba 100644 -+--- a/gcc/config/nds32/nds32.opt -++++ b/gcc/config/nds32/nds32.opt -+@@ -32,6 +32,13 @@ EL -+ Target RejectNegative Alias(mlittle-endian) -+ Generate code in little-endian mode. -+ -++mfp-as-gp -++Target RejectNegative Alias(mforce-fp-as-gp) -++Force performing fp-as-gp optimization. -++ -++mno-fp-as-gp -++Target RejectNegative Alias(mforbid-fp-as-gp) -++Forbid performing fp-as-gp optimization. -+ -+ ; --------------------------------------------------------------- -+ -+@@ -85,11 +92,36 @@ mlittle-endian -+ Target Undocumented RejectNegative Negative(mbig-endian) InverseMask(BIG_ENDIAN) -+ Generate code in little-endian mode. -+ -++mforce-fp-as-gp -++Target Undocumented Mask(FORCE_FP_AS_GP) -++Prevent $fp being allocated during register allocation so that compiler is able to force performing fp-as-gp optimization. -++ -++mforbid-fp-as-gp -++Target Undocumented Mask(FORBID_FP_AS_GP) -++Forbid using $fp to access static and global variables. This option strictly forbids fp-as-gp optimization regardless of '-mforce-fp-as-gp'. -++ -++mict-model= -++Target Undocumented RejectNegative Joined Enum(nds32_ict_model_type) Var(nds32_ict_model) Init(ICT_MODEL_SMALL) -++Specify the address generation strategy for ICT call's code model. -++ -++Enum -++Name(nds32_ict_model_type) Type(enum nds32_ict_model_type) -++Known cmodel types (for use with the -mict-model= option): -++ -++EnumValue -++Enum(nds32_ict_model_type) String(small) Value(ICT_MODEL_SMALL) -++ -++EnumValue -++Enum(nds32_ict_model_type) String(large) Value(ICT_MODEL_LARGE) -+ -+ mcmov -+ Target Report Mask(CMOV) -+ Generate conditional move instructions. -+ -++mhw-abs -++Target Report Mask(HW_ABS) -++Generate hardware abs instructions. -++ -+ mext-perf -+ Target Report Mask(EXT_PERF) -+ Generate performance extension instructions. -+@@ -102,6 +134,10 @@ mext-string -+ Target Report Mask(EXT_STRING) -+ Generate string extension instructions. -+ -++mext-dsp -++Target Report Mask(EXT_DSP) -++Generate DSP extension instructions. -++ -+ mv3push -+ Target Report Mask(V3PUSH) -+ Generate v3 push25/pop25 instructions. -+@@ -115,13 +151,17 @@ Target Report Mask(RELAX_HINT) -+ Insert relax hint for linker to do relaxation. -+ -+ mvh -+-Target Report Mask(VH) -++Target Report Mask(VH) Condition(!TARGET_LINUX_ABI) -+ Enable Virtual Hosting support. -+ -+ misr-vector-size= -+ Target RejectNegative Joined UInteger Var(nds32_isr_vector_size) Init(NDS32_DEFAULT_ISR_VECTOR_SIZE) -+ Specify the size of each interrupt vector, which must be 4 or 16. -+ -++misr-secure= -++Target RejectNegative Joined UInteger Var(nds32_isr_secure_level) Init(0) -++Specify the security level of c-isr for the whole file. -++ -+ mcache-block-size= -+ Target RejectNegative Joined UInteger Var(nds32_cache_block_size) Init(NDS32_DEFAULT_CACHE_BLOCK_SIZE) -+ Specify the size of each cache block, which must be a power of 2 between 4 and 512. -+@@ -140,6 +180,9 @@ Enum(nds32_arch_type) String(v2) Value(ARCH_V2) -+ EnumValue -+ Enum(nds32_arch_type) String(v3) Value(ARCH_V3) -+ -++EnumValue -++Enum(nds32_arch_type) String(v3j) Value(ARCH_V3J) -++ -+ EnumValue -+ Enum(nds32_arch_type) String(v3m) Value(ARCH_V3M) -+ -+@@ -149,23 +192,6 @@ Enum(nds32_arch_type) String(v3f) Value(ARCH_V3F) -+ EnumValue -+ Enum(nds32_arch_type) String(v3s) Value(ARCH_V3S) -+ -+-mcmodel= -+-Target RejectNegative Joined Enum(nds32_cmodel_type) Var(nds32_cmodel_option) Init(CMODEL_LARGE) -+-Specify the address generation strategy for code model. -+- -+-Enum -+-Name(nds32_cmodel_type) Type(enum nds32_cmodel_type) -+-Known cmodel types (for use with the -mcmodel= option): -+- -+-EnumValue -+-Enum(nds32_cmodel_type) String(small) Value(CMODEL_SMALL) -+- -+-EnumValue -+-Enum(nds32_cmodel_type) String(medium) Value(CMODEL_MEDIUM) -+- -+-EnumValue -+-Enum(nds32_cmodel_type) String(large) Value(CMODEL_LARGE) -+- -+ mcpu= -+ Target RejectNegative Joined Enum(nds32_cpu_type) Var(nds32_cpu_option) Init(CPU_N9) -+ Specify the cpu for pipeline model. -+@@ -234,6 +260,99 @@ Enum(nds32_cpu_type) String(n968) Value(CPU_N9) -+ EnumValue -+ Enum(nds32_cpu_type) String(n968a) Value(CPU_N9) -+ -++EnumValue -++Enum(nds32_cpu_type) String(n10) Value(CPU_N10) -++ -++EnumValue -++Enum(nds32_cpu_type) String(n1033) Value(CPU_N10) -++ -++EnumValue -++Enum(nds32_cpu_type) String(n1033a) Value(CPU_N10) -++ -++EnumValue -++Enum(nds32_cpu_type) String(n1033-fpu) Value(CPU_N10) -++ -++EnumValue -++Enum(nds32_cpu_type) String(n1033-spu) Value(CPU_N10) -++ -++EnumValue -++Enum(nds32_cpu_type) String(n1068) Value(CPU_N10) -++ -++EnumValue -++Enum(nds32_cpu_type) String(n1068a) Value(CPU_N10) -++ -++EnumValue -++Enum(nds32_cpu_type) String(n1068-fpu) Value(CPU_N10) -++ -++EnumValue -++Enum(nds32_cpu_type) String(n1068a-fpu) Value(CPU_N10) -++ -++EnumValue -++Enum(nds32_cpu_type) String(n1068-spu) Value(CPU_N10) -++ -++EnumValue -++Enum(nds32_cpu_type) String(n1068a-spu) Value(CPU_N10) -++ -++EnumValue -++Enum(nds32_cpu_type) String(d10) Value(CPU_N10) -++ -++EnumValue -++Enum(nds32_cpu_type) String(d1088) Value(CPU_N10) -++ -++EnumValue -++Enum(nds32_cpu_type) String(d1088-fpu) Value(CPU_N10) -++ -++EnumValue -++Enum(nds32_cpu_type) String(d1088-spu) Value(CPU_N10) -++ -++EnumValue -++Enum(nds32_cpu_type) Undocumented String(graywolf) Value(CPU_GRAYWOLF) -++ -++EnumValue -++Enum(nds32_cpu_type) String(n15) Value(CPU_GRAYWOLF) -++ -++EnumValue -++Enum(nds32_cpu_type) String(d15) Value(CPU_GRAYWOLF) -++ -++EnumValue -++Enum(nds32_cpu_type) String(n15s) Value(CPU_GRAYWOLF) -++ -++EnumValue -++Enum(nds32_cpu_type) String(d15s) Value(CPU_GRAYWOLF) -++ -++EnumValue -++Enum(nds32_cpu_type) String(n15f) Value(CPU_GRAYWOLF) -++ -++EnumValue -++Enum(nds32_cpu_type) String(d15f) Value(CPU_GRAYWOLF) -++ -++EnumValue -++Enum(nds32_cpu_type) String(n12) Value(CPU_N12) -++ -++EnumValue -++Enum(nds32_cpu_type) String(n1213) Value(CPU_N12) -++ -++EnumValue -++Enum(nds32_cpu_type) String(n1233) Value(CPU_N12) -++ -++EnumValue -++Enum(nds32_cpu_type) String(n1233-fpu) Value(CPU_N12) -++ -++EnumValue -++Enum(nds32_cpu_type) String(n1233-spu) Value(CPU_N12) -++ -++EnumValue -++Enum(nds32_cpu_type) String(n13) Value(CPU_N13) -++ -++EnumValue -++Enum(nds32_cpu_type) String(n1337) Value(CPU_N13) -++ -++EnumValue -++Enum(nds32_cpu_type) String(n1337-fpu) Value(CPU_N13) -++ -++EnumValue -++Enum(nds32_cpu_type) String(n1337-spu) Value(CPU_N13) -++ -+ EnumValue -+ Enum(nds32_cpu_type) String(simple) Value(CPU_SIMPLE) -+ -+@@ -321,6 +440,18 @@ mext-fpu-dp -+ Target Report Mask(FPU_DOUBLE) -+ Generate double-precision floating-point instructions. -+ -++mforce-no-ext-dsp -++Target Undocumented Report Mask(FORCE_NO_EXT_DSP) -++Force disable hardware loop, even use -mext-dsp. -++ -++msched-prolog-epilog -++Target Var(flag_sched_prolog_epilog) Init(0) -++Permit scheduling of a function's prologue and epilogue sequence. -++ -++mret-in-naked-func -++Target Var(flag_ret_in_naked_func) Init(1) -++Generate return instruction in naked function. -++ -+ malways-save-lp -+ Target Var(flag_always_save_lp) Init(0) -+ Always save $lp in the stack. -+@@ -328,3 +459,7 @@ Always save $lp in the stack. -+ munaligned-access -+ Target Report Var(flag_unaligned_access) Init(0) -+ Enable unaligned word and halfword accesses to packed data. -++ -++minline-asm-r15 -++Target Report Var(flag_inline_asm_r15) Init(0) -++Allow use r15 for inline ASM. -+diff --git a/gcc/config/nds32/nds32_init.inc b/gcc/config/nds32/nds32_init.inc -+new file mode 100644 -+index 00000000000..1084ad0e471 -+--- /dev/null -++++ b/gcc/config/nds32/nds32_init.inc -+@@ -0,0 +1,43 @@ -++/* -++ * nds32_init.inc -++ * -++ * NDS32 architecture startup assembler header file -++ * -++ */ -++ -++.macro nds32_init -++ -++ ! Initialize GP for data access -++ la $gp, _SDA_BASE_ -++ -++#if defined(__NDS32_EXT_EX9__) -++ ! Check HW for EX9 -++ mfsr $r0, $MSC_CFG -++ li $r1, (1 << 24) -++ and $r2, $r0, $r1 -++ beqz $r2, 1f -++ -++ ! Initialize the table base of EX9 instruction -++ la $r0, _ITB_BASE_ -++ mtusr $r0, $ITB -++1: -++#endif -++ -++#if defined(__NDS32_EXT_FPU_DP__) || defined(__NDS32_EXT_FPU_SP__) -++ ! Enable FPU -++ mfsr $r0, $FUCOP_CTL -++ ori $r0, $r0, #0x1 -++ mtsr $r0, $FUCOP_CTL -++ dsb -++ -++ ! Enable denormalized flush-to-Zero mode -++ fmfcsr $r0 -++ ori $r0,$r0,#0x1000 -++ fmtcsr $r0 -++ dsb -++#endif -++ -++ ! Initialize default stack pointer -++ la $sp, _stack -++ -++.endm -+diff --git a/gcc/config/nds32/nds32_intrinsic.h b/gcc/config/nds32/nds32_intrinsic.h -+index 7bb117712dc..24cb2915491 100644 -+--- a/gcc/config/nds32/nds32_intrinsic.h -++++ b/gcc/config/nds32/nds32_intrinsic.h -+@@ -26,6 +26,13 @@ -+ #ifndef _NDS32_INTRINSIC_H -+ #define _NDS32_INTRINSIC_H -+ -++typedef signed char int8x4_t __attribute ((vector_size(4))); -++typedef short int16x2_t __attribute ((vector_size(4))); -++typedef int int32x2_t __attribute__((vector_size(8))); -++typedef unsigned char uint8x4_t __attribute__ ((vector_size (4))); -++typedef unsigned short uint16x2_t __attribute__ ((vector_size (4))); -++typedef unsigned int uint32x2_t __attribute__((vector_size(8))); -++ -+ /* General instrinsic register names. */ -+ enum nds32_intrinsic_registers -+ { -+@@ -691,6 +698,55 @@ enum nds32_dpref -+ #define __nds32__tlbop_flua() \ -+ (__builtin_nds32_tlbop_flua()) -+ -++#define __nds32__kaddw(a, b) \ -++ (__builtin_nds32_kaddw ((a), (b))) -++#define __nds32__kaddh(a, b) \ -++ (__builtin_nds32_kaddh ((a), (b))) -++#define __nds32__ksubw(a, b) \ -++ (__builtin_nds32_ksubw ((a), (b))) -++#define __nds32__ksubh(a, b) \ -++ (__builtin_nds32_ksubh ((a), (b))) -++#define __nds32__kdmbb(a, b) \ -++ (__builtin_nds32_kdmbb ((a), (b))) -++#define __nds32__v_kdmbb(a, b) \ -++ (__builtin_nds32_v_kdmbb ((a), (b))) -++#define __nds32__kdmbt(a, b) \ -++ (__builtin_nds32_kdmbt ((a), (b))) -++#define __nds32__v_kdmbt(a, b) \ -++ (__builtin_nds32_v_kdmbt ((a), (b))) -++#define __nds32__kdmtb(a, b) \ -++ (__builtin_nds32_kdmtb ((a), (b))) -++#define __nds32__v_kdmtb(a, b) \ -++ (__builtin_nds32_v_kdmtb ((a), (b))) -++#define __nds32__kdmtt(a, b) \ -++ (__builtin_nds32_kdmtt ((a), (b))) -++#define __nds32__v_kdmtt(a, b) \ -++ (__builtin_nds32_v_kdmtt ((a), (b))) -++#define __nds32__khmbb(a, b) \ -++ (__builtin_nds32_khmbb ((a), (b))) -++#define __nds32__v_khmbb(a, b) \ -++ (__builtin_nds32_v_khmbb ((a), (b))) -++#define __nds32__khmbt(a, b) \ -++ (__builtin_nds32_khmbt ((a), (b))) -++#define __nds32__v_khmbt(a, b) \ -++ (__builtin_nds32_v_khmbt ((a), (b))) -++#define __nds32__khmtb(a, b) \ -++ (__builtin_nds32_khmtb ((a), (b))) -++#define __nds32__v_khmtb(a, b) \ -++ (__builtin_nds32_v_khmtb ((a), (b))) -++#define __nds32__khmtt(a, b) \ -++ (__builtin_nds32_khmtt ((a), (b))) -++#define __nds32__v_khmtt(a, b) \ -++ (__builtin_nds32_v_khmtt ((a), (b))) -++#define __nds32__kslraw(a, b) \ -++ (__builtin_nds32_kslraw ((a), (b))) -++#define __nds32__kslraw_u(a, b) \ -++ (__builtin_nds32_kslraw_u ((a), (b))) -++ -++#define __nds32__rdov() \ -++ (__builtin_nds32_rdov()) -++#define __nds32__clrov() \ -++ (__builtin_nds32_clrov()) -+ #define __nds32__gie_dis() \ -+ (__builtin_nds32_gie_dis()) -+ #define __nds32__gie_en() \ -+@@ -720,10 +776,622 @@ enum nds32_dpref -+ #define __nds32__get_trig_type(a) \ -+ (__builtin_nds32_get_trig_type ((a))) -+ -++#define __nds32__get_unaligned_hw(a) \ -++ (__builtin_nds32_unaligned_load_hw ((a))) -++#define __nds32__get_unaligned_w(a) \ -++ (__builtin_nds32_unaligned_load_w ((a))) -++#define __nds32__get_unaligned_dw(a) \ -++ (__builtin_nds32_unaligned_load_dw ((a))) -++#define __nds32__put_unaligned_hw(a, data) \ -++ (__builtin_nds32_unaligned_store_hw ((a), (data))) -++#define __nds32__put_unaligned_w(a, data) \ -++ (__builtin_nds32_unaligned_store_w ((a), (data))) -++#define __nds32__put_unaligned_dw(a, data) \ -++ (__builtin_nds32_unaligned_store_dw ((a), (data))) -++ -++#define __nds32__add16(a, b) \ -++ (__builtin_nds32_add16 ((a), (b))) -++#define __nds32__v_uadd16(a, b) \ -++ (__builtin_nds32_v_uadd16 ((a), (b))) -++#define __nds32__v_sadd16(a, b) \ -++ (__builtin_nds32_v_sadd16 ((a), (b))) -++#define __nds32__radd16(a, b) \ -++ (__builtin_nds32_radd16 ((a), (b))) -++#define __nds32__v_radd16(a, b) \ -++ (__builtin_nds32_v_radd16 ((a), (b))) -++#define __nds32__uradd16(a, b) \ -++ (__builtin_nds32_uradd16 ((a), (b))) -++#define __nds32__v_uradd16(a, b) \ -++ (__builtin_nds32_v_uradd16 ((a), (b))) -++#define __nds32__kadd16(a, b) \ -++ (__builtin_nds32_kadd16 ((a), (b))) -++#define __nds32__v_kadd16(a, b) \ -++ (__builtin_nds32_v_kadd16 ((a), (b))) -++#define __nds32__ukadd16(a, b) \ -++ (__builtin_nds32_ukadd16 ((a), (b))) -++#define __nds32__v_ukadd16(a, b) \ -++ (__builtin_nds32_v_ukadd16 ((a), (b))) -++#define __nds32__sub16(a, b) \ -++ (__builtin_nds32_sub16 ((a), (b))) -++#define __nds32__v_usub16(a, b) \ -++ (__builtin_nds32_v_usub16 ((a), (b))) -++#define __nds32__v_ssub16(a, b) \ -++ (__builtin_nds32_v_ssub16 ((a), (b))) -++#define __nds32__rsub16(a, b) \ -++ (__builtin_nds32_rsub16 ((a), (b))) -++#define __nds32__v_rsub16(a, b) \ -++ (__builtin_nds32_v_rsub16 ((a), (b))) -++#define __nds32__ursub16(a, b) \ -++ (__builtin_nds32_ursub16 ((a), (b))) -++#define __nds32__v_ursub16(a, b) \ -++ (__builtin_nds32_v_ursub16 ((a), (b))) -++#define __nds32__ksub16(a, b) \ -++ (__builtin_nds32_ksub16 ((a), (b))) -++#define __nds32__v_ksub16(a, b) \ -++ (__builtin_nds32_v_ksub16 ((a), (b))) -++#define __nds32__uksub16(a, b) \ -++ (__builtin_nds32_uksub16 ((a), (b))) -++#define __nds32__v_uksub16(a, b) \ -++ (__builtin_nds32_v_uksub16 ((a), (b))) -++#define __nds32__cras16(a, b) \ -++ (__builtin_nds32_cras16 ((a), (b))) -++#define __nds32__v_ucras16(a, b) \ -++ (__builtin_nds32_v_ucras16 ((a), (b))) -++#define __nds32__v_scras16(a, b) \ -++ (__builtin_nds32_v_scras16 ((a), (b))) -++#define __nds32__rcras16(a, b) \ -++ (__builtin_nds32_rcras16 ((a), (b))) -++#define __nds32__v_rcras16(a, b) \ -++ (__builtin_nds32_v_rcras16 ((a), (b))) -++#define __nds32__urcras16(a, b) \ -++ (__builtin_nds32_urcras16 ((a), (b))) -++#define __nds32__v_urcras16(a, b) \ -++ (__builtin_nds32_v_urcras16 ((a), (b))) -++#define __nds32__kcras16(a, b) \ -++ (__builtin_nds32_kcras16 ((a), (b))) -++#define __nds32__v_kcras16(a, b) \ -++ (__builtin_nds32_v_kcras16 ((a), (b))) -++#define __nds32__ukcras16(a, b) \ -++ (__builtin_nds32_ukcras16 ((a), (b))) -++#define __nds32__v_ukcras16(a, b) \ -++ (__builtin_nds32_v_ukcras16 ((a), (b))) -++#define __nds32__crsa16(a, b) \ -++ (__builtin_nds32_crsa16 ((a), (b))) -++#define __nds32__v_ucrsa16(a, b) \ -++ (__builtin_nds32_v_ucrsa16 ((a), (b))) -++#define __nds32__v_scrsa16(a, b) \ -++ (__builtin_nds32_v_scrsa16 ((a), (b))) -++#define __nds32__rcrsa16(a, b) \ -++ (__builtin_nds32_rcrsa16 ((a), (b))) -++#define __nds32__v_rcrsa16(a, b) \ -++ (__builtin_nds32_v_rcrsa16 ((a), (b))) -++#define __nds32__urcrsa16(a, b) \ -++ (__builtin_nds32_urcrsa16 ((a), (b))) -++#define __nds32__v_urcrsa16(a, b) \ -++ (__builtin_nds32_v_urcrsa16 ((a), (b))) -++#define __nds32__kcrsa16(a, b) \ -++ (__builtin_nds32_kcrsa16 ((a), (b))) -++#define __nds32__v_kcrsa16(a, b) \ -++ (__builtin_nds32_v_kcrsa16 ((a), (b))) -++#define __nds32__ukcrsa16(a, b) \ -++ (__builtin_nds32_ukcrsa16 ((a), (b))) -++#define __nds32__v_ukcrsa16(a, b) \ -++ (__builtin_nds32_v_ukcrsa16 ((a), (b))) -++ -++#define __nds32__add8(a, b) \ -++ (__builtin_nds32_add8 ((a), (b))) -++#define __nds32__v_uadd8(a, b) \ -++ (__builtin_nds32_v_uadd8 ((a), (b))) -++#define __nds32__v_sadd8(a, b) \ -++ (__builtin_nds32_v_sadd8 ((a), (b))) -++#define __nds32__radd8(a, b) \ -++ (__builtin_nds32_radd8 ((a), (b))) -++#define __nds32__v_radd8(a, b) \ -++ (__builtin_nds32_v_radd8 ((a), (b))) -++#define __nds32__uradd8(a, b) \ -++ (__builtin_nds32_uradd8 ((a), (b))) -++#define __nds32__v_uradd8(a, b) \ -++ (__builtin_nds32_v_uradd8 ((a), (b))) -++#define __nds32__kadd8(a, b) \ -++ (__builtin_nds32_kadd8 ((a), (b))) -++#define __nds32__v_kadd8(a, b) \ -++ (__builtin_nds32_v_kadd8 ((a), (b))) -++#define __nds32__ukadd8(a, b) \ -++ (__builtin_nds32_ukadd8 ((a), (b))) -++#define __nds32__v_ukadd8(a, b) \ -++ (__builtin_nds32_v_ukadd8 ((a), (b))) -++#define __nds32__sub8(a, b) \ -++ (__builtin_nds32_sub8 ((a), (b))) -++#define __nds32__v_usub8(a, b) \ -++ (__builtin_nds32_v_usub8 ((a), (b))) -++#define __nds32__v_ssub8(a, b) \ -++ (__builtin_nds32_v_ssub8 ((a), (b))) -++#define __nds32__rsub8(a, b) \ -++ (__builtin_nds32_rsub8 ((a), (b))) -++#define __nds32__v_rsub8(a, b) \ -++ (__builtin_nds32_v_rsub8 ((a), (b))) -++#define __nds32__ursub8(a, b) \ -++ (__builtin_nds32_ursub8 ((a), (b))) -++#define __nds32__v_ursub8(a, b) \ -++ (__builtin_nds32_v_ursub8 ((a), (b))) -++#define __nds32__ksub8(a, b) \ -++ (__builtin_nds32_ksub8 ((a), (b))) -++#define __nds32__v_ksub8(a, b) \ -++ (__builtin_nds32_v_ksub8 ((a), (b))) -++#define __nds32__uksub8(a, b) \ -++ (__builtin_nds32_uksub8 ((a), (b))) -++#define __nds32__v_uksub8(a, b) \ -++ (__builtin_nds32_v_uksub8 ((a), (b))) -++ -++#define __nds32__sra16(a, b) \ -++ (__builtin_nds32_sra16 ((a), (b))) -++#define __nds32__v_sra16(a, b) \ -++ (__builtin_nds32_v_sra16 ((a), (b))) -++#define __nds32__sra16_u(a, b) \ -++ (__builtin_nds32_sra16_u ((a), (b))) -++#define __nds32__v_sra16_u(a, b) \ -++ (__builtin_nds32_v_sra16_u ((a), (b))) -++#define __nds32__srl16(a, b) \ -++ (__builtin_nds32_srl16 ((a), (b))) -++#define __nds32__v_srl16(a, b) \ -++ (__builtin_nds32_v_srl16 ((a), (b))) -++#define __nds32__srl16_u(a, b) \ -++ (__builtin_nds32_srl16_u ((a), (b))) -++#define __nds32__v_srl16_u(a, b) \ -++ (__builtin_nds32_v_srl16_u ((a), (b))) -++#define __nds32__sll16(a, b) \ -++ (__builtin_nds32_sll16 ((a), (b))) -++#define __nds32__v_sll16(a, b) \ -++ (__builtin_nds32_v_sll16 ((a), (b))) -++#define __nds32__ksll16(a, b) \ -++ (__builtin_nds32_ksll16 ((a), (b))) -++#define __nds32__v_ksll16(a, b) \ -++ (__builtin_nds32_v_ksll16 ((a), (b))) -++#define __nds32__kslra16(a, b) \ -++ (__builtin_nds32_kslra16 ((a), (b))) -++#define __nds32__v_kslra16(a, b) \ -++ (__builtin_nds32_v_kslra16 ((a), (b))) -++#define __nds32__kslra16_u(a, b) \ -++ (__builtin_nds32_kslra16_u ((a), (b))) -++#define __nds32__v_kslra16_u(a, b) \ -++ (__builtin_nds32_v_kslra16_u ((a), (b))) -++ -++#define __nds32__cmpeq16(a, b) \ -++ (__builtin_nds32_cmpeq16 ((a), (b))) -++#define __nds32__v_scmpeq16(a, b) \ -++ (__builtin_nds32_v_scmpeq16 ((a), (b))) -++#define __nds32__v_ucmpeq16(a, b) \ -++ (__builtin_nds32_v_ucmpeq16 ((a), (b))) -++#define __nds32__scmplt16(a, b) \ -++ (__builtin_nds32_scmplt16 ((a), (b))) -++#define __nds32__v_scmplt16(a, b) \ -++ (__builtin_nds32_v_scmplt16 ((a), (b))) -++#define __nds32__scmple16(a, b) \ -++ (__builtin_nds32_scmple16 ((a), (b))) -++#define __nds32__v_scmple16(a, b) \ -++ (__builtin_nds32_v_scmple16 ((a), (b))) -++#define __nds32__ucmplt16(a, b) \ -++ (__builtin_nds32_ucmplt16 ((a), (b))) -++#define __nds32__v_ucmplt16(a, b) \ -++ (__builtin_nds32_v_ucmplt16 ((a), (b))) -++#define __nds32__ucmple16(a, b) \ -++ (__builtin_nds32_ucmple16 ((a), (b))) -++#define __nds32__v_ucmple16(a, b) \ -++ (__builtin_nds32_v_ucmple16 ((a), (b))) -++ -++#define __nds32__cmpeq8(a, b) \ -++ (__builtin_nds32_cmpeq8 ((a), (b))) -++#define __nds32__v_scmpeq8(a, b) \ -++ (__builtin_nds32_v_scmpeq8 ((a), (b))) -++#define __nds32__v_ucmpeq8(a, b) \ -++ (__builtin_nds32_v_ucmpeq8 ((a), (b))) -++#define __nds32__scmplt8(a, b) \ -++ (__builtin_nds32_scmplt8 ((a), (b))) -++#define __nds32__v_scmplt8(a, b) \ -++ (__builtin_nds32_v_scmplt8 ((a), (b))) -++#define __nds32__scmple8(a, b) \ -++ (__builtin_nds32_scmple8 ((a), (b))) -++#define __nds32__v_scmple8(a, b) \ -++ (__builtin_nds32_v_scmple8 ((a), (b))) -++#define __nds32__ucmplt8(a, b) \ -++ (__builtin_nds32_ucmplt8 ((a), (b))) -++#define __nds32__v_ucmplt8(a, b) \ -++ (__builtin_nds32_v_ucmplt8 ((a), (b))) -++#define __nds32__ucmple8(a, b) \ -++ (__builtin_nds32_ucmple8 ((a), (b))) -++#define __nds32__v_ucmple8(a, b) \ -++ (__builtin_nds32_v_ucmple8 ((a), (b))) -++ -++#define __nds32__smin16(a, b) \ -++ (__builtin_nds32_smin16 ((a), (b))) -++#define __nds32__v_smin16(a, b) \ -++ (__builtin_nds32_v_smin16 ((a), (b))) -++#define __nds32__umin16(a, b) \ -++ (__builtin_nds32_umin16 ((a), (b))) -++#define __nds32__v_umin16(a, b) \ -++ (__builtin_nds32_v_umin16 ((a), (b))) -++#define __nds32__smax16(a, b) \ -++ (__builtin_nds32_smax16 ((a), (b))) -++#define __nds32__v_smax16(a, b) \ -++ (__builtin_nds32_v_smax16 ((a), (b))) -++#define __nds32__umax16(a, b) \ -++ (__builtin_nds32_umax16 ((a), (b))) -++#define __nds32__v_umax16(a, b) \ -++ (__builtin_nds32_v_umax16 ((a), (b))) -++#define __nds32__sclip16(a, b) \ -++ (__builtin_nds32_sclip16 ((a), (b))) -++#define __nds32__v_sclip16(a, b) \ -++ (__builtin_nds32_v_sclip16 ((a), (b))) -++#define __nds32__uclip16(a, b) \ -++ (__builtin_nds32_uclip16 ((a), (b))) -++#define __nds32__v_uclip16(a, b) \ -++ (__builtin_nds32_v_uclip16 ((a), (b))) -++#define __nds32__khm16(a, b) \ -++ (__builtin_nds32_khm16 ((a), (b))) -++#define __nds32__v_khm16(a, b) \ -++ (__builtin_nds32_v_khm16 ((a), (b))) -++#define __nds32__khmx16(a, b) \ -++ (__builtin_nds32_khmx16 ((a), (b))) -++#define __nds32__v_khmx16(a, b) \ -++ (__builtin_nds32_v_khmx16 ((a), (b))) -++#define __nds32__kabs16(a) \ -++ (__builtin_nds32_kabs16 ((a))) -++#define __nds32__v_kabs16(a) \ -++ (__builtin_nds32_v_kabs16 ((a))) -++ -++#define __nds32__smin8(a, b) \ -++ (__builtin_nds32_smin8 ((a), (b))) -++#define __nds32__v_smin8(a, b) \ -++ (__builtin_nds32_v_smin8 ((a), (b))) -++#define __nds32__umin8(a, b) \ -++ (__builtin_nds32_umin8 ((a), (b))) -++#define __nds32__v_umin8(a, b) \ -++ (__builtin_nds32_v_umin8 ((a), (b))) -++#define __nds32__smax8(a, b) \ -++ (__builtin_nds32_smax8 ((a), (b))) -++#define __nds32__v_smax8(a, b) \ -++ (__builtin_nds32_v_smax8 ((a), (b))) -++#define __nds32__umax8(a, b) \ -++ (__builtin_nds32_umax8 ((a), (b))) -++#define __nds32__v_umax8(a, b) \ -++ (__builtin_nds32_v_umax8 ((a), (b))) -++#define __nds32__kabs8(a) \ -++ (__builtin_nds32_kabs8 ((a))) -++#define __nds32__v_kabs8(a) \ -++ (__builtin_nds32_v_kabs8 ((a))) -++ -++#define __nds32__sunpkd810(a) \ -++ (__builtin_nds32_sunpkd810 ((a))) -++#define __nds32__v_sunpkd810(a) \ -++ (__builtin_nds32_v_sunpkd810 ((a))) -++#define __nds32__sunpkd820(a) \ -++ (__builtin_nds32_sunpkd820 ((a))) -++#define __nds32__v_sunpkd820(a) \ -++ (__builtin_nds32_v_sunpkd820 ((a))) -++#define __nds32__sunpkd830(a) \ -++ (__builtin_nds32_sunpkd830 ((a))) -++#define __nds32__v_sunpkd830(a) \ -++ (__builtin_nds32_v_sunpkd830 ((a))) -++#define __nds32__sunpkd831(a) \ -++ (__builtin_nds32_sunpkd831 ((a))) -++#define __nds32__v_sunpkd831(a) \ -++ (__builtin_nds32_v_sunpkd831 ((a))) -++#define __nds32__zunpkd810(a) \ -++ (__builtin_nds32_zunpkd810 ((a))) -++#define __nds32__v_zunpkd810(a) \ -++ (__builtin_nds32_v_zunpkd810 ((a))) -++#define __nds32__zunpkd820(a) \ -++ (__builtin_nds32_zunpkd820 ((a))) -++#define __nds32__v_zunpkd820(a) \ -++ (__builtin_nds32_v_zunpkd820 ((a))) -++#define __nds32__zunpkd830(a) \ -++ (__builtin_nds32_zunpkd830 ((a))) -++#define __nds32__v_zunpkd830(a) \ -++ (__builtin_nds32_v_zunpkd830 ((a))) -++#define __nds32__zunpkd831(a) \ -++ (__builtin_nds32_zunpkd831 ((a))) -++#define __nds32__v_zunpkd831(a) \ -++ (__builtin_nds32_v_zunpkd831 ((a))) -++ -++#define __nds32__raddw(a, b) \ -++ (__builtin_nds32_raddw ((a), (b))) -++#define __nds32__uraddw(a, b) \ -++ (__builtin_nds32_uraddw ((a), (b))) -++#define __nds32__rsubw(a, b) \ -++ (__builtin_nds32_rsubw ((a), (b))) -++#define __nds32__ursubw(a, b) \ -++ (__builtin_nds32_ursubw ((a), (b))) -++ -++#define __nds32__sra_u(a, b) \ -++ (__builtin_nds32_sra_u ((a), (b))) -++#define __nds32__ksll(a, b) \ -++ (__builtin_nds32_ksll ((a), (b))) -++#define __nds32__pkbb16(a, b) \ -++ (__builtin_nds32_pkbb16 ((a), (b))) -++#define __nds32__v_pkbb16(a, b) \ -++ (__builtin_nds32_v_pkbb16 ((a), (b))) -++#define __nds32__pkbt16(a, b) \ -++ (__builtin_nds32_pkbt16 ((a), (b))) -++#define __nds32__v_pkbt16(a, b) \ -++ (__builtin_nds32_v_pkbt16 ((a), (b))) -++#define __nds32__pktb16(a, b) \ -++ (__builtin_nds32_pktb16 ((a), (b))) -++#define __nds32__v_pktb16(a, b) \ -++ (__builtin_nds32_v_pktb16 ((a), (b))) -++#define __nds32__pktt16(a, b) \ -++ (__builtin_nds32_pktt16 ((a), (b))) -++#define __nds32__v_pktt16(a, b) \ -++ (__builtin_nds32_v_pktt16 ((a), (b))) -++ -++#define __nds32__smmul(a, b) \ -++ (__builtin_nds32_smmul ((a), (b))) -++#define __nds32__smmul_u(a, b) \ -++ (__builtin_nds32_smmul_u ((a), (b))) -++#define __nds32__kmmac(r, a, b) \ -++ (__builtin_nds32_kmmac ((r), (a), (b))) -++#define __nds32__kmmac_u(r, a, b) \ -++ (__builtin_nds32_kmmac_u ((r), (a), (b))) -++#define __nds32__kmmsb(r, a, b) \ -++ (__builtin_nds32_kmmsb ((r), (a), (b))) -++#define __nds32__kmmsb_u(r, a, b) \ -++ (__builtin_nds32_kmmsb_u ((r), (a), (b))) -++#define __nds32__kwmmul(a, b) \ -++ (__builtin_nds32_kwmmul ((a), (b))) -++#define __nds32__kwmmul_u(a, b) \ -++ (__builtin_nds32_kwmmul_u ((a), (b))) -++ -++#define __nds32__smmwb(a, b) \ -++ (__builtin_nds32_smmwb ((a), (b))) -++#define __nds32__v_smmwb(a, b) \ -++ (__builtin_nds32_v_smmwb ((a), (b))) -++#define __nds32__smmwb_u(a, b) \ -++ (__builtin_nds32_smmwb_u ((a), (b))) -++#define __nds32__v_smmwb_u(a, b) \ -++ (__builtin_nds32_v_smmwb_u ((a), (b))) -++#define __nds32__smmwt(a, b) \ -++ (__builtin_nds32_smmwt ((a), (b))) -++#define __nds32__v_smmwt(a, b) \ -++ (__builtin_nds32_v_smmwt ((a), (b))) -++#define __nds32__smmwt_u(a, b) \ -++ (__builtin_nds32_smmwt_u ((a), (b))) -++#define __nds32__v_smmwt_u(a, b) \ -++ (__builtin_nds32_v_smmwt_u ((a), (b))) -++#define __nds32__kmmawb(r, a, b) \ -++ (__builtin_nds32_kmmawb ((r), (a), (b))) -++#define __nds32__v_kmmawb(r, a, b) \ -++ (__builtin_nds32_v_kmmawb ((r), (a), (b))) -++#define __nds32__kmmawb_u(r, a, b) \ -++ (__builtin_nds32_kmmawb_u ((r), (a), (b))) -++#define __nds32__v_kmmawb_u(r, a, b) \ -++ (__builtin_nds32_v_kmmawb_u ((r), (a), (b))) -++#define __nds32__kmmawt(r, a, b) \ -++ (__builtin_nds32_kmmawt ((r), (a), (b))) -++#define __nds32__v_kmmawt(r, a, b) \ -++ (__builtin_nds32_v_kmmawt ((r), (a), (b))) -++#define __nds32__kmmawt_u(r, a, b) \ -++ (__builtin_nds32_kmmawt_u ((r), (a), (b))) -++#define __nds32__v_kmmawt_u(r, a, b) \ -++ (__builtin_nds32_v_kmmawt_u ((r), (a), (b))) -++ -++#define __nds32__smbb(a, b) \ -++ (__builtin_nds32_smbb ((a), (b))) -++#define __nds32__v_smbb(a, b) \ -++ (__builtin_nds32_v_smbb ((a), (b))) -++#define __nds32__smbt(a, b) \ -++ (__builtin_nds32_smbt ((a), (b))) -++#define __nds32__v_smbt(a, b) \ -++ (__builtin_nds32_v_smbt ((a), (b))) -++#define __nds32__smtt(a, b) \ -++ (__builtin_nds32_smtt ((a), (b))) -++#define __nds32__v_smtt(a, b) \ -++ (__builtin_nds32_v_smtt ((a), (b))) -++#define __nds32__kmda(a, b) \ -++ (__builtin_nds32_kmda ((a), (b))) -++#define __nds32__v_kmda(a, b) \ -++ (__builtin_nds32_v_kmda ((a), (b))) -++#define __nds32__kmxda(a, b) \ -++ (__builtin_nds32_kmxda ((a), (b))) -++#define __nds32__v_kmxda(a, b) \ -++ (__builtin_nds32_v_kmxda ((a), (b))) -++#define __nds32__smds(a, b) \ -++ (__builtin_nds32_smds ((a), (b))) -++#define __nds32__v_smds(a, b) \ -++ (__builtin_nds32_v_smds ((a), (b))) -++#define __nds32__smdrs(a, b) \ -++ (__builtin_nds32_smdrs ((a), (b))) -++#define __nds32__v_smdrs(a, b) \ -++ (__builtin_nds32_v_smdrs ((a), (b))) -++#define __nds32__smxds(a, b) \ -++ (__builtin_nds32_smxds ((a), (b))) -++#define __nds32__v_smxds(a, b) \ -++ (__builtin_nds32_v_smxds ((a), (b))) -++#define __nds32__kmabb(r, a, b) \ -++ (__builtin_nds32_kmabb ((r), (a), (b))) -++#define __nds32__v_kmabb(r, a, b) \ -++ (__builtin_nds32_v_kmabb ((r), (a), (b))) -++#define __nds32__kmabt(r, a, b) \ -++ (__builtin_nds32_kmabt ((r), (a), (b))) -++#define __nds32__v_kmabt(r, a, b) \ -++ (__builtin_nds32_v_kmabt ((r), (a), (b))) -++#define __nds32__kmatt(r, a, b) \ -++ (__builtin_nds32_kmatt ((r), (a), (b))) -++#define __nds32__v_kmatt(r, a, b) \ -++ (__builtin_nds32_v_kmatt ((r), (a), (b))) -++#define __nds32__kmada(r, a, b) \ -++ (__builtin_nds32_kmada ((r), (a), (b))) -++#define __nds32__v_kmada(r, a, b) \ -++ (__builtin_nds32_v_kmada ((r), (a), (b))) -++#define __nds32__kmaxda(r, a, b) \ -++ (__builtin_nds32_kmaxda ((r), (a), (b))) -++#define __nds32__v_kmaxda(r, a, b) \ -++ (__builtin_nds32_v_kmaxda ((r), (a), (b))) -++#define __nds32__kmads(r, a, b) \ -++ (__builtin_nds32_kmads ((r), (a), (b))) -++#define __nds32__v_kmads(r, a, b) \ -++ (__builtin_nds32_v_kmads ((r), (a), (b))) -++#define __nds32__kmadrs(r, a, b) \ -++ (__builtin_nds32_kmadrs ((r), (a), (b))) -++#define __nds32__v_kmadrs(r, a, b) \ -++ (__builtin_nds32_v_kmadrs ((r), (a), (b))) -++#define __nds32__kmaxds(r, a, b) \ -++ (__builtin_nds32_kmaxds ((r), (a), (b))) -++#define __nds32__v_kmaxds(r, a, b) \ -++ (__builtin_nds32_v_kmaxds ((r), (a), (b))) -++#define __nds32__kmsda(r, a, b) \ -++ (__builtin_nds32_kmsda ((r), (a), (b))) -++#define __nds32__v_kmsda(r, a, b) \ -++ (__builtin_nds32_v_kmsda ((r), (a), (b))) -++#define __nds32__kmsxda(r, a, b) \ -++ (__builtin_nds32_kmsxda ((r), (a), (b))) -++#define __nds32__v_kmsxda(r, a, b) \ -++ (__builtin_nds32_v_kmsxda ((r), (a), (b))) -++ -++#define __nds32__smal(a, b) \ -++ (__builtin_nds32_smal ((a), (b))) -++#define __nds32__v_smal(a, b) \ -++ (__builtin_nds32_v_smal ((a), (b))) -++ -++#define __nds32__bitrev(a, b) \ -++ (__builtin_nds32_bitrev ((a), (b))) -++#define __nds32__wext(a, b) \ -++ (__builtin_nds32_wext ((a), (b))) -++#define __nds32__bpick(r, a, b) \ -++ (__builtin_nds32_bpick ((r), (a), (b))) -++#define __nds32__insb(r, a, b) \ -++ (__builtin_nds32_insb ((r), (a), (b))) -++ -++#define __nds32__sadd64(a, b) \ -++ (__builtin_nds32_sadd64 ((a), (b))) -++#define __nds32__uadd64(a, b) \ -++ (__builtin_nds32_uadd64 ((a), (b))) -++#define __nds32__radd64(a, b) \ -++ (__builtin_nds32_radd64 ((a), (b))) -++#define __nds32__uradd64(a, b) \ -++ (__builtin_nds32_uradd64 ((a), (b))) -++#define __nds32__kadd64(a, b) \ -++ (__builtin_nds32_kadd64 ((a), (b))) -++#define __nds32__ukadd64(a, b) \ -++ (__builtin_nds32_ukadd64 ((a), (b))) -++#define __nds32__ssub64(a, b) \ -++ (__builtin_nds32_ssub64 ((a), (b))) -++#define __nds32__usub64(a, b) \ -++ (__builtin_nds32_usub64 ((a), (b))) -++#define __nds32__rsub64(a, b) \ -++ (__builtin_nds32_rsub64 ((a), (b))) -++#define __nds32__ursub64(a, b) \ -++ (__builtin_nds32_ursub64 ((a), (b))) -++#define __nds32__ksub64(a, b) \ -++ (__builtin_nds32_ksub64 ((a), (b))) -++#define __nds32__uksub64(a, b) \ -++ (__builtin_nds32_uksub64 ((a), (b))) -++ -++#define __nds32__smar64(r, a, b) \ -++ (__builtin_nds32_smar64 ((r), (a), (b))) -++#define __nds32__smsr64(r, a, b) \ -++ (__builtin_nds32_smsr64 ((r), (a), (b))) -++#define __nds32__umar64(r, a, b) \ -++ (__builtin_nds32_umar64 ((r), (a), (b))) -++#define __nds32__umsr64(r, a, b) \ -++ (__builtin_nds32_umsr64 ((r), (a), (b))) -++#define __nds32__kmar64(r, a, b) \ -++ (__builtin_nds32_kmar64 ((r), (a), (b))) -++#define __nds32__kmsr64(r, a, b) \ -++ (__builtin_nds32_kmsr64 ((r), (a), (b))) -++#define __nds32__ukmar64(r, a, b) \ -++ (__builtin_nds32_ukmar64 ((r), (a), (b))) -++#define __nds32__ukmsr64(r, a, b) \ -++ (__builtin_nds32_ukmsr64 ((r), (a), (b))) -++ -++#define __nds32__smalbb(r, a, b) \ -++ (__builtin_nds32_smalbb ((r), (a), (b))) -++#define __nds32__v_smalbb(r, a, b) \ -++ (__builtin_nds32_v_smalbb ((r), (a), (b))) -++#define __nds32__smalbt(r, a, b) \ -++ (__builtin_nds32_smalbt ((r), (a), (b))) -++#define __nds32__v_smalbt(r, a, b) \ -++ (__builtin_nds32_v_smalbt ((r), (a), (b))) -++#define __nds32__smaltt(r, a, b) \ -++ (__builtin_nds32_smaltt ((r), (a), (b))) -++#define __nds32__v_smaltt(r, a, b) \ -++ (__builtin_nds32_v_smaltt ((r), (a), (b))) -++#define __nds32__smalda(r, a, b) \ -++ (__builtin_nds32_smalda ((r), (a), (b))) -++#define __nds32__v_smalda(r, a, b) \ -++ (__builtin_nds32_v_smalda ((r), (a), (b))) -++#define __nds32__smalxda(r, a, b) \ -++ (__builtin_nds32_smalxda ((r), (a), (b))) -++#define __nds32__v_smalxda(r, a, b) \ -++ (__builtin_nds32_v_smalxda ((r), (a), (b))) -++#define __nds32__smalds(r, a, b) \ -++ (__builtin_nds32_smalds ((r), (a), (b))) -++#define __nds32__v_smalds(r, a, b) \ -++ (__builtin_nds32_v_smalds ((r), (a), (b))) -++#define __nds32__smaldrs(r, a, b) \ -++ (__builtin_nds32_smaldrs ((r), (a), (b))) -++#define __nds32__v_smaldrs(r, a, b) \ -++ (__builtin_nds32_v_smaldrs ((r), (a), (b))) -++#define __nds32__smalxds(r, a, b) \ -++ (__builtin_nds32_smalxds ((r), (a), (b))) -++#define __nds32__v_smalxds(r, a, b) \ -++ (__builtin_nds32_v_smalxds ((r), (a), (b))) -++#define __nds32__smslda(r, a, b) \ -++ (__builtin_nds32_smslda ((r), (a), (b))) -++#define __nds32__v_smslda(r, a, b) \ -++ (__builtin_nds32_v_smslda ((r), (a), (b))) -++#define __nds32__smslxda(r, a, b) \ -++ (__builtin_nds32_smslxda ((r), (a), (b))) -++#define __nds32__v_smslxda(r, a, b) \ -++ (__builtin_nds32_v_smslxda ((r), (a), (b))) -++ -++#define __nds32__smul16(a, b) \ -++ (__builtin_nds32_smul16 ((a), (b))) -++#define __nds32__v_smul16(a, b) \ -++ (__builtin_nds32_v_smul16 ((a), (b))) -++#define __nds32__smulx16(a, b) \ -++ (__builtin_nds32_smulx16 ((a), (b))) -++#define __nds32__v_smulx16(a, b) \ -++ (__builtin_nds32_v_smulx16 ((a), (b))) -++#define __nds32__umul16(a, b) \ -++ (__builtin_nds32_umul16 ((a), (b))) -++#define __nds32__v_umul16(a, b) \ -++ (__builtin_nds32_v_umul16 ((a), (b))) -++#define __nds32__umulx16(a, b) \ -++ (__builtin_nds32_umulx16 ((a), (b))) -++#define __nds32__v_umulx16(a, b) \ -++ (__builtin_nds32_v_umulx16 ((a), (b))) -++ -++#define __nds32__uclip32(a, imm) \ -++ (__builtin_nds32_uclip32 ((a), (imm))) -++#define __nds32__sclip32(a, imm) \ -++ (__builtin_nds32_sclip32 ((a), (imm))) -++#define __nds32__kabs(a) \ -++ (__builtin_nds32_kabs ((a))) -++ -+ #define __nds32__unaligned_feature() \ -+ (__builtin_nds32_unaligned_feature()) -+ #define __nds32__enable_unaligned() \ -+ (__builtin_nds32_enable_unaligned()) -+ #define __nds32__disable_unaligned() \ -+ (__builtin_nds32_disable_unaligned()) -++ -++#define __nds32__get_unaligned_u16x2(a) \ -++ (__builtin_nds32_get_unaligned_u16x2 ((a))) -++#define __nds32__get_unaligned_s16x2(a) \ -++ (__builtin_nds32_get_unaligned_s16x2 ((a))) -++#define __nds32__get_unaligned_u8x4(a) \ -++ (__builtin_nds32_get_unaligned_u8x4 ((a))) -++#define __nds32__get_unaligned_s8x4(a) \ -++ (__builtin_nds32_get_unaligned_s8x4 ((a))) -++ -++#define __nds32__put_unaligned_u16x2(a, data) \ -++ (__builtin_nds32_put_unaligned_u16x2 ((a), (data))) -++#define __nds32__put_unaligned_s16x2(a, data) \ -++ (__builtin_nds32_put_unaligned_s16x2 ((a), (data))) -++#define __nds32__put_unaligned_u8x4(a, data) \ -++ (__builtin_nds32_put_unaligned_u8x4 ((a), (data))) -++#define __nds32__put_unaligned_s8x4(a, data) \ -++ (__builtin_nds32_put_unaligned_s8x4 ((a), (data))) -++ -++#define NDS32ATTR_SIGNATURE __attribute__((signature)) -++ -+ #endif /* nds32_intrinsic.h */ -+diff --git a/gcc/config/nds32/nds32_isr.h b/gcc/config/nds32/nds32_isr.h -+new file mode 100644 -+index 00000000000..8ea58f951e1 -+--- /dev/null -++++ b/gcc/config/nds32/nds32_isr.h -+@@ -0,0 +1,526 @@ -++/* Intrinsic definitions of Andes NDS32 cpu for GNU compiler -++ Copyright (C) 2012-2018 Free Software Foundation, Inc. -++ Contributed by Andes Technology Corporation. -++ -++ This file is part of GCC. -++ -++ GCC is free software; you can redistribute it and/or modify it -++ under the terms of the GNU General Public License as published -++ by the Free Software Foundation; either version 3, or (at your -++ option) any later version. -++ -++ GCC is distributed in the hope that it will be useful, but WITHOUT -++ ANY WARRANTY; without even the implied warranty of MERCHANTABILITY -++ or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public -++ License for more details. -++ -++ Under Section 7 of GPL version 3, you are granted additional -++ permissions described in the GCC Runtime Library Exception, version -++ 3.1, as published by the Free Software Foundation. -++ -++ You should have received a copy of the GNU General Public License and -++ a copy of the GCC Runtime Library Exception along with this program; -++ see the files COPYING3 and COPYING.RUNTIME respectively. If not, see -++ . */ -++ -++#ifndef _NDS32_ISR_H -++#define _NDS32_ISR_H -++ -++/* Attribute of a interrupt or exception handler: -++ -++ NDS32_READY_NESTED: This handler is interruptible if user re-enable GIE bit. -++ NDS32_NESTED : This handler is interruptible. This is not suitable -++ exception handler. -++ NDS32_NOT_NESTED : This handler is NOT interruptible. Users have to do -++ some work if nested is wanted -++ NDS32_CRITICAL : This handler is critical ISR, which means it is small -++ and efficient. */ -++#define NDS32_READY_NESTED 0 -++#define NDS32_NESTED 1 -++#define NDS32_NOT_NESTED 2 -++#define NDS32_CRITICAL 3 -++ -++/* Attribute of a interrupt or exception handler: -++ -++ NDS32_SAVE_ALL_REGS : Save all registers in a table. -++ NDS32_SAVE_PARTIAL_REGS: Save partial registers. */ -++#define NDS32_SAVE_CALLER_REGS 0 -++#define NDS32_SAVE_ALL_REGS 1 -++ -++/* There are two version of Register table for interrupt and exception handler, -++ one for 16-register CPU the other for 32-register CPU. These structures are -++ used for context switching or system call handling. The address of this -++ data can be get from the input argument of the handler functions. -++ -++ For system call handling, r0 to r5 are used to pass arguments. If more -++ arguments are used they are put into the stack and its starting address is -++ in sp. Return value of system call can be put into r0 and r1 upon exit from -++ system call handler. System call ID is in a system register and it can be -++ fetched via intrinsic function. For more information please read ABI and -++ other related documents. -++ -++ For context switching, at least 2 values need to saved in kernel. One is -++ IPC and the other is the stack address of current task. Use intrinsic -++ function to get IPC and the input argument of the handler functions + 8 to -++ get stack address of current task. To do context switching, you replace -++ new_sp with the stack address of new task and replace IPC system register -++ with IPC of new task, then, just return from handler. The context switching -++ will happen. */ -++ -++/* Register table for exception handler; 32-register version. */ -++typedef struct -++{ -++ int r0; -++ int r1; -++ int r2; -++ int r3; -++ int r4; -++ int r5; -++ int r6; -++ int r7; -++ int r8; -++ int r9; -++ int r10; -++ int r11; -++ int r12; -++ int r13; -++ int r14; -++ int r15; -++ int r16; -++ int r17; -++ int r18; -++ int r19; -++ int r20; -++ int r21; -++ int r22; -++ int r23; -++ int r24; -++ int r25; -++ int r26; -++ int r27; -++ int fp; -++ int gp; -++ int lp; -++ int sp; -++} NDS32_GPR32; -++ -++/* Register table for exception handler; 16-register version. */ -++typedef struct -++{ -++ int r0; -++ int r1; -++ int r2; -++ int r3; -++ int r4; -++ int r5; -++ int r6; -++ int r7; -++ int r8; -++ int r9; -++ int r10; -++ int r15; -++ int fp; -++ int gp; -++ int lp; -++ int sp; -++} NDS32_GPR16; -++ -++ -++/* Use NDS32_REG32_TAB or NDS32_REG16_TAB in your program to -++ access register table. */ -++typedef struct -++{ -++ union -++ { -++ int reg_a[32] ; -++ NDS32_GPR32 reg_s ; -++ } u ; -++} NDS32_REG32_TAB; -++ -++typedef struct -++{ -++ union -++ { -++ int reg_a[16] ; -++ NDS32_GPR16 reg_s ; -++ } u ; -++} NDS32_REG16_TAB; -++ -++typedef struct -++{ -++ int d0lo; -++ int d0hi; -++ int d1lo; -++ int d1hi; -++} NDS32_DX_TAB; -++ -++typedef struct -++{ -++#ifdef __NDS32_EB__ -++ float fsr0; -++ float fsr1; -++ float fsr2; -++ float fsr3; -++ float fsr4; -++ float fsr5; -++ float fsr6; -++ float fsr7; -++#else -++ float fsr1; -++ float fsr0; -++ float fsr3; -++ float fsr2; -++ float fsr5; -++ float fsr4; -++ float fsr7; -++ float fsr6; -++#endif -++} NDS32_FSR8; -++ -++typedef struct -++{ -++ double dsr0; -++ double dsr1; -++ double dsr2; -++ double dsr3; -++} NDS32_DSR4; -++ -++typedef struct -++{ -++#ifdef __NDS32_EB__ -++ float fsr0; -++ float fsr1; -++ float fsr2; -++ float fsr3; -++ float fsr4; -++ float fsr5; -++ float fsr6; -++ float fsr7; -++ float fsr8; -++ float fsr9; -++ float fsr10; -++ float fsr11; -++ float fsr12; -++ float fsr13; -++ float fsr14; -++ float fsr15; -++#else -++ float fsr1; -++ float fsr0; -++ float fsr3; -++ float fsr2; -++ float fsr5; -++ float fsr4; -++ float fsr7; -++ float fsr6; -++ float fsr9; -++ float fsr8; -++ float fsr11; -++ float fsr10; -++ float fsr13; -++ float fsr12; -++ float fsr15; -++ float fsr14; -++#endif -++} NDS32_FSR16; -++ -++typedef struct -++{ -++ double dsr0; -++ double dsr1; -++ double dsr2; -++ double dsr3; -++ double dsr4; -++ double dsr5; -++ double dsr6; -++ double dsr7; -++} NDS32_DSR8; -++ -++typedef struct -++{ -++#ifdef __NDS32_EB__ -++ float fsr0; -++ float fsr1; -++ float fsr2; -++ float fsr3; -++ float fsr4; -++ float fsr5; -++ float fsr6; -++ float fsr7; -++ float fsr8; -++ float fsr9; -++ float fsr10; -++ float fsr11; -++ float fsr12; -++ float fsr13; -++ float fsr14; -++ float fsr15; -++ float fsr16; -++ float fsr17; -++ float fsr18; -++ float fsr19; -++ float fsr20; -++ float fsr21; -++ float fsr22; -++ float fsr23; -++ float fsr24; -++ float fsr25; -++ float fsr26; -++ float fsr27; -++ float fsr28; -++ float fsr29; -++ float fsr30; -++ float fsr31; -++#else -++ float fsr1; -++ float fsr0; -++ float fsr3; -++ float fsr2; -++ float fsr5; -++ float fsr4; -++ float fsr7; -++ float fsr6; -++ float fsr9; -++ float fsr8; -++ float fsr11; -++ float fsr10; -++ float fsr13; -++ float fsr12; -++ float fsr15; -++ float fsr14; -++ float fsr17; -++ float fsr16; -++ float fsr19; -++ float fsr18; -++ float fsr21; -++ float fsr20; -++ float fsr23; -++ float fsr22; -++ float fsr25; -++ float fsr24; -++ float fsr27; -++ float fsr26; -++ float fsr29; -++ float fsr28; -++ float fsr31; -++ float fsr30; -++#endif -++} NDS32_FSR32; -++ -++typedef struct -++{ -++ double dsr0; -++ double dsr1; -++ double dsr2; -++ double dsr3; -++ double dsr4; -++ double dsr5; -++ double dsr6; -++ double dsr7; -++ double dsr8; -++ double dsr9; -++ double dsr10; -++ double dsr11; -++ double dsr12; -++ double dsr13; -++ double dsr14; -++ double dsr15; -++} NDS32_DSR16; -++ -++typedef struct -++{ -++ double dsr0; -++ double dsr1; -++ double dsr2; -++ double dsr3; -++ double dsr4; -++ double dsr5; -++ double dsr6; -++ double dsr7; -++ double dsr8; -++ double dsr9; -++ double dsr10; -++ double dsr11; -++ double dsr12; -++ double dsr13; -++ double dsr14; -++ double dsr15; -++ double dsr16; -++ double dsr17; -++ double dsr18; -++ double dsr19; -++ double dsr20; -++ double dsr21; -++ double dsr22; -++ double dsr23; -++ double dsr24; -++ double dsr25; -++ double dsr26; -++ double dsr27; -++ double dsr28; -++ double dsr29; -++ double dsr30; -++ double dsr31; -++} NDS32_DSR32; -++ -++typedef struct -++{ -++ union -++ { -++ NDS32_FSR8 fsr_s ; -++ NDS32_DSR4 dsr_s ; -++ } u ; -++} NDS32_FPU8_TAB; -++ -++typedef struct -++{ -++ union -++ { -++ NDS32_FSR16 fsr_s ; -++ NDS32_DSR8 dsr_s ; -++ } u ; -++} NDS32_FPU16_TAB; -++ -++typedef struct -++{ -++ union -++ { -++ NDS32_FSR32 fsr_s ; -++ NDS32_DSR16 dsr_s ; -++ } u ; -++} NDS32_FPU32_TAB; -++ -++typedef struct -++{ -++ union -++ { -++ NDS32_FSR32 fsr_s ; -++ NDS32_DSR32 dsr_s ; -++ } u ; -++} NDS32_FPU64_TAB; -++ -++typedef struct -++{ -++ int ipc; -++ int ipsw; -++#if defined(NDS32_EXT_FPU_CONFIG_0) -++ NDS32_FPU8_TAB fpr; -++#elif defined(NDS32_EXT_FPU_CONFIG_1) -++ NDS32_FPU16_TAB fpr; -++#elif defined(NDS32_EXT_FPU_CONFIG_2) -++ NDS32_FPU32_TAB fpr; -++#elif defined(NDS32_EXT_FPU_CONFIG_3) -++ NDS32_FPU64_TAB fpr; -++#endif -++#if __NDS32_DX_REGS__ -++ NDS32_DX_TAB dxr; -++#endif -++#if __NDS32_EXT_IFC__ -++ int ifc_lp; -++ int filler; -++#endif -++#if __NDS32_REDUCED_REGS__ || __NDS32_REDUCE_REGS -++ NDS32_REG16_TAB gpr; -++#else -++ NDS32_REG32_TAB gpr; -++#endif -++} NDS32_CONTEXT; -++ -++/* Predefined Vector Definition. -++ -++ For IVIC Mode: 9 to 14 are for hardware interrupt -++ and 15 is for software interrupt. -++ For EVIC Mode: 9 to 72 are for hardware interrupt -++ and software interrupt can be routed to any one of them. -++ -++ You may want to define your hardware interrupts in the following way -++ for easy maintainance. -++ -++ IVIC mode: -++ #define MY_HW_IVIC_TIMER NDS32_VECTOR_INTERRUPT_HW0 + 1 -++ #define MY_HW_IVIC_USB NDS32_VECTOR_INTERRUPT_HW0 + 3 -++ EVIC mode: -++ #define MY_HW_EVIC_DMA NDS32_VECTOR_INTERRUPT_HW0 + 2 -++ #define MY_HW_EVIC_SWI NDS32_VECTOR_INTERRUPT_HW0 + 10 */ -++#define NDS32_VECTOR_RESET 0 -++#define NDS32_VECTOR_TLB_FILL 1 -++#define NDS32_VECTOR_PTE_NOT_PRESENT 2 -++#define NDS32_VECTOR_TLB_MISC 3 -++#define NDS32_VECTOR_TLB_VLPT_MISS 4 -++#define NDS32_VECTOR_MACHINE_ERROR 5 -++#define NDS32_VECTOR_DEBUG_RELATED 6 -++#define NDS32_VECTOR_GENERAL_EXCEPTION 7 -++#define NDS32_VECTOR_SYSCALL 8 -++#define NDS32_VECTOR_INTERRUPT_HW0 9 -++#define NDS32_VECTOR_INTERRUPT_HW1 10 -++#define NDS32_VECTOR_INTERRUPT_HW2 11 -++#define NDS32_VECTOR_INTERRUPT_HW3 12 -++#define NDS32_VECTOR_INTERRUPT_HW4 13 -++#define NDS32_VECTOR_INTERRUPT_HW5 14 -++#define NDS32_VECTOR_INTERRUPT_HW6 15 -++#define NDS32_VECTOR_SWI 15 /* THIS IS FOR IVIC MODE ONLY */ -++#define NDS32_VECTOR_INTERRUPT_HW7 16 -++#define NDS32_VECTOR_INTERRUPT_HW8 17 -++#define NDS32_VECTOR_INTERRUPT_HW9 18 -++#define NDS32_VECTOR_INTERRUPT_HW10 19 -++#define NDS32_VECTOR_INTERRUPT_HW11 20 -++#define NDS32_VECTOR_INTERRUPT_HW12 21 -++#define NDS32_VECTOR_INTERRUPT_HW13 22 -++#define NDS32_VECTOR_INTERRUPT_HW14 23 -++#define NDS32_VECTOR_INTERRUPT_HW15 24 -++#define NDS32_VECTOR_INTERRUPT_HW16 25 -++#define NDS32_VECTOR_INTERRUPT_HW17 26 -++#define NDS32_VECTOR_INTERRUPT_HW18 27 -++#define NDS32_VECTOR_INTERRUPT_HW19 28 -++#define NDS32_VECTOR_INTERRUPT_HW20 29 -++#define NDS32_VECTOR_INTERRUPT_HW21 30 -++#define NDS32_VECTOR_INTERRUPT_HW22 31 -++#define NDS32_VECTOR_INTERRUPT_HW23 32 -++#define NDS32_VECTOR_INTERRUPT_HW24 33 -++#define NDS32_VECTOR_INTERRUPT_HW25 34 -++#define NDS32_VECTOR_INTERRUPT_HW26 35 -++#define NDS32_VECTOR_INTERRUPT_HW27 36 -++#define NDS32_VECTOR_INTERRUPT_HW28 37 -++#define NDS32_VECTOR_INTERRUPT_HW29 38 -++#define NDS32_VECTOR_INTERRUPT_HW30 39 -++#define NDS32_VECTOR_INTERRUPT_HW31 40 -++#define NDS32_VECTOR_INTERRUPT_HW32 41 -++#define NDS32_VECTOR_INTERRUPT_HW33 42 -++#define NDS32_VECTOR_INTERRUPT_HW34 43 -++#define NDS32_VECTOR_INTERRUPT_HW35 44 -++#define NDS32_VECTOR_INTERRUPT_HW36 45 -++#define NDS32_VECTOR_INTERRUPT_HW37 46 -++#define NDS32_VECTOR_INTERRUPT_HW38 47 -++#define NDS32_VECTOR_INTERRUPT_HW39 48 -++#define NDS32_VECTOR_INTERRUPT_HW40 49 -++#define NDS32_VECTOR_INTERRUPT_HW41 50 -++#define NDS32_VECTOR_INTERRUPT_HW42 51 -++#define NDS32_VECTOR_INTERRUPT_HW43 52 -++#define NDS32_VECTOR_INTERRUPT_HW44 53 -++#define NDS32_VECTOR_INTERRUPT_HW45 54 -++#define NDS32_VECTOR_INTERRUPT_HW46 55 -++#define NDS32_VECTOR_INTERRUPT_HW47 56 -++#define NDS32_VECTOR_INTERRUPT_HW48 57 -++#define NDS32_VECTOR_INTERRUPT_HW49 58 -++#define NDS32_VECTOR_INTERRUPT_HW50 59 -++#define NDS32_VECTOR_INTERRUPT_HW51 60 -++#define NDS32_VECTOR_INTERRUPT_HW52 61 -++#define NDS32_VECTOR_INTERRUPT_HW53 62 -++#define NDS32_VECTOR_INTERRUPT_HW54 63 -++#define NDS32_VECTOR_INTERRUPT_HW55 64 -++#define NDS32_VECTOR_INTERRUPT_HW56 65 -++#define NDS32_VECTOR_INTERRUPT_HW57 66 -++#define NDS32_VECTOR_INTERRUPT_HW58 67 -++#define NDS32_VECTOR_INTERRUPT_HW59 68 -++#define NDS32_VECTOR_INTERRUPT_HW60 69 -++#define NDS32_VECTOR_INTERRUPT_HW61 70 -++#define NDS32_VECTOR_INTERRUPT_HW62 71 -++#define NDS32_VECTOR_INTERRUPT_HW63 72 -++ -++#define NDS32ATTR_RESET(option) __attribute__((reset(option))) -++#define NDS32ATTR_EXCEPT(type) __attribute__((exception(type))) -++#define NDS32ATTR_EXCEPTION(type) __attribute__((exception(type))) -++#define NDS32ATTR_INTERRUPT(type) __attribute__((interrupt(type))) -++#define NDS32ATTR_ISR(type) __attribute__((interrupt(type))) -++ -++#endif /* nds32_isr.h */ -+diff --git a/gcc/config/nds32/pipelines.md b/gcc/config/nds32/pipelines.md -+index 34288076f42..12cd2623f1c 100644 -+--- a/gcc/config/nds32/pipelines.md -++++ b/gcc/config/nds32/pipelines.md -+@@ -43,6 +43,24 @@ -+ (include "nds32-n9-2r1w.md") -+ -+ -++;; ------------------------------------------------------------------------ -++;; Include N10 pipeline settings. -++;; ------------------------------------------------------------------------ -++(include "nds32-n10.md") -++ -++ -++;; ------------------------------------------------------------------------ -++;; Include Graywolf pipeline settings. -++;; ------------------------------------------------------------------------ -++(include "nds32-graywolf.md") -++ -++ -++;; ------------------------------------------------------------------------ -++;; Include N12/N13 pipeline settings. -++;; ------------------------------------------------------------------------ -++(include "nds32-n13.md") -++ -++ -+ ;; ------------------------------------------------------------------------ -+ ;; Define simple pipeline settings. -+ ;; ------------------------------------------------------------------------ -+diff --git a/gcc/config/nds32/predicates.md b/gcc/config/nds32/predicates.md -+index 9eb84685514..ee4cf3cf48e 100644 -+--- a/gcc/config/nds32/predicates.md -++++ b/gcc/config/nds32/predicates.md -+@@ -40,7 +40,15 @@ -+ (match_code "mult,and,ior,xor")) -+ -+ (define_predicate "nds32_symbolic_operand" -+- (match_code "const,symbol_ref,label_ref")) -++ (and (match_code "const,symbol_ref,label_ref") -++ (match_test "!(TARGET_ICT_MODEL_LARGE -++ && nds32_indirect_call_referenced_p (op))"))) -++ -++(define_predicate "nds32_nonunspec_symbolic_operand" -++ (and (match_code "const,symbol_ref,label_ref") -++ (match_test "!flag_pic && nds32_const_unspec_p (op) -++ && !(TARGET_ICT_MODEL_LARGE -++ && nds32_indirect_call_referenced_p (op))"))) -+ -+ (define_predicate "nds32_reg_constant_operand" -+ (ior (match_operand 0 "register_operand") -+@@ -56,14 +64,51 @@ -+ (and (match_operand 0 "const_int_operand") -+ (match_test "satisfies_constraint_Is11 (op)")))) -+ -++(define_predicate "nds32_imm_0_1_operand" -++ (and (match_operand 0 "const_int_operand") -++ (ior (match_test "satisfies_constraint_Iv00 (op)") -++ (match_test "satisfies_constraint_Iv01 (op)")))) -++ -++(define_predicate "nds32_imm_1_2_operand" -++ (and (match_operand 0 "const_int_operand") -++ (ior (match_test "satisfies_constraint_Iv01 (op)") -++ (match_test "satisfies_constraint_Iv02 (op)")))) -++ -++(define_predicate "nds32_imm_1_2_4_8_operand" -++ (and (match_operand 0 "const_int_operand") -++ (ior (ior (match_test "satisfies_constraint_Iv01 (op)") -++ (match_test "satisfies_constraint_Iv02 (op)")) -++ (ior (match_test "satisfies_constraint_Iv04 (op)") -++ (match_test "satisfies_constraint_Iv08 (op)"))))) -++ -++(define_predicate "nds32_imm2u_operand" -++ (and (match_operand 0 "const_int_operand") -++ (match_test "satisfies_constraint_Iu02 (op)"))) -++ -++(define_predicate "nds32_imm4u_operand" -++ (and (match_operand 0 "const_int_operand") -++ (match_test "satisfies_constraint_Iu04 (op)"))) -++ -+ (define_predicate "nds32_imm5u_operand" -+ (and (match_operand 0 "const_int_operand") -+ (match_test "satisfies_constraint_Iu05 (op)"))) -+ -++(define_predicate "nds32_imm6u_operand" -++ (and (match_operand 0 "const_int_operand") -++ (match_test "satisfies_constraint_Iu06 (op)"))) -++ -++(define_predicate "nds32_rimm4u_operand" -++ (ior (match_operand 0 "register_operand") -++ (match_operand 0 "nds32_imm4u_operand"))) -++ -+ (define_predicate "nds32_rimm5u_operand" -+ (ior (match_operand 0 "register_operand") -+ (match_operand 0 "nds32_imm5u_operand"))) -+ -++(define_predicate "nds32_rimm6u_operand" -++ (ior (match_operand 0 "register_operand") -++ (match_operand 0 "nds32_imm6u_operand"))) -++ -+ (define_predicate "nds32_move_operand" -+ (and (match_operand 0 "general_operand") -+ (not (match_code "high,const,symbol_ref,label_ref"))) -+@@ -78,6 +123,20 @@ -+ return true; -+ }) -+ -++(define_predicate "nds32_vmove_operand" -++ (and (match_operand 0 "general_operand") -++ (not (match_code "high,const,symbol_ref,label_ref"))) -++{ -++ /* If the constant op does NOT satisfy Is20 nor Ihig, -++ we can not perform move behavior by a single instruction. */ -++ if (GET_CODE (op) == CONST_VECTOR -++ && !satisfies_constraint_CVs2 (op) -++ && !satisfies_constraint_CVhi (op)) -++ return false; -++ -++ return true; -++}) -++ -+ (define_predicate "nds32_and_operand" -+ (match_operand 0 "nds32_reg_constant_operand") -+ { -+@@ -127,6 +186,15 @@ -+ (ior (match_operand 0 "nds32_symbolic_operand") -+ (match_operand 0 "nds32_general_register_operand"))) -+ -++(define_predicate "nds32_insv_operand" -++ (match_code "const_int") -++{ -++ return INTVAL (op) == 0 -++ || INTVAL (op) == 8 -++ || INTVAL (op) == 16 -++ || INTVAL (op) == 24; -++}) -++ -+ (define_predicate "nds32_lmw_smw_base_operand" -+ (and (match_code "mem") -+ (match_test "nds32_valid_smw_lwm_base_p (op)"))) -+diff --git a/gcc/config/nds32/t-elf b/gcc/config/nds32/t-elf -+new file mode 100644 -+index 00000000000..3401dae4881 -+--- /dev/null -++++ b/gcc/config/nds32/t-elf -+@@ -0,0 +1,42 @@ -++# The multilib settings of Andes NDS32 cpu for GNU compiler -++# Copyright (C) 2012-2018 Free Software Foundation, Inc. -++# Contributed by Andes Technology Corporation. -++# -++# This file is part of GCC. -++# -++# GCC is free software; you can redistribute it and/or modify it -++# under the terms of the GNU General Public License as published -++# by the Free Software Foundation; either version 3, or (at your -++# option) any later version. -++# -++# GCC is distributed in the hope that it will be useful, but WITHOUT -++# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY -++# or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public -++# License for more details. -++# -++# You should have received a copy of the GNU General Public License -++# along with GCC; see the file COPYING3. If not see -++# . -++ -++# We also define a macro MULTILIB_DEFAULTS in nds32.h that tells the -++# driver program which options are defaults for this target and thus -++# do not need to be handled specially. -++MULTILIB_OPTIONS += mcmodel=small/mcmodel=medium/mcmodel=large mvh -++ -++ifneq ($(filter graywolf,$(TM_MULTILIB_CONFIG)),) -++MULTILIB_OPTIONS += mcpu=graywolf -++endif -++ -++ifneq ($(filter dsp,$(TM_MULTILIB_CONFIG)),) -++MULTILIB_OPTIONS += mext-dsp -++endif -++ -++ifneq ($(filter zol,$(TM_MULTILIB_CONFIG)),) -++MULTILIB_OPTIONS += mext-zol -++endif -++ -++ifneq ($(filter v3m+,$(TM_MULTILIB_CONFIG)),) -++MULTILIB_OPTIONS += march=v3m+ -++endif -++ -++# ------------------------------------------------------------------------ -+diff --git a/gcc/config/nds32/t-linux b/gcc/config/nds32/t-linux -+new file mode 100644 -+index 00000000000..33328f65e7b -+--- /dev/null -++++ b/gcc/config/nds32/t-linux -+@@ -0,0 +1,26 @@ -++# The multilib settings of Andes NDS32 cpu for GNU compiler -++# Copyright (C) 2012-2018 Free Software Foundation, Inc. -++# Contributed by Andes Technology Corporation. -++# -++# This file is part of GCC. -++# -++# GCC is free software; you can redistribute it and/or modify it -++# under the terms of the GNU General Public License as published -++# by the Free Software Foundation; either version 3, or (at your -++# option) any later version. -++# -++# GCC is distributed in the hope that it will be useful, but WITHOUT -++# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY -++# or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public -++# License for more details. -++# -++# You should have received a copy of the GNU General Public License -++# along with GCC; see the file COPYING3. If not see -++# . -++ -++# We also define a macro MULTILIB_DEFAULTS in nds32.h that tells the -++# driver program which options are defaults for this target and thus -++# do not need to be handled specially. -++MULTILIB_OPTIONS += -++ -++# ------------------------------------------------------------------------ -+diff --git a/gcc/configure b/gcc/configure -+index 6121e163259..07a485e8598 100755 -+--- a/gcc/configure -++++ b/gcc/configure -+@@ -27784,7 +27784,7 @@ esac -+ # version to the per-target configury. -+ case "$cpu_type" in -+ aarch64 | alpha | arc | arm | avr | bfin | cris | i386 | m32c | m68k \ -+- | microblaze | mips | nios2 | pa | riscv | rs6000 | score | sparc | spu \ -++ | microblaze | mips | nds32 | nios2 | pa | riscv | rs6000 | score | sparc | spu \ -+ | tilegx | tilepro | visium | xstormy16 | xtensa) -+ insn="nop" -+ ;; -+diff --git a/gcc/configure.ac b/gcc/configure.ac -+index b066cc609e1..ae73df30b42 100644 -+--- a/gcc/configure.ac -++++ b/gcc/configure.ac -+@@ -4910,7 +4910,7 @@ esac -+ # version to the per-target configury. -+ case "$cpu_type" in -+ aarch64 | alpha | arc | arm | avr | bfin | cris | i386 | m32c | m68k \ -+- | microblaze | mips | nios2 | pa | riscv | rs6000 | score | sparc | spu \ -++ | microblaze | mips | nds32 | nios2 | pa | riscv | rs6000 | score | sparc | spu \ -+ | tilegx | tilepro | visium | xstormy16 | xtensa) -+ insn="nop" -+ ;; -+diff --git a/gcc/testsuite/gcc.c-torture/execute/20010122-1.c b/gcc/testsuite/gcc.c-torture/execute/20010122-1.c -+index 4eeb8c7a30b..6cd02bc2aa8 100644 -+--- a/gcc/testsuite/gcc.c-torture/execute/20010122-1.c -++++ b/gcc/testsuite/gcc.c-torture/execute/20010122-1.c -+@@ -1,4 +1,5 @@ -+ /* { dg-skip-if "requires frame pointers" { *-*-* } "-fomit-frame-pointer" "" } */ -++/* { dg-additional-options "-malways-save-lp" { target nds32*-*-* } } */ -+ /* { dg-require-effective-target return_address } */ -+ -+ extern void exit (int); -+diff --git a/gcc/testsuite/gcc.dg/lower-subreg-1.c b/gcc/testsuite/gcc.dg/lower-subreg-1.c -+index 6bae73055a9..4a5099bfbdb 100644 -+--- a/gcc/testsuite/gcc.dg/lower-subreg-1.c -++++ b/gcc/testsuite/gcc.dg/lower-subreg-1.c -+@@ -1,4 +1,4 @@ -+-/* { dg-do compile { target { ! { mips64 || { aarch64*-*-* arm*-*-* ia64-*-* sparc*-*-* spu-*-* tilegx-*-* } } } } } */ -++/* { dg-do compile { target { ! { mips64 || { aarch64*-*-* arm*-*-* ia64-*-* nds32*-*-* sparc*-*-* spu-*-* tilegx-*-* } } } } } */ -+ /* { dg-options "-O -fdump-rtl-subreg1" } */ -+ /* { dg-additional-options "-mno-stv" { target ia32 } } */ -+ /* { dg-skip-if "" { { i?86-*-* x86_64-*-* } && x32 } } */ -+diff --git a/gcc/testsuite/gcc.dg/stack-usage-1.c b/gcc/testsuite/gcc.dg/stack-usage-1.c -+index 45d2c7b6aae..b9ae9dc6030 100644 -+--- a/gcc/testsuite/gcc.dg/stack-usage-1.c -++++ b/gcc/testsuite/gcc.dg/stack-usage-1.c -+@@ -2,6 +2,7 @@ -+ /* { dg-options "-fstack-usage" } */ -+ /* nvptx doesn't have a reg allocator, and hence no stack usage data. */ -+ /* { dg-skip-if "" { nvptx-*-* } } */ -++/* { dg-options "-fstack-usage -fno-omit-frame-pointer" { target { nds32*-*-* } } } */ -+ -+ /* This is aimed at testing basic support for -fstack-usage in the back-ends. -+ See the SPARC back-end for example (grep flag_stack_usage_info in sparc.c). -+diff --git a/gcc/testsuite/gcc.target/nds32/builtin-setgie-dis.c b/gcc/testsuite/gcc.target/nds32/builtin-setgie-dis.c -+deleted file mode 100644 -+index 2dceed98ac8..00000000000 -+--- a/gcc/testsuite/gcc.target/nds32/builtin-setgie-dis.c -++++ /dev/null -+@@ -1,11 +0,0 @@ -+-/* Verify that we generate setgie.d instruction with builtin function. */ -+- -+-/* { dg-do compile } */ -+-/* { dg-options "-O0" } */ -+-/* { dg-final { scan-assembler "\\tsetgie.d" } } */ -+- -+-void -+-test (void) -+-{ -+- __builtin_nds32_setgie_dis (); -+-} -+diff --git a/gcc/testsuite/gcc.target/nds32/builtin-setgie-en.c b/gcc/testsuite/gcc.target/nds32/builtin-setgie-en.c -+deleted file mode 100644 -+index 892887019c9..00000000000 -+--- a/gcc/testsuite/gcc.target/nds32/builtin-setgie-en.c -++++ /dev/null -+@@ -1,11 +0,0 @@ -+-/* Verify that we generate setgie.e instruction with builtin function. */ -+- -+-/* { dg-do compile } */ -+-/* { dg-options "-O0" } */ -+-/* { dg-final { scan-assembler "\\tsetgie.e" } } */ -+- -+-void -+-test (void) -+-{ -+- __builtin_nds32_setgie_en (); -+-} -+diff --git a/gcc/testsuite/gcc.target/nds32/builtin-setgie_mtsr_mfsr.c b/gcc/testsuite/gcc.target/nds32/builtin-setgie_mtsr_mfsr.c -+new file mode 100644 -+index 00000000000..3b4eede295d -+--- /dev/null -++++ b/gcc/testsuite/gcc.target/nds32/builtin-setgie_mtsr_mfsr.c -+@@ -0,0 +1,36 @@ -++/* This is a test program for checking gie with -++ mtsr/mfsr instruction. */ -++ -++/* { dg-do run } */ -++/* { dg-options "-O0" } */ -++ -++#include -++#include -++ -++int -++main () -++{ -++ unsigned int psw; -++ unsigned int gie; -++ unsigned int pfm_ctl; -++ -++ __nds32__setgie_en (); -++ __nds32__dsb(); /* This is needed for waiting pipeline. */ -++ psw = __nds32__mfsr (NDS32_SR_PSW); -++ -++ gie = psw & 0x00000001; -++ -++ if (gie != 1) -++ abort (); -++ -++ psw = psw & 0xFFFFFFFE; -++ __nds32__mtsr (psw,NDS32_SR_PSW); -++ __nds32__dsb(); /* This is needed for waiting pipeline. */ -++ psw = __nds32__mfsr (NDS32_SR_PSW); -++ gie = psw & 0x00000001; -++ -++ if (gie != 0) -++ abort (); -++ else -++ exit (0); -++} -+diff --git a/gcc/testsuite/gcc.target/nds32/compile/builtin-clr-pending-hw.c b/gcc/testsuite/gcc.target/nds32/compile/builtin-clr-pending-hw.c -+new file mode 100644 -+index 00000000000..fce90e9720b -+--- /dev/null -++++ b/gcc/testsuite/gcc.target/nds32/compile/builtin-clr-pending-hw.c -+@@ -0,0 +1,16 @@ -++/* { dg-do compile } */ -++/* { dg-options "-O1" } */ -++ -++#include -++ -++void -++main (void) -++{ -++ __nds32__clr_pending_hwint (NDS32_INT_H0); -++ __nds32__clr_pending_hwint (NDS32_INT_H1); -++ __nds32__clr_pending_hwint (NDS32_INT_H2); -++ -++ __nds32__clr_pending_hwint (NDS32_INT_H15); -++ __nds32__clr_pending_hwint (NDS32_INT_H16); -++ __nds32__clr_pending_hwint (NDS32_INT_H31); -++} -+diff --git a/gcc/testsuite/gcc.target/nds32/compile/builtin-clr-pending.c b/gcc/testsuite/gcc.target/nds32/compile/builtin-clr-pending.c -+new file mode 100644 -+index 00000000000..08e1dd0c83f -+--- /dev/null -++++ b/gcc/testsuite/gcc.target/nds32/compile/builtin-clr-pending.c -+@@ -0,0 +1,10 @@ -++/* { dg-do compile } */ -++/* { dg-options "-O1" } */ -++ -++#include -++ -++void -++main (void) -++{ -++ __nds32__clr_pending_swint (); -++} -+diff --git a/gcc/testsuite/gcc.target/nds32/compile/builtin-disable.c b/gcc/testsuite/gcc.target/nds32/compile/builtin-disable.c -+new file mode 100644 -+index 00000000000..a3a1f44fce5 -+--- /dev/null -++++ b/gcc/testsuite/gcc.target/nds32/compile/builtin-disable.c -+@@ -0,0 +1,13 @@ -++/* { dg-do compile } */ -++/* { dg-options "-O1" } */ -++ -++#include -++ -++void -++main (void) -++{ -++ __nds32__disable_int (NDS32_INT_H15); -++ __nds32__disable_int (NDS32_INT_H16); -++ __nds32__disable_int (NDS32_INT_H31); -++ __nds32__disable_int (NDS32_INT_SWI); -++} -+diff --git a/gcc/testsuite/gcc.target/nds32/compile/builtin-enable.c b/gcc/testsuite/gcc.target/nds32/compile/builtin-enable.c -+new file mode 100644 -+index 00000000000..e18ed7a9ff0 -+--- /dev/null -++++ b/gcc/testsuite/gcc.target/nds32/compile/builtin-enable.c -+@@ -0,0 +1,13 @@ -++/* { dg-do compile } */ -++/* { dg-options "-O1" } */ -++ -++#include -++ -++void -++main (void) -++{ -++ __nds32__enable_int (NDS32_INT_H15); -++ __nds32__enable_int (NDS32_INT_H16); -++ __nds32__enable_int (NDS32_INT_H31); -++ __nds32__enable_int (NDS32_INT_SWI); -++} -+diff --git a/gcc/testsuite/gcc.target/nds32/compile/builtin-get-pending-int.c b/gcc/testsuite/gcc.target/nds32/compile/builtin-get-pending-int.c -+new file mode 100644 -+index 00000000000..4ced0a55d96 -+--- /dev/null -++++ b/gcc/testsuite/gcc.target/nds32/compile/builtin-get-pending-int.c -+@@ -0,0 +1,14 @@ -++/* { dg-do compile } */ -++/* { dg-options "-O1" } */ -++ -++#include -++ -++int -++main (void) -++{ -++ int a = __nds32__get_pending_int (NDS32_INT_H15); -++ int b = __nds32__get_pending_int (NDS32_INT_SWI); -++ int c = __nds32__get_pending_int (NDS32_INT_H16); -++ -++ return a + b + c; -++} -+diff --git a/gcc/testsuite/gcc.target/nds32/compile/builtin-get-trig.c b/gcc/testsuite/gcc.target/nds32/compile/builtin-get-trig.c -+new file mode 100644 -+index 00000000000..a394a60958a -+--- /dev/null -++++ b/gcc/testsuite/gcc.target/nds32/compile/builtin-get-trig.c -+@@ -0,0 +1,14 @@ -++/* { dg-do compile } */ -++/* { dg-options "-O1" } */ -++ -++#include -++ -++int -++main (void) -++{ -++ int a = __nds32__get_trig_type (NDS32_INT_H0); -++ int b = __nds32__get_trig_type (NDS32_INT_H15); -++ int c = __nds32__get_trig_type (NDS32_INT_H16); -++ int d = __nds32__get_trig_type (NDS32_INT_H31); -++ return a + b + c + d; -++} -+diff --git a/gcc/testsuite/gcc.target/nds32/builtin-isb.c b/gcc/testsuite/gcc.target/nds32/compile/builtin-isb.c -+similarity index 100% -+rename from gcc/testsuite/gcc.target/nds32/builtin-isb.c -+rename to gcc/testsuite/gcc.target/nds32/compile/builtin-isb.c -+diff --git a/gcc/testsuite/gcc.target/nds32/builtin-isync.c b/gcc/testsuite/gcc.target/nds32/compile/builtin-isync.c -+similarity index 100% -+rename from gcc/testsuite/gcc.target/nds32/builtin-isync.c -+rename to gcc/testsuite/gcc.target/nds32/compile/builtin-isync.c -+diff --git a/gcc/testsuite/gcc.target/nds32/builtin-mfsr-mtsr.c b/gcc/testsuite/gcc.target/nds32/compile/builtin-mfsr-mtsr.c -+similarity index 100% -+rename from gcc/testsuite/gcc.target/nds32/builtin-mfsr-mtsr.c -+rename to gcc/testsuite/gcc.target/nds32/compile/builtin-mfsr-mtsr.c -+diff --git a/gcc/testsuite/gcc.target/nds32/builtin-mfusr-mtusr.c b/gcc/testsuite/gcc.target/nds32/compile/builtin-mfusr-mtusr.c -+similarity index 100% -+rename from gcc/testsuite/gcc.target/nds32/builtin-mfusr-mtusr.c -+rename to gcc/testsuite/gcc.target/nds32/compile/builtin-mfusr-mtusr.c -+diff --git a/gcc/testsuite/gcc.target/nds32/compile/builtin-set-pending.c b/gcc/testsuite/gcc.target/nds32/compile/builtin-set-pending.c -+new file mode 100644 -+index 00000000000..f10b83d2d60 -+--- /dev/null -++++ b/gcc/testsuite/gcc.target/nds32/compile/builtin-set-pending.c -+@@ -0,0 +1,10 @@ -++/* { dg-do compile } */ -++/* { dg-options "-O1" } */ -++ -++#include -++ -++int -++main (void) -++{ -++ __nds32__set_pending_swint (); -++} -+diff --git a/gcc/testsuite/gcc.target/nds32/compile/builtin-set-trig-edge.c b/gcc/testsuite/gcc.target/nds32/compile/builtin-set-trig-edge.c -+new file mode 100644 -+index 00000000000..bd8178c7165 -+--- /dev/null -++++ b/gcc/testsuite/gcc.target/nds32/compile/builtin-set-trig-edge.c -+@@ -0,0 +1,13 @@ -++/* { dg-do compile } */ -++/* { dg-options "-O1" } */ -++ -++#include -++ -++void -++main (void) -++{ -++ __nds32__set_trig_type_edge (NDS32_INT_H0); -++ __nds32__set_trig_type_edge (NDS32_INT_H15); -++ __nds32__set_trig_type_edge (NDS32_INT_H16); -++ __nds32__set_trig_type_edge (NDS32_INT_H31); -++} -+diff --git a/gcc/testsuite/gcc.target/nds32/compile/builtin-set-trig-level.c b/gcc/testsuite/gcc.target/nds32/compile/builtin-set-trig-level.c -+new file mode 100644 -+index 00000000000..17805433280 -+--- /dev/null -++++ b/gcc/testsuite/gcc.target/nds32/compile/builtin-set-trig-level.c -+@@ -0,0 +1,13 @@ -++/* { dg-do compile } */ -++/* { dg-options "-O1" } */ -++ -++#include -++ -++void -++main (void) -++{ -++ __nds32__set_trig_type_level (NDS32_INT_H0); -++ __nds32__set_trig_type_level (NDS32_INT_H15); -++ __nds32__set_trig_type_level (NDS32_INT_H16); -++ __nds32__set_trig_type_level (NDS32_INT_H31); -++} -+diff --git a/gcc/testsuite/gcc.target/nds32/compile/builtin-setgie-dis.c b/gcc/testsuite/gcc.target/nds32/compile/builtin-setgie-dis.c -+new file mode 100644 -+index 00000000000..e143d3fefb7 -+--- /dev/null -++++ b/gcc/testsuite/gcc.target/nds32/compile/builtin-setgie-dis.c -+@@ -0,0 +1,13 @@ -++/* Verify that we generate setgie.d instruction with builtin function. */ -++ -++/* { dg-do compile } */ -++/* { dg-options "-O0" } */ -++/* { dg-final { scan-assembler "\\tsetgie.d" } } */ -++ -++#include -++ -++void -++test (void) -++{ -++ __nds32__setgie_dis (); -++} -+diff --git a/gcc/testsuite/gcc.target/nds32/compile/builtin-setgie-en.c b/gcc/testsuite/gcc.target/nds32/compile/builtin-setgie-en.c -+new file mode 100644 -+index 00000000000..ed95782ee5f -+--- /dev/null -++++ b/gcc/testsuite/gcc.target/nds32/compile/builtin-setgie-en.c -+@@ -0,0 +1,13 @@ -++/* Verify that we generate setgie.e instruction with builtin function. */ -++ -++/* { dg-do compile */ -++/* { dg-options "-O0" } */ -++/* { dg-final { scan-assembler "\\tsetgie.e" } } */ -++ -++#include -++ -++void -++test (void) -++{ -++ __nds32__setgie_en (); -++} -+diff --git a/gcc/testsuite/gcc.target/nds32/nds32.exp b/gcc/testsuite/gcc.target/nds32/nds32.exp -+index 44ce72d2583..2f1bff60d67 100644 -+--- a/gcc/testsuite/gcc.target/nds32/nds32.exp -++++ b/gcc/testsuite/gcc.target/nds32/nds32.exp -+@@ -38,8 +38,10 @@ if ![info exists DEFAULT_CFLAGS] then { -+ dg-init -+ -+ # Main loop. -+-dg-runtest [lsort [glob -nocomplain $srcdir/$subdir/*.\[cS\]]] \ -++dg-runtest [lsort [glob -nocomplain $srcdir/$subdir/compile/*.\[cS\]]] \ -+ "" $DEFAULT_CFLAGS -++gcc-dg-runtest [lsort [glob -nocomplain $srcdir/$subdir/*.\[cS\]]] \ -++ "" "" -+ -+ # All done. -+ dg-finish -+diff --git a/gcc/testsuite/lib/target-supports.exp b/gcc/testsuite/lib/target-supports.exp -+index 50665dfd30e..fbf7998b7ed 100644 -+--- a/gcc/testsuite/lib/target-supports.exp -++++ b/gcc/testsuite/lib/target-supports.exp -+@@ -8767,6 +8767,7 @@ proc check_effective_target_logical_op_short_circuit {} { -+ || [istarget avr*-*-*] -+ || [istarget crisv32-*-*] || [istarget cris-*-*] -+ || [istarget mmix-*-*] -++ || [istarget nds32*-*-*] -+ || [istarget s390*-*-*] -+ || [istarget powerpc*-*-*] -+ || [istarget nios2*-*-*] -+diff --git a/libgcc/config.host b/libgcc/config.host -+index 11b4acaff55..fbbc9219d68 100644 -+--- a/libgcc/config.host -++++ b/libgcc/config.host -+@@ -974,6 +974,23 @@ msp430*-*-elf) -+ tmake_file="$tm_file t-crtstuff t-fdpbit msp430/t-msp430" -+ extra_parts="$extra_parts libmul_none.a libmul_16.a libmul_32.a libmul_f5.a" -+ ;; -++nds32*-linux*) -++ # Basic makefile fragment and extra_parts for crt stuff. -++ # We also append c-isr library implementation. -++ tmake_file="${tmake_file} t-slibgcc-libgcc" -++ tmake_file="${tmake_file} nds32/t-nds32-glibc nds32/t-crtstuff t-softfp-sfdf t-softfp" -++ # The header file of defining MD_FALLBACK_FRAME_STATE_FOR. -++ md_unwind_header=nds32/linux-unwind.h -++ # Append library definition makefile fragment according to --with-nds32-lib=X setting. -++ case "${with_nds32_lib}" in -++ "" | glibc | uclibc ) -++ ;; -++ *) -++ echo "Cannot accept --with-nds32-lib=$with_nds32_lib, available values are: glibc uclibc" 1>&2 -++ exit 1 -++ ;; -++ esac -++ ;; -+ nds32*-elf*) -+ # Basic makefile fragment and extra_parts for crt stuff. -+ # We also append c-isr library implementation. -+diff --git a/libgcc/config/nds32/initfini.c b/libgcc/config/nds32/initfini.c -+index 49ca44fa659..dfbcc43f776 100644 -+--- a/libgcc/config/nds32/initfini.c -++++ b/libgcc/config/nds32/initfini.c -+@@ -25,6 +25,10 @@ -+ see the files COPYING3 and COPYING.RUNTIME respectively. If not, see -+ . */ -+ -++#include -++/* Need header file for `struct object' type. */ -++#include "../libgcc/unwind-dw2-fde.h" -++ -+ /* Declare a pointer to void function type. */ -+ typedef void (*func_ptr) (void); -+ -+@@ -42,11 +46,59 @@ typedef void (*func_ptr) (void); -+ refer to only the __CTOR_END__ symbol in crtfini.o and the __DTOR_LIST__ -+ symbol in crtinit.o, where they are defined. */ -+ -+-static func_ptr __CTOR_LIST__[1] __attribute__ ((section (".ctors"))) -+- = { (func_ptr) (-1) }; -++static func_ptr __CTOR_LIST__[1] __attribute__ ((section (".ctors"), used)) -++ = { (func_ptr) 0 }; -++ -++static func_ptr __DTOR_LIST__[1] __attribute__ ((section (".dtors"), used)) -++ = { (func_ptr) 0 }; -++ -++ -++#ifdef SUPPORT_UNWINDING_DWARF2 -++/* Preparation of exception handling with dwar2 mechanism registration. */ -+ -+-static func_ptr __DTOR_LIST__[1] __attribute__ ((section (".dtors"))) -+- = { (func_ptr) (-1) }; -++asm ("\n\ -++ .section .eh_frame,\"aw\",@progbits\n\ -++ .global __EH_FRAME_BEGIN__\n\ -++ .type __EH_FRAME_BEGIN__, @object\n\ -++ .align 2\n\ -++__EH_FRAME_BEGIN__:\n\ -++ ! Beginning location of eh_frame section\n\ -++ .previous\n\ -++"); -++ -++extern func_ptr __EH_FRAME_BEGIN__[]; -++ -++ -++/* Note that the following two functions are going to be chained into -++ constructor and destructor list, repectively. So these two declarations -++ must be placed after __CTOR_LIST__ and __DTOR_LIST. */ -++extern void __nds32_register_eh(void) __attribute__((constructor, used)); -++extern void __nds32_deregister_eh(void) __attribute__((destructor, used)); -++ -++/* Register the exception handling table as the first constructor. */ -++void -++__nds32_register_eh (void) -++{ -++ static struct object object; -++ if (__register_frame_info) -++ __register_frame_info (__EH_FRAME_BEGIN__, &object); -++} -++ -++/* Unregister the exception handling table as a deconstructor. */ -++void -++__nds32_deregister_eh (void) -++{ -++ static int completed = 0; -++ -++ if (completed) -++ return; -++ -++ if (__deregister_frame_info) -++ __deregister_frame_info (__EH_FRAME_BEGIN__); -++ -++ completed = 1; -++} -++#endif -+ -+ /* Run all the global destructors on exit from the program. */ -+ -+@@ -63,7 +115,7 @@ static func_ptr __DTOR_LIST__[1] __attribute__ ((section (".dtors"))) -+ same particular root executable or shared library file. */ -+ -+ static void __do_global_dtors (void) -+-asm ("__do_global_dtors") __attribute__ ((section (".text"))); -++asm ("__do_global_dtors") __attribute__ ((section (".text"), used)); -+ -+ static void -+ __do_global_dtors (void) -+@@ -116,23 +168,37 @@ void *__dso_handle = 0; -+ last, these words naturally end up at the very ends of the two lists -+ contained in these two sections. */ -+ -+-static func_ptr __CTOR_END__[1] __attribute__ ((section (".ctors"))) -++static func_ptr __CTOR_END__[1] __attribute__ ((section (".ctors"), used)) -+ = { (func_ptr) 0 }; -+ -+-static func_ptr __DTOR_END__[1] __attribute__ ((section (".dtors"))) -++static func_ptr __DTOR_END__[1] __attribute__ ((section (".dtors"), used)) -+ = { (func_ptr) 0 }; -+ -++#ifdef SUPPORT_UNWINDING_DWARF2 -++/* ZERO terminator in .eh_frame section. */ -++asm ("\n\ -++ .section .eh_frame,\"aw\",@progbits\n\ -++ .global __EH_FRAME_END__\n\ -++ .type __EH_FRAME_END__, @object\n\ -++ .align 2\n\ -++__EH_FRAME_END__:\n\ -++ ! End location of eh_frame section with ZERO terminator\n\ -++ .word 0\n\ -++ .previous\n\ -++"); -++#endif -++ -+ /* Run all global constructors for the program. -+ Note that they are run in reverse order. */ -+ -+ static void __do_global_ctors (void) -+-asm ("__do_global_ctors") __attribute__ ((section (".text"))); -++asm ("__do_global_ctors") __attribute__ ((section (".text"), used)); -+ -+ static void -+ __do_global_ctors (void) -+ { -+ func_ptr *p; -+- for (p = __CTOR_END__ - 1; *p != (func_ptr) -1; p--) -++ for (p = __CTOR_END__ - 1; *p; p--) -+ (*p) (); -+ } -+ -+diff --git a/libgcc/config/nds32/isr-library/adj_intr_lvl.inc b/libgcc/config/nds32/isr-library/adj_intr_lvl.inc -+index 5cc1a6fc88a..275e5580ef3 100644 -+--- a/libgcc/config/nds32/isr-library/adj_intr_lvl.inc -++++ b/libgcc/config/nds32/isr-library/adj_intr_lvl.inc -+@@ -26,13 +26,26 @@ -+ .macro ADJ_INTR_LVL -+ #if defined(NDS32_NESTED) /* Nested handler. */ -+ mfsr $r3, $PSW -++ /* By substracting 1 from $PSW, we can lower PSW.INTL -++ and enable GIE simultaneously. */ -+ addi $r3, $r3, #-0x1 -++ #if __NDS32_EXT_ZOL__ || __NDS32_EXT_DSP__ -++ ori $r3, $r3, 0x2000 /* Set PSW.AEN(b'13) */ -++ #endif -+ mtsr $r3, $PSW -+ #elif defined(NDS32_NESTED_READY) /* Nested ready handler. */ -+ /* Save ipc and ipsw and lower INT level. */ -+ mfsr $r3, $PSW -+ addi $r3, $r3, #-0x2 -++ #if __NDS32_EXT_ZOL__ || __NDS32_EXT_DSP__ -++ ori $r3, $r3, 0x2000 /* Set PSW.AEN(b'13) */ -++ #endif -+ mtsr $r3, $PSW -+ #else /* Not nested handler. */ -++ #if __NDS32_EXT_ZOL__ || __NDS32_EXT_DSP__ -++ mfsr $r3, $PSW -++ ori $r3, $r3, 0x2000 /* Set PSW.AEN(b'13) */ -++ mtsr $r3, $PSW -++ #endif -+ #endif -+ .endm -+diff --git a/libgcc/config/nds32/isr-library/excp_isr.S b/libgcc/config/nds32/isr-library/excp_isr.S -+index f24f856e6ee..6e7de5f8fb5 100644 -+--- a/libgcc/config/nds32/isr-library/excp_isr.S -++++ b/libgcc/config/nds32/isr-library/excp_isr.S -+@@ -23,6 +23,7 @@ -+ see the files COPYING3 and COPYING.RUNTIME respectively. If not, see -+ . */ -+ -++#include "save_usr_regs.inc" -+ #include "save_mac_regs.inc" -+ #include "save_fpu_regs.inc" -+ #include "save_fpu_regs_00.inc" -+@@ -32,35 +33,33 @@ -+ #include "save_all.inc" -+ #include "save_partial.inc" -+ #include "adj_intr_lvl.inc" -+-#include "restore_mac_regs.inc" -+ #include "restore_fpu_regs_00.inc" -+ #include "restore_fpu_regs_01.inc" -+ #include "restore_fpu_regs_02.inc" -+ #include "restore_fpu_regs_03.inc" -+ #include "restore_fpu_regs.inc" -++#include "restore_mac_regs.inc" -++#include "restore_usr_regs.inc" -+ #include "restore_all.inc" -+ #include "restore_partial.inc" -++ -+ .section .nds32_isr, "ax" /* Put it in the section of 1st level handler. */ -+ .align 1 -+-/* -+- First Level Handlers -+- 1. First Level Handlers are invokded in vector section via jump instruction -+- with specific names for different configurations. -+- 2. Naming Format: _nds32_e_SR_NT for exception handlers. -+- _nds32_i_SR_NT for interrupt handlers. -+- 2.1 All upper case letters are replaced with specific lower case letters encodings. -+- 2.2 SR: Saved Registers -+- sa: Save All regs (context) -+- ps: Partial Save (all caller-saved regs) -+- 2.3 NT: Nested Type -+- ns: nested -+- nn: not nested -+- nr: nested ready -+-*/ -+- -+-/* -+- This is original 16-byte vector size version. -+-*/ -++ -++/* First Level Handlers -++ 1. First Level Handlers are invokded in vector section via jump instruction -++ with specific names for different configurations. -++ 2. Naming Format: _nds32_e_SR_NT for exception handlers. -++ _nds32_i_SR_NT for interrupt handlers. -++ 2.1 All upper case letters are replaced with specific lower case letters encodings. -++ 2.2 SR -- Saved Registers -++ sa: Save All regs (context) -++ ps: Partial Save (all caller-saved regs) -++ 2.3 NT -- Nested Type -++ ns: nested -++ nn: not nested -++ nr: nested ready */ -++ -+ #ifdef NDS32_SAVE_ALL_REGS -+ #if defined(NDS32_NESTED) -+ .globl _nds32_e_sa_ns -+@@ -91,21 +90,26 @@ _nds32_e_ps_nn: -+ #endif /* endif for Nest Type */ -+ #endif /* not NDS32_SAVE_ALL_REGS */ -+ -+-/* -+- This is 16-byte vector size version. -+- The vector id was restored into $r0 in vector by compiler. -+-*/ -++ -++/* For 4-byte vector size version, the vector id is -++ extracted from $ITYPE and is set into $r0 by library. -++ For 16-byte vector size version, the vector id -++ is set into $r0 in vector section by compiler. */ -++ -++/* Save used registers. */ -+ #ifdef NDS32_SAVE_ALL_REGS -+ SAVE_ALL -+ #else -+ SAVE_PARTIAL -+ #endif -++ -+ /* Prepare to call 2nd level handler. */ -+ la $r2, _nds32_jmptbl_00 -+ lw $r2, [$r2 + $r0 << #2] -+ ADJ_INTR_LVL /* Adjust INTR level. $r3 is clobbered. */ -+ jral $r2 -+- /* Restore used registers. */ -++ -++/* Restore used registers. */ -+ #ifdef NDS32_SAVE_ALL_REGS -+ RESTORE_ALL -+ #else -+@@ -113,6 +117,7 @@ _nds32_e_ps_nn: -+ #endif -+ iret -+ -++ -+ #ifdef NDS32_SAVE_ALL_REGS -+ #if defined(NDS32_NESTED) -+ .size _nds32_e_sa_ns, .-_nds32_e_sa_ns -+diff --git a/libgcc/config/nds32/isr-library/intr_isr.S b/libgcc/config/nds32/isr-library/intr_isr.S -+index 0431ac114fb..23ffa100206 100644 -+--- a/libgcc/config/nds32/isr-library/intr_isr.S -++++ b/libgcc/config/nds32/isr-library/intr_isr.S -+@@ -23,6 +23,7 @@ -+ see the files COPYING3 and COPYING.RUNTIME respectively. If not, see -+ . */ -+ -++#include "save_usr_regs.inc" -+ #include "save_mac_regs.inc" -+ #include "save_fpu_regs.inc" -+ #include "save_fpu_regs_00.inc" -+@@ -32,35 +33,33 @@ -+ #include "save_all.inc" -+ #include "save_partial.inc" -+ #include "adj_intr_lvl.inc" -+-#include "restore_mac_regs.inc" -+ #include "restore_fpu_regs_00.inc" -+ #include "restore_fpu_regs_01.inc" -+ #include "restore_fpu_regs_02.inc" -+ #include "restore_fpu_regs_03.inc" -+ #include "restore_fpu_regs.inc" -++#include "restore_mac_regs.inc" -++#include "restore_usr_regs.inc" -+ #include "restore_all.inc" -+ #include "restore_partial.inc" -++ -+ .section .nds32_isr, "ax" /* Put it in the section of 1st level handler. */ -+ .align 1 -+-/* -+- First Level Handlers -+- 1. First Level Handlers are invokded in vector section via jump instruction -+- with specific names for different configurations. -+- 2. Naming Format: _nds32_e_SR_NT for exception handlers. -+- _nds32_i_SR_NT for interrupt handlers. -+- 2.1 All upper case letters are replaced with specific lower case letters encodings. -+- 2.2 SR: Saved Registers -+- sa: Save All regs (context) -+- ps: Partial Save (all caller-saved regs) -+- 2.3 NT: Nested Type -+- ns: nested -+- nn: not nested -+- nr: nested ready -+-*/ -+- -+-/* -+- This is original 16-byte vector size version. -+-*/ -++ -++/* First Level Handlers -++ 1. First Level Handlers are invokded in vector section via jump instruction -++ with specific names for different configurations. -++ 2. Naming Format: _nds32_e_SR_NT for exception handlers. -++ _nds32_i_SR_NT for interrupt handlers. -++ 2.1 All upper case letters are replaced with specific lower case letters encodings. -++ 2.2 SR -- Saved Registers -++ sa: Save All regs (context) -++ ps: Partial Save (all caller-saved regs) -++ 2.3 NT -- Nested Type -++ ns: nested -++ nn: not nested -++ nr: nested ready */ -++ -+ #ifdef NDS32_SAVE_ALL_REGS -+ #if defined(NDS32_NESTED) -+ .globl _nds32_i_sa_ns -+@@ -91,21 +90,36 @@ _nds32_i_ps_nn: -+ #endif /* endif for Nest Type */ -+ #endif /* not NDS32_SAVE_ALL_REGS */ -+ -+-/* -+- This is 16-byte vector size version. -+- The vector id was restored into $r0 in vector by compiler. -+-*/ -++ -++/* For 4-byte vector size version, the vector id is -++ extracted from $ITYPE and is set into $r0 by library. -++ For 16-byte vector size version, the vector id -++ is set into $r0 in vector section by compiler. */ -++ -++/* Save used registers first. */ -+ #ifdef NDS32_SAVE_ALL_REGS -+ SAVE_ALL -+ #else -+ SAVE_PARTIAL -+ #endif -+- /* Prepare to call 2nd level handler. */ -++ -++/* According to vector size, we need to have different implementation. */ -++#if __NDS32_ISR_VECTOR_SIZE_4__ -++ /* Prepare to call 2nd level handler. */ -++ la $r2, _nds32_jmptbl_00 -++ lw $r2, [$r2 + $r0 << #2] -++ addi $r0, $r0, #-9 /* Make interrput vector id zero-based. */ -++ ADJ_INTR_LVL /* Adjust INTR level. $r3 is clobbered. */ -++ jral $r2 -++#else /* not __NDS32_ISR_VECTOR_SIZE_4__ */ -++ /* Prepare to call 2nd level handler. */ -+ la $r2, _nds32_jmptbl_09 /* For zero-based vcetor id. */ -+ lw $r2, [$r2 + $r0 << #2] -+ ADJ_INTR_LVL /* Adjust INTR level. $r3 is clobbered. */ -+ jral $r2 -+- /* Restore used registers. */ -++#endif /* not __NDS32_ISR_VECTOR_SIZE_4__ */ -++ -++/* Restore used registers. */ -+ #ifdef NDS32_SAVE_ALL_REGS -+ RESTORE_ALL -+ #else -+@@ -113,6 +127,7 @@ _nds32_i_ps_nn: -+ #endif -+ iret -+ -++ -+ #ifdef NDS32_SAVE_ALL_REGS -+ #if defined(NDS32_NESTED) -+ .size _nds32_i_sa_ns, .-_nds32_i_sa_ns -+diff --git a/libgcc/config/nds32/isr-library/reset.S b/libgcc/config/nds32/isr-library/reset.S -+index 78abeb2127c..2ac247e99fb 100644 -+--- a/libgcc/config/nds32/isr-library/reset.S -++++ b/libgcc/config/nds32/isr-library/reset.S -+@@ -26,22 +26,18 @@ -+ .section .nds32_isr, "ax" /* Put it in the section of 1st level handler. */ -+ .align 1 -+ .weak _SDA_BASE_ /* For reset handler only. */ -+- .weak _FP_BASE_ /* For reset handler only. */ -+ .weak _nds32_init_mem /* User defined memory initialization function. */ -+ .globl _start -+ .globl _nds32_reset -+ .type _nds32_reset, @function -+ _nds32_reset: -+ _start: -+-#ifdef NDS32_EXT_EX9 -+- .no_ex9_begin -+-#endif -+ /* Handle NMI and warm boot if any of them exists. */ -+ beqz $sp, 1f /* Reset, NMI or warm boot? */ -+ /* Either NMI or warm boot; save all regs. */ -+ -+ /* Preserve registers for context-switching. */ -+-#ifdef __NDS32_REDUCED_REGS__ -++#if __NDS32_REDUCED_REGS__ || __NDS32_REDUCE_REGS -+ /* For 16-reg mode. */ -+ smw.adm $r0, [$sp], $r10, #0x0 -+ smw.adm $r15, [$sp], $r15, #0xf -+@@ -49,10 +45,9 @@ _start: -+ /* For 32-reg mode. */ -+ smw.adm $r0, [$sp], $r27, #0xf -+ #endif -+-#ifdef NDS32_EXT_IFC -++#if __NDS32_EXT_IFC__ -+ mfusr $r1, $IFC_LP -+- smw.adm $r1, [$sp], $r2, #0x0 /* Save extra $r2 to keep -+- stack 8-byte alignment. */ -++ smw.adm $r1, [$sp], $r2, #0x0 /* Save extra $r2 to keep stack 8-byte alignment. */ -+ #endif -+ -+ la $gp, _SDA_BASE_ /* Init GP for small data access. */ -+@@ -71,12 +66,11 @@ _start: -+ bnez $r0, 1f /* If fail to resume, do cold boot. */ -+ -+ /* Restore registers for context-switching. */ -+-#ifdef NDS32_EXT_IFC -+- lmw.bim $r1, [$sp], $r2, #0x0 /* Restore extra $r2 to keep -+- stack 8-byte alignment. */ -++#if __NDS32_EXT_IFC__ -++ lmw.bim $r1, [$sp], $r2, #0x0 /* Restore extra $r2 to keep stack 8-byte alignment. */ -+ mtusr $r1, $IFC_LP -+ #endif -+-#ifdef __NDS32_REDUCED_REGS__ -++#if __NDS32_REDUCED_REGS__ || __NDS32_REDUCE_REGS -+ /* For 16-reg mode. */ -+ lmw.bim $r15, [$sp], $r15, #0xf -+ lmw.bim $r0, [$sp], $r10, #0x0 -+@@ -88,6 +82,17 @@ _start: -+ -+ -+ 1: /* Cold boot. */ -++#if __NDS32_ISR_VECTOR_SIZE_4__ -++ /* With vector ID feature for v3 architecture, default vector size is 4-byte. */ -++ /* Set IVB.ESZ = 0 (vector table entry size = 4 bytes) */ -++ mfsr $r0, $IVB -++ li $r1, #0xc000 -++ or $r0, $r0, $r1 -++ xor $r0, $r0, $r1 -++ mtsr $r0, $IVB -++ dsb -++#else -++ /* There is no vector ID feature, so the vector size must be 16-byte. */ -+ /* Set IVB.ESZ = 1 (vector table entry size = 16 bytes) */ -+ mfsr $r0, $IVB -+ li $r1, #0xffff3fff -+@@ -95,36 +100,54 @@ _start: -+ ori $r0, $r0, #0x4000 -+ mtsr $r0, $IVB -+ dsb -++#endif -+ -+ la $gp, _SDA_BASE_ /* Init $gp. */ -+- la $fp, _FP_BASE_ /* Init $fp. */ -+ la $sp, _stack /* Init $sp. */ -+-#ifdef NDS32_EXT_EX9 -+-/* -+- * Initialize the table base of EX9 instruction -+- * ex9 generation needs to disable before the ITB is set -+- */ -+- mfsr $r0, $MSC_CFG /* Check if HW support of EX9. */ -++ -++#if __NDS32_EXT_EX9__ -++.L_init_itb: -++ /* Initialization for Instruction Table Base (ITB). -++ The symbol _ITB_BASE_ is determined by Linker. -++ Set $ITB only if MSC_CFG.EIT (cr4.b'24) is set. */ -++ mfsr $r0, $MSC_CFG -+ srli $r0, $r0, 24 -+ andi $r0, $r0, 0x1 -+- beqz $r0, 4f /* Zero means HW does not support EX9. */ -+- la $r0, _ITB_BASE_ /* Init $ITB. */ -++ beqz $r0, 4f /* Fall through ? */ -++ la $r0, _ITB_BASE_ -+ mtusr $r0, $ITB -+- .no_ex9_end -+ 4: -+ #endif -+- la $r15, _nds32_init_mem /* Call DRAM init. _nds32_init_mem -+- may written by C language. */ -++ -++#if __NDS32_EXT_FPU_SP__ || __NDS32_EXT_FPU_DP__ -++.L_init_fpu: -++ /* Initialize FPU -++ Set FUCOP_CTL.CP0EN (fucpr.b'0). */ -++ mfsr $r0, $FUCOP_CTL -++ ori $r0, $r0, 0x1 -++ mtsr $r0, $FUCOP_CTL -++ dsb -++ /* According to [bugzilla #9425], set flush-to-zero mode. -++ That is, set $FPCSR.DNZ(b'12) = 1. */ -++ FMFCSR $r0 -++ ori $r0, $r0, 0x1000 -++ FMTCSR $r0 -++ dsb -++#endif -++ -++ /* Call DRAM init. _nds32_init_mem may written by C language. */ -++ la $r15, _nds32_init_mem -+ beqz $r15, 6f -+ jral $r15 -+ 6: -+ l.w $r15, _nds32_jmptbl_00 /* Load reset handler. */ -+ jral $r15 -+-/* Reset handler() should never return in a RTOS or non-OS system. -+- In case it does return, an exception will be generated. -+- This exception will be caught either by default break handler or by EDM. -+- Default break handle may just do an infinite loop. -+- EDM will notify GDB and GDB will regain control when the ID is 0x7fff. */ -++ -++ /* Reset handler() should never return in a RTOS or non-OS system. -++ In case it does return, an exception will be generated. -++ This exception will be caught either by default break handler or by EDM. -++ Default break handle may just do an infinite loop. -++ EDM will notify GDB and GDB will regain control when the ID is 0x7fff. */ -+ 5: -+ break #0x7fff -+ .size _nds32_reset, .-_nds32_reset -+diff --git a/libgcc/config/nds32/isr-library/restore_all.inc b/libgcc/config/nds32/isr-library/restore_all.inc -+index 74556466fa9..23cdf8c6f16 100644 -+--- a/libgcc/config/nds32/isr-library/restore_all.inc -++++ b/libgcc/config/nds32/isr-library/restore_all.inc -+@@ -31,15 +31,11 @@ -+ mtsr $r2, $IPSW -+ RESTORE_FPU_REGS -+ RESTORE_MAC_REGS -+-#ifdef NDS32_EXT_IFC -+- lmw.bim $r1, [$sp], $r2, #0x0 /* Restore extra $r2 to keep -+- stack 8-byte alignment. */ -+- mtusr $r1, $IFC_LP -+-#endif -+-#ifdef __NDS32_REDUCED_REGS__ -++ RESTORE_USR_REGS -++#if __NDS32_REDUCED_REGS__ || __NDS32_REDUCE_REGS -+ lmw.bim $r0, [$sp], $r10, #0x0 /* Restore all regs. */ -+ lmw.bim $r15, [$sp], $r15, #0xf -+-#else /* not __NDS32_REDUCED_REGS__ */ -++#else -+ lmw.bim $r0, [$sp], $r27, #0xf /* Restore all regs. */ -+ #endif -+ .endm -+diff --git a/libgcc/config/nds32/isr-library/restore_mac_regs.inc b/libgcc/config/nds32/isr-library/restore_mac_regs.inc -+index 1e6aac669af..a4340833a76 100644 -+--- a/libgcc/config/nds32/isr-library/restore_mac_regs.inc -++++ b/libgcc/config/nds32/isr-library/restore_mac_regs.inc -+@@ -24,7 +24,7 @@ -+ . */ -+ -+ .macro RESTORE_MAC_REGS -+-#ifdef NDS32_DX_REGS -++#if __NDS32_DX_REGS__ -+ lmw.bim $r1, [$sp], $r4, #0x0 -+ mtusr $r1, $d0.lo -+ mtusr $r2, $d0.hi -+diff --git a/libgcc/config/nds32/isr-library/restore_partial.inc b/libgcc/config/nds32/isr-library/restore_partial.inc -+index d406a99820d..c43ad1600e1 100644 -+--- a/libgcc/config/nds32/isr-library/restore_partial.inc -++++ b/libgcc/config/nds32/isr-library/restore_partial.inc -+@@ -31,15 +31,11 @@ -+ mtsr $r1, $IPC /* Set IPC. */ -+ mtsr $r2, $IPSW /* Set IPSW. */ -+ #endif -+- RESTORE_FPU_REGS -+- RESTORE_MAC_REGS -+-#ifdef NDS32_EXT_IFC -+- lmw.bim $r1, [$sp], $r2, #0x0 /* Restore extra $r2 to keep -+- stack 8-byte alignment. */ -+- mtusr $r1, $IFC_LP -+-#endif -++ RESTORE_FPU_REGS -++ RESTORE_MAC_REGS -++ RESTORE_USR_REGS -+ lmw.bim $r0, [$sp], $r5, #0x0 /* Restore all regs. */ -+-#ifdef __NDS32_REDUCED_REGS__ -++#if __NDS32_REDUCED_REGS__ || __NDS32_REDUCE_REGS -+ lmw.bim $r15, [$sp], $r15, #0x2 -+ #else -+ lmw.bim $r15, [$sp], $r27, #0x2 /* Restore all regs. */ -+diff --git a/libgcc/config/nds32/isr-library/restore_usr_regs.inc b/libgcc/config/nds32/isr-library/restore_usr_regs.inc -+new file mode 100644 -+index 00000000000..9602c741cbd -+--- /dev/null -++++ b/libgcc/config/nds32/isr-library/restore_usr_regs.inc -+@@ -0,0 +1,42 @@ -++/* c-isr library stuff of Andes NDS32 cpu for GNU compiler -++ Copyright (C) 2012-2018 Free Software Foundation, Inc. -++ Contributed by Andes Technology Corporation. -++ -++ This file is part of GCC. -++ -++ GCC is free software; you can redistribute it and/or modify it -++ under the terms of the GNU General Public License as published -++ by the Free Software Foundation; either version 3, or (at your -++ option) any later version. -++ -++ GCC is distributed in the hope that it will be useful, but WITHOUT -++ ANY WARRANTY; without even the implied warranty of MERCHANTABILITY -++ or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public -++ License for more details. -++ -++ Under Section 7 of GPL version 3, you are granted additional -++ permissions described in the GCC Runtime Library Exception, version -++ 3.1, as published by the Free Software Foundation. -++ -++ You should have received a copy of the GNU General Public License and -++ a copy of the GCC Runtime Library Exception along with this program; -++ see the files COPYING3 and COPYING.RUNTIME respectively. If not, see -++ . */ -++ -++.macro RESTORE_USR_REGS -++#if __NDS32_EXT_IFC__ && (__NDS32_EXT_ZOL__ || __NDS32_EXT_DSP__) -++ lmw.bim $r1, [$sp], $r4, #0x0 -++ mtusr $r1, $IFC_LP -++ mtusr $r2, $LB -++ mtusr $r3, $LE -++ mtusr $r4, $LC -++#elif __NDS32_EXT_IFC__ -++ lmw.bim $r1, [$sp], $r2, #0x0 -++ mtusr $r1, $IFC_LP -++#elif __NDS32_EXT_ZOL__ || __NDS32_EXT_DSP__ -++ lmw.bim $r1, [$sp], $r4, #0x0 -++ mtusr $r1, $LB -++ mtusr $r2, $LE -++ mtusr $r3, $LC -++#endif -++.endm -+diff --git a/libgcc/config/nds32/isr-library/save_all.inc b/libgcc/config/nds32/isr-library/save_all.inc -+index fa08b399bb4..8886edb1f64 100644 -+--- a/libgcc/config/nds32/isr-library/save_all.inc -++++ b/libgcc/config/nds32/isr-library/save_all.inc -+@@ -23,45 +23,42 @@ -+ see the files COPYING3 and COPYING.RUNTIME respectively. If not, see -+ . */ -+ -+-.macro SAVE_ALL_4B -+-#ifdef __NDS32_REDUCED_REGS__ -++#if __NDS32_ISR_VECTOR_SIZE_4__ -++ -++/* If vector size is 4-byte, we have to save registers -++ in the macro implementation. */ -++.macro SAVE_ALL -++#if __NDS32_REDUCED_REGS__ || __NDS32_REDUCE_REGS -+ smw.adm $r15, [$sp], $r15, #0xf -+ smw.adm $r0, [$sp], $r10, #0x0 -+-#else /* not __NDS32_REDUCED_REGS__ */ -++#else -+ smw.adm $r0, [$sp], $r27, #0xf -+-#endif /* not __NDS32_REDUCED_REGS__ */ -+-#ifdef NDS32_EXT_IFC -+- mfusr $r1, $IFC_LP -+- smw.adm $r1, [$sp], $r2, #0x0 /* Save extra $r2 to keep -+- stack 8-byte alignment. */ -+ #endif -+- SAVE_MAC_REGS -+- SAVE_FPU_REGS -++ SAVE_USR_REGS -++ SAVE_MAC_REGS -++ SAVE_FPU_REGS -+ mfsr $r1, $IPC /* Get IPC. */ -+ mfsr $r2, $IPSW /* Get IPSW. */ -+ smw.adm $r1, [$sp], $r2, #0x0 /* Push IPC, IPSW. */ -+ move $r1, $sp /* $r1 is ptr to NDS32_CONTEXT. */ -+ mfsr $r0, $ITYPE /* Get VID to $r0. */ -+ srli $r0, $r0, #5 -+-#ifdef __NDS32_ISA_V2__ -+ andi $r0, $r0, #127 -+-#else -+- fexti33 $r0, #6 -+-#endif -+ .endm -+ -++#else /* not __NDS32_ISR_VECTOR_SIZE_4__ */ -++ -++/* If vector size is 16-byte, some works can be done in -++ the vector section generated by compiler, so that we -++ can implement less in the macro. */ -+ .macro SAVE_ALL -+-/* SAVE_REG_TBL code has been moved to -+- vector table generated by compiler. */ -+-#ifdef NDS32_EXT_IFC -+- mfusr $r1, $IFC_LP -+- smw.adm $r1, [$sp], $r2, #0x0 /* Save extra $r2 to keep -+- stack 8-byte alignment. */ -+-#endif -+- SAVE_MAC_REGS -+- SAVE_FPU_REGS -++ SAVE_USR_REGS -++ SAVE_MAC_REGS -++ SAVE_FPU_REGS -+ mfsr $r1, $IPC /* Get IPC. */ -+ mfsr $r2, $IPSW /* Get IPSW. */ -+ smw.adm $r1, [$sp], $r2, #0x0 /* Push IPC, IPSW. */ -+ move $r1, $sp /* $r1 is ptr to NDS32_CONTEXT. */ -+ .endm -++ -++#endif /* not __NDS32_ISR_VECTOR_SIZE_4__ */ -+diff --git a/libgcc/config/nds32/isr-library/save_mac_regs.inc b/libgcc/config/nds32/isr-library/save_mac_regs.inc -+index ff120e87a8f..a6a92307fef 100644 -+--- a/libgcc/config/nds32/isr-library/save_mac_regs.inc -++++ b/libgcc/config/nds32/isr-library/save_mac_regs.inc -+@@ -24,7 +24,7 @@ -+ . */ -+ -+ .macro SAVE_MAC_REGS -+-#ifdef NDS32_DX_REGS -++#if __NDS32_DX_REGS__ -+ mfusr $r1, $d0.lo -+ mfusr $r2, $d0.hi -+ mfusr $r3, $d1.lo -+diff --git a/libgcc/config/nds32/isr-library/save_partial.inc b/libgcc/config/nds32/isr-library/save_partial.inc -+index 2445e48067e..c81ebaa693c 100644 -+--- a/libgcc/config/nds32/isr-library/save_partial.inc -++++ b/libgcc/config/nds32/isr-library/save_partial.inc -+@@ -23,20 +23,20 @@ -+ see the files COPYING3 and COPYING.RUNTIME respectively. If not, see -+ . */ -+ -+-.macro SAVE_PARTIAL_4B -+-#ifdef __NDS32_REDUCED_REGS__ -++#if __NDS32_ISR_VECTOR_SIZE_4__ -++ -++/* If vector size is 4-byte, we have to save registers -++ in the macro implementation. */ -++.macro SAVE_PARTIAL -++#if __NDS32_REDUCED_REGS__ || __NDS32_REDUCE_REGS -+ smw.adm $r15, [$sp], $r15, #0x2 -+-#else /* not __NDS32_REDUCED_REGS__ */ -++#else -+ smw.adm $r15, [$sp], $r27, #0x2 -+-#endif /* not __NDS32_REDUCED_REGS__ */ -+- smw.adm $r0, [$sp], $r5, #0x0 -+-#ifdef NDS32_EXT_IFC -+- mfusr $r1, $IFC_LP -+- smw.adm $r1, [$sp], $r2, #0x0 /* Save extra $r2 to keep -+- stack 8-byte alignment. */ -+ #endif -+- SAVE_MAC_REGS -+- SAVE_FPU_REGS -++ smw.adm $r0, [$sp], $r5, #0x0 -++ SAVE_USR_REGS -++ SAVE_MAC_REGS -++ SAVE_FPU_REGS -+ #if defined(NDS32_NESTED) || defined(NDS32_NESTED_READY) -+ mfsr $r1, $IPC /* Get IPC. */ -+ mfsr $r2, $IPSW /* Get IPSW. */ -+@@ -44,26 +44,24 @@ -+ #endif -+ mfsr $r0, $ITYPE /* Get VID to $r0. */ -+ srli $r0, $r0, #5 -+-#ifdef __NDS32_ISA_V2__ -+ andi $r0, $r0, #127 -+-#else -+- fexti33 $r0, #6 -+-#endif -+ .endm -+ -++#else /* not __NDS32_ISR_VECTOR_SIZE_4__ */ -++ -++/* If vector size is 16-byte, some works can be done in -++ the vector section generated by compiler, so that we -++ can implement less in the macro. */ -++ -+ .macro SAVE_PARTIAL -+-/* SAVE_CALLER_REGS code has been moved to -+- vector table generated by compiler. */ -+-#ifdef NDS32_EXT_IFC -+- mfusr $r1, $IFC_LP -+- smw.adm $r1, [$sp], $r2, #0x0 /* Save extra $r2 to keep -+- stack 8-byte alignment. */ -+-#endif -+- SAVE_MAC_REGS -+- SAVE_FPU_REGS -++ SAVE_USR_REGS -++ SAVE_MAC_REGS -++ SAVE_FPU_REGS -+ #if defined(NDS32_NESTED) || defined(NDS32_NESTED_READY) -+ mfsr $r1, $IPC /* Get IPC. */ -+ mfsr $r2, $IPSW /* Get IPSW. */ -+ smw.adm $r1, [$sp], $r2, #0x0 /* Push IPC, IPSW. */ -+ #endif -+ .endm -++ -++#endif /* not __NDS32_ISR_VECTOR_SIZE_4__ */ -+diff --git a/libgcc/config/nds32/isr-library/save_usr_regs.inc b/libgcc/config/nds32/isr-library/save_usr_regs.inc -+new file mode 100644 -+index 00000000000..5a3f6183b68 -+--- /dev/null -++++ b/libgcc/config/nds32/isr-library/save_usr_regs.inc -+@@ -0,0 +1,44 @@ -++/* c-isr library stuff of Andes NDS32 cpu for GNU compiler -++ Copyright (C) 2012-2018 Free Software Foundation, Inc. -++ Contributed by Andes Technology Corporation. -++ -++ This file is part of GCC. -++ -++ GCC is free software; you can redistribute it and/or modify it -++ under the terms of the GNU General Public License as published -++ by the Free Software Foundation; either version 3, or (at your -++ option) any later version. -++ -++ GCC is distributed in the hope that it will be useful, but WITHOUT -++ ANY WARRANTY; without even the implied warranty of MERCHANTABILITY -++ or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public -++ License for more details. -++ -++ Under Section 7 of GPL version 3, you are granted additional -++ permissions described in the GCC Runtime Library Exception, version -++ 3.1, as published by the Free Software Foundation. -++ -++ You should have received a copy of the GNU General Public License and -++ a copy of the GCC Runtime Library Exception along with this program; -++ see the files COPYING3 and COPYING.RUNTIME respectively. If not, see -++ . */ -++ -++.macro SAVE_USR_REGS -++/* Store User Special Registers according to supported ISA extension -++ !!! WATCH OUT !!! Take care of 8-byte alignment issue. */ -++#if __NDS32_EXT_IFC__ && (__NDS32_EXT_ZOL__ || __NDS32_EXT_DSP__) -++ mfusr $r1, $IFC_LP -++ mfusr $r2, $LB -++ mfusr $r3, $LE -++ mfusr $r4, $LC -++ smw.adm $r1, [$sp], $r4, #0x0 /* Save even. Ok! */ -++#elif __NDS32_EXT_IFC__ -++ mfusr $r1, $IFC_LP -++ smw.adm $r1, [$sp], $r2, #0x0 /* Save extra $r2 to keep stack 8-byte aligned. */ -++#elif (__NDS32_EXT_ZOL__ || __NDS32_EXT_DSP__) -++ mfusr $r1, $LB -++ mfusr $r2, $LE -++ mfusr $r3, $LC -++ smw.adm $r1, [$sp], $r4, #0x0 /* Save extra $r4 to keep stack 8-byte aligned. */ -++#endif -++.endm -+diff --git a/libgcc/config/nds32/isr-library/vec_vid00.S b/libgcc/config/nds32/isr-library/vec_vid00.S -+index b2a645c53f0..643009eb800 100644 -+--- a/libgcc/config/nds32/isr-library/vec_vid00.S -++++ b/libgcc/config/nds32/isr-library/vec_vid00.S -+@@ -24,8 +24,15 @@ -+ . */ -+ -+ .section .nds32_vector.00, "ax" -++#if __NDS32_ISR_VECTOR_SIZE_4__ -++ /* The vector size is default 4-byte for v3 architecture. */ -++ .vec_size 4 -++ .align 2 -++#else -++ /* The vector size is default 16-byte for other architectures. */ -+ .vec_size 16 -+ .align 4 -++#endif -+ .weak _nds32_vector_00 -+ .type _nds32_vector_00, @function -+ _nds32_vector_00: -+diff --git a/libgcc/config/nds32/isr-library/vec_vid01.S b/libgcc/config/nds32/isr-library/vec_vid01.S -+index 9e796c70524..fd9bc8b6850 100644 -+--- a/libgcc/config/nds32/isr-library/vec_vid01.S -++++ b/libgcc/config/nds32/isr-library/vec_vid01.S -+@@ -24,8 +24,15 @@ -+ . */ -+ -+ .section .nds32_vector.01, "ax" -++#if __NDS32_ISR_VECTOR_SIZE_4__ -++ /* The vector size is default 4-byte for v3 architecture. */ -++ .vec_size 4 -++ .align 2 -++#else -++ /* The vector size is default 16-byte for other architectures. */ -+ .vec_size 16 -+ .align 4 -++#endif -+ .weak _nds32_vector_01 -+ .type _nds32_vector_01, @function -+ _nds32_vector_01: -+diff --git a/libgcc/config/nds32/isr-library/vec_vid02.S b/libgcc/config/nds32/isr-library/vec_vid02.S -+index a6b34b7d63a..c5a88435cab 100644 -+--- a/libgcc/config/nds32/isr-library/vec_vid02.S -++++ b/libgcc/config/nds32/isr-library/vec_vid02.S -+@@ -24,8 +24,15 @@ -+ . */ -+ -+ .section .nds32_vector.02, "ax" -++#if __NDS32_ISR_VECTOR_SIZE_4__ -++ /* The vector size is default 4-byte for v3 architecture. */ -++ .vec_size 4 -++ .align 2 -++#else -++ /* The vector size is default 16-byte for other architectures. */ -+ .vec_size 16 -+ .align 4 -++#endif -+ .weak _nds32_vector_02 -+ .type _nds32_vector_02, @function -+ _nds32_vector_02: -+diff --git a/libgcc/config/nds32/isr-library/vec_vid03.S b/libgcc/config/nds32/isr-library/vec_vid03.S -+index 680f6d9a60f..7f11fb9166b 100644 -+--- a/libgcc/config/nds32/isr-library/vec_vid03.S -++++ b/libgcc/config/nds32/isr-library/vec_vid03.S -+@@ -24,8 +24,15 @@ -+ . */ -+ -+ .section .nds32_vector.03, "ax" -++#if __NDS32_ISR_VECTOR_SIZE_4__ -++ /* The vector size is default 4-byte for v3 architecture. */ -++ .vec_size 4 -++ .align 2 -++#else -++ /* The vector size is default 16-byte for other architectures. */ -+ .vec_size 16 -+ .align 4 -++#endif -+ .weak _nds32_vector_03 -+ .type _nds32_vector_03, @function -+ _nds32_vector_03: -+diff --git a/libgcc/config/nds32/isr-library/vec_vid04.S b/libgcc/config/nds32/isr-library/vec_vid04.S -+index f0b616ceb8a..de2e249b78f 100644 -+--- a/libgcc/config/nds32/isr-library/vec_vid04.S -++++ b/libgcc/config/nds32/isr-library/vec_vid04.S -+@@ -24,8 +24,15 @@ -+ . */ -+ -+ .section .nds32_vector.04, "ax" -++#if __NDS32_ISR_VECTOR_SIZE_4__ -++ /* The vector size is default 4-byte for v3 architecture. */ -++ .vec_size 4 -++ .align 2 -++#else -++ /* The vector size is default 16-byte for other architectures. */ -+ .vec_size 16 -+ .align 4 -++#endif -+ .weak _nds32_vector_04 -+ .type _nds32_vector_04, @function -+ _nds32_vector_04: -+diff --git a/libgcc/config/nds32/isr-library/vec_vid05.S b/libgcc/config/nds32/isr-library/vec_vid05.S -+index 47cbcea0a51..62e1cdac4a3 100644 -+--- a/libgcc/config/nds32/isr-library/vec_vid05.S -++++ b/libgcc/config/nds32/isr-library/vec_vid05.S -+@@ -24,8 +24,15 @@ -+ . */ -+ -+ .section .nds32_vector.05, "ax" -++#if __NDS32_ISR_VECTOR_SIZE_4__ -++ /* The vector size is default 4-byte for v3 architecture. */ -++ .vec_size 4 -++ .align 2 -++#else -++ /* The vector size is default 16-byte for other architectures. */ -+ .vec_size 16 -+ .align 4 -++#endif -+ .weak _nds32_vector_05 -+ .type _nds32_vector_05, @function -+ _nds32_vector_05: -+diff --git a/libgcc/config/nds32/isr-library/vec_vid06.S b/libgcc/config/nds32/isr-library/vec_vid06.S -+index 851836cf9ea..e41a60c4db4 100644 -+--- a/libgcc/config/nds32/isr-library/vec_vid06.S -++++ b/libgcc/config/nds32/isr-library/vec_vid06.S -+@@ -24,8 +24,15 @@ -+ . */ -+ -+ .section .nds32_vector.06, "ax" -++#if __NDS32_ISR_VECTOR_SIZE_4__ -++ /* The vector size is default 4-byte for v3 architecture. */ -++ .vec_size 4 -++ .align 2 -++#else -++ /* The vector size is default 16-byte for other architectures. */ -+ .vec_size 16 -+ .align 4 -++#endif -+ .weak _nds32_vector_06 -+ .type _nds32_vector_06, @function -+ _nds32_vector_06: -+diff --git a/libgcc/config/nds32/isr-library/vec_vid07.S b/libgcc/config/nds32/isr-library/vec_vid07.S -+index 664ee0ca7b0..b5447a85045 100644 -+--- a/libgcc/config/nds32/isr-library/vec_vid07.S -++++ b/libgcc/config/nds32/isr-library/vec_vid07.S -+@@ -24,8 +24,15 @@ -+ . */ -+ -+ .section .nds32_vector.07, "ax" -++#if __NDS32_ISR_VECTOR_SIZE_4__ -++ /* The vector size is default 4-byte for v3 architecture. */ -++ .vec_size 4 -++ .align 2 -++#else -++ /* The vector size is default 16-byte for other architectures. */ -+ .vec_size 16 -+ .align 4 -++#endif -+ .weak _nds32_vector_07 -+ .type _nds32_vector_07, @function -+ _nds32_vector_07: -+diff --git a/libgcc/config/nds32/isr-library/vec_vid08.S b/libgcc/config/nds32/isr-library/vec_vid08.S -+index 1b5534c3475..2c07dd35416 100644 -+--- a/libgcc/config/nds32/isr-library/vec_vid08.S -++++ b/libgcc/config/nds32/isr-library/vec_vid08.S -+@@ -24,8 +24,15 @@ -+ . */ -+ -+ .section .nds32_vector.08, "ax" -++#if __NDS32_ISR_VECTOR_SIZE_4__ -++ /* The vector size is default 4-byte for v3 architecture. */ -++ .vec_size 4 -++ .align 2 -++#else -++ /* The vector size is default 16-byte for other architectures. */ -+ .vec_size 16 -+ .align 4 -++#endif -+ .weak _nds32_vector_08 -+ .type _nds32_vector_08, @function -+ _nds32_vector_08: -+diff --git a/libgcc/config/nds32/isr-library/vec_vid09.S b/libgcc/config/nds32/isr-library/vec_vid09.S -+index 81a56753202..e858cea5f11 100644 -+--- a/libgcc/config/nds32/isr-library/vec_vid09.S -++++ b/libgcc/config/nds32/isr-library/vec_vid09.S -+@@ -24,8 +24,15 @@ -+ . */ -+ -+ .section .nds32_vector.09, "ax" -++#if __NDS32_ISR_VECTOR_SIZE_4__ -++ /* The vector size is default 4-byte for v3 architecture. */ -++ .vec_size 4 -++ .align 2 -++#else -++ /* The vector size is default 16-byte for other architectures. */ -+ .vec_size 16 -+ .align 4 -++#endif -+ .weak _nds32_vector_09 -+ .type _nds32_vector_09, @function -+ _nds32_vector_09: -+diff --git a/libgcc/config/nds32/isr-library/vec_vid10.S b/libgcc/config/nds32/isr-library/vec_vid10.S -+index 102f7cf2ae6..e8bbc0b6a2c 100644 -+--- a/libgcc/config/nds32/isr-library/vec_vid10.S -++++ b/libgcc/config/nds32/isr-library/vec_vid10.S -+@@ -24,8 +24,15 @@ -+ . */ -+ -+ .section .nds32_vector.10, "ax" -++#if __NDS32_ISR_VECTOR_SIZE_4__ -++ /* The vector size is default 4-byte for v3 architecture. */ -++ .vec_size 4 -++ .align 2 -++#else -++ /* The vector size is default 16-byte for other architectures. */ -+ .vec_size 16 -+ .align 4 -++#endif -+ .weak _nds32_vector_10 -+ .type _nds32_vector_10, @function -+ _nds32_vector_10: -+diff --git a/libgcc/config/nds32/isr-library/vec_vid11.S b/libgcc/config/nds32/isr-library/vec_vid11.S -+index ade2ee5190c..92aebb41022 100644 -+--- a/libgcc/config/nds32/isr-library/vec_vid11.S -++++ b/libgcc/config/nds32/isr-library/vec_vid11.S -+@@ -24,8 +24,15 @@ -+ . */ -+ -+ .section .nds32_vector.11, "ax" -++#if __NDS32_ISR_VECTOR_SIZE_4__ -++ /* The vector size is default 4-byte for v3 architecture. */ -++ .vec_size 4 -++ .align 2 -++#else -++ /* The vector size is default 16-byte for other architectures. */ -+ .vec_size 16 -+ .align 4 -++#endif -+ .weak _nds32_vector_11 -+ .type _nds32_vector_11, @function -+ _nds32_vector_11: -+diff --git a/libgcc/config/nds32/isr-library/vec_vid12.S b/libgcc/config/nds32/isr-library/vec_vid12.S -+index a5958111946..6fd050afd40 100644 -+--- a/libgcc/config/nds32/isr-library/vec_vid12.S -++++ b/libgcc/config/nds32/isr-library/vec_vid12.S -+@@ -24,8 +24,15 @@ -+ . */ -+ -+ .section .nds32_vector.12, "ax" -++#if __NDS32_ISR_VECTOR_SIZE_4__ -++ /* The vector size is default 4-byte for v3 architecture. */ -++ .vec_size 4 -++ .align 2 -++#else -++ /* The vector size is default 16-byte for other architectures. */ -+ .vec_size 16 -+ .align 4 -++#endif -+ .weak _nds32_vector_12 -+ .type _nds32_vector_12, @function -+ _nds32_vector_12: -+diff --git a/libgcc/config/nds32/isr-library/vec_vid13.S b/libgcc/config/nds32/isr-library/vec_vid13.S -+index 55863be5e72..0a45c456b24 100644 -+--- a/libgcc/config/nds32/isr-library/vec_vid13.S -++++ b/libgcc/config/nds32/isr-library/vec_vid13.S -+@@ -24,8 +24,15 @@ -+ . */ -+ -+ .section .nds32_vector.13, "ax" -++#if __NDS32_ISR_VECTOR_SIZE_4__ -++ /* The vector size is default 4-byte for v3 architecture. */ -++ .vec_size 4 -++ .align 2 -++#else -++ /* The vector size is default 16-byte for other architectures. */ -+ .vec_size 16 -+ .align 4 -++#endif -+ .weak _nds32_vector_13 -+ .type _nds32_vector_13, @function -+ _nds32_vector_13: -+diff --git a/libgcc/config/nds32/isr-library/vec_vid14.S b/libgcc/config/nds32/isr-library/vec_vid14.S -+index abe7f42d1df..837b8487606 100644 -+--- a/libgcc/config/nds32/isr-library/vec_vid14.S -++++ b/libgcc/config/nds32/isr-library/vec_vid14.S -+@@ -24,8 +24,15 @@ -+ . */ -+ -+ .section .nds32_vector.14, "ax" -++#if __NDS32_ISR_VECTOR_SIZE_4__ -++ /* The vector size is default 4-byte for v3 architecture. */ -++ .vec_size 4 -++ .align 2 -++#else -++ /* The vector size is default 16-byte for other architectures. */ -+ .vec_size 16 -+ .align 4 -++#endif -+ .weak _nds32_vector_14 -+ .type _nds32_vector_14, @function -+ _nds32_vector_14: -+diff --git a/libgcc/config/nds32/isr-library/vec_vid15.S b/libgcc/config/nds32/isr-library/vec_vid15.S -+index 890819f3ec2..c639aa444ba 100644 -+--- a/libgcc/config/nds32/isr-library/vec_vid15.S -++++ b/libgcc/config/nds32/isr-library/vec_vid15.S -+@@ -24,8 +24,15 @@ -+ . */ -+ -+ .section .nds32_vector.15, "ax" -++#if __NDS32_ISR_VECTOR_SIZE_4__ -++ /* The vector size is default 4-byte for v3 architecture. */ -++ .vec_size 4 -++ .align 2 -++#else -++ /* The vector size is default 16-byte for other architectures. */ -+ .vec_size 16 -+ .align 4 -++#endif -+ .weak _nds32_vector_15 -+ .type _nds32_vector_15, @function -+ _nds32_vector_15: -+diff --git a/libgcc/config/nds32/isr-library/vec_vid16.S b/libgcc/config/nds32/isr-library/vec_vid16.S -+index 20db62501ba..a762130631c 100644 -+--- a/libgcc/config/nds32/isr-library/vec_vid16.S -++++ b/libgcc/config/nds32/isr-library/vec_vid16.S -+@@ -24,8 +24,15 @@ -+ . */ -+ -+ .section .nds32_vector.16, "ax" -++#if __NDS32_ISR_VECTOR_SIZE_4__ -++ /* The vector size is default 4-byte for v3 architecture. */ -++ .vec_size 4 -++ .align 2 -++#else -++ /* The vector size is default 16-byte for other architectures. */ -+ .vec_size 16 -+ .align 4 -++#endif -+ .weak _nds32_vector_16 -+ .type _nds32_vector_16, @function -+ _nds32_vector_16: -+diff --git a/libgcc/config/nds32/isr-library/vec_vid17.S b/libgcc/config/nds32/isr-library/vec_vid17.S -+index c1ca9f62353..b17681fcb96 100644 -+--- a/libgcc/config/nds32/isr-library/vec_vid17.S -++++ b/libgcc/config/nds32/isr-library/vec_vid17.S -+@@ -24,8 +24,15 @@ -+ . */ -+ -+ .section .nds32_vector.17, "ax" -++#if __NDS32_ISR_VECTOR_SIZE_4__ -++ /* The vector size is default 4-byte for v3 architecture. */ -++ .vec_size 4 -++ .align 2 -++#else -++ /* The vector size is default 16-byte for other architectures. */ -+ .vec_size 16 -+ .align 4 -++#endif -+ .weak _nds32_vector_17 -+ .type _nds32_vector_17, @function -+ _nds32_vector_17: -+diff --git a/libgcc/config/nds32/isr-library/vec_vid18.S b/libgcc/config/nds32/isr-library/vec_vid18.S -+index ef4cbeec2e6..4166fa1957f 100644 -+--- a/libgcc/config/nds32/isr-library/vec_vid18.S -++++ b/libgcc/config/nds32/isr-library/vec_vid18.S -+@@ -24,8 +24,15 @@ -+ . */ -+ -+ .section .nds32_vector.18, "ax" -++#if __NDS32_ISR_VECTOR_SIZE_4__ -++ /* The vector size is default 4-byte for v3 architecture. */ -++ .vec_size 4 -++ .align 2 -++#else -++ /* The vector size is default 16-byte for other architectures. */ -+ .vec_size 16 -+ .align 4 -++#endif -+ .weak _nds32_vector_18 -+ .type _nds32_vector_18, @function -+ _nds32_vector_18: -+diff --git a/libgcc/config/nds32/isr-library/vec_vid19.S b/libgcc/config/nds32/isr-library/vec_vid19.S -+index 5efab98f379..0d7d1de38c7 100644 -+--- a/libgcc/config/nds32/isr-library/vec_vid19.S -++++ b/libgcc/config/nds32/isr-library/vec_vid19.S -+@@ -24,8 +24,15 @@ -+ . */ -+ -+ .section .nds32_vector.19, "ax" -++#if __NDS32_ISR_VECTOR_SIZE_4__ -++ /* The vector size is default 4-byte for v3 architecture. */ -++ .vec_size 4 -++ .align 2 -++#else -++ /* The vector size is default 16-byte for other architectures. */ -+ .vec_size 16 -+ .align 4 -++#endif -+ .weak _nds32_vector_19 -+ .type _nds32_vector_19, @function -+ _nds32_vector_19: -+diff --git a/libgcc/config/nds32/isr-library/vec_vid20.S b/libgcc/config/nds32/isr-library/vec_vid20.S -+index 95e124700c3..d39d74b9ad6 100644 -+--- a/libgcc/config/nds32/isr-library/vec_vid20.S -++++ b/libgcc/config/nds32/isr-library/vec_vid20.S -+@@ -24,8 +24,15 @@ -+ . */ -+ -+ .section .nds32_vector.20, "ax" -++#if __NDS32_ISR_VECTOR_SIZE_4__ -++ /* The vector size is default 4-byte for v3 architecture. */ -++ .vec_size 4 -++ .align 2 -++#else -++ /* The vector size is default 16-byte for other architectures. */ -+ .vec_size 16 -+ .align 4 -++#endif -+ .weak _nds32_vector_20 -+ .type _nds32_vector_20, @function -+ _nds32_vector_20: -+diff --git a/libgcc/config/nds32/isr-library/vec_vid21.S b/libgcc/config/nds32/isr-library/vec_vid21.S -+index f3f401e25a0..deff0cf9ea9 100644 -+--- a/libgcc/config/nds32/isr-library/vec_vid21.S -++++ b/libgcc/config/nds32/isr-library/vec_vid21.S -+@@ -24,8 +24,15 @@ -+ . */ -+ -+ .section .nds32_vector.21, "ax" -++#if __NDS32_ISR_VECTOR_SIZE_4__ -++ /* The vector size is default 4-byte for v3 architecture. */ -++ .vec_size 4 -++ .align 2 -++#else -++ /* The vector size is default 16-byte for other architectures. */ -+ .vec_size 16 -+ .align 4 -++#endif -+ .weak _nds32_vector_21 -+ .type _nds32_vector_21, @function -+ _nds32_vector_21: -+diff --git a/libgcc/config/nds32/isr-library/vec_vid22.S b/libgcc/config/nds32/isr-library/vec_vid22.S -+index 28d0d99795f..ebd3891af71 100644 -+--- a/libgcc/config/nds32/isr-library/vec_vid22.S -++++ b/libgcc/config/nds32/isr-library/vec_vid22.S -+@@ -24,8 +24,15 @@ -+ . */ -+ -+ .section .nds32_vector.22, "ax" -++#if __NDS32_ISR_VECTOR_SIZE_4__ -++ /* The vector size is default 4-byte for v3 architecture. */ -++ .vec_size 4 -++ .align 2 -++#else -++ /* The vector size is default 16-byte for other architectures. */ -+ .vec_size 16 -+ .align 4 -++#endif -+ .weak _nds32_vector_22 -+ .type _nds32_vector_22, @function -+ _nds32_vector_22: -+diff --git a/libgcc/config/nds32/isr-library/vec_vid23.S b/libgcc/config/nds32/isr-library/vec_vid23.S -+index a8246298fed..90562e77bad 100644 -+--- a/libgcc/config/nds32/isr-library/vec_vid23.S -++++ b/libgcc/config/nds32/isr-library/vec_vid23.S -+@@ -24,8 +24,15 @@ -+ . */ -+ -+ .section .nds32_vector.23, "ax" -++#if __NDS32_ISR_VECTOR_SIZE_4__ -++ /* The vector size is default 4-byte for v3 architecture. */ -++ .vec_size 4 -++ .align 2 -++#else -++ /* The vector size is default 16-byte for other architectures. */ -+ .vec_size 16 -+ .align 4 -++#endif -+ .weak _nds32_vector_23 -+ .type _nds32_vector_23, @function -+ _nds32_vector_23: -+diff --git a/libgcc/config/nds32/isr-library/vec_vid24.S b/libgcc/config/nds32/isr-library/vec_vid24.S -+index 2c0e2d81c8c..7bd344c6c26 100644 -+--- a/libgcc/config/nds32/isr-library/vec_vid24.S -++++ b/libgcc/config/nds32/isr-library/vec_vid24.S -+@@ -24,8 +24,15 @@ -+ . */ -+ -+ .section .nds32_vector.24, "ax" -++#if __NDS32_ISR_VECTOR_SIZE_4__ -++ /* The vector size is default 4-byte for v3 architecture. */ -++ .vec_size 4 -++ .align 2 -++#else -++ /* The vector size is default 16-byte for other architectures. */ -+ .vec_size 16 -+ .align 4 -++#endif -+ .weak _nds32_vector_24 -+ .type _nds32_vector_24, @function -+ _nds32_vector_24: -+diff --git a/libgcc/config/nds32/isr-library/vec_vid25.S b/libgcc/config/nds32/isr-library/vec_vid25.S -+index 56f78863cef..245db6e67b0 100644 -+--- a/libgcc/config/nds32/isr-library/vec_vid25.S -++++ b/libgcc/config/nds32/isr-library/vec_vid25.S -+@@ -24,8 +24,15 @@ -+ . */ -+ -+ .section .nds32_vector.25, "ax" -++#if __NDS32_ISR_VECTOR_SIZE_4__ -++ /* The vector size is default 4-byte for v3 architecture. */ -++ .vec_size 4 -++ .align 2 -++#else -++ /* The vector size is default 16-byte for other architectures. */ -+ .vec_size 16 -+ .align 4 -++#endif -+ .weak _nds32_vector_25 -+ .type _nds32_vector_25, @function -+ _nds32_vector_25: -+diff --git a/libgcc/config/nds32/isr-library/vec_vid26.S b/libgcc/config/nds32/isr-library/vec_vid26.S -+index b02163ead68..4df61ff52e4 100644 -+--- a/libgcc/config/nds32/isr-library/vec_vid26.S -++++ b/libgcc/config/nds32/isr-library/vec_vid26.S -+@@ -24,8 +24,15 @@ -+ . */ -+ -+ .section .nds32_vector.26, "ax" -++#if __NDS32_ISR_VECTOR_SIZE_4__ -++ /* The vector size is default 4-byte for v3 architecture. */ -++ .vec_size 4 -++ .align 2 -++#else -++ /* The vector size is default 16-byte for other architectures. */ -+ .vec_size 16 -+ .align 4 -++#endif -+ .weak _nds32_vector_26 -+ .type _nds32_vector_26, @function -+ _nds32_vector_26: -+diff --git a/libgcc/config/nds32/isr-library/vec_vid27.S b/libgcc/config/nds32/isr-library/vec_vid27.S -+index 276d1f0b49e..50960dbd12c 100644 -+--- a/libgcc/config/nds32/isr-library/vec_vid27.S -++++ b/libgcc/config/nds32/isr-library/vec_vid27.S -+@@ -24,8 +24,15 @@ -+ . */ -+ -+ .section .nds32_vector.27, "ax" -++#if __NDS32_ISR_VECTOR_SIZE_4__ -++ /* The vector size is default 4-byte for v3 architecture. */ -++ .vec_size 4 -++ .align 2 -++#else -++ /* The vector size is default 16-byte for other architectures. */ -+ .vec_size 16 -+ .align 4 -++#endif -+ .weak _nds32_vector_27 -+ .type _nds32_vector_27, @function -+ _nds32_vector_27: -+diff --git a/libgcc/config/nds32/isr-library/vec_vid28.S b/libgcc/config/nds32/isr-library/vec_vid28.S -+index 59e8cc2c4ea..e44adbb58af 100644 -+--- a/libgcc/config/nds32/isr-library/vec_vid28.S -++++ b/libgcc/config/nds32/isr-library/vec_vid28.S -+@@ -24,8 +24,15 @@ -+ . */ -+ -+ .section .nds32_vector.28, "ax" -++#if __NDS32_ISR_VECTOR_SIZE_4__ -++ /* The vector size is default 4-byte for v3 architecture. */ -++ .vec_size 4 -++ .align 2 -++#else -++ /* The vector size is default 16-byte for other architectures. */ -+ .vec_size 16 -+ .align 4 -++#endif -+ .weak _nds32_vector_28 -+ .type _nds32_vector_28, @function -+ _nds32_vector_28: -+diff --git a/libgcc/config/nds32/isr-library/vec_vid29.S b/libgcc/config/nds32/isr-library/vec_vid29.S -+index 7119e254afc..f7e6c770e2b 100644 -+--- a/libgcc/config/nds32/isr-library/vec_vid29.S -++++ b/libgcc/config/nds32/isr-library/vec_vid29.S -+@@ -24,8 +24,15 @@ -+ . */ -+ -+ .section .nds32_vector.29, "ax" -++#if __NDS32_ISR_VECTOR_SIZE_4__ -++ /* The vector size is default 4-byte for v3 architecture. */ -++ .vec_size 4 -++ .align 2 -++#else -++ /* The vector size is default 16-byte for other architectures. */ -+ .vec_size 16 -+ .align 4 -++#endif -+ .weak _nds32_vector_29 -+ .type _nds32_vector_29, @function -+ _nds32_vector_29: -+diff --git a/libgcc/config/nds32/isr-library/vec_vid30.S b/libgcc/config/nds32/isr-library/vec_vid30.S -+index 7c7bd5fd191..7fac25da175 100644 -+--- a/libgcc/config/nds32/isr-library/vec_vid30.S -++++ b/libgcc/config/nds32/isr-library/vec_vid30.S -+@@ -24,8 +24,15 @@ -+ . */ -+ -+ .section .nds32_vector.30, "ax" -++#if __NDS32_ISR_VECTOR_SIZE_4__ -++ /* The vector size is default 4-byte for v3 architecture. */ -++ .vec_size 4 -++ .align 2 -++#else -++ /* The vector size is default 16-byte for other architectures. */ -+ .vec_size 16 -+ .align 4 -++#endif -+ .weak _nds32_vector_30 -+ .type _nds32_vector_30, @function -+ _nds32_vector_30: -+diff --git a/libgcc/config/nds32/isr-library/vec_vid31.S b/libgcc/config/nds32/isr-library/vec_vid31.S -+index bd29e03c4b8..5857765d22e 100644 -+--- a/libgcc/config/nds32/isr-library/vec_vid31.S -++++ b/libgcc/config/nds32/isr-library/vec_vid31.S -+@@ -24,8 +24,15 @@ -+ . */ -+ -+ .section .nds32_vector.31, "ax" -++#if __NDS32_ISR_VECTOR_SIZE_4__ -++ /* The vector size is default 4-byte for v3 architecture. */ -++ .vec_size 4 -++ .align 2 -++#else -++ /* The vector size is default 16-byte for other architectures. */ -+ .vec_size 16 -+ .align 4 -++#endif -+ .weak _nds32_vector_31 -+ .type _nds32_vector_31, @function -+ _nds32_vector_31: -+diff --git a/libgcc/config/nds32/isr-library/vec_vid32.S b/libgcc/config/nds32/isr-library/vec_vid32.S -+index 57b8db0bbe4..bcd5dbf88c8 100644 -+--- a/libgcc/config/nds32/isr-library/vec_vid32.S -++++ b/libgcc/config/nds32/isr-library/vec_vid32.S -+@@ -24,8 +24,15 @@ -+ . */ -+ -+ .section .nds32_vector.32, "ax" -++#if __NDS32_ISR_VECTOR_SIZE_4__ -++ /* The vector size is default 4-byte for v3 architecture. */ -++ .vec_size 4 -++ .align 2 -++#else -++ /* The vector size is default 16-byte for other architectures. */ -+ .vec_size 16 -+ .align 4 -++#endif -+ .weak _nds32_vector_32 -+ .type _nds32_vector_32, @function -+ _nds32_vector_32: -+diff --git a/libgcc/config/nds32/isr-library/vec_vid33.S b/libgcc/config/nds32/isr-library/vec_vid33.S -+index 609735e731d..abfed4eaf7a 100644 -+--- a/libgcc/config/nds32/isr-library/vec_vid33.S -++++ b/libgcc/config/nds32/isr-library/vec_vid33.S -+@@ -24,8 +24,15 @@ -+ . */ -+ -+ .section .nds32_vector.33, "ax" -++#if __NDS32_ISR_VECTOR_SIZE_4__ -++ /* The vector size is default 4-byte for v3 architecture. */ -++ .vec_size 4 -++ .align 2 -++#else -++ /* The vector size is default 16-byte for other architectures. */ -+ .vec_size 16 -+ .align 4 -++#endif -+ .weak _nds32_vector_33 -+ .type _nds32_vector_33, @function -+ _nds32_vector_33: -+diff --git a/libgcc/config/nds32/isr-library/vec_vid34.S b/libgcc/config/nds32/isr-library/vec_vid34.S -+index 2a91328fb11..f9446bb1b07 100644 -+--- a/libgcc/config/nds32/isr-library/vec_vid34.S -++++ b/libgcc/config/nds32/isr-library/vec_vid34.S -+@@ -24,8 +24,15 @@ -+ . */ -+ -+ .section .nds32_vector.34, "ax" -++#if __NDS32_ISR_VECTOR_SIZE_4__ -++ /* The vector size is default 4-byte for v3 architecture. */ -++ .vec_size 4 -++ .align 2 -++#else -++ /* The vector size is default 16-byte for other architectures. */ -+ .vec_size 16 -+ .align 4 -++#endif -+ .weak _nds32_vector_34 -+ .type _nds32_vector_34, @function -+ _nds32_vector_34: -+diff --git a/libgcc/config/nds32/isr-library/vec_vid35.S b/libgcc/config/nds32/isr-library/vec_vid35.S -+index 65dd081d7b3..8862137b38f 100644 -+--- a/libgcc/config/nds32/isr-library/vec_vid35.S -++++ b/libgcc/config/nds32/isr-library/vec_vid35.S -+@@ -24,8 +24,15 @@ -+ . */ -+ -+ .section .nds32_vector.35, "ax" -++#if __NDS32_ISR_VECTOR_SIZE_4__ -++ /* The vector size is default 4-byte for v3 architecture. */ -++ .vec_size 4 -++ .align 2 -++#else -++ /* The vector size is default 16-byte for other architectures. */ -+ .vec_size 16 -+ .align 4 -++#endif -+ .weak _nds32_vector_35 -+ .type _nds32_vector_35, @function -+ _nds32_vector_35: -+diff --git a/libgcc/config/nds32/isr-library/vec_vid36.S b/libgcc/config/nds32/isr-library/vec_vid36.S -+index fa47b8e879c..dbcbbf4298f 100644 -+--- a/libgcc/config/nds32/isr-library/vec_vid36.S -++++ b/libgcc/config/nds32/isr-library/vec_vid36.S -+@@ -24,8 +24,15 @@ -+ . */ -+ -+ .section .nds32_vector.36, "ax" -++#if __NDS32_ISR_VECTOR_SIZE_4__ -++ /* The vector size is default 4-byte for v3 architecture. */ -++ .vec_size 4 -++ .align 2 -++#else -++ /* The vector size is default 16-byte for other architectures. */ -+ .vec_size 16 -+ .align 4 -++#endif -+ .weak _nds32_vector_36 -+ .type _nds32_vector_36, @function -+ _nds32_vector_36: -+diff --git a/libgcc/config/nds32/isr-library/vec_vid37.S b/libgcc/config/nds32/isr-library/vec_vid37.S -+index ece845633f2..392f18bfe05 100644 -+--- a/libgcc/config/nds32/isr-library/vec_vid37.S -++++ b/libgcc/config/nds32/isr-library/vec_vid37.S -+@@ -24,8 +24,15 @@ -+ . */ -+ -+ .section .nds32_vector.37, "ax" -++#if __NDS32_ISR_VECTOR_SIZE_4__ -++ /* The vector size is default 4-byte for v3 architecture. */ -++ .vec_size 4 -++ .align 2 -++#else -++ /* The vector size is default 16-byte for other architectures. */ -+ .vec_size 16 -+ .align 4 -++#endif -+ .weak _nds32_vector_37 -+ .type _nds32_vector_37, @function -+ _nds32_vector_37: -+diff --git a/libgcc/config/nds32/isr-library/vec_vid38.S b/libgcc/config/nds32/isr-library/vec_vid38.S -+index c4a12f574ef..efe6619b3a7 100644 -+--- a/libgcc/config/nds32/isr-library/vec_vid38.S -++++ b/libgcc/config/nds32/isr-library/vec_vid38.S -+@@ -24,8 +24,15 @@ -+ . */ -+ -+ .section .nds32_vector.38, "ax" -++#if __NDS32_ISR_VECTOR_SIZE_4__ -++ /* The vector size is default 4-byte for v3 architecture. */ -++ .vec_size 4 -++ .align 2 -++#else -++ /* The vector size is default 16-byte for other architectures. */ -+ .vec_size 16 -+ .align 4 -++#endif -+ .weak _nds32_vector_38 -+ .type _nds32_vector_38, @function -+ _nds32_vector_38: -+diff --git a/libgcc/config/nds32/isr-library/vec_vid39.S b/libgcc/config/nds32/isr-library/vec_vid39.S -+index b3e56ed7077..238c43aec88 100644 -+--- a/libgcc/config/nds32/isr-library/vec_vid39.S -++++ b/libgcc/config/nds32/isr-library/vec_vid39.S -+@@ -24,8 +24,15 @@ -+ . */ -+ -+ .section .nds32_vector.39, "ax" -++#if __NDS32_ISR_VECTOR_SIZE_4__ -++ /* The vector size is default 4-byte for v3 architecture. */ -++ .vec_size 4 -++ .align 2 -++#else -++ /* The vector size is default 16-byte for other architectures. */ -+ .vec_size 16 -+ .align 4 -++#endif -+ .weak _nds32_vector_39 -+ .type _nds32_vector_39, @function -+ _nds32_vector_39: -+diff --git a/libgcc/config/nds32/isr-library/vec_vid40.S b/libgcc/config/nds32/isr-library/vec_vid40.S -+index 01364aa4909..cf3eaa21fa6 100644 -+--- a/libgcc/config/nds32/isr-library/vec_vid40.S -++++ b/libgcc/config/nds32/isr-library/vec_vid40.S -+@@ -24,8 +24,15 @@ -+ . */ -+ -+ .section .nds32_vector.40, "ax" -++#if __NDS32_ISR_VECTOR_SIZE_4__ -++ /* The vector size is default 4-byte for v3 architecture. */ -++ .vec_size 4 -++ .align 2 -++#else -++ /* The vector size is default 16-byte for other architectures. */ -+ .vec_size 16 -+ .align 4 -++#endif -+ .weak _nds32_vector_40 -+ .type _nds32_vector_40, @function -+ _nds32_vector_40: -+diff --git a/libgcc/config/nds32/isr-library/vec_vid41.S b/libgcc/config/nds32/isr-library/vec_vid41.S -+index f20beec98c0..27b7aac3dbb 100644 -+--- a/libgcc/config/nds32/isr-library/vec_vid41.S -++++ b/libgcc/config/nds32/isr-library/vec_vid41.S -+@@ -24,8 +24,15 @@ -+ . */ -+ -+ .section .nds32_vector.41, "ax" -++#if __NDS32_ISR_VECTOR_SIZE_4__ -++ /* The vector size is default 4-byte for v3 architecture. */ -++ .vec_size 4 -++ .align 2 -++#else -++ /* The vector size is default 16-byte for other architectures. */ -+ .vec_size 16 -+ .align 4 -++#endif -+ .weak _nds32_vector_41 -+ .type _nds32_vector_41, @function -+ _nds32_vector_41: -+diff --git a/libgcc/config/nds32/isr-library/vec_vid42.S b/libgcc/config/nds32/isr-library/vec_vid42.S -+index 6c29f1ff5a4..bfeed46e263 100644 -+--- a/libgcc/config/nds32/isr-library/vec_vid42.S -++++ b/libgcc/config/nds32/isr-library/vec_vid42.S -+@@ -24,8 +24,15 @@ -+ . */ -+ -+ .section .nds32_vector.42, "ax" -++#if __NDS32_ISR_VECTOR_SIZE_4__ -++ /* The vector size is default 4-byte for v3 architecture. */ -++ .vec_size 4 -++ .align 2 -++#else -++ /* The vector size is default 16-byte for other architectures. */ -+ .vec_size 16 -+ .align 4 -++#endif -+ .weak _nds32_vector_42 -+ .type _nds32_vector_42, @function -+ _nds32_vector_42: -+diff --git a/libgcc/config/nds32/isr-library/vec_vid43.S b/libgcc/config/nds32/isr-library/vec_vid43.S -+index 8767f998513..54640c9b4f7 100644 -+--- a/libgcc/config/nds32/isr-library/vec_vid43.S -++++ b/libgcc/config/nds32/isr-library/vec_vid43.S -+@@ -24,8 +24,15 @@ -+ . */ -+ -+ .section .nds32_vector.43, "ax" -++#if __NDS32_ISR_VECTOR_SIZE_4__ -++ /* The vector size is default 4-byte for v3 architecture. */ -++ .vec_size 4 -++ .align 2 -++#else -++ /* The vector size is default 16-byte for other architectures. */ -+ .vec_size 16 -+ .align 4 -++#endif -+ .weak _nds32_vector_43 -+ .type _nds32_vector_43, @function -+ _nds32_vector_43: -+diff --git a/libgcc/config/nds32/isr-library/vec_vid44.S b/libgcc/config/nds32/isr-library/vec_vid44.S -+index 8b6f53db5a8..f617243c473 100644 -+--- a/libgcc/config/nds32/isr-library/vec_vid44.S -++++ b/libgcc/config/nds32/isr-library/vec_vid44.S -+@@ -24,8 +24,15 @@ -+ . */ -+ -+ .section .nds32_vector.44, "ax" -++#if __NDS32_ISR_VECTOR_SIZE_4__ -++ /* The vector size is default 4-byte for v3 architecture. */ -++ .vec_size 4 -++ .align 2 -++#else -++ /* The vector size is default 16-byte for other architectures. */ -+ .vec_size 16 -+ .align 4 -++#endif -+ .weak _nds32_vector_44 -+ .type _nds32_vector_44, @function -+ _nds32_vector_44: -+diff --git a/libgcc/config/nds32/isr-library/vec_vid45.S b/libgcc/config/nds32/isr-library/vec_vid45.S -+index 52e344b0de4..2cfeb785b1b 100644 -+--- a/libgcc/config/nds32/isr-library/vec_vid45.S -++++ b/libgcc/config/nds32/isr-library/vec_vid45.S -+@@ -24,8 +24,15 @@ -+ . */ -+ -+ .section .nds32_vector.45, "ax" -++#if __NDS32_ISR_VECTOR_SIZE_4__ -++ /* The vector size is default 4-byte for v3 architecture. */ -++ .vec_size 4 -++ .align 2 -++#else -++ /* The vector size is default 16-byte for other architectures. */ -+ .vec_size 16 -+ .align 4 -++#endif -+ .weak _nds32_vector_45 -+ .type _nds32_vector_45, @function -+ _nds32_vector_45: -+diff --git a/libgcc/config/nds32/isr-library/vec_vid46.S b/libgcc/config/nds32/isr-library/vec_vid46.S -+index f9dc0d11382..45c88477ee9 100644 -+--- a/libgcc/config/nds32/isr-library/vec_vid46.S -++++ b/libgcc/config/nds32/isr-library/vec_vid46.S -+@@ -24,8 +24,15 @@ -+ . */ -+ -+ .section .nds32_vector.46, "ax" -++#if __NDS32_ISR_VECTOR_SIZE_4__ -++ /* The vector size is default 4-byte for v3 architecture. */ -++ .vec_size 4 -++ .align 2 -++#else -++ /* The vector size is default 16-byte for other architectures. */ -+ .vec_size 16 -+ .align 4 -++#endif -+ .weak _nds32_vector_46 -+ .type _nds32_vector_46, @function -+ _nds32_vector_46: -+diff --git a/libgcc/config/nds32/isr-library/vec_vid47.S b/libgcc/config/nds32/isr-library/vec_vid47.S -+index 436e7e3a977..25469e456fd 100644 -+--- a/libgcc/config/nds32/isr-library/vec_vid47.S -++++ b/libgcc/config/nds32/isr-library/vec_vid47.S -+@@ -24,8 +24,15 @@ -+ . */ -+ -+ .section .nds32_vector.47, "ax" -++#if __NDS32_ISR_VECTOR_SIZE_4__ -++ /* The vector size is default 4-byte for v3 architecture. */ -++ .vec_size 4 -++ .align 2 -++#else -++ /* The vector size is default 16-byte for other architectures. */ -+ .vec_size 16 -+ .align 4 -++#endif -+ .weak _nds32_vector_47 -+ .type _nds32_vector_47, @function -+ _nds32_vector_47: -+diff --git a/libgcc/config/nds32/isr-library/vec_vid48.S b/libgcc/config/nds32/isr-library/vec_vid48.S -+index 219dfd49b19..5a001194edd 100644 -+--- a/libgcc/config/nds32/isr-library/vec_vid48.S -++++ b/libgcc/config/nds32/isr-library/vec_vid48.S -+@@ -24,8 +24,15 @@ -+ . */ -+ -+ .section .nds32_vector.48, "ax" -++#if __NDS32_ISR_VECTOR_SIZE_4__ -++ /* The vector size is default 4-byte for v3 architecture. */ -++ .vec_size 4 -++ .align 2 -++#else -++ /* The vector size is default 16-byte for other architectures. */ -+ .vec_size 16 -+ .align 4 -++#endif -+ .weak _nds32_vector_48 -+ .type _nds32_vector_48, @function -+ _nds32_vector_48: -+diff --git a/libgcc/config/nds32/isr-library/vec_vid49.S b/libgcc/config/nds32/isr-library/vec_vid49.S -+index e3ba7537f08..dfe11f14017 100644 -+--- a/libgcc/config/nds32/isr-library/vec_vid49.S -++++ b/libgcc/config/nds32/isr-library/vec_vid49.S -+@@ -24,8 +24,15 @@ -+ . */ -+ -+ .section .nds32_vector.49, "ax" -++#if __NDS32_ISR_VECTOR_SIZE_4__ -++ /* The vector size is default 4-byte for v3 architecture. */ -++ .vec_size 4 -++ .align 2 -++#else -++ /* The vector size is default 16-byte for other architectures. */ -+ .vec_size 16 -+ .align 4 -++#endif -+ .weak _nds32_vector_49 -+ .type _nds32_vector_49, @function -+ _nds32_vector_49: -+diff --git a/libgcc/config/nds32/isr-library/vec_vid50.S b/libgcc/config/nds32/isr-library/vec_vid50.S -+index b0b3fc2b73f..0dacd26315d 100644 -+--- a/libgcc/config/nds32/isr-library/vec_vid50.S -++++ b/libgcc/config/nds32/isr-library/vec_vid50.S -+@@ -24,8 +24,15 @@ -+ . */ -+ -+ .section .nds32_vector.50, "ax" -++#if __NDS32_ISR_VECTOR_SIZE_4__ -++ /* The vector size is default 4-byte for v3 architecture. */ -++ .vec_size 4 -++ .align 2 -++#else -++ /* The vector size is default 16-byte for other architectures. */ -+ .vec_size 16 -+ .align 4 -++#endif -+ .weak _nds32_vector_50 -+ .type _nds32_vector_50, @function -+ _nds32_vector_50: -+diff --git a/libgcc/config/nds32/isr-library/vec_vid51.S b/libgcc/config/nds32/isr-library/vec_vid51.S -+index bf3011d5ccb..5ab28ef7238 100644 -+--- a/libgcc/config/nds32/isr-library/vec_vid51.S -++++ b/libgcc/config/nds32/isr-library/vec_vid51.S -+@@ -24,8 +24,15 @@ -+ . */ -+ -+ .section .nds32_vector.51, "ax" -++#if __NDS32_ISR_VECTOR_SIZE_4__ -++ /* The vector size is default 4-byte for v3 architecture. */ -++ .vec_size 4 -++ .align 2 -++#else -++ /* The vector size is default 16-byte for other architectures. */ -+ .vec_size 16 -+ .align 4 -++#endif -+ .weak _nds32_vector_51 -+ .type _nds32_vector_51, @function -+ _nds32_vector_51: -+diff --git a/libgcc/config/nds32/isr-library/vec_vid52.S b/libgcc/config/nds32/isr-library/vec_vid52.S -+index eaf5f14ef25..ed00f4000d1 100644 -+--- a/libgcc/config/nds32/isr-library/vec_vid52.S -++++ b/libgcc/config/nds32/isr-library/vec_vid52.S -+@@ -24,8 +24,15 @@ -+ . */ -+ -+ .section .nds32_vector.52, "ax" -++#if __NDS32_ISR_VECTOR_SIZE_4__ -++ /* The vector size is default 4-byte for v3 architecture. */ -++ .vec_size 4 -++ .align 2 -++#else -++ /* The vector size is default 16-byte for other architectures. */ -+ .vec_size 16 -+ .align 4 -++#endif -+ .weak _nds32_vector_52 -+ .type _nds32_vector_52, @function -+ _nds32_vector_52: -+diff --git a/libgcc/config/nds32/isr-library/vec_vid53.S b/libgcc/config/nds32/isr-library/vec_vid53.S -+index 3f92e56d665..564cadbf1d4 100644 -+--- a/libgcc/config/nds32/isr-library/vec_vid53.S -++++ b/libgcc/config/nds32/isr-library/vec_vid53.S -+@@ -24,8 +24,15 @@ -+ . */ -+ -+ .section .nds32_vector.53, "ax" -++#if __NDS32_ISR_VECTOR_SIZE_4__ -++ /* The vector size is default 4-byte for v3 architecture. */ -++ .vec_size 4 -++ .align 2 -++#else -++ /* The vector size is default 16-byte for other architectures. */ -+ .vec_size 16 -+ .align 4 -++#endif -+ .weak _nds32_vector_53 -+ .type _nds32_vector_53, @function -+ _nds32_vector_53: -+diff --git a/libgcc/config/nds32/isr-library/vec_vid54.S b/libgcc/config/nds32/isr-library/vec_vid54.S -+index f22793fe3f2..377c524361e 100644 -+--- a/libgcc/config/nds32/isr-library/vec_vid54.S -++++ b/libgcc/config/nds32/isr-library/vec_vid54.S -+@@ -24,8 +24,15 @@ -+ . */ -+ -+ .section .nds32_vector.54, "ax" -++#if __NDS32_ISR_VECTOR_SIZE_4__ -++ /* The vector size is default 4-byte for v3 architecture. */ -++ .vec_size 4 -++ .align 2 -++#else -++ /* The vector size is default 16-byte for other architectures. */ -+ .vec_size 16 -+ .align 4 -++#endif -+ .weak _nds32_vector_54 -+ .type _nds32_vector_54, @function -+ _nds32_vector_54: -+diff --git a/libgcc/config/nds32/isr-library/vec_vid55.S b/libgcc/config/nds32/isr-library/vec_vid55.S -+index 1017130a9da..497252ada22 100644 -+--- a/libgcc/config/nds32/isr-library/vec_vid55.S -++++ b/libgcc/config/nds32/isr-library/vec_vid55.S -+@@ -24,8 +24,15 @@ -+ . */ -+ -+ .section .nds32_vector.55, "ax" -++#if __NDS32_ISR_VECTOR_SIZE_4__ -++ /* The vector size is default 4-byte for v3 architecture. */ -++ .vec_size 4 -++ .align 2 -++#else -++ /* The vector size is default 16-byte for other architectures. */ -+ .vec_size 16 -+ .align 4 -++#endif -+ .weak _nds32_vector_55 -+ .type _nds32_vector_55, @function -+ _nds32_vector_55: -+diff --git a/libgcc/config/nds32/isr-library/vec_vid56.S b/libgcc/config/nds32/isr-library/vec_vid56.S -+index a0923e9e791..b62534b9cbc 100644 -+--- a/libgcc/config/nds32/isr-library/vec_vid56.S -++++ b/libgcc/config/nds32/isr-library/vec_vid56.S -+@@ -24,8 +24,15 @@ -+ . */ -+ -+ .section .nds32_vector.56, "ax" -++#if __NDS32_ISR_VECTOR_SIZE_4__ -++ /* The vector size is default 4-byte for v3 architecture. */ -++ .vec_size 4 -++ .align 2 -++#else -++ /* The vector size is default 16-byte for other architectures. */ -+ .vec_size 16 -+ .align 4 -++#endif -+ .weak _nds32_vector_56 -+ .type _nds32_vector_56, @function -+ _nds32_vector_56: -+diff --git a/libgcc/config/nds32/isr-library/vec_vid57.S b/libgcc/config/nds32/isr-library/vec_vid57.S -+index e711b890ef4..b1bb42d9c03 100644 -+--- a/libgcc/config/nds32/isr-library/vec_vid57.S -++++ b/libgcc/config/nds32/isr-library/vec_vid57.S -+@@ -24,8 +24,15 @@ -+ . */ -+ -+ .section .nds32_vector.57, "ax" -++#if __NDS32_ISR_VECTOR_SIZE_4__ -++ /* The vector size is default 4-byte for v3 architecture. */ -++ .vec_size 4 -++ .align 2 -++#else -++ /* The vector size is default 16-byte for other architectures. */ -+ .vec_size 16 -+ .align 4 -++#endif -+ .weak _nds32_vector_57 -+ .type _nds32_vector_57, @function -+ _nds32_vector_57: -+diff --git a/libgcc/config/nds32/isr-library/vec_vid58.S b/libgcc/config/nds32/isr-library/vec_vid58.S -+index f8d90643af1..14595a527a9 100644 -+--- a/libgcc/config/nds32/isr-library/vec_vid58.S -++++ b/libgcc/config/nds32/isr-library/vec_vid58.S -+@@ -24,8 +24,15 @@ -+ . */ -+ -+ .section .nds32_vector.58, "ax" -++#if __NDS32_ISR_VECTOR_SIZE_4__ -++ /* The vector size is default 4-byte for v3 architecture. */ -++ .vec_size 4 -++ .align 2 -++#else -++ /* The vector size is default 16-byte for other architectures. */ -+ .vec_size 16 -+ .align 4 -++#endif -+ .weak _nds32_vector_58 -+ .type _nds32_vector_58, @function -+ _nds32_vector_58: -+diff --git a/libgcc/config/nds32/isr-library/vec_vid59.S b/libgcc/config/nds32/isr-library/vec_vid59.S -+index 58fb6e626e3..e5be1772425 100644 -+--- a/libgcc/config/nds32/isr-library/vec_vid59.S -++++ b/libgcc/config/nds32/isr-library/vec_vid59.S -+@@ -24,8 +24,15 @@ -+ . */ -+ -+ .section .nds32_vector.59, "ax" -++#if __NDS32_ISR_VECTOR_SIZE_4__ -++ /* The vector size is default 4-byte for v3 architecture. */ -++ .vec_size 4 -++ .align 2 -++#else -++ /* The vector size is default 16-byte for other architectures. */ -+ .vec_size 16 -+ .align 4 -++#endif -+ .weak _nds32_vector_59 -+ .type _nds32_vector_59, @function -+ _nds32_vector_59: -+diff --git a/libgcc/config/nds32/isr-library/vec_vid60.S b/libgcc/config/nds32/isr-library/vec_vid60.S -+index 94aa6e0ef7a..f6df9712907 100644 -+--- a/libgcc/config/nds32/isr-library/vec_vid60.S -++++ b/libgcc/config/nds32/isr-library/vec_vid60.S -+@@ -24,8 +24,15 @@ -+ . */ -+ -+ .section .nds32_vector.60, "ax" -++#if __NDS32_ISR_VECTOR_SIZE_4__ -++ /* The vector size is default 4-byte for v3 architecture. */ -++ .vec_size 4 -++ .align 2 -++#else -++ /* The vector size is default 16-byte for other architectures. */ -+ .vec_size 16 -+ .align 4 -++#endif -+ .weak _nds32_vector_60 -+ .type _nds32_vector_60, @function -+ _nds32_vector_60: -+diff --git a/libgcc/config/nds32/isr-library/vec_vid61.S b/libgcc/config/nds32/isr-library/vec_vid61.S -+index 869f6c86514..4f97b043154 100644 -+--- a/libgcc/config/nds32/isr-library/vec_vid61.S -++++ b/libgcc/config/nds32/isr-library/vec_vid61.S -+@@ -24,8 +24,15 @@ -+ . */ -+ -+ .section .nds32_vector.61, "ax" -++#if __NDS32_ISR_VECTOR_SIZE_4__ -++ /* The vector size is default 4-byte for v3 architecture. */ -++ .vec_size 4 -++ .align 2 -++#else -++ /* The vector size is default 16-byte for other architectures. */ -+ .vec_size 16 -+ .align 4 -++#endif -+ .weak _nds32_vector_61 -+ .type _nds32_vector_61, @function -+ _nds32_vector_61: -+diff --git a/libgcc/config/nds32/isr-library/vec_vid62.S b/libgcc/config/nds32/isr-library/vec_vid62.S -+index acc846c320b..08d1bbb2567 100644 -+--- a/libgcc/config/nds32/isr-library/vec_vid62.S -++++ b/libgcc/config/nds32/isr-library/vec_vid62.S -+@@ -24,8 +24,15 @@ -+ . */ -+ -+ .section .nds32_vector.62, "ax" -++#if __NDS32_ISR_VECTOR_SIZE_4__ -++ /* The vector size is default 4-byte for v3 architecture. */ -++ .vec_size 4 -++ .align 2 -++#else -++ /* The vector size is default 16-byte for other architectures. */ -+ .vec_size 16 -+ .align 4 -++#endif -+ .weak _nds32_vector_62 -+ .type _nds32_vector_62, @function -+ _nds32_vector_62: -+diff --git a/libgcc/config/nds32/isr-library/vec_vid63.S b/libgcc/config/nds32/isr-library/vec_vid63.S -+index d0727ecdd08..2b2068c4fb5 100644 -+--- a/libgcc/config/nds32/isr-library/vec_vid63.S -++++ b/libgcc/config/nds32/isr-library/vec_vid63.S -+@@ -24,8 +24,15 @@ -+ . */ -+ -+ .section .nds32_vector.63, "ax" -++#if __NDS32_ISR_VECTOR_SIZE_4__ -++ /* The vector size is default 4-byte for v3 architecture. */ -++ .vec_size 4 -++ .align 2 -++#else -++ /* The vector size is default 16-byte for other architectures. */ -+ .vec_size 16 -+ .align 4 -++#endif -+ .weak _nds32_vector_63 -+ .type _nds32_vector_63, @function -+ _nds32_vector_63: -+diff --git a/libgcc/config/nds32/isr-library/vec_vid64.S b/libgcc/config/nds32/isr-library/vec_vid64.S -+index cb1659ad3ee..2c06ea0cc90 100644 -+--- a/libgcc/config/nds32/isr-library/vec_vid64.S -++++ b/libgcc/config/nds32/isr-library/vec_vid64.S -+@@ -24,8 +24,15 @@ -+ . */ -+ -+ .section .nds32_vector.64, "ax" -++#if __NDS32_ISR_VECTOR_SIZE_4__ -++ /* The vector size is default 4-byte for v3 architecture. */ -++ .vec_size 4 -++ .align 2 -++#else -++ /* The vector size is default 16-byte for other architectures. */ -+ .vec_size 16 -+ .align 4 -++#endif -+ .weak _nds32_vector_64 -+ .type _nds32_vector_64, @function -+ _nds32_vector_64: -+diff --git a/libgcc/config/nds32/isr-library/vec_vid65.S b/libgcc/config/nds32/isr-library/vec_vid65.S -+index da46481ec02..d2359fd6b2b 100644 -+--- a/libgcc/config/nds32/isr-library/vec_vid65.S -++++ b/libgcc/config/nds32/isr-library/vec_vid65.S -+@@ -24,8 +24,15 @@ -+ . */ -+ -+ .section .nds32_vector.65, "ax" -++#if __NDS32_ISR_VECTOR_SIZE_4__ -++ /* The vector size is default 4-byte for v3 architecture. */ -++ .vec_size 4 -++ .align 2 -++#else -++ /* The vector size is default 16-byte for other architectures. */ -+ .vec_size 16 -+ .align 4 -++#endif -+ .weak _nds32_vector_65 -+ .type _nds32_vector_65, @function -+ _nds32_vector_65: -+diff --git a/libgcc/config/nds32/isr-library/vec_vid66.S b/libgcc/config/nds32/isr-library/vec_vid66.S -+index a8c18b804b3..69ccf368f6d 100644 -+--- a/libgcc/config/nds32/isr-library/vec_vid66.S -++++ b/libgcc/config/nds32/isr-library/vec_vid66.S -+@@ -24,8 +24,15 @@ -+ . */ -+ -+ .section .nds32_vector.66, "ax" -++#if __NDS32_ISR_VECTOR_SIZE_4__ -++ /* The vector size is default 4-byte for v3 architecture. */ -++ .vec_size 4 -++ .align 2 -++#else -++ /* The vector size is default 16-byte for other architectures. */ -+ .vec_size 16 -+ .align 4 -++#endif -+ .weak _nds32_vector_66 -+ .type _nds32_vector_66, @function -+ _nds32_vector_66: -+diff --git a/libgcc/config/nds32/isr-library/vec_vid67.S b/libgcc/config/nds32/isr-library/vec_vid67.S -+index d2996a375ee..78a68cb89a9 100644 -+--- a/libgcc/config/nds32/isr-library/vec_vid67.S -++++ b/libgcc/config/nds32/isr-library/vec_vid67.S -+@@ -24,8 +24,15 @@ -+ . */ -+ -+ .section .nds32_vector.67, "ax" -++#if __NDS32_ISR_VECTOR_SIZE_4__ -++ /* The vector size is default 4-byte for v3 architecture. */ -++ .vec_size 4 -++ .align 2 -++#else -++ /* The vector size is default 16-byte for other architectures. */ -+ .vec_size 16 -+ .align 4 -++#endif -+ .weak _nds32_vector_67 -+ .type _nds32_vector_67, @function -+ _nds32_vector_67: -+diff --git a/libgcc/config/nds32/isr-library/vec_vid68.S b/libgcc/config/nds32/isr-library/vec_vid68.S -+index 0c9de86b1d7..a120ec34377 100644 -+--- a/libgcc/config/nds32/isr-library/vec_vid68.S -++++ b/libgcc/config/nds32/isr-library/vec_vid68.S -+@@ -24,8 +24,15 @@ -+ . */ -+ -+ .section .nds32_vector.68, "ax" -++#if __NDS32_ISR_VECTOR_SIZE_4__ -++ /* The vector size is default 4-byte for v3 architecture. */ -++ .vec_size 4 -++ .align 2 -++#else -++ /* The vector size is default 16-byte for other architectures. */ -+ .vec_size 16 -+ .align 4 -++#endif -+ .weak _nds32_vector_68 -+ .type _nds32_vector_68, @function -+ _nds32_vector_68: -+diff --git a/libgcc/config/nds32/isr-library/vec_vid69.S b/libgcc/config/nds32/isr-library/vec_vid69.S -+index 43cf748d442..e2bdd5f0442 100644 -+--- a/libgcc/config/nds32/isr-library/vec_vid69.S -++++ b/libgcc/config/nds32/isr-library/vec_vid69.S -+@@ -24,8 +24,15 @@ -+ . */ -+ -+ .section .nds32_vector.69, "ax" -++#if __NDS32_ISR_VECTOR_SIZE_4__ -++ /* The vector size is default 4-byte for v3 architecture. */ -++ .vec_size 4 -++ .align 2 -++#else -++ /* The vector size is default 16-byte for other architectures. */ -+ .vec_size 16 -+ .align 4 -++#endif -+ .weak _nds32_vector_69 -+ .type _nds32_vector_69, @function -+ _nds32_vector_69: -+diff --git a/libgcc/config/nds32/isr-library/vec_vid70.S b/libgcc/config/nds32/isr-library/vec_vid70.S -+index aba3e6aede0..a5ac1f306ff 100644 -+--- a/libgcc/config/nds32/isr-library/vec_vid70.S -++++ b/libgcc/config/nds32/isr-library/vec_vid70.S -+@@ -24,8 +24,15 @@ -+ . */ -+ -+ .section .nds32_vector.70, "ax" -++#if __NDS32_ISR_VECTOR_SIZE_4__ -++ /* The vector size is default 4-byte for v3 architecture. */ -++ .vec_size 4 -++ .align 2 -++#else -++ /* The vector size is default 16-byte for other architectures. */ -+ .vec_size 16 -+ .align 4 -++#endif -+ .weak _nds32_vector_70 -+ .type _nds32_vector_70, @function -+ _nds32_vector_70: -+diff --git a/libgcc/config/nds32/isr-library/vec_vid71.S b/libgcc/config/nds32/isr-library/vec_vid71.S -+index be8aaa52534..06ed89c633a 100644 -+--- a/libgcc/config/nds32/isr-library/vec_vid71.S -++++ b/libgcc/config/nds32/isr-library/vec_vid71.S -+@@ -24,8 +24,15 @@ -+ . */ -+ -+ .section .nds32_vector.71, "ax" -++#if __NDS32_ISR_VECTOR_SIZE_4__ -++ /* The vector size is default 4-byte for v3 architecture. */ -++ .vec_size 4 -++ .align 2 -++#else -++ /* The vector size is default 16-byte for other architectures. */ -+ .vec_size 16 -+ .align 4 -++#endif -+ .weak _nds32_vector_71 -+ .type _nds32_vector_71, @function -+ _nds32_vector_71: -+diff --git a/libgcc/config/nds32/isr-library/vec_vid72.S b/libgcc/config/nds32/isr-library/vec_vid72.S -+index 041c89517e3..2163201b620 100644 -+--- a/libgcc/config/nds32/isr-library/vec_vid72.S -++++ b/libgcc/config/nds32/isr-library/vec_vid72.S -+@@ -24,8 +24,15 @@ -+ . */ -+ -+ .section .nds32_vector.72, "ax" -++#if __NDS32_ISR_VECTOR_SIZE_4__ -++ /* The vector size is default 4-byte for v3 architecture. */ -++ .vec_size 4 -++ .align 2 -++#else -++ /* The vector size is default 16-byte for other architectures. */ -+ .vec_size 16 -+ .align 4 -++#endif -+ .weak _nds32_vector_72 -+ .type _nds32_vector_72, @function -+ _nds32_vector_72: -+diff --git a/libgcc/config/nds32/linux-atomic.c b/libgcc/config/nds32/linux-atomic.c -+new file mode 100644 -+index 00000000000..6da7be9a653 -+--- /dev/null -++++ b/libgcc/config/nds32/linux-atomic.c -+@@ -0,0 +1,282 @@ -++/* Linux-specific atomic operations for NDS32 Linux. -++ Copyright (C) 2012-2018 Free Software Foundation, Inc. -++ -++This file is free software; you can redistribute it and/or modify it -++under the terms of the GNU General Public License as published by the -++Free Software Foundation; either version 3, or (at your option) any -++later version. -++ -++This file 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. -++ -++Under Section 7 of GPL version 3, you are granted additional -++permissions described in the GCC Runtime Library Exception, version -++3.1, as published by the Free Software Foundation. -++ -++You should have received a copy of the GNU General Public License and -++a copy of the GCC Runtime Library Exception along with this program; -++see the files COPYING3 and COPYING.RUNTIME respectively. If not, see -++. */ -++ -++/* We implement byte, short and int versions of each atomic operation -++ using the kernel helper defined below. There is no support for -++ 64-bit operations yet. */ -++ -++/* This function copy form NDS32 Linux-kernal. */ -++static inline int -++__kernel_cmpxchg (int oldval, int newval, int *mem) -++{ -++ int temp1, temp2, temp3, offset; -++ -++ asm volatile ("msync\tall\n" -++ "movi\t%0, #0\n" -++ "1:\n" -++ "\tllw\t%1, [%4+%0]\n" -++ "\tsub\t%3, %1, %6\n" -++ "\tcmovz\t%2, %5, %3\n" -++ "\tcmovn\t%2, %1, %3\n" -++ "\tscw\t%2, [%4+%0]\n" -++ "\tbeqz\t%2, 1b\n" -++ : "=&r" (offset), "=&r" (temp3), "=&r" (temp2), "=&r" (temp1) -++ : "r" (mem), "r" (newval), "r" (oldval) : "memory"); -++ -++ return temp1; -++} -++ -++#define HIDDEN __attribute__ ((visibility ("hidden"))) -++ -++#ifdef __NDS32_EL__ -++#define INVERT_MASK_1 0 -++#define INVERT_MASK_2 0 -++#else -++#define INVERT_MASK_1 24 -++#define INVERT_MASK_2 16 -++#endif -++ -++#define MASK_1 0xffu -++#define MASK_2 0xffffu -++ -++#define FETCH_AND_OP_WORD(OP, PFX_OP, INF_OP) \ -++ int HIDDEN \ -++ __sync_fetch_and_##OP##_4 (int *ptr, int val) \ -++ { \ -++ int failure, tmp; \ -++ \ -++ do { \ -++ tmp = __atomic_load_n (ptr, __ATOMIC_SEQ_CST); \ -++ failure = __kernel_cmpxchg (tmp, PFX_OP (tmp INF_OP val), ptr); \ -++ } while (failure != 0); \ -++ \ -++ return tmp; \ -++ } -++ -++FETCH_AND_OP_WORD (add, , +) -++FETCH_AND_OP_WORD (sub, , -) -++FETCH_AND_OP_WORD (or, , |) -++FETCH_AND_OP_WORD (and, , &) -++FETCH_AND_OP_WORD (xor, , ^) -++FETCH_AND_OP_WORD (nand, ~, &) -++ -++#define NAME_oldval(OP, WIDTH) __sync_fetch_and_##OP##_##WIDTH -++#define NAME_newval(OP, WIDTH) __sync_##OP##_and_fetch_##WIDTH -++ -++/* Implement both __sync__and_fetch and __sync_fetch_and_ for -++ subword-sized quantities. */ -++ -++#define SUBWORD_SYNC_OP(OP, PFX_OP, INF_OP, TYPE, WIDTH, RETURN) \ -++ TYPE HIDDEN \ -++ NAME##_##RETURN (OP, WIDTH) (TYPE *ptr, TYPE val) \ -++ { \ -++ int *wordptr = (int *) ((unsigned long) ptr & ~3); \ -++ unsigned int mask, shift, oldval, newval; \ -++ int failure; \ -++ \ -++ shift = (((unsigned long) ptr & 3) << 3) ^ INVERT_MASK_##WIDTH; \ -++ mask = MASK_##WIDTH << shift; \ -++ \ -++ do { \ -++ oldval = __atomic_load_n (wordptr, __ATOMIC_SEQ_CST); \ -++ newval = ((PFX_OP (((oldval & mask) >> shift) \ -++ INF_OP (unsigned int) val)) << shift) & mask; \ -++ newval |= oldval & ~mask; \ -++ failure = __kernel_cmpxchg (oldval, newval, wordptr); \ -++ } while (failure != 0); \ -++ \ -++ return (RETURN & mask) >> shift; \ -++ } -++ -++ -++SUBWORD_SYNC_OP (add, , +, unsigned short, 2, oldval) -++SUBWORD_SYNC_OP (sub, , -, unsigned short, 2, oldval) -++SUBWORD_SYNC_OP (or, , |, unsigned short, 2, oldval) -++SUBWORD_SYNC_OP (and, , &, unsigned short, 2, oldval) -++SUBWORD_SYNC_OP (xor, , ^, unsigned short, 2, oldval) -++SUBWORD_SYNC_OP (nand, ~, &, unsigned short, 2, oldval) -++ -++SUBWORD_SYNC_OP (add, , +, unsigned char, 1, oldval) -++SUBWORD_SYNC_OP (sub, , -, unsigned char, 1, oldval) -++SUBWORD_SYNC_OP (or, , |, unsigned char, 1, oldval) -++SUBWORD_SYNC_OP (and, , &, unsigned char, 1, oldval) -++SUBWORD_SYNC_OP (xor, , ^, unsigned char, 1, oldval) -++SUBWORD_SYNC_OP (nand, ~, &, unsigned char, 1, oldval) -++ -++#define OP_AND_FETCH_WORD(OP, PFX_OP, INF_OP) \ -++ int HIDDEN \ -++ __sync_##OP##_and_fetch_4 (int *ptr, int val) \ -++ { \ -++ int tmp, failure; \ -++ \ -++ do { \ -++ tmp = __atomic_load_n (ptr, __ATOMIC_SEQ_CST); \ -++ failure = __kernel_cmpxchg (tmp, PFX_OP (tmp INF_OP val), ptr); \ -++ } while (failure != 0); \ -++ \ -++ return PFX_OP (tmp INF_OP val); \ -++ } -++ -++OP_AND_FETCH_WORD (add, , +) -++OP_AND_FETCH_WORD (sub, , -) -++OP_AND_FETCH_WORD (or, , |) -++OP_AND_FETCH_WORD (and, , &) -++OP_AND_FETCH_WORD (xor, , ^) -++OP_AND_FETCH_WORD (nand, ~, &) -++ -++SUBWORD_SYNC_OP (add, , +, unsigned short, 2, newval) -++SUBWORD_SYNC_OP (sub, , -, unsigned short, 2, newval) -++SUBWORD_SYNC_OP (or, , |, unsigned short, 2, newval) -++SUBWORD_SYNC_OP (and, , &, unsigned short, 2, newval) -++SUBWORD_SYNC_OP (xor, , ^, unsigned short, 2, newval) -++SUBWORD_SYNC_OP (nand, ~, &, unsigned short, 2, newval) -++ -++SUBWORD_SYNC_OP (add, , +, unsigned char, 1, newval) -++SUBWORD_SYNC_OP (sub, , -, unsigned char, 1, newval) -++SUBWORD_SYNC_OP (or, , |, unsigned char, 1, newval) -++SUBWORD_SYNC_OP (and, , &, unsigned char, 1, newval) -++SUBWORD_SYNC_OP (xor, , ^, unsigned char, 1, newval) -++SUBWORD_SYNC_OP (nand, ~, &, unsigned char, 1, newval) -++ -++int HIDDEN -++__sync_val_compare_and_swap_4 (int *ptr, int oldval, int newval) -++{ -++ int actual_oldval, fail; -++ -++ while (1) -++ { -++ actual_oldval = __atomic_load_n (ptr, __ATOMIC_SEQ_CST); -++ -++ if (oldval != actual_oldval) -++ return actual_oldval; -++ -++ fail = __kernel_cmpxchg (actual_oldval, newval, ptr); -++ -++ if (!fail) -++ return oldval; -++ } -++} -++ -++#define SUBWORD_VAL_CAS(TYPE, WIDTH) \ -++ TYPE HIDDEN \ -++ __sync_val_compare_and_swap_##WIDTH (TYPE *ptr, TYPE oldval, \ -++ TYPE newval) \ -++ { \ -++ int *wordptr = (int *)((unsigned long) ptr & ~3), fail; \ -++ unsigned int mask, shift, actual_oldval, actual_newval; \ -++ \ -++ shift = (((unsigned long) ptr & 3) << 3) ^ INVERT_MASK_##WIDTH; \ -++ mask = MASK_##WIDTH << shift; \ -++ \ -++ while (1) \ -++ { \ -++ actual_oldval = __atomic_load_n (wordptr, __ATOMIC_SEQ_CST); \ -++ \ -++ if (((actual_oldval & mask) >> shift) != (unsigned int) oldval) \ -++ return (actual_oldval & mask) >> shift; \ -++ \ -++ actual_newval = (actual_oldval & ~mask) \ -++ | (((unsigned int) newval << shift) & mask); \ -++ \ -++ fail = __kernel_cmpxchg (actual_oldval, actual_newval, \ -++ wordptr); \ -++ \ -++ if (!fail) \ -++ return oldval; \ -++ } \ -++ } -++ -++SUBWORD_VAL_CAS (unsigned short, 2) -++SUBWORD_VAL_CAS (unsigned char, 1) -++ -++typedef unsigned char bool; -++ -++bool HIDDEN -++__sync_bool_compare_and_swap_4 (int *ptr, int oldval, int newval) -++{ -++ int failure = __kernel_cmpxchg (oldval, newval, ptr); -++ return (failure == 0); -++} -++ -++#define SUBWORD_BOOL_CAS(TYPE, WIDTH) \ -++ bool HIDDEN \ -++ __sync_bool_compare_and_swap_##WIDTH (TYPE *ptr, TYPE oldval, \ -++ TYPE newval) \ -++ { \ -++ TYPE actual_oldval \ -++ = __sync_val_compare_and_swap_##WIDTH (ptr, oldval, newval); \ -++ return (oldval == actual_oldval); \ -++ } -++ -++SUBWORD_BOOL_CAS (unsigned short, 2) -++SUBWORD_BOOL_CAS (unsigned char, 1) -++ -++int HIDDEN -++__sync_lock_test_and_set_4 (int *ptr, int val) -++{ -++ int failure, oldval; -++ -++ do { -++ oldval = __atomic_load_n (ptr, __ATOMIC_SEQ_CST); -++ failure = __kernel_cmpxchg (oldval, val, ptr); -++ } while (failure != 0); -++ -++ return oldval; -++} -++ -++#define SUBWORD_TEST_AND_SET(TYPE, WIDTH) \ -++ TYPE HIDDEN \ -++ __sync_lock_test_and_set_##WIDTH (TYPE *ptr, TYPE val) \ -++ { \ -++ int failure; \ -++ unsigned int oldval, newval, shift, mask; \ -++ int *wordptr = (int *) ((unsigned long) ptr & ~3); \ -++ \ -++ shift = (((unsigned long) ptr & 3) << 3) ^ INVERT_MASK_##WIDTH; \ -++ mask = MASK_##WIDTH << shift; \ -++ \ -++ do { \ -++ oldval = __atomic_load_n (wordptr, __ATOMIC_SEQ_CST); \ -++ newval = (oldval & ~mask) \ -++ | (((unsigned int) val << shift) & mask); \ -++ failure = __kernel_cmpxchg (oldval, newval, wordptr); \ -++ } while (failure != 0); \ -++ \ -++ return (oldval & mask) >> shift; \ -++ } -++ -++SUBWORD_TEST_AND_SET (unsigned short, 2) -++SUBWORD_TEST_AND_SET (unsigned char, 1) -++ -++#define SYNC_LOCK_RELEASE(TYPE, WIDTH) \ -++ void HIDDEN \ -++ __sync_lock_release_##WIDTH (TYPE *ptr) \ -++ { \ -++ /* All writes before this point must be seen before we release \ -++ the lock itself. */ \ -++ __builtin_nds32_msync_all (); \ -++ *ptr = 0; \ -++ } -++ -++SYNC_LOCK_RELEASE (int, 4) -++SYNC_LOCK_RELEASE (short, 2) -++SYNC_LOCK_RELEASE (char, 1) -+diff --git a/libgcc/config/nds32/linux-unwind.h b/libgcc/config/nds32/linux-unwind.h -+new file mode 100644 -+index 00000000000..00f2b2cfe43 -+--- /dev/null -++++ b/libgcc/config/nds32/linux-unwind.h -+@@ -0,0 +1,143 @@ -++/* DWARF2 EH unwinding support for NDS32 Linux signal frame. -++ Copyright (C) 2014-2015 Free Software Foundation, Inc. -++ Contributed by Andes Technology Corporation. -++ -++ This file is part of GCC. -++ -++ GCC is free software; you can redistribute it and/or modify it -++ under the terms of the GNU General Public License as published -++ by the Free Software Foundation; either version 3, or (at your -++ option) any later version. -++ -++ GCC is distributed in the hope that it will be useful, but WITHOUT -++ ANY WARRANTY; without even the implied warranty of MERCHANTABILITY -++ or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public -++ License for more details. -++ -++ Under Section 7 of GPL version 3, you are granted additional -++ permissions described in the GCC Runtime Library Exception, version -++ 3.1, as published by the Free Software Foundation. -++ -++ You should have received a copy of the GNU General Public License and -++ a copy of the GCC Runtime Library Exception along with this program; -++ see the files COPYING3 and COPYING.RUNTIME respectively. If not, see -++ . */ -++ -++#ifndef inhibit_libc -++ -++/* Do code reading to identify a signal frame, and set the frame -++ state data appropriately. See unwind-dw2.c for the structs. -++ The corresponding bits in the Linux kernel are in -++ arch/nds32/kernel/signal.c. */ -++ -++#include -++#include -++#include -++ -++/* Exactly the same layout as the kernel structures, unique names. */ -++ -++/* arch/nds32/kernel/signal.c */ -++struct _rt_sigframe { -++ siginfo_t info; -++ struct ucontext_t uc; -++}; -++ -++#define RT_SIGRETURN 0x8b00f044 -++ -++#define MD_FALLBACK_FRAME_STATE_FOR nds32_fallback_frame_state -++ -++/* This function is supposed to be invoked by uw_frame_state_for() -++ when there is no unwind data available. -++ -++ Generally, given the _Unwind_Context CONTEXT for a stack frame, -++ we need to look up its caller and decode information into FS. -++ However, if the exception handling happens within a signal handler, -++ the return address of signal handler is a special module, which -++ contains signal return syscall and has no FDE in the .eh_frame section. -++ We need to implement MD_FALLBACK_FRAME_STATE_FOR so that we can -++ unwind through signal frames. */ -++static _Unwind_Reason_Code -++nds32_fallback_frame_state (struct _Unwind_Context *context, -++ _Unwind_FrameState *fs) -++{ -++ u_int32_t *pc = (u_int32_t *) context->ra; -++ struct sigcontext *sc_; -++ _Unwind_Ptr new_cfa; -++ -++#ifdef __NDS32_EB__ -++#error "Signal handler is not supported for force unwind." -++#endif -++ -++ if ((_Unwind_Ptr) pc & 3) -++ return _URC_END_OF_STACK; -++ -++ /* Check if we are going through a signal handler. -++ See arch/nds32/kernel/signal.c implementation. -++ FIXME: Currently we only handle little endian (EL) case. */ -++ if (pc[0] == RT_SIGRETURN) -++ { -++ /* Using '_sigfame' memory address to locate kernal's sigcontext. -++ The sigcontext structures in arch/nds32/include/asm/sigcontext.h. */ -++ struct _rt_sigframe *rt_; -++ rt_ = context->cfa; -++ sc_ = &rt_->uc.uc_mcontext; -++ } -++ else -++ return _URC_END_OF_STACK; -++ -++ /* Update cfa from sigcontext. */ -++ new_cfa = (_Unwind_Ptr) sc_; -++ fs->regs.cfa_how = CFA_REG_OFFSET; -++ fs->regs.cfa_reg = STACK_POINTER_REGNUM; -++ fs->regs.cfa_offset = new_cfa - (_Unwind_Ptr) context->cfa; -++ -++#define NDS32_PUT_FS_REG(NUM, NAME) \ -++ (fs->regs.reg[NUM].how = REG_SAVED_OFFSET, \ -++ fs->regs.reg[NUM].loc.offset = (_Unwind_Ptr) &(sc_->NAME) - new_cfa) -++ -++ /* Restore all registers value. */ -++ NDS32_PUT_FS_REG (0, nds32_r0); -++ NDS32_PUT_FS_REG (1, nds32_r1); -++ NDS32_PUT_FS_REG (2, nds32_r2); -++ NDS32_PUT_FS_REG (3, nds32_r3); -++ NDS32_PUT_FS_REG (4, nds32_r4); -++ NDS32_PUT_FS_REG (5, nds32_r5); -++ NDS32_PUT_FS_REG (6, nds32_r6); -++ NDS32_PUT_FS_REG (7, nds32_r7); -++ NDS32_PUT_FS_REG (8, nds32_r8); -++ NDS32_PUT_FS_REG (9, nds32_r9); -++ NDS32_PUT_FS_REG (10, nds32_r10); -++ NDS32_PUT_FS_REG (11, nds32_r11); -++ NDS32_PUT_FS_REG (12, nds32_r12); -++ NDS32_PUT_FS_REG (13, nds32_r13); -++ NDS32_PUT_FS_REG (14, nds32_r14); -++ NDS32_PUT_FS_REG (15, nds32_r15); -++ NDS32_PUT_FS_REG (16, nds32_r16); -++ NDS32_PUT_FS_REG (17, nds32_r17); -++ NDS32_PUT_FS_REG (18, nds32_r18); -++ NDS32_PUT_FS_REG (19, nds32_r19); -++ NDS32_PUT_FS_REG (20, nds32_r20); -++ NDS32_PUT_FS_REG (21, nds32_r21); -++ NDS32_PUT_FS_REG (22, nds32_r22); -++ NDS32_PUT_FS_REG (23, nds32_r23); -++ NDS32_PUT_FS_REG (24, nds32_r24); -++ NDS32_PUT_FS_REG (25, nds32_r25); -++ -++ NDS32_PUT_FS_REG (28, nds32_fp); -++ NDS32_PUT_FS_REG (29, nds32_gp); -++ NDS32_PUT_FS_REG (30, nds32_lp); -++ NDS32_PUT_FS_REG (31, nds32_sp); -++ -++ /* Restore PC, point to trigger signal instruction. */ -++ NDS32_PUT_FS_REG (32, nds32_ipc); -++ -++#undef NDS32_PUT_FS_REG -++ -++ /* The retaddr is PC, use PC to find FDE. */ -++ fs->retaddr_column = 32; -++ fs->signal_frame = 1; -++ -++ return _URC_NO_REASON; -++} -++ -++#endif -+diff --git a/libgcc/config/nds32/sfp-machine.h b/libgcc/config/nds32/sfp-machine.h -+index 499bdad7423..bfbdaf9c3bf 100644 -+--- a/libgcc/config/nds32/sfp-machine.h -++++ b/libgcc/config/nds32/sfp-machine.h -+@@ -76,6 +76,25 @@ typedef int __gcc_CMPtype __attribute__ ((mode (__libgcc_cmp_return__))); -+ R##_c = FP_CLS_NAN; \ -+ } while (0) -+ -++#ifdef NDS32_ABI_2FP_PLUS -++#define FP_RND_NEAREST 0x0 -++#define FP_RND_PINF 0x1 -++#define FP_RND_MINF 0x2 -++#define FP_RND_ZERO 0x3 -++#define FP_RND_MASK 0x3 -++ -++#define _FP_DECL_EX \ -++ unsigned long int _fcsr __attribute__ ((unused)) = FP_RND_NEAREST -++ -++#define FP_INIT_ROUNDMODE \ -++ do { \ -++ _fcsr = __builtin_nds32_fmfcsr (); \ -++ } while (0) -++ -++#define FP_ROUNDMODE (_fcsr & FP_RND_MASK) -++ -++#endif -++ -+ /* Not checked. */ -+ #define _FP_TININESS_AFTER_ROUNDING 0 -+ -+diff --git a/libgcc/config/nds32/t-nds32-glibc b/libgcc/config/nds32/t-nds32-glibc -+new file mode 100644 -+index 00000000000..4e229314c34 -+--- /dev/null -++++ b/libgcc/config/nds32/t-nds32-glibc -+@@ -0,0 +1,34 @@ -++# Rules of glibc library makefile of Andes NDS32 cpu for GNU compiler -++# Copyright (C) 2012-2015 Free Software Foundation, Inc. -++# Contributed by Andes Technology Corporation. -++# -++# This file is part of GCC. -++# -++# GCC is free software; you can redistribute it and/or modify it -++# under the terms of the GNU General Public License as published -++# by the Free Software Foundation; either version 3, or (at your -++# option) any later version. -++# -++# GCC is distributed in the hope that it will be useful, but WITHOUT -++# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY -++# or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public -++# License for more details. -++# -++# You should have received a copy of the GNU General Public License -++# along with GCC; see the file COPYING3. If not see -++# . -++ -++# Compiler flags to use when compiling 'libgcc2.c' -++HOST_LIBGCC2_CFLAGS = -O2 -fPIC -fwrapv -++LIB2ADD += $(srcdir)/config/nds32/linux-atomic.c -++ -++#LIB1ASMSRC = nds32/lib1asmsrc-newlib.S -++#LIB1ASMFUNCS = _divsi3 _modsi3 _udivsi3 _umodsi3 -++ -++# List of functions not to build from libgcc2.c. -++#LIB2FUNCS_EXCLUDE = _clzsi2 -++ -++# List of extra C and assembler files(*.S) to add to static libgcc2. -++#LIB2ADD_ST += $(srcdir)/config/nds32/lib2csrc-newlib/_clzsi2.c -++ -++# ------------------------------------------------------------------------ -+diff --git a/libgcc/config/nds32/t-nds32-isr b/libgcc/config/nds32/t-nds32-isr -+index 4f86f900395..abfd82b2248 100644 -+--- a/libgcc/config/nds32/t-nds32-isr -++++ b/libgcc/config/nds32/t-nds32-isr -+@@ -23,11 +23,11 @@ -+ # Makfile fragment rules for libnds32_isr.a to support ISR attribute extension -+ ############################################################################### -+ -+-# basic flags setting -++# Basic flags setting. -+ ISR_CFLAGS = $(CFLAGS) -c -+ -+-# the object files we would like to create -+-LIBNDS32_ISR_16B_OBJS = \ -++# The object files we would like to create. -++LIBNDS32_ISR_VEC_OBJS = \ -+ vec_vid00.o vec_vid01.o vec_vid02.o vec_vid03.o \ -+ vec_vid04.o vec_vid05.o vec_vid06.o vec_vid07.o \ -+ vec_vid08.o vec_vid09.o vec_vid10.o vec_vid11.o \ -+@@ -46,40 +46,9 @@ LIBNDS32_ISR_16B_OBJS = \ -+ vec_vid60.o vec_vid61.o vec_vid62.o vec_vid63.o \ -+ vec_vid64.o vec_vid65.o vec_vid66.o vec_vid67.o \ -+ vec_vid68.o vec_vid69.o vec_vid70.o vec_vid71.o \ -+- vec_vid72.o \ -+- excp_isr_ps_nn.o excp_isr_ps_ns.o excp_isr_ps_nr.o \ -+- excp_isr_sa_nn.o excp_isr_sa_ns.o excp_isr_sa_nr.o \ -+- intr_isr_ps_nn.o intr_isr_ps_ns.o intr_isr_ps_nr.o \ -+- intr_isr_sa_nn.o intr_isr_sa_ns.o intr_isr_sa_nr.o \ -+- reset.o -+- -+-LIBNDS32_ISR_4B_OBJS = \ -+- vec_vid00_4b.o vec_vid01_4b.o vec_vid02_4b.o vec_vid03_4b.o \ -+- vec_vid04_4b.o vec_vid05_4b.o vec_vid06_4b.o vec_vid07_4b.o \ -+- vec_vid08_4b.o vec_vid09_4b.o vec_vid10_4b.o vec_vid11_4b.o \ -+- vec_vid12_4b.o vec_vid13_4b.o vec_vid14_4b.o vec_vid15_4b.o \ -+- vec_vid16_4b.o vec_vid17_4b.o vec_vid18_4b.o vec_vid19_4b.o \ -+- vec_vid20_4b.o vec_vid21_4b.o vec_vid22_4b.o vec_vid23_4b.o \ -+- vec_vid24_4b.o vec_vid25_4b.o vec_vid26_4b.o vec_vid27_4b.o \ -+- vec_vid28_4b.o vec_vid29_4b.o vec_vid30_4b.o vec_vid31_4b.o \ -+- vec_vid32_4b.o vec_vid33_4b.o vec_vid34_4b.o vec_vid35_4b.o \ -+- vec_vid36_4b.o vec_vid37_4b.o vec_vid38_4b.o vec_vid39_4b.o \ -+- vec_vid40_4b.o vec_vid41_4b.o vec_vid42_4b.o vec_vid43_4b.o \ -+- vec_vid44_4b.o vec_vid45_4b.o vec_vid46_4b.o vec_vid47_4b.o \ -+- vec_vid48_4b.o vec_vid49_4b.o vec_vid50_4b.o vec_vid51_4b.o \ -+- vec_vid52_4b.o vec_vid53_4b.o vec_vid54_4b.o vec_vid55_4b.o \ -+- vec_vid56_4b.o vec_vid57_4b.o vec_vid58_4b.o vec_vid59_4b.o \ -+- vec_vid60_4b.o vec_vid61_4b.o vec_vid62_4b.o vec_vid63_4b.o \ -+- vec_vid64_4b.o vec_vid65_4b.o vec_vid66_4b.o vec_vid67_4b.o \ -+- vec_vid68_4b.o vec_vid69_4b.o vec_vid70_4b.o vec_vid71_4b.o \ -+- vec_vid72_4b.o \ -+- excp_isr_ps_nn_4b.o excp_isr_ps_ns_4b.o excp_isr_ps_nr_4b.o \ -+- excp_isr_sa_nn_4b.o excp_isr_sa_ns_4b.o excp_isr_sa_nr_4b.o \ -+- intr_isr_ps_nn_4b.o intr_isr_ps_ns_4b.o intr_isr_ps_nr_4b.o \ -+- intr_isr_sa_nn_4b.o intr_isr_sa_ns_4b.o intr_isr_sa_nr_4b.o \ -+- reset_4b.o -++ vec_vid72.o -+ -+-LIBNDS32_ISR_COMMON_OBJS = \ -++LIBNDS32_ISR_JMP_OBJS = \ -+ jmptbl_vid00.o jmptbl_vid01.o jmptbl_vid02.o jmptbl_vid03.o \ -+ jmptbl_vid04.o jmptbl_vid05.o jmptbl_vid06.o jmptbl_vid07.o \ -+ jmptbl_vid08.o jmptbl_vid09.o jmptbl_vid10.o jmptbl_vid11.o \ -+@@ -98,29 +67,32 @@ LIBNDS32_ISR_COMMON_OBJS = \ -+ jmptbl_vid60.o jmptbl_vid61.o jmptbl_vid62.o jmptbl_vid63.o \ -+ jmptbl_vid64.o jmptbl_vid65.o jmptbl_vid66.o jmptbl_vid67.o \ -+ jmptbl_vid68.o jmptbl_vid69.o jmptbl_vid70.o jmptbl_vid71.o \ -+- jmptbl_vid72.o \ -++ jmptbl_vid72.o -++ -++LIBNDS32_ISR_COMMON_OBJS = \ -++ excp_isr_ps_nn.o excp_isr_ps_ns.o excp_isr_ps_nr.o \ -++ excp_isr_sa_nn.o excp_isr_sa_ns.o excp_isr_sa_nr.o \ -++ intr_isr_ps_nn.o intr_isr_ps_ns.o intr_isr_ps_nr.o \ -++ intr_isr_sa_nn.o intr_isr_sa_ns.o intr_isr_sa_nr.o \ -++ reset.o \ -+ nmih.o \ -+ wrh.o -+ -+-LIBNDS32_ISR_COMPLETE_OBJS = $(LIBNDS32_ISR_16B_OBJS) $(LIBNDS32_ISR_4B_OBJS) $(LIBNDS32_ISR_COMMON_OBJS) -++LIBNDS32_ISR_COMPLETE_OBJS = $(LIBNDS32_ISR_VEC_OBJS) $(LIBNDS32_ISR_JMP_OBJS) $(LIBNDS32_ISR_COMMON_OBJS) -+ -+ -+-# Build common objects for ISR library -+-nmih.o: $(srcdir)/config/nds32/isr-library/nmih.S -+- $(GCC_FOR_TARGET) $(ISR_CFLAGS) $(srcdir)/config/nds32/isr-library/nmih.S -o nmih.o -+ -+-wrh.o: $(srcdir)/config/nds32/isr-library/wrh.S -+- $(GCC_FOR_TARGET) $(ISR_CFLAGS) $(srcdir)/config/nds32/isr-library/wrh.S -o wrh.o -+- -+-jmptbl_vid%.o: $(srcdir)/config/nds32/isr-library/jmptbl_vid%.S -++# Build vector vid objects for ISR library. -++vec_vid%.o: $(srcdir)/config/nds32/isr-library/vec_vid%.S -+ $(GCC_FOR_TARGET) $(ISR_CFLAGS) $< -o $@ -+ -+ -+- -+-# Build 16b version objects for ISR library. (no "_4b" postfix string) -+-vec_vid%.o: $(srcdir)/config/nds32/isr-library/vec_vid%.S -++# Build jump table objects for ISR library. -++jmptbl_vid%.o: $(srcdir)/config/nds32/isr-library/jmptbl_vid%.S -+ $(GCC_FOR_TARGET) $(ISR_CFLAGS) $< -o $@ -+ -++ -++# Build commen objects for ISR library. -+ excp_isr_ps_nn.o: $(srcdir)/config/nds32/isr-library/excp_isr.S -+ $(GCC_FOR_TARGET) $(ISR_CFLAGS) $(srcdir)/config/nds32/isr-library/excp_isr.S -o excp_isr_ps_nn.o -+ -+@@ -160,48 +132,12 @@ intr_isr_sa_nr.o: $(srcdir)/config/nds32/isr-library/intr_isr.S -+ reset.o: $(srcdir)/config/nds32/isr-library/reset.S -+ $(GCC_FOR_TARGET) $(ISR_CFLAGS) $(srcdir)/config/nds32/isr-library/reset.S -o reset.o -+ -+-# Build 4b version objects for ISR library. -+-vec_vid%_4b.o: $(srcdir)/config/nds32/isr-library/vec_vid%_4b.S -+- $(GCC_FOR_TARGET) $(ISR_CFLAGS) $< -o $@ -+- -+-excp_isr_ps_nn_4b.o: $(srcdir)/config/nds32/isr-library/excp_isr_4b.S -+- $(GCC_FOR_TARGET) $(ISR_CFLAGS) $(srcdir)/config/nds32/isr-library/excp_isr_4b.S -o excp_isr_ps_nn_4b.o -+- -+-excp_isr_ps_ns_4b.o: $(srcdir)/config/nds32/isr-library/excp_isr_4b.S -+- $(GCC_FOR_TARGET) $(ISR_CFLAGS) -DNDS32_NESTED $(srcdir)/config/nds32/isr-library/excp_isr_4b.S -o excp_isr_ps_ns_4b.o -+- -+-excp_isr_ps_nr_4b.o: $(srcdir)/config/nds32/isr-library/excp_isr_4b.S -+- $(GCC_FOR_TARGET) $(ISR_CFLAGS) -DNDS32_NESTED_READY $(srcdir)/config/nds32/isr-library/excp_isr_4b.S -o excp_isr_ps_nr_4b.o -+- -+-excp_isr_sa_nn_4b.o: $(srcdir)/config/nds32/isr-library/excp_isr_4b.S -+- $(GCC_FOR_TARGET) $(ISR_CFLAGS) -DNDS32_SAVE_ALL_REGS $(srcdir)/config/nds32/isr-library/excp_isr_4b.S -o excp_isr_sa_nn_4b.o -+- -+-excp_isr_sa_ns_4b.o: $(srcdir)/config/nds32/isr-library/excp_isr_4b.S -+- $(GCC_FOR_TARGET) $(ISR_CFLAGS) -DNDS32_SAVE_ALL_REGS -DNDS32_NESTED $(srcdir)/config/nds32/isr-library/excp_isr_4b.S -o excp_isr_sa_ns_4b.o -+- -+-excp_isr_sa_nr_4b.o: $(srcdir)/config/nds32/isr-library/excp_isr_4b.S -+- $(GCC_FOR_TARGET) $(ISR_CFLAGS) -DNDS32_SAVE_ALL_REGS -DNDS32_NESTED_READY $(srcdir)/config/nds32/isr-library/excp_isr_4b.S -o excp_isr_sa_nr_4b.o -+- -+-intr_isr_ps_nn_4b.o: $(srcdir)/config/nds32/isr-library/intr_isr_4b.S -+- $(GCC_FOR_TARGET) $(ISR_CFLAGS) $(srcdir)/config/nds32/isr-library/intr_isr_4b.S -o intr_isr_ps_nn_4b.o -+- -+-intr_isr_ps_ns_4b.o: $(srcdir)/config/nds32/isr-library/intr_isr_4b.S -+- $(GCC_FOR_TARGET) $(ISR_CFLAGS) -DNDS32_NESTED $(srcdir)/config/nds32/isr-library/intr_isr_4b.S -o intr_isr_ps_ns_4b.o -+- -+-intr_isr_ps_nr_4b.o: $(srcdir)/config/nds32/isr-library/intr_isr_4b.S -+- $(GCC_FOR_TARGET) $(ISR_CFLAGS) -DNDS32_NESTED_READY $(srcdir)/config/nds32/isr-library/intr_isr_4b.S -o intr_isr_ps_nr_4b.o -+- -+-intr_isr_sa_nn_4b.o: $(srcdir)/config/nds32/isr-library/intr_isr_4b.S -+- $(GCC_FOR_TARGET) $(ISR_CFLAGS) -DNDS32_SAVE_ALL_REGS $(srcdir)/config/nds32/isr-library/intr_isr_4b.S -o intr_isr_sa_nn_4b.o -+- -+-intr_isr_sa_ns_4b.o: $(srcdir)/config/nds32/isr-library/intr_isr_4b.S -+- $(GCC_FOR_TARGET) $(ISR_CFLAGS) -DNDS32_SAVE_ALL_REGS -DNDS32_NESTED $(srcdir)/config/nds32/isr-library/intr_isr_4b.S -o intr_isr_sa_ns_4b.o -++nmih.o: $(srcdir)/config/nds32/isr-library/nmih.S -++ $(GCC_FOR_TARGET) $(ISR_CFLAGS) $(srcdir)/config/nds32/isr-library/nmih.S -o nmih.o -+ -+-intr_isr_sa_nr_4b.o: $(srcdir)/config/nds32/isr-library/intr_isr_4b.S -+- $(GCC_FOR_TARGET) $(ISR_CFLAGS) -DNDS32_SAVE_ALL_REGS -DNDS32_NESTED_READY $(srcdir)/config/nds32/isr-library/intr_isr_4b.S -o intr_isr_sa_nr_4b.o -++wrh.o: $(srcdir)/config/nds32/isr-library/wrh.S -++ $(GCC_FOR_TARGET) $(ISR_CFLAGS) $(srcdir)/config/nds32/isr-library/wrh.S -o wrh.o -+ -+-reset_4b.o: $(srcdir)/config/nds32/isr-library/reset_4b.S -+- $(GCC_FOR_TARGET) $(ISR_CFLAGS) $(srcdir)/config/nds32/isr-library/reset_4b.S -o reset_4b.o -+ -+ -+ # The rule to create libnds32_isr.a file -+diff --git a/libgcc/config/nds32/t-nds32-newlib b/libgcc/config/nds32/t-nds32-newlib -+index 1ea2bc32163..a59646fcff5 100644 -+--- a/libgcc/config/nds32/t-nds32-newlib -++++ b/libgcc/config/nds32/t-nds32-newlib -+@@ -19,7 +19,7 @@ -+ # . -+ -+ # Compiler flags to use when compiling 'libgcc2.c' -+-HOST_LIBGCC2_CFLAGS = -O2 -++HOST_LIBGCC2_CFLAGS = -O2 -fwrapv -+ -+ -+ #LIB1ASMSRC = nds32/lib1asmsrc-newlib.S -diff --git a/util/crossgcc/sum/binutils-2.29.1.tar.xz.cksum b/util/crossgcc/sum/binutils-2.29.1.tar.xz.cksum -deleted file mode 100644 -index 4d48d87bea..0000000000 ---- a/util/crossgcc/sum/binutils-2.29.1.tar.xz.cksum -+++ /dev/null -@@ -1 +0,0 @@ --172244a349d07ec205c39c0321cbc354c125e78e tarballs/binutils-2.29.tar.xz -diff --git a/util/crossgcc/sum/binutils-2.30.tar.xz.cksum b/util/crossgcc/sum/binutils-2.30.tar.xz.cksum -new file mode 100644 -index 0000000000..3493413556 ---- /dev/null -+++ b/util/crossgcc/sum/binutils-2.30.tar.xz.cksum -@@ -0,0 +1 @@ -+574d3b5650413d6ee65195a4f5ecbddc3a38f718 tarballs/binutils-2.30.tar.xz -diff --git a/util/crossgcc/sum/gcc-6.3.0.tar.bz2.cksum b/util/crossgcc/sum/gcc-6.3.0.tar.bz2.cksum -deleted file mode 100644 -index f3bb227ec0..0000000000 ---- a/util/crossgcc/sum/gcc-6.3.0.tar.bz2.cksum -+++ /dev/null -@@ -1 +0,0 @@ --928ab552666ee08eed645ff20ceb49d139205dea tarballs/gcc-6.3.0.tar.bz2 -diff --git a/util/crossgcc/sum/gcc-8.1.0.tar.xz.cksum b/util/crossgcc/sum/gcc-8.1.0.tar.xz.cksum -new file mode 100644 -index 0000000000..d185533514 ---- /dev/null -+++ b/util/crossgcc/sum/gcc-8.1.0.tar.xz.cksum -@@ -0,0 +1 @@ -+b34031ba9ff3e248b2c62de0825e49a1e0e01998 tarballs/gcc-8.1.0.tar.xz --- -2.17.1 - diff --git a/patches/coreboot-4.8.1/0057-util-crosgcc-patches-update-make-4.2.1-patches.patch b/patches/coreboot-4.8.1/0057-util-crosgcc-patches-update-make-4.2.1-patches.patch deleted file mode 100644 index eeaac14ec..000000000 --- a/patches/coreboot-4.8.1/0057-util-crosgcc-patches-update-make-4.2.1-patches.patch +++ /dev/null @@ -1,156 +0,0 @@ -From 234eabaa8da28dfa750826c200c08959bb917b28 Mon Sep 17 00:00:00 2001 -From: Martin Roth -Date: Sat, 21 Jul 2018 14:17:22 -0600 -Subject: [PATCH 57/59] util/crosgcc/patches: update make-4.2.1 patches - -- Add the Do-not-assume-glibc-glob-internals patch to fix segfaults. -- Update glob_interface_v2 patch to the patch directly from the -make git repository instead of translating it. This gives better -attributution to the original author. - -Change-Id: Ibc936fc00925a4ca2170a6f5dca7c2b8d8d62f02 -Signed-off-by: Martin Roth -Reviewed-on: https://review.coreboot.org/27591 -Tested-by: build bot (Jenkins) -Reviewed-by: Paul Menzel -Reviewed-by: Patrick Georgi ---- - ...b-Do-not-assume-glibc-glob-internals.patch | 67 +++++++++++++++++++ - ...pport-GLIBC-glob-interface-version-2.patch | 28 ++++++++ - .../make-4.2.1_gnu_glob_interface_v2.patch | 15 ----- - 3 files changed, 95 insertions(+), 15 deletions(-) - create mode 100644 util/crossgcc/patches/make-4.2.1_0053-glob-Do-not-assume-glibc-glob-internals.patch - create mode 100644 util/crossgcc/patches/make-4.2.1_0068-configure.ac-Support-GLIBC-glob-interface-version-2.patch - delete mode 100644 util/crossgcc/patches/make-4.2.1_gnu_glob_interface_v2.patch - -diff --git a/util/crossgcc/patches/make-4.2.1_0053-glob-Do-not-assume-glibc-glob-internals.patch b/util/crossgcc/patches/make-4.2.1_0053-glob-Do-not-assume-glibc-glob-internals.patch -new file mode 100644 -index 0000000000..3d45025fe1 ---- /dev/null -+++ b/util/crossgcc/patches/make-4.2.1_0053-glob-Do-not-assume-glibc-glob-internals.patch -@@ -0,0 +1,67 @@ -+From 193f1e81edd6b1b56b0eb0ff8aa4b41c7b4257b4 Mon Sep 17 00:00:00 2001 -+From: Paul Eggert -+Date: Sun, 24 Sep 2017 09:12:58 -0400 -+Subject: [PATCH 53/78] glob: Do not assume glibc glob internals. -+ -+It has been proposed that glibc glob start using gl_lstat, -+which the API allows it to do. GNU 'make' should not get in -+the way of this. See: -+https://sourceware.org/ml/libc-alpha/2017-09/msg00409.html -+ -+* dir.c (local_lstat): New function, like local_stat. -+(dir_setup_glob): Use it to initialize gl_lstat too, as the API -+requires. -+--- -+ dir.c | 29 +++++++++++++++++++++++++++-- -+ 1 file changed, 27 insertions(+), 2 deletions(-) -+ -+diff --git a/dir.c b/dir.c -+index adbb8a9..c343e4c 100644 -+--- a/dir.c -++++ b/dir.c -+@@ -1299,15 +1299,40 @@ local_stat (const char *path, struct stat *buf) -+ } -+ #endif -+ -++/* Similarly for lstat. */ -++#if !defined(lstat) && !defined(WINDOWS32) || defined(VMS) -++# ifndef VMS -++# ifndef HAVE_SYS_STAT_H -++int lstat (const char *path, struct stat *sbuf); -++# endif -++# else -++ /* We are done with the fake lstat. Go back to the real lstat */ -++# ifdef lstat -++# undef lstat -++# endif -++# endif -++# define local_lstat lstat -++#elif defined(WINDOWS32) -++/* Windows doesn't support lstat(). */ -++# define local_lstat local_stat -++#else -++static int -++local_lstat (const char *path, struct stat *buf) -++{ -++ int e; -++ EINTRLOOP (e, lstat (path, buf)); -++ return e; -++} -++#endif -++ -+ void -+ dir_setup_glob (glob_t *gl) -+ { -+ gl->gl_opendir = open_dirstream; -+ gl->gl_readdir = read_dirstream; -+ gl->gl_closedir = free; -++ gl->gl_lstat = local_lstat; -+ gl->gl_stat = local_stat; -+- /* We don't bother setting gl_lstat, since glob never calls it. -+- The slot is only there for compatibility with 4.4 BSD. */ -+ } -+ -+ void -+-- -+2.18.0 -+ -diff --git a/util/crossgcc/patches/make-4.2.1_0068-configure.ac-Support-GLIBC-glob-interface-version-2.patch b/util/crossgcc/patches/make-4.2.1_0068-configure.ac-Support-GLIBC-glob-interface-version-2.patch -new file mode 100644 -index 0000000000..53e61b8bf7 ---- /dev/null -+++ b/util/crossgcc/patches/make-4.2.1_0068-configure.ac-Support-GLIBC-glob-interface-version-2.patch -@@ -0,0 +1,28 @@ -+From 48c8a116a914a325a0497721f5d8b58d5bba34d4 Mon Sep 17 00:00:00 2001 -+From: Paul Smith -+Date: Sun, 19 Nov 2017 15:09:16 -0500 -+Subject: [PATCH 68/78] * configure.ac: Support GLIBC glob interface version 2 -+ -+--- -+ configure.ac | 3 +-- -+ 1 file changed, 1 insertion(+), 2 deletions(-) -+ -+diff --git a/configure.ac b/configure.ac -+index 8c72568..4710832 100644 -+--- a/configure.ac -++++ b/configure.ac -+@@ -404,10 +404,9 @@ AC_CACHE_CHECK([if system libc has GNU glob], [make_cv_sys_gnu_glob], -+ #include -+ #include -+ -+-#define GLOB_INTERFACE_VERSION 1 -+ #if !defined _LIBC && defined __GNU_LIBRARY__ && __GNU_LIBRARY__ > 1 -+ # include -+-# if _GNU_GLOB_INTERFACE_VERSION == GLOB_INTERFACE_VERSION -++# if _GNU_GLOB_INTERFACE_VERSION == 1 || _GNU_GLOB_INTERFACE_VERSION == 2 -+ gnu glob -+ # endif -+ #endif], -+-- -+2.18.0 -+ -diff --git a/util/crossgcc/patches/make-4.2.1_gnu_glob_interface_v2.patch b/util/crossgcc/patches/make-4.2.1_gnu_glob_interface_v2.patch -deleted file mode 100644 -index 466d6fdd70..0000000000 ---- a/util/crossgcc/patches/make-4.2.1_gnu_glob_interface_v2.patch -+++ /dev/null -@@ -1,15 +0,0 @@ --diff -Naur make-4.2.1/configure.ac make-4.2.1/configure.ac ----- make-4.2.1/configure.ac --+++ make-4.2.1/configure.ac --@@ -399,10 +399,9 @@ -- #include -- #include -- ---#define GLOB_INTERFACE_VERSION 1 -- #if !defined _LIBC && defined __GNU_LIBRARY__ && __GNU_LIBRARY__ > 1 -- # include ---# if _GNU_GLOB_INTERFACE_VERSION == GLOB_INTERFACE_VERSION --+# if _GNU_GLOB_INTERFACE_VERSION == 1 || _GNU_GLOB_INTERFACE_VERSION == 2 -- gnu glob -- # endif -- #endif], --- -2.17.1 - diff --git a/patches/coreboot-4.8.1/0058-util-crosgcc-Fix-most-shellcheck-errors-in-buildgcc.patch b/patches/coreboot-4.8.1/0058-util-crosgcc-Fix-most-shellcheck-errors-in-buildgcc.patch deleted file mode 100644 index 82c653b6e..000000000 --- a/patches/coreboot-4.8.1/0058-util-crosgcc-Fix-most-shellcheck-errors-in-buildgcc.patch +++ /dev/null @@ -1,826 +0,0 @@ -From 987d42da1de420cb28cb7f4f979cbb01511877d6 Mon Sep 17 00:00:00 2001 -From: Martin Roth -Date: Sun, 22 Jul 2018 11:45:29 -0600 -Subject: [PATCH 58/59] util/crosgcc: Fix most shellcheck errors in buildgcc - -This fixes most of the simpler shellcheck errors in shellcheck 0.4.6. - -There are still a few warnings left that weren't simple to fix or -would have required more testing before I was confident in them. - -Change-Id: I79ab3614cc1d69d3dfe1e0374e930313f2011cbf -Signed-off-by: Martin Roth -Reviewed-on: https://review.coreboot.org/27598 -Tested-by: build bot (Jenkins) -Reviewed-by: Patrick Georgi ---- - util/crossgcc/buildgcc | 298 ++++++++++++++++++++++++----------------- - 1 file changed, 172 insertions(+), 126 deletions(-) - -diff --git a/util/crossgcc/buildgcc b/util/crossgcc/buildgcc -index a9d90572cd..5823707acf 100755 ---- a/util/crossgcc/buildgcc -+++ b/util/crossgcc/buildgcc -@@ -1,4 +1,16 @@ - #!/bin/sh -+# shellcheck disable=SC2030,SC2031,SC2059 -+# The above line must be directly after the shebang line. -+# Disables these warnings: -+# 2030 - Modification of var is local (to subshell caused by pipeline). -+# shell check 0.4.6 gets confused by the read -t 1 command and interprets -+# the '1' as $1 getting modified. -+# 2031 - var was modified in a subshell. That change might be lost. -+# caused by shell check bug with SC2030? This causes any $1 from that -+# point on to be flagged. -+# 2059 - Don't use variables in the printf format string. Use printf "..%s.." "$foo". -+# This is used for all of our color printing. -+ - # - # Copyright (C) 2008-2010 by coresystems GmbH - # written by Patrick Georgi and -@@ -16,7 +28,7 @@ - # GNU General Public License for more details. - # - --cd $(dirname $0) -+cd "$(dirname "$0")" || exit 1 - - CROSSGCC_DATE="June 11th, 2018" - CROSSGCC_VERSION="1.52" -@@ -80,7 +92,9 @@ ALL_ARCHIVES="$GMP_ARCHIVE $MPFR_ARCHIVE $MPC_ARCHIVE \ - GMP_DIR="gmp-${GMP_VERSION}" - MPFR_DIR="mpfr-${MPFR_VERSION}" - MPC_DIR="mpc-${MPC_VERSION}" -+# shellcheck disable=SC2034 - GCC_DIR="gcc-${GCC_VERSION}" -+# shellcheck disable=SC2034 - BINUTILS_DIR="binutils-${BINUTILS_VERSION}" - GDB_DIR="gdb-${GDB_VERSION}" - IASL_DIR="acpica-unix2-${IASL_VERSION}" -@@ -101,51 +115,49 @@ RED='\033[1;31m' - green='\033[0;32m' - GREEN='\033[1;32m' - blue='\033[0;34m' --BLUE='\033[1;34m' --cyan='\033[0;36m' - CYAN='\033[1;36m' - NC='\033[0m' # No Color - --UNAME=$(uname | grep -iq cygwin && echo Cygwin || uname) -+UNAME=$(if uname | grep -iq cygwin; then echo Cygwin; else uname; fi) - HALT_FOR_TOOLS=0 - - hostcc() - { - # $1 "host" or "target" -- if [ "$BOOTSTRAP" = 1 -a "$1" = target ]; then -- echo $DESTDIR$TARGETDIR/bin/gcc -+ if [ "$BOOTSTRAP" = 1 ] && [ "$1" = target ]; then -+ echo "$DESTDIR$TARGETDIR/bin/gcc" - else -- echo $CC -+ echo "$CC" - fi - } - - hostcxx() - { - # $1 "host" or "target" -- if [ "$BOOTSTRAP" = 1 -a "$1" = target ]; then -- echo $DESTDIR$TARGETDIR/bin/g++ -+ if [ "$BOOTSTRAP" = 1 ] && [ "$1" = target ]; then -+ echo "$DESTDIR$TARGETDIR/bin/g++" - else -- echo $CXX -+ echo "$CXX" - fi - } - - normalize_dirs() - { -- mkdir -p $DESTDIR$TARGETDIR/lib -- test -d $DESTDIR$TARGETDIR/lib32 && mv $DESTDIR$TARGETDIR/lib32/* $DESTDIR$TARGETDIR/lib -- test -d $DESTDIR$TARGETDIR/lib64 && mv $DESTDIR$TARGETDIR/lib64/* $DESTDIR$TARGETDIR/lib -- rmdir -p $DESTDIR$TARGETDIR/lib32 $DESTDIR$TARGETDIR/lib64 -+ mkdir -p "$DESTDIR$TARGETDIR/lib" -+ test -d "$DESTDIR$TARGETDIR/lib32" && mv "$DESTDIR$TARGETDIR"/lib32/* "$DESTDIR$TARGETDIR/lib" -+ test -d "$DESTDIR$TARGETDIR/lib64" && mv "$DESTDIR$TARGETDIR"/lib64/* "$DESTDIR$TARGETDIR/lib" -+ rmdir -p "$DESTDIR$TARGETDIR/lib32" "$DESTDIR$TARGETDIR/lib64" - -- perl -pi -e "s,/lib32,/lib," $DESTDIR$TARGETDIR/lib/*.la -- perl -pi -e "s,/lib64,/lib," $DESTDIR$TARGETDIR/lib/*.la -+ perl -pi -e "s,/lib32,/lib," "$DESTDIR$TARGETDIR"/lib/*.la -+ perl -pi -e "s,/lib64,/lib," "$DESTDIR$TARGETDIR"/lib/*.la - } - - countdown() - { - tout=${1:-10} - -- printf "\nPress Ctrl-C to abort, Enter to continue... %2ds" $tout -- while [ $tout -gt 0 ]; do -+ printf "\nPress Ctrl-C to abort, Enter to continue... %2ds" "$tout" -+ while [ "$tout" -gt 0 ]; do - sleep 1 - tout=$((tout - 1)) - printf "\b\b\b%2ds" $tout -@@ -162,11 +174,12 @@ timeout() - # Clean up in case the user aborts. - trap 'kill $counter > /dev/null 2>&1' EXIT - -- (countdown $tout; kill -USR1 $$)& -+ (countdown "$tout"; kill -USR1 $$)& - counter=$! - - # Some shells with sh compatibility mode (e.g. zsh, mksh) only - # let us interrupt `read` if a non-standard -t parameter is given. -+ # shellcheck disable=SC2034,SC2039,SC2162 - if echo | read -t 1 foo 2>/dev/null; then - read -t $((tout + 1)) foo - else -@@ -180,6 +193,7 @@ timeout() - please_install() - { - HALT_FOR_TOOLS=1 -+ # shellcheck disable=SC1091 - test -r /etc/os-release && . /etc/os-release - # vanilla debian doesn't define `ID_LIKE`, just `ID` - if [ -z "${ID_LIKE}" ] && [ -n "${ID}" ]; then -@@ -210,59 +224,60 @@ searchtool() - search="$2" - fi - for i in "$1" "g$1" "gnu$1"; do -- if [ -x "$(command -v $i 2>/dev/null)" ]; then -+ if [ -x "$(command -v "$i" 2>/dev/null)" ]; then - if [ "$(cat /dev/null | $i --version 2>&1 | grep -c "$search")" \ - -gt 0 ]; then -- echo $i -+ echo "$i" - return - fi - fi - done - # A workaround for OSX 10.9 and some BSDs, whose nongnu - # patch and tar also work. -- if [ $UNAME = "Darwin" -o $UNAME = "FreeBSD" -o $UNAME = "NetBSD" -o $UNAME = "OpenBSD" ]; then -- if [ "$1" = "patch" -o "$1" = "tar" ]; then -- if [ -x "$(command -v $1 2>/dev/null)" ]; then -- echo $1 -+ if [ "$UNAME" = "Darwin" ] || [ "$UNAME" = "FreeBSD" ] || [ "$UNAME" = "NetBSD" ] || [ "$UNAME" = "OpenBSD" ]; then -+ if [ "$1" = "patch" ] || [ "$1" = "tar" ]; then -+ if [ -x "$(command -v "$1" 2>/dev/null)" ]; then -+ echo "$1" - return - fi - fi - fi -- if echo $1 | grep -q "sum" ; then -- algor=$(echo $1 | sed -e 's,sum,,') -- if [ -x "$(command -v $1 2>/dev/null)" ]; then -+ if echo "$1" | grep -q "sum" ; then -+ algor=$(echo "$1" | sed -e 's,sum,,') -+ if [ -x "$(command -v "$1" 2>/dev/null)" ]; then - #xxxsum [file] -- echo $1 -+ echo "$1" - return -- elif [ -x "$(command -v $algor 2>/dev/null)" ]; then -+ elif [ -x "$(command -v "$algor" 2>/dev/null)" ]; then - #xxx [file] -- echo $algor -+ echo "$algor" - return - elif [ -x "$(command -v openssl 2>/dev/null)" ]; then - #openssl xxx [file] -- echo openssl $algor -+ echo openssl "$algor" - return - elif [ -x "$(command -v cksum 2>/dev/null)" ]; then - #cksum -a xxx [file] - #cksum has special options in NetBSD. Actually, NetBSD will use the second case above. -- echo "buildgcc" | cksum -a $algor > /dev/null 2>/dev/null && \ -- echo cksum -a $algor -+ echo "buildgcc" | cksum -a "$algor" > /dev/null 2>/dev/null && \ -+ echo cksum -a "$algor" - return - fi - fi - -- [ -z "$3" ] && please_install $1 $4 -+ [ -z "$3" ] && please_install "$1" "$4" - false - } - - # Run a compile check of the specified library option to see if it's installed - check_for_library() { -- local LIBRARY_FLAGS=$1 -- local LIBRARY_PACKAGES="$2" -- local LIBTEST_FILE=.libtest -+ LIBRARY_FLAGS="$1" -+ LIBRARY_PACKAGES="$2" -+ LIBTEST_FILE=.libtest - - echo "int main(int argc, char **argv) { (void) argc; (void) argv; return 0; }" > "${LIBTEST_FILE}.c" - -+ # shellcheck disable=SC2086 - "$CC" $CFLAGS $LIBRARY_FLAGS "${LIBTEST_FILE}.c" -o "${LIBTEST_FILE}" >/dev/null 2>&1 || \ - please_install "$LIBRARY_PACKAGES" - rm -rf "${LIBTEST_FILE}.c" "${LIBTEST_FILE}" -@@ -307,22 +322,23 @@ ada_requested() { - - download() { - package=$1 -+ # shellcheck disable=SC2086 - archive="$(eval echo \$$package"_ARCHIVE")" - -- FILE=$(basename $archive) -+ FILE=$(basename "$archive") - printf " * $FILE " - -- if test -f tarballs/$FILE; then -+ if test -f "tarballs/$FILE"; then - printf "(cached)... " - else - printf "(downloading from $archive)" -- rm -f tarballs/$FILE -- cd tarballs -- download_showing_percentage $archive -+ rm -f "tarballs/$FILE" -+ cd tarballs || exit 1 -+ download_showing_percentage "$archive" - cd .. - fi - -- if [ ! -f tarballs/$FILE ]; then -+ if [ ! -f "tarballs/$FILE" ]; then - printf "${RED}Failed to download $FILE.${NC}\n" - exit 1 - fi -@@ -332,6 +348,7 @@ download() { - # hexadecimal hash). - compute_hash() { - package=$1 -+ # shellcheck disable=SC2086 - archive="$(eval echo \$$package"_ARCHIVE")" - file="$(basename "$archive")" - -@@ -345,6 +362,7 @@ compute_hash() { - - error_hash_missing() { - package="$1" -+ # shellcheck disable=SC2086 - archive="$(eval echo \$$package"_ARCHIVE")" - file="$(basename "$archive")" - -@@ -361,6 +379,7 @@ error_hash_missing() { - # Read the known hash file of the package given in $1, and print it raw. - get_known_hash() { - package=$1 -+ # shellcheck disable=SC2086 - archive="$(eval echo \$$package"_ARCHIVE")" - file="$(basename "$archive")" - hashfile="sum/$file.cksum" -@@ -373,13 +392,14 @@ get_known_hash() { - exit 1 - fi - -- cat "$hashfile" | sed -e 's@.*\([0-9a-f]\{40,\}\).*@\1@' -+ sed -e 's@.*\([0-9a-f]\{40,\}\).*@\1@' < "$hashfile" - } - - error_hash_mismatch() { - package=$1 - known_hash="$2" - computed_hash="$3" -+ # shellcheck disable=SC2086 - archive="$(eval echo \$$package"_ARCHIVE")" - file="$(basename "$archive")" - -@@ -400,6 +420,7 @@ error_hash_mismatch() { - # hash; Bail out on mismatch or missing hash file. - verify_hash() { - package=$1 -+ # shellcheck disable=SC2086 - archive="$(eval echo \$$package"_ARCHIVE")" - - known_hash="$(get_known_hash "$package")" || exit "$?" -@@ -410,17 +431,19 @@ verify_hash() { - exit 1 - fi - -- printf "${GREEN}hash verified ("$known_hash")${NC}\n" -+ printf "${GREEN}hash verified (\"$known_hash\")${NC}\n" - } - - unpack_and_patch() { -- package=$1 -+ package="$1" -+ # shellcheck disable=SC2086 - archive="$(eval echo \$$package"_ARCHIVE")" -+ # shellcheck disable=SC2086 - dir="$(eval echo \$$package"_DIR")" -- test -d ${dir} && test -f ${dir}/.unpack_success || ( -- printf " * $(basename $archive)\n" -+ test -d "${dir}" && test -f "${dir}/.unpack_success" || ( -+ printf " * $(basename "$archive")\n" - FLAGS=zxf -- suffix=$(echo $archive | sed 's,.*\.,,') -+ suffix=$(echo "$archive" | sed 's,.*\.,,') - if [ "$suffix" = "gz" ] && [ -n "$PIGZ" ]; then FLAGS="-I pigz -xf" - elif [ "$suffix" = "gz" ]; then FLAGS=zxf - elif [ "$suffix" = "bz2" ] && [ -n "$LBZIP2" ]; then FLAGS="-I lbzip2 -xf" -@@ -428,22 +451,24 @@ unpack_and_patch() { - elif [ "$suffix" = "xz" ]; then FLAGS="--xz -xf" - elif [ "$suffix" = "lzma" ]; then FLAGS="--lzma -xf" - fi -- $TAR $FLAGS tarballs/$(basename $archive) -+ # shellcheck disable=SC2086 -+ $TAR $FLAGS "tarballs/$(basename "$archive")" - for patch in patches/${dir}_*.patch; do -- test -r $patch || continue -- printf " o $(basename $patch)\n" -- (cd ${dir} && $PATCH -s -N -p1 <../${patch}) || { -+ test -r "$patch" || continue -+ printf " o $(basename "$patch")\n" -+ (cd "${dir}" || exit 1; $PATCH -s -N -p1 <"../${patch}") || { - printf "\n${RED}Failed $patch.${NC}\n" - exit 1 - } - done -- touch ${dir}/.unpack_success -+ touch "${dir}/.unpack_success" - ) - } - - fn_exists() - { -- type $1 >/dev/null 2>&1 -+ # shellcheck disable=SC2039 -+ type "$1" >/dev/null 2>&1 - } - - is_package_enabled() -@@ -468,7 +493,7 @@ generic_build() - success=$4 - version=$5 - -- fn_exists build_$package || return -+ fn_exists "build_$package" || return - - mkdir -p "$builddir" - -@@ -477,10 +502,10 @@ generic_build() - else - printf "Building $package v$version for $host_target ... " - DIR="$PWD" -- cd "$builddir" -+ cd "$builddir" || exit 1 - rm -f .failed -- build_${package} $host_target > build.log 2>&1 -- cd "$DIR" -+ "build_${package}" "$host_target" > build.log 2>&1 -+ cd "$DIR" || exit 1 - if [ ! -f "$builddir/.failed" ]; then - touch "$success"; - else -@@ -494,6 +519,7 @@ generic_build() - build_for_host() - { - package="$1" -+ # shellcheck disable=SC2086 - version="$(eval echo \$$package"_VERSION")" - generic_build "$package" host "build-$package" "${DESTDIR}${TARGETDIR}/.${package}.${version}.success" "$version" - } -@@ -501,19 +527,20 @@ build_for_host() - build_for_target() - { - package="$1" -+ # shellcheck disable=SC2086 - version="$(eval echo \$$package"_VERSION")" - generic_build "$package" target "build-${TARGETARCH}-$package" "${DESTDIR}${TARGETDIR}/.${TARGETARCH}-${package}.${version}.success" "$version" - } - - build() - { -- if package_uses_targetarch $1; then -- if [ $BOOTSTRAP -eq 1 -a ! -f "${DESTDIR}${TARGETDIR}/.GCC.${GCC_VERSION}.success" ]; then -+ if package_uses_targetarch "$1"; then -+ if [ $BOOTSTRAP -eq 1 ] && [ ! -f "${DESTDIR}${TARGETDIR}/.GCC.${GCC_VERSION}.success" ]; then - build_for_host GCC - fi -- build_for_target $1 -+ build_for_target "$1" - else -- build_for_host $1 -+ build_for_host "$1" - fi - } - -@@ -532,7 +559,8 @@ cleanup() - - printf "Cleaning up temporary files... " - for package in $PACKAGES; do -- rm -rf build-${TARGETARCH}-$package build-$package $(eval echo \$$package"_DIR") -+ # shellcheck disable=SC2086 -+ rm -rf "build-${TARGETARCH}-$package" "build-$package" "$(eval echo \$$package"_DIR")" - done - rm -f getopt - printf "${green}ok${NC}\n" -@@ -601,14 +629,15 @@ EOF - } - - have_hostcflags_from_gmp() { -- grep -q __GMP_CFLAGS $DESTDIR$TARGETDIR/include/gmp.h >/dev/null 2>&1 -+ grep -q __GMP_CFLAGS "$DESTDIR$TARGETDIR/include/gmp.h" >/dev/null 2>&1 - } - - set_hostcflags_from_gmp() { - # Now set CFLAGS to match GMP CFLAGS but strip out -pedantic - # as GCC 4.6.x fails if it's there. -- export HOSTCFLAGS="$(grep __GMP_CFLAGS $DESTDIR$TARGETDIR/include/gmp.h |cut -d\" -f2 |\ -+ HOSTCFLAGS="$(grep __GMP_CFLAGS "$DESTDIR$TARGETDIR/include/gmp.h" |cut -d\" -f2 |\ - sed s,-pedantic,,)" -+ export HOSTCFLAGS - } - - build_GMP() { -@@ -619,10 +648,12 @@ build_GMP() { - OPTIONS="$OPTIONS --with-pic" - fi - -+ # shellcheck disable=SC2086 - CC="$(hostcc host)" CXX="$(hostcxx host)" \ - ../${GMP_DIR}/configure --disable-shared --enable-fat \ -- --prefix=$TARGETDIR $OPTIONS \ -+ --prefix="$TARGETDIR" $OPTIONS \ - || touch .failed -+ # shellcheck disable=SC2086 - $MAKE $JOBS || touch .failed - $MAKE install DESTDIR=$DESTDIR || touch .failed - -@@ -632,12 +663,13 @@ build_GMP() { - } - - build_MPFR() { -- test $UNAME = "Darwin" && CFLAGS="$CFLAGS -force_cpusubtype_ALL" -+ test "$UNAME" = "Darwin" && CFLAGS="$CFLAGS -force_cpusubtype_ALL" - CC="$(hostcc host)" CXX="$(hostcxx host)" \ -- ../${MPFR_DIR}/configure --disable-shared --prefix=$TARGETDIR \ -- --infodir=$TARGETDIR/info \ -- --with-gmp=$DESTDIR$TARGETDIR CFLAGS="$HOSTCFLAGS" || \ -+ ../${MPFR_DIR}/configure --disable-shared --prefix="$TARGETDIR" \ -+ --infodir="$TARGETDIR/info" \ -+ --with-gmp="$DESTDIR$TARGETDIR" CFLAGS="$HOSTCFLAGS" || \ - touch .failed -+ # shellcheck disable=SC2086 - $MAKE $JOBS || touch .failed - $MAKE install DESTDIR=$DESTDIR || touch .failed - -@@ -645,28 +677,29 @@ build_MPFR() { - - # work around build problem of libgmp.la - if [ "$DESTDIR" != "" ]; then -- perl -pi -e "s,$DESTDIR,," $DESTDIR$TARGETDIR/lib/libgmp.la -+ perl -pi -e "s,$DESTDIR,," "$DESTDIR$TARGETDIR/lib/libgmp.la" - fi - } - - build_MPC() { - CC="$(hostcc host)" CXX="$(hostcxx host)" \ -- ../${MPC_DIR}/configure --disable-shared --prefix=$TARGETDIR \ -- --infodir=$TARGETDIR/info --with-mpfr=$DESTDIR$TARGETDIR \ -- --with-gmp=$DESTDIR$TARGETDIR CFLAGS="$HOSTCFLAGS" || \ -+ ../${MPC_DIR}/configure --disable-shared --prefix="$TARGETDIR" \ -+ --infodir="$TARGETDIR/info" --with-mpfr="$DESTDIR$TARGETDIR" \ -+ --with-gmp="$DESTDIR$TARGETDIR" CFLAGS="$HOSTCFLAGS" || \ - touch .failed - - # work around build problem of libmpfr.la - if [ "$DESTDIR" != "" ]; then -- perl -pi -e "s,$TARGETDIR/lib/libgmp.la,$DESTDIR\$&," $DESTDIR$TARGETDIR/lib/libmpfr.la -+ perl -pi -e "s,$TARGETDIR/lib/libgmp.la,$DESTDIR\$&," "$DESTDIR$TARGETDIR/lib/libmpfr.la" - fi - -+ # shellcheck disable=SC2086 - $MAKE $JOBS || touch .failed - $MAKE install DESTDIR=$DESTDIR || touch .failed - - # work around build problem of libmpfr.la - if [ "$DESTDIR" != "" ]; then -- perl -pi -e "s,$DESTDIR,," $DESTDIR$TARGETDIR/lib/libmpfr.la -+ perl -pi -e "s,$DESTDIR,," "$DESTDIR$TARGETDIR/lib/libmpfr.la" - fi - - normalize_dirs -@@ -677,7 +710,7 @@ build_BINUTILS() { - ADDITIONALTARGET=",i386-elf" - fi - CC="$(hostcc target)" CXX="$(hostcxx target)" \ -- ../binutils-${BINUTILS_VERSION}/configure --prefix=$TARGETDIR \ -+ ../binutils-${BINUTILS_VERSION}/configure --prefix="$TARGETDIR" \ - --target=${TARGETARCH} --enable-targets=${TARGETARCH}${ADDITIONALTARGET} \ - --disable-werror --disable-nls --enable-lto --enable-gold \ - --enable-interwork --enable-multilib \ -@@ -685,11 +718,13 @@ build_BINUTILS() { - CFLAGS="$HOSTCFLAGS" \ - CXXFLAGS="$HOSTCFLAGS" \ - || touch .failed -+ # shellcheck disable=SC2086 - $MAKE $JOBS || touch .failed - $MAKE install DESTDIR=$DESTDIR || touch .failed - } - - bootstrap_GCC() { -+ # shellcheck disable=SC2086 - CC="$(hostcc host)" CXX="$(hostcxx host)" \ - CFLAGS="$HOSTCFLAGS" \ - CFLAGS_FOR_BUILD="$HOSTCFLAGS" \ -@@ -698,17 +733,18 @@ bootstrap_GCC() { - CXXFLAGS_FOR_BUILD="$HOSTCFLAGS" \ - CXXFLAGS_FOR_TARGET="$HOSTCFLAGS -fPIC" \ - ../gcc-${GCC_VERSION}/configure \ -- --prefix=$TARGETDIR --libexecdir=$TARGETDIR/lib \ -+ --prefix="$TARGETDIR" --libexecdir="$TARGETDIR/lib" \ - --enable-bootstrap \ - --disable-werror --disable-nls \ - --disable-shared --disable-multilib \ - --disable-libssp --disable-libquadmath --disable-libcc1 \ - --disable-libsanitizer \ - ${GCC_OPTIONS} --enable-languages="${LANGUAGES}" \ -- --with-gmp=$DESTDIR$TARGETDIR --with-mpfr=$DESTDIR$TARGETDIR \ -- --with-mpc=$DESTDIR$TARGETDIR \ -+ --with-gmp="$DESTDIR$TARGETDIR" --with-mpfr="$DESTDIR$TARGETDIR" \ -+ --with-mpc="$DESTDIR$TARGETDIR" \ - --with-pkgversion="coreboot bootstrap v$CROSSGCC_VERSION $CROSSGCC_DATE" \ - && \ -+ # shellcheck disable=SC2086 - $MAKE $JOBS BOOT_CFLAGS="$HOSTCFLAGS" BUILD_CONFIG="" bootstrap && \ - $MAKE install-gcc \ - install-target-libgcc \ -@@ -731,6 +767,7 @@ build_cross_GCC() { - # libiberty is not compiled with CFLAGS_FOR_BUILD. - # Also set the CXX version of the flags because GCC is now compiled - # using C++. -+ # shellcheck disable=SC2086 - CC="$(hostcc target)" CXX="$(hostcxx target)" \ - CFLAGS_FOR_TARGET="-O2 -Dinhibit_libc" \ - CFLAGS="$HOSTCFLAGS $CLANGFLAGS" \ -@@ -738,7 +775,7 @@ build_cross_GCC() { - CXXFLAGS="$HOSTCFLAGS $CLANGCXXFLAGS" \ - CXXFLAGS_FOR_BUILD="$HOSTCFLAGS $CLANGCXXFLAGS" \ - ../gcc-${GCC_VERSION}/configure \ -- --prefix=$TARGETDIR --libexecdir=$TARGETDIR/lib \ -+ --prefix="$TARGETDIR" --libexecdir="$TARGETDIR/lib" \ - --target=${TARGETARCH} --disable-werror --disable-shared \ - --enable-lto --enable-plugins --enable-gold --enable-ld=default \ - --disable-libssp --disable-bootstrap --disable-nls \ -@@ -748,16 +785,17 @@ build_cross_GCC() { - --disable-libatomic --disable-libcc1 --disable-decimal-float \ - ${GCC_OPTIONS} --enable-languages="${LANGUAGES}" \ - --with-system-zlib \ -- --with-gmp=$DESTDIR$TARGETDIR --with-mpfr=$DESTDIR$TARGETDIR \ -- --with-mpc=$DESTDIR$TARGETDIR \ -+ --with-gmp="$DESTDIR$TARGETDIR" --with-mpfr="$DESTDIR$TARGETDIR" \ -+ --with-mpc="$DESTDIR$TARGETDIR" \ - --with-pkgversion="coreboot toolchain v$CROSSGCC_VERSION $CROSSGCC_DATE" \ - && \ - mkdir -p gcc/$TARGETARCH && \ -- ln -s $DESTDIR$TARGETDIR/$TARGETARCH/bin gcc/$TARGETARCH/$GCC_VERSION && \ -+ ln -s "$DESTDIR$TARGETDIR/$TARGETARCH/bin" "gcc/$TARGETARCH/$GCC_VERSION" && \ - $MAKE $JOBS CFLAGS_FOR_BUILD="$HOSTCFLAGS" all-gcc && \ -- $MAKE install-gcc DESTDIR=$DESTDIR || touch .failed -+ $MAKE install-gcc DESTDIR="$DESTDIR" || touch .failed - -- if [ ! -f .failed -a "$(echo $TARGETARCH | grep -c -- -mingw32)" -eq 0 ]; then -+ if [ ! -f .failed ] && [ "$(echo $TARGETARCH | grep -c -- -mingw32)" -eq 0 ]; then -+ # shellcheck disable=SC2086 - $MAKE $JOBS CFLAGS_FOR_BUILD="$HOSTCFLAGS" all-target-libgcc && \ - $MAKE install-target-libgcc DESTDIR=$DESTDIR || touch .failed - fi -@@ -765,15 +803,15 @@ build_cross_GCC() { - - build_GCC() { - if [ "$1" = host ]; then -- bootstrap_GCC $1 -+ bootstrap_GCC "$1" - else -- build_cross_GCC $1 -+ build_cross_GCC "$1" - fi - } - - build_EXPAT() { - CC="$(hostcc host)" CXX="$(hostcxx host)" CFLAGS="$HOSTCFLAGS" -- ../${EXPAT_DIR}/configure --disable-shared --prefix=$TARGETDIR \ -+ ../${EXPAT_DIR}/configure --disable-shared --prefix="$TARGETDIR" \ - || touch .failed - $MAKE || touch .failed - $MAKE install DESTDIR=$DESTDIR || touch .failed -@@ -783,8 +821,9 @@ build_EXPAT() { - - build_PYTHON() { - CC="$(hostcc host)" CXX="$(hostcxx host)" CFLAGS="$HOSTCFLAGS" -- ../${PYTHON_DIR}/configure --prefix=$TARGETDIR \ -+ ../${PYTHON_DIR}/configure --prefix="$TARGETDIR" \ - || touch .failed -+ # shellcheck disable=SC2086 - $MAKE $JOBS || touch .failed - $MAKE install DESTDIR=$DESTDIR || touch .failed - -@@ -793,62 +832,66 @@ build_PYTHON() { - - build_GDB() { - export PYTHONHOME=$DESTDIR$TARGETDIR -- if [ $(uname) != "FreeBSD" -a $(uname) != "NetBSD" ]; then -+ if [ "$UNAME" != "FreeBSD" ] && [ "$UNAME" != "NetBSD" ]; then - LIBDL="-ldl" - fi - LDFLAGS="-Wl,-rpath,\$\$ORIGIN/../lib/ -L$DESTDIR$TARGETDIR/lib \ - -lpthread $LIBDL -lutil" \ - CC="$(hostcc target)" CXX="$(hostcxx target)" \ - CFLAGS="$HOSTCFLAGS -I$DESTDIR$TARGETDIR/include" \ -- ../${GDB_DIR}/configure --prefix=$TARGETDIR \ -+ ../${GDB_DIR}/configure --prefix="$TARGETDIR" \ - --target=${TARGETARCH} --disable-werror --disable-nls -+ # shellcheck disable=SC2086 - $MAKE $JOBS || touch .failed - $MAKE install DESTDIR=$DESTDIR || touch .failed - } - - build_IASL() { - RDIR=$PWD -- cd ../$IASL_DIR/generate/unix -+ cd ../$IASL_DIR/generate/unix || exit 1 - CFLAGS="$HOSTCFLAGS" - HOST="_LINUX" -- test $UNAME = "Darwin" && HOST="_APPLE" -- test $UNAME = "FreeBSD" && HOST="_FreeBSD" -- test $UNAME = "Cygwin" && HOST="_CYGWIN" -+ test "$UNAME" = "Darwin" && HOST="_APPLE" -+ test "$UNAME" = "FreeBSD" && HOST="_FreeBSD" -+ test "$UNAME" = "Cygwin" && HOST="_CYGWIN" - HOST="$HOST" CFLAGS="$CFLAGS" \ - OPT_CFLAGS="-O -D_FORTIFY_SOURCE=2 -D COREBOOT_TOOLCHAIN_VERSION='\"coreboot toolchain v$CROSSGCC_VERSION $CROSSGCC_DATE\"' " \ -- $MAKE CC="$(hostcc host)" iasl || touch $RDIR/.failed -- rm -f $DESTDIR$TARGETDIR/bin/iasl || touch $RDIR/.failed -- cp bin/iasl $DESTDIR$TARGETDIR/bin || touch $RDIR/.failed -+ $MAKE CC="$(hostcc host)" iasl || touch "$RDIR/.failed" -+ rm -f "$DESTDIR$TARGETDIR/bin/iasl" || touch "$RDIR/.failed" -+ cp bin/iasl "$DESTDIR$TARGETDIR/bin" || touch "$RDIR/.failed" - } - - build_LLVM() { -- cd .. -- ln -sf $PWD/$CFE_DIR $LLVM_DIR/tools/clang -- ln -sf $PWD/$CTE_DIR $LLVM_DIR/tools/clang/tools/extra -- ln -sf $PWD/$CRT_DIR $LLVM_DIR/projects/compiler-rt -- cd - - -- $CMAKE -G "Unix Makefiles" -DCMAKE_INSTALL_PREFIX=$DESTDIR$TARGETDIR \ -+ cd .. || exit 1 -+ ln -sf "$PWD/$CFE_DIR" "$LLVM_DIR/tools/clang" -+ ln -sf "$PWD/$CTE_DIR" "$LLVM_DIR/tools/clang/tools/extra" -+ ln -sf "$PWD/$CRT_DIR" "$LLVM_DIR/projects/compiler-rt" -+ cd - || exit 1 -+ -+ $CMAKE -G "Unix Makefiles" -DCMAKE_INSTALL_PREFIX="$DESTDIR$TARGETDIR" \ - -DCLANG_VENDOR="coreboot toolchain v$CROSSGCC_VERSION $CROSSGCC_DATE - " \ - -DCMAKE_BUILD_TYPE=Release ../$LLVM_DIR || touch .failed -+ # shellcheck disable=SC2086 - $MAKE $JOBS || touch .failed - $MAKE install || touch .failed - -- cp -a ../$CFE_DIR/tools/scan-build/* $DESTDIR$TARGETDIR/bin -- cp -a ../$CFE_DIR/tools/scan-view/* $DESTDIR$TARGETDIR/bin -+ cp -a ../$CFE_DIR/tools/scan-build/* "$DESTDIR$TARGETDIR/bin" -+ cp -a ../$CFE_DIR/tools/scan-view/* "$DESTDIR$TARGETDIR/bin" - - # create symlinks to work around broken --print-librt-file-name - # when used with -target. -- cd $DESTDIR$TARGETDIR/lib/clang/${CLANG_VERSION}/lib -+ cd "$DESTDIR$TARGETDIR/lib/clang/${CLANG_VERSION}/lib" || exit 1 - for i in */libclang_rt.builtins*.a; do -- ln -s $i . -+ ln -s "$i" . - done - } - - build_MAKE() { - CC="$(hostcc host)" CXX="$(hostcxx host)" CFLAGS="$HOSTCFLAGS" \ -- ../${MAKE_DIR}/configure --prefix=$TARGETDIR --disable-nls \ -+ ../${MAKE_DIR}/configure --prefix="$TARGETDIR" --disable-nls \ - || touch .failed -+ # shellcheck disable=SC2086 - $MAKE $JOBS || touch .failed - $MAKE install DESTDIR=$DESTDIR || touch .failed - -@@ -857,8 +900,9 @@ build_MAKE() { - - build_CMAKE() { - CC="$(hostcc host)" CXX="$(hostcxx host)" CFLAGS="$HOSTCFLAGS" \ -- ../${CMAKE_DIR}/configure --prefix=$TARGETDIR \ -+ ../${CMAKE_DIR}/configure --prefix="$TARGETDIR" \ - || touch .failed -+ # shellcheck disable=SC2086 - $MAKE $JOBS || touch .failed - $MAKE install DESTDIR=$DESTDIR || touch .failed - -@@ -900,6 +944,7 @@ else - # Detected non-GNU getopt - args=$(getopt Vhcd:bBp:l:P:j:D:tSys:un $*) - getopt_ret=$? -+ # shellcheck disable=SC2086 - set -- $args - fi - -@@ -1026,8 +1071,8 @@ if searchtool wget "GNU" nofail > /dev/null; then - download_showing_percentage() { - url=$1 - printf "... ${red} 0%%" -- wget $url 2>&1 | while read line; do -- echo $line | grep -o "[0-9]\+%" | awk '{printf("\b\b\b\b%4s", $1)}' -+ wget "$url" 2>&1 | while read -r line; do -+ echo "$line" | grep -o "[0-9]\+%" | awk '{printf("\b\b\b\b%4s", $1)}' - done - printf "${NC}... " - } -@@ -1035,7 +1080,7 @@ elif searchtool curl "^curl " > /dev/null; then - download_showing_percentage() { - url=$1 - echo -- curl -#OL $url -+ curl -#OL "$url" - } - fi - -@@ -1089,7 +1134,7 @@ if is_package_enabled "GCC"; then - # sane preset: let the configure script figure out things by itself - # more importantly, avoid any values that might already linger in the variable - OPTIONS="ABI=" --if [ $UNAME = "Darwin" ]; then -+if [ "$UNAME" = "Darwin" ]; then - #GCC_OPTIONS="$GCC_OPTIONS --enable-threads=posix" - - # generally the OS X compiler can create x64 binaries. -@@ -1097,7 +1142,7 @@ if [ $UNAME = "Darwin" ]; then - # binaries in 10.6 (even if the kernel is 32bit) - # For some weird reason, 10.5 autodetects an ABI=64 though - # so we're setting the ABI explicitly here. -- if [ $(sysctl -n hw.optional.x86_64 2>/dev/null) -eq 1 ] 2>/dev/null; then -+ if [ "$(sysctl -n hw.optional.x86_64 2>/dev/null)" -eq 1 ] 2>/dev/null; then - OPTIONS="ABI=64" - else - OPTIONS="ABI=32" -@@ -1109,13 +1154,13 @@ if [ $UNAME = "Darwin" ]; then - if $CC -v 2>&1 | grep -q LLVM; then - CC=llvm-gcc - fi --elif [ $UNAME = "Linux" -o $UNAME = "Cygwin" ]; then -+elif [ "$UNAME" = "Linux" ] || [ "$UNAME" = "Cygwin" ]; then - # gmp is overeager with detecting 64bit CPUs even if they run - # a 32bit kernel and userland. - if [ "$(uname -m 2>/dev/null)" = "i686" ]; then - OPTIONS="ABI=32" - fi --elif [ $UNAME = "NetBSD" ]; then -+elif [ "$UNAME" = "NetBSD" ]; then - # same for NetBSD but this one reports an i386 - if [ "$(uname -m 2>/dev/null)" = "i386" ]; then - OPTIONS="ABI=32" -@@ -1149,9 +1194,10 @@ if [ -z "${LANGUAGES}" ]; then - fi - if ada_requested; then - if have_gnat; then -- if [ "$BOOTSTRAP" != 1 -a \ -- \( "$(hostcc_major)" -lt 4 -o \ -- \( "$(hostcc_major)" -eq 4 -a "$(hostcc_minor)" -lt 9 \) \) ] -+ if [ "$BOOTSTRAP" != 1 ] && \ -+ \( [ "$(hostcc_major)" -lt 4 ] || \ -+ \( [ "$(hostcc_major)" -eq 4 ] && \ -+ [ "$(hostcc_minor)" -lt 9 ] \) \) ] - then - printf "\n${red}WARNING${NC}\n" - printf "Building the Ada compiler (GNAT $(buildcc_version)) with a host compiler older\n" -@@ -1167,7 +1213,7 @@ if ada_requested; then - exit 1 - fi - else -- if [ "$(hostcc_major)" -lt 4 -a "$BOOTSTRAP" != 1 ]; then -+ if [ "$(hostcc_major)" -lt 4 ] && [ "$BOOTSTRAP" != 1 ]; then - printf "\n${red}WARNING${NC}\n" - printf "Building GCC $(buildcc_version) with a very old host compiler ($(hostcc_version)).\n" - printf "Bootstrapping (-b) is recommended.\n" -@@ -1187,8 +1233,8 @@ fi - - # Prepare target directory for building GCC - # (dependencies must be in the PATH) --mkdir -p $DESTDIR$TARGETDIR/bin --mkdir -p $DESTDIR$TARGETDIR/share -+mkdir -p "$DESTDIR$TARGETDIR/bin" -+mkdir -p "$DESTDIR$TARGETDIR/share" - export PATH=$DESTDIR$TARGETDIR/bin:$PATH - - # Download, unpack, patch and build all packages --- -2.17.1 - diff --git a/patches/coreboot-4.8.1/0059-util-Add-description.md-to-each-util.patch b/patches/coreboot-4.8.1/0059-util-Add-description.md-to-each-util.patch deleted file mode 100644 index 608b6b68a..000000000 --- a/patches/coreboot-4.8.1/0059-util-Add-description.md-to-each-util.patch +++ /dev/null @@ -1,29 +0,0 @@ -From 8ba9e8cf63f92902cdb71eb5c4d3b3ea579380f4 Mon Sep 17 00:00:00 2001 -From: Tom Hiller -Date: Sat, 21 Jul 2018 00:14:00 -0400 -Subject: [PATCH 59/59] util: Add description.md to each util - -Descriptions are taken from the files themselves or READMEs. Description -followed by a space with the language in marked up as code. - -Change-Id: I5f91e85d1034736289aedf27de00df00db3ff19c -Signed-off-by: Tom Hiller -Reviewed-on: https://review.coreboot.org/27563 -Tested-by: build bot (Jenkins) -Reviewed-by: Philipp Deppenwiese -Reviewed-by: Paul Menzel ---- - util/crossgcc/description.md | 1 + - 1 file changed, 1 insertion(+) - create mode 100644 util/crossgcc/description.md - -diff --git a/util/crossgcc/description.md b/util/crossgcc/description.md -new file mode 100644 -index 0000000000..fa37c2b6ab ---- /dev/null -+++ b/util/crossgcc/description.md -@@ -0,0 +1 @@ -+A cross toolchain builder for -elf toolchains (ie. no libc support) --- -2.17.1 - diff --git a/patches/coreboot-4.8.1/0000-measuredboot.patch b/patches/coreboot-4.9/0000-measuredboot.patch similarity index 61% rename from patches/coreboot-4.8.1/0000-measuredboot.patch rename to patches/coreboot-4.9/0000-measuredboot.patch index 7731a5aef..a74bafbdf 100644 --- a/patches/coreboot-4.8.1/0000-measuredboot.patch +++ b/patches/coreboot-4.9/0000-measuredboot.patch @@ -1,15 +1,15 @@ -diff --git ./src/Kconfig ./src/Kconfig -index 99a704d..004b4a7 100644 ---- ./src/Kconfig -+++ ./src/Kconfig -@@ -260,6 +260,21 @@ config BOOTSPLASH_FILE +diff --git a/src/Kconfig b/src/Kconfig +index 62a7a92368..62c72b4389 100644 +--- a/src/Kconfig ++++ b/src/Kconfig +@@ -278,6 +278,21 @@ config BOOTSPLASH_FILE The path and filename of the file to use as graphical bootsplash screen. The file format has to be jpg. +config MEASURED_BOOT + bool "Enable TPM measured boot" + default n -+ select TPM ++ select TPM1 + depends on MAINBOARD_HAS_LPC_TPM + depends on !VBOOT + help @@ -24,63 +24,10 @@ index 99a704d..004b4a7 100644 endmenu menu "Mainboard" -diff --git ./src/drivers/pc80/tpm/romstage.c ./src/drivers/pc80/tpm/romstage.c -index b8e4705..7732e66 100644 ---- ./src/drivers/pc80/tpm/romstage.c -+++ ./src/drivers/pc80/tpm/romstage.c -@@ -48,6 +48,12 @@ static const struct { - - static const struct { - u8 buffer[12]; -+} tpm2_startup_cmd = { -+ {0x80, 0x01, 0x0, 0x0, 0x0, 0xc, 0x0, 0x0, 0x01, 0x44, 0x0, 0x0 } -+}; -+ -+static const struct { -+ u8 buffer[12]; - } tpm_deactivate_cmd = { - {0x0, 0xc1, 0x0, 0x0, 0x0, 0xc, 0x0, 0x0, 0x0, 0x99, 0x0, 0x3 } - }; -@@ -229,9 +235,15 @@ void init_tpm(int s3resume) - return; - } - } else { -- printk(BIOS_SPEW, "TPM: Startup\n"); -- result = TlclSendReceive(tpm_startup_cmd.buffer, -- response, sizeof(response)); -+ if (IS_ENABLED(CONFIG_TPM2)) { -+ printk(BIOS_SPEW, "TPM2: Startup\n"); -+ result = TlclSendReceive(tpm2_startup_cmd.buffer, -+ response, sizeof(response)); -+ } else { -+ printk(BIOS_SPEW, "TPM: Startup\n"); -+ result = TlclSendReceive(tpm_startup_cmd.buffer, -+ response, sizeof(response)); -+ } - } - - tis_close(); -diff --git ./src/drivers/pc80/tpm/tis.c ./src/drivers/pc80/tpm/tis.c -index 3549173..11fc027 100644 ---- ./src/drivers/pc80/tpm/tis.c -+++ ./src/drivers/pc80/tpm/tis.c -@@ -125,10 +125,11 @@ static const struct device_name atmel_devices[] = { - - static const struct device_name infineon_devices[] = { - {0x000b, "SLB9635 TT 1.2"}, -- {0x001a, "SLB9660 TT 1.2"}, - #if IS_ENABLED(CONFIG_TPM2) -+ {0x001a, "SLB9665 TT 2.0"}, - {0x001b, "SLB9670 TT 2.0"}, - #else -+ {0x001a, "SLB9660 TT 1.2"}, - {0x001b, "SLB9670 TT 1.2"}, - #endif - {0xffff} -diff --git ./src/include/program_loading.h ./src/include/program_loading.h -index 7aba302..879c26e 100644 ---- ./src/include/program_loading.h -+++ ./src/include/program_loading.h +diff --git a/src/include/program_loading.h b/src/include/program_loading.h +index 468f0b35a6..c928111290 100644 +--- a/src/include/program_loading.h ++++ b/src/include/program_loading.h @@ -24,6 +24,8 @@ enum { /* Last segment of program. Can be used to take different actions for * cache maintenance of a program load. */ @@ -89,17 +36,17 @@ index 7aba302..879c26e 100644 + SEG_NO_MEASURE = 1 << 1, }; - // The prog_type is a bit mask, so that in searches one can find, e.g., -diff --git ./src/lib/cbfs.c ./src/lib/cbfs.c -index 87ab387..708d321 100644 ---- ./src/lib/cbfs.c -+++ ./src/lib/cbfs.c -@@ -70,7 +70,13 @@ void *cbfs_boot_map_with_leak(const char *name, uint32_t type, size_t *size) + enum prog_type { +diff --git a/src/lib/cbfs.c b/src/lib/cbfs.c +index a5c9f85238..fbe1844e8c 100644 +--- a/src/lib/cbfs.c ++++ b/src/lib/cbfs.c +@@ -75,7 +75,13 @@ void *cbfs_boot_map_with_leak(const char *name, uint32_t type, size_t *size) if (size != NULL) *size = fsize; - return rdev_mmap(&fh.data, 0, fsize); -+ void * buffer = rdev_mmap(&fh.data, 0, fsize); ++ void *buffer = rdev_mmap(&fh.data, 0, fsize); + +#ifndef __SMM__ + prog_segment_loaded((uintptr_t)buffer, fsize, 0); @@ -109,7 +56,7 @@ index 87ab387..708d321 100644 } int cbfs_locate_file_in_region(struct cbfsf *fh, const char *region_name, -@@ -98,7 +104,8 @@ size_t cbfs_load_and_decompress(const struct region_device *rdev, size_t offset, +@@ -103,7 +109,8 @@ size_t cbfs_load_and_decompress(const struct region_device *rdev, size_t offset, return 0; if (rdev_readat(rdev, buffer, offset, in_size) != in_size) return 0; @@ -119,7 +66,7 @@ index 87ab387..708d321 100644 case CBFS_COMPRESS_LZ4: if ((ENV_BOOTBLOCK || ENV_VERSTAGE) && -@@ -116,7 +123,7 @@ size_t cbfs_load_and_decompress(const struct region_device *rdev, size_t offset, +@@ -121,7 +128,7 @@ size_t cbfs_load_and_decompress(const struct region_device *rdev, size_t offset, timestamp_add_now(TS_START_ULZ4F); out_size = ulz4fn(compr_start, in_size, buffer, buffer_size); timestamp_add_now(TS_END_ULZ4F); @@ -127,8 +74,8 @@ index 87ab387..708d321 100644 + break; case CBFS_COMPRESS_LZMA: - if (ENV_BOOTBLOCK || ENV_VERSTAGE) -@@ -135,11 +142,15 @@ size_t cbfs_load_and_decompress(const struct region_device *rdev, size_t offset, + /* We assume here romstage and postcar are never compressed. */ +@@ -143,11 +150,15 @@ size_t cbfs_load_and_decompress(const struct region_device *rdev, size_t offset, rdev_munmap(rdev, map); @@ -145,19 +92,19 @@ index 87ab387..708d321 100644 } static inline int tohex4(unsigned int c) -diff --git ./src/lib/hardwaremain.c ./src/lib/hardwaremain.c -index 6fd55d7..b5b7d91 100644 ---- ./src/lib/hardwaremain.c -+++ ./src/lib/hardwaremain.c -@@ -33,6 +33,7 @@ +diff --git a/src/lib/hardwaremain.c b/src/lib/hardwaremain.c +index e6cf67f064..23d5eb9334 100644 +--- a/src/lib/hardwaremain.c ++++ b/src/lib/hardwaremain.c +@@ -32,6 +32,7 @@ #include #include #include +#include - #include #if IS_ENABLED(CONFIG_HAVE_ACPI_RESUME) #include -@@ -545,3 +546,13 @@ void boot_state_current_unblock(void) + #endif +@@ -543,3 +544,10 @@ void boot_state_current_unblock(void) { boot_state_unblock(current_phase.state_id, current_phase.seq); } @@ -166,50 +113,44 @@ index 6fd55d7..b5b7d91 100644 +void platform_segment_loaded(uintptr_t start, size_t size, int flags) +{ + if (IS_ENABLED(CONFIG_MEASURED_BOOT) && !(flags & SEG_NO_MEASURE)) -+ { -+ tlcl_measure(3, (const void*) start, size); -+ } ++ tlcl_measure(3, (const void *) start, size); +} -+ -diff --git ./src/lib/rmodule.c ./src/lib/rmodule.c -index 66d5120..b50afe7 100644 ---- ./src/lib/rmodule.c -+++ ./src/lib/rmodule.c -@@ -198,7 +198,7 @@ int rmodule_load(void *base, struct rmodule *module) +diff --git a/src/lib/rmodule.c b/src/lib/rmodule.c +index 56529d2fb2..2702b9d36e 100644 +--- a/src/lib/rmodule.c ++++ b/src/lib/rmodule.c +@@ -197,7 +197,8 @@ int rmodule_load(void *base, struct rmodule *module) rmodule_clear_bss(module); prog_segment_loaded((uintptr_t)module->location, - rmodule_memory_size(module), SEG_FINAL); -+ rmodule_memory_size(module), SEG_FINAL | SEG_NO_MEASURE); ++ rmodule_memory_size(module), ++ SEG_FINAL | SEG_NO_MEASURE); return 0; } -diff --git ./src/security/tpm/Makefile.inc ./src/security/tpm/Makefile.inc -index 2385635..0743a84 100644 ---- ./src/security/tpm/Makefile.inc -+++ ./src/security/tpm/Makefile.inc -@@ -4,6 +4,15 @@ verstage-$(CONFIG_TPM) += tss/tcg-1.2/tss.c - verstage-$(CONFIG_TPM2) += tss/tcg-2.0/tss_marshaling.c - verstage-$(CONFIG_TPM2) += tss/tcg-2.0/tss.c +diff --git a/src/security/tpm/Makefile.inc b/src/security/tpm/Makefile.inc +index 34ead8f07d..c4cbe697e6 100644 +--- a/src/security/tpm/Makefile.inc ++++ b/src/security/tpm/Makefile.inc +@@ -18,6 +18,11 @@ romstage-y += tspi/tspi.c tspi/log.c + verstage-$(CONFIG_VBOOT) += tspi/tspi.c tspi/log.c + postcar-$(CONFIG_VBOOT) += tspi/tspi.c tspi/log.c +ifeq ($(CONFIG_MEASURED_BOOT),y) -+ifneq ($(CONFIG_VBOOT_SEPARATE_VERSTAGE),y) -+romstage-$(CONFIG_TPM) += tss/tcg-1.2/tss.c -+endif -+romstage-$(CONFIG_TPM) += sha1.c -+ramstage-$(CONFIG_TPM) += tss/tcg-1.2/tss.c -+ramstage-$(CONFIG_TPM) += sha1.c ++romstage-y += sha1.c ++ramstage-y += sha1.c +endif # CONFIG_MEASURED_BOOT + - ifeq ($(CONFIG_VBOOT_SEPARATE_VERSTAGE),y) - romstage-$(CONFIG_TPM) += tss/tcg-1.2/tss.c - romstage-$(CONFIG_TPM2) += tss/tcg-2.0/tss_marshaling.c -diff --git ./src/security/tpm/sha1.c ./src/security/tpm/sha1.c + endif # CONFIG_TPM1 + + ifeq ($(CONFIG_TPM2),y) +diff --git a/src/security/tpm/sha1.c b/src/security/tpm/sha1.c new file mode 100644 -index 0000000..6b154f8 +index 0000000000..9879f729b1 --- /dev/null -+++ ./src/security/tpm/sha1.c -@@ -0,0 +1,175 @@ ++++ b/src/security/tpm/sha1.c +@@ -0,0 +1,180 @@ +/* Copyright (c) 2010 The Chromium OS Authors. All rights reserved. + * Use of this source code is governed by a BSD-style license that can be + * found in the LICENSE file. @@ -246,11 +187,12 @@ index 0000000..6b154f8 + D = ctx->state[3]; + E = ctx->state[4]; + -+#define SHA_F1(A, B, C, D, E, t) \ ++#define SHA_F1(A, B, C, D, E, t) do { \ + E += ror27(A) + \ + (W[t] = __builtin_bswap32(ctx->buf.w[t])) + \ + (D^(B&(C^D))) + 0x5A827999; \ -+ B = ror2(B); ++ B = ror2(B); \ ++ } while (0) + + for (t = 0; t < 15; t += 5) { + SHA_F1(A, B, C, D, E, t + 0); @@ -263,11 +205,12 @@ index 0000000..6b154f8 + +#undef SHA_F1 + -+#define SHA_F1(A, B, C, D, E, t) \ ++#define SHA_F1(A, B, C, D, E, t) do { \ + E += ror27(A) + \ + (W[t] = ror31(W[t-3] ^ W[t-8] ^ W[t-14] ^ W[t-16])) + \ + (D^(B&(C^D))) + 0x5A827999; \ -+ B = ror2(B); ++ B = ror2(B); \ ++ } while (0) + + SHA_F1(E, A, B, C, D, t + 1); + SHA_F1(D, E, A, B, C, t + 2); @@ -276,11 +219,12 @@ index 0000000..6b154f8 + +#undef SHA_F1 + -+#define SHA_F2(A, B, C, D, E, t) \ ++#define SHA_F2(A, B, C, D, E, t) do { \ + E += ror27(A) + \ + (W[t] = ror31(W[t-3] ^ W[t-8] ^ W[t-14] ^ W[t-16])) + \ + (B^C^D) + 0x6ED9EBA1; \ -+ B = ror2(B); ++ B = ror2(B); \ ++ } while (0) + + for (t = 20; t < 40; t += 5) { + SHA_F2(A, B, C, D, E, t + 0); @@ -292,11 +236,12 @@ index 0000000..6b154f8 + +#undef SHA_F2 + -+#define SHA_F3(A, B, C, D, E, t) \ ++#define SHA_F3(A, B, C, D, E, t) do { \ + E += ror27(A) + \ + (W[t] = ror31(W[t-3] ^ W[t-8] ^ W[t-14] ^ W[t-16])) + \ + ((B&C)|(D&(B|C))) + 0x8F1BBCDC; \ -+ B = ror2(B); ++ B = ror2(B); \ ++ } while (0) + + for (; t < 60; t += 5) { + SHA_F3(A, B, C, D, E, t + 0); @@ -308,11 +253,12 @@ index 0000000..6b154f8 + +#undef SHA_F3 + -+#define SHA_F4(A, B, C, D, E, t) \ ++#define SHA_F4(A, B, C, D, E, t) do { \ + E += ror27(A) + \ + (W[t] = ror31(W[t-3] ^ W[t-8] ^ W[t-14] ^ W[t-16])) + \ + (B^C^D) + 0xCA62C1D6; \ -+ B = ror2(B); ++ B = ror2(B); \ ++ } while (0) + + for (; t < 80; t += 5) { + SHA_F4(A, B, C, D, E, t + 0); @@ -385,11 +331,11 @@ index 0000000..6b154f8 + ctx->state[4] = 0xC3D2E1F0; + ctx->count = 0; +} -diff --git ./src/security/tpm/sha1.h ./src/security/tpm/sha1.h +diff --git a/src/security/tpm/sha1.h b/src/security/tpm/sha1.h new file mode 100644 -index 0000000..e7e28e6 +index 0000000000..e7e28e6cdb --- /dev/null -+++ ./src/security/tpm/sha1.h ++++ b/src/security/tpm/sha1.h @@ -0,0 +1,31 @@ +/* Copyright (c) 2014 The Chromium OS Authors. All rights reserved. + * Use of this source code is governed by a BSD-style license that can be @@ -422,26 +368,26 @@ index 0000000..e7e28e6 +uint8_t *sha1_final(struct sha1_ctx *ctx); + +#endif /* _sha1_h_ */ -diff --git ./src/security/tpm/tss.h ./src/security/tpm/tss.h -index 8f3f1cb..5c569cb 100644 ---- ./src/security/tpm/tss.h -+++ ./src/security/tpm/tss.h -@@ -147,6 +147,11 @@ uint32_t tlcl_extend(int pcr_num, const uint8_t *in_digest, - uint8_t *out_digest); +diff --git a/src/security/tpm/tss.h b/src/security/tpm/tss.h +index c4f2608603..5ea7b365dc 100644 +--- a/src/security/tpm/tss.h ++++ b/src/security/tpm/tss.h +@@ -51,6 +51,11 @@ uint32_t tlcl_get_flags(uint8_t *disable, uint8_t *deactivated, + */ + uint32_t tlcl_get_permanent_flags(TPM_PERMANENT_FLAGS *pflags); - /** ++/** + * Perform a SHA1 hash on a region and extend a PCR with the hash. + */ -+uint32_t tlcl_measure(int pcr_num, const void * start, size_t len); ++uint32_t tlcl_measure(int pcr_num, const void *start, size_t len); + -+/** - * Get the entire set of permanent flags. - */ - uint32_t tlcl_get_permanent_flags(TPM_PERMANENT_FLAGS *pflags); -diff --git ./src/security/tpm/tss/tcg-1.2/tss.c ./src/security/tpm/tss/tcg-1.2/tss.c -index 161d29f..95e55b9 100644 ---- ./src/security/tpm/tss/tcg-1.2/tss.c -+++ ./src/security/tpm/tss/tcg-1.2/tss.c + #endif + + #if IS_ENABLED(CONFIG_TPM2) +diff --git a/src/security/tpm/tss/tcg-1.2/tss.c b/src/security/tpm/tss/tcg-1.2/tss.c +index b11d6a3d16..ef4f4d8b86 100644 +--- a/src/security/tpm/tss/tcg-1.2/tss.c ++++ b/src/security/tpm/tss/tcg-1.2/tss.c @@ -17,6 +17,7 @@ #include #include @@ -450,13 +396,12 @@ index 161d29f..95e55b9 100644 #include #include #include -@@ -354,3 +355,23 @@ uint32_t tlcl_extend(int pcr_num, const uint8_t *in_digest, +@@ -361,3 +362,21 @@ uint32_t tlcl_extend(int pcr_num, const uint8_t *in_digest, kPcrDigestLength); return result; } + -+ -+uint32_t tlcl_measure(int pcr_num, const void * start, size_t len) ++uint32_t tlcl_measure(int pcr_num, const void *start, size_t len) +{ + VBDEBUG("TPM: pcr %d measure %p @ %zu: ", pcr_num, start, len); + @@ -464,8 +409,8 @@ index 161d29f..95e55b9 100644 + sha1_init(&sha); + sha1_update(&sha, start, len); + -+ const uint8_t * hash = sha1_final(&sha); -+ for(unsigned i = 0 ; i < SHA1_DIGEST_SIZE ; i++) ++ const uint8_t *hash = sha1_final(&sha); ++ for (unsigned int i = 0; i < SHA1_DIGEST_SIZE; i++) + VBDEBUG("%02x", hash[i]); + VBDEBUG("\n"); + @@ -473,4 +418,3 @@ index 161d29f..95e55b9 100644 + + return tlcl_extend(pcr_num, hash, NULL); +} -+ diff --git a/patches/coreboot-4.8.1/0030-sandybridge.patch b/patches/coreboot-4.9/0030-sandybridge.patch similarity index 50% rename from patches/coreboot-4.8.1/0030-sandybridge.patch rename to patches/coreboot-4.9/0030-sandybridge.patch index 8559b4090..662190591 100644 --- a/patches/coreboot-4.8.1/0030-sandybridge.patch +++ b/patches/coreboot-4.9/0030-sandybridge.patch @@ -1,27 +1,28 @@ -diff --git ./src/northbridge/intel/sandybridge/romstage.c ./src/northbridge/intel/sandybridge/romstage.c -index 0426b83..d348b9e 100644 ---- ./src/northbridge/intel/sandybridge/romstage.c -+++ ./src/northbridge/intel/sandybridge/romstage.c -@@ -29,6 +29,8 @@ +diff --git a/src/northbridge/intel/sandybridge/romstage.c b/src/northbridge/intel/sandybridge/romstage.c +index 7345443c3d..7c204072b5 100644 +--- a/src/northbridge/intel/sandybridge/romstage.c ++++ b/src/northbridge/intel/sandybridge/romstage.c +@@ -27,6 +27,9 @@ + #include #include #include - #include +#include ++#include +#include #include - #include "southbridge/intel/bd82x6x/pch.h" + #include #include -@@ -72,6 +74,19 @@ void mainboard_romstage_entry(unsigned long bist) +@@ -70,6 +73,19 @@ void mainboard_romstage_entry(unsigned long bist) /* Initialize superio */ mainboard_config_superio(); + if (IS_ENABLED(CONFIG_MEASURED_BOOT) && IS_ENABLED(CONFIG_LPC_TPM)) { + // we don't know if we are coming out of a resume + // at this point, but want to setup the tpm ASAP -+ init_tpm(0); ++ tpm_setup(0); + tlcl_lib_init(); -+ const void * const bootblock = (const void*) 0xFFFFF800; -+ const unsigned bootblock_size = 0x800; ++ const void *const bootblock = (const void *) 0xFFFFF800; ++ const unsigned int bootblock_size = 0x800; + tlcl_measure(0, bootblock, bootblock_size); + + extern char _romstage, _eromstage; @@ -31,28 +32,14 @@ index 0426b83..d348b9e 100644 /* USB is initialized in MRC if MRC is used. */ if (CONFIG_USE_NATIVE_RAMINIT) { early_usb_init(mainboard_usb_ports); -@@ -117,9 +132,23 @@ void mainboard_romstage_entry(unsigned long bist) +@@ -117,3 +133,10 @@ void mainboard_romstage_entry(unsigned long bist) - northbridge_romstage_finalize(s3resume); - -- if (IS_ENABLED(CONFIG_LPC_TPM)) { -+ // the normal TPM init happens here, if we haven't already -+ // set it up as part of the measured boot. -+ if (!IS_ENABLED(CONFIG_MEASURED_BOOT) && IS_ENABLED(CONFIG_LPC_TPM)) { - init_tpm(s3resume); - } - -+ printk(BIOS_DEBUG, "%s: romstage complete\n", __FILE__); -+ post_code(0x3f); } + -+ +void platform_segment_loaded(uintptr_t start, size_t size, int flags) +{ + if (IS_ENABLED(CONFIG_MEASURED_BOOT) && !(flags & SEG_NO_MEASURE)) -+ { -+ tlcl_measure(2, (const void*) start, size); -+ } ++ tlcl_measure(2, (const void *) start, size); +} +