diff --git a/config/coreboot-kgpe-d16.config b/config/coreboot-kgpe-d16.config index e294e944..4be5a04b 100644 --- a/config/coreboot-kgpe-d16.config +++ b/config/coreboot-kgpe-d16.config @@ -1,714 +1,14 @@ -# -# Automatically generated file; DO NOT EDIT. -# coreboot configuration -# - -# -# General setup -# -CONFIG_COREBOOT_BUILD=y CONFIG_LOCALVERSION="heads" -CONFIG_CBFS_PREFIX="fallback" -CONFIG_COMPILER_GCC=y -# CONFIG_COMPILER_LLVM_CLANG is not set -# CONFIG_ANY_TOOLCHAIN is not set -# CONFIG_CCACHE is not set -# CONFIG_FMD_GENPARSER is not set -# CONFIG_UTIL_GENPARSER is not set CONFIG_USE_OPTION_TABLE=y -# CONFIG_STATIC_OPTION_TABLE is not set -CONFIG_COMPRESS_RAMSTAGE=y -CONFIG_INCLUDE_CONFIG_FILE=y # CONFIG_COLLECT_TIMESTAMPS is not set -# CONFIG_USE_BLOBS is not set -# CONFIG_COVERAGE is not set -# CONFIG_UBSAN is not set -# CONFIG_RELOCATABLE_RAMSTAGE is not set -# CONFIG_UPDATE_IMAGE is not set -# CONFIG_BOOTSPLASH_IMAGE is not set -# CONFIG_MEASURED_BOOT is not set - -# -# Mainboard -# - -# -# Important: Run 'make distclean' before switching boards -# -# CONFIG_VENDOR_A_TREND is not set -# CONFIG_VENDOR_AAEON is not set -# CONFIG_VENDOR_ABIT is not set -# CONFIG_VENDOR_ADI is not set -# CONFIG_VENDOR_ADLINK is not set -# CONFIG_VENDOR_ADVANSUS is not set -# CONFIG_VENDOR_AMD is not set -# CONFIG_VENDOR_AOPEN is not set -# CONFIG_VENDOR_APPLE is not set -# CONFIG_VENDOR_ARTECGROUP is not set -# CONFIG_VENDOR_ASROCK is not set CONFIG_VENDOR_ASUS=y -# CONFIG_VENDOR_AVALUE is not set -# CONFIG_VENDOR_AZZA is not set -# CONFIG_VENDOR_BACHMANN is not set -# CONFIG_VENDOR_BAP is not set -# CONFIG_VENDOR_BCOM is not set -# CONFIG_VENDOR_BIOSTAR is not set -# CONFIG_VENDOR_BROADCOM is not set -# CONFIG_VENDOR_COMPAQ is not set -# CONFIG_VENDOR_COMPULAB is not set -# CONFIG_VENDOR_CUBIETECH is not set -# CONFIG_VENDOR_DIGITALLOGIC is not set -# CONFIG_VENDOR_DMP is not set -# CONFIG_VENDOR_ECS is not set -# CONFIG_VENDOR_ELMEX is not set -# CONFIG_VENDOR_EMULATION is not set -# CONFIG_VENDOR_ESD is not set -# CONFIG_VENDOR_FOXCONN is not set -# CONFIG_VENDOR_GETAC is not set -# CONFIG_VENDOR_GIGABYTE is not set -# CONFIG_VENDOR_GIZMOSPHERE is not set -# CONFIG_VENDOR_GOOGLE is not set -# CONFIG_VENDOR_HP is not set -# CONFIG_VENDOR_IBASE is not set -# CONFIG_VENDOR_IEI is not set -# CONFIG_VENDOR_INTEL is not set -# CONFIG_VENDOR_IWAVE is not set -# CONFIG_VENDOR_IWILL is not set -# CONFIG_VENDOR_JETWAY is not set -# CONFIG_VENDOR_KONTRON is not set -# CONFIG_VENDOR_LANNER is not set -# CONFIG_VENDOR_LENOVO is not set -# CONFIG_VENDOR_LINUTOP is not set -# CONFIG_VENDOR_LIPPERT is not set -# CONFIG_VENDOR_LOWRISC is not set -# CONFIG_VENDOR_MITAC is not set -# CONFIG_VENDOR_MSI is not set -# CONFIG_VENDOR_NEC is not set -# CONFIG_VENDOR_NOKIA is not set -# CONFIG_VENDOR_NVIDIA is not set -# CONFIG_VENDOR_PACKARDBELL is not set -# CONFIG_VENDOR_PCENGINES is not set -# CONFIG_VENDOR_PURISM is not set -# CONFIG_VENDOR_RCA is not set -# CONFIG_VENDOR_RODA is not set -# CONFIG_VENDOR_SAMSUNG is not set -# CONFIG_VENDOR_SAPPHIRE is not set -# CONFIG_VENDOR_SIEMENS is not set -# CONFIG_VENDOR_SOYO is not set -# CONFIG_VENDOR_SUNW is not set -# CONFIG_VENDOR_SUPERMICRO is not set -# CONFIG_VENDOR_TECHNEXION is not set -# CONFIG_VENDOR_THOMSON is not set -# CONFIG_VENDOR_TI is not set -# CONFIG_VENDOR_TRAVERSE is not set -# CONFIG_VENDOR_TYAN is not set -# CONFIG_VENDOR_VIA is not set -# CONFIG_VENDOR_WINENT is not set -# CONFIG_VENDOR_WINNET is not set -# CONFIG_VENDOR_WYSE is not set -CONFIG_BOARD_SPECIFIC_OPTIONS=y -CONFIG_MAINBOARD_DIR="asus/kgpe-d16" -CONFIG_MAINBOARD_PART_NUMBER="KGPE-D16" -CONFIG_IRQ_SLOT_COUNT=13 -CONFIG_MAINBOARD_VENDOR="ASUS" -CONFIG_MAX_CPUS=32 -CONFIG_CACHE_ROM_SIZE_OVERRIDE=0x0 -CONFIG_CBFS_SIZE=0x1000000 CONFIG_UART_FOR_CONSOLE=1 -CONFIG_APIC_ID_OFFSET=0x0 -CONFIG_HW_MEM_HOLE_SIZEK=0x100000 -CONFIG_MAX_PHYSICAL_CPUS=4 -# CONFIG_HW_MEM_HOLE_SIZE_AUTO_INC is not set -CONFIG_HT_CHAIN_END_UNITID_BASE=0x20 -CONFIG_HT_CHAIN_UNITID_BASE=0x0 -CONFIG_VGA_BIOS_ID="1a03,2000" -CONFIG_ONBOARD_VGA_IS_PRIMARY=y -CONFIG_DIMM_SPD_SIZE=256 -# CONFIG_VGA_BIOS is not set -CONFIG_MAINBOARD_SERIAL_NUMBER="123456789" -CONFIG_DCACHE_RAM_BASE=0xc2000 -CONFIG_DCACHE_RAM_SIZE=0x1e000 -CONFIG_MAINBOARD_SMBIOS_MANUFACTURER="ASUS" -# CONFIG_BOARD_ASUS_A8N_E is not set -# CONFIG_BOARD_ASUS_A8N_SLI is not set -# CONFIG_BOARD_ASUS_A8V_E_DELUXE is not set -# CONFIG_BOARD_ASUS_A8V_E_SE is not set -# CONFIG_BOARD_ASUS_AM1I_A is not set -# CONFIG_BOARD_ASUS_DSBF is not set -# CONFIG_BOARD_ASUS_F2A85_M is not set -# CONFIG_BOARD_ASUS_F2A85_M_PRO is not set -# CONFIG_BOARD_ASUS_F2A85_M_LE is not set -# CONFIG_BOARD_ASUS_K8V_X is not set -# CONFIG_BOARD_ASUS_KCMA_D8 is not set -# CONFIG_BOARD_ASUS_KFSN4_DRE is not set -# CONFIG_BOARD_ASUS_KFSN4_DRE_K8 is not set CONFIG_BOARD_ASUS_KGPE_D16=y -# CONFIG_BOARD_ASUS_M2N_E is not set -# CONFIG_BOARD_ASUS_M2V_MX_SE is not set -# CONFIG_BOARD_ASUS_M2V is not set -# CONFIG_BOARD_ASUS_M4A78_EM is not set -# CONFIG_BOARD_ASUS_M4A785M is not set -# CONFIG_BOARD_ASUS_M4A785TM is not set -# CONFIG_BOARD_ASUS_M5A88_V is not set -# CONFIG_BOARD_ASUS_MEW_AM is not set -# CONFIG_BOARD_ASUS_MEW_VM is not set -# CONFIG_BOARD_ASUS_P2B_D is not set -# CONFIG_BOARD_ASUS_P2B_DS is not set -# CONFIG_BOARD_ASUS_P2B_F is not set -# CONFIG_BOARD_ASUS_P2B_LS is not set -# CONFIG_BOARD_ASUS_P2B is not set -# CONFIG_BOARD_ASUS_P3B_F is not set -# CONFIG_BOARD_ASUS_P5GC_MX is not set -CONFIG_MMCONF_BASE_ADDRESS=0xc0000000 -CONFIG_POST_IO=y -CONFIG_DEVICETREE="devicetree.cb" -CONFIG_AGP_APERTURE_SIZE=0x4000000 -CONFIG_BOOTBLOCK_MAINBOARD_INIT="mainboard/asus/kgpe-d16/bootblock.c" -CONFIG_SOUTHBRIDGE_AMD_SB700_SATA_PORT_COUNT_BITFIELD=0x3f -CONFIG_MAINBOARD_POWER_ON_AFTER_POWER_FAIL=y -CONFIG_MAX_REBOOT_CNT=10 -CONFIG_ID_SECTION_OFFSET=0x80 -CONFIG_POST_DEVICE=y -# CONFIG_VBOOT is not set -CONFIG_TPM_PIRQ=0x0 -CONFIG_BOOT_DEVICE_SPI_FLASH_BUS=0 -CONFIG_FMDFILE="" -CONFIG_PRERAM_CBMEM_CONSOLE_SIZE=0xc00 -CONFIG_TTYS0_LCS=3 -CONFIG_DRIVERS_UART_8250IO=y -CONFIG_UDELAY_LAPIC_FIXED_FSB=200 -CONFIG_MAINBOARD_SMBIOS_PRODUCT_NAME="KGPE-D16" -CONFIG_CPU_ADDR_BITS=48 -CONFIG_DEFAULT_CONSOLE_LOGLEVEL=8 -# CONFIG_USBDEBUG is not set -CONFIG_MAINBOARD_VERSION="1.0" CONFIG_DRIVERS_PS2_KEYBOARD=y -CONFIG_PCIEXP_L1_SUB_STATE=y -# CONFIG_NO_POST is not set -CONFIG_BOARD_ROMSIZE_KB_2048=y -# CONFIG_COREBOOT_ROMSIZE_KB_64 is not set -# CONFIG_COREBOOT_ROMSIZE_KB_128 is not set -# CONFIG_COREBOOT_ROMSIZE_KB_256 is not set -# CONFIG_COREBOOT_ROMSIZE_KB_512 is not set -# CONFIG_COREBOOT_ROMSIZE_KB_1024 is not set -# CONFIG_COREBOOT_ROMSIZE_KB_2048 is not set -# CONFIG_COREBOOT_ROMSIZE_KB_4096 is not set -# CONFIG_COREBOOT_ROMSIZE_KB_8192 is not set -# CONFIG_COREBOOT_ROMSIZE_KB_10240 is not set -# CONFIG_COREBOOT_ROMSIZE_KB_12288 is not set CONFIG_COREBOOT_ROMSIZE_KB_16384=y -# CONFIG_COREBOOT_ROMSIZE_KB_32768 is not set -# CONFIG_COREBOOT_ROMSIZE_KB_65536 is not set -CONFIG_COREBOOT_ROMSIZE_KB=16384 -CONFIG_ROM_SIZE=0x1000000 -# CONFIG_MAINBOARD_HAS_TPM2 is not set -# CONFIG_SYSTEM_TYPE_LAPTOP is not set -# CONFIG_CBFS_AUTOGEN_ATTRIBUTES is not set - -# -# Chipset -# - -# -# SoC -# -CONFIG_DCACHE_BSP_STACK_SIZE=0x4000 -CONFIG_MMCONF_BUS_NUMBER=256 -CONFIG_RAMTOP=0x400000 -CONFIG_HEAP_SIZE=0xc0000 -CONFIG_RAMBASE=0x100000 -CONFIG_EHCI_BAR=0xfef00000 -CONFIG_ACPI_CPU_STRING="\\_PR.CP%02d" -# CONFIG_SOC_BROADCOM_CYGNUS is not set -# CONFIG_SOC_INTEL_GLK is not set -CONFIG_C_ENV_BOOTBLOCK_SIZE=0x10000 -CONFIG_X86_TOP4G_BOOTMEDIA_MAP=y -CONFIG_ROMSTAGE_ADDR=0x2000000 -CONFIG_VERSTAGE_ADDR=0x2000000 -CONFIG_SPI_FLASH_INCLUDE_ALL_DRIVERS=y -CONFIG_PCIEXP_ASPM=y -CONFIG_PCIEXP_COMMON_CLOCK=y -CONFIG_PCIEXP_CLK_PM=y -CONFIG_BOOTBLOCK_NORTHBRIDGE_INIT="northbridge/amd/amdfam10/bootblock.c" -CONFIG_BOOTBLOCK_SOUTHBRIDGE_INIT="southbridge/amd/sb700/bootblock.c" -CONFIG_TTYS0_BASE=0x2f8 -CONFIG_STACK_SIZE=0x1000 -CONFIG_CONSOLE_CBMEM=y -CONFIG_UART_PCI_ADDR=0x0 -CONFIG_HPET_MIN_TICKS=0x14 -# CONFIG_SOC_INTEL_KABYLAKE is not set -# CONFIG_SOC_LOWRISC_LOWRISC is not set -# CONFIG_SOC_MARVELL_MVMAP2315 is not set -CONFIG_TTYS0_BAUD=115200 -# CONFIG_SOC_MEDIATEK_MT8173 is not set -# CONFIG_SOC_NVIDIA_TEGRA124 is not set -# CONFIG_SOC_NVIDIA_TEGRA210 is not set -# CONFIG_SOC_QC_IPQ40XX is not set -# CONFIG_SOC_QC_IPQ806X is not set -# CONFIG_SOC_ROCKCHIP_RK3288 is not set -# CONFIG_SOC_ROCKCHIP_RK3399 is not set -# CONFIG_CPU_SAMSUNG_EXYNOS5250 is not set -# CONFIG_CPU_SAMSUNG_EXYNOS5420 is not set -# CONFIG_SOC_UCB_RISCV is not set - -# -# CPU -# -# CONFIG_CPU_ALLWINNER_A10 is not set -CONFIG_DCACHE_BSP_STACK_SLUSH=0x4000 -CONFIG_DCACHE_AP_STACK_SIZE=0x500 -CONFIG_CPU_SOCKET_TYPE=0x15 -# CONFIG_EXT_RT_TBL_SUPPORT is not set -CONFIG_CBB=0x0 -CONFIG_CDB=0x18 -CONFIG_XIP_ROM_SIZE=0x80000 -CONFIG_CPU_AMD_SOCKET_G34_NON_AGESA=y -CONFIG_DIMM_SUPPORT=0x0005 -CONFIG_LIFT_BSP_APIC_ID=y -CONFIG_SET_FIDVID=y -CONFIG_SET_FIDVID_DEBUG=y -# CONFIG_SET_FIDVID_CORE0_ONLY is not set -CONFIG_SET_FIDVID_STORE_AP_APICID_AT_FIRST=y -CONFIG_CPU_AMD_MODEL_10XXX=y -CONFIG_USE_LARGE_DCACHE=y -CONFIG_NUM_IPI_STARTS=1 -CONFIG_SET_FIDVID_CORE_RANGE=0 -# CONFIG_CPU_AMD_AGESA is not set -CONFIG_S3_DATA_POS=0x0 -CONFIG_S3_DATA_SIZE=32768 -# CONFIG_CPU_AMD_PI is not set -CONFIG_EXT_CONF_SUPPORT=y -# CONFIG_CPU_ARMLTD_CORTEX_A9 is not set -CONFIG_SSE2=y -# CONFIG_CPU_INTEL_FIRMWARE_INTERFACE_TABLE is not set -# CONFIG_CPU_INTEL_TURBO_NOT_PACKAGE_SCOPED is not set -# CONFIG_CPU_TI_AM335X is not set -CONFIG_PARALLEL_CPU_INIT=y -# CONFIG_PARALLEL_MP is not set -# CONFIG_UDELAY_IO is not set -CONFIG_UDELAY_LAPIC=y -# CONFIG_LAPIC_MONOTONIC_TIMER is not set -# CONFIG_UDELAY_TSC is not set -# CONFIG_UDELAY_TIMER2 is not set -CONFIG_TSC_SYNC_LFENCE=y -# CONFIG_TSC_SYNC_MFENCE is not set -# CONFIG_NO_FIXED_XIP_ROM_SIZE is not set -CONFIG_LOGICAL_CPUS=y -# CONFIG_SMM_TSEG is not set -# CONFIG_SMM_LAPIC_REMAP_MITIGATION is not set -# CONFIG_SERIALIZED_SMM_INITIALIZATION is not set -CONFIG_X86_AMD_FIXED_MTRRS=y -# CONFIG_PLATFORM_USES_FSP1_0 is not set -# CONFIG_MIRROR_PAYLOAD_TO_RAM_BEFORE_LOADING is not set -# CONFIG_SOC_SETS_MSRS is not set -CONFIG_CACHE_AS_RAM=y -# CONFIG_NO_CAR_GLOBAL_MIGRATION is not set -CONFIG_SMP=y -CONFIG_AP_SIPI_VECTOR=0xfffff000 -CONFIG_SSE=y -CONFIG_SUPPORT_CPU_UCODE_IN_CBFS=y -# CONFIG_USES_MICROCODE_HEADER_FILES is not set -CONFIG_CPU_MICROCODE_CBFS_GENERATE=y -# CONFIG_CPU_MICROCODE_CBFS_EXTERNAL_HEADER is not set -# CONFIG_CPU_MICROCODE_CBFS_NONE is not set -CONFIG_CPU_MICROCODE_MULTIPLE_FILES=y -CONFIG_CPU_UCODE_BINARIES="" - -# -# Northbridge -# -# CONFIG_NORTHBRIDGE_AMD_AGESA is not set -CONFIG_NORTHBRIDGE_AMD_AMDFAM10=y -CONFIG_SB_HT_CHAIN_UNITID_OFFSET_ONLY=y -# CONFIG_HT_CHAIN_DISTRIBUTE is not set -# CONFIG_DIMM_FBDIMM is not set -# CONFIG_DIMM_DDR2 is not set -CONFIG_DIMM_DDR3=y -CONFIG_DIMM_REGISTERED=y -CONFIG_DIMM_VOLTAGE_SET_SUPPORT=y -# CONFIG_SVI_HIGH_FREQ is not set - -# -# HyperTransport setup -# -# CONFIG_LIMIT_HT_DOWN_WIDTH_8 is not set -CONFIG_LIMIT_HT_DOWN_WIDTH_16=y -# CONFIG_LIMIT_HT_UP_WIDTH_8 is not set -CONFIG_LIMIT_HT_UP_WIDTH_16=y -# CONFIG_NO_MMCONF_SUPPORT is not set -# CONFIG_AMD_NB_CIMX is not set -# CONFIG_NORTHBRIDGE_AMD_CIMX_RD890 is not set -# CONFIG_NORTHBRIDGE_AMD_PI is not set -# CONFIG_NORTHBRIDGE_INTEL_COMMON_MRC_CACHE is not set -CONFIG_HPET_ADDRESS=0xfed00000 -CONFIG_MAX_PIRQ_LINKS=4 - -# -# Southbridge -# -# CONFIG_AMD_SB_CIMX is not set -# CONFIG_SOUTHBRIDGE_AMD_CIMX_SB800 is not set -# CONFIG_SOUTHBRIDGE_AMD_CIMX_SB900 is not set -CONFIG_SOUTHBRIDGE_AMD_SB700=y -CONFIG_SOUTHBRIDGE_SPECIFIC_OPTIONS=y -# CONFIG_SOUTHBRIDGE_AMD_SB700_33MHZ_SPI is not set -CONFIG_SOUTHBRIDGE_AMD_SUBTYPE_SP5100=y -# CONFIG_SOUTHBRIDGE_AMD_SB700_SKIP_ISA_DMA_INIT is not set -CONFIG_SOUTHBRIDGE_AMD_SB700_DISABLE_ISA_DMA=y -CONFIG_SOUTHBRIDGE_AMD_SR5650=y -# CONFIG_SOUTHBRIDGE_INTEL_COMMON is not set -# CONFIG_SOUTHBRIDGE_INTEL_COMMON_GPIO is not set -# CONFIG_SOUTHBRIDGE_INTEL_COMMON_SMBUS is not set -# CONFIG_SOUTHBRIDGE_INTEL_COMMON_SPI is not set -# CONFIG_SOUTHBRIDGE_INTEL_COMMON_PIRQ_ACPI_GEN is not set -# CONFIG_SOUTHBRIDGE_INTEL_COMMON_RCBA_PIRQ is not set -# CONFIG_HAVE_INTEL_CHIPSET_LOCKDOWN is not set - -# -# Super I/O -# -# CONFIG_SUPERIO_NUVOTON_NCT6776_COM_A is not set -CONFIG_SUPERIO_WINBOND_COMMON_ROMSTAGE=y -CONFIG_SUPERIO_WINBOND_W83667HG_A=y - -# -# Embedded Controllers -# -# CONFIG_MAINBOARD_HAS_CHROMEOS is not set -# CONFIG_GOOGLE_SMBIOS_MAINBOARD_VERSION is not set -# CONFIG_UEFI_2_4_BINDING is not set -# CONFIG_UDK_2015_BINDING is not set -# CONFIG_USE_SIEMENS_HWILIB is not set -# CONFIG_ARCH_ARM is not set -# CONFIG_ARCH_BOOTBLOCK_ARM is not set -# CONFIG_ARCH_VERSTAGE_ARM is not set -# CONFIG_ARCH_ROMSTAGE_ARM is not set -# CONFIG_ARCH_RAMSTAGE_ARM is not set -# CONFIG_ARCH_BOOTBLOCK_ARMV4 is not set -# CONFIG_ARCH_VERSTAGE_ARMV4 is not set -# CONFIG_ARCH_ROMSTAGE_ARMV4 is not set -# CONFIG_ARCH_RAMSTAGE_ARMV4 is not set -# CONFIG_ARCH_BOOTBLOCK_ARMV7 is not set -# CONFIG_ARCH_VERSTAGE_ARMV7 is not set -# CONFIG_ARCH_ROMSTAGE_ARMV7 is not set -# CONFIG_ARCH_RAMSTAGE_ARMV7 is not set -# CONFIG_ARCH_BOOTBLOCK_ARMV7_M is not set -# CONFIG_ARCH_VERSTAGE_ARMV7_M is not set -# CONFIG_ARCH_BOOTBLOCK_ARMV7_R is not set -# CONFIG_ARCH_VERSTAGE_ARMV7_R is not set -# CONFIG_ARCH_ROMSTAGE_ARMV7_R is not set -# CONFIG_ARCH_RAMSTAGE_ARMV7_R is not set -# CONFIG_ARM_LPAE is not set -# CONFIG_ARCH_ARM64 is not set -# CONFIG_ARCH_BOOTBLOCK_ARM64 is not set -# CONFIG_ARCH_VERSTAGE_ARM64 is not set -# CONFIG_ARCH_ROMSTAGE_ARM64 is not set -# CONFIG_ARCH_RAMSTAGE_ARM64 is not set -# CONFIG_ARCH_BOOTBLOCK_ARMV8_64 is not set -# CONFIG_ARCH_VERSTAGE_ARMV8_64 is not set -# CONFIG_ARCH_ROMSTAGE_ARMV8_64 is not set -# CONFIG_ARCH_RAMSTAGE_ARMV8_64 is not set -# CONFIG_ARM64_A53_ERRATUM_843419 is not set -# CONFIG_ARCH_MIPS is not set -# CONFIG_ARCH_BOOTBLOCK_MIPS is not set -# CONFIG_ARCH_VERSTAGE_MIPS is not set -# CONFIG_ARCH_ROMSTAGE_MIPS is not set -# CONFIG_ARCH_RAMSTAGE_MIPS is not set -# CONFIG_ARCH_POWER8 is not set -# CONFIG_ARCH_BOOTBLOCK_POWER8 is not set -# CONFIG_ARCH_VERSTAGE_POWER8 is not set -# CONFIG_ARCH_ROMSTAGE_POWER8 is not set -# CONFIG_ARCH_RAMSTAGE_POWER8 is not set -# CONFIG_ARCH_RISCV is not set -# CONFIG_ARCH_BOOTBLOCK_RISCV is not set -# CONFIG_ARCH_VERSTAGE_RISCV is not set -# CONFIG_ARCH_ROMSTAGE_RISCV is not set -# CONFIG_ARCH_RAMSTAGE_RISCV is not set -CONFIG_ARCH_X86=y -CONFIG_ARCH_BOOTBLOCK_X86_32=y -CONFIG_ARCH_VERSTAGE_X86_32=y -CONFIG_ARCH_ROMSTAGE_X86_32=y -CONFIG_ARCH_RAMSTAGE_X86_32=y -# CONFIG_ARCH_BOOTBLOCK_X86_64 is not set -# CONFIG_ARCH_VERSTAGE_X86_64 is not set -# CONFIG_ARCH_ROMSTAGE_X86_64 is not set -# CONFIG_ARCH_RAMSTAGE_X86_64 is not set -# CONFIG_USE_MARCH_586 is not set -# CONFIG_AP_IN_SIPI_WAIT is not set -# CONFIG_SIPI_VECTOR_IN_ROM is not set -# CONFIG_ROMCC is not set -# CONFIG_CBMEM_TOP_BACKUP is not set -# CONFIG_LATE_CBMEM_INIT is not set -# CONFIG_EARLY_EBDA_INIT is not set -CONFIG_PC80_SYSTEM=y -# CONFIG_BOOTBLOCK_DEBUG_SPINLOOP is not set -# CONFIG_BOOTBLOCK_SAVE_BIST_AND_TIMESTAMP is not set -CONFIG_HAVE_CMOS_DEFAULT=y -CONFIG_CMOS_DEFAULT_FILE="src/mainboard/$(MAINBOARDDIR)/cmos.default" -CONFIG_IOAPIC_INTERRUPTS_ON_FSB=y -# CONFIG_IOAPIC_INTERRUPTS_ON_APIC_SERIAL_BUS is not set -# CONFIG_POSTCAR_STAGE is not set -# CONFIG_VERSTAGE_DEBUG_SPINLOOP is not set -# CONFIG_ROMSTAGE_DEBUG_SPINLOOP is not set -CONFIG_BOOTBLOCK_SIMPLE=y -# CONFIG_BOOTBLOCK_NORMAL is not set -CONFIG_BOOTBLOCK_SOURCE="bootblock_simple.c" - -# -# Devices -# -CONFIG_MAINBOARD_HAS_NATIVE_VGA_INIT=y -CONFIG_MAINBOARD_FORCE_NATIVE_VGA_INIT=y -# CONFIG_MAINBOARD_HAS_LIBGFXINIT is not set -CONFIG_MAINBOARD_DO_NATIVE_VGA_INIT=y -# CONFIG_MULTIPLE_VGA_ADAPTERS is not set -CONFIG_SMBUS_HAS_AUX_CHANNELS=y -CONFIG_PCI=y -CONFIG_MMCONF_SUPPORT=y -CONFIG_HYPERTRANSPORT_PLUGIN_SUPPORT=y -CONFIG_PCIX_PLUGIN_SUPPORT=y -CONFIG_CARDBUS_PLUGIN_SUPPORT=y -# CONFIG_AZALIA_PLUGIN_SUPPORT is not set -CONFIG_PCIEXP_PLUGIN_SUPPORT=y -# CONFIG_EARLY_PCI_BRIDGE is not set -CONFIG_SUBSYSTEM_VENDOR_ID=0x0000 -CONFIG_SUBSYSTEM_DEVICE_ID=0x0000 -# CONFIG_SOFTWARE_I2C is not set - -# -# Generic Drivers -# -# CONFIG_DRIVERS_AS3722_RTC is not set -# CONFIG_GIC is not set -# CONFIG_IPMI_KCS is not set -# CONFIG_DRIVERS_LENOVO_WACOM is not set -# CONFIG_RT8168_GET_MAC_FROM_VPD is not set -# CONFIG_RT8168_SET_LED_MODE is not set -CONFIG_SPI_FLASH=y -CONFIG_BOOT_DEVICE_SPI_FLASH_RW_NOMMAP=y -# CONFIG_BOOT_DEVICE_SPI_FLASH_RW_NOMMAP_EARLY is not set -# CONFIG_SPI_FLASH_NO_FAST_READ is not set -CONFIG_SPI_FLASH_ADESTO=y -CONFIG_SPI_FLASH_AMIC=y -CONFIG_SPI_FLASH_ATMEL=y -CONFIG_SPI_FLASH_EON=y -CONFIG_SPI_FLASH_GIGADEVICE=y -CONFIG_SPI_FLASH_MACRONIX=y -CONFIG_SPI_FLASH_SPANSION=y -CONFIG_SPI_FLASH_SST=y -CONFIG_SPI_FLASH_STMICRO=y -CONFIG_SPI_FLASH_WINBOND=y -# CONFIG_SPI_FLASH_FAST_READ_DUAL_OUTPUT_3B is not set -# CONFIG_SPI_FLASH_HAS_VOLATILE_GROUP is not set -# CONFIG_HAVE_SPI_CONSOLE_SUPPORT is not set -CONFIG_DRIVERS_UART=y -# CONFIG_DRIVERS_UART_8250IO_SKIP_INIT is not set -# CONFIG_NO_UART_ON_SUPERIO is not set -# CONFIG_UART_OVERRIDE_INPUT_CLOCK_DIVIDER is not set -# CONFIG_UART_OVERRIDE_REFCLK is not set -# CONFIG_DRIVERS_UART_8250MEM is not set -# CONFIG_DRIVERS_UART_8250MEM_32 is not set -# CONFIG_HAVE_UART_SPECIAL is not set -# CONFIG_DRIVERS_UART_OXPCIE is not set -# CONFIG_DRIVERS_UART_PL011 is not set -# CONFIG_UART_USE_REFCLK_AS_INPUT_CLOCK is not set -CONFIG_HAVE_USBDEBUG=y -CONFIG_HAVE_USBDEBUG_OPTIONS=y -# CONFIG_DRIVERS_AMD_PI is not set -CONFIG_DRIVERS_ASPEED_AST2050=y -CONFIG_DRIVERS_ASPEED_AST_COMMON=y -# CONFIG_SMBIOS_PROVIDED_BY_MOBO is not set -# CONFIG_DRIVERS_I2C_MAX98927 is not set -# CONFIG_DRIVERS_I2C_PCF8523 is not set -# CONFIG_DRIVERS_I2C_RT5663 is not set -# CONFIG_DRIVERS_I2C_RTD2132 is not set -# CONFIG_DRIVERS_I2C_RX6110SA is not set -# CONFIG_I2C_TPM is not set -# CONFIG_MAINBOARD_HAS_I2C_TPM_ATMEL is not set -# CONFIG_MAINBOARD_HAS_I2C_TPM_CR50 is not set -CONFIG_DRIVERS_I2C_W83795=y -# CONFIG_INTEL_DDI is not set -# CONFIG_INTEL_EDID is not set -# CONFIG_INTEL_INT15 is not set -# CONFIG_INTEL_GMA_ACPI is not set -# CONFIG_INTEL_GMA_SSC_ALTERNATE_REF is not set -# CONFIG_DRIVER_INTEL_I210 is not set -# CONFIG_DRIVERS_INTEL_MIPI_CAMERA is not set # CONFIG_DRIVERS_INTEL_WIFI is not set -# CONFIG_USE_SAR is not set -# CONFIG_DRIVERS_LENOVO_HYBRID_GRAPHICS is not set -# CONFIG_DRIVER_MAXIM_MAX77686 is not set -# CONFIG_DRIVER_PARADE_PS8625 is not set -# CONFIG_DRIVER_PARADE_PS8640 is not set -CONFIG_DRIVERS_MC146818=y -CONFIG_MAINBOARD_HAS_LPC_TPM=y -CONFIG_LPC_TPM=y -CONFIG_TPM_TIS_BASE_ADDRESS=0xfed40000 -# CONFIG_TPM_INIT_FAILURE_IS_FATAL is not set -# CONFIG_SKIP_TPM_STARTUP_ON_NORMAL_BOOT is not set -# CONFIG_TPM_DEACTIVATE is not set -CONFIG_VGA=y -# CONFIG_DRIVERS_RICOH_RCE822 is not set -# CONFIG_DRIVER_SIEMENS_NC_FPGA is not set -# CONFIG_NC_FPGA_NOTIFY_CB_READY is not set -# CONFIG_DRIVERS_SIL_3114 is not set -# CONFIG_SPI_TPM is not set -# CONFIG_MAINBOARD_HAS_SPI_TPM_CR50 is not set -# CONFIG_DRIVER_TI_TPS65090 is not set -# CONFIG_DRIVERS_TI_TPS65913 is not set -# CONFIG_DRIVERS_TI_TPS65913_RTC is not set -# CONFIG_DRIVER_XPOWERS_AXP209 is not set -# CONFIG_COMMONLIB_STORAGE is not set - -# -# Security -# - -# -# Verified Boot (vboot) -# -# CONFIG_ACPI_SATA_GENERATOR is not set -# CONFIG_ACPI_INTEL_HARDWARE_SLEEP_VALUES is not set -# CONFIG_ACPI_AMD_HARDWARE_SLEEP_VALUES is not set -# CONFIG_BOOT_DEVICE_NOT_SPI_FLASH is not set -CONFIG_BOOT_DEVICE_SPI_FLASH=y -CONFIG_BOOT_DEVICE_MEMORY_MAPPED=y -# CONFIG_BOOT_DEVICE_SUPPORTS_WRITES is not set -# CONFIG_RTC is not set -# CONFIG_TPM is not set -CONFIG_TPM2=y -# CONFIG_MAINBOARD_HAS_TPM_CR50 is not set - -# -# Console -# -CONFIG_SQUELCH_EARLY_SMP=y -CONFIG_CONSOLE_SERIAL=y - -# -# I/O mapped, 8250-compatible -# - -# -# Serial port base address = 0x2f8 -# -# CONFIG_CONSOLE_SERIAL_921600 is not set -# CONFIG_CONSOLE_SERIAL_460800 is not set -# CONFIG_CONSOLE_SERIAL_230400 is not set -CONFIG_CONSOLE_SERIAL_115200=y -# CONFIG_CONSOLE_SERIAL_57600 is not set -# CONFIG_CONSOLE_SERIAL_38400 is not set -# CONFIG_CONSOLE_SERIAL_19200 is not set -# CONFIG_CONSOLE_SERIAL_9600 is not set -# CONFIG_SPKMODEM is not set -# CONFIG_CONSOLE_NE2K is not set -CONFIG_CONSOLE_CBMEM_BUFFER_SIZE=0x20000 -# CONFIG_CONSOLE_SPI_FLASH is not set CONFIG_DEFAULT_CONSOLE_LOGLEVEL_8=y -# CONFIG_DEFAULT_CONSOLE_LOGLEVEL_7 is not set -# CONFIG_DEFAULT_CONSOLE_LOGLEVEL_6 is not set -# CONFIG_DEFAULT_CONSOLE_LOGLEVEL_5 is not set -# CONFIG_DEFAULT_CONSOLE_LOGLEVEL_4 is not set -# CONFIG_DEFAULT_CONSOLE_LOGLEVEL_3 is not set -# CONFIG_DEFAULT_CONSOLE_LOGLEVEL_2 is not set -# CONFIG_DEFAULT_CONSOLE_LOGLEVEL_1 is not set -# CONFIG_DEFAULT_CONSOLE_LOGLEVEL_0 is not set -# CONFIG_CMOS_POST is not set -# CONFIG_CONSOLE_POST is not set -CONFIG_POST_DEVICE_NONE=y -# CONFIG_POST_DEVICE_LPC is not set -# CONFIG_POST_DEVICE_PCI_PCIE is not set -CONFIG_POST_IO_PORT=0x80 -# CONFIG_NO_EARLY_BOOTBLOCK_POSTCODES is not set -CONFIG_HWBASE_DEBUG_CB=y -CONFIG_HAVE_ACPI_RESUME=y -CONFIG_ACPI_HUGE_LOWMEM_BACKUP=y -CONFIG_RESUME_PATH_SAME_AS_BOOT=y -CONFIG_HAVE_HARD_RESET=y -CONFIG_HAVE_ROMSTAGE_CONSOLE_SPINLOCK=y -CONFIG_HAVE_ROMSTAGE_NVRAM_CBFS_SPINLOCK=y -CONFIG_HAVE_ROMSTAGE_MICROCODE_CBFS_SPINLOCK=y -CONFIG_HAVE_MONOTONIC_TIMER=y -# CONFIG_GENERIC_UDELAY is not set -# CONFIG_TIMER_QUEUE is not set -CONFIG_HAVE_OPTION_TABLE=y -# CONFIG_PIRQ_ROUTE is not set -# CONFIG_HAVE_SMI_HANDLER is not set -CONFIG_PCI_IO_CFG_EXT=y -CONFIG_IOAPIC=y -# CONFIG_USE_WATCHDOG_ON_BOOT is not set -# CONFIG_GFXUMA is not set -CONFIG_HAVE_ACPI_TABLES=y -CONFIG_HAVE_MP_TABLE=y -CONFIG_HAVE_PIRQ_TABLE=y -# CONFIG_COMMON_FADT is not set -# CONFIG_ACPI_NHLT is not set - -# -# System tables -# -CONFIG_GENERATE_MP_TABLE=y -CONFIG_GENERATE_PIRQ_TABLE=y -CONFIG_GENERATE_SMBIOS_TABLES=y - -# -# Payload -# -# CONFIG_PAYLOAD_NONE is not set -# CONFIG_PAYLOAD_ELF is not set -# CONFIG_PAYLOAD_BAYOU is not set -# CONFIG_PAYLOAD_FILO is not set -# CONFIG_PAYLOAD_GRUB2 is not set -# CONFIG_PAYLOAD_SEABIOS is not set -# CONFIG_PAYLOAD_UBOOT is not set CONFIG_PAYLOAD_LINUX=y -# CONFIG_PAYLOAD_TIANOCORE is not set CONFIG_PAYLOAD_FILE="../../build/kgpe-d16/bzImage" -CONFIG_PAYLOAD_OPTIONS="" -# CONFIG_PXE is not set CONFIG_LINUX_COMMAND_LINE="nohz=on console=ttyS1,115200n8 earlyprintk=ttyS1,115200" CONFIG_LINUX_INITRD="../../build/kgpe-d16/initrd.cpio.xz" -# CONFIG_PAYLOAD_IS_FLAT_BINARY is not set - -# -# Secondary Payloads -# -# CONFIG_COREINFO_SECONDARY_PAYLOAD is not set -# CONFIG_MEMTEST_SECONDARY_PAYLOAD is not set -# CONFIG_NVRAMCUI_SECONDARY_PAYLOAD is not set -# CONFIG_TINT_SECONDARY_PAYLOAD is not set - -# -# Debugging -# -# CONFIG_GDB_STUB is not set -# CONFIG_FATAL_ASSERTS is not set -# CONFIG_DEBUG_CBFS is not set -CONFIG_HAVE_DEBUG_RAM_SETUP=y -# CONFIG_DEBUG_RAM_SETUP is not set -CONFIG_HAVE_DEBUG_CAR=y -# CONFIG_DEBUG_CAR is not set -# CONFIG_DEBUG_PIRQ is not set -CONFIG_HAVE_DEBUG_SMBUS=y -# CONFIG_DEBUG_SMBUS is not set -# CONFIG_DEBUG_MALLOC is not set -# CONFIG_DEBUG_ACPI is not set -# CONFIG_DEBUG_TPM is not set -# CONFIG_DEBUG_SPI_FLASH is not set -# CONFIG_TRACE is not set -# CONFIG_DEBUG_BOOT_STATE is not set -# CONFIG_DEBUG_ADA_CODE is not set -CONFIG_ENABLE_APIC_EXT_ID=y -CONFIG_WARNINGS_ARE_ERRORS=y -# CONFIG_POWER_BUTTON_DEFAULT_ENABLE is not set -# CONFIG_POWER_BUTTON_DEFAULT_DISABLE is not set -# CONFIG_POWER_BUTTON_FORCE_ENABLE is not set -# CONFIG_POWER_BUTTON_FORCE_DISABLE is not set -# CONFIG_POWER_BUTTON_IS_OPTIONAL is not set -# CONFIG_REG_SCRIPT is not set -# CONFIG_CREATE_BOARD_CHECKLIST is not set -# CONFIG_MAKE_CHECKLIST_PUBLIC is not set -# CONFIG_NO_XIP_EARLY_STAGES is not set -CONFIG_EARLY_CBMEM_INIT=y -# CONFIG_EARLY_CBMEM_LIST is not set -CONFIG_BOOTBLOCK_CUSTOM=y diff --git a/config/coreboot-librem13v2.config b/config/coreboot-librem13v2.config index 74c4a565..f05c1d12 100644 --- a/config/coreboot-librem13v2.config +++ b/config/coreboot-librem13v2.config @@ -1,742 +1,32 @@ -# -# Automatically generated file; DO NOT EDIT. -# coreboot configuration -# - -# -# General setup -# -CONFIG_COREBOOT_BUILD=y CONFIG_LOCALVERSION="4.7-Purism-4-heads" -CONFIG_CBFS_PREFIX="fallback" -CONFIG_COMPILER_GCC=y -# CONFIG_COMPILER_LLVM_CLANG is not set -# CONFIG_ANY_TOOLCHAIN is not set -# CONFIG_CCACHE is not set -# CONFIG_FMD_GENPARSER is not set -# CONFIG_UTIL_GENPARSER is not set -CONFIG_COMPRESS_RAMSTAGE=y -CONFIG_INCLUDE_CONFIG_FILE=y -CONFIG_COLLECT_TIMESTAMPS=y CONFIG_USE_BLOBS=y -# CONFIG_COVERAGE is not set -# CONFIG_UBSAN is not set -CONFIG_RELOCATABLE_RAMSTAGE=y -CONFIG_CACHE_RELOCATED_RAMSTAGE_OUTSIDE_CBMEM=y -# CONFIG_UPDATE_IMAGE is not set -# CONFIG_BOOTSPLASH_IMAGE is not set CONFIG_MEASURED_BOOT=y - -# -# Mainboard -# - -# -# Important: Run 'make distclean' before switching boards -# -# CONFIG_VENDOR_A_TREND is not set -# CONFIG_VENDOR_AAEON is not set -# CONFIG_VENDOR_ABIT is not set -# CONFIG_VENDOR_ADI is not set -# CONFIG_VENDOR_ADLINK is not set -# CONFIG_VENDOR_ADVANSUS is not set -# CONFIG_VENDOR_AMD is not set -# CONFIG_VENDOR_AOPEN is not set -# CONFIG_VENDOR_APPLE is not set -# CONFIG_VENDOR_ARTECGROUP is not set -# CONFIG_VENDOR_ASROCK is not set -# CONFIG_VENDOR_ASUS is not set -# CONFIG_VENDOR_AVALUE is not set -# CONFIG_VENDOR_AZZA is not set -# CONFIG_VENDOR_BACHMANN is not set -# CONFIG_VENDOR_BAP is not set -# CONFIG_VENDOR_BCOM is not set -# CONFIG_VENDOR_BIOSTAR is not set -# CONFIG_VENDOR_BROADCOM is not set -# CONFIG_VENDOR_COMPAQ is not set -# CONFIG_VENDOR_COMPULAB is not set -# CONFIG_VENDOR_CUBIETECH is not set -# CONFIG_VENDOR_DIGITALLOGIC is not set -# CONFIG_VENDOR_DMP is not set -# CONFIG_VENDOR_ECS is not set -# CONFIG_VENDOR_ELMEX is not set -# CONFIG_VENDOR_EMULATION is not set -# CONFIG_VENDOR_ESD is not set -# CONFIG_VENDOR_FOXCONN is not set -# CONFIG_VENDOR_GETAC is not set -# CONFIG_VENDOR_GIGABYTE is not set -# CONFIG_VENDOR_GIZMOSPHERE is not set -# CONFIG_VENDOR_GOOGLE is not set -# CONFIG_VENDOR_HP is not set -# CONFIG_VENDOR_IBASE is not set -# CONFIG_VENDOR_IEI is not set -# CONFIG_VENDOR_INTEL is not set -# CONFIG_VENDOR_IWAVE is not set -# CONFIG_VENDOR_IWILL is not set -# CONFIG_VENDOR_JETWAY is not set -# CONFIG_VENDOR_KONTRON is not set -# CONFIG_VENDOR_LANNER is not set -# CONFIG_VENDOR_LENOVO is not set -# CONFIG_VENDOR_LINUTOP is not set -# CONFIG_VENDOR_LIPPERT is not set -# CONFIG_VENDOR_LOWRISC is not set -# CONFIG_VENDOR_MITAC is not set -# CONFIG_VENDOR_MSI is not set -# CONFIG_VENDOR_NEC is not set -# CONFIG_VENDOR_NOKIA is not set -# CONFIG_VENDOR_NVIDIA is not set -# CONFIG_VENDOR_PACKARDBELL is not set -# CONFIG_VENDOR_PCENGINES is not set CONFIG_VENDOR_PURISM=y -# CONFIG_VENDOR_RCA is not set -# CONFIG_VENDOR_RODA is not set -# CONFIG_VENDOR_SAMSUNG is not set -# CONFIG_VENDOR_SAPPHIRE is not set -# CONFIG_VENDOR_SIEMENS is not set -# CONFIG_VENDOR_SOYO is not set -# CONFIG_VENDOR_SUNW is not set -# CONFIG_VENDOR_SUPERMICRO is not set -# CONFIG_VENDOR_TECHNEXION is not set -# CONFIG_VENDOR_THOMSON is not set -# CONFIG_VENDOR_TI is not set -# CONFIG_VENDOR_TRAVERSE is not set -# CONFIG_VENDOR_TYAN is not set -# CONFIG_VENDOR_VIA is not set -# CONFIG_VENDOR_WINENT is not set -# CONFIG_VENDOR_WINNET is not set -# CONFIG_VENDOR_WYSE is not set -CONFIG_MAINBOARD_DIR="purism/librem_skl" -CONFIG_MAINBOARD_PART_NUMBER="Librem 13 v2" -CONFIG_IRQ_SLOT_COUNT=18 -CONFIG_MAINBOARD_VENDOR="Purism" -CONFIG_MAX_CPUS=8 -CONFIG_CACHE_ROM_SIZE_OVERRIDE=0x0 CONFIG_CBFS_SIZE=0xe00000 -CONFIG_UART_FOR_CONSOLE=0 -CONFIG_VGA_BIOS_ID="8086,1916" -# CONFIG_ONBOARD_VGA_IS_PRIMARY is not set -CONFIG_DIMM_SPD_SIZE=512 -# CONFIG_VGA_BIOS is not set CONFIG_MAINBOARD_SERIAL_NUMBER="Unknown Serial Number" -CONFIG_DCACHE_RAM_BASE=0xfef00000 -CONFIG_DCACHE_RAM_SIZE=0x40000 -CONFIG_MAINBOARD_SMBIOS_MANUFACTURER="Purism" CONFIG_HAVE_IFD_BIN=y CONFIG_HAVE_ME_BIN=y -CONFIG_MMCONF_BASE_ADDRESS=0xe0000000 # CONFIG_POST_IO is not set -CONFIG_DEVICETREE="variants/librem13v2/devicetree.cb" -CONFIG_MAX_REBOOT_CNT=3 -# CONFIG_HAVE_GBE_BIN is not set -CONFIG_ID_SECTION_OFFSET=0x80 # CONFIG_POST_DEVICE is not set -CONFIG_VARIANT_DIR="librem13v2" -# CONFIG_VBOOT is not set -CONFIG_MAINBOARD_FAMILY="Librem 13" -CONFIG_TPM_PIRQ=0x0 -CONFIG_DIMM_MAX=1 -CONFIG_BOOT_DEVICE_SPI_FLASH_BUS=0 -CONFIG_FMDFILE="" -CONFIG_PRERAM_CBMEM_CONSOLE_SIZE=0xc00 # CONFIG_DRIVERS_UART_8250IO is not set CONFIG_IFD_BIN_PATH="../../blobs/librem_skl/descriptor.bin" CONFIG_ME_BIN_PATH="../../blobs/librem_skl/me.bin" -CONFIG_MAINBOARD_SMBIOS_PRODUCT_NAME="Librem 13 v2" CONFIG_ADD_FSP_BINARIES=y CONFIG_FSP_M_FILE="../../blobs/librem_skl/fspm.bin" CONFIG_FSP_S_FILE="../../blobs/librem_skl/fsps.bin" -CONFIG_FSP_S_CBFS="fsps.bin" -CONFIG_FSP_M_CBFS="fspm.bin" -CONFIG_CPU_ADDR_BITS=36 -CONFIG_DEFAULT_CONSOLE_LOGLEVEL=8 -CONFIG_MAINBOARD_VERSION="2.0" -# CONFIG_DRIVERS_PS2_KEYBOARD is not set -# CONFIG_BOARD_PURISM_LIBREM13_V1 is not set CONFIG_BOARD_PURISM_LIBREM13_V2=y -# CONFIG_BOARD_PURISM_LIBREM15_V3 is not set -CONFIG_PCIEXP_L1_SUB_STATE=y # CONFIG_NO_POST is not set -CONFIG_BOARD_PURISM_BASEBOARD_LIBREM_SKL=y -CONFIG_CPU_MICROCODE_CBFS_LEN=0x18000 -CONFIG_CPU_MICROCODE_CBFS_LOC=0xFFE115A0 -CONFIG_BOARD_ROMSIZE_KB_16384=y -# CONFIG_COREBOOT_ROMSIZE_KB_64 is not set -# CONFIG_COREBOOT_ROMSIZE_KB_128 is not set -# CONFIG_COREBOOT_ROMSIZE_KB_256 is not set -# CONFIG_COREBOOT_ROMSIZE_KB_512 is not set -# CONFIG_COREBOOT_ROMSIZE_KB_1024 is not set -# CONFIG_COREBOOT_ROMSIZE_KB_2048 is not set -# CONFIG_COREBOOT_ROMSIZE_KB_4096 is not set -# CONFIG_COREBOOT_ROMSIZE_KB_8192 is not set -# CONFIG_COREBOOT_ROMSIZE_KB_10240 is not set -# CONFIG_COREBOOT_ROMSIZE_KB_12288 is not set -CONFIG_COREBOOT_ROMSIZE_KB_16384=y -# CONFIG_COREBOOT_ROMSIZE_KB_32768 is not set -# CONFIG_COREBOOT_ROMSIZE_KB_65536 is not set -CONFIG_COREBOOT_ROMSIZE_KB=16384 -CONFIG_ROM_SIZE=0x1000000 -# CONFIG_MAINBOARD_HAS_TPM2 is not set -CONFIG_SYSTEM_TYPE_LAPTOP=y -# CONFIG_CBFS_AUTOGEN_ATTRIBUTES is not set - -# -# Chipset -# - -# -# SoC -# -CONFIG_CPU_SPECIFIC_OPTIONS=y -CONFIG_DCACHE_BSP_STACK_SIZE=0x4000 -CONFIG_RAMTOP=0x200000 -CONFIG_HEAP_SIZE=0x80000 -CONFIG_RAMBASE=0x100000 -CONFIG_SERIRQ_CONTINUOUS_MODE=y -CONFIG_SMM_TSEG_SIZE=0x800000 -CONFIG_SMM_RESERVED_SIZE=0x200000 -CONFIG_ACPI_CPU_STRING="\\_PR.CP%02d" -CONFIG_DRIVERS_I2C_DESIGNWARE_CLOCK_MHZ=120 -# CONFIG_SOC_BROADCOM_CYGNUS is not set -# CONFIG_SOC_INTEL_GLK is not set -CONFIG_SOC_INTEL_COMMON_RESET=y -CONFIG_PCR_BASE_ADDRESS=0xfd000000 -CONFIG_SOC_INTEL_COMMON_LPSS_CLOCK_MHZ=120 -CONFIG_C_ENV_BOOTBLOCK_SIZE=0xC000 -CONFIG_X86_TOP4G_BOOTMEDIA_MAP=y -CONFIG_ROMSTAGE_ADDR=0x2000000 -CONFIG_VERSTAGE_ADDR=0x2000000 -# CONFIG_NHLT_MAX98357 is not set -# CONFIG_NHLT_DA7219 is not set -# CONFIG_SPI_FLASH_INCLUDE_ALL_DRIVERS is not set -CONFIG_CPU_BCLK_MHZ=100 -CONFIG_SOC_INTEL_COMMON_LPSS_UART_CLK_M_VAL=0x30 -CONFIG_SOC_INTEL_COMMON_LPSS_UART_CLK_N_VAL=0xc35 -# CONFIG_RESET_ON_INVALID_RAMSTAGE_CACHE is not set -CONFIG_CHIPSET_BOOTBLOCK_INCLUDE="soc/intel/skylake/bootblock/timestamp.inc" -CONFIG_IED_REGION_SIZE=0x400000 -CONFIG_PCIEXP_ASPM=y -CONFIG_PCIEXP_COMMON_CLOCK=y -CONFIG_PCIEXP_CLK_PM=y -# CONFIG_SERIAL_CPU_INIT is not set -# CONFIG_UART_DEBUG is not set -CONFIG_MAX_ROOT_PORTS=24 -CONFIG_SOC_INTEL_COMMON_BLOCK_GSPI_MAX=2 -CONFIG_STACK_SIZE=0x1000 -CONFIG_CONSOLE_CBMEM=y -CONFIG_UART_PCI_ADDR=0x0 -CONFIG_SOC_INTEL_SKYLAKE=y -# CONFIG_SOC_INTEL_KABYLAKE is not set -CONFIG_MAINBOARD_USES_FSP2_0=y -CONFIG_USE_FSP2_0_DRIVER=y -CONFIG_BOOTBLOCK_RESETS="soc/intel/common/reset.c" -# CONFIG_EXCLUDE_NATIVE_SD_INTERFACE is not set -# CONFIG_SKYLAKE_SOC_PCH_H is not set -# CONFIG_NHLT_DMIC_2CH is not set -# CONFIG_NHLT_DMIC_4CH is not set -# CONFIG_NHLT_NAU88L25 is not set -# CONFIG_NHLT_SSM4567 is not set -# CONFIG_NHLT_RT5514 is not set -# CONFIG_NHLT_RT5663 is not set -# CONFIG_NHLT_MAX98927 is not set -CONFIG_CAR_NEM_ENHANCED=y -# CONFIG_USE_SKYLAKE_FSP_CAR is not set -CONFIG_SKIP_FSP_CAR=y -# CONFIG_NO_FADT_8042 is not set -CONFIG_SOC_INTEL_COMMON=y - -# -# Intel SoC Common Code -# -CONFIG_SOC_INTEL_COMMON_BLOCK=y - -# -# Intel SoC Common IP Code -# -CONFIG_SOC_INTEL_COMMON_BLOCK_CPU=y -CONFIG_SOC_INTEL_COMMON_BLOCK_CPU_MPINIT=y -CONFIG_SOC_INTEL_COMMON_BLOCK_CAR=y -# CONFIG_INTEL_CAR_NEM is not set -# CONFIG_INTEL_CAR_CQOS is not set -CONFIG_INTEL_CAR_NEM_ENHANCED=y -CONFIG_SOC_INTEL_COMMON_BLOCK_CSE=y -CONFIG_SOC_INTEL_COMMON_BLOCK_DSP=y -CONFIG_SOC_INTEL_COMMON_BLOCK_EBDA=y -CONFIG_SOC_INTEL_COMMON_BLOCK_FAST_SPI=y -CONFIG_FAST_SPI_DISABLE_WRITE_STATUS=y -CONFIG_SOC_INTEL_COMMON_BLOCK_GPIO=y -# CONFIG_DEBUG_SOC_COMMON_BLOCK_GPIO is not set -# CONFIG_SOC_INTEL_COMMON_BLOCK_GPIO_ITSS_POL_CFG is not set -CONFIG_SOC_INTEL_COMMON_BLOCK_GPIO_PADCFG_PADTOL=y -# CONFIG_SOC_INTEL_COMMON_BLOCK_GPIO_IOSTANDBY is not set -CONFIG_SOC_INTEL_COMMON_BLOCK_GPIO_LEGACY_MACROS=y -# CONFIG_SOC_INTEL_COMMON_BLOCK_GPIO_MULTI_ACPI_DEVICES is not set -CONFIG_SOC_INTEL_COMMON_BLOCK_GRAPHICS=y -CONFIG_SOC_INTEL_COMMON_BLOCK_GSPI=y -# CONFIG_SOC_INTEL_COMMON_BLOCK_GSPI_VERSION_2 is not set -CONFIG_SOC_INTEL_COMMON_BLOCK_I2C=y -# CONFIG_SOC_INTEL_COMMON_BLOCK_I2C_DEBUG is not set -CONFIG_SOC_INTEL_COMMON_BLOCK_ITSS=y -CONFIG_SOC_INTEL_COMMON_BLOCK_LPC=y -CONFIG_SOC_INTEL_COMMON_BLOCK_LPSS=y -CONFIG_SOC_INTEL_COMMON_BLOCK_PCIE=y -CONFIG_SOC_INTEL_COMMON_BLOCK_PCR=y -CONFIG_SOC_INTEL_COMMON_BLOCK_PMC=y -# CONFIG_POWER_STATE_OFF_AFTER_FAILURE is not set -CONFIG_POWER_STATE_ON_AFTER_FAILURE=y -# CONFIG_POWER_STATE_PREVIOUS_AFTER_FAILURE is not set -CONFIG_SOC_INTEL_COMMON_BLOCK_RTC=y -CONFIG_SOC_INTEL_COMMON_BLOCK_SATA=y -CONFIG_SOC_INTEL_COMMON_BLOCK_SCS=y -CONFIG_SOC_INTEL_COMMON_BLOCK_SGX=y -CONFIG_SOC_INTEL_COMMON_BLOCK_SMBUS=y -CONFIG_SOC_INTEL_COMMON_BLOCK_SMM=y -CONFIG_SOC_INTEL_COMMON_BLOCK_SMM_IO_TRAP=y -CONFIG_SOC_INTEL_COMMON_BLOCK_SPI=y -CONFIG_SOC_INTEL_COMMON_BLOCK_SA=y -CONFIG_SA_PCIEX_LENGTH=0x4000000 -CONFIG_PCIEX_LENGTH_64MB=y -# CONFIG_SA_ENABLE_IMR is not set -CONFIG_SA_ENABLE_DPR=y -CONFIG_SOC_INTEL_COMMON_BLOCK_TIMER=y -CONFIG_SOC_INTEL_COMMON_BLOCK_UART=y -CONFIG_SOC_INTEL_COMMON_BLOCK_XHCI=y -# CONFIG_DISPLAY_MTRRS is not set -# CONFIG_DISPLAY_SMM_MEMORY_MAP is not set -CONFIG_SOC_INTEL_COMMON_ACPI_WAKE_SOURCE=y -# CONFIG_ACPI_CONSOLE is not set -# CONFIG_MMA is not set -CONFIG_SOC_INTEL_COMMON_GFX_OPREGION=y -# CONFIG_SOC_INTEL_COMMON_SMI is not set -# CONFIG_SOC_INTEL_COMMON_ACPI is not set -CONFIG_SOC_INTEL_COMMON_NHLT=y -# CONFIG_SOC_LOWRISC_LOWRISC is not set -# CONFIG_SOC_MARVELL_MVMAP2315 is not set -# CONFIG_SOC_MEDIATEK_MT8173 is not set -# CONFIG_SOC_NVIDIA_TEGRA124 is not set -# CONFIG_SOC_NVIDIA_TEGRA210 is not set -# CONFIG_SOC_QC_IPQ40XX is not set -# CONFIG_SOC_QC_IPQ806X is not set -# CONFIG_SOC_ROCKCHIP_RK3288 is not set -# CONFIG_SOC_ROCKCHIP_RK3399 is not set -# CONFIG_CPU_SAMSUNG_EXYNOS5250 is not set -# CONFIG_CPU_SAMSUNG_EXYNOS5420 is not set -# CONFIG_SOC_UCB_RISCV is not set - -# -# CPU -# -# CONFIG_CPU_ALLWINNER_A10 is not set -CONFIG_NUM_IPI_STARTS=2 -# CONFIG_CPU_AMD_AGESA is not set -# CONFIG_CPU_AMD_PI is not set -# CONFIG_CPU_ARMLTD_CORTEX_A9 is not set -CONFIG_SSE2=y -CONFIG_CPU_INTEL_FIRMWARE_INTERFACE_TABLE=y -CONFIG_CPU_INTEL_NUM_FIT_ENTRIES=4 -# CONFIG_CPU_INTEL_TURBO_NOT_PACKAGE_SCOPED is not set -# CONFIG_CPU_TI_AM335X is not set -# CONFIG_PARALLEL_CPU_INIT is not set -CONFIG_PARALLEL_MP=y -CONFIG_PARALLEL_MP_AP_WORK=y -# CONFIG_UDELAY_IO is not set -# CONFIG_UDELAY_LAPIC is not set -CONFIG_UDELAY_TSC=y -CONFIG_TSC_CONSTANT_RATE=y -CONFIG_TSC_MONOTONIC_TIMER=y -# CONFIG_UDELAY_TIMER2 is not set -# CONFIG_TSC_SYNC_LFENCE is not set -CONFIG_TSC_SYNC_MFENCE=y -CONFIG_NO_FIXED_XIP_ROM_SIZE=y -CONFIG_LOGICAL_CPUS=y -CONFIG_SMM_TSEG=y -CONFIG_SMM_MODULE_HEAP_SIZE=0x4000 -# CONFIG_SMM_LAPIC_REMAP_MITIGATION is not set -# CONFIG_SERIALIZED_SMM_INITIALIZATION is not set -# CONFIG_X86_AMD_FIXED_MTRRS is not set -# CONFIG_PLATFORM_USES_FSP1_0 is not set -# CONFIG_MIRROR_PAYLOAD_TO_RAM_BEFORE_LOADING is not set -# CONFIG_SOC_SETS_MSRS is not set -CONFIG_CACHE_AS_RAM=y -CONFIG_NO_CAR_GLOBAL_MIGRATION=y -CONFIG_SMP=y -CONFIG_AP_SIPI_VECTOR=0xfffff000 -CONFIG_SSE=y -CONFIG_SUPPORT_CPU_UCODE_IN_CBFS=y -# CONFIG_USES_MICROCODE_HEADER_FILES is not set -CONFIG_CPU_MICROCODE_CBFS_GENERATE=y -# CONFIG_CPU_MICROCODE_CBFS_EXTERNAL_HEADER is not set -# CONFIG_CPU_MICROCODE_CBFS_NONE is not set -# CONFIG_CPU_MICROCODE_MULTIPLE_FILES is not set CONFIG_CPU_UCODE_BINARIES="../../blobs/librem_skl/cpu_microcode_blob.bin" - -# -# Northbridge -# -# CONFIG_NORTHBRIDGE_AMD_AGESA is not set -# CONFIG_NO_MMCONF_SUPPORT is not set -# CONFIG_AMD_NB_CIMX is not set -# CONFIG_NORTHBRIDGE_AMD_CIMX_RD890 is not set -# CONFIG_NORTHBRIDGE_AMD_PI is not set -# CONFIG_NORTHBRIDGE_INTEL_COMMON_MRC_CACHE is not set -CONFIG_HPET_ADDRESS=0xfed00000 -CONFIG_MAX_PIRQ_LINKS=4 - -# -# Southbridge -# -# CONFIG_AMD_SB_CIMX is not set -# CONFIG_SOUTHBRIDGE_AMD_CIMX_SB800 is not set -# CONFIG_SOUTHBRIDGE_AMD_CIMX_SB900 is not set -# CONFIG_SOUTHBRIDGE_INTEL_COMMON is not set -# CONFIG_SOUTHBRIDGE_INTEL_COMMON_GPIO is not set -# CONFIG_SOUTHBRIDGE_INTEL_COMMON_SMBUS is not set -# CONFIG_SOUTHBRIDGE_INTEL_COMMON_SPI is not set -# CONFIG_SOUTHBRIDGE_INTEL_COMMON_PIRQ_ACPI_GEN is not set -# CONFIG_SOUTHBRIDGE_INTEL_COMMON_RCBA_PIRQ is not set -# CONFIG_HAVE_INTEL_CHIPSET_LOCKDOWN is not set -# CONFIG_LOCK_MANAGEMENT_ENGINE is not set - -# -# Super I/O -# -# CONFIG_SUPERIO_NUVOTON_NCT6776_COM_A is not set - -# -# Embedded Controllers -# -CONFIG_HAVE_INTEL_FIRMWARE=y - -# -# Intel Firmware -# -# CONFIG_EM100 is not set -# CONFIG_CHECK_ME is not set -# CONFIG_USE_ME_CLEANER is not set -# CONFIG_HAVE_EC_BIN is not set -# CONFIG_MAINBOARD_HAS_CHROMEOS is not set -# CONFIG_GOOGLE_SMBIOS_MAINBOARD_VERSION is not set -# CONFIG_UEFI_2_4_BINDING is not set -CONFIG_UDK_2015_BINDING=y -# CONFIG_USE_SIEMENS_HWILIB is not set -# CONFIG_ARCH_ARM is not set -# CONFIG_ARCH_BOOTBLOCK_ARM is not set -# CONFIG_ARCH_VERSTAGE_ARM is not set -# CONFIG_ARCH_ROMSTAGE_ARM is not set -# CONFIG_ARCH_RAMSTAGE_ARM is not set -# CONFIG_ARCH_BOOTBLOCK_ARMV4 is not set -# CONFIG_ARCH_VERSTAGE_ARMV4 is not set -# CONFIG_ARCH_ROMSTAGE_ARMV4 is not set -# CONFIG_ARCH_RAMSTAGE_ARMV4 is not set -# CONFIG_ARCH_BOOTBLOCK_ARMV7 is not set -# CONFIG_ARCH_VERSTAGE_ARMV7 is not set -# CONFIG_ARCH_ROMSTAGE_ARMV7 is not set -# CONFIG_ARCH_RAMSTAGE_ARMV7 is not set -# CONFIG_ARCH_BOOTBLOCK_ARMV7_M is not set -# CONFIG_ARCH_VERSTAGE_ARMV7_M is not set -# CONFIG_ARCH_BOOTBLOCK_ARMV7_R is not set -# CONFIG_ARCH_VERSTAGE_ARMV7_R is not set -# CONFIG_ARCH_ROMSTAGE_ARMV7_R is not set -# CONFIG_ARCH_RAMSTAGE_ARMV7_R is not set -# CONFIG_ARM_LPAE is not set -# CONFIG_ARCH_ARM64 is not set -# CONFIG_ARCH_BOOTBLOCK_ARM64 is not set -# CONFIG_ARCH_VERSTAGE_ARM64 is not set -# CONFIG_ARCH_ROMSTAGE_ARM64 is not set -# CONFIG_ARCH_RAMSTAGE_ARM64 is not set -# CONFIG_ARCH_BOOTBLOCK_ARMV8_64 is not set -# CONFIG_ARCH_VERSTAGE_ARMV8_64 is not set -# CONFIG_ARCH_ROMSTAGE_ARMV8_64 is not set -# CONFIG_ARCH_RAMSTAGE_ARMV8_64 is not set -# CONFIG_ARM64_A53_ERRATUM_843419 is not set -# CONFIG_ARCH_MIPS is not set -# CONFIG_ARCH_BOOTBLOCK_MIPS is not set -# CONFIG_ARCH_VERSTAGE_MIPS is not set -# CONFIG_ARCH_ROMSTAGE_MIPS is not set -# CONFIG_ARCH_RAMSTAGE_MIPS is not set -# CONFIG_ARCH_POWER8 is not set -# CONFIG_ARCH_BOOTBLOCK_POWER8 is not set -# CONFIG_ARCH_VERSTAGE_POWER8 is not set -# CONFIG_ARCH_ROMSTAGE_POWER8 is not set -# CONFIG_ARCH_RAMSTAGE_POWER8 is not set -# CONFIG_ARCH_RISCV is not set -# CONFIG_ARCH_BOOTBLOCK_RISCV is not set -# CONFIG_ARCH_VERSTAGE_RISCV is not set -# CONFIG_ARCH_ROMSTAGE_RISCV is not set -# CONFIG_ARCH_RAMSTAGE_RISCV is not set -CONFIG_ARCH_X86=y -CONFIG_ARCH_BOOTBLOCK_X86_32=y -CONFIG_ARCH_VERSTAGE_X86_32=y -CONFIG_ARCH_ROMSTAGE_X86_32=y -CONFIG_ARCH_RAMSTAGE_X86_32=y -# CONFIG_ARCH_BOOTBLOCK_X86_64 is not set -# CONFIG_ARCH_VERSTAGE_X86_64 is not set -# CONFIG_ARCH_ROMSTAGE_X86_64 is not set -# CONFIG_ARCH_RAMSTAGE_X86_64 is not set -# CONFIG_USE_MARCH_586 is not set -# CONFIG_AP_IN_SIPI_WAIT is not set -# CONFIG_SIPI_VECTOR_IN_ROM is not set -# CONFIG_ROMCC is not set -# CONFIG_CBMEM_TOP_BACKUP is not set -# CONFIG_LATE_CBMEM_INIT is not set -CONFIG_EARLY_EBDA_INIT=y -CONFIG_PC80_SYSTEM=y -# CONFIG_BOOTBLOCK_DEBUG_SPINLOOP is not set -# CONFIG_BOOTBLOCK_SAVE_BIST_AND_TIMESTAMP is not set -CONFIG_IOAPIC_INTERRUPTS_ON_FSB=y -# CONFIG_IOAPIC_INTERRUPTS_ON_APIC_SERIAL_BUS is not set -CONFIG_POSTCAR_STAGE=y -# CONFIG_VERSTAGE_DEBUG_SPINLOOP is not set -# CONFIG_ROMSTAGE_DEBUG_SPINLOOP is not set -CONFIG_BOOTBLOCK_SIMPLE=y -# CONFIG_BOOTBLOCK_NORMAL is not set -CONFIG_BOOTBLOCK_SOURCE="bootblock_simple.c" - -# -# Devices -# -CONFIG_HAVE_FSP_GOP=y -# CONFIG_MAINBOARD_HAS_NATIVE_VGA_INIT is not set -# CONFIG_MAINBOARD_HAS_LIBGFXINIT is not set -# CONFIG_RUN_FSP_GOP is not set -# CONFIG_VGA_ROM_RUN is not set CONFIG_NO_GFX_INIT=y -# CONFIG_MULTIPLE_VGA_ADAPTERS is not set -# CONFIG_SMBUS_HAS_AUX_CHANNELS is not set -CONFIG_PCI=y -CONFIG_MMCONF_SUPPORT=y -# CONFIG_HYPERTRANSPORT_PLUGIN_SUPPORT is not set -CONFIG_PCIX_PLUGIN_SUPPORT=y -CONFIG_CARDBUS_PLUGIN_SUPPORT=y -# CONFIG_AZALIA_PLUGIN_SUPPORT is not set -CONFIG_PCIEXP_PLUGIN_SUPPORT=y -# CONFIG_EARLY_PCI_BRIDGE is not set -CONFIG_SUBSYSTEM_VENDOR_ID=0x0000 -CONFIG_SUBSYSTEM_DEVICE_ID=0x0000 CONFIG_INTEL_GMA_ADD_VBT_DATA_FILE=y CONFIG_INTEL_GMA_VBT_FILE="../../blobs/librem_skl/vbt.bin" -# CONFIG_SOFTWARE_I2C is not set - -# -# Generic Drivers -# -# CONFIG_DRIVERS_AS3722_RTC is not set -# CONFIG_ELOG is not set -# CONFIG_GIC is not set -# CONFIG_IPMI_KCS is not set -# CONFIG_DRIVERS_LENOVO_WACOM is not set -CONFIG_CACHE_MRC_SETTINGS=y -CONFIG_MRC_SETTINGS_CACHE_BASE=0xfffe0000 -CONFIG_MRC_SETTINGS_CACHE_SIZE=0x10000 -CONFIG_MRC_SETTINGS_PROTECT=y -# CONFIG_HAS_RECOVERY_MRC_CACHE is not set -# CONFIG_MRC_CLEAR_NORMAL_CACHE_ON_RECOVERY_RETRAIN is not set -# CONFIG_MRC_SETTINGS_VARIABLE_DATA is not set -# CONFIG_RT8168_GET_MAC_FROM_VPD is not set -# CONFIG_RT8168_SET_LED_MODE is not set -CONFIG_SPI_FLASH=y -CONFIG_BOOT_DEVICE_SPI_FLASH_RW_NOMMAP=y -CONFIG_BOOT_DEVICE_SPI_FLASH_RW_NOMMAP_EARLY=y -# CONFIG_SPI_FLASH_SMM is not set -# CONFIG_SPI_FLASH_NO_FAST_READ is not set -# CONFIG_SPI_FLASH_FAST_READ_DUAL_OUTPUT_3B is not set -# CONFIG_SPI_FLASH_HAS_VOLATILE_GROUP is not set -# CONFIG_HAVE_SPI_CONSOLE_SUPPORT is not set -# CONFIG_DRIVERS_UART is not set -# CONFIG_NO_UART_ON_SUPERIO is not set -# CONFIG_UART_OVERRIDE_INPUT_CLOCK_DIVIDER is not set -# CONFIG_UART_OVERRIDE_REFCLK is not set -# CONFIG_DRIVERS_UART_8250MEM is not set -# CONFIG_DRIVERS_UART_8250MEM_32 is not set -# CONFIG_HAVE_UART_SPECIAL is not set -# CONFIG_DRIVERS_UART_OXPCIE is not set -# CONFIG_DRIVERS_UART_PL011 is not set -# CONFIG_UART_USE_REFCLK_AS_INPUT_CLOCK is not set -# CONFIG_HAVE_USBDEBUG is not set -# CONFIG_HAVE_USBDEBUG_OPTIONS is not set -# CONFIG_DRIVERS_AMD_PI is not set -# CONFIG_SMBIOS_PROVIDED_BY_MOBO is not set -CONFIG_DRIVERS_I2C_DESIGNWARE=y -# CONFIG_DRIVERS_I2C_DESIGNWARE_DEBUG is not set -# CONFIG_DRIVERS_I2C_MAX98927 is not set -# CONFIG_DRIVERS_I2C_PCF8523 is not set -# CONFIG_DRIVERS_I2C_RT5663 is not set -# CONFIG_DRIVERS_I2C_RTD2132 is not set -# CONFIG_DRIVERS_I2C_RX6110SA is not set -# CONFIG_I2C_TPM is not set -# CONFIG_MAINBOARD_HAS_I2C_TPM_ATMEL is not set -# CONFIG_MAINBOARD_HAS_I2C_TPM_CR50 is not set -# CONFIG_DISPLAY_HOBS is not set -# CONFIG_DISPLAY_UPD_DATA is not set -CONFIG_CHECKLIST_DATA_FILE_LOCATION="src/vendorcode/intel/fsp/fsp2_0/checklist" -CONFIG_PLATFORM_USES_FSP2_0=y CONFIG_DISPLAY_FSP_CALLS_AND_STATUS=y -# CONFIG_DISPLAY_FSP_HEADER is not set -# CONFIG_FSP_CAR is not set CONFIG_FSP_M_XIP=y -# CONFIG_VERIFY_HOBS is not set -# CONFIG_FSP2_0_USES_TPM_MRC_HASH is not set -# CONFIG_INTEL_DDI is not set -# CONFIG_INTEL_EDID is not set -# CONFIG_INTEL_INT15 is not set -# CONFIG_INTEL_GMA_ACPI is not set -# CONFIG_INTEL_GMA_SSC_ALTERNATE_REF is not set -# CONFIG_DRIVER_INTEL_I210 is not set -# CONFIG_DRIVERS_INTEL_MIPI_CAMERA is not set # CONFIG_DRIVERS_INTEL_WIFI is not set -# CONFIG_USE_SAR is not set -# CONFIG_DRIVERS_LENOVO_HYBRID_GRAPHICS is not set -# CONFIG_DRIVER_MAXIM_MAX77686 is not set -# CONFIG_DRIVER_PARADE_PS8625 is not set -# CONFIG_DRIVER_PARADE_PS8640 is not set -CONFIG_DRIVERS_MC146818=y -CONFIG_MAINBOARD_HAS_LPC_TPM=y -CONFIG_LPC_TPM=y -CONFIG_TPM_TIS_BASE_ADDRESS=0xfed40000 -# CONFIG_TPM_INIT_FAILURE_IS_FATAL is not set -# CONFIG_SKIP_TPM_STARTUP_ON_NORMAL_BOOT is not set -# CONFIG_TPM_DEACTIVATE is not set -# CONFIG_DRIVERS_RICOH_RCE822 is not set -# CONFIG_DRIVER_SIEMENS_NC_FPGA is not set -# CONFIG_NC_FPGA_NOTIFY_CB_READY is not set -# CONFIG_DRIVERS_SIL_3114 is not set -# CONFIG_MAINBOARD_HAS_SPI_TPM_CR50 is not set -# CONFIG_DRIVER_TI_TPS65090 is not set -# CONFIG_DRIVERS_TI_TPS65913 is not set -# CONFIG_DRIVERS_TI_TPS65913_RTC is not set -# CONFIG_DRIVER_XPOWERS_AXP209 is not set -# CONFIG_COMMONLIB_STORAGE is not set - -# -# Security -# - -# -# Verified Boot (vboot) -# -# CONFIG_ACPI_SATA_GENERATOR is not set -CONFIG_ACPI_INTEL_HARDWARE_SLEEP_VALUES=y -# CONFIG_ACPI_AMD_HARDWARE_SLEEP_VALUES is not set -# CONFIG_BOOT_DEVICE_NOT_SPI_FLASH is not set -CONFIG_BOOT_DEVICE_SPI_FLASH=y -CONFIG_BOOT_DEVICE_MEMORY_MAPPED=y -CONFIG_BOOT_DEVICE_SUPPORTS_WRITES=y -CONFIG_RTC=y -CONFIG_TPM=y -# CONFIG_MAINBOARD_HAS_TPM_CR50 is not set - -# -# Console -# -CONFIG_BOOTBLOCK_CONSOLE=y -CONFIG_POSTCAR_CONSOLE=y -CONFIG_SQUELCH_EARLY_SMP=y -# CONFIG_SPKMODEM is not set -# CONFIG_CONSOLE_NE2K is not set -CONFIG_CONSOLE_CBMEM_BUFFER_SIZE=0x20000 -# CONFIG_CONSOLE_CBMEM_DUMP_TO_UART is not set -# CONFIG_CONSOLE_SPI_FLASH is not set CONFIG_DEFAULT_CONSOLE_LOGLEVEL_8=y -# CONFIG_DEFAULT_CONSOLE_LOGLEVEL_7 is not set -# CONFIG_DEFAULT_CONSOLE_LOGLEVEL_6 is not set -# CONFIG_DEFAULT_CONSOLE_LOGLEVEL_5 is not set -# CONFIG_DEFAULT_CONSOLE_LOGLEVEL_4 is not set -# CONFIG_DEFAULT_CONSOLE_LOGLEVEL_3 is not set -# CONFIG_DEFAULT_CONSOLE_LOGLEVEL_2 is not set -# CONFIG_DEFAULT_CONSOLE_LOGLEVEL_1 is not set -# CONFIG_DEFAULT_CONSOLE_LOGLEVEL_0 is not set -# CONFIG_CMOS_POST is not set -# CONFIG_CONSOLE_POST is not set -# CONFIG_NO_EARLY_BOOTBLOCK_POSTCODES is not set -CONFIG_HWBASE_DEBUG_CB=y -CONFIG_HAVE_ACPI_RESUME=y -# CONFIG_ACPI_HUGE_LOWMEM_BACKUP is not set -CONFIG_RESUME_PATH_SAME_AS_BOOT=y -CONFIG_HAVE_HARD_RESET=y -# CONFIG_HAVE_ROMSTAGE_CONSOLE_SPINLOCK is not set -# CONFIG_HAVE_ROMSTAGE_NVRAM_CBFS_SPINLOCK is not set -# CONFIG_HAVE_ROMSTAGE_MICROCODE_CBFS_SPINLOCK is not set -CONFIG_HAVE_MONOTONIC_TIMER=y -# CONFIG_GENERIC_UDELAY is not set -# CONFIG_TIMER_QUEUE is not set -# CONFIG_HAVE_OPTION_TABLE is not set -# CONFIG_PIRQ_ROUTE is not set -CONFIG_HAVE_SMI_HANDLER=y -# CONFIG_PCI_IO_CFG_EXT is not set -CONFIG_IOAPIC=y -# CONFIG_USE_WATCHDOG_ON_BOOT is not set -# CONFIG_GFXUMA is not set -CONFIG_HAVE_ACPI_TABLES=y -CONFIG_COMMON_FADT=y -CONFIG_ACPI_NHLT=y - -# -# System tables -# -# CONFIG_GENERATE_MP_TABLE is not set -# CONFIG_GENERATE_PIRQ_TABLE is not set -CONFIG_GENERATE_SMBIOS_TABLES=y - -# -# Payload -# -# CONFIG_PAYLOAD_NONE is not set -# CONFIG_PAYLOAD_ELF is not set -# CONFIG_PAYLOAD_BAYOU is not set -# CONFIG_PAYLOAD_FILO is not set -# CONFIG_PAYLOAD_GRUB2 is not set -# CONFIG_PAYLOAD_SEABIOS is not set -# CONFIG_PAYLOAD_UBOOT is not set CONFIG_PAYLOAD_LINUX=y -# CONFIG_PAYLOAD_TIANOCORE is not set CONFIG_PAYLOAD_FILE="../../build/librem13v2/bzImage" -CONFIG_PAYLOAD_OPTIONS="" -# CONFIG_PXE is not set CONFIG_LINUX_COMMAND_LINE="intel_iommu=on iommu=pt" CONFIG_LINUX_INITRD="../../build/librem13v2/initrd.cpio.xz" -# CONFIG_PAYLOAD_IS_FLAT_BINARY is not set - -# -# Secondary Payloads -# CONFIG_COREINFO_SECONDARY_PAYLOAD=y CONFIG_MEMTEST_SECONDARY_PAYLOAD=y -CONFIG_MEMTEST_STABLE=y -# CONFIG_MEMTEST_MASTER is not set -# CONFIG_NVRAMCUI_SECONDARY_PAYLOAD is not set -# CONFIG_TINT_SECONDARY_PAYLOAD is not set - -# -# Debugging -# -# CONFIG_FATAL_ASSERTS is not set -# CONFIG_DEBUG_CBFS is not set -# CONFIG_HAVE_DEBUG_RAM_SETUP is not set -# CONFIG_HAVE_DEBUG_CAR is not set -# CONFIG_HAVE_DEBUG_SMBUS is not set -# CONFIG_DEBUG_SMI is not set -# CONFIG_DEBUG_SMM_RELOCATION is not set -# CONFIG_DEBUG_MALLOC is not set -# CONFIG_DEBUG_ACPI is not set -# CONFIG_DEBUG_TPM is not set -# CONFIG_DEBUG_SPI_FLASH is not set -# CONFIG_TRACE is not set -# CONFIG_DEBUG_BOOT_STATE is not set -# CONFIG_DEBUG_ADA_CODE is not set -CONFIG_NO_EDID_FILL_FB=y -# CONFIG_ENABLE_APIC_EXT_ID is not set -CONFIG_WARNINGS_ARE_ERRORS=y -# CONFIG_POWER_BUTTON_DEFAULT_ENABLE is not set -# CONFIG_POWER_BUTTON_DEFAULT_DISABLE is not set -# CONFIG_POWER_BUTTON_FORCE_ENABLE is not set -# CONFIG_POWER_BUTTON_FORCE_DISABLE is not set -# CONFIG_POWER_BUTTON_IS_OPTIONAL is not set -CONFIG_REG_SCRIPT=y -# CONFIG_CREATE_BOARD_CHECKLIST is not set -# CONFIG_MAKE_CHECKLIST_PUBLIC is not set -# CONFIG_NO_XIP_EARLY_STAGES is not set -CONFIG_EARLY_CBMEM_INIT=y -# CONFIG_EARLY_CBMEM_LIST is not set -CONFIG_RELOCATABLE_MODULES=y -CONFIG_GENERIC_GPIO_LIB=y -CONFIG_SPD_READ_BY_WORD=y -CONFIG_C_ENVIRONMENT_BOOTBLOCK=y diff --git a/config/coreboot-librem15v3.config b/config/coreboot-librem15v3.config index 7d6f16da..53d196b5 100644 --- a/config/coreboot-librem15v3.config +++ b/config/coreboot-librem15v3.config @@ -1,742 +1,32 @@ -# -# Automatically generated file; DO NOT EDIT. -# coreboot configuration -# - -# -# General setup -# -CONFIG_COREBOOT_BUILD=y CONFIG_LOCALVERSION="4.7-Purism-4-heads" -CONFIG_CBFS_PREFIX="fallback" -CONFIG_COMPILER_GCC=y -# CONFIG_COMPILER_LLVM_CLANG is not set -# CONFIG_ANY_TOOLCHAIN is not set -# CONFIG_CCACHE is not set -# CONFIG_FMD_GENPARSER is not set -# CONFIG_UTIL_GENPARSER is not set -CONFIG_COMPRESS_RAMSTAGE=y -CONFIG_INCLUDE_CONFIG_FILE=y -CONFIG_COLLECT_TIMESTAMPS=y CONFIG_USE_BLOBS=y -# CONFIG_COVERAGE is not set -# CONFIG_UBSAN is not set -CONFIG_RELOCATABLE_RAMSTAGE=y -CONFIG_CACHE_RELOCATED_RAMSTAGE_OUTSIDE_CBMEM=y -# CONFIG_UPDATE_IMAGE is not set -# CONFIG_BOOTSPLASH_IMAGE is not set CONFIG_MEASURED_BOOT=y - -# -# Mainboard -# - -# -# Important: Run 'make distclean' before switching boards -# -# CONFIG_VENDOR_A_TREND is not set -# CONFIG_VENDOR_AAEON is not set -# CONFIG_VENDOR_ABIT is not set -# CONFIG_VENDOR_ADI is not set -# CONFIG_VENDOR_ADLINK is not set -# CONFIG_VENDOR_ADVANSUS is not set -# CONFIG_VENDOR_AMD is not set -# CONFIG_VENDOR_AOPEN is not set -# CONFIG_VENDOR_APPLE is not set -# CONFIG_VENDOR_ARTECGROUP is not set -# CONFIG_VENDOR_ASROCK is not set -# CONFIG_VENDOR_ASUS is not set -# CONFIG_VENDOR_AVALUE is not set -# CONFIG_VENDOR_AZZA is not set -# CONFIG_VENDOR_BACHMANN is not set -# CONFIG_VENDOR_BAP is not set -# CONFIG_VENDOR_BCOM is not set -# CONFIG_VENDOR_BIOSTAR is not set -# CONFIG_VENDOR_BROADCOM is not set -# CONFIG_VENDOR_COMPAQ is not set -# CONFIG_VENDOR_COMPULAB is not set -# CONFIG_VENDOR_CUBIETECH is not set -# CONFIG_VENDOR_DIGITALLOGIC is not set -# CONFIG_VENDOR_DMP is not set -# CONFIG_VENDOR_ECS is not set -# CONFIG_VENDOR_ELMEX is not set -# CONFIG_VENDOR_EMULATION is not set -# CONFIG_VENDOR_ESD is not set -# CONFIG_VENDOR_FOXCONN is not set -# CONFIG_VENDOR_GETAC is not set -# CONFIG_VENDOR_GIGABYTE is not set -# CONFIG_VENDOR_GIZMOSPHERE is not set -# CONFIG_VENDOR_GOOGLE is not set -# CONFIG_VENDOR_HP is not set -# CONFIG_VENDOR_IBASE is not set -# CONFIG_VENDOR_IEI is not set -# CONFIG_VENDOR_INTEL is not set -# CONFIG_VENDOR_IWAVE is not set -# CONFIG_VENDOR_IWILL is not set -# CONFIG_VENDOR_JETWAY is not set -# CONFIG_VENDOR_KONTRON is not set -# CONFIG_VENDOR_LANNER is not set -# CONFIG_VENDOR_LENOVO is not set -# CONFIG_VENDOR_LINUTOP is not set -# CONFIG_VENDOR_LIPPERT is not set -# CONFIG_VENDOR_LOWRISC is not set -# CONFIG_VENDOR_MITAC is not set -# CONFIG_VENDOR_MSI is not set -# CONFIG_VENDOR_NEC is not set -# CONFIG_VENDOR_NOKIA is not set -# CONFIG_VENDOR_NVIDIA is not set -# CONFIG_VENDOR_PACKARDBELL is not set -# CONFIG_VENDOR_PCENGINES is not set CONFIG_VENDOR_PURISM=y -# CONFIG_VENDOR_RCA is not set -# CONFIG_VENDOR_RODA is not set -# CONFIG_VENDOR_SAMSUNG is not set -# CONFIG_VENDOR_SAPPHIRE is not set -# CONFIG_VENDOR_SIEMENS is not set -# CONFIG_VENDOR_SOYO is not set -# CONFIG_VENDOR_SUNW is not set -# CONFIG_VENDOR_SUPERMICRO is not set -# CONFIG_VENDOR_TECHNEXION is not set -# CONFIG_VENDOR_THOMSON is not set -# CONFIG_VENDOR_TI is not set -# CONFIG_VENDOR_TRAVERSE is not set -# CONFIG_VENDOR_TYAN is not set -# CONFIG_VENDOR_VIA is not set -# CONFIG_VENDOR_WINENT is not set -# CONFIG_VENDOR_WINNET is not set -# CONFIG_VENDOR_WYSE is not set -CONFIG_MAINBOARD_DIR="purism/librem_skl" -CONFIG_MAINBOARD_PART_NUMBER="Librem 15 v3" -CONFIG_IRQ_SLOT_COUNT=18 -CONFIG_MAINBOARD_VENDOR="Purism" -CONFIG_MAX_CPUS=8 -CONFIG_CACHE_ROM_SIZE_OVERRIDE=0x0 CONFIG_CBFS_SIZE=0xe00000 -CONFIG_UART_FOR_CONSOLE=0 -CONFIG_VGA_BIOS_ID="8086,1916" -# CONFIG_ONBOARD_VGA_IS_PRIMARY is not set -CONFIG_DIMM_SPD_SIZE=512 -# CONFIG_VGA_BIOS is not set CONFIG_MAINBOARD_SERIAL_NUMBER="Unknown Serial Number" -CONFIG_DCACHE_RAM_BASE=0xfef00000 -CONFIG_DCACHE_RAM_SIZE=0x40000 -CONFIG_MAINBOARD_SMBIOS_MANUFACTURER="Purism" CONFIG_HAVE_IFD_BIN=y CONFIG_HAVE_ME_BIN=y -CONFIG_MMCONF_BASE_ADDRESS=0xe0000000 # CONFIG_POST_IO is not set -CONFIG_DEVICETREE="variants/librem15v3/devicetree.cb" -CONFIG_MAX_REBOOT_CNT=3 -# CONFIG_HAVE_GBE_BIN is not set -CONFIG_ID_SECTION_OFFSET=0x80 # CONFIG_POST_DEVICE is not set -CONFIG_VARIANT_DIR="librem15v3" -# CONFIG_VBOOT is not set -CONFIG_MAINBOARD_FAMILY="Librem 15" -CONFIG_TPM_PIRQ=0x0 -CONFIG_DIMM_MAX=1 -CONFIG_BOOT_DEVICE_SPI_FLASH_BUS=0 -CONFIG_FMDFILE="" -CONFIG_PRERAM_CBMEM_CONSOLE_SIZE=0xc00 # CONFIG_DRIVERS_UART_8250IO is not set CONFIG_IFD_BIN_PATH="../../blobs/librem_skl/descriptor.bin" CONFIG_ME_BIN_PATH="../../blobs/librem_skl/me.bin" -CONFIG_MAINBOARD_SMBIOS_PRODUCT_NAME="Librem 15 v3" CONFIG_ADD_FSP_BINARIES=y CONFIG_FSP_M_FILE="../../blobs/librem_skl/fspm.bin" CONFIG_FSP_S_FILE="../../blobs/librem_skl/fsps.bin" -CONFIG_FSP_S_CBFS="fsps.bin" -CONFIG_FSP_M_CBFS="fspm.bin" -CONFIG_CPU_ADDR_BITS=36 -CONFIG_DEFAULT_CONSOLE_LOGLEVEL=8 -CONFIG_MAINBOARD_VERSION="3.0" -# CONFIG_DRIVERS_PS2_KEYBOARD is not set -# CONFIG_BOARD_PURISM_LIBREM13_V1 is not set -# CONFIG_BOARD_PURISM_LIBREM13_V2 is not set CONFIG_BOARD_PURISM_LIBREM15_V3=y -CONFIG_PCIEXP_L1_SUB_STATE=y # CONFIG_NO_POST is not set -CONFIG_BOARD_PURISM_BASEBOARD_LIBREM_SKL=y -CONFIG_CPU_MICROCODE_CBFS_LEN=0x18000 -CONFIG_CPU_MICROCODE_CBFS_LOC=0xFFE115A0 -CONFIG_BOARD_ROMSIZE_KB_16384=y -# CONFIG_COREBOOT_ROMSIZE_KB_64 is not set -# CONFIG_COREBOOT_ROMSIZE_KB_128 is not set -# CONFIG_COREBOOT_ROMSIZE_KB_256 is not set -# CONFIG_COREBOOT_ROMSIZE_KB_512 is not set -# CONFIG_COREBOOT_ROMSIZE_KB_1024 is not set -# CONFIG_COREBOOT_ROMSIZE_KB_2048 is not set -# CONFIG_COREBOOT_ROMSIZE_KB_4096 is not set -# CONFIG_COREBOOT_ROMSIZE_KB_8192 is not set -# CONFIG_COREBOOT_ROMSIZE_KB_10240 is not set -# CONFIG_COREBOOT_ROMSIZE_KB_12288 is not set -CONFIG_COREBOOT_ROMSIZE_KB_16384=y -# CONFIG_COREBOOT_ROMSIZE_KB_32768 is not set -# CONFIG_COREBOOT_ROMSIZE_KB_65536 is not set -CONFIG_COREBOOT_ROMSIZE_KB=16384 -CONFIG_ROM_SIZE=0x1000000 -# CONFIG_MAINBOARD_HAS_TPM2 is not set -CONFIG_SYSTEM_TYPE_LAPTOP=y -# CONFIG_CBFS_AUTOGEN_ATTRIBUTES is not set - -# -# Chipset -# - -# -# SoC -# -CONFIG_CPU_SPECIFIC_OPTIONS=y -CONFIG_DCACHE_BSP_STACK_SIZE=0x4000 -CONFIG_RAMTOP=0x200000 -CONFIG_HEAP_SIZE=0x80000 -CONFIG_RAMBASE=0x100000 -CONFIG_SERIRQ_CONTINUOUS_MODE=y -CONFIG_SMM_TSEG_SIZE=0x800000 -CONFIG_SMM_RESERVED_SIZE=0x200000 -CONFIG_ACPI_CPU_STRING="\\_PR.CP%02d" -CONFIG_DRIVERS_I2C_DESIGNWARE_CLOCK_MHZ=120 -# CONFIG_SOC_BROADCOM_CYGNUS is not set -# CONFIG_SOC_INTEL_GLK is not set -CONFIG_SOC_INTEL_COMMON_RESET=y -CONFIG_PCR_BASE_ADDRESS=0xfd000000 -CONFIG_SOC_INTEL_COMMON_LPSS_CLOCK_MHZ=120 -CONFIG_C_ENV_BOOTBLOCK_SIZE=0xC000 -CONFIG_X86_TOP4G_BOOTMEDIA_MAP=y -CONFIG_ROMSTAGE_ADDR=0x2000000 -CONFIG_VERSTAGE_ADDR=0x2000000 -# CONFIG_NHLT_MAX98357 is not set -# CONFIG_NHLT_DA7219 is not set -# CONFIG_SPI_FLASH_INCLUDE_ALL_DRIVERS is not set -CONFIG_CPU_BCLK_MHZ=100 -CONFIG_SOC_INTEL_COMMON_LPSS_UART_CLK_M_VAL=0x30 -CONFIG_SOC_INTEL_COMMON_LPSS_UART_CLK_N_VAL=0xc35 -# CONFIG_RESET_ON_INVALID_RAMSTAGE_CACHE is not set -CONFIG_CHIPSET_BOOTBLOCK_INCLUDE="soc/intel/skylake/bootblock/timestamp.inc" -CONFIG_IED_REGION_SIZE=0x400000 -CONFIG_PCIEXP_ASPM=y -CONFIG_PCIEXP_COMMON_CLOCK=y -CONFIG_PCIEXP_CLK_PM=y -# CONFIG_SERIAL_CPU_INIT is not set -# CONFIG_UART_DEBUG is not set -CONFIG_MAX_ROOT_PORTS=24 -CONFIG_SOC_INTEL_COMMON_BLOCK_GSPI_MAX=2 -CONFIG_STACK_SIZE=0x1000 -CONFIG_CONSOLE_CBMEM=y -CONFIG_UART_PCI_ADDR=0x0 -CONFIG_SOC_INTEL_SKYLAKE=y -# CONFIG_SOC_INTEL_KABYLAKE is not set -CONFIG_MAINBOARD_USES_FSP2_0=y -CONFIG_USE_FSP2_0_DRIVER=y -CONFIG_BOOTBLOCK_RESETS="soc/intel/common/reset.c" -# CONFIG_EXCLUDE_NATIVE_SD_INTERFACE is not set -# CONFIG_SKYLAKE_SOC_PCH_H is not set -# CONFIG_NHLT_DMIC_2CH is not set -# CONFIG_NHLT_DMIC_4CH is not set -# CONFIG_NHLT_NAU88L25 is not set -# CONFIG_NHLT_SSM4567 is not set -# CONFIG_NHLT_RT5514 is not set -# CONFIG_NHLT_RT5663 is not set -# CONFIG_NHLT_MAX98927 is not set -CONFIG_CAR_NEM_ENHANCED=y -# CONFIG_USE_SKYLAKE_FSP_CAR is not set -CONFIG_SKIP_FSP_CAR=y -# CONFIG_NO_FADT_8042 is not set -CONFIG_SOC_INTEL_COMMON=y - -# -# Intel SoC Common Code -# -CONFIG_SOC_INTEL_COMMON_BLOCK=y - -# -# Intel SoC Common IP Code -# -CONFIG_SOC_INTEL_COMMON_BLOCK_CPU=y -CONFIG_SOC_INTEL_COMMON_BLOCK_CPU_MPINIT=y -CONFIG_SOC_INTEL_COMMON_BLOCK_CAR=y -# CONFIG_INTEL_CAR_NEM is not set -# CONFIG_INTEL_CAR_CQOS is not set -CONFIG_INTEL_CAR_NEM_ENHANCED=y -CONFIG_SOC_INTEL_COMMON_BLOCK_CSE=y -CONFIG_SOC_INTEL_COMMON_BLOCK_DSP=y -CONFIG_SOC_INTEL_COMMON_BLOCK_EBDA=y -CONFIG_SOC_INTEL_COMMON_BLOCK_FAST_SPI=y -CONFIG_FAST_SPI_DISABLE_WRITE_STATUS=y -CONFIG_SOC_INTEL_COMMON_BLOCK_GPIO=y -# CONFIG_DEBUG_SOC_COMMON_BLOCK_GPIO is not set -# CONFIG_SOC_INTEL_COMMON_BLOCK_GPIO_ITSS_POL_CFG is not set -CONFIG_SOC_INTEL_COMMON_BLOCK_GPIO_PADCFG_PADTOL=y -# CONFIG_SOC_INTEL_COMMON_BLOCK_GPIO_IOSTANDBY is not set -CONFIG_SOC_INTEL_COMMON_BLOCK_GPIO_LEGACY_MACROS=y -# CONFIG_SOC_INTEL_COMMON_BLOCK_GPIO_MULTI_ACPI_DEVICES is not set -CONFIG_SOC_INTEL_COMMON_BLOCK_GRAPHICS=y -CONFIG_SOC_INTEL_COMMON_BLOCK_GSPI=y -# CONFIG_SOC_INTEL_COMMON_BLOCK_GSPI_VERSION_2 is not set -CONFIG_SOC_INTEL_COMMON_BLOCK_I2C=y -# CONFIG_SOC_INTEL_COMMON_BLOCK_I2C_DEBUG is not set -CONFIG_SOC_INTEL_COMMON_BLOCK_ITSS=y -CONFIG_SOC_INTEL_COMMON_BLOCK_LPC=y -CONFIG_SOC_INTEL_COMMON_BLOCK_LPSS=y -CONFIG_SOC_INTEL_COMMON_BLOCK_PCIE=y -CONFIG_SOC_INTEL_COMMON_BLOCK_PCR=y -CONFIG_SOC_INTEL_COMMON_BLOCK_PMC=y -# CONFIG_POWER_STATE_OFF_AFTER_FAILURE is not set -CONFIG_POWER_STATE_ON_AFTER_FAILURE=y -# CONFIG_POWER_STATE_PREVIOUS_AFTER_FAILURE is not set -CONFIG_SOC_INTEL_COMMON_BLOCK_RTC=y -CONFIG_SOC_INTEL_COMMON_BLOCK_SATA=y -CONFIG_SOC_INTEL_COMMON_BLOCK_SCS=y -CONFIG_SOC_INTEL_COMMON_BLOCK_SGX=y -CONFIG_SOC_INTEL_COMMON_BLOCK_SMBUS=y -CONFIG_SOC_INTEL_COMMON_BLOCK_SMM=y -CONFIG_SOC_INTEL_COMMON_BLOCK_SMM_IO_TRAP=y -CONFIG_SOC_INTEL_COMMON_BLOCK_SPI=y -CONFIG_SOC_INTEL_COMMON_BLOCK_SA=y -CONFIG_SA_PCIEX_LENGTH=0x4000000 -CONFIG_PCIEX_LENGTH_64MB=y -# CONFIG_SA_ENABLE_IMR is not set -CONFIG_SA_ENABLE_DPR=y -CONFIG_SOC_INTEL_COMMON_BLOCK_TIMER=y -CONFIG_SOC_INTEL_COMMON_BLOCK_UART=y -CONFIG_SOC_INTEL_COMMON_BLOCK_XHCI=y -# CONFIG_DISPLAY_MTRRS is not set -# CONFIG_DISPLAY_SMM_MEMORY_MAP is not set -CONFIG_SOC_INTEL_COMMON_ACPI_WAKE_SOURCE=y -# CONFIG_ACPI_CONSOLE is not set -# CONFIG_MMA is not set -CONFIG_SOC_INTEL_COMMON_GFX_OPREGION=y -# CONFIG_SOC_INTEL_COMMON_SMI is not set -# CONFIG_SOC_INTEL_COMMON_ACPI is not set -CONFIG_SOC_INTEL_COMMON_NHLT=y -# CONFIG_SOC_LOWRISC_LOWRISC is not set -# CONFIG_SOC_MARVELL_MVMAP2315 is not set -# CONFIG_SOC_MEDIATEK_MT8173 is not set -# CONFIG_SOC_NVIDIA_TEGRA124 is not set -# CONFIG_SOC_NVIDIA_TEGRA210 is not set -# CONFIG_SOC_QC_IPQ40XX is not set -# CONFIG_SOC_QC_IPQ806X is not set -# CONFIG_SOC_ROCKCHIP_RK3288 is not set -# CONFIG_SOC_ROCKCHIP_RK3399 is not set -# CONFIG_CPU_SAMSUNG_EXYNOS5250 is not set -# CONFIG_CPU_SAMSUNG_EXYNOS5420 is not set -# CONFIG_SOC_UCB_RISCV is not set - -# -# CPU -# -# CONFIG_CPU_ALLWINNER_A10 is not set -CONFIG_NUM_IPI_STARTS=2 -# CONFIG_CPU_AMD_AGESA is not set -# CONFIG_CPU_AMD_PI is not set -# CONFIG_CPU_ARMLTD_CORTEX_A9 is not set -CONFIG_SSE2=y -CONFIG_CPU_INTEL_FIRMWARE_INTERFACE_TABLE=y -CONFIG_CPU_INTEL_NUM_FIT_ENTRIES=4 -# CONFIG_CPU_INTEL_TURBO_NOT_PACKAGE_SCOPED is not set -# CONFIG_CPU_TI_AM335X is not set -# CONFIG_PARALLEL_CPU_INIT is not set -CONFIG_PARALLEL_MP=y -CONFIG_PARALLEL_MP_AP_WORK=y -# CONFIG_UDELAY_IO is not set -# CONFIG_UDELAY_LAPIC is not set -CONFIG_UDELAY_TSC=y -CONFIG_TSC_CONSTANT_RATE=y -CONFIG_TSC_MONOTONIC_TIMER=y -# CONFIG_UDELAY_TIMER2 is not set -# CONFIG_TSC_SYNC_LFENCE is not set -CONFIG_TSC_SYNC_MFENCE=y -CONFIG_NO_FIXED_XIP_ROM_SIZE=y -CONFIG_LOGICAL_CPUS=y -CONFIG_SMM_TSEG=y -CONFIG_SMM_MODULE_HEAP_SIZE=0x4000 -# CONFIG_SMM_LAPIC_REMAP_MITIGATION is not set -# CONFIG_SERIALIZED_SMM_INITIALIZATION is not set -# CONFIG_X86_AMD_FIXED_MTRRS is not set -# CONFIG_PLATFORM_USES_FSP1_0 is not set -# CONFIG_MIRROR_PAYLOAD_TO_RAM_BEFORE_LOADING is not set -# CONFIG_SOC_SETS_MSRS is not set -CONFIG_CACHE_AS_RAM=y -CONFIG_NO_CAR_GLOBAL_MIGRATION=y -CONFIG_SMP=y -CONFIG_AP_SIPI_VECTOR=0xfffff000 -CONFIG_SSE=y -CONFIG_SUPPORT_CPU_UCODE_IN_CBFS=y -# CONFIG_USES_MICROCODE_HEADER_FILES is not set -CONFIG_CPU_MICROCODE_CBFS_GENERATE=y -# CONFIG_CPU_MICROCODE_CBFS_EXTERNAL_HEADER is not set -# CONFIG_CPU_MICROCODE_CBFS_NONE is not set -# CONFIG_CPU_MICROCODE_MULTIPLE_FILES is not set CONFIG_CPU_UCODE_BINARIES="../../blobs/librem_skl/cpu_microcode_blob.bin" - -# -# Northbridge -# -# CONFIG_NORTHBRIDGE_AMD_AGESA is not set -# CONFIG_NO_MMCONF_SUPPORT is not set -# CONFIG_AMD_NB_CIMX is not set -# CONFIG_NORTHBRIDGE_AMD_CIMX_RD890 is not set -# CONFIG_NORTHBRIDGE_AMD_PI is not set -# CONFIG_NORTHBRIDGE_INTEL_COMMON_MRC_CACHE is not set -CONFIG_HPET_ADDRESS=0xfed00000 -CONFIG_MAX_PIRQ_LINKS=4 - -# -# Southbridge -# -# CONFIG_AMD_SB_CIMX is not set -# CONFIG_SOUTHBRIDGE_AMD_CIMX_SB800 is not set -# CONFIG_SOUTHBRIDGE_AMD_CIMX_SB900 is not set -# CONFIG_SOUTHBRIDGE_INTEL_COMMON is not set -# CONFIG_SOUTHBRIDGE_INTEL_COMMON_GPIO is not set -# CONFIG_SOUTHBRIDGE_INTEL_COMMON_SMBUS is not set -# CONFIG_SOUTHBRIDGE_INTEL_COMMON_SPI is not set -# CONFIG_SOUTHBRIDGE_INTEL_COMMON_PIRQ_ACPI_GEN is not set -# CONFIG_SOUTHBRIDGE_INTEL_COMMON_RCBA_PIRQ is not set -# CONFIG_HAVE_INTEL_CHIPSET_LOCKDOWN is not set -# CONFIG_LOCK_MANAGEMENT_ENGINE is not set - -# -# Super I/O -# -# CONFIG_SUPERIO_NUVOTON_NCT6776_COM_A is not set - -# -# Embedded Controllers -# -CONFIG_HAVE_INTEL_FIRMWARE=y - -# -# Intel Firmware -# -# CONFIG_EM100 is not set -# CONFIG_CHECK_ME is not set -# CONFIG_USE_ME_CLEANER is not set -# CONFIG_HAVE_EC_BIN is not set -# CONFIG_MAINBOARD_HAS_CHROMEOS is not set -# CONFIG_GOOGLE_SMBIOS_MAINBOARD_VERSION is not set -# CONFIG_UEFI_2_4_BINDING is not set -CONFIG_UDK_2015_BINDING=y -# CONFIG_USE_SIEMENS_HWILIB is not set -# CONFIG_ARCH_ARM is not set -# CONFIG_ARCH_BOOTBLOCK_ARM is not set -# CONFIG_ARCH_VERSTAGE_ARM is not set -# CONFIG_ARCH_ROMSTAGE_ARM is not set -# CONFIG_ARCH_RAMSTAGE_ARM is not set -# CONFIG_ARCH_BOOTBLOCK_ARMV4 is not set -# CONFIG_ARCH_VERSTAGE_ARMV4 is not set -# CONFIG_ARCH_ROMSTAGE_ARMV4 is not set -# CONFIG_ARCH_RAMSTAGE_ARMV4 is not set -# CONFIG_ARCH_BOOTBLOCK_ARMV7 is not set -# CONFIG_ARCH_VERSTAGE_ARMV7 is not set -# CONFIG_ARCH_ROMSTAGE_ARMV7 is not set -# CONFIG_ARCH_RAMSTAGE_ARMV7 is not set -# CONFIG_ARCH_BOOTBLOCK_ARMV7_M is not set -# CONFIG_ARCH_VERSTAGE_ARMV7_M is not set -# CONFIG_ARCH_BOOTBLOCK_ARMV7_R is not set -# CONFIG_ARCH_VERSTAGE_ARMV7_R is not set -# CONFIG_ARCH_ROMSTAGE_ARMV7_R is not set -# CONFIG_ARCH_RAMSTAGE_ARMV7_R is not set -# CONFIG_ARM_LPAE is not set -# CONFIG_ARCH_ARM64 is not set -# CONFIG_ARCH_BOOTBLOCK_ARM64 is not set -# CONFIG_ARCH_VERSTAGE_ARM64 is not set -# CONFIG_ARCH_ROMSTAGE_ARM64 is not set -# CONFIG_ARCH_RAMSTAGE_ARM64 is not set -# CONFIG_ARCH_BOOTBLOCK_ARMV8_64 is not set -# CONFIG_ARCH_VERSTAGE_ARMV8_64 is not set -# CONFIG_ARCH_ROMSTAGE_ARMV8_64 is not set -# CONFIG_ARCH_RAMSTAGE_ARMV8_64 is not set -# CONFIG_ARM64_A53_ERRATUM_843419 is not set -# CONFIG_ARCH_MIPS is not set -# CONFIG_ARCH_BOOTBLOCK_MIPS is not set -# CONFIG_ARCH_VERSTAGE_MIPS is not set -# CONFIG_ARCH_ROMSTAGE_MIPS is not set -# CONFIG_ARCH_RAMSTAGE_MIPS is not set -# CONFIG_ARCH_POWER8 is not set -# CONFIG_ARCH_BOOTBLOCK_POWER8 is not set -# CONFIG_ARCH_VERSTAGE_POWER8 is not set -# CONFIG_ARCH_ROMSTAGE_POWER8 is not set -# CONFIG_ARCH_RAMSTAGE_POWER8 is not set -# CONFIG_ARCH_RISCV is not set -# CONFIG_ARCH_BOOTBLOCK_RISCV is not set -# CONFIG_ARCH_VERSTAGE_RISCV is not set -# CONFIG_ARCH_ROMSTAGE_RISCV is not set -# CONFIG_ARCH_RAMSTAGE_RISCV is not set -CONFIG_ARCH_X86=y -CONFIG_ARCH_BOOTBLOCK_X86_32=y -CONFIG_ARCH_VERSTAGE_X86_32=y -CONFIG_ARCH_ROMSTAGE_X86_32=y -CONFIG_ARCH_RAMSTAGE_X86_32=y -# CONFIG_ARCH_BOOTBLOCK_X86_64 is not set -# CONFIG_ARCH_VERSTAGE_X86_64 is not set -# CONFIG_ARCH_ROMSTAGE_X86_64 is not set -# CONFIG_ARCH_RAMSTAGE_X86_64 is not set -# CONFIG_USE_MARCH_586 is not set -# CONFIG_AP_IN_SIPI_WAIT is not set -# CONFIG_SIPI_VECTOR_IN_ROM is not set -# CONFIG_ROMCC is not set -# CONFIG_CBMEM_TOP_BACKUP is not set -# CONFIG_LATE_CBMEM_INIT is not set -CONFIG_EARLY_EBDA_INIT=y -CONFIG_PC80_SYSTEM=y -# CONFIG_BOOTBLOCK_DEBUG_SPINLOOP is not set -# CONFIG_BOOTBLOCK_SAVE_BIST_AND_TIMESTAMP is not set -CONFIG_IOAPIC_INTERRUPTS_ON_FSB=y -# CONFIG_IOAPIC_INTERRUPTS_ON_APIC_SERIAL_BUS is not set -CONFIG_POSTCAR_STAGE=y -# CONFIG_VERSTAGE_DEBUG_SPINLOOP is not set -# CONFIG_ROMSTAGE_DEBUG_SPINLOOP is not set -CONFIG_BOOTBLOCK_SIMPLE=y -# CONFIG_BOOTBLOCK_NORMAL is not set -CONFIG_BOOTBLOCK_SOURCE="bootblock_simple.c" - -# -# Devices -# -CONFIG_HAVE_FSP_GOP=y -# CONFIG_MAINBOARD_HAS_NATIVE_VGA_INIT is not set -# CONFIG_MAINBOARD_HAS_LIBGFXINIT is not set -# CONFIG_RUN_FSP_GOP is not set -# CONFIG_VGA_ROM_RUN is not set CONFIG_NO_GFX_INIT=y -# CONFIG_MULTIPLE_VGA_ADAPTERS is not set -# CONFIG_SMBUS_HAS_AUX_CHANNELS is not set -CONFIG_PCI=y -CONFIG_MMCONF_SUPPORT=y -# CONFIG_HYPERTRANSPORT_PLUGIN_SUPPORT is not set -CONFIG_PCIX_PLUGIN_SUPPORT=y -CONFIG_CARDBUS_PLUGIN_SUPPORT=y -# CONFIG_AZALIA_PLUGIN_SUPPORT is not set -CONFIG_PCIEXP_PLUGIN_SUPPORT=y -# CONFIG_EARLY_PCI_BRIDGE is not set -CONFIG_SUBSYSTEM_VENDOR_ID=0x0000 -CONFIG_SUBSYSTEM_DEVICE_ID=0x0000 CONFIG_INTEL_GMA_ADD_VBT_DATA_FILE=y CONFIG_INTEL_GMA_VBT_FILE="../../blobs/librem_skl/vbt.bin" -# CONFIG_SOFTWARE_I2C is not set - -# -# Generic Drivers -# -# CONFIG_DRIVERS_AS3722_RTC is not set -# CONFIG_ELOG is not set -# CONFIG_GIC is not set -# CONFIG_IPMI_KCS is not set -# CONFIG_DRIVERS_LENOVO_WACOM is not set -CONFIG_CACHE_MRC_SETTINGS=y -CONFIG_MRC_SETTINGS_CACHE_BASE=0xfffe0000 -CONFIG_MRC_SETTINGS_CACHE_SIZE=0x10000 -CONFIG_MRC_SETTINGS_PROTECT=y -# CONFIG_HAS_RECOVERY_MRC_CACHE is not set -# CONFIG_MRC_CLEAR_NORMAL_CACHE_ON_RECOVERY_RETRAIN is not set -# CONFIG_MRC_SETTINGS_VARIABLE_DATA is not set -# CONFIG_RT8168_GET_MAC_FROM_VPD is not set -# CONFIG_RT8168_SET_LED_MODE is not set -CONFIG_SPI_FLASH=y -CONFIG_BOOT_DEVICE_SPI_FLASH_RW_NOMMAP=y -CONFIG_BOOT_DEVICE_SPI_FLASH_RW_NOMMAP_EARLY=y -# CONFIG_SPI_FLASH_SMM is not set -# CONFIG_SPI_FLASH_NO_FAST_READ is not set -# CONFIG_SPI_FLASH_FAST_READ_DUAL_OUTPUT_3B is not set -# CONFIG_SPI_FLASH_HAS_VOLATILE_GROUP is not set -# CONFIG_HAVE_SPI_CONSOLE_SUPPORT is not set -# CONFIG_DRIVERS_UART is not set -# CONFIG_NO_UART_ON_SUPERIO is not set -# CONFIG_UART_OVERRIDE_INPUT_CLOCK_DIVIDER is not set -# CONFIG_UART_OVERRIDE_REFCLK is not set -# CONFIG_DRIVERS_UART_8250MEM is not set -# CONFIG_DRIVERS_UART_8250MEM_32 is not set -# CONFIG_HAVE_UART_SPECIAL is not set -# CONFIG_DRIVERS_UART_OXPCIE is not set -# CONFIG_DRIVERS_UART_PL011 is not set -# CONFIG_UART_USE_REFCLK_AS_INPUT_CLOCK is not set -# CONFIG_HAVE_USBDEBUG is not set -# CONFIG_HAVE_USBDEBUG_OPTIONS is not set -# CONFIG_DRIVERS_AMD_PI is not set -# CONFIG_SMBIOS_PROVIDED_BY_MOBO is not set -CONFIG_DRIVERS_I2C_DESIGNWARE=y -# CONFIG_DRIVERS_I2C_DESIGNWARE_DEBUG is not set -# CONFIG_DRIVERS_I2C_MAX98927 is not set -# CONFIG_DRIVERS_I2C_PCF8523 is not set -# CONFIG_DRIVERS_I2C_RT5663 is not set -# CONFIG_DRIVERS_I2C_RTD2132 is not set -# CONFIG_DRIVERS_I2C_RX6110SA is not set -# CONFIG_I2C_TPM is not set -# CONFIG_MAINBOARD_HAS_I2C_TPM_ATMEL is not set -# CONFIG_MAINBOARD_HAS_I2C_TPM_CR50 is not set -# CONFIG_DISPLAY_HOBS is not set -# CONFIG_DISPLAY_UPD_DATA is not set -CONFIG_CHECKLIST_DATA_FILE_LOCATION="src/vendorcode/intel/fsp/fsp2_0/checklist" -CONFIG_PLATFORM_USES_FSP2_0=y CONFIG_DISPLAY_FSP_CALLS_AND_STATUS=y -# CONFIG_DISPLAY_FSP_HEADER is not set -# CONFIG_FSP_CAR is not set CONFIG_FSP_M_XIP=y -# CONFIG_VERIFY_HOBS is not set -# CONFIG_FSP2_0_USES_TPM_MRC_HASH is not set -# CONFIG_INTEL_DDI is not set -# CONFIG_INTEL_EDID is not set -# CONFIG_INTEL_INT15 is not set -# CONFIG_INTEL_GMA_ACPI is not set -# CONFIG_INTEL_GMA_SSC_ALTERNATE_REF is not set -# CONFIG_DRIVER_INTEL_I210 is not set -# CONFIG_DRIVERS_INTEL_MIPI_CAMERA is not set # CONFIG_DRIVERS_INTEL_WIFI is not set -# CONFIG_USE_SAR is not set -# CONFIG_DRIVERS_LENOVO_HYBRID_GRAPHICS is not set -# CONFIG_DRIVER_MAXIM_MAX77686 is not set -# CONFIG_DRIVER_PARADE_PS8625 is not set -# CONFIG_DRIVER_PARADE_PS8640 is not set -CONFIG_DRIVERS_MC146818=y -CONFIG_MAINBOARD_HAS_LPC_TPM=y -CONFIG_LPC_TPM=y -CONFIG_TPM_TIS_BASE_ADDRESS=0xfed40000 -# CONFIG_TPM_INIT_FAILURE_IS_FATAL is not set -# CONFIG_SKIP_TPM_STARTUP_ON_NORMAL_BOOT is not set -# CONFIG_TPM_DEACTIVATE is not set -# CONFIG_DRIVERS_RICOH_RCE822 is not set -# CONFIG_DRIVER_SIEMENS_NC_FPGA is not set -# CONFIG_NC_FPGA_NOTIFY_CB_READY is not set -# CONFIG_DRIVERS_SIL_3114 is not set -# CONFIG_MAINBOARD_HAS_SPI_TPM_CR50 is not set -# CONFIG_DRIVER_TI_TPS65090 is not set -# CONFIG_DRIVERS_TI_TPS65913 is not set -# CONFIG_DRIVERS_TI_TPS65913_RTC is not set -# CONFIG_DRIVER_XPOWERS_AXP209 is not set -# CONFIG_COMMONLIB_STORAGE is not set - -# -# Security -# - -# -# Verified Boot (vboot) -# -# CONFIG_ACPI_SATA_GENERATOR is not set -CONFIG_ACPI_INTEL_HARDWARE_SLEEP_VALUES=y -# CONFIG_ACPI_AMD_HARDWARE_SLEEP_VALUES is not set -# CONFIG_BOOT_DEVICE_NOT_SPI_FLASH is not set -CONFIG_BOOT_DEVICE_SPI_FLASH=y -CONFIG_BOOT_DEVICE_MEMORY_MAPPED=y -CONFIG_BOOT_DEVICE_SUPPORTS_WRITES=y -CONFIG_RTC=y -CONFIG_TPM=y -# CONFIG_MAINBOARD_HAS_TPM_CR50 is not set - -# -# Console -# -CONFIG_BOOTBLOCK_CONSOLE=y -CONFIG_POSTCAR_CONSOLE=y -CONFIG_SQUELCH_EARLY_SMP=y -# CONFIG_SPKMODEM is not set -# CONFIG_CONSOLE_NE2K is not set -CONFIG_CONSOLE_CBMEM_BUFFER_SIZE=0x20000 -# CONFIG_CONSOLE_CBMEM_DUMP_TO_UART is not set -# CONFIG_CONSOLE_SPI_FLASH is not set CONFIG_DEFAULT_CONSOLE_LOGLEVEL_8=y -# CONFIG_DEFAULT_CONSOLE_LOGLEVEL_7 is not set -# CONFIG_DEFAULT_CONSOLE_LOGLEVEL_6 is not set -# CONFIG_DEFAULT_CONSOLE_LOGLEVEL_5 is not set -# CONFIG_DEFAULT_CONSOLE_LOGLEVEL_4 is not set -# CONFIG_DEFAULT_CONSOLE_LOGLEVEL_3 is not set -# CONFIG_DEFAULT_CONSOLE_LOGLEVEL_2 is not set -# CONFIG_DEFAULT_CONSOLE_LOGLEVEL_1 is not set -# CONFIG_DEFAULT_CONSOLE_LOGLEVEL_0 is not set -# CONFIG_CMOS_POST is not set -# CONFIG_CONSOLE_POST is not set -# CONFIG_NO_EARLY_BOOTBLOCK_POSTCODES is not set -CONFIG_HWBASE_DEBUG_CB=y -CONFIG_HAVE_ACPI_RESUME=y -# CONFIG_ACPI_HUGE_LOWMEM_BACKUP is not set -CONFIG_RESUME_PATH_SAME_AS_BOOT=y -CONFIG_HAVE_HARD_RESET=y -# CONFIG_HAVE_ROMSTAGE_CONSOLE_SPINLOCK is not set -# CONFIG_HAVE_ROMSTAGE_NVRAM_CBFS_SPINLOCK is not set -# CONFIG_HAVE_ROMSTAGE_MICROCODE_CBFS_SPINLOCK is not set -CONFIG_HAVE_MONOTONIC_TIMER=y -# CONFIG_GENERIC_UDELAY is not set -# CONFIG_TIMER_QUEUE is not set -# CONFIG_HAVE_OPTION_TABLE is not set -# CONFIG_PIRQ_ROUTE is not set -CONFIG_HAVE_SMI_HANDLER=y -# CONFIG_PCI_IO_CFG_EXT is not set -CONFIG_IOAPIC=y -# CONFIG_USE_WATCHDOG_ON_BOOT is not set -# CONFIG_GFXUMA is not set -CONFIG_HAVE_ACPI_TABLES=y -CONFIG_COMMON_FADT=y -CONFIG_ACPI_NHLT=y - -# -# System tables -# -# CONFIG_GENERATE_MP_TABLE is not set -# CONFIG_GENERATE_PIRQ_TABLE is not set -CONFIG_GENERATE_SMBIOS_TABLES=y - -# -# Payload -# -# CONFIG_PAYLOAD_NONE is not set -# CONFIG_PAYLOAD_ELF is not set -# CONFIG_PAYLOAD_BAYOU is not set -# CONFIG_PAYLOAD_FILO is not set -# CONFIG_PAYLOAD_GRUB2 is not set -# CONFIG_PAYLOAD_SEABIOS is not set -# CONFIG_PAYLOAD_UBOOT is not set CONFIG_PAYLOAD_LINUX=y -# CONFIG_PAYLOAD_TIANOCORE is not set CONFIG_PAYLOAD_FILE="../../build/librem15v3/bzImage" -CONFIG_PAYLOAD_OPTIONS="" -# CONFIG_PXE is not set CONFIG_LINUX_COMMAND_LINE="intel_iommu=on iommu=pt" CONFIG_LINUX_INITRD="../../build/librem15v3/initrd.cpio.xz" -# CONFIG_PAYLOAD_IS_FLAT_BINARY is not set - -# -# Secondary Payloads -# CONFIG_COREINFO_SECONDARY_PAYLOAD=y CONFIG_MEMTEST_SECONDARY_PAYLOAD=y -CONFIG_MEMTEST_STABLE=y -# CONFIG_MEMTEST_MASTER is not set -# CONFIG_NVRAMCUI_SECONDARY_PAYLOAD is not set -# CONFIG_TINT_SECONDARY_PAYLOAD is not set - -# -# Debugging -# -# CONFIG_FATAL_ASSERTS is not set -# CONFIG_DEBUG_CBFS is not set -# CONFIG_HAVE_DEBUG_RAM_SETUP is not set -# CONFIG_HAVE_DEBUG_CAR is not set -# CONFIG_HAVE_DEBUG_SMBUS is not set -# CONFIG_DEBUG_SMI is not set -# CONFIG_DEBUG_SMM_RELOCATION is not set -# CONFIG_DEBUG_MALLOC is not set -# CONFIG_DEBUG_ACPI is not set -# CONFIG_DEBUG_TPM is not set -# CONFIG_DEBUG_SPI_FLASH is not set -# CONFIG_TRACE is not set -# CONFIG_DEBUG_BOOT_STATE is not set -# CONFIG_DEBUG_ADA_CODE is not set -CONFIG_NO_EDID_FILL_FB=y -# CONFIG_ENABLE_APIC_EXT_ID is not set -CONFIG_WARNINGS_ARE_ERRORS=y -# CONFIG_POWER_BUTTON_DEFAULT_ENABLE is not set -# CONFIG_POWER_BUTTON_DEFAULT_DISABLE is not set -# CONFIG_POWER_BUTTON_FORCE_ENABLE is not set -# CONFIG_POWER_BUTTON_FORCE_DISABLE is not set -# CONFIG_POWER_BUTTON_IS_OPTIONAL is not set -CONFIG_REG_SCRIPT=y -# CONFIG_CREATE_BOARD_CHECKLIST is not set -# CONFIG_MAKE_CHECKLIST_PUBLIC is not set -# CONFIG_NO_XIP_EARLY_STAGES is not set -CONFIG_EARLY_CBMEM_INIT=y -# CONFIG_EARLY_CBMEM_LIST is not set -CONFIG_RELOCATABLE_MODULES=y -CONFIG_GENERIC_GPIO_LIB=y -CONFIG_SPD_READ_BY_WORD=y -CONFIG_C_ENVIRONMENT_BOOTBLOCK=y diff --git a/config/coreboot-qemu.config b/config/coreboot-qemu.config index 33d632da..cfccf526 100644 --- a/config/coreboot-qemu.config +++ b/config/coreboot-qemu.config @@ -1,576 +1,17 @@ -# -# Automatically generated file; DO NOT EDIT. -# coreboot configuration -# - -# -# General setup -# -CONFIG_COREBOOT_BUILD=y CONFIG_LOCALVERSION="-heads" -CONFIG_CBFS_PREFIX="fallback" -CONFIG_COMPILER_GCC=y -# CONFIG_COMPILER_LLVM_CLANG is not set -# CONFIG_ANY_TOOLCHAIN is not set -# CONFIG_CCACHE is not set -# CONFIG_FMD_GENPARSER is not set -# CONFIG_UTIL_GENPARSER is not set -CONFIG_COMPRESS_RAMSTAGE=y # CONFIG_INCLUDE_CONFIG_FILE is not set -CONFIG_COLLECT_TIMESTAMPS=y -# CONFIG_USE_BLOBS is not set -# CONFIG_COVERAGE is not set -# CONFIG_UBSAN is not set -# CONFIG_RELOCATABLE_RAMSTAGE is not set -# CONFIG_UPDATE_IMAGE is not set -# CONFIG_BOOTSPLASH_IMAGE is not set - -# -# Mainboard -# - -# -# Important: Run 'make distclean' before switching boards -# -# CONFIG_VENDOR_A_TREND is not set -# CONFIG_VENDOR_AAEON is not set -# CONFIG_VENDOR_ABIT is not set -# CONFIG_VENDOR_ADI is not set -# CONFIG_VENDOR_ADLINK is not set -# CONFIG_VENDOR_ADVANSUS is not set -# CONFIG_VENDOR_AMD is not set -# CONFIG_VENDOR_AOPEN is not set -# CONFIG_VENDOR_APPLE is not set -# CONFIG_VENDOR_ARTECGROUP is not set -# CONFIG_VENDOR_ASROCK is not set -# CONFIG_VENDOR_ASUS is not set -# CONFIG_VENDOR_AVALUE is not set -# CONFIG_VENDOR_AZZA is not set -# CONFIG_VENDOR_BACHMANN is not set -# CONFIG_VENDOR_BAP is not set -# CONFIG_VENDOR_BCOM is not set -# CONFIG_VENDOR_BIOSTAR is not set -# CONFIG_VENDOR_BROADCOM is not set -# CONFIG_VENDOR_COMPAQ is not set -# CONFIG_VENDOR_COMPULAB is not set -# CONFIG_VENDOR_CUBIETECH is not set -# CONFIG_VENDOR_DIGITALLOGIC is not set -# CONFIG_VENDOR_DMP is not set -# CONFIG_VENDOR_ECS is not set -# CONFIG_VENDOR_ELMEX is not set -CONFIG_VENDOR_EMULATION=y -# CONFIG_VENDOR_ESD is not set -# CONFIG_VENDOR_FOXCONN is not set -# CONFIG_VENDOR_GETAC is not set -# CONFIG_VENDOR_GIGABYTE is not set -# CONFIG_VENDOR_GIZMOSPHERE is not set -# CONFIG_VENDOR_GOOGLE is not set -# CONFIG_VENDOR_HP is not set -# CONFIG_VENDOR_IBASE is not set -# CONFIG_VENDOR_IEI is not set -# CONFIG_VENDOR_INTEL is not set -# CONFIG_VENDOR_IWAVE is not set -# CONFIG_VENDOR_IWILL is not set -# CONFIG_VENDOR_JETWAY is not set -# CONFIG_VENDOR_KONTRON is not set -# CONFIG_VENDOR_LANNER is not set -# CONFIG_VENDOR_LENOVO is not set -# CONFIG_VENDOR_LINUTOP is not set -# CONFIG_VENDOR_LIPPERT is not set -# CONFIG_VENDOR_LOWRISC is not set -# CONFIG_VENDOR_MITAC is not set -# CONFIG_VENDOR_MSI is not set -# CONFIG_VENDOR_NEC is not set -# CONFIG_VENDOR_NOKIA is not set -# CONFIG_VENDOR_NVIDIA is not set -# CONFIG_VENDOR_PACKARDBELL is not set -# CONFIG_VENDOR_PCENGINES is not set -# CONFIG_VENDOR_PURISM is not set -# CONFIG_VENDOR_RCA is not set -# CONFIG_VENDOR_RODA is not set -# CONFIG_VENDOR_SAMSUNG is not set -# CONFIG_VENDOR_SAPPHIRE is not set -# CONFIG_VENDOR_SIEMENS is not set -# CONFIG_VENDOR_SOYO is not set -# CONFIG_VENDOR_SUNW is not set -# CONFIG_VENDOR_SUPERMICRO is not set -# CONFIG_VENDOR_TECHNEXION is not set -# CONFIG_VENDOR_THOMSON is not set -# CONFIG_VENDOR_TI is not set -# CONFIG_VENDOR_TRAVERSE is not set -# CONFIG_VENDOR_TYAN is not set -# CONFIG_VENDOR_VIA is not set -# CONFIG_VENDOR_WINENT is not set -# CONFIG_VENDOR_WINNET is not set -# CONFIG_VENDOR_WYSE is not set -CONFIG_BOARD_SPECIFIC_OPTIONS=y -CONFIG_MAINBOARD_DIR="emulation/qemu-q35" -CONFIG_MAINBOARD_PART_NUMBER="QEMU x86 q35/ich9" -CONFIG_MAINBOARD_VENDOR="Emulation" -CONFIG_MAX_CPUS=1 -CONFIG_CACHE_ROM_SIZE_OVERRIDE=0x0 CONFIG_CBFS_SIZE=0x700000 -# CONFIG_ONBOARD_VGA_IS_PRIMARY is not set -CONFIG_DIMM_SPD_SIZE=256 -# CONFIG_VGA_BIOS is not set -CONFIG_MAINBOARD_SERIAL_NUMBER="123456789" -CONFIG_DCACHE_RAM_BASE=0xd0000 -CONFIG_DCACHE_RAM_SIZE=0x10000 -CONFIG_MAINBOARD_SMBIOS_MANUFACTURER="Emulation" -CONFIG_MMCONF_BASE_ADDRESS=0xb0000000 # CONFIG_POST_IO is not set -CONFIG_DEVICETREE="devicetree.cb" -CONFIG_BOOTBLOCK_MAINBOARD_INIT="mainboard/emulation/qemu-q35/bootblock.c" -CONFIG_MAX_REBOOT_CNT=3 -CONFIG_ID_SECTION_OFFSET=0x80 -# CONFIG_BOARD_EMULATION_QEMU_ARMV7 is not set -# CONFIG_BOARD_EMULATION_QEMU_X86_I440FX is not set -# CONFIG_BOARD_EMULATION_QEMU_POWER8 is not set CONFIG_BOARD_EMULATION_QEMU_X86_Q35=y -# CONFIG_BOARD_EMULATION_QEMU_UCB_RISCV is not set -# CONFIG_BOARD_EMULATION_SPIKE_UCB_RISCV is not set -CONFIG_BOARD_EMULATION_QEMU_X86=y # CONFIG_POST_DEVICE is not set -# CONFIG_VBOOT is not set -CONFIG_FMDFILE="" -CONFIG_PRERAM_CBMEM_CONSOLE_SIZE=0xc00 -CONFIG_DRIVERS_UART_8250IO=y -CONFIG_MAINBOARD_SMBIOS_PRODUCT_NAME="QEMU x86 q35/ich9" -CONFIG_CPU_ADDR_BITS=36 -CONFIG_DEFAULT_CONSOLE_LOGLEVEL=6 -# CONFIG_USBDEBUG is not set -CONFIG_MAINBOARD_VERSION="1.0" CONFIG_DRIVERS_PS2_KEYBOARD=y -# CONFIG_PCIEXP_L1_SUB_STATE is not set -# CONFIG_NO_POST is not set -CONFIG_BOARD_ROMSIZE_KB_2048=y -# CONFIG_COREBOOT_ROMSIZE_KB_64 is not set -# CONFIG_COREBOOT_ROMSIZE_KB_128 is not set -# CONFIG_COREBOOT_ROMSIZE_KB_256 is not set -# CONFIG_COREBOOT_ROMSIZE_KB_512 is not set -# CONFIG_COREBOOT_ROMSIZE_KB_1024 is not set -# CONFIG_COREBOOT_ROMSIZE_KB_2048 is not set -# CONFIG_COREBOOT_ROMSIZE_KB_4096 is not set CONFIG_COREBOOT_ROMSIZE_KB_8192=y -# CONFIG_COREBOOT_ROMSIZE_KB_10240 is not set -# CONFIG_COREBOOT_ROMSIZE_KB_12288 is not set -# CONFIG_COREBOOT_ROMSIZE_KB_16384 is not set -# CONFIG_COREBOOT_ROMSIZE_KB_32768 is not set -# CONFIG_COREBOOT_ROMSIZE_KB_65536 is not set -CONFIG_COREBOOT_ROMSIZE_KB=8192 -CONFIG_ROM_SIZE=0x800000 -# CONFIG_MAINBOARD_HAS_TPM2 is not set -# CONFIG_SYSTEM_TYPE_LAPTOP is not set -# CONFIG_CBFS_AUTOGEN_ATTRIBUTES is not set - -# -# Chipset -# - -# -# SoC -# -CONFIG_RAMTOP=0x200000 -CONFIG_HEAP_SIZE=0x4000 -CONFIG_RAMBASE=0x100000 -CONFIG_EHCI_BAR=0xfef00000 -CONFIG_ACPI_CPU_STRING="\\_PR.CP%02d" -# CONFIG_SOC_BROADCOM_CYGNUS is not set -# CONFIG_SOC_INTEL_GLK is not set -CONFIG_C_ENV_BOOTBLOCK_SIZE=0x10000 -CONFIG_X86_TOP4G_BOOTMEDIA_MAP=y -CONFIG_ROMSTAGE_ADDR=0x2000000 -CONFIG_VERSTAGE_ADDR=0x2000000 CONFIG_PCIEXP_ASPM=y CONFIG_PCIEXP_COMMON_CLOCK=y -# CONFIG_PCIEXP_CLK_PM is not set -CONFIG_BOOTBLOCK_SOUTHBRIDGE_INIT="southbridge/intel/i82801ix/bootblock.c" -CONFIG_STACK_SIZE=0x1000 -CONFIG_CONSOLE_CBMEM=y CONFIG_UART_PCI_ADDR=0 -CONFIG_HPET_MIN_TICKS=0x80 -# CONFIG_SOC_INTEL_KABYLAKE is not set -# CONFIG_SOC_LOWRISC_LOWRISC is not set -# CONFIG_SOC_MARVELL_MVMAP2315 is not set -# CONFIG_SOC_MEDIATEK_MT8173 is not set -# CONFIG_SOC_NVIDIA_TEGRA124 is not set -# CONFIG_SOC_NVIDIA_TEGRA210 is not set -# CONFIG_SOC_QC_IPQ40XX is not set -# CONFIG_SOC_QC_IPQ806X is not set -# CONFIG_SOC_ROCKCHIP_RK3288 is not set -# CONFIG_SOC_ROCKCHIP_RK3399 is not set -# CONFIG_CPU_SAMSUNG_EXYNOS5250 is not set -# CONFIG_CPU_SAMSUNG_EXYNOS5420 is not set -# CONFIG_SOC_UCB_RISCV is not set - -# -# CPU -# -# CONFIG_CPU_ALLWINNER_A10 is not set -CONFIG_XIP_ROM_SIZE=0x10000 -CONFIG_NUM_IPI_STARTS=2 -# CONFIG_CPU_AMD_AGESA is not set -# CONFIG_CPU_AMD_PI is not set -# CONFIG_CPU_ARMLTD_CORTEX_A9 is not set -# CONFIG_SSE2 is not set -# CONFIG_CPU_INTEL_FIRMWARE_INTERFACE_TABLE is not set -# CONFIG_CPU_INTEL_TURBO_NOT_PACKAGE_SCOPED is not set -CONFIG_CPU_QEMU_X86=y -# CONFIG_CPU_TI_AM335X is not set -# CONFIG_PARALLEL_CPU_INIT is not set -# CONFIG_PARALLEL_MP is not set -CONFIG_UDELAY_IO=y -# CONFIG_UDELAY_LAPIC is not set -# CONFIG_UDELAY_TSC is not set -# CONFIG_UDELAY_TIMER2 is not set -# CONFIG_TSC_SYNC_LFENCE is not set -# CONFIG_TSC_SYNC_MFENCE is not set -# CONFIG_NO_FIXED_XIP_ROM_SIZE is not set -CONFIG_LOGICAL_CPUS=y -# CONFIG_SMM_TSEG is not set -# CONFIG_SMM_LAPIC_REMAP_MITIGATION is not set -# CONFIG_SERIALIZED_SMM_INITIALIZATION is not set -# CONFIG_X86_AMD_FIXED_MTRRS is not set -# CONFIG_PLATFORM_USES_FSP1_0 is not set -# CONFIG_MIRROR_PAYLOAD_TO_RAM_BEFORE_LOADING is not set -# CONFIG_SOC_SETS_MSRS is not set -CONFIG_CACHE_AS_RAM=y -# CONFIG_NO_CAR_GLOBAL_MIGRATION is not set -CONFIG_SMP=y -CONFIG_AP_SIPI_VECTOR=0xfffff000 -# CONFIG_SUPPORT_CPU_UCODE_IN_CBFS is not set -# CONFIG_USES_MICROCODE_HEADER_FILES is not set CONFIG_CPU_MICROCODE_CBFS_GENERATE=y -# CONFIG_CPU_MICROCODE_CBFS_EXTERNAL_HEADER is not set -# CONFIG_CPU_MICROCODE_CBFS_NONE is not set -# CONFIG_CPU_MICROCODE_MULTIPLE_FILES is not set -CONFIG_CPU_UCODE_BINARIES="" - -# -# Northbridge -# -# CONFIG_NORTHBRIDGE_AMD_AGESA is not set -# CONFIG_NO_MMCONF_SUPPORT is not set -# CONFIG_AMD_NB_CIMX is not set -# CONFIG_NORTHBRIDGE_AMD_CIMX_RD890 is not set -# CONFIG_NORTHBRIDGE_AMD_PI is not set -# CONFIG_NORTHBRIDGE_INTEL_COMMON_MRC_CACHE is not set -CONFIG_HPET_ADDRESS=0xfed00000 -CONFIG_MAX_PIRQ_LINKS=4 - -# -# Southbridge -# -# CONFIG_AMD_SB_CIMX is not set -# CONFIG_SOUTHBRIDGE_AMD_CIMX_SB800 is not set -# CONFIG_SOUTHBRIDGE_AMD_CIMX_SB900 is not set -CONFIG_SOUTHBRIDGE_INTEL_COMMON=y -CONFIG_SOUTHBRIDGE_INTEL_COMMON_GPIO=y -CONFIG_SOUTHBRIDGE_INTEL_COMMON_SMBUS=y -# CONFIG_SOUTHBRIDGE_INTEL_COMMON_SPI is not set -# CONFIG_SOUTHBRIDGE_INTEL_COMMON_PIRQ_ACPI_GEN is not set -# CONFIG_SOUTHBRIDGE_INTEL_COMMON_RCBA_PIRQ is not set -# CONFIG_HAVE_INTEL_CHIPSET_LOCKDOWN is not set -CONFIG_SOUTHBRIDGE_INTEL_I82801IX=y - -# -# Super I/O -# -# CONFIG_SUPERIO_NUVOTON_NCT6776_COM_A is not set - -# -# Embedded Controllers -# -# CONFIG_MAINBOARD_HAS_CHROMEOS is not set -# CONFIG_GOOGLE_SMBIOS_MAINBOARD_VERSION is not set -# CONFIG_UEFI_2_4_BINDING is not set -# CONFIG_UDK_2015_BINDING is not set -# CONFIG_USE_SIEMENS_HWILIB is not set -# CONFIG_ARCH_ARM is not set -# CONFIG_ARCH_BOOTBLOCK_ARM is not set -# CONFIG_ARCH_VERSTAGE_ARM is not set -# CONFIG_ARCH_ROMSTAGE_ARM is not set -# CONFIG_ARCH_RAMSTAGE_ARM is not set -# CONFIG_ARCH_BOOTBLOCK_ARMV4 is not set -# CONFIG_ARCH_VERSTAGE_ARMV4 is not set -# CONFIG_ARCH_ROMSTAGE_ARMV4 is not set -# CONFIG_ARCH_RAMSTAGE_ARMV4 is not set -# CONFIG_ARCH_BOOTBLOCK_ARMV7 is not set -# CONFIG_ARCH_VERSTAGE_ARMV7 is not set -# CONFIG_ARCH_ROMSTAGE_ARMV7 is not set -# CONFIG_ARCH_RAMSTAGE_ARMV7 is not set -# CONFIG_ARCH_BOOTBLOCK_ARMV7_M is not set -# CONFIG_ARCH_VERSTAGE_ARMV7_M is not set -# CONFIG_ARCH_BOOTBLOCK_ARMV7_R is not set -# CONFIG_ARCH_VERSTAGE_ARMV7_R is not set -# CONFIG_ARCH_ROMSTAGE_ARMV7_R is not set -# CONFIG_ARCH_RAMSTAGE_ARMV7_R is not set -# CONFIG_ARM_LPAE is not set -# CONFIG_ARCH_ARM64 is not set -# CONFIG_ARCH_BOOTBLOCK_ARM64 is not set -# CONFIG_ARCH_VERSTAGE_ARM64 is not set -# CONFIG_ARCH_ROMSTAGE_ARM64 is not set -# CONFIG_ARCH_RAMSTAGE_ARM64 is not set -# CONFIG_ARCH_BOOTBLOCK_ARMV8_64 is not set -# CONFIG_ARCH_VERSTAGE_ARMV8_64 is not set -# CONFIG_ARCH_ROMSTAGE_ARMV8_64 is not set -# CONFIG_ARCH_RAMSTAGE_ARMV8_64 is not set -# CONFIG_ARM64_A53_ERRATUM_843419 is not set -# CONFIG_ARCH_MIPS is not set -# CONFIG_ARCH_BOOTBLOCK_MIPS is not set -# CONFIG_ARCH_VERSTAGE_MIPS is not set -# CONFIG_ARCH_ROMSTAGE_MIPS is not set -# CONFIG_ARCH_RAMSTAGE_MIPS is not set -# CONFIG_ARCH_POWER8 is not set -# CONFIG_ARCH_BOOTBLOCK_POWER8 is not set -# CONFIG_ARCH_VERSTAGE_POWER8 is not set -# CONFIG_ARCH_ROMSTAGE_POWER8 is not set -# CONFIG_ARCH_RAMSTAGE_POWER8 is not set -# CONFIG_ARCH_RISCV is not set -# CONFIG_ARCH_BOOTBLOCK_RISCV is not set -# CONFIG_ARCH_VERSTAGE_RISCV is not set -# CONFIG_ARCH_ROMSTAGE_RISCV is not set -# CONFIG_ARCH_RAMSTAGE_RISCV is not set -CONFIG_ARCH_X86=y -CONFIG_ARCH_BOOTBLOCK_X86_32=y -CONFIG_ARCH_VERSTAGE_X86_32=y -CONFIG_ARCH_ROMSTAGE_X86_32=y -CONFIG_ARCH_RAMSTAGE_X86_32=y -# CONFIG_ARCH_BOOTBLOCK_X86_64 is not set -# CONFIG_ARCH_VERSTAGE_X86_64 is not set -# CONFIG_ARCH_ROMSTAGE_X86_64 is not set -# CONFIG_ARCH_RAMSTAGE_X86_64 is not set -# CONFIG_USE_MARCH_586 is not set -# CONFIG_AP_IN_SIPI_WAIT is not set -# CONFIG_SIPI_VECTOR_IN_ROM is not set -# CONFIG_ROMCC is not set -# CONFIG_CBMEM_TOP_BACKUP is not set -# CONFIG_LATE_CBMEM_INIT is not set -# CONFIG_EARLY_EBDA_INIT is not set -CONFIG_PC80_SYSTEM=y -# CONFIG_BOOTBLOCK_DEBUG_SPINLOOP is not set -# CONFIG_BOOTBLOCK_SAVE_BIST_AND_TIMESTAMP is not set -CONFIG_IOAPIC_INTERRUPTS_ON_APIC_SERIAL_BUS=y -# CONFIG_POSTCAR_STAGE is not set -# CONFIG_VERSTAGE_DEBUG_SPINLOOP is not set -# CONFIG_ROMSTAGE_DEBUG_SPINLOOP is not set -CONFIG_BOOTBLOCK_SIMPLE=y -# CONFIG_BOOTBLOCK_NORMAL is not set -CONFIG_BOOTBLOCK_SOURCE="bootblock_simple.c" - -# -# Devices -# -CONFIG_HAVE_VGA_TEXT_FRAMEBUFFER=y -CONFIG_HAVE_LINEAR_FRAMEBUFFER=y -CONFIG_MAINBOARD_HAS_NATIVE_VGA_INIT=y -CONFIG_MAINBOARD_FORCE_NATIVE_VGA_INIT=y -# CONFIG_MAINBOARD_HAS_LIBGFXINIT is not set -CONFIG_MAINBOARD_DO_NATIVE_VGA_INIT=y -# CONFIG_MULTIPLE_VGA_ADAPTERS is not set - -# -# Display -# -CONFIG_VGA_TEXT_FRAMEBUFFER=y -# CONFIG_GENERIC_LINEAR_FRAMEBUFFER is not set -# CONFIG_SMBUS_HAS_AUX_CHANNELS is not set -CONFIG_PCI=y -CONFIG_MMCONF_SUPPORT=y -# CONFIG_HYPERTRANSPORT_PLUGIN_SUPPORT is not set -CONFIG_PCIX_PLUGIN_SUPPORT=y -CONFIG_CARDBUS_PLUGIN_SUPPORT=y -# CONFIG_AZALIA_PLUGIN_SUPPORT is not set -CONFIG_PCIEXP_PLUGIN_SUPPORT=y -# CONFIG_EARLY_PCI_BRIDGE is not set -CONFIG_SUBSYSTEM_VENDOR_ID=0x0000 -CONFIG_SUBSYSTEM_DEVICE_ID=0x0000 -# CONFIG_SOFTWARE_I2C is not set - -# -# Generic Drivers -# -# CONFIG_DRIVERS_AS3722_RTC is not set -# CONFIG_GIC is not set -# CONFIG_IPMI_KCS is not set -# CONFIG_DRIVERS_LENOVO_WACOM is not set -# CONFIG_RT8168_GET_MAC_FROM_VPD is not set -# CONFIG_RT8168_SET_LED_MODE is not set -# CONFIG_SPI_FLASH is not set -# CONFIG_HAVE_SPI_CONSOLE_SUPPORT is not set -# CONFIG_DRIVERS_UART is not set -# CONFIG_DRIVERS_UART_8250IO_SKIP_INIT is not set -# CONFIG_NO_UART_ON_SUPERIO is not set -# CONFIG_UART_OVERRIDE_INPUT_CLOCK_DIVIDER is not set -# CONFIG_UART_OVERRIDE_REFCLK is not set -# CONFIG_DRIVERS_UART_8250MEM is not set -# CONFIG_DRIVERS_UART_8250MEM_32 is not set -# CONFIG_HAVE_UART_SPECIAL is not set -# CONFIG_DRIVERS_UART_OXPCIE is not set -# CONFIG_DRIVERS_UART_PL011 is not set -# CONFIG_UART_USE_REFCLK_AS_INPUT_CLOCK is not set -CONFIG_HAVE_USBDEBUG=y -CONFIG_HAVE_USBDEBUG_OPTIONS=y -# CONFIG_DRIVERS_AMD_PI is not set -CONFIG_DRIVERS_EMULATION_QEMU_BOCHS=y -# CONFIG_SMBIOS_PROVIDED_BY_MOBO is not set -# CONFIG_DRIVERS_I2C_MAX98927 is not set -# CONFIG_DRIVERS_I2C_PCF8523 is not set -# CONFIG_DRIVERS_I2C_RT5663 is not set -# CONFIG_DRIVERS_I2C_RTD2132 is not set -# CONFIG_DRIVERS_I2C_RX6110SA is not set -# CONFIG_MAINBOARD_HAS_I2C_TPM_ATMEL is not set -# CONFIG_MAINBOARD_HAS_I2C_TPM_CR50 is not set -# CONFIG_INTEL_DDI is not set -# CONFIG_INTEL_EDID is not set -# CONFIG_INTEL_INT15 is not set -# CONFIG_INTEL_GMA_ACPI is not set -# CONFIG_INTEL_GMA_SSC_ALTERNATE_REF is not set -# CONFIG_DRIVER_INTEL_I210 is not set -# CONFIG_DRIVERS_INTEL_MIPI_CAMERA is not set -CONFIG_DRIVERS_INTEL_WIFI=y -# CONFIG_USE_SAR is not set -# CONFIG_DRIVERS_LENOVO_HYBRID_GRAPHICS is not set -# CONFIG_DRIVER_MAXIM_MAX77686 is not set -# CONFIG_DRIVER_PARADE_PS8625 is not set -# CONFIG_DRIVER_PARADE_PS8640 is not set -CONFIG_DRIVERS_MC146818=y -# CONFIG_MAINBOARD_HAS_LPC_TPM is not set -CONFIG_VGA=y -# CONFIG_DRIVERS_RICOH_RCE822 is not set -# CONFIG_DRIVER_SIEMENS_NC_FPGA is not set -# CONFIG_NC_FPGA_NOTIFY_CB_READY is not set -# CONFIG_DRIVERS_SIL_3114 is not set -# CONFIG_MAINBOARD_HAS_SPI_TPM_CR50 is not set -# CONFIG_DRIVER_TI_TPS65090 is not set -# CONFIG_DRIVERS_TI_TPS65913 is not set -# CONFIG_DRIVERS_TI_TPS65913_RTC is not set -# CONFIG_DRIVER_XPOWERS_AXP209 is not set -# CONFIG_COMMONLIB_STORAGE is not set - -# -# Security -# - -# -# Verified Boot (vboot) -# -# CONFIG_ACPI_SATA_GENERATOR is not set -# CONFIG_ACPI_INTEL_HARDWARE_SLEEP_VALUES is not set -# CONFIG_ACPI_AMD_HARDWARE_SLEEP_VALUES is not set -# CONFIG_BOOT_DEVICE_NOT_SPI_FLASH is not set -CONFIG_BOOT_DEVICE_SPI_FLASH=y -CONFIG_BOOT_DEVICE_MEMORY_MAPPED=y -# CONFIG_BOOT_DEVICE_SUPPORTS_WRITES is not set -# CONFIG_RTC is not set -# CONFIG_TPM is not set -# CONFIG_MAINBOARD_HAS_TPM_CR50 is not set - -# -# Console -# -CONFIG_SQUELCH_EARLY_SMP=y # CONFIG_CONSOLE_SERIAL is not set -# CONFIG_SPKMODEM is not set -# CONFIG_CONSOLE_NE2K is not set -CONFIG_CONSOLE_CBMEM_BUFFER_SIZE=0x20000 -# CONFIG_CONSOLE_CBMEM_DUMP_TO_UART is not set -# CONFIG_CONSOLE_SPI_FLASH is not set -CONFIG_CONSOLE_QEMU_DEBUGCON=y -CONFIG_CONSOLE_QEMU_DEBUGCON_PORT=0x402 -# CONFIG_DEFAULT_CONSOLE_LOGLEVEL_8 is not set -# CONFIG_DEFAULT_CONSOLE_LOGLEVEL_7 is not set CONFIG_DEFAULT_CONSOLE_LOGLEVEL_6=y -# CONFIG_DEFAULT_CONSOLE_LOGLEVEL_5 is not set -# CONFIG_DEFAULT_CONSOLE_LOGLEVEL_4 is not set -# CONFIG_DEFAULT_CONSOLE_LOGLEVEL_3 is not set -# CONFIG_DEFAULT_CONSOLE_LOGLEVEL_2 is not set -# CONFIG_DEFAULT_CONSOLE_LOGLEVEL_1 is not set -# CONFIG_DEFAULT_CONSOLE_LOGLEVEL_0 is not set -# CONFIG_CMOS_POST is not set -# CONFIG_CONSOLE_POST is not set -# CONFIG_NO_EARLY_BOOTBLOCK_POSTCODES is not set -# CONFIG_HWBASE_DEBUG_CB is not set -CONFIG_HWBASE_DEBUG_NULL=y -# CONFIG_HAVE_ACPI_RESUME is not set -# CONFIG_ACPI_HUGE_LOWMEM_BACKUP is not set -CONFIG_HAVE_HARD_RESET=y -# CONFIG_HAVE_ROMSTAGE_CONSOLE_SPINLOCK is not set -# CONFIG_HAVE_ROMSTAGE_NVRAM_CBFS_SPINLOCK is not set -# CONFIG_HAVE_ROMSTAGE_MICROCODE_CBFS_SPINLOCK is not set -# CONFIG_HAVE_MONOTONIC_TIMER is not set -# CONFIG_HAVE_OPTION_TABLE is not set -# CONFIG_PIRQ_ROUTE is not set -CONFIG_HAVE_SMI_HANDLER=y -# CONFIG_PCI_IO_CFG_EXT is not set -CONFIG_IOAPIC=y -CONFIG_USE_WATCHDOG_ON_BOOT=y -# CONFIG_GFXUMA is not set -CONFIG_HAVE_ACPI_TABLES=y -# CONFIG_COMMON_FADT is not set -# CONFIG_ACPI_NHLT is not set - -# -# System tables -# -# CONFIG_GENERATE_MP_TABLE is not set -# CONFIG_GENERATE_PIRQ_TABLE is not set -CONFIG_GENERATE_SMBIOS_TABLES=y - -# -# Payload -# -# CONFIG_PAYLOAD_NONE is not set -# CONFIG_PAYLOAD_ELF is not set -# CONFIG_PAYLOAD_BAYOU is not set -# CONFIG_PAYLOAD_FILO is not set -# CONFIG_PAYLOAD_GRUB2 is not set -# CONFIG_PAYLOAD_SEABIOS is not set -# CONFIG_PAYLOAD_UBOOT is not set CONFIG_PAYLOAD_LINUX=y -# CONFIG_PAYLOAD_TIANOCORE is not set CONFIG_PAYLOAD_FILE="../../build/qemu-coreboot/bzImage" -CONFIG_PAYLOAD_OPTIONS="" -# CONFIG_PXE is not set -CONFIG_LINUX_COMMAND_LINE="" CONFIG_LINUX_INITRD="../../build/qemu-coreboot/initrd.cpio.xz" -# CONFIG_PAYLOAD_IS_FLAT_BINARY is not set - -# -# Secondary Payloads -# -# CONFIG_COREINFO_SECONDARY_PAYLOAD is not set -# CONFIG_MEMTEST_SECONDARY_PAYLOAD is not set -# CONFIG_NVRAMCUI_SECONDARY_PAYLOAD is not set -# CONFIG_TINT_SECONDARY_PAYLOAD is not set - -# -# Debugging -# -# CONFIG_FATAL_ASSERTS is not set -# CONFIG_DEBUG_CBFS is not set -# CONFIG_HAVE_DEBUG_RAM_SETUP is not set -# CONFIG_HAVE_DEBUG_CAR is not set -CONFIG_HAVE_DEBUG_SMBUS=y -# CONFIG_DEBUG_SMBUS is not set -# CONFIG_DEBUG_SMI is not set -# CONFIG_DEBUG_SMM_RELOCATION is not set -# CONFIG_DEBUG_MALLOC is not set -# CONFIG_DEBUG_ACPI is not set -# CONFIG_TRACE is not set -# CONFIG_DEBUG_BOOT_STATE is not set -# CONFIG_DEBUG_ADA_CODE is not set -# CONFIG_ENABLE_APIC_EXT_ID is not set -CONFIG_WARNINGS_ARE_ERRORS=y -# CONFIG_POWER_BUTTON_DEFAULT_ENABLE is not set -# CONFIG_POWER_BUTTON_DEFAULT_DISABLE is not set -# CONFIG_POWER_BUTTON_FORCE_ENABLE is not set -# CONFIG_POWER_BUTTON_FORCE_DISABLE is not set -# CONFIG_POWER_BUTTON_IS_OPTIONAL is not set -# CONFIG_REG_SCRIPT is not set -# CONFIG_CREATE_BOARD_CHECKLIST is not set -# CONFIG_MAKE_CHECKLIST_PUBLIC is not set -# CONFIG_NO_XIP_EARLY_STAGES is not set -CONFIG_EARLY_CBMEM_INIT=y -# CONFIG_EARLY_CBMEM_LIST is not set -CONFIG_BOOTBLOCK_CUSTOM=y diff --git a/config/coreboot-x220.config b/config/coreboot-x220.config index 3effe48a..a91aef7d 100644 --- a/config/coreboot-x220.config +++ b/config/coreboot-x220.config @@ -1,683 +1,25 @@ -# -# Automatically generated file; DO NOT EDIT. -# coreboot configuration -# - -# -# General setup -# -CONFIG_COREBOOT_BUILD=y CONFIG_LOCALVERSION="heads" -CONFIG_CBFS_PREFIX="fallback" -CONFIG_COMPILER_GCC=y -# CONFIG_COMPILER_LLVM_CLANG is not set -# CONFIG_ANY_TOOLCHAIN is not set -# CONFIG_CCACHE is not set -# CONFIG_FMD_GENPARSER is not set -# CONFIG_UTIL_GENPARSER is not set -# CONFIG_USE_OPTION_TABLE is not set -CONFIG_COMPRESS_RAMSTAGE=y # CONFIG_INCLUDE_CONFIG_FILE is not set # CONFIG_COLLECT_TIMESTAMPS is not set CONFIG_USE_BLOBS=y -# CONFIG_COVERAGE is not set -# CONFIG_UBSAN is not set -CONFIG_RELOCATABLE_RAMSTAGE=y -# CONFIG_UPDATE_IMAGE is not set -# CONFIG_BOOTSPLASH_IMAGE is not set CONFIG_MEASURED_BOOT=y - -# -# Mainboard -# - -# -# Important: Run 'make distclean' before switching boards -# -# CONFIG_VENDOR_A_TREND is not set -# CONFIG_VENDOR_AAEON is not set -# CONFIG_VENDOR_ABIT is not set -# CONFIG_VENDOR_ADI is not set -# CONFIG_VENDOR_ADLINK is not set -# CONFIG_VENDOR_ADVANSUS is not set -# CONFIG_VENDOR_AMD is not set -# CONFIG_VENDOR_AOPEN is not set -# CONFIG_VENDOR_APPLE is not set -# CONFIG_VENDOR_ARTECGROUP is not set -# CONFIG_VENDOR_ASROCK is not set -# CONFIG_VENDOR_ASUS is not set -# CONFIG_VENDOR_AVALUE is not set -# CONFIG_VENDOR_AZZA is not set -# CONFIG_VENDOR_BACHMANN is not set -# CONFIG_VENDOR_BAP is not set -# CONFIG_VENDOR_BCOM is not set -# CONFIG_VENDOR_BIOSTAR is not set -# CONFIG_VENDOR_BROADCOM is not set -# CONFIG_VENDOR_COMPAQ is not set -# CONFIG_VENDOR_COMPULAB is not set -# CONFIG_VENDOR_CUBIETECH is not set -# CONFIG_VENDOR_DIGITALLOGIC is not set -# CONFIG_VENDOR_DMP is not set -# CONFIG_VENDOR_ECS is not set -# CONFIG_VENDOR_ELMEX is not set -# CONFIG_VENDOR_EMULATION is not set -# CONFIG_VENDOR_ESD is not set -# CONFIG_VENDOR_FOXCONN is not set -# CONFIG_VENDOR_GETAC is not set -# CONFIG_VENDOR_GIGABYTE is not set -# CONFIG_VENDOR_GIZMOSPHERE is not set -# CONFIG_VENDOR_GOOGLE is not set -# CONFIG_VENDOR_HP is not set -# CONFIG_VENDOR_IBASE is not set -# CONFIG_VENDOR_IEI is not set -# CONFIG_VENDOR_INTEL is not set -# CONFIG_VENDOR_IWAVE is not set -# CONFIG_VENDOR_IWILL is not set -# CONFIG_VENDOR_JETWAY is not set -# CONFIG_VENDOR_KONTRON is not set -# CONFIG_VENDOR_LANNER is not set CONFIG_VENDOR_LENOVO=y -# CONFIG_VENDOR_LINUTOP is not set -# CONFIG_VENDOR_LIPPERT is not set -# CONFIG_VENDOR_LOWRISC is not set -# CONFIG_VENDOR_MITAC is not set -# CONFIG_VENDOR_MSI is not set -# CONFIG_VENDOR_NEC is not set -# CONFIG_VENDOR_NOKIA is not set -# CONFIG_VENDOR_NVIDIA is not set -# CONFIG_VENDOR_PACKARDBELL is not set -# CONFIG_VENDOR_PCENGINES is not set -# CONFIG_VENDOR_PURISM is not set -# CONFIG_VENDOR_RCA is not set -# CONFIG_VENDOR_RODA is not set -# CONFIG_VENDOR_SAMSUNG is not set -# CONFIG_VENDOR_SAPPHIRE is not set -# CONFIG_VENDOR_SIEMENS is not set -# CONFIG_VENDOR_SOYO is not set -# CONFIG_VENDOR_SUNW is not set -# CONFIG_VENDOR_SUPERMICRO is not set -# CONFIG_VENDOR_TECHNEXION is not set -# CONFIG_VENDOR_THOMSON is not set -# CONFIG_VENDOR_TI is not set -# CONFIG_VENDOR_TRAVERSE is not set -# CONFIG_VENDOR_TYAN is not set -# CONFIG_VENDOR_VIA is not set -# CONFIG_VENDOR_WINENT is not set -# CONFIG_VENDOR_WINNET is not set -# CONFIG_VENDOR_WYSE is not set -CONFIG_BOARD_SPECIFIC_OPTIONS=y -CONFIG_MAINBOARD_DIR="lenovo/x220" -CONFIG_MAINBOARD_PART_NUMBER="ThinkPad X220" -CONFIG_MAINBOARD_VENDOR="LENOVO" -CONFIG_MAX_CPUS=8 -CONFIG_CACHE_ROM_SIZE_OVERRIDE=0x0 CONFIG_CBFS_SIZE=0x7e8000 -CONFIG_VGA_BIOS_ID="8086,0126" CONFIG_ONBOARD_VGA_IS_PRIMARY=y -CONFIG_DIMM_SPD_SIZE=256 -# CONFIG_VGA_BIOS is not set -CONFIG_DCACHE_RAM_BASE=0xfefe0000 -CONFIG_DCACHE_RAM_SIZE=0x20000 -CONFIG_VGA_BIOS_FILE="pci8086,0126.rom" -CONFIG_MAINBOARD_PCI_SUBSYSTEM_VENDOR_ID=0x17aa -CONFIG_MAINBOARD_PCI_SUBSYSTEM_DEVICE_ID=0x21db CONFIG_HAVE_IFD_BIN=y CONFIG_HAVE_ME_BIN=y -CONFIG_DRAM_RESET_GATE_GPIO=10 -CONFIG_MMCONF_BASE_ADDRESS=0xf8000000 -CONFIG_DEVICETREE="devicetree.cb" -CONFIG_MAX_REBOOT_CNT=3 CONFIG_HAVE_GBE_BIN=y -CONFIG_USBDEBUG_HCD_INDEX=2 -CONFIG_ID_SECTION_OFFSET=0x80 -# CONFIG_VBOOT is not set -CONFIG_TPM_PIRQ=0x0 -CONFIG_BOOT_DEVICE_SPI_FLASH_BUS=0 -CONFIG_FMDFILE="" -CONFIG_PRERAM_CBMEM_CONSOLE_SIZE=0xc00 -# CONFIG_DRIVERS_UART_8250IO is not set CONFIG_IFD_BIN_PATH="../../blobs/x220/ifd.bin" CONFIG_ME_BIN_PATH="../../blobs/x220/me.bin" -# CONFIG_BOARD_LENOVO_G505S is not set -# CONFIG_BOARD_LENOVO_L520 is not set -# CONFIG_BOARD_LENOVO_R400 is not set -# CONFIG_BOARD_LENOVO_S230U is not set -# CONFIG_BOARD_LENOVO_T400 is not set -# CONFIG_BOARD_LENOVO_T420 is not set -# CONFIG_BOARD_LENOVO_T420S is not set -# CONFIG_BOARD_LENOVO_THINKPAD_T430 is not set -# CONFIG_BOARD_LENOVO_T430S is not set -# CONFIG_BOARD_LENOVO_T500 is not set -# CONFIG_BOARD_LENOVO_T520 is not set -# CONFIG_BOARD_LENOVO_T530 is not set -# CONFIG_BOARD_LENOVO_T60 is not set -# CONFIG_BOARD_LENOVO_X131E is not set -# CONFIG_BOARD_LENOVO_X1_CARBON_GEN1 is not set -# CONFIG_BOARD_LENOVO_X200 is not set -# CONFIG_BOARD_LENOVO_X201 is not set CONFIG_BOARD_LENOVO_X220=y -# CONFIG_BOARD_LENOVO_X220I is not set -# CONFIG_BOARD_LENOVO_X230 is not set -# CONFIG_BOARD_LENOVO_X60 is not set -# CONFIG_BOARD_LENOVO_Z61T is not set -CONFIG_CPU_ADDR_BITS=36 -CONFIG_DEFAULT_CONSOLE_LOGLEVEL=5 -# CONFIG_USBDEBUG is not set CONFIG_DRIVERS_PS2_KEYBOARD=y -# CONFIG_PCIEXP_L1_SUB_STATE is not set CONFIG_NO_POST=y -CONFIG_BOARD_ROMSIZE_KB_8192=y -# CONFIG_COREBOOT_ROMSIZE_KB_64 is not set -# CONFIG_COREBOOT_ROMSIZE_KB_128 is not set -# CONFIG_COREBOOT_ROMSIZE_KB_256 is not set -# CONFIG_COREBOOT_ROMSIZE_KB_512 is not set -# CONFIG_COREBOOT_ROMSIZE_KB_1024 is not set -# CONFIG_COREBOOT_ROMSIZE_KB_2048 is not set -# CONFIG_COREBOOT_ROMSIZE_KB_4096 is not set -CONFIG_COREBOOT_ROMSIZE_KB_8192=y -# CONFIG_COREBOOT_ROMSIZE_KB_10240 is not set -# CONFIG_COREBOOT_ROMSIZE_KB_12288 is not set -# CONFIG_COREBOOT_ROMSIZE_KB_16384 is not set -# CONFIG_COREBOOT_ROMSIZE_KB_32768 is not set -# CONFIG_COREBOOT_ROMSIZE_KB_65536 is not set -CONFIG_COREBOOT_ROMSIZE_KB=8192 -CONFIG_ROM_SIZE=0x800000 -# CONFIG_MAINBOARD_HAS_TPM2 is not set -CONFIG_SYSTEM_TYPE_LAPTOP=y -# CONFIG_CBFS_AUTOGEN_ATTRIBUTES is not set - -# -# Chipset -# - -# -# SoC -# -CONFIG_CPU_SPECIFIC_OPTIONS=y -CONFIG_RAMTOP=0x200000 -CONFIG_HEAP_SIZE=0x4000 -CONFIG_RAMBASE=0x100000 -CONFIG_EHCI_BAR=0xfef00000 -CONFIG_SERIRQ_CONTINUOUS_MODE=y -CONFIG_SMM_TSEG_SIZE=0x800000 -CONFIG_ACPI_CPU_STRING="\\_PR.CP%02d" -# CONFIG_SOC_BROADCOM_CYGNUS is not set -CONFIG_BOOTBLOCK_CPU_INIT="cpu/intel/model_206ax/bootblock.c" -# CONFIG_SOC_INTEL_GLK is not set -CONFIG_C_ENV_BOOTBLOCK_SIZE=0x10000 -CONFIG_X86_TOP4G_BOOTMEDIA_MAP=y -CONFIG_ROMSTAGE_ADDR=0x2000000 -CONFIG_VERSTAGE_ADDR=0x2000000 -CONFIG_SPI_FLASH_INCLUDE_ALL_DRIVERS=y -CONFIG_DCACHE_RAM_MRC_VAR_SIZE=0x0 -# CONFIG_BUILD_WITH_FAKE_IFD is not set -CONFIG_PCIEXP_ASPM=y -CONFIG_PCIEXP_COMMON_CLOCK=y -# CONFIG_PCIEXP_CLK_PM is not set -CONFIG_BOOTBLOCK_NORTHBRIDGE_INIT="northbridge/intel/sandybridge/bootblock.c" -CONFIG_BOOTBLOCK_SOUTHBRIDGE_INIT="southbridge/intel/bd82x6x/bootblock.c" -CONFIG_CACHE_MRC_SIZE_KB=512 -CONFIG_STACK_SIZE=0x1000 -CONFIG_CONSOLE_CBMEM=y -CONFIG_UART_PCI_ADDR=0x0 -CONFIG_HPET_MIN_TICKS=0x80 -# CONFIG_SOC_INTEL_KABYLAKE is not set -# CONFIG_SOC_LOWRISC_LOWRISC is not set -# CONFIG_SOC_MARVELL_MVMAP2315 is not set -# CONFIG_SOC_MEDIATEK_MT8173 is not set -# CONFIG_SOC_NVIDIA_TEGRA124 is not set -# CONFIG_SOC_NVIDIA_TEGRA210 is not set -# CONFIG_SOC_QC_IPQ40XX is not set -# CONFIG_SOC_QC_IPQ806X is not set -# CONFIG_SOC_ROCKCHIP_RK3288 is not set -# CONFIG_SOC_ROCKCHIP_RK3399 is not set -# CONFIG_CPU_SAMSUNG_EXYNOS5250 is not set -# CONFIG_CPU_SAMSUNG_EXYNOS5420 is not set -# CONFIG_SOC_UCB_RISCV is not set - -# -# CPU -# -# CONFIG_CPU_ALLWINNER_A10 is not set -CONFIG_SOCKET_SPECIFIC_OPTIONS=y -CONFIG_XIP_ROM_SIZE=0x20000 -CONFIG_NUM_IPI_STARTS=2 -# CONFIG_CPU_AMD_AGESA is not set -# CONFIG_CPU_AMD_PI is not set -# CONFIG_CPU_ARMLTD_CORTEX_A9 is not set -CONFIG_CPU_INTEL_MODEL_206AX=y -CONFIG_SSE2=y -CONFIG_CPU_INTEL_SOCKET_RPGA989=y -# CONFIG_CPU_INTEL_FIRMWARE_INTERFACE_TABLE is not set -# CONFIG_CPU_INTEL_TURBO_NOT_PACKAGE_SCOPED is not set -CONFIG_CPU_INTEL_COMMON=y -CONFIG_ENABLE_VMX=y -CONFIG_SET_VMX_LOCK_BIT=y -# CONFIG_CPU_TI_AM335X is not set -# CONFIG_PARALLEL_CPU_INIT is not set -# CONFIG_PARALLEL_MP is not set -# CONFIG_UDELAY_IO is not set -# CONFIG_UDELAY_LAPIC is not set -CONFIG_UDELAY_TSC=y -CONFIG_TSC_CONSTANT_RATE=y -CONFIG_TSC_MONOTONIC_TIMER=y -# CONFIG_UDELAY_TIMER2 is not set -# CONFIG_TSC_SYNC_LFENCE is not set -CONFIG_TSC_SYNC_MFENCE=y -# CONFIG_NO_FIXED_XIP_ROM_SIZE is not set -CONFIG_LOGICAL_CPUS=y -CONFIG_SMM_TSEG=y -CONFIG_SMM_MODULE_HEAP_SIZE=0x4000 -# CONFIG_SMM_LAPIC_REMAP_MITIGATION is not set -# CONFIG_SERIALIZED_SMM_INITIALIZATION is not set -# CONFIG_X86_AMD_FIXED_MTRRS is not set -# CONFIG_PLATFORM_USES_FSP1_0 is not set -# CONFIG_MIRROR_PAYLOAD_TO_RAM_BEFORE_LOADING is not set -# CONFIG_SOC_SETS_MSRS is not set -CONFIG_CACHE_AS_RAM=y -# CONFIG_NO_CAR_GLOBAL_MIGRATION is not set -CONFIG_SMP=y -CONFIG_AP_SIPI_VECTOR=0xfffff000 -CONFIG_MMX=y -CONFIG_SSE=y -CONFIG_SUPPORT_CPU_UCODE_IN_CBFS=y -# CONFIG_USES_MICROCODE_HEADER_FILES is not set -CONFIG_CPU_MICROCODE_CBFS_GENERATE=y -# CONFIG_CPU_MICROCODE_CBFS_EXTERNAL_HEADER is not set -# CONFIG_CPU_MICROCODE_CBFS_NONE is not set -# CONFIG_CPU_MICROCODE_MULTIPLE_FILES is not set -CONFIG_CPU_UCODE_BINARIES="" - -# -# Northbridge -# -# CONFIG_NORTHBRIDGE_AMD_AGESA is not set -# CONFIG_NO_MMCONF_SUPPORT is not set -# CONFIG_AMD_NB_CIMX is not set -# CONFIG_NORTHBRIDGE_AMD_CIMX_RD890 is not set -# CONFIG_NORTHBRIDGE_AMD_PI is not set -CONFIG_NORTHBRIDGE_INTEL_COMMON_MRC_CACHE=y -CONFIG_MRC_CACHE_SIZE=0x10000 -CONFIG_NORTHBRIDGE_INTEL_SANDYBRIDGE=y -CONFIG_USE_NATIVE_RAMINIT=y -# CONFIG_NATIVE_RAMINIT_IGNORE_MAX_MEM_FUSES is not set -# CONFIG_NATIVE_RAMINIT_IGNORE_XMP_MAX_DIMMS is not set -CONFIG_SANDYBRIDGE_IVYBRIDGE_LVDS=y -CONFIG_IF_NATIVE_VGA_INIT=y -CONFIG_HPET_ADDRESS=0xfed00000 -CONFIG_MAX_PIRQ_LINKS=4 - -# -# Southbridge -# -# CONFIG_AMD_SB_CIMX is not set -# CONFIG_SOUTHBRIDGE_AMD_CIMX_SB800 is not set -# CONFIG_SOUTHBRIDGE_AMD_CIMX_SB900 is not set -CONFIG_SOUTHBRIDGE_INTEL_C216=y -CONFIG_SOUTH_BRIDGE_OPTIONS=y -CONFIG_LOCK_SPI_FLASH_NONE=y -# CONFIG_LOCK_SPI_FLASH_RO is not set -# CONFIG_LOCK_SPI_FLASH_NO_ACCESS is not set -CONFIG_SOUTHBRIDGE_INTEL_COMMON=y -CONFIG_SOUTHBRIDGE_INTEL_COMMON_GPIO=y -CONFIG_SOUTHBRIDGE_INTEL_COMMON_SMBUS=y -CONFIG_SOUTHBRIDGE_INTEL_COMMON_SPI=y -CONFIG_SOUTHBRIDGE_INTEL_COMMON_PIRQ_ACPI_GEN=y -CONFIG_SOUTHBRIDGE_INTEL_COMMON_RCBA_PIRQ=y -CONFIG_HAVE_INTEL_CHIPSET_LOCKDOWN=y -CONFIG_INTEL_CHIPSET_LOCKDOWN=y -# CONFIG_LOCK_MANAGEMENT_ENGINE is not set - -# -# Super I/O -# -# CONFIG_SUPERIO_NUVOTON_NCT6776_COM_A is not set - -# -# Embedded Controllers -# -CONFIG_EC_ACPI=y -CONFIG_EC_LENOVO_H8=y -CONFIG_H8_BEEP_ON_DEATH=y -CONFIG_H8_FLASH_LEDS_ON_DEATH=y -# CONFIG_H8_SUPPORT_BT_ON_WIFI is not set -CONFIG_EC_LENOVO_PMH7=y -CONFIG_HAVE_INTEL_FIRMWARE=y - -# -# Intel Firmware -# -# CONFIG_EM100 is not set CONFIG_CHECK_ME=y -# CONFIG_USE_ME_CLEANER is not set CONFIG_GBE_BIN_PATH="../../blobs/x220/gbe.bin" -# CONFIG_HAVE_EC_BIN is not set -# CONFIG_MAINBOARD_HAS_CHROMEOS is not set -# CONFIG_GOOGLE_SMBIOS_MAINBOARD_VERSION is not set -# CONFIG_UEFI_2_4_BINDING is not set -# CONFIG_UDK_2015_BINDING is not set -# CONFIG_USE_SIEMENS_HWILIB is not set -# CONFIG_ARCH_ARM is not set -# CONFIG_ARCH_BOOTBLOCK_ARM is not set -# CONFIG_ARCH_VERSTAGE_ARM is not set -# CONFIG_ARCH_ROMSTAGE_ARM is not set -# CONFIG_ARCH_RAMSTAGE_ARM is not set -# CONFIG_ARCH_BOOTBLOCK_ARMV4 is not set -# CONFIG_ARCH_VERSTAGE_ARMV4 is not set -# CONFIG_ARCH_ROMSTAGE_ARMV4 is not set -# CONFIG_ARCH_RAMSTAGE_ARMV4 is not set -# CONFIG_ARCH_BOOTBLOCK_ARMV7 is not set -# CONFIG_ARCH_VERSTAGE_ARMV7 is not set -# CONFIG_ARCH_ROMSTAGE_ARMV7 is not set -# CONFIG_ARCH_RAMSTAGE_ARMV7 is not set -# CONFIG_ARCH_BOOTBLOCK_ARMV7_M is not set -# CONFIG_ARCH_VERSTAGE_ARMV7_M is not set -# CONFIG_ARCH_BOOTBLOCK_ARMV7_R is not set -# CONFIG_ARCH_VERSTAGE_ARMV7_R is not set -# CONFIG_ARCH_ROMSTAGE_ARMV7_R is not set -# CONFIG_ARCH_RAMSTAGE_ARMV7_R is not set -# CONFIG_ARM_LPAE is not set -# CONFIG_ARCH_ARM64 is not set -# CONFIG_ARCH_BOOTBLOCK_ARM64 is not set -# CONFIG_ARCH_VERSTAGE_ARM64 is not set -# CONFIG_ARCH_ROMSTAGE_ARM64 is not set -# CONFIG_ARCH_RAMSTAGE_ARM64 is not set -# CONFIG_ARCH_BOOTBLOCK_ARMV8_64 is not set -# CONFIG_ARCH_VERSTAGE_ARMV8_64 is not set -# CONFIG_ARCH_ROMSTAGE_ARMV8_64 is not set -# CONFIG_ARCH_RAMSTAGE_ARMV8_64 is not set -# CONFIG_ARM64_A53_ERRATUM_843419 is not set -# CONFIG_ARCH_MIPS is not set -# CONFIG_ARCH_BOOTBLOCK_MIPS is not set -# CONFIG_ARCH_VERSTAGE_MIPS is not set -# CONFIG_ARCH_ROMSTAGE_MIPS is not set -# CONFIG_ARCH_RAMSTAGE_MIPS is not set -# CONFIG_ARCH_POWER8 is not set -# CONFIG_ARCH_BOOTBLOCK_POWER8 is not set -# CONFIG_ARCH_VERSTAGE_POWER8 is not set -# CONFIG_ARCH_ROMSTAGE_POWER8 is not set -# CONFIG_ARCH_RAMSTAGE_POWER8 is not set -# CONFIG_ARCH_RISCV is not set -# CONFIG_ARCH_BOOTBLOCK_RISCV is not set -# CONFIG_ARCH_VERSTAGE_RISCV is not set -# CONFIG_ARCH_ROMSTAGE_RISCV is not set -# CONFIG_ARCH_RAMSTAGE_RISCV is not set -CONFIG_ARCH_X86=y -CONFIG_ARCH_BOOTBLOCK_X86_32=y -CONFIG_ARCH_VERSTAGE_X86_32=y -CONFIG_ARCH_ROMSTAGE_X86_32=y -CONFIG_ARCH_RAMSTAGE_X86_32=y -# CONFIG_ARCH_BOOTBLOCK_X86_64 is not set -# CONFIG_ARCH_VERSTAGE_X86_64 is not set -# CONFIG_ARCH_ROMSTAGE_X86_64 is not set -# CONFIG_ARCH_RAMSTAGE_X86_64 is not set -# CONFIG_USE_MARCH_586 is not set -# CONFIG_AP_IN_SIPI_WAIT is not set -# CONFIG_SIPI_VECTOR_IN_ROM is not set -# CONFIG_ROMCC is not set -# CONFIG_CBMEM_TOP_BACKUP is not set -# CONFIG_LATE_CBMEM_INIT is not set -# CONFIG_EARLY_EBDA_INIT is not set -CONFIG_PC80_SYSTEM=y -# CONFIG_BOOTBLOCK_DEBUG_SPINLOOP is not set -# CONFIG_BOOTBLOCK_SAVE_BIST_AND_TIMESTAMP is not set -CONFIG_HAVE_CMOS_DEFAULT=y -CONFIG_CMOS_DEFAULT_FILE="src/mainboard/$(MAINBOARDDIR)/cmos.default" -CONFIG_IOAPIC_INTERRUPTS_ON_FSB=y -# CONFIG_IOAPIC_INTERRUPTS_ON_APIC_SERIAL_BUS is not set -# CONFIG_POSTCAR_STAGE is not set -# CONFIG_VERSTAGE_DEBUG_SPINLOOP is not set -# CONFIG_ROMSTAGE_DEBUG_SPINLOOP is not set -CONFIG_BOOTBLOCK_SIMPLE=y -# CONFIG_BOOTBLOCK_NORMAL is not set -CONFIG_BOOTBLOCK_SOURCE="bootblock_simple.c" - -# -# Devices -# -CONFIG_HAVE_VGA_TEXT_FRAMEBUFFER=y -CONFIG_HAVE_LINEAR_FRAMEBUFFER=y -CONFIG_MAINBOARD_HAS_NATIVE_VGA_INIT=y -# CONFIG_MAINBOARD_FORCE_NATIVE_VGA_INIT is not set -CONFIG_MAINBOARD_HAS_LIBGFXINIT=y -CONFIG_MAINBOARD_DO_NATIVE_VGA_INIT=y -# CONFIG_MAINBOARD_USE_LIBGFXINIT is not set -# CONFIG_VGA_ROM_RUN is not set -# CONFIG_NO_GFX_INIT is not set -# CONFIG_MULTIPLE_VGA_ADAPTERS is not set - -# -# Display -# -CONFIG_VGA_TEXT_FRAMEBUFFER=y -# CONFIG_GENERIC_LINEAR_FRAMEBUFFER is not set -# CONFIG_SMBUS_HAS_AUX_CHANNELS is not set -CONFIG_PCI=y -CONFIG_MMCONF_SUPPORT=y -# CONFIG_HYPERTRANSPORT_PLUGIN_SUPPORT is not set -CONFIG_PCIX_PLUGIN_SUPPORT=y -CONFIG_CARDBUS_PLUGIN_SUPPORT=y -# CONFIG_AZALIA_PLUGIN_SUPPORT is not set -CONFIG_PCIEXP_PLUGIN_SUPPORT=y -# CONFIG_EARLY_PCI_BRIDGE is not set -CONFIG_SUBSYSTEM_VENDOR_ID=0x0000 -CONFIG_SUBSYSTEM_DEVICE_ID=0x0000 -# CONFIG_INTEL_GMA_ADD_VBT_DATA_FILE is not set -# CONFIG_SOFTWARE_I2C is not set - -# -# Generic Drivers -# -# CONFIG_DRIVERS_AS3722_RTC is not set -# CONFIG_GIC is not set -# CONFIG_IPMI_KCS is not set -# CONFIG_DRIVERS_LENOVO_WACOM is not set -# CONFIG_RT8168_GET_MAC_FROM_VPD is not set -# CONFIG_RT8168_SET_LED_MODE is not set -CONFIG_SPI_FLASH=y -CONFIG_BOOT_DEVICE_SPI_FLASH_RW_NOMMAP=y -# CONFIG_BOOT_DEVICE_SPI_FLASH_RW_NOMMAP_EARLY is not set -# CONFIG_SPI_FLASH_SMM is not set -# CONFIG_SPI_FLASH_NO_FAST_READ is not set -CONFIG_SPI_FLASH_ADESTO=y -CONFIG_SPI_FLASH_AMIC=y -CONFIG_SPI_FLASH_ATMEL=y -CONFIG_SPI_FLASH_EON=y -CONFIG_SPI_FLASH_GIGADEVICE=y -CONFIG_SPI_FLASH_MACRONIX=y -CONFIG_SPI_FLASH_SPANSION=y -CONFIG_SPI_FLASH_SST=y -CONFIG_SPI_FLASH_STMICRO=y -CONFIG_SPI_FLASH_WINBOND=y -# CONFIG_SPI_FLASH_FAST_READ_DUAL_OUTPUT_3B is not set -# CONFIG_SPI_FLASH_HAS_VOLATILE_GROUP is not set -# CONFIG_HAVE_SPI_CONSOLE_SUPPORT is not set -# CONFIG_DRIVERS_UART is not set -CONFIG_NO_UART_ON_SUPERIO=y -# CONFIG_UART_OVERRIDE_INPUT_CLOCK_DIVIDER is not set -# CONFIG_UART_OVERRIDE_REFCLK is not set -# CONFIG_DRIVERS_UART_8250MEM is not set -# CONFIG_DRIVERS_UART_8250MEM_32 is not set -# CONFIG_HAVE_UART_SPECIAL is not set -# CONFIG_DRIVERS_UART_OXPCIE is not set -# CONFIG_DRIVERS_UART_PL011 is not set -# CONFIG_UART_USE_REFCLK_AS_INPUT_CLOCK is not set -CONFIG_HAVE_USBDEBUG=y -CONFIG_HAVE_USBDEBUG_OPTIONS=y -# CONFIG_DRIVERS_AMD_PI is not set -CONFIG_SMBIOS_PROVIDED_BY_MOBO=y -# CONFIG_DRIVERS_I2C_MAX98927 is not set -# CONFIG_DRIVERS_I2C_PCF8523 is not set -# CONFIG_DRIVERS_I2C_RT5663 is not set -# CONFIG_DRIVERS_I2C_RTD2132 is not set -# CONFIG_DRIVERS_I2C_RX6110SA is not set -# CONFIG_I2C_TPM is not set -# CONFIG_MAINBOARD_HAS_I2C_TPM_ATMEL is not set -# CONFIG_MAINBOARD_HAS_I2C_TPM_CR50 is not set -# CONFIG_INTEL_DDI is not set -CONFIG_INTEL_EDID=y -CONFIG_INTEL_INT15=y -CONFIG_INTEL_GMA_ACPI=y -# CONFIG_INTEL_GMA_SSC_ALTERNATE_REF is not set -CONFIG_GFX_GMA=y -CONFIG_GFX_GMA_CPU="Sandybridge" -CONFIG_GFX_GMA_CPU_VARIANT="Normal" -# CONFIG_GFX_GMA_INTERNAL_IS_EDP is not set -CONFIG_GFX_GMA_INTERNAL_IS_LVDS=y -CONFIG_GFX_GMA_INTERNAL_PORT="LVDS" -CONFIG_GFX_GMA_ANALOG_I2C_PORT="PCH_DAC" -# CONFIG_DRIVER_INTEL_I210 is not set -# CONFIG_DRIVERS_INTEL_MIPI_CAMERA is not set -CONFIG_DRIVERS_INTEL_WIFI=y -# CONFIG_USE_SAR is not set -# CONFIG_DRIVERS_LENOVO_HYBRID_GRAPHICS is not set -# CONFIG_DRIVER_MAXIM_MAX77686 is not set -# CONFIG_DRIVER_PARADE_PS8625 is not set -# CONFIG_DRIVER_PARADE_PS8640 is not set -CONFIG_DRIVERS_MC146818=y -CONFIG_MAINBOARD_HAS_LPC_TPM=y -CONFIG_LPC_TPM=y -CONFIG_TPM_TIS_BASE_ADDRESS=0xfed40000 -# CONFIG_TPM_INIT_FAILURE_IS_FATAL is not set -# CONFIG_SKIP_TPM_STARTUP_ON_NORMAL_BOOT is not set -# CONFIG_TPM_DEACTIVATE is not set -CONFIG_VGA=y -CONFIG_DRIVERS_RICOH_RCE822=y -# CONFIG_DRIVER_SIEMENS_NC_FPGA is not set -# CONFIG_NC_FPGA_NOTIFY_CB_READY is not set -# CONFIG_DRIVERS_SIL_3114 is not set -# CONFIG_MAINBOARD_HAS_SPI_TPM_CR50 is not set -# CONFIG_DRIVER_TI_TPS65090 is not set -# CONFIG_DRIVERS_TI_TPS65913 is not set -# CONFIG_DRIVERS_TI_TPS65913_RTC is not set -# CONFIG_DRIVER_XPOWERS_AXP209 is not set -# CONFIG_COMMONLIB_STORAGE is not set - -# -# Security -# - -# -# Verified Boot (vboot) -# -CONFIG_ACPI_SATA_GENERATOR=y -CONFIG_ACPI_INTEL_HARDWARE_SLEEP_VALUES=y -# CONFIG_ACPI_AMD_HARDWARE_SLEEP_VALUES is not set -# CONFIG_BOOT_DEVICE_NOT_SPI_FLASH is not set -CONFIG_BOOT_DEVICE_SPI_FLASH=y -CONFIG_BOOT_DEVICE_MEMORY_MAPPED=y -# CONFIG_BOOT_DEVICE_SUPPORTS_WRITES is not set -CONFIG_RTC=y -CONFIG_TPM=y -# CONFIG_MAINBOARD_HAS_TPM_CR50 is not set - -# -# Console -# -CONFIG_SQUELCH_EARLY_SMP=y -# CONFIG_SPKMODEM is not set -# CONFIG_CONSOLE_NE2K is not set CONFIG_CONSOLE_CBMEM_BUFFER_SIZE=0x80000 -# CONFIG_CONSOLE_CBMEM_DUMP_TO_UART is not set -# CONFIG_CONSOLE_SPI_FLASH is not set -# CONFIG_DEFAULT_CONSOLE_LOGLEVEL_8 is not set -# CONFIG_DEFAULT_CONSOLE_LOGLEVEL_7 is not set -# CONFIG_DEFAULT_CONSOLE_LOGLEVEL_6 is not set CONFIG_DEFAULT_CONSOLE_LOGLEVEL_5=y -# CONFIG_DEFAULT_CONSOLE_LOGLEVEL_4 is not set -# CONFIG_DEFAULT_CONSOLE_LOGLEVEL_3 is not set -# CONFIG_DEFAULT_CONSOLE_LOGLEVEL_2 is not set -# CONFIG_DEFAULT_CONSOLE_LOGLEVEL_1 is not set -# CONFIG_DEFAULT_CONSOLE_LOGLEVEL_0 is not set -# CONFIG_NO_EARLY_BOOTBLOCK_POSTCODES is not set -# CONFIG_HWBASE_DEBUG_CB is not set -CONFIG_HWBASE_DEBUG_NULL=y -CONFIG_HAVE_ACPI_RESUME=y -# CONFIG_ACPI_HUGE_LOWMEM_BACKUP is not set -CONFIG_RESUME_PATH_SAME_AS_BOOT=y -CONFIG_HAVE_HARD_RESET=y -# CONFIG_HAVE_ROMSTAGE_CONSOLE_SPINLOCK is not set -# CONFIG_HAVE_ROMSTAGE_NVRAM_CBFS_SPINLOCK is not set -# CONFIG_HAVE_ROMSTAGE_MICROCODE_CBFS_SPINLOCK is not set -CONFIG_HAVE_MONOTONIC_TIMER=y -# CONFIG_GENERIC_UDELAY is not set -# CONFIG_TIMER_QUEUE is not set -CONFIG_HAVE_OPTION_TABLE=y -# CONFIG_PIRQ_ROUTE is not set -CONFIG_HAVE_SMI_HANDLER=y -# CONFIG_PCI_IO_CFG_EXT is not set -CONFIG_IOAPIC=y -CONFIG_USE_WATCHDOG_ON_BOOT=y -# CONFIG_GFXUMA is not set -CONFIG_HAVE_ACPI_TABLES=y -CONFIG_COMMON_FADT=y -# CONFIG_ACPI_NHLT is not set - -# -# System tables -# -# CONFIG_GENERATE_MP_TABLE is not set -# CONFIG_GENERATE_PIRQ_TABLE is not set -CONFIG_GENERATE_SMBIOS_TABLES=y - -# -# Payload -# -# CONFIG_PAYLOAD_NONE is not set -# CONFIG_PAYLOAD_ELF is not set -# CONFIG_PAYLOAD_BAYOU is not set -# CONFIG_PAYLOAD_FILO is not set -# CONFIG_PAYLOAD_GRUB2 is not set -# CONFIG_PAYLOAD_SEABIOS is not set -# CONFIG_PAYLOAD_UBOOT is not set CONFIG_PAYLOAD_LINUX=y -# CONFIG_PAYLOAD_TIANOCORE is not set CONFIG_PAYLOAD_FILE="../../build/x220/bzImage" -CONFIG_PAYLOAD_OPTIONS="" -# CONFIG_PXE is not set CONFIG_LINUX_COMMAND_LINE="quiet" CONFIG_LINUX_INITRD="../../build/x220/initrd.cpio.xz" -# CONFIG_PAYLOAD_IS_FLAT_BINARY is not set - -# -# Secondary Payloads -# -# CONFIG_COREINFO_SECONDARY_PAYLOAD is not set -# CONFIG_MEMTEST_SECONDARY_PAYLOAD is not set -# CONFIG_NVRAMCUI_SECONDARY_PAYLOAD is not set -# CONFIG_TINT_SECONDARY_PAYLOAD is not set - -# -# Debugging -# -# CONFIG_FATAL_ASSERTS is not set -# CONFIG_DEBUG_CBFS is not set -CONFIG_HAVE_DEBUG_RAM_SETUP=y -# CONFIG_DEBUG_RAM_SETUP is not set -# CONFIG_HAVE_DEBUG_CAR is not set -CONFIG_HAVE_DEBUG_SMBUS=y -# CONFIG_DEBUG_SMBUS is not set -# CONFIG_DEBUG_SMI is not set CONFIG_DEBUG_SMM_RELOCATION=y -# CONFIG_DEBUG_MALLOC is not set -# CONFIG_DEBUG_ACPI is not set -# CONFIG_DEBUG_TPM is not set -# CONFIG_DEBUG_SPI_FLASH is not set -# CONFIG_TRACE is not set -# CONFIG_DEBUG_BOOT_STATE is not set -# CONFIG_DEBUG_ADA_CODE is not set -# CONFIG_ENABLE_APIC_EXT_ID is not set -CONFIG_WARNINGS_ARE_ERRORS=y -# CONFIG_POWER_BUTTON_DEFAULT_ENABLE is not set -# CONFIG_POWER_BUTTON_DEFAULT_DISABLE is not set -# CONFIG_POWER_BUTTON_FORCE_ENABLE is not set -# CONFIG_POWER_BUTTON_FORCE_DISABLE is not set -# CONFIG_POWER_BUTTON_IS_OPTIONAL is not set -# CONFIG_REG_SCRIPT is not set -# CONFIG_CREATE_BOARD_CHECKLIST is not set -# CONFIG_MAKE_CHECKLIST_PUBLIC is not set -# CONFIG_NO_XIP_EARLY_STAGES is not set -CONFIG_EARLY_CBMEM_INIT=y -# CONFIG_EARLY_CBMEM_LIST is not set -CONFIG_RELOCATABLE_MODULES=y -CONFIG_BOOTBLOCK_CUSTOM=y diff --git a/config/coreboot-x230-flash.config b/config/coreboot-x230-flash.config index f15c29e5..66f3a53c 100644 --- a/config/coreboot-x230-flash.config +++ b/config/coreboot-x230-flash.config @@ -1,705 +1,18 @@ -# -# Automatically generated file; DO NOT EDIT. -# coreboot configuration -# - -# -# General setup -# -CONFIG_COREBOOT_BUILD=y CONFIG_LOCALVERSION="heads" -CONFIG_CBFS_PREFIX="fallback" -CONFIG_COMPILER_GCC=y -# CONFIG_COMPILER_LLVM_CLANG is not set -# CONFIG_ANY_TOOLCHAIN is not set -# CONFIG_CCACHE is not set -# CONFIG_FMD_GENPARSER is not set -# CONFIG_UTIL_GENPARSER is not set -# CONFIG_USE_OPTION_TABLE is not set -CONFIG_COMPRESS_RAMSTAGE=y # CONFIG_INCLUDE_CONFIG_FILE is not set # CONFIG_COLLECT_TIMESTAMPS is not set CONFIG_USE_BLOBS=y -# CONFIG_COVERAGE is not set -# CONFIG_UBSAN is not set -CONFIG_RELOCATABLE_RAMSTAGE=y -# CONFIG_UPDATE_IMAGE is not set -# CONFIG_BOOTSPLASH_IMAGE is not set CONFIG_MEASURED_BOOT=y - -# -# Mainboard -# - -# -# Important: Run 'make distclean' before switching boards -# -# CONFIG_VENDOR_A_TREND is not set -# CONFIG_VENDOR_AAEON is not set -# CONFIG_VENDOR_ABIT is not set -# CONFIG_VENDOR_ADI is not set -# CONFIG_VENDOR_ADLINK is not set -# CONFIG_VENDOR_ADVANSUS is not set -# CONFIG_VENDOR_AMD is not set -# CONFIG_VENDOR_AOPEN is not set -# CONFIG_VENDOR_APPLE is not set -# CONFIG_VENDOR_ARTECGROUP is not set -# CONFIG_VENDOR_ASROCK is not set -# CONFIG_VENDOR_ASUS is not set -# CONFIG_VENDOR_AVALUE is not set -# CONFIG_VENDOR_AZZA is not set -# CONFIG_VENDOR_BACHMANN is not set -# CONFIG_VENDOR_BAP is not set -# CONFIG_VENDOR_BCOM is not set -# CONFIG_VENDOR_BIOSTAR is not set -# CONFIG_VENDOR_BROADCOM is not set -# CONFIG_VENDOR_COMPAQ is not set -# CONFIG_VENDOR_COMPULAB is not set -# CONFIG_VENDOR_CUBIETECH is not set -# CONFIG_VENDOR_DIGITALLOGIC is not set -# CONFIG_VENDOR_DMP is not set -# CONFIG_VENDOR_ECS is not set -# CONFIG_VENDOR_ELMEX is not set -# CONFIG_VENDOR_EMULATION is not set -# CONFIG_VENDOR_ESD is not set -# CONFIG_VENDOR_FOXCONN is not set -# CONFIG_VENDOR_GETAC is not set -# CONFIG_VENDOR_GIGABYTE is not set -# CONFIG_VENDOR_GIZMOSPHERE is not set -# CONFIG_VENDOR_GOOGLE is not set -# CONFIG_VENDOR_HP is not set -# CONFIG_VENDOR_IBASE is not set -# CONFIG_VENDOR_IEI is not set -# CONFIG_VENDOR_INTEL is not set -# CONFIG_VENDOR_IWAVE is not set -# CONFIG_VENDOR_IWILL is not set -# CONFIG_VENDOR_JETWAY is not set -# CONFIG_VENDOR_KONTRON is not set -# CONFIG_VENDOR_LANNER is not set CONFIG_VENDOR_LENOVO=y -# CONFIG_VENDOR_LINUTOP is not set -# CONFIG_VENDOR_LIPPERT is not set -# CONFIG_VENDOR_LOWRISC is not set -# CONFIG_VENDOR_MITAC is not set -# CONFIG_VENDOR_MSI is not set -# CONFIG_VENDOR_NEC is not set -# CONFIG_VENDOR_NOKIA is not set -# CONFIG_VENDOR_NVIDIA is not set -# CONFIG_VENDOR_PACKARDBELL is not set -# CONFIG_VENDOR_PCENGINES is not set -# CONFIG_VENDOR_PURISM is not set -# CONFIG_VENDOR_RCA is not set -# CONFIG_VENDOR_RODA is not set -# CONFIG_VENDOR_SAMSUNG is not set -# CONFIG_VENDOR_SAPPHIRE is not set -# CONFIG_VENDOR_SIEMENS is not set -# CONFIG_VENDOR_SOYO is not set -# CONFIG_VENDOR_SUNW is not set -# CONFIG_VENDOR_SUPERMICRO is not set -# CONFIG_VENDOR_TECHNEXION is not set -# CONFIG_VENDOR_THOMSON is not set -# CONFIG_VENDOR_TI is not set -# CONFIG_VENDOR_TRAVERSE is not set -# CONFIG_VENDOR_TYAN is not set -# CONFIG_VENDOR_VIA is not set -# CONFIG_VENDOR_WINENT is not set -# CONFIG_VENDOR_WINNET is not set -# CONFIG_VENDOR_WYSE is not set -CONFIG_BOARD_SPECIFIC_OPTIONS=y -CONFIG_MAINBOARD_DIR="lenovo/x230" -CONFIG_MAINBOARD_PART_NUMBER="ThinkPad X230" -CONFIG_MAINBOARD_VENDOR="LENOVO" -CONFIG_MAX_CPUS=8 -CONFIG_CACHE_ROM_SIZE_OVERRIDE=0x0 CONFIG_CBFS_SIZE=0x400000 -CONFIG_UART_FOR_CONSOLE=0 -CONFIG_VGA_BIOS_ID="8086,0166" -# CONFIG_ONBOARD_VGA_IS_PRIMARY is not set -CONFIG_DIMM_SPD_SIZE=256 -# CONFIG_VGA_BIOS is not set -CONFIG_DCACHE_RAM_BASE=0xfefe0000 -CONFIG_DCACHE_RAM_SIZE=0x20000 -CONFIG_VGA_BIOS_FILE="pci8086,0166.rom" -CONFIG_MAINBOARD_PCI_SUBSYSTEM_VENDOR_ID=0x17aa -CONFIG_MAINBOARD_PCI_SUBSYSTEM_DEVICE_ID=0x21fa -# CONFIG_HAVE_IFD_BIN is not set -# CONFIG_HAVE_ME_BIN is not set -CONFIG_DRAM_RESET_GATE_GPIO=10 -CONFIG_MMCONF_BASE_ADDRESS=0xf8000000 -CONFIG_POST_IO=y -CONFIG_DEVICETREE="devicetree.cb" -CONFIG_MAX_REBOOT_CNT=3 -CONFIG_USBDEBUG_HCD_INDEX=2 -CONFIG_ID_SECTION_OFFSET=0x80 # CONFIG_POST_DEVICE is not set -CONFIG_IFD_BIOS_SECTION="" -CONFIG_IFD_ME_SECTION="" -# CONFIG_VBOOT is not set -CONFIG_TPM_PIRQ=0x0 -CONFIG_BOOT_DEVICE_SPI_FLASH_BUS=0 -CONFIG_FMDFILE="" -CONFIG_PRERAM_CBMEM_CONSOLE_SIZE=0xc00 -CONFIG_TTYS0_LCS=3 CONFIG_DRIVERS_UART_8250IO=y -CONFIG_IFD_GBE_SECTION="" -# CONFIG_BOARD_LENOVO_G505S is not set -# CONFIG_BOARD_LENOVO_L520 is not set -# CONFIG_BOARD_LENOVO_R400 is not set -# CONFIG_BOARD_LENOVO_S230U is not set -# CONFIG_BOARD_LENOVO_T400 is not set -# CONFIG_BOARD_LENOVO_T420 is not set -# CONFIG_BOARD_LENOVO_T420S is not set -# CONFIG_BOARD_LENOVO_THINKPAD_T430 is not set -# CONFIG_BOARD_LENOVO_T430S is not set -# CONFIG_BOARD_LENOVO_T500 is not set -# CONFIG_BOARD_LENOVO_T520 is not set -# CONFIG_BOARD_LENOVO_T530 is not set -# CONFIG_BOARD_LENOVO_T60 is not set -# CONFIG_BOARD_LENOVO_X131E is not set -# CONFIG_BOARD_LENOVO_X1_CARBON_GEN1 is not set -# CONFIG_BOARD_LENOVO_X200 is not set -# CONFIG_BOARD_LENOVO_X201 is not set -# CONFIG_BOARD_LENOVO_X220 is not set -# CONFIG_BOARD_LENOVO_X220I is not set CONFIG_BOARD_LENOVO_X230=y -# CONFIG_BOARD_LENOVO_X60 is not set -# CONFIG_BOARD_LENOVO_Z61T is not set -CONFIG_CPU_ADDR_BITS=36 -CONFIG_DEFAULT_CONSOLE_LOGLEVEL=8 -# CONFIG_USBDEBUG is not set CONFIG_DRIVERS_PS2_KEYBOARD=y -# CONFIG_PCIEXP_L1_SUB_STATE is not set -# CONFIG_NO_POST is not set -CONFIG_BOARD_ROMSIZE_KB_12288=y -# CONFIG_COREBOOT_ROMSIZE_KB_64 is not set -# CONFIG_COREBOOT_ROMSIZE_KB_128 is not set -# CONFIG_COREBOOT_ROMSIZE_KB_256 is not set -# CONFIG_COREBOOT_ROMSIZE_KB_512 is not set -# CONFIG_COREBOOT_ROMSIZE_KB_1024 is not set -# CONFIG_COREBOOT_ROMSIZE_KB_2048 is not set -# CONFIG_COREBOOT_ROMSIZE_KB_4096 is not set -# CONFIG_COREBOOT_ROMSIZE_KB_8192 is not set -# CONFIG_COREBOOT_ROMSIZE_KB_10240 is not set -CONFIG_COREBOOT_ROMSIZE_KB_12288=y -# CONFIG_COREBOOT_ROMSIZE_KB_16384 is not set -# CONFIG_COREBOOT_ROMSIZE_KB_32768 is not set -# CONFIG_COREBOOT_ROMSIZE_KB_65536 is not set -CONFIG_COREBOOT_ROMSIZE_KB=12288 -CONFIG_ROM_SIZE=0xc00000 -# CONFIG_MAINBOARD_HAS_TPM2 is not set -CONFIG_SYSTEM_TYPE_LAPTOP=y -# CONFIG_CBFS_AUTOGEN_ATTRIBUTES is not set - -# -# Chipset -# - -# -# SoC -# -CONFIG_CPU_SPECIFIC_OPTIONS=y -CONFIG_RAMTOP=0x200000 -CONFIG_HEAP_SIZE=0x4000 -CONFIG_RAMBASE=0x100000 -CONFIG_EHCI_BAR=0xfef00000 -CONFIG_SERIRQ_CONTINUOUS_MODE=y -CONFIG_SMM_TSEG_SIZE=0x800000 -CONFIG_ACPI_CPU_STRING="\\_PR.CP%02d" -# CONFIG_SOC_BROADCOM_CYGNUS is not set -CONFIG_BOOTBLOCK_CPU_INIT="cpu/intel/model_206ax/bootblock.c" -# CONFIG_SOC_INTEL_GLK is not set -CONFIG_C_ENV_BOOTBLOCK_SIZE=0x10000 -CONFIG_X86_TOP4G_BOOTMEDIA_MAP=y -CONFIG_ROMSTAGE_ADDR=0x2000000 -CONFIG_VERSTAGE_ADDR=0x2000000 -CONFIG_SPI_FLASH_INCLUDE_ALL_DRIVERS=y -CONFIG_DCACHE_RAM_MRC_VAR_SIZE=0x0 -CONFIG_BUILD_WITH_FAKE_IFD=y -CONFIG_PCIEXP_ASPM=y -CONFIG_PCIEXP_COMMON_CLOCK=y -# CONFIG_PCIEXP_CLK_PM is not set -CONFIG_BOOTBLOCK_NORTHBRIDGE_INIT="northbridge/intel/sandybridge/bootblock.c" -CONFIG_BOOTBLOCK_SOUTHBRIDGE_INIT="southbridge/intel/bd82x6x/bootblock.c" -CONFIG_CACHE_MRC_SIZE_KB=512 -CONFIG_TTYS0_BASE=0x3f8 -CONFIG_STACK_SIZE=0x1000 -CONFIG_CONSOLE_CBMEM=y CONFIG_UART_PCI_ADDR=0 -CONFIG_HPET_MIN_TICKS=0x80 -# CONFIG_SOC_INTEL_KABYLAKE is not set -# CONFIG_SOC_LOWRISC_LOWRISC is not set -# CONFIG_SOC_MARVELL_MVMAP2315 is not set -CONFIG_TTYS0_BAUD=115200 -# CONFIG_SOC_MEDIATEK_MT8173 is not set -# CONFIG_SOC_NVIDIA_TEGRA124 is not set -# CONFIG_SOC_NVIDIA_TEGRA210 is not set -# CONFIG_SOC_QC_IPQ40XX is not set -# CONFIG_SOC_QC_IPQ806X is not set -# CONFIG_SOC_ROCKCHIP_RK3288 is not set -# CONFIG_SOC_ROCKCHIP_RK3399 is not set -# CONFIG_CPU_SAMSUNG_EXYNOS5250 is not set -# CONFIG_CPU_SAMSUNG_EXYNOS5420 is not set -# CONFIG_SOC_UCB_RISCV is not set - -# -# CPU -# -# CONFIG_CPU_ALLWINNER_A10 is not set -CONFIG_SOCKET_SPECIFIC_OPTIONS=y -CONFIG_XIP_ROM_SIZE=0x20000 -CONFIG_NUM_IPI_STARTS=2 -# CONFIG_CPU_AMD_AGESA is not set -# CONFIG_CPU_AMD_PI is not set -# CONFIG_CPU_ARMLTD_CORTEX_A9 is not set -CONFIG_CPU_INTEL_MODEL_306AX=y -CONFIG_SSE2=y -CONFIG_CPU_INTEL_SOCKET_RPGA989=y -# CONFIG_CPU_INTEL_FIRMWARE_INTERFACE_TABLE is not set -# CONFIG_CPU_INTEL_TURBO_NOT_PACKAGE_SCOPED is not set -CONFIG_CPU_INTEL_COMMON=y -CONFIG_ENABLE_VMX=y -CONFIG_SET_VMX_LOCK_BIT=y -# CONFIG_CPU_TI_AM335X is not set -# CONFIG_PARALLEL_CPU_INIT is not set -# CONFIG_PARALLEL_MP is not set -# CONFIG_UDELAY_IO is not set -# CONFIG_UDELAY_LAPIC is not set -CONFIG_UDELAY_TSC=y -CONFIG_TSC_CONSTANT_RATE=y -CONFIG_TSC_MONOTONIC_TIMER=y -# CONFIG_UDELAY_TIMER2 is not set -# CONFIG_TSC_SYNC_LFENCE is not set -CONFIG_TSC_SYNC_MFENCE=y -# CONFIG_NO_FIXED_XIP_ROM_SIZE is not set -CONFIG_LOGICAL_CPUS=y -CONFIG_SMM_TSEG=y -CONFIG_SMM_MODULE_HEAP_SIZE=0x4000 -# CONFIG_SMM_LAPIC_REMAP_MITIGATION is not set -# CONFIG_SERIALIZED_SMM_INITIALIZATION is not set -# CONFIG_X86_AMD_FIXED_MTRRS is not set -# CONFIG_PLATFORM_USES_FSP1_0 is not set -# CONFIG_MIRROR_PAYLOAD_TO_RAM_BEFORE_LOADING is not set -# CONFIG_SOC_SETS_MSRS is not set -CONFIG_CACHE_AS_RAM=y -# CONFIG_NO_CAR_GLOBAL_MIGRATION is not set -CONFIG_SMP=y -CONFIG_AP_SIPI_VECTOR=0xfffff000 -CONFIG_MMX=y -CONFIG_SSE=y -CONFIG_SUPPORT_CPU_UCODE_IN_CBFS=y -# CONFIG_USES_MICROCODE_HEADER_FILES is not set -CONFIG_CPU_MICROCODE_CBFS_GENERATE=y -# CONFIG_CPU_MICROCODE_CBFS_EXTERNAL_HEADER is not set -# CONFIG_CPU_MICROCODE_CBFS_NONE is not set -# CONFIG_CPU_MICROCODE_MULTIPLE_FILES is not set -CONFIG_CPU_UCODE_BINARIES="" - -# -# Northbridge -# -# CONFIG_NORTHBRIDGE_AMD_AGESA is not set -# CONFIG_NO_MMCONF_SUPPORT is not set -# CONFIG_AMD_NB_CIMX is not set -# CONFIG_NORTHBRIDGE_AMD_CIMX_RD890 is not set -# CONFIG_NORTHBRIDGE_AMD_PI is not set -CONFIG_NORTHBRIDGE_INTEL_COMMON_MRC_CACHE=y -CONFIG_MRC_CACHE_SIZE=0x10000 -CONFIG_NORTHBRIDGE_INTEL_IVYBRIDGE=y -CONFIG_USE_NATIVE_RAMINIT=y -# CONFIG_NATIVE_RAMINIT_IGNORE_MAX_MEM_FUSES is not set -# CONFIG_NATIVE_RAMINIT_IGNORE_XMP_MAX_DIMMS is not set -CONFIG_SANDYBRIDGE_IVYBRIDGE_LVDS=y -CONFIG_IF_NATIVE_VGA_INIT=y -CONFIG_HPET_ADDRESS=0xfed00000 -CONFIG_MAX_PIRQ_LINKS=4 - -# -# Southbridge -# -# CONFIG_AMD_SB_CIMX is not set -# CONFIG_SOUTHBRIDGE_AMD_CIMX_SB800 is not set -# CONFIG_SOUTHBRIDGE_AMD_CIMX_SB900 is not set -CONFIG_SOUTHBRIDGE_INTEL_C216=y -CONFIG_SOUTH_BRIDGE_OPTIONS=y -CONFIG_LOCK_SPI_FLASH_NONE=y -# CONFIG_LOCK_SPI_FLASH_RO is not set -# CONFIG_LOCK_SPI_FLASH_NO_ACCESS is not set -CONFIG_SOUTHBRIDGE_INTEL_COMMON=y -CONFIG_SOUTHBRIDGE_INTEL_COMMON_GPIO=y -CONFIG_SOUTHBRIDGE_INTEL_COMMON_SMBUS=y -CONFIG_SOUTHBRIDGE_INTEL_COMMON_SPI=y -CONFIG_SOUTHBRIDGE_INTEL_COMMON_PIRQ_ACPI_GEN=y -CONFIG_SOUTHBRIDGE_INTEL_COMMON_RCBA_PIRQ=y -CONFIG_HAVE_INTEL_CHIPSET_LOCKDOWN=y -CONFIG_INTEL_CHIPSET_LOCKDOWN=y -# CONFIG_LOCK_MANAGEMENT_ENGINE is not set - -# -# Super I/O -# -# CONFIG_SUPERIO_NUVOTON_NCT6776_COM_A is not set - -# -# Embedded Controllers -# -CONFIG_EC_ACPI=y -CONFIG_EC_LENOVO_H8=y -CONFIG_H8_BEEP_ON_DEATH=y -CONFIG_H8_FLASH_LEDS_ON_DEATH=y -# CONFIG_H8_SUPPORT_BT_ON_WIFI is not set -CONFIG_EC_LENOVO_PMH7=y -CONFIG_HAVE_INTEL_FIRMWARE=y - -# -# Intel Firmware -# -CONFIG_IFD_PLATFORM_SECTION="" -# CONFIG_MAINBOARD_HAS_CHROMEOS is not set -# CONFIG_GOOGLE_SMBIOS_MAINBOARD_VERSION is not set -# CONFIG_UEFI_2_4_BINDING is not set -# CONFIG_UDK_2015_BINDING is not set -# CONFIG_USE_SIEMENS_HWILIB is not set -# CONFIG_ARCH_ARM is not set -# CONFIG_ARCH_BOOTBLOCK_ARM is not set -# CONFIG_ARCH_VERSTAGE_ARM is not set -# CONFIG_ARCH_ROMSTAGE_ARM is not set -# CONFIG_ARCH_RAMSTAGE_ARM is not set -# CONFIG_ARCH_BOOTBLOCK_ARMV4 is not set -# CONFIG_ARCH_VERSTAGE_ARMV4 is not set -# CONFIG_ARCH_ROMSTAGE_ARMV4 is not set -# CONFIG_ARCH_RAMSTAGE_ARMV4 is not set -# CONFIG_ARCH_BOOTBLOCK_ARMV7 is not set -# CONFIG_ARCH_VERSTAGE_ARMV7 is not set -# CONFIG_ARCH_ROMSTAGE_ARMV7 is not set -# CONFIG_ARCH_RAMSTAGE_ARMV7 is not set -# CONFIG_ARCH_BOOTBLOCK_ARMV7_M is not set -# CONFIG_ARCH_VERSTAGE_ARMV7_M is not set -# CONFIG_ARCH_BOOTBLOCK_ARMV7_R is not set -# CONFIG_ARCH_VERSTAGE_ARMV7_R is not set -# CONFIG_ARCH_ROMSTAGE_ARMV7_R is not set -# CONFIG_ARCH_RAMSTAGE_ARMV7_R is not set -# CONFIG_ARM_LPAE is not set -# CONFIG_ARCH_ARM64 is not set -# CONFIG_ARCH_BOOTBLOCK_ARM64 is not set -# CONFIG_ARCH_VERSTAGE_ARM64 is not set -# CONFIG_ARCH_ROMSTAGE_ARM64 is not set -# CONFIG_ARCH_RAMSTAGE_ARM64 is not set -# CONFIG_ARCH_BOOTBLOCK_ARMV8_64 is not set -# CONFIG_ARCH_VERSTAGE_ARMV8_64 is not set -# CONFIG_ARCH_ROMSTAGE_ARMV8_64 is not set -# CONFIG_ARCH_RAMSTAGE_ARMV8_64 is not set -# CONFIG_ARM64_A53_ERRATUM_843419 is not set -# CONFIG_ARCH_MIPS is not set -# CONFIG_ARCH_BOOTBLOCK_MIPS is not set -# CONFIG_ARCH_VERSTAGE_MIPS is not set -# CONFIG_ARCH_ROMSTAGE_MIPS is not set -# CONFIG_ARCH_RAMSTAGE_MIPS is not set -# CONFIG_ARCH_POWER8 is not set -# CONFIG_ARCH_BOOTBLOCK_POWER8 is not set -# CONFIG_ARCH_VERSTAGE_POWER8 is not set -# CONFIG_ARCH_ROMSTAGE_POWER8 is not set -# CONFIG_ARCH_RAMSTAGE_POWER8 is not set -# CONFIG_ARCH_RISCV is not set -# CONFIG_ARCH_BOOTBLOCK_RISCV is not set -# CONFIG_ARCH_VERSTAGE_RISCV is not set -# CONFIG_ARCH_ROMSTAGE_RISCV is not set -# CONFIG_ARCH_RAMSTAGE_RISCV is not set -CONFIG_ARCH_X86=y -CONFIG_ARCH_BOOTBLOCK_X86_32=y -CONFIG_ARCH_VERSTAGE_X86_32=y -CONFIG_ARCH_ROMSTAGE_X86_32=y -CONFIG_ARCH_RAMSTAGE_X86_32=y -# CONFIG_ARCH_BOOTBLOCK_X86_64 is not set -# CONFIG_ARCH_VERSTAGE_X86_64 is not set -# CONFIG_ARCH_ROMSTAGE_X86_64 is not set -# CONFIG_ARCH_RAMSTAGE_X86_64 is not set -# CONFIG_USE_MARCH_586 is not set -# CONFIG_AP_IN_SIPI_WAIT is not set -# CONFIG_SIPI_VECTOR_IN_ROM is not set -# CONFIG_ROMCC is not set -# CONFIG_CBMEM_TOP_BACKUP is not set -# CONFIG_LATE_CBMEM_INIT is not set -# CONFIG_EARLY_EBDA_INIT is not set -CONFIG_PC80_SYSTEM=y -# CONFIG_BOOTBLOCK_DEBUG_SPINLOOP is not set -# CONFIG_BOOTBLOCK_SAVE_BIST_AND_TIMESTAMP is not set -CONFIG_HAVE_CMOS_DEFAULT=y -CONFIG_CMOS_DEFAULT_FILE="src/mainboard/$(MAINBOARDDIR)/cmos.default" -CONFIG_IOAPIC_INTERRUPTS_ON_FSB=y -# CONFIG_IOAPIC_INTERRUPTS_ON_APIC_SERIAL_BUS is not set -# CONFIG_POSTCAR_STAGE is not set -# CONFIG_VERSTAGE_DEBUG_SPINLOOP is not set -# CONFIG_ROMSTAGE_DEBUG_SPINLOOP is not set -CONFIG_BOOTBLOCK_SIMPLE=y -# CONFIG_BOOTBLOCK_NORMAL is not set -CONFIG_BOOTBLOCK_SOURCE="bootblock_simple.c" - -# -# Devices -# -CONFIG_HAVE_VGA_TEXT_FRAMEBUFFER=y -CONFIG_HAVE_LINEAR_FRAMEBUFFER=y -CONFIG_MAINBOARD_HAS_NATIVE_VGA_INIT=y -# CONFIG_MAINBOARD_FORCE_NATIVE_VGA_INIT is not set -CONFIG_MAINBOARD_HAS_LIBGFXINIT=y -CONFIG_MAINBOARD_DO_NATIVE_VGA_INIT=y -# CONFIG_MAINBOARD_USE_LIBGFXINIT is not set -# CONFIG_VGA_ROM_RUN is not set -# CONFIG_NO_GFX_INIT is not set -# CONFIG_MULTIPLE_VGA_ADAPTERS is not set - -# -# Display -# -CONFIG_VGA_TEXT_FRAMEBUFFER=y -# CONFIG_GENERIC_LINEAR_FRAMEBUFFER is not set -# CONFIG_SMBUS_HAS_AUX_CHANNELS is not set -CONFIG_PCI=y -CONFIG_MMCONF_SUPPORT=y -# CONFIG_HYPERTRANSPORT_PLUGIN_SUPPORT is not set -CONFIG_PCIX_PLUGIN_SUPPORT=y -CONFIG_CARDBUS_PLUGIN_SUPPORT=y -# CONFIG_AZALIA_PLUGIN_SUPPORT is not set -CONFIG_PCIEXP_PLUGIN_SUPPORT=y -# CONFIG_EARLY_PCI_BRIDGE is not set -CONFIG_SUBSYSTEM_VENDOR_ID=0x0000 -CONFIG_SUBSYSTEM_DEVICE_ID=0x0000 -# CONFIG_INTEL_GMA_ADD_VBT_DATA_FILE is not set -# CONFIG_SOFTWARE_I2C is not set - -# -# Generic Drivers -# -# CONFIG_DRIVERS_AS3722_RTC is not set -# CONFIG_GIC is not set -# CONFIG_IPMI_KCS is not set -# CONFIG_DRIVERS_LENOVO_WACOM is not set -# CONFIG_RT8168_GET_MAC_FROM_VPD is not set -# CONFIG_RT8168_SET_LED_MODE is not set -CONFIG_SPI_FLASH=y -CONFIG_BOOT_DEVICE_SPI_FLASH_RW_NOMMAP=y -# CONFIG_BOOT_DEVICE_SPI_FLASH_RW_NOMMAP_EARLY is not set -# CONFIG_SPI_FLASH_SMM is not set -# CONFIG_SPI_FLASH_NO_FAST_READ is not set -CONFIG_SPI_FLASH_ADESTO=y -CONFIG_SPI_FLASH_AMIC=y -CONFIG_SPI_FLASH_ATMEL=y -CONFIG_SPI_FLASH_EON=y -CONFIG_SPI_FLASH_GIGADEVICE=y -CONFIG_SPI_FLASH_MACRONIX=y -CONFIG_SPI_FLASH_SPANSION=y -CONFIG_SPI_FLASH_SST=y -CONFIG_SPI_FLASH_STMICRO=y -CONFIG_SPI_FLASH_WINBOND=y -# CONFIG_SPI_FLASH_FAST_READ_DUAL_OUTPUT_3B is not set -# CONFIG_SPI_FLASH_HAS_VOLATILE_GROUP is not set -# CONFIG_HAVE_SPI_CONSOLE_SUPPORT is not set -CONFIG_DRIVERS_UART=y -# CONFIG_DRIVERS_UART_8250IO_SKIP_INIT is not set -CONFIG_NO_UART_ON_SUPERIO=y -# CONFIG_UART_OVERRIDE_INPUT_CLOCK_DIVIDER is not set -# CONFIG_UART_OVERRIDE_REFCLK is not set -# CONFIG_DRIVERS_UART_8250MEM is not set -# CONFIG_DRIVERS_UART_8250MEM_32 is not set -# CONFIG_HAVE_UART_SPECIAL is not set -# CONFIG_DRIVERS_UART_OXPCIE is not set -# CONFIG_DRIVERS_UART_PL011 is not set -# CONFIG_UART_USE_REFCLK_AS_INPUT_CLOCK is not set -CONFIG_HAVE_USBDEBUG=y -CONFIG_HAVE_USBDEBUG_OPTIONS=y -# CONFIG_DRIVERS_AMD_PI is not set -CONFIG_SMBIOS_PROVIDED_BY_MOBO=y -# CONFIG_DRIVERS_I2C_MAX98927 is not set -# CONFIG_DRIVERS_I2C_PCF8523 is not set -# CONFIG_DRIVERS_I2C_RT5663 is not set -# CONFIG_DRIVERS_I2C_RTD2132 is not set -# CONFIG_DRIVERS_I2C_RX6110SA is not set -# CONFIG_I2C_TPM is not set -# CONFIG_MAINBOARD_HAS_I2C_TPM_ATMEL is not set -# CONFIG_MAINBOARD_HAS_I2C_TPM_CR50 is not set -# CONFIG_INTEL_DDI is not set -CONFIG_INTEL_EDID=y -CONFIG_INTEL_INT15=y -CONFIG_INTEL_GMA_ACPI=y -# CONFIG_INTEL_GMA_SSC_ALTERNATE_REF is not set -CONFIG_GFX_GMA=y -CONFIG_GFX_GMA_CPU="Ivybridge" -CONFIG_GFX_GMA_CPU_VARIANT="Normal" -# CONFIG_GFX_GMA_INTERNAL_IS_EDP is not set -CONFIG_GFX_GMA_INTERNAL_IS_LVDS=y -CONFIG_GFX_GMA_INTERNAL_PORT="LVDS" -CONFIG_GFX_GMA_ANALOG_I2C_PORT="PCH_DAC" -# CONFIG_DRIVER_INTEL_I210 is not set -# CONFIG_DRIVERS_INTEL_MIPI_CAMERA is not set -CONFIG_DRIVERS_INTEL_WIFI=y -# CONFIG_USE_SAR is not set -# CONFIG_DRIVERS_LENOVO_HYBRID_GRAPHICS is not set -# CONFIG_DRIVER_MAXIM_MAX77686 is not set -# CONFIG_DRIVER_PARADE_PS8625 is not set -# CONFIG_DRIVER_PARADE_PS8640 is not set -CONFIG_DRIVERS_MC146818=y -CONFIG_MAINBOARD_HAS_LPC_TPM=y -CONFIG_LPC_TPM=y -CONFIG_TPM_TIS_BASE_ADDRESS=0xfed40000 -# CONFIG_TPM_INIT_FAILURE_IS_FATAL is not set -# CONFIG_SKIP_TPM_STARTUP_ON_NORMAL_BOOT is not set -# CONFIG_TPM_DEACTIVATE is not set -CONFIG_VGA=y -CONFIG_DRIVERS_RICOH_RCE822=y -# CONFIG_DRIVER_SIEMENS_NC_FPGA is not set -# CONFIG_NC_FPGA_NOTIFY_CB_READY is not set -# CONFIG_DRIVERS_SIL_3114 is not set -# CONFIG_MAINBOARD_HAS_SPI_TPM_CR50 is not set -# CONFIG_DRIVER_TI_TPS65090 is not set -# CONFIG_DRIVERS_TI_TPS65913 is not set -# CONFIG_DRIVERS_TI_TPS65913_RTC is not set -# CONFIG_DRIVER_XPOWERS_AXP209 is not set -# CONFIG_COMMONLIB_STORAGE is not set - -# -# Security -# - -# -# Verified Boot (vboot) -# -CONFIG_ACPI_SATA_GENERATOR=y -CONFIG_ACPI_INTEL_HARDWARE_SLEEP_VALUES=y -# CONFIG_ACPI_AMD_HARDWARE_SLEEP_VALUES is not set -# CONFIG_BOOT_DEVICE_NOT_SPI_FLASH is not set -CONFIG_BOOT_DEVICE_SPI_FLASH=y -CONFIG_BOOT_DEVICE_MEMORY_MAPPED=y -# CONFIG_BOOT_DEVICE_SUPPORTS_WRITES is not set -CONFIG_RTC=y -CONFIG_TPM=y -# CONFIG_MAINBOARD_HAS_TPM_CR50 is not set - -# -# Console -# -CONFIG_SQUELCH_EARLY_SMP=y -CONFIG_CONSOLE_SERIAL=y - -# -# I/O mapped, 8250-compatible -# - -# -# Serial port base address = 0x3f8 -# -# CONFIG_CONSOLE_SERIAL_921600 is not set -# CONFIG_CONSOLE_SERIAL_460800 is not set -# CONFIG_CONSOLE_SERIAL_230400 is not set -CONFIG_CONSOLE_SERIAL_115200=y -# CONFIG_CONSOLE_SERIAL_57600 is not set -# CONFIG_CONSOLE_SERIAL_38400 is not set -# CONFIG_CONSOLE_SERIAL_19200 is not set -# CONFIG_CONSOLE_SERIAL_9600 is not set -# CONFIG_SPKMODEM is not set -# CONFIG_CONSOLE_NE2K is not set CONFIG_CONSOLE_CBMEM_BUFFER_SIZE=0x80000 -# CONFIG_CONSOLE_SPI_FLASH is not set CONFIG_DEFAULT_CONSOLE_LOGLEVEL_8=y -# CONFIG_DEFAULT_CONSOLE_LOGLEVEL_7 is not set -# CONFIG_DEFAULT_CONSOLE_LOGLEVEL_6 is not set -# CONFIG_DEFAULT_CONSOLE_LOGLEVEL_5 is not set -# CONFIG_DEFAULT_CONSOLE_LOGLEVEL_4 is not set -# CONFIG_DEFAULT_CONSOLE_LOGLEVEL_3 is not set -# CONFIG_DEFAULT_CONSOLE_LOGLEVEL_2 is not set -# CONFIG_DEFAULT_CONSOLE_LOGLEVEL_1 is not set -# CONFIG_DEFAULT_CONSOLE_LOGLEVEL_0 is not set -# CONFIG_CMOS_POST is not set -# CONFIG_CONSOLE_POST is not set -CONFIG_POST_IO_PORT=0x80 -# CONFIG_NO_EARLY_BOOTBLOCK_POSTCODES is not set -CONFIG_HWBASE_DEBUG_CB=y -CONFIG_HAVE_ACPI_RESUME=y -# CONFIG_ACPI_HUGE_LOWMEM_BACKUP is not set -CONFIG_RESUME_PATH_SAME_AS_BOOT=y -CONFIG_HAVE_HARD_RESET=y -# CONFIG_HAVE_ROMSTAGE_CONSOLE_SPINLOCK is not set -# CONFIG_HAVE_ROMSTAGE_NVRAM_CBFS_SPINLOCK is not set -# CONFIG_HAVE_ROMSTAGE_MICROCODE_CBFS_SPINLOCK is not set -CONFIG_HAVE_MONOTONIC_TIMER=y -# CONFIG_GENERIC_UDELAY is not set -# CONFIG_TIMER_QUEUE is not set -CONFIG_HAVE_OPTION_TABLE=y -# CONFIG_PIRQ_ROUTE is not set -CONFIG_HAVE_SMI_HANDLER=y -# CONFIG_PCI_IO_CFG_EXT is not set -CONFIG_IOAPIC=y -CONFIG_USE_WATCHDOG_ON_BOOT=y -# CONFIG_GFXUMA is not set -CONFIG_HAVE_ACPI_TABLES=y -CONFIG_COMMON_FADT=y -# CONFIG_ACPI_NHLT is not set - -# -# System tables -# -# CONFIG_GENERATE_MP_TABLE is not set -# CONFIG_GENERATE_PIRQ_TABLE is not set -CONFIG_GENERATE_SMBIOS_TABLES=y - -# -# Payload -# -# CONFIG_PAYLOAD_NONE is not set -# CONFIG_PAYLOAD_ELF is not set -# CONFIG_PAYLOAD_BAYOU is not set -# CONFIG_PAYLOAD_FILO is not set -# CONFIG_PAYLOAD_GRUB2 is not set -# CONFIG_PAYLOAD_SEABIOS is not set -# CONFIG_PAYLOAD_UBOOT is not set CONFIG_PAYLOAD_LINUX=y -# CONFIG_PAYLOAD_TIANOCORE is not set CONFIG_PAYLOAD_FILE="../../build/x230-flash/bzImage" -CONFIG_PAYLOAD_OPTIONS="" -# CONFIG_PXE is not set -CONFIG_LINUX_COMMAND_LINE="" CONFIG_LINUX_INITRD="../../build/x230-flash/initrd.cpio.xz" -# CONFIG_PAYLOAD_IS_FLAT_BINARY is not set - -# -# Secondary Payloads -# -# CONFIG_COREINFO_SECONDARY_PAYLOAD is not set -# CONFIG_MEMTEST_SECONDARY_PAYLOAD is not set -# CONFIG_NVRAMCUI_SECONDARY_PAYLOAD is not set -# CONFIG_TINT_SECONDARY_PAYLOAD is not set - -# -# Debugging -# -# CONFIG_GDB_STUB is not set -# CONFIG_FATAL_ASSERTS is not set -# CONFIG_DEBUG_CBFS is not set -CONFIG_HAVE_DEBUG_RAM_SETUP=y -# CONFIG_DEBUG_RAM_SETUP is not set -# CONFIG_HAVE_DEBUG_CAR is not set -CONFIG_HAVE_DEBUG_SMBUS=y -# CONFIG_DEBUG_SMBUS is not set -# CONFIG_DEBUG_SMI is not set CONFIG_DEBUG_SMM_RELOCATION=y -# CONFIG_DEBUG_MALLOC is not set -# CONFIG_DEBUG_ACPI is not set -# CONFIG_DEBUG_TPM is not set -# CONFIG_DEBUG_SPI_FLASH is not set -# CONFIG_TRACE is not set -# CONFIG_DEBUG_BOOT_STATE is not set -# CONFIG_DEBUG_ADA_CODE is not set -# CONFIG_ENABLE_APIC_EXT_ID is not set -CONFIG_WARNINGS_ARE_ERRORS=y -# CONFIG_POWER_BUTTON_DEFAULT_ENABLE is not set -# CONFIG_POWER_BUTTON_DEFAULT_DISABLE is not set -# CONFIG_POWER_BUTTON_FORCE_ENABLE is not set -# CONFIG_POWER_BUTTON_FORCE_DISABLE is not set -# CONFIG_POWER_BUTTON_IS_OPTIONAL is not set -# CONFIG_REG_SCRIPT is not set -# CONFIG_CREATE_BOARD_CHECKLIST is not set -# CONFIG_MAKE_CHECKLIST_PUBLIC is not set -# CONFIG_NO_XIP_EARLY_STAGES is not set -CONFIG_EARLY_CBMEM_INIT=y -# CONFIG_EARLY_CBMEM_LIST is not set -CONFIG_RELOCATABLE_MODULES=y -CONFIG_BOOTBLOCK_CUSTOM=y diff --git a/config/coreboot-x230.config b/config/coreboot-x230.config index 7edc2999..61e9dd9d 100644 --- a/config/coreboot-x230.config +++ b/config/coreboot-x230.config @@ -1,685 +1,21 @@ -# -# Automatically generated file; DO NOT EDIT. -# coreboot configuration -# - -# -# General setup -# -CONFIG_COREBOOT_BUILD=y CONFIG_LOCALVERSION="heads" -CONFIG_CBFS_PREFIX="fallback" -CONFIG_COMPILER_GCC=y -# CONFIG_COMPILER_LLVM_CLANG is not set -# CONFIG_ANY_TOOLCHAIN is not set -# CONFIG_CCACHE is not set -# CONFIG_FMD_GENPARSER is not set -# CONFIG_UTIL_GENPARSER is not set -# CONFIG_USE_OPTION_TABLE is not set -CONFIG_COMPRESS_RAMSTAGE=y # CONFIG_INCLUDE_CONFIG_FILE is not set # CONFIG_COLLECT_TIMESTAMPS is not set CONFIG_USE_BLOBS=y -# CONFIG_COVERAGE is not set -# CONFIG_UBSAN is not set -CONFIG_RELOCATABLE_RAMSTAGE=y -# CONFIG_UPDATE_IMAGE is not set -# CONFIG_BOOTSPLASH_IMAGE is not set CONFIG_MEASURED_BOOT=y - -# -# Mainboard -# - -# -# Important: Run 'make distclean' before switching boards -# -# CONFIG_VENDOR_A_TREND is not set -# CONFIG_VENDOR_AAEON is not set -# CONFIG_VENDOR_ABIT is not set -# CONFIG_VENDOR_ADI is not set -# CONFIG_VENDOR_ADLINK is not set -# CONFIG_VENDOR_ADVANSUS is not set -# CONFIG_VENDOR_AMD is not set -# CONFIG_VENDOR_AOPEN is not set -# CONFIG_VENDOR_APPLE is not set -# CONFIG_VENDOR_ARTECGROUP is not set -# CONFIG_VENDOR_ASROCK is not set -# CONFIG_VENDOR_ASUS is not set -# CONFIG_VENDOR_AVALUE is not set -# CONFIG_VENDOR_AZZA is not set -# CONFIG_VENDOR_BACHMANN is not set -# CONFIG_VENDOR_BAP is not set -# CONFIG_VENDOR_BCOM is not set -# CONFIG_VENDOR_BIOSTAR is not set -# CONFIG_VENDOR_BROADCOM is not set -# CONFIG_VENDOR_COMPAQ is not set -# CONFIG_VENDOR_COMPULAB is not set -# CONFIG_VENDOR_CUBIETECH is not set -# CONFIG_VENDOR_DIGITALLOGIC is not set -# CONFIG_VENDOR_DMP is not set -# CONFIG_VENDOR_ECS is not set -# CONFIG_VENDOR_ELMEX is not set -# CONFIG_VENDOR_EMULATION is not set -# CONFIG_VENDOR_ESD is not set -# CONFIG_VENDOR_FOXCONN is not set -# CONFIG_VENDOR_GETAC is not set -# CONFIG_VENDOR_GIGABYTE is not set -# CONFIG_VENDOR_GIZMOSPHERE is not set -# CONFIG_VENDOR_GOOGLE is not set -# CONFIG_VENDOR_HP is not set -# CONFIG_VENDOR_IBASE is not set -# CONFIG_VENDOR_IEI is not set -# CONFIG_VENDOR_INTEL is not set -# CONFIG_VENDOR_IWAVE is not set -# CONFIG_VENDOR_IWILL is not set -# CONFIG_VENDOR_JETWAY is not set -# CONFIG_VENDOR_KONTRON is not set -# CONFIG_VENDOR_LANNER is not set CONFIG_VENDOR_LENOVO=y -# CONFIG_VENDOR_LINUTOP is not set -# CONFIG_VENDOR_LIPPERT is not set -# CONFIG_VENDOR_LOWRISC is not set -# CONFIG_VENDOR_MITAC is not set -# CONFIG_VENDOR_MSI is not set -# CONFIG_VENDOR_NEC is not set -# CONFIG_VENDOR_NOKIA is not set -# CONFIG_VENDOR_NVIDIA is not set -# CONFIG_VENDOR_PACKARDBELL is not set -# CONFIG_VENDOR_PCENGINES is not set -# CONFIG_VENDOR_PURISM is not set -# CONFIG_VENDOR_RCA is not set -# CONFIG_VENDOR_RODA is not set -# CONFIG_VENDOR_SAMSUNG is not set -# CONFIG_VENDOR_SAPPHIRE is not set -# CONFIG_VENDOR_SIEMENS is not set -# CONFIG_VENDOR_SOYO is not set -# CONFIG_VENDOR_SUNW is not set -# CONFIG_VENDOR_SUPERMICRO is not set -# CONFIG_VENDOR_TECHNEXION is not set -# CONFIG_VENDOR_THOMSON is not set -# CONFIG_VENDOR_TI is not set -# CONFIG_VENDOR_TRAVERSE is not set -# CONFIG_VENDOR_TYAN is not set -# CONFIG_VENDOR_VIA is not set -# CONFIG_VENDOR_WINENT is not set -# CONFIG_VENDOR_WINNET is not set -# CONFIG_VENDOR_WYSE is not set -CONFIG_BOARD_SPECIFIC_OPTIONS=y -CONFIG_MAINBOARD_DIR="lenovo/x230" -CONFIG_MAINBOARD_PART_NUMBER="ThinkPad X230" -CONFIG_MAINBOARD_VENDOR="LENOVO" -CONFIG_MAX_CPUS=8 -CONFIG_CACHE_ROM_SIZE_OVERRIDE=0x0 CONFIG_CBFS_SIZE=0x700000 -CONFIG_VGA_BIOS_ID="8086,0166" -# CONFIG_ONBOARD_VGA_IS_PRIMARY is not set -CONFIG_DIMM_SPD_SIZE=256 -# CONFIG_VGA_BIOS is not set -CONFIG_DCACHE_RAM_BASE=0xfefe0000 -CONFIG_DCACHE_RAM_SIZE=0x20000 -CONFIG_VGA_BIOS_FILE="pci8086,0166.rom" -CONFIG_MAINBOARD_PCI_SUBSYSTEM_VENDOR_ID=0x17aa -CONFIG_MAINBOARD_PCI_SUBSYSTEM_DEVICE_ID=0x21fa -# CONFIG_HAVE_IFD_BIN is not set -# CONFIG_HAVE_ME_BIN is not set -CONFIG_DRAM_RESET_GATE_GPIO=10 -CONFIG_MMCONF_BASE_ADDRESS=0xf8000000 # CONFIG_POST_IO is not set -CONFIG_DEVICETREE="devicetree.cb" -CONFIG_MAX_REBOOT_CNT=3 -CONFIG_USBDEBUG_HCD_INDEX=2 -CONFIG_ID_SECTION_OFFSET=0x80 # CONFIG_POST_DEVICE is not set -CONFIG_IFD_BIOS_SECTION="" -CONFIG_IFD_ME_SECTION="" -# CONFIG_VBOOT is not set -CONFIG_TPM_PIRQ=0x0 -CONFIG_BOOT_DEVICE_SPI_FLASH_BUS=0 -CONFIG_FMDFILE="" -CONFIG_PRERAM_CBMEM_CONSOLE_SIZE=0xc00 CONFIG_DRIVERS_UART_8250IO=y -CONFIG_IFD_GBE_SECTION="" -# CONFIG_BOARD_LENOVO_G505S is not set -# CONFIG_BOARD_LENOVO_L520 is not set -# CONFIG_BOARD_LENOVO_R400 is not set -# CONFIG_BOARD_LENOVO_S230U is not set -# CONFIG_BOARD_LENOVO_T400 is not set -# CONFIG_BOARD_LENOVO_T420 is not set -# CONFIG_BOARD_LENOVO_T420S is not set -# CONFIG_BOARD_LENOVO_THINKPAD_T430 is not set -# CONFIG_BOARD_LENOVO_T430S is not set -# CONFIG_BOARD_LENOVO_T500 is not set -# CONFIG_BOARD_LENOVO_T520 is not set -# CONFIG_BOARD_LENOVO_T530 is not set -# CONFIG_BOARD_LENOVO_T60 is not set -# CONFIG_BOARD_LENOVO_X131E is not set -# CONFIG_BOARD_LENOVO_X1_CARBON_GEN1 is not set -# CONFIG_BOARD_LENOVO_X200 is not set -# CONFIG_BOARD_LENOVO_X201 is not set -# CONFIG_BOARD_LENOVO_X220 is not set -# CONFIG_BOARD_LENOVO_X220I is not set CONFIG_BOARD_LENOVO_X230=y -# CONFIG_BOARD_LENOVO_X60 is not set -# CONFIG_BOARD_LENOVO_Z61T is not set -CONFIG_CPU_ADDR_BITS=36 -CONFIG_DEFAULT_CONSOLE_LOGLEVEL=5 -# CONFIG_USBDEBUG is not set CONFIG_DRIVERS_PS2_KEYBOARD=y -# CONFIG_PCIEXP_L1_SUB_STATE is not set -# CONFIG_NO_POST is not set -CONFIG_BOARD_ROMSIZE_KB_12288=y -# CONFIG_COREBOOT_ROMSIZE_KB_64 is not set -# CONFIG_COREBOOT_ROMSIZE_KB_128 is not set -# CONFIG_COREBOOT_ROMSIZE_KB_256 is not set -# CONFIG_COREBOOT_ROMSIZE_KB_512 is not set -# CONFIG_COREBOOT_ROMSIZE_KB_1024 is not set -# CONFIG_COREBOOT_ROMSIZE_KB_2048 is not set -# CONFIG_COREBOOT_ROMSIZE_KB_4096 is not set -# CONFIG_COREBOOT_ROMSIZE_KB_8192 is not set -# CONFIG_COREBOOT_ROMSIZE_KB_10240 is not set -CONFIG_COREBOOT_ROMSIZE_KB_12288=y -# CONFIG_COREBOOT_ROMSIZE_KB_16384 is not set -# CONFIG_COREBOOT_ROMSIZE_KB_32768 is not set -# CONFIG_COREBOOT_ROMSIZE_KB_65536 is not set -CONFIG_COREBOOT_ROMSIZE_KB=12288 -CONFIG_ROM_SIZE=0xc00000 -# CONFIG_MAINBOARD_HAS_TPM2 is not set -CONFIG_SYSTEM_TYPE_LAPTOP=y -# CONFIG_CBFS_AUTOGEN_ATTRIBUTES is not set - -# -# Chipset -# - -# -# SoC -# -CONFIG_CPU_SPECIFIC_OPTIONS=y -CONFIG_RAMTOP=0x200000 -CONFIG_HEAP_SIZE=0x4000 -CONFIG_RAMBASE=0x100000 -CONFIG_EHCI_BAR=0xfef00000 -CONFIG_SERIRQ_CONTINUOUS_MODE=y -CONFIG_SMM_TSEG_SIZE=0x800000 -CONFIG_ACPI_CPU_STRING="\\_PR.CP%02d" -# CONFIG_SOC_BROADCOM_CYGNUS is not set -CONFIG_BOOTBLOCK_CPU_INIT="cpu/intel/model_206ax/bootblock.c" -# CONFIG_SOC_INTEL_GLK is not set -CONFIG_C_ENV_BOOTBLOCK_SIZE=0x10000 -CONFIG_X86_TOP4G_BOOTMEDIA_MAP=y -CONFIG_ROMSTAGE_ADDR=0x2000000 -CONFIG_VERSTAGE_ADDR=0x2000000 -CONFIG_SPI_FLASH_INCLUDE_ALL_DRIVERS=y -CONFIG_DCACHE_RAM_MRC_VAR_SIZE=0x0 -CONFIG_BUILD_WITH_FAKE_IFD=y -CONFIG_PCIEXP_ASPM=y -CONFIG_PCIEXP_COMMON_CLOCK=y -# CONFIG_PCIEXP_CLK_PM is not set -CONFIG_BOOTBLOCK_NORTHBRIDGE_INIT="northbridge/intel/sandybridge/bootblock.c" -CONFIG_BOOTBLOCK_SOUTHBRIDGE_INIT="southbridge/intel/bd82x6x/bootblock.c" -CONFIG_CACHE_MRC_SIZE_KB=512 -CONFIG_STACK_SIZE=0x1000 -CONFIG_CONSOLE_CBMEM=y CONFIG_UART_PCI_ADDR=0 -CONFIG_HPET_MIN_TICKS=0x80 -# CONFIG_SOC_INTEL_KABYLAKE is not set -# CONFIG_SOC_LOWRISC_LOWRISC is not set -# CONFIG_SOC_MARVELL_MVMAP2315 is not set -# CONFIG_SOC_MEDIATEK_MT8173 is not set -# CONFIG_SOC_NVIDIA_TEGRA124 is not set -# CONFIG_SOC_NVIDIA_TEGRA210 is not set -# CONFIG_SOC_QC_IPQ40XX is not set -# CONFIG_SOC_QC_IPQ806X is not set -# CONFIG_SOC_ROCKCHIP_RK3288 is not set -# CONFIG_SOC_ROCKCHIP_RK3399 is not set -# CONFIG_CPU_SAMSUNG_EXYNOS5250 is not set -# CONFIG_CPU_SAMSUNG_EXYNOS5420 is not set -# CONFIG_SOC_UCB_RISCV is not set - -# -# CPU -# -# CONFIG_CPU_ALLWINNER_A10 is not set -CONFIG_SOCKET_SPECIFIC_OPTIONS=y -CONFIG_XIP_ROM_SIZE=0x20000 -CONFIG_NUM_IPI_STARTS=2 -# CONFIG_CPU_AMD_AGESA is not set -# CONFIG_CPU_AMD_PI is not set -# CONFIG_CPU_ARMLTD_CORTEX_A9 is not set -CONFIG_CPU_INTEL_MODEL_306AX=y -CONFIG_SSE2=y -CONFIG_CPU_INTEL_SOCKET_RPGA989=y -# CONFIG_CPU_INTEL_FIRMWARE_INTERFACE_TABLE is not set -# CONFIG_CPU_INTEL_TURBO_NOT_PACKAGE_SCOPED is not set -CONFIG_CPU_INTEL_COMMON=y -CONFIG_ENABLE_VMX=y -CONFIG_SET_VMX_LOCK_BIT=y -# CONFIG_CPU_TI_AM335X is not set -# CONFIG_PARALLEL_CPU_INIT is not set -# CONFIG_PARALLEL_MP is not set -# CONFIG_UDELAY_IO is not set -# CONFIG_UDELAY_LAPIC is not set -CONFIG_UDELAY_TSC=y -CONFIG_TSC_CONSTANT_RATE=y -CONFIG_TSC_MONOTONIC_TIMER=y -# CONFIG_UDELAY_TIMER2 is not set -# CONFIG_TSC_SYNC_LFENCE is not set -CONFIG_TSC_SYNC_MFENCE=y -# CONFIG_NO_FIXED_XIP_ROM_SIZE is not set -CONFIG_LOGICAL_CPUS=y -CONFIG_SMM_TSEG=y -CONFIG_SMM_MODULE_HEAP_SIZE=0x4000 -# CONFIG_SMM_LAPIC_REMAP_MITIGATION is not set -# CONFIG_SERIALIZED_SMM_INITIALIZATION is not set -# CONFIG_X86_AMD_FIXED_MTRRS is not set -# CONFIG_PLATFORM_USES_FSP1_0 is not set -# CONFIG_MIRROR_PAYLOAD_TO_RAM_BEFORE_LOADING is not set -# CONFIG_SOC_SETS_MSRS is not set -CONFIG_CACHE_AS_RAM=y -# CONFIG_NO_CAR_GLOBAL_MIGRATION is not set -CONFIG_SMP=y -CONFIG_AP_SIPI_VECTOR=0xfffff000 -CONFIG_MMX=y -CONFIG_SSE=y -CONFIG_SUPPORT_CPU_UCODE_IN_CBFS=y -# CONFIG_USES_MICROCODE_HEADER_FILES is not set -CONFIG_CPU_MICROCODE_CBFS_GENERATE=y -# CONFIG_CPU_MICROCODE_CBFS_EXTERNAL_HEADER is not set -# CONFIG_CPU_MICROCODE_CBFS_NONE is not set -# CONFIG_CPU_MICROCODE_MULTIPLE_FILES is not set -CONFIG_CPU_UCODE_BINARIES="" - -# -# Northbridge -# -# CONFIG_NORTHBRIDGE_AMD_AGESA is not set -# CONFIG_NO_MMCONF_SUPPORT is not set -# CONFIG_AMD_NB_CIMX is not set -# CONFIG_NORTHBRIDGE_AMD_CIMX_RD890 is not set -# CONFIG_NORTHBRIDGE_AMD_PI is not set -CONFIG_NORTHBRIDGE_INTEL_COMMON_MRC_CACHE=y -CONFIG_MRC_CACHE_SIZE=0x10000 -CONFIG_NORTHBRIDGE_INTEL_IVYBRIDGE=y -CONFIG_USE_NATIVE_RAMINIT=y -# CONFIG_NATIVE_RAMINIT_IGNORE_MAX_MEM_FUSES is not set -# CONFIG_NATIVE_RAMINIT_IGNORE_XMP_MAX_DIMMS is not set -CONFIG_SANDYBRIDGE_IVYBRIDGE_LVDS=y -CONFIG_IF_NATIVE_VGA_INIT=y -CONFIG_HPET_ADDRESS=0xfed00000 -CONFIG_MAX_PIRQ_LINKS=4 - -# -# Southbridge -# -# CONFIG_AMD_SB_CIMX is not set -# CONFIG_SOUTHBRIDGE_AMD_CIMX_SB800 is not set -# CONFIG_SOUTHBRIDGE_AMD_CIMX_SB900 is not set -CONFIG_SOUTHBRIDGE_INTEL_C216=y -CONFIG_SOUTH_BRIDGE_OPTIONS=y -CONFIG_LOCK_SPI_FLASH_NONE=y -# CONFIG_LOCK_SPI_FLASH_RO is not set -# CONFIG_LOCK_SPI_FLASH_NO_ACCESS is not set -CONFIG_SOUTHBRIDGE_INTEL_COMMON=y -CONFIG_SOUTHBRIDGE_INTEL_COMMON_GPIO=y -CONFIG_SOUTHBRIDGE_INTEL_COMMON_SMBUS=y -CONFIG_SOUTHBRIDGE_INTEL_COMMON_SPI=y -CONFIG_SOUTHBRIDGE_INTEL_COMMON_PIRQ_ACPI_GEN=y -CONFIG_SOUTHBRIDGE_INTEL_COMMON_RCBA_PIRQ=y -CONFIG_HAVE_INTEL_CHIPSET_LOCKDOWN=y -CONFIG_INTEL_CHIPSET_LOCKDOWN=y -# CONFIG_LOCK_MANAGEMENT_ENGINE is not set - -# -# Super I/O -# -# CONFIG_SUPERIO_NUVOTON_NCT6776_COM_A is not set - -# -# Embedded Controllers -# -CONFIG_EC_ACPI=y -CONFIG_EC_LENOVO_H8=y -CONFIG_H8_BEEP_ON_DEATH=y -CONFIG_H8_FLASH_LEDS_ON_DEATH=y -# CONFIG_H8_SUPPORT_BT_ON_WIFI is not set -CONFIG_EC_LENOVO_PMH7=y -CONFIG_HAVE_INTEL_FIRMWARE=y - -# -# Intel Firmware -# -CONFIG_IFD_PLATFORM_SECTION="" -# CONFIG_MAINBOARD_HAS_CHROMEOS is not set -# CONFIG_GOOGLE_SMBIOS_MAINBOARD_VERSION is not set -# CONFIG_UEFI_2_4_BINDING is not set -# CONFIG_UDK_2015_BINDING is not set -# CONFIG_USE_SIEMENS_HWILIB is not set -# CONFIG_ARCH_ARM is not set -# CONFIG_ARCH_BOOTBLOCK_ARM is not set -# CONFIG_ARCH_VERSTAGE_ARM is not set -# CONFIG_ARCH_ROMSTAGE_ARM is not set -# CONFIG_ARCH_RAMSTAGE_ARM is not set -# CONFIG_ARCH_BOOTBLOCK_ARMV4 is not set -# CONFIG_ARCH_VERSTAGE_ARMV4 is not set -# CONFIG_ARCH_ROMSTAGE_ARMV4 is not set -# CONFIG_ARCH_RAMSTAGE_ARMV4 is not set -# CONFIG_ARCH_BOOTBLOCK_ARMV7 is not set -# CONFIG_ARCH_VERSTAGE_ARMV7 is not set -# CONFIG_ARCH_ROMSTAGE_ARMV7 is not set -# CONFIG_ARCH_RAMSTAGE_ARMV7 is not set -# CONFIG_ARCH_BOOTBLOCK_ARMV7_M is not set -# CONFIG_ARCH_VERSTAGE_ARMV7_M is not set -# CONFIG_ARCH_BOOTBLOCK_ARMV7_R is not set -# CONFIG_ARCH_VERSTAGE_ARMV7_R is not set -# CONFIG_ARCH_ROMSTAGE_ARMV7_R is not set -# CONFIG_ARCH_RAMSTAGE_ARMV7_R is not set -# CONFIG_ARM_LPAE is not set -# CONFIG_ARCH_ARM64 is not set -# CONFIG_ARCH_BOOTBLOCK_ARM64 is not set -# CONFIG_ARCH_VERSTAGE_ARM64 is not set -# CONFIG_ARCH_ROMSTAGE_ARM64 is not set -# CONFIG_ARCH_RAMSTAGE_ARM64 is not set -# CONFIG_ARCH_BOOTBLOCK_ARMV8_64 is not set -# CONFIG_ARCH_VERSTAGE_ARMV8_64 is not set -# CONFIG_ARCH_ROMSTAGE_ARMV8_64 is not set -# CONFIG_ARCH_RAMSTAGE_ARMV8_64 is not set -# CONFIG_ARM64_A53_ERRATUM_843419 is not set -# CONFIG_ARCH_MIPS is not set -# CONFIG_ARCH_BOOTBLOCK_MIPS is not set -# CONFIG_ARCH_VERSTAGE_MIPS is not set -# CONFIG_ARCH_ROMSTAGE_MIPS is not set -# CONFIG_ARCH_RAMSTAGE_MIPS is not set -# CONFIG_ARCH_POWER8 is not set -# CONFIG_ARCH_BOOTBLOCK_POWER8 is not set -# CONFIG_ARCH_VERSTAGE_POWER8 is not set -# CONFIG_ARCH_ROMSTAGE_POWER8 is not set -# CONFIG_ARCH_RAMSTAGE_POWER8 is not set -# CONFIG_ARCH_RISCV is not set -# CONFIG_ARCH_BOOTBLOCK_RISCV is not set -# CONFIG_ARCH_VERSTAGE_RISCV is not set -# CONFIG_ARCH_ROMSTAGE_RISCV is not set -# CONFIG_ARCH_RAMSTAGE_RISCV is not set -CONFIG_ARCH_X86=y -CONFIG_ARCH_BOOTBLOCK_X86_32=y -CONFIG_ARCH_VERSTAGE_X86_32=y -CONFIG_ARCH_ROMSTAGE_X86_32=y -CONFIG_ARCH_RAMSTAGE_X86_32=y -# CONFIG_ARCH_BOOTBLOCK_X86_64 is not set -# CONFIG_ARCH_VERSTAGE_X86_64 is not set -# CONFIG_ARCH_ROMSTAGE_X86_64 is not set -# CONFIG_ARCH_RAMSTAGE_X86_64 is not set -# CONFIG_USE_MARCH_586 is not set -# CONFIG_AP_IN_SIPI_WAIT is not set -# CONFIG_SIPI_VECTOR_IN_ROM is not set -# CONFIG_ROMCC is not set -# CONFIG_CBMEM_TOP_BACKUP is not set -# CONFIG_LATE_CBMEM_INIT is not set -# CONFIG_EARLY_EBDA_INIT is not set -CONFIG_PC80_SYSTEM=y -# CONFIG_BOOTBLOCK_DEBUG_SPINLOOP is not set -# CONFIG_BOOTBLOCK_SAVE_BIST_AND_TIMESTAMP is not set -CONFIG_HAVE_CMOS_DEFAULT=y -CONFIG_CMOS_DEFAULT_FILE="src/mainboard/$(MAINBOARDDIR)/cmos.default" -CONFIG_IOAPIC_INTERRUPTS_ON_FSB=y -# CONFIG_IOAPIC_INTERRUPTS_ON_APIC_SERIAL_BUS is not set -# CONFIG_POSTCAR_STAGE is not set -# CONFIG_VERSTAGE_DEBUG_SPINLOOP is not set -# CONFIG_ROMSTAGE_DEBUG_SPINLOOP is not set -CONFIG_BOOTBLOCK_SIMPLE=y -# CONFIG_BOOTBLOCK_NORMAL is not set -CONFIG_BOOTBLOCK_SOURCE="bootblock_simple.c" - -# -# Devices -# -CONFIG_HAVE_VGA_TEXT_FRAMEBUFFER=y -CONFIG_HAVE_LINEAR_FRAMEBUFFER=y -CONFIG_MAINBOARD_HAS_NATIVE_VGA_INIT=y -# CONFIG_MAINBOARD_FORCE_NATIVE_VGA_INIT is not set -CONFIG_MAINBOARD_HAS_LIBGFXINIT=y -CONFIG_MAINBOARD_DO_NATIVE_VGA_INIT=y -# CONFIG_MAINBOARD_USE_LIBGFXINIT is not set -# CONFIG_VGA_ROM_RUN is not set -# CONFIG_NO_GFX_INIT is not set -# CONFIG_MULTIPLE_VGA_ADAPTERS is not set - -# -# Display -# -CONFIG_VGA_TEXT_FRAMEBUFFER=y -# CONFIG_GENERIC_LINEAR_FRAMEBUFFER is not set -# CONFIG_SMBUS_HAS_AUX_CHANNELS is not set -CONFIG_PCI=y -CONFIG_MMCONF_SUPPORT=y -# CONFIG_HYPERTRANSPORT_PLUGIN_SUPPORT is not set -CONFIG_PCIX_PLUGIN_SUPPORT=y -CONFIG_CARDBUS_PLUGIN_SUPPORT=y -# CONFIG_AZALIA_PLUGIN_SUPPORT is not set -CONFIG_PCIEXP_PLUGIN_SUPPORT=y -# CONFIG_EARLY_PCI_BRIDGE is not set -CONFIG_SUBSYSTEM_VENDOR_ID=0x0000 -CONFIG_SUBSYSTEM_DEVICE_ID=0x0000 -# CONFIG_INTEL_GMA_ADD_VBT_DATA_FILE is not set -# CONFIG_SOFTWARE_I2C is not set - -# -# Generic Drivers -# -# CONFIG_DRIVERS_AS3722_RTC is not set -# CONFIG_GIC is not set -# CONFIG_IPMI_KCS is not set -# CONFIG_DRIVERS_LENOVO_WACOM is not set -# CONFIG_RT8168_GET_MAC_FROM_VPD is not set -# CONFIG_RT8168_SET_LED_MODE is not set -CONFIG_SPI_FLASH=y -CONFIG_BOOT_DEVICE_SPI_FLASH_RW_NOMMAP=y -# CONFIG_BOOT_DEVICE_SPI_FLASH_RW_NOMMAP_EARLY is not set -# CONFIG_SPI_FLASH_SMM is not set -# CONFIG_SPI_FLASH_NO_FAST_READ is not set -CONFIG_SPI_FLASH_ADESTO=y -CONFIG_SPI_FLASH_AMIC=y -CONFIG_SPI_FLASH_ATMEL=y -CONFIG_SPI_FLASH_EON=y -CONFIG_SPI_FLASH_GIGADEVICE=y -CONFIG_SPI_FLASH_MACRONIX=y -CONFIG_SPI_FLASH_SPANSION=y -CONFIG_SPI_FLASH_SST=y -CONFIG_SPI_FLASH_STMICRO=y -CONFIG_SPI_FLASH_WINBOND=y -# CONFIG_SPI_FLASH_FAST_READ_DUAL_OUTPUT_3B is not set -# CONFIG_SPI_FLASH_HAS_VOLATILE_GROUP is not set -# CONFIG_HAVE_SPI_CONSOLE_SUPPORT is not set -# CONFIG_DRIVERS_UART is not set -# CONFIG_DRIVERS_UART_8250IO_SKIP_INIT is not set -CONFIG_NO_UART_ON_SUPERIO=y -# CONFIG_UART_OVERRIDE_INPUT_CLOCK_DIVIDER is not set -# CONFIG_UART_OVERRIDE_REFCLK is not set -# CONFIG_DRIVERS_UART_8250MEM is not set -# CONFIG_DRIVERS_UART_8250MEM_32 is not set -# CONFIG_HAVE_UART_SPECIAL is not set -# CONFIG_DRIVERS_UART_OXPCIE is not set -# CONFIG_DRIVERS_UART_PL011 is not set -# CONFIG_UART_USE_REFCLK_AS_INPUT_CLOCK is not set -CONFIG_HAVE_USBDEBUG=y -CONFIG_HAVE_USBDEBUG_OPTIONS=y -# CONFIG_DRIVERS_AMD_PI is not set -CONFIG_SMBIOS_PROVIDED_BY_MOBO=y -# CONFIG_DRIVERS_I2C_MAX98927 is not set -# CONFIG_DRIVERS_I2C_PCF8523 is not set -# CONFIG_DRIVERS_I2C_RT5663 is not set -# CONFIG_DRIVERS_I2C_RTD2132 is not set -# CONFIG_DRIVERS_I2C_RX6110SA is not set -# CONFIG_I2C_TPM is not set -# CONFIG_MAINBOARD_HAS_I2C_TPM_ATMEL is not set -# CONFIG_MAINBOARD_HAS_I2C_TPM_CR50 is not set -# CONFIG_INTEL_DDI is not set -CONFIG_INTEL_EDID=y -CONFIG_INTEL_INT15=y -CONFIG_INTEL_GMA_ACPI=y -# CONFIG_INTEL_GMA_SSC_ALTERNATE_REF is not set -CONFIG_GFX_GMA=y -CONFIG_GFX_GMA_CPU="Ivybridge" -CONFIG_GFX_GMA_CPU_VARIANT="Normal" -# CONFIG_GFX_GMA_INTERNAL_IS_EDP is not set -CONFIG_GFX_GMA_INTERNAL_IS_LVDS=y -CONFIG_GFX_GMA_INTERNAL_PORT="LVDS" -CONFIG_GFX_GMA_ANALOG_I2C_PORT="PCH_DAC" -# CONFIG_DRIVER_INTEL_I210 is not set -# CONFIG_DRIVERS_INTEL_MIPI_CAMERA is not set -CONFIG_DRIVERS_INTEL_WIFI=y -# CONFIG_USE_SAR is not set -# CONFIG_DRIVERS_LENOVO_HYBRID_GRAPHICS is not set -# CONFIG_DRIVER_MAXIM_MAX77686 is not set -# CONFIG_DRIVER_PARADE_PS8625 is not set -# CONFIG_DRIVER_PARADE_PS8640 is not set -CONFIG_DRIVERS_MC146818=y -CONFIG_MAINBOARD_HAS_LPC_TPM=y -CONFIG_LPC_TPM=y -CONFIG_TPM_TIS_BASE_ADDRESS=0xfed40000 -# CONFIG_TPM_INIT_FAILURE_IS_FATAL is not set -# CONFIG_SKIP_TPM_STARTUP_ON_NORMAL_BOOT is not set -# CONFIG_TPM_DEACTIVATE is not set -CONFIG_VGA=y -CONFIG_DRIVERS_RICOH_RCE822=y -# CONFIG_DRIVER_SIEMENS_NC_FPGA is not set -# CONFIG_NC_FPGA_NOTIFY_CB_READY is not set -# CONFIG_DRIVERS_SIL_3114 is not set -# CONFIG_MAINBOARD_HAS_SPI_TPM_CR50 is not set -# CONFIG_DRIVER_TI_TPS65090 is not set -# CONFIG_DRIVERS_TI_TPS65913 is not set -# CONFIG_DRIVERS_TI_TPS65913_RTC is not set -# CONFIG_DRIVER_XPOWERS_AXP209 is not set -# CONFIG_COMMONLIB_STORAGE is not set - -# -# Security -# - -# -# Verified Boot (vboot) -# -CONFIG_ACPI_SATA_GENERATOR=y -CONFIG_ACPI_INTEL_HARDWARE_SLEEP_VALUES=y -# CONFIG_ACPI_AMD_HARDWARE_SLEEP_VALUES is not set -# CONFIG_BOOT_DEVICE_NOT_SPI_FLASH is not set -CONFIG_BOOT_DEVICE_SPI_FLASH=y -CONFIG_BOOT_DEVICE_MEMORY_MAPPED=y -# CONFIG_BOOT_DEVICE_SUPPORTS_WRITES is not set -CONFIG_RTC=y -CONFIG_TPM=y -# CONFIG_MAINBOARD_HAS_TPM_CR50 is not set - -# -# Console -# -CONFIG_SQUELCH_EARLY_SMP=y # CONFIG_CONSOLE_SERIAL is not set -# CONFIG_SPKMODEM is not set -# CONFIG_CONSOLE_NE2K is not set CONFIG_CONSOLE_CBMEM_BUFFER_SIZE=0x80000 -# CONFIG_CONSOLE_CBMEM_DUMP_TO_UART is not set -# CONFIG_CONSOLE_SPI_FLASH is not set -# CONFIG_DEFAULT_CONSOLE_LOGLEVEL_8 is not set -# CONFIG_DEFAULT_CONSOLE_LOGLEVEL_7 is not set -# CONFIG_DEFAULT_CONSOLE_LOGLEVEL_6 is not set CONFIG_DEFAULT_CONSOLE_LOGLEVEL_5=y -# CONFIG_DEFAULT_CONSOLE_LOGLEVEL_4 is not set -# CONFIG_DEFAULT_CONSOLE_LOGLEVEL_3 is not set -# CONFIG_DEFAULT_CONSOLE_LOGLEVEL_2 is not set -# CONFIG_DEFAULT_CONSOLE_LOGLEVEL_1 is not set -# CONFIG_DEFAULT_CONSOLE_LOGLEVEL_0 is not set -# CONFIG_CMOS_POST is not set -# CONFIG_CONSOLE_POST is not set -# CONFIG_NO_EARLY_BOOTBLOCK_POSTCODES is not set -# CONFIG_HWBASE_DEBUG_CB is not set -CONFIG_HWBASE_DEBUG_NULL=y -CONFIG_HAVE_ACPI_RESUME=y -# CONFIG_ACPI_HUGE_LOWMEM_BACKUP is not set -CONFIG_RESUME_PATH_SAME_AS_BOOT=y -CONFIG_HAVE_HARD_RESET=y -# CONFIG_HAVE_ROMSTAGE_CONSOLE_SPINLOCK is not set -# CONFIG_HAVE_ROMSTAGE_NVRAM_CBFS_SPINLOCK is not set -# CONFIG_HAVE_ROMSTAGE_MICROCODE_CBFS_SPINLOCK is not set -CONFIG_HAVE_MONOTONIC_TIMER=y -# CONFIG_GENERIC_UDELAY is not set -# CONFIG_TIMER_QUEUE is not set -CONFIG_HAVE_OPTION_TABLE=y -# CONFIG_PIRQ_ROUTE is not set -CONFIG_HAVE_SMI_HANDLER=y -# CONFIG_PCI_IO_CFG_EXT is not set -CONFIG_IOAPIC=y -CONFIG_USE_WATCHDOG_ON_BOOT=y -# CONFIG_GFXUMA is not set -CONFIG_HAVE_ACPI_TABLES=y -CONFIG_COMMON_FADT=y -# CONFIG_ACPI_NHLT is not set - -# -# System tables -# -# CONFIG_GENERATE_MP_TABLE is not set -# CONFIG_GENERATE_PIRQ_TABLE is not set -CONFIG_GENERATE_SMBIOS_TABLES=y - -# -# Payload -# -# CONFIG_PAYLOAD_NONE is not set -# CONFIG_PAYLOAD_ELF is not set -# CONFIG_PAYLOAD_BAYOU is not set -# CONFIG_PAYLOAD_FILO is not set -# CONFIG_PAYLOAD_GRUB2 is not set -# CONFIG_PAYLOAD_SEABIOS is not set -# CONFIG_PAYLOAD_UBOOT is not set CONFIG_PAYLOAD_LINUX=y -# CONFIG_PAYLOAD_TIANOCORE is not set CONFIG_PAYLOAD_FILE="../../build/x230/bzImage" -CONFIG_PAYLOAD_OPTIONS="" -# CONFIG_PXE is not set CONFIG_LINUX_COMMAND_LINE="quiet" CONFIG_LINUX_INITRD="../../build/x230/initrd.cpio.xz" -# CONFIG_PAYLOAD_IS_FLAT_BINARY is not set - -# -# Secondary Payloads -# -# CONFIG_COREINFO_SECONDARY_PAYLOAD is not set -# CONFIG_MEMTEST_SECONDARY_PAYLOAD is not set -# CONFIG_NVRAMCUI_SECONDARY_PAYLOAD is not set -# CONFIG_TINT_SECONDARY_PAYLOAD is not set - -# -# Debugging -# -# CONFIG_FATAL_ASSERTS is not set -# CONFIG_DEBUG_CBFS is not set -CONFIG_HAVE_DEBUG_RAM_SETUP=y -# CONFIG_DEBUG_RAM_SETUP is not set -# CONFIG_HAVE_DEBUG_CAR is not set -CONFIG_HAVE_DEBUG_SMBUS=y -# CONFIG_DEBUG_SMBUS is not set -# CONFIG_DEBUG_SMI is not set CONFIG_DEBUG_SMM_RELOCATION=y -# CONFIG_DEBUG_MALLOC is not set -# CONFIG_DEBUG_ACPI is not set -# CONFIG_DEBUG_TPM is not set -# CONFIG_DEBUG_SPI_FLASH is not set -# CONFIG_TRACE is not set -# CONFIG_DEBUG_BOOT_STATE is not set -# CONFIG_DEBUG_ADA_CODE is not set -# CONFIG_ENABLE_APIC_EXT_ID is not set -CONFIG_WARNINGS_ARE_ERRORS=y -# CONFIG_POWER_BUTTON_DEFAULT_ENABLE is not set -# CONFIG_POWER_BUTTON_DEFAULT_DISABLE is not set -# CONFIG_POWER_BUTTON_FORCE_ENABLE is not set -# CONFIG_POWER_BUTTON_FORCE_DISABLE is not set -# CONFIG_POWER_BUTTON_IS_OPTIONAL is not set -# CONFIG_REG_SCRIPT is not set -# CONFIG_CREATE_BOARD_CHECKLIST is not set -# CONFIG_MAKE_CHECKLIST_PUBLIC is not set -# CONFIG_NO_XIP_EARLY_STAGES is not set -CONFIG_EARLY_CBMEM_INIT=y -# CONFIG_EARLY_CBMEM_LIST is not set -CONFIG_RELOCATABLE_MODULES=y -CONFIG_BOOTBLOCK_CUSTOM=y diff --git a/modules/coreboot b/modules/coreboot index d785abbc..7081fe08 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.7 +coreboot_version := 4.8.1 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 := d68a83f8f687e8ea212b8c5bb501e24444b57c3f73896042d09628188c851368 +coreboot_hash := f0ddf4db0628c1fe1e8348c40084d9cbeb5771400c963fd419cda3995b69ad23 # Coreboot builds are specialized on a per-target basis. # The builds are done in a per-target subdirectory @@ -19,18 +19,20 @@ $(build)/$(coreboot_dir)/.configured: $(CONFIG_COREBOOT_CONFIG) EXTRA_FLAGS := -fdebug-prefix-map=$(pwd)=heads -gno-record-gcc-switches coreboot_configure := \ - $(MAKE) -C $(build)/$(coreboot_base_dir) \ - oldconfig \ - obj=$(build)/$(coreboot_dir) \ - DOTCONFIG=../../$(CONFIG_COREBOOT_CONFIG) \ + mkdir -p "$(build)/$(coreboot_dir)" \ + && cp "$(pwd)/$(CONFIG_COREBOOT_CONFIG)" "$(build)/$(coreboot_dir)/.config" \ + && $(MAKE) olddefconfig \ + -C "$(build)/$(coreboot_base_dir)" \ + obj="$(build)/$(coreboot_dir)" \ + DOTCONFIG="$(build)/$(coreboot_dir)/.config" \ BUILD_TIMELESS=1 \ CFLAGS_x86_32="$(EXTRA_FLAGS)" \ CFLAGS_x86_64="$(EXTRA_FLAGS)" \ coreboot_target := \ - -C $(build)/$(coreboot_base_dir) \ - obj=$(build)/$(coreboot_dir) \ - DOTCONFIG=../../$(CONFIG_COREBOOT_CONFIG) \ + -C "$(build)/$(coreboot_base_dir)" \ + obj="$(build)/$(coreboot_dir)" \ + DOTCONFIG="$(build)/$(coreboot_dir)/.config" \ BUILD_TIMELESS=1 \ CFLAGS_x86_32="$(EXTRA_FLAGS)" \ CFLAGS_x86_64="$(EXTRA_FLAGS)" \ @@ -64,9 +66,18 @@ $(build)/$(BOARD)/coreboot.rom: $(build)/$(coreboot_dir)/.build coreboot.menuconfig: $(MAKE) \ -C "$(build)/$(coreboot_base_dir)" \ - DOTCONFIG="../../$(CONFIG_COREBOOT_CONFIG)" \ + DOTCONFIG="$(build)/$(coreboot_dir)/.config" \ menuconfig +# The config file in the repo is stored as a "defconfig" format +# which only includes the options that have changed from the defaults. +coreboot.saveconfig: + $(MAKE) \ + -C "$(build)/$(coreboot_base_dir)" \ + DOTCONFIG="$(build)/$(coreboot_dir)/.config" \ + DEFCONFIG="$(pwd)/$(CONFIG_COREBOOT_CONFIG)" \ + savedefconfig + # if we are not building from a git checkout, # we must also download the coreboot-blobs tree @@ -79,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 := 443379a2207e350747cbbfe7968ceafddc7dd8563b067476f755ff11791bb5f5 +coreboot-blobs_hash := 18aa509ae3af005a05d7b1e0b0246dc640249c14fc828f5144b6fd20bb10e295 ## there is nothing to build for the blobs, this should be ## made easier to make happen diff --git a/modules/lvm2 b/modules/lvm2 index ed7a0866..91f0f53f 100644 --- a/modules/lvm2 +++ b/modules/lvm2 @@ -29,6 +29,8 @@ lvm2_configure := \ --disable-use-lvmpolld \ --disable-blkid_wiping \ --disable-cmirrord \ + --disable-cache_check_needs_check \ + --disable-thin_check_needs_check \ --with-cluster=none \ # not sure why LIB_SUFFIX is not defined in the cross build diff --git a/modules/slang b/modules/slang index 69226390..a4ac84bc 100644 --- a/modules/slang +++ b/modules/slang @@ -8,8 +8,10 @@ slang_hash := 54f0c3007fde918039c058965dffdfd6c5aec0bad0f4227192cc486021f08c36 slang_configure := ./configure \ $(CROSS_TOOLS) \ + ac_cv_path_nc5config=no \ --prefix "/" \ --host i386-elf-linux \ + --with-z=no \ --with-png=no \ --with-pcre=no \ --with-onig=no \ diff --git a/patches/coreboot-4.7/0001-intel-fsp-Fix-TPM-initialization-when-vboot-is-disab.patch b/patches/coreboot-4.7/0001-intel-fsp-Fix-TPM-initialization-when-vboot-is-disab.patch deleted file mode 100644 index ac34a737..00000000 --- a/patches/coreboot-4.7/0001-intel-fsp-Fix-TPM-initialization-when-vboot-is-disab.patch +++ /dev/null @@ -1,72 +0,0 @@ -From feb246c6e8a87c1223c84b4b74f976d23506bb96 Mon Sep 17 00:00:00 2001 -From: Youness Alaoui -Date: Wed, 7 Feb 2018 11:49:35 -0500 -Subject: [PATCH 1/9] intel/fsp: Fix TPM initialization when vboot is disabled - -A change introduced by commit fe4983e5 [1] in order to prevent -re-initialization of the TPM if already setup in verstage -had the wrong logic in the if statement, causing the TPM -to never be initialized if vboot is disabled. - -The RESUME_PATH_SAME_AS_BOOT config is enabled by default for -ARCH_X86 and therefore the if statement would be false. The -behavior that was intended was probably meant to use an OR -instead of an AND. - -This patch also enabled TPM initialization for FSP 2.0. - -[1] https://review.coreboot.org/#/c/coreboot/+/14106/ - -Change-Id: Ic43d1aa31a296386c7eab6d997f9b701e9ea0fe5 -Signed-off-by: Youness Alaoui ---- - src/drivers/intel/fsp1_1/romstage.c | 4 ++-- - src/drivers/intel/fsp2_0/memory_init.c | 10 ++++++++++ - 2 files changed, 12 insertions(+), 2 deletions(-) - -diff --git a/src/drivers/intel/fsp1_1/romstage.c b/src/drivers/intel/fsp1_1/romstage.c -index 81939c4c33..76b4ad7c4d 100644 ---- a/src/drivers/intel/fsp1_1/romstage.c -+++ b/src/drivers/intel/fsp1_1/romstage.c -@@ -172,8 +172,8 @@ void romstage_common(struct romstage_params *params) - * in verstage and used to verify romstage. - */ - if (IS_ENABLED(CONFIG_LPC_TPM) && -- !IS_ENABLED(CONFIG_RESUME_PATH_SAME_AS_BOOT) && -- !IS_ENABLED(CONFIG_VBOOT_STARTS_IN_BOOTBLOCK)) -+ (!IS_ENABLED(CONFIG_RESUME_PATH_SAME_AS_BOOT) || -+ !IS_ENABLED(CONFIG_VBOOT_STARTS_IN_BOOTBLOCK))) - init_tpm(params->power_state->prev_sleep_state == - ACPI_S3); - } -diff --git a/src/drivers/intel/fsp2_0/memory_init.c b/src/drivers/intel/fsp2_0/memory_init.c -index 368fafa5d7..575f277466 100644 ---- a/src/drivers/intel/fsp2_0/memory_init.c -+++ b/src/drivers/intel/fsp2_0/memory_init.c -@@ -28,6 +28,7 @@ - #include - #include - #include -+#include - #include - #include - #include -@@ -146,6 +147,15 @@ static void do_fsp_post_memory_init(bool s3wake, uint32_t fsp_version) - - /* Create romstage handof information */ - romstage_handoff_init(s3wake); -+ -+ /* -+ * Initialize the TPM, unless the TPM was already initialized -+ * in verstage and used to verify romstage. -+ */ -+ if (IS_ENABLED(CONFIG_LPC_TPM) && -+ (!IS_ENABLED(CONFIG_RESUME_PATH_SAME_AS_BOOT) || -+ !IS_ENABLED(CONFIG_VBOOT_STARTS_IN_BOOTBLOCK))) -+ init_tpm(s3wake); - } - - static int mrc_cache_verify_tpm_hash(const uint8_t *data, size_t size) --- -2.14.3 - diff --git a/patches/coreboot-4.7/0003-soc-intel-skylake-Enable-VT-d-and-X2APIC.patch b/patches/coreboot-4.7/0003-soc-intel-skylake-Enable-VT-d-and-X2APIC.patch deleted file mode 100644 index 6cc0303a..00000000 --- a/patches/coreboot-4.7/0003-soc-intel-skylake-Enable-VT-d-and-X2APIC.patch +++ /dev/null @@ -1,173 +0,0 @@ -From 403242fbaf2c3b8c12f4b1d55a581513aabf02a3 Mon Sep 17 00:00:00 2001 -From: Nico Huber -Date: Tue, 19 Sep 2017 09:36:03 +0200 -Subject: [PATCH 3/9] soc/intel/skylake: Enable VT-d and X2APIC - -We use the usual static addresses 0xfed90000/0xfed91000 for the GFX -IOMMU and the general IOMMU respectively. These addresses have to be -configured in MCHBAR registers (maybe, who knows, the blob is undocu- -mented), advertised to FSP and reserved from the OS. - -Change-Id: I77f87c385736615c127143760bbd144f97986b37 -Signed-off-by: Nico Huber ---- - src/soc/intel/skylake/chip_fsp20.c | 10 ++++++++++ - src/soc/intel/skylake/include/soc/iomap.h | 6 ++++++ - src/soc/intel/skylake/include/soc/systemagent.h | 11 +++++++++++ - src/soc/intel/skylake/romstage/systemagent.c | 8 ++++++++ - src/soc/intel/skylake/systemagent.c | 13 +++++++++++++ - 5 files changed, 48 insertions(+) - -diff --git a/src/soc/intel/skylake/chip_fsp20.c b/src/soc/intel/skylake/chip_fsp20.c -index ccda3032c5..875542c9c6 100644 ---- a/src/soc/intel/skylake/chip_fsp20.c -+++ b/src/soc/intel/skylake/chip_fsp20.c -@@ -30,9 +30,11 @@ - #include - #include - #include -+#include - #include - #include - #include -+#include - #include - - void soc_init_pre_device(void *chip_info) -@@ -313,6 +315,14 @@ void platform_fsp_silicon_init_params_cb(FSPS_UPD *supd) - /* Set TccActivationOffset */ - tconfig->TccActivationOffset = config->tcc_offset; - -+ /* Enable VT-d and X2APIC */ -+ if (soc_is_vtd_capable()) { -+ params->VtdBaseAddress[0] = GFXVT_BASE_ADDRESS; -+ params->VtdBaseAddress[1] = VTVC0_BASE_ADDRESS; -+ params->X2ApicOptOut = 0; -+ tconfig->VtdDisable = 0; -+ } -+ - soc_irq_settings(params); - } - -diff --git a/src/soc/intel/skylake/include/soc/iomap.h b/src/soc/intel/skylake/include/soc/iomap.h -index 0a573acb38..5f868061ec 100644 ---- a/src/soc/intel/skylake/include/soc/iomap.h -+++ b/src/soc/intel/skylake/include/soc/iomap.h -@@ -52,6 +52,12 @@ - #define GDXC_BASE_ADDRESS 0xfed84000 - #define GDXC_BASE_SIZE 0x1000 - -+#define GFXVT_BASE_ADDRESS 0xfed90000 -+#define GFXVT_BASE_SIZE 0x1000 -+ -+#define VTVC0_BASE_ADDRESS 0xfed91000 -+#define VTVC0_BASE_SIZE 0x1000 -+ - #define HPET_BASE_ADDRESS 0xfed00000 - - #define PCH_PWRM_BASE_ADDRESS 0xfe000000 -diff --git a/src/soc/intel/skylake/include/soc/systemagent.h b/src/soc/intel/skylake/include/soc/systemagent.h -index d8192a3e75..8e53f54b75 100644 ---- a/src/soc/intel/skylake/include/soc/systemagent.h -+++ b/src/soc/intel/skylake/include/soc/systemagent.h -@@ -32,9 +32,13 @@ - #define D_LCK (1 << 4) - #define G_SMRAME (1 << 3) - #define C_BASE_SEG ((0 << 2) | (1 << 1) | (0 << 0)) -+#define CAPID0_A 0xe4 -+#define VTD_DISABLE (1 << 23) - - #define BIOS_RESET_CPL 0x5da8 -+#define GFXVTBAR 0x5400 - #define EDRAMBAR 0x5408 -+#define VTVC0BAR 0x5410 - #define GDXCBAR 0x5420 - - #define MCH_PKG_POWER_LIMIT_LO 0x59a0 -@@ -42,4 +46,11 @@ - #define MCH_DDR_POWER_LIMIT_LO 0x58e0 - #define MCH_DDR_POWER_LIMIT_HI 0x58e4 - -+bool soc_is_vtd_capable(void); -+ -+static const struct sa_mmio_descriptor soc_vtd_resources[] = { -+ { GFXVTBAR, GFXVT_BASE_ADDRESS, GFXVT_BASE_SIZE, "GFXVTBAR" }, -+ { VTVC0BAR, VTVC0_BASE_ADDRESS, VTVC0_BASE_SIZE, "VTVC0BAR" }, -+}; -+ - #endif -diff --git a/src/soc/intel/skylake/romstage/systemagent.c b/src/soc/intel/skylake/romstage/systemagent.c -index 8f2fb337ed..66676c1fbf 100644 ---- a/src/soc/intel/skylake/romstage/systemagent.c -+++ b/src/soc/intel/skylake/romstage/systemagent.c -@@ -18,6 +18,7 @@ - #include - #include - #include -+#include - #include - #include - -@@ -34,12 +35,19 @@ void systemagent_early_init(void) - { EDRAMBAR, EDRAM_BASE_ADDRESS, EDRAM_BASE_SIZE, "EDRAMBAR" }, - }; - -+ const bool vtd_capable = -+ !(pci_read_config32(SA_DEV_ROOT, CAPID0_A) & VTD_DISABLE); -+ - /* Set Fixed MMIO addresss into PCI configuration space */ - sa_set_pci_bar(soc_fixed_pci_resources, - ARRAY_SIZE(soc_fixed_pci_resources)); - /* Set Fixed MMIO addresss into MCH base address */ - sa_set_mch_bar(soc_fixed_mch_resources, - ARRAY_SIZE(soc_fixed_mch_resources)); -+ if (vtd_capable) -+ sa_set_mch_bar(soc_vtd_resources, -+ ARRAY_SIZE(soc_vtd_resources)); -+ - /* Enable PAM regisers */ - enable_pam_region(); - } -diff --git a/src/soc/intel/skylake/systemagent.c b/src/soc/intel/skylake/systemagent.c -index 8af995d133..796e7ae131 100644 ---- a/src/soc/intel/skylake/systemagent.c -+++ b/src/soc/intel/skylake/systemagent.c -@@ -15,6 +15,7 @@ - * GNU General Public License for more details. - */ - -+#include - #include - #include - #include -@@ -23,8 +24,16 @@ - #include - #include - #include -+#include - #include - -+bool soc_is_vtd_capable(void) -+{ -+ struct device *const root_dev = SA_DEV_ROOT; -+ return root_dev && -+ !(pci_read_config32(root_dev, CAPID0_A) & VTD_DISABLE); -+} -+ - /* - * SoC implementation - * -@@ -45,6 +54,10 @@ void soc_add_fixed_mmio_resources(struct device *dev, int *index) - - sa_add_fixed_mmio_resources(dev, index, soc_fixed_resources, - ARRAY_SIZE(soc_fixed_resources)); -+ -+ if (soc_is_vtd_capable()) -+ sa_add_fixed_mmio_resources(dev, index, soc_vtd_resources, -+ ARRAY_SIZE(soc_vtd_resources)); - } - - /* --- -2.14.3 - diff --git a/patches/coreboot-4.7/0004-soc-intel-skylake-Generate-ACPI-DMAR-table.patch b/patches/coreboot-4.7/0004-soc-intel-skylake-Generate-ACPI-DMAR-table.patch deleted file mode 100644 index 9b6d6e19..00000000 --- a/patches/coreboot-4.7/0004-soc-intel-skylake-Generate-ACPI-DMAR-table.patch +++ /dev/null @@ -1,154 +0,0 @@ -From 65b3bf5a7d211f7e1e37d73d0b59ed053dff85a8 Mon Sep 17 00:00:00 2001 -From: Nico Huber -Date: Mon, 18 Sep 2017 20:03:46 +0200 -Subject: [PATCH 4/9] soc/intel/skylake: Generate ACPI DMAR table - -If the SoC is VT-d capable, write an ACPI DMAR table. The entry for the -GFXVTBAR is only generated if the IGD is enabled. - -Change-Id: I8176401dd19aee7ad09a8a145b7a3801fe5b2ae1 -Signed-off-by: Nico Huber ---- - src/soc/intel/skylake/acpi.c | 68 ++++++++++++++++++++++++++++++++ - src/soc/intel/skylake/chip_fsp20.c | 3 +- - src/soc/intel/skylake/include/soc/acpi.h | 2 + - src/soc/intel/skylake/include/soc/p2sb.h | 3 ++ - 4 files changed, 75 insertions(+), 1 deletion(-) - -diff --git a/src/soc/intel/skylake/acpi.c b/src/soc/intel/skylake/acpi.c -index 61360dafae..45061aba6f 100644 ---- a/src/soc/intel/skylake/acpi.c -+++ b/src/soc/intel/skylake/acpi.c -@@ -34,14 +34,17 @@ - #include - #include - #include -+#include - #include - #include - #include - #include - #include -+#include - #include - #include - #include -+#include - #include - #include - #include -@@ -539,6 +542,71 @@ void generate_cpu_entries(device_t device) - } - } - -+static unsigned long acpi_fill_dmar(unsigned long current) -+{ -+ struct device *const igfx_dev = dev_find_slot(0, SA_DEVFN_IGD); -+ const u32 gfx_vtbar = MCHBAR32(GFXVTBAR) & ~0xfff; -+ -+ /* iGFX has to be enabled, GFXVTBAR set and in 32-bit space. */ -+ if (igfx_dev && igfx_dev->enabled && -+ gfx_vtbar && !MCHBAR32(GFXVTBAR + 4)) { -+ const unsigned long tmp = current; -+ -+ current += acpi_create_dmar_drhd(current, 0, 0, gfx_vtbar); -+ current += acpi_create_dmar_drhd_ds_pci(current, 0, 2, 0); -+ -+ acpi_dmar_drhd_fixup(tmp, current); -+ } -+ -+ struct device *const p2sb_dev = dev_find_slot(0, PCH_DEVFN_P2SB); -+ const u32 vtvc0bar = MCHBAR32(VTVC0BAR) & ~0xfff; -+ -+ /* General VTBAR has to be set and in 32-bit space. */ -+ if (p2sb_dev && vtvc0bar && !MCHBAR32(VTVC0BAR + 4)) { -+ const unsigned long tmp = current; -+ -+ /* P2SB may already be hidden. There's no clear rule, when. */ -+ const u8 p2sb_hidden = -+ pci_read_config8(p2sb_dev, PCH_P2SB_E0 + 1); -+ pci_write_config8(p2sb_dev, PCH_P2SB_E0 + 1, 0); -+ -+ const u16 ibdf = pci_read_config16(p2sb_dev, PCH_P2SB_IBDF); -+ const u16 hbdf = pci_read_config16(p2sb_dev, PCH_P2SB_HBDF); -+ -+ pci_write_config8(p2sb_dev, PCH_P2SB_E0 + 1, p2sb_hidden); -+ -+ current += acpi_create_dmar_drhd(current, -+ DRHD_INCLUDE_PCI_ALL, 0, vtvc0bar); -+ current += acpi_create_dmar_drhd_ds_ioapic(current, -+ 2, ibdf >> 8, PCI_SLOT(ibdf), PCI_FUNC(ibdf)); -+ current += acpi_create_dmar_drhd_ds_msi_hpet(current, -+ 0, hbdf >> 8, PCI_SLOT(hbdf), PCI_FUNC(hbdf)); -+ -+ acpi_dmar_drhd_fixup(tmp, current); -+ } -+ -+ return current; -+} -+ -+unsigned long northbridge_write_acpi_tables(struct device *const dev, -+ unsigned long current, -+ struct acpi_rsdp *const rsdp) -+{ -+ acpi_dmar_t *const dmar = (acpi_dmar_t *)current; -+ -+ /* Create DMAR table only if we have VT-d capability. */ -+ if (!soc_is_vtd_capable()) -+ return current; -+ -+ printk(BIOS_DEBUG, "ACPI: * DMAR\n"); -+ acpi_create_dmar(dmar, DMAR_INTR_REMAP, acpi_fill_dmar); -+ current += dmar->header.length; -+ current = acpi_align_current(current); -+ acpi_add_table(rsdp, dmar); -+ -+ return current; -+} -+ - unsigned long acpi_madt_irq_overrides(unsigned long current) - { - int sci = acpi_sci_irq(); -diff --git a/src/soc/intel/skylake/chip_fsp20.c b/src/soc/intel/skylake/chip_fsp20.c -index 875542c9c6..9fbc3da8dc 100644 ---- a/src/soc/intel/skylake/chip_fsp20.c -+++ b/src/soc/intel/skylake/chip_fsp20.c -@@ -59,7 +59,8 @@ static struct device_operations pci_domain_ops = { - .scan_bus = &pci_domain_scan_bus, - .ops_pci_bus = &pci_bus_default_ops, - #if IS_ENABLED(CONFIG_HAVE_ACPI_TABLES) -- .acpi_name = &soc_acpi_name, -+ .write_acpi_tables = &northbridge_write_acpi_tables, -+ .acpi_name = &soc_acpi_name, - #endif - }; - -diff --git a/src/soc/intel/skylake/include/soc/acpi.h b/src/soc/intel/skylake/include/soc/acpi.h -index b0d2194612..6d492acd67 100644 ---- a/src/soc/intel/skylake/include/soc/acpi.h -+++ b/src/soc/intel/skylake/include/soc/acpi.h -@@ -32,5 +32,7 @@ void acpi_mainboard_gnvs(global_nvs_t *gnvs); - void southbridge_inject_dsdt(device_t device); - unsigned long southbridge_write_acpi_tables(device_t device, - unsigned long current, struct acpi_rsdp *rsdp); -+unsigned long northbridge_write_acpi_tables(struct device *, -+ unsigned long current, struct acpi_rsdp *); - - #endif /* _SOC_ACPI_H_ */ -diff --git a/src/soc/intel/skylake/include/soc/p2sb.h b/src/soc/intel/skylake/include/soc/p2sb.h -index d846dfc8f5..09e73fc254 100644 ---- a/src/soc/intel/skylake/include/soc/p2sb.h -+++ b/src/soc/intel/skylake/include/soc/p2sb.h -@@ -19,6 +19,9 @@ - #define HPTC_OFFSET 0x60 - #define HPTC_ADDR_ENABLE_BIT (1 << 7) - -+#define PCH_P2SB_IBDF 0x6c -+#define PCH_P2SB_HBDF 0x70 -+ - #define PCH_P2SB_EPMASK0 0xB0 - #define PCH_P2SB_EPMASK(mask_number) (PCH_P2SB_EPMASK0 + ((mask_number) * 4)) - --- -2.14.3 - diff --git a/patches/coreboot-4.7/0005-purism-librem_skl-Enable-TPM-support.patch b/patches/coreboot-4.7/0005-purism-librem_skl-Enable-TPM-support.patch deleted file mode 100644 index 37c1ed08..00000000 --- a/patches/coreboot-4.7/0005-purism-librem_skl-Enable-TPM-support.patch +++ /dev/null @@ -1,341 +0,0 @@ -From c142a773852b8bbfddc3791248b8365242df4f4c Mon Sep 17 00:00:00 2001 -From: Youness Alaoui -Date: Fri, 9 Feb 2018 18:42:49 -0500 -Subject: [PATCH 5/9] purism/librem_skl: Enable TPM support - -Change the GPIO to match the TPM-enabled motherboards, and add TPM -support in devicetree and enable the config. -After changing the GPIO table, the librem 13v2 and librem 15v3 now -have the same GPIOs, so use a single gpio.h file instead of one -file per variant. - -Change-Id: I425654c1c972118aa81c27961246238c2eef782d -Signed-off-by: Youness Alaoui ---- - src/mainboard/purism/librem_skl/Kconfig | 1 + - src/mainboard/purism/librem_skl/Makefile.inc | 1 - - .../librem13v2/include/variant => }/gpio.h | 16 +- - src/mainboard/purism/librem_skl/ramstage.c | 2 +- - .../librem_skl/variants/librem13v2/devicetree.cb | 3 + - .../librem_skl/variants/librem15v3/devicetree.cb | 3 + - .../variants/librem15v3/include/variant/gpio.h | 201 --------------------- - 7 files changed, 16 insertions(+), 211 deletions(-) - rename src/mainboard/purism/librem_skl/{variants/librem13v2/include/variant => }/gpio.h (94%) - delete mode 100644 src/mainboard/purism/librem_skl/variants/librem15v3/include/variant/gpio.h - -diff --git a/src/mainboard/purism/librem_skl/Kconfig b/src/mainboard/purism/librem_skl/Kconfig -index f68fd239f9..be4b7a37c7 100644 ---- a/src/mainboard/purism/librem_skl/Kconfig -+++ b/src/mainboard/purism/librem_skl/Kconfig -@@ -9,6 +9,7 @@ config BOARD_PURISM_BASEBOARD_LIBREM_SKL - select SERIRQ_CONTINUOUS_MODE - select MAINBOARD_USES_FSP2_0 - select SPD_READ_BY_WORD -+ select MAINBOARD_HAS_LPC_TPM - - if BOARD_PURISM_BASEBOARD_LIBREM_SKL - -diff --git a/src/mainboard/purism/librem_skl/Makefile.inc b/src/mainboard/purism/librem_skl/Makefile.inc -index 18c9ad6520..eb01360863 100644 ---- a/src/mainboard/purism/librem_skl/Makefile.inc -+++ b/src/mainboard/purism/librem_skl/Makefile.inc -@@ -19,4 +19,3 @@ ramstage-y += pei_data.c - ramstage-y += ramstage.c - ramstage-y += hda_verb.c - --CPPFLAGS_common += -I$(src)/mainboard/$(MAINBOARDDIR)/variants/$(VARIANT_DIR)/include -diff --git a/src/mainboard/purism/librem_skl/variants/librem13v2/include/variant/gpio.h b/src/mainboard/purism/librem_skl/gpio.h -similarity index 94% -rename from src/mainboard/purism/librem_skl/variants/librem13v2/include/variant/gpio.h -rename to src/mainboard/purism/librem_skl/gpio.h -index 148e40b279..e3328a3336 100644 ---- a/src/mainboard/purism/librem_skl/variants/librem13v2/include/variant/gpio.h -+++ b/src/mainboard/purism/librem_skl/gpio.h -@@ -41,9 +41,9 @@ static const struct pad_config gpio_table[] = { - /* SUSACK# */ PAD_CFG_NF(GPP_A15, DN_20K, DEEP, NF1), - /* SD_1P8_SEL */ PAD_CFG_NC(GPP_A16), - /* SD_PWR_EN# */ PAD_CFG_NF(GPP_A17, NONE, DEEP, NF1), --/* ISH_GP0 */ PAD_CFG_NC(GPP_A18), --/* ISH_GP1 */ PAD_CFG_NC(GPP_A19), --/* ISH_GP2 */ PAD_CFG_NC(GPP_A20), -+/* ISH_GP0 */ PAD_CFG_GPI_GPIO_DRIVER(GPP_A18, NONE, DEEP), -+/* ISH_GP1 */ PAD_CFG_GPI_GPIO_DRIVER(GPP_A19, NONE, DEEP), -+/* ISH_GP2 */ PAD_CFG_GPI_GPIO_DRIVER(GPP_A20, NONE, DEEP), - /* ISH_GP3 */ PAD_CFG_NC(GPP_A21), - /* ISH_GP4 */ PAD_CFG_NC(GPP_A22), - /* ISH_GP5 */ PAD_CFG_NC(GPP_A23), -@@ -108,18 +108,18 @@ static const struct pad_config gpio_table[] = { - /* ISH_I2C0_SCL */ PAD_CFG_NC(GPP_D6), - /* ISH_I2C1_SDA */ PAD_CFG_NC(GPP_D7), - /* ISH_I2C1_SCL */ PAD_CFG_NC(GPP_D8), --/* ISH_SPI_CS# */ PAD_CFG_NC(GPP_D9), --/* ISH_SPI_CLK */ PAD_CFG_NC(GPP_D10), --/* ISH_SPI_MISO */ PAD_CFG_NC(GPP_D11), -+/* ISH_SPI_CS# */ PAD_CFG_TERM_GPO(GPP_D9, 0, NONE, DEEP), -+/* ISH_SPI_CLK */ PAD_CFG_GPI_GPIO_DRIVER(GPP_D10, NONE, DEEP), -+/* ISH_SPI_MISO */ PAD_CFG_TERM_GPO(GPP_D11, 1, NONE, DEEP), - /* ISH_SPI_MOSI */ PAD_CFG_NC(GPP_D12), - /* ISH_UART0_RXD */ PAD_CFG_NC(GPP_D13), - /* ISH_UART0_TXD */ PAD_CFG_NC(GPP_D14), - /* ISH_UART0_RTS# */ PAD_CFG_NC(GPP_D15), - /* ISH_UART0_CTS# */ PAD_CFG_NC(GPP_D16), - /* DMIC_CLK1 */ PAD_CFG_NF(GPP_D17, NONE, DEEP, NF1), --/* DMIC_DATA1 */ PAD_CFG_NF(GPP_D18, NONE, DEEP, NF1), -+/* DMIC_DATA1 */ PAD_CFG_NF(GPP_D18, DN_20K, DEEP, NF1), - /* DMIC_CLK0 */ PAD_CFG_NF(GPP_D19, NONE, DEEP, NF1), --/* DMIC_DATA0 */ PAD_CFG_NF(GPP_D20, NONE, DEEP, NF1), -+/* DMIC_DATA0 */ PAD_CFG_NF(GPP_D20, DN_20K, DEEP, NF1), - /* SPI1_IO2 */ PAD_CFG_NC(GPP_D21), - /* SPI1_IO3 */ PAD_CFG_NC(GPP_D22), - /* I2S_MCLK */ PAD_CFG_NC(GPP_D23), -diff --git a/src/mainboard/purism/librem_skl/ramstage.c b/src/mainboard/purism/librem_skl/ramstage.c -index 15912cf862..94f8071340 100644 ---- a/src/mainboard/purism/librem_skl/ramstage.c -+++ b/src/mainboard/purism/librem_skl/ramstage.c -@@ -15,7 +15,7 @@ - */ - - #include --#include -+#include "gpio.h" - - void mainboard_silicon_init_params(FSP_SIL_UPD *params) - { -diff --git a/src/mainboard/purism/librem_skl/variants/librem13v2/devicetree.cb b/src/mainboard/purism/librem_skl/variants/librem13v2/devicetree.cb -index 1fc19a5675..e2e2ac03da 100644 ---- a/src/mainboard/purism/librem_skl/variants/librem13v2/devicetree.cb -+++ b/src/mainboard/purism/librem_skl/variants/librem13v2/devicetree.cb -@@ -195,6 +195,9 @@ chip soc/intel/skylake - chip ec/purism/librem - device pnp 0c09.0 on end - end -+ chip drivers/pc80/tpm -+ device pnp 0c31.0 on end -+ end - end # LPC Interface - device pci 1f.1 on end # P2SB - device pci 1f.2 on end # Power Management Controller -diff --git a/src/mainboard/purism/librem_skl/variants/librem15v3/devicetree.cb b/src/mainboard/purism/librem_skl/variants/librem15v3/devicetree.cb -index 647f054f74..6cf183a61f 100644 ---- a/src/mainboard/purism/librem_skl/variants/librem15v3/devicetree.cb -+++ b/src/mainboard/purism/librem_skl/variants/librem15v3/devicetree.cb -@@ -202,6 +202,9 @@ chip soc/intel/skylake - chip ec/purism/librem - device pnp 0c09.0 on end - end -+ chip drivers/pc80/tpm -+ device pnp 0c31.0 on end -+ end - end # LPC Interface - device pci 1f.1 on end # P2SB - device pci 1f.2 on end # Power Management Controller -diff --git a/src/mainboard/purism/librem_skl/variants/librem15v3/include/variant/gpio.h b/src/mainboard/purism/librem_skl/variants/librem15v3/include/variant/gpio.h -deleted file mode 100644 -index 9c22f00f42..0000000000 ---- a/src/mainboard/purism/librem_skl/variants/librem15v3/include/variant/gpio.h -+++ /dev/null -@@ -1,201 +0,0 @@ --/* -- * This file is part of the coreboot project. -- * -- * Copyright (C) 2015 Google Inc. -- * -- * This program is free software; you can redistribute it and/or modify -- * it under the terms of the GNU General Public License as published by -- * the Free Software Foundation; version 2 of the License. -- * -- * This program is distributed in the hope that it will be useful, -- * but WITHOUT ANY WARRANTY; without even the implied warranty of -- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.See the -- * GNU General Public License for more details. -- */ -- --#ifndef MAINBOARD_GPIO_H --#define MAINBOARD_GPIO_H -- --#include --#include -- --#ifndef __ACPI__ -- --/* Pad configuration in ramstage. */ --static const struct pad_config gpio_table[] = { --/* RCIN# */ PAD_CFG_NF(GPP_A0, NONE, DEEP, NF1), --/* LAD0 */ PAD_CFG_NF(GPP_A1, NONE, DEEP, NF1), --/* LAD1 */ PAD_CFG_NF(GPP_A2, NONE, DEEP, NF1), --/* LAD2 */ PAD_CFG_NF(GPP_A3, NONE, DEEP, NF1), --/* LAD3 */ PAD_CFG_NF(GPP_A4, NONE, DEEP, NF1), --/* LFRAME# */ PAD_CFG_NF(GPP_A5, NONE, DEEP, NF1), --/* SERIRQ */ PAD_CFG_NF(GPP_A6, NONE, DEEP, NF1), --/* PIRQA# */ PAD_CFG_NC(GPP_A7), --/* CLKRUN# */ PAD_CFG_NF(GPP_A8, NONE, DEEP, NF1), --/* CLKOUT_LPC0 */ PAD_CFG_NF(GPP_A9, NONE, DEEP, NF1), --/* CLKOUT_LPC1 */ PAD_CFG_NF(GPP_A10, NONE, DEEP, NF1), --/* PME# */ PAD_CFG_NC(GPP_A11), --/* BM_BUSY# */ PAD_CFG_NC(GPP_A12), --/* SUSWARN# */ PAD_CFG_NF(GPP_A13, NONE, DEEP, NF1), --/* SUS_STAT# */ PAD_CFG_NF(GPP_A14, NONE, DEEP, NF1), --/* SUSACK# */ PAD_CFG_NF(GPP_A15, DN_20K, DEEP, NF1), --/* SD_1P8_SEL */ PAD_CFG_NC(GPP_A16), --/* SD_PWR_EN# */ PAD_CFG_NF(GPP_A17, NONE, DEEP, NF1), --/* ISH_GP0 */ PAD_CFG_GPI(GPP_A18, NONE, DEEP), --/* ISH_GP1 */ PAD_CFG_GPI(GPP_A19, NONE, DEEP), --/* ISH_GP2 */ PAD_CFG_GPI(GPP_A20, NONE, DEEP), --/* ISH_GP3 */ PAD_CFG_NC(GPP_A21), --/* ISH_GP4 */ PAD_CFG_NC(GPP_A22), --/* ISH_GP5 */ PAD_CFG_NC(GPP_A23), -- --/* CORE_VID0 */ PAD_CFG_NC(GPP_B0), --/* CORE_VID1 */ PAD_CFG_NC(GPP_B1), --/* VRALERT# */ PAD_CFG_NC(GPP_B2), --/* CPU_GP2 */ PAD_CFG_NC(GPP_B3), --/* CPU_GP3 */ PAD_CFG_NC(GPP_B4), --/* SRCCLKREQ0# */ PAD_CFG_NF(GPP_B5, NONE, DEEP, NF1), --/* SRCCLKREQ1# */ PAD_CFG_NF(GPP_B6, NONE, DEEP, NF1), --/* SRCCLKREQ2# */ PAD_CFG_NF(GPP_B7, NONE, DEEP, NF1), --/* SRCCLKREQ3# */ PAD_CFG_NF(GPP_B8, NONE, DEEP, NF1), --/* SRCCLKREQ4# */ PAD_CFG_NF(GPP_B9, NONE, DEEP, NF1), --/* SRCCLKREQ5# */ PAD_CFG_NF(GPP_B10, NONE, DEEP, NF1), --/* EXT_PWR_GATE# */ PAD_CFG_NC(GPP_B11), --/* SLP_S0# */ PAD_CFG_NF(GPP_B12, NONE, DEEP, NF1), --/* PLTRST# */ PAD_CFG_NF(GPP_B13, NONE, DEEP, NF1), --/* SPKR */ PAD_CFG_TERM_GPO(GPP_B14, 1, DN_20K, DEEP), --/* GSPI0_CS# */ PAD_CFG_NC(GPP_B15), --/* GSPI0_CLK */ PAD_CFG_NC(GPP_B16), --/* GSPI0_MISO */ PAD_CFG_NC(GPP_B17), --/* GSPI0_MOSI */ PAD_CFG_GPI_SCI(GPP_B18, UP_20K, PLTRST, LEVEL, INVERT), --/* GSPI1_CS# */ PAD_CFG_NC(GPP_B19), --/* GSPI1_CLK */ PAD_CFG_NC(GPP_B20), --/* GSPI1_MISO */ PAD_CFG_NC(GPP_B21), --/* GSPI1_MOSI */ PAD_CFG_NF(GPP_B22, DN_20K, DEEP, NF1), --/* SM1ALERT# */ PAD_CFG_TERM_GPO(GPP_B23, 1, DN_20K, DEEP), -- --/* SMBCLK */ PAD_CFG_NF(GPP_C0, NONE, DEEP, NF1), --/* SMBDATA */ PAD_CFG_NF(GPP_C1, DN_20K, DEEP, NF1), --/* SMBALERT# */ PAD_CFG_TERM_GPO(GPP_C2, 1, DN_20K, DEEP), --/* SML0CLK */ PAD_CFG_NF(GPP_C3, NONE, DEEP, NF1), --/* SML0DATA */ PAD_CFG_NF(GPP_C4, NONE, DEEP, NF1), --/* SML0ALERT# */ PAD_CFG_GPI_APIC_INVERT(GPP_C5, DN_20K, DEEP), --/* SML1CLK */ PAD_CFG_NC(GPP_C6), /* RESERVED */ --/* SML1DATA */ PAD_CFG_NC(GPP_C7), /* RESERVED */ --/* UART0_RXD */ PAD_CFG_NF(GPP_C8, NONE, DEEP, NF1), --/* UART0_TXD */ PAD_CFG_NF(GPP_C9, NONE, DEEP, NF1), --/* UART0_RTS# */ PAD_CFG_NF(GPP_C10, NONE, DEEP, NF1), --/* UART0_CTS# */ PAD_CFG_NF(GPP_C11, NONE, DEEP, NF1), --/* UART1_RXD */ PAD_CFG_NC(GPP_C12), --/* UART1_TXD */ PAD_CFG_NC(GPP_C13), --/* UART1_RTS# */ PAD_CFG_NC(GPP_C14), --/* UART1_CTS# */ PAD_CFG_NC(GPP_C15), --/* I2C0_SDA */ PAD_CFG_GPI(GPP_C16, NONE, DEEP), --/* I2C0_SCL */ PAD_CFG_GPI(GPP_C17, NONE, DEEP), --/* I2C1_SDA */ PAD_CFG_GPI(GPP_C18, NONE, DEEP), --/* I2C1_SCL */ PAD_CFG_NC(GPP_C19), --/* UART2_RXD */ PAD_CFG_NC(GPP_C20), --/* UART2_TXD */ PAD_CFG_NC(GPP_C21), --/* UART2_RTS# */ PAD_CFG_NC(GPP_C22), --/* UART2_CTS# */ PAD_CFG_NC(GPP_C23), -- --/* SPI1_CS# */ PAD_CFG_NC(GPP_D0), --/* SPI1_CLK */ PAD_CFG_NC(GPP_D1), --/* SPI1_MISO */ PAD_CFG_NC(GPP_D2), --/* SPI1_MOSI */ PAD_CFG_NC(GPP_D3), --/* FASHTRIG */ PAD_CFG_NC(GPP_D4), --/* ISH_I2C0_SDA */ PAD_CFG_NC(GPP_D5), --/* ISH_I2C0_SCL */ PAD_CFG_NC(GPP_D6), --/* ISH_I2C1_SDA */ PAD_CFG_NC(GPP_D7), --/* ISH_I2C1_SCL */ PAD_CFG_NC(GPP_D8), --/* ISH_SPI_CS# */ PAD_CFG_TERM_GPO(GPP_D9, 0, NONE, DEEP), --/* ISH_SPI_CLK */ PAD_CFG_GPI(GPP_D10, NONE, DEEP), --/* ISH_SPI_MISO */ PAD_CFG_TERM_GPO(GPP_D11, 1, NONE, DEEP), --/* ISH_SPI_MOSI */ PAD_CFG_NC(GPP_D12), --/* ISH_UART0_RXD */ PAD_CFG_NC(GPP_D13), --/* ISH_UART0_TXD */ PAD_CFG_NC(GPP_D14), --/* ISH_UART0_RTS# */ PAD_CFG_NC(GPP_D15), --/* ISH_UART0_CTS# */ PAD_CFG_NC(GPP_D16), --/* DMIC_CLK1 */ PAD_CFG_NF(GPP_D17, NONE, DEEP, NF1), --/* DMIC_DATA1 */ PAD_CFG_NF(GPP_D18, NONE, DEEP, NF1), --/* DMIC_CLK0 */ PAD_CFG_NF(GPP_D19, NONE, DEEP, NF1), --/* DMIC_DATA0 */ PAD_CFG_NF(GPP_D20, NONE, DEEP, NF1), --/* SPI1_IO2 */ PAD_CFG_NC(GPP_D21), --/* SPI1_IO3 */ PAD_CFG_NC(GPP_D22), --/* I2S_MCLK */ PAD_CFG_NC(GPP_D23), -- --/* SATAXPCI0 */ PAD_CFG_NC(GPP_E0), --/* SATAXPCIE1 */ PAD_CFG_NC(GPP_E1), --/* SATAXPCIE2 */ PAD_CFG_NF(GPP_E2, UP_20K, DEEP, NF1), --/* CPU_GP0 */ PAD_CFG_NC(GPP_E3), --/* SATA_DEVSLP0 */ PAD_CFG_NC(GPP_E4), --/* SATA_DEVSLP1 */ PAD_CFG_NC(GPP_E5), --/* SATA_DEVSLP2 */ PAD_CFG_NC(GPP_E6), --/* CPU_GP1 */ PAD_CFG_NC(GPP_E7), --/* SATALED# */ PAD_CFG_NC(GPP_E8), --/* USB2_OCO# */ PAD_CFG_NF(GPP_E9, NONE, DEEP, NF1), --/* USB2_OC1# */ PAD_CFG_NF(GPP_E10, NONE, DEEP, NF1), --/* USB2_OC2# */ PAD_CFG_NF(GPP_E11, NONE, DEEP, NF1), --/* USB2_OC3# */ PAD_CFG_NC(GPP_E12), --/* DDPB_HPD0 */ PAD_CFG_NF(GPP_E13, NONE, DEEP, NF1), --/* DDPC_HPD1 */ PAD_CFG_NF(GPP_E14, NONE, DEEP, NF1), --/* DDPD_HPD2 */ PAD_CFG_NC(GPP_E15), --/* DDPE_HPD3 */ PAD_CFG_GPI_ACPI_SCI(GPP_E16, NONE, PLTRST, NONE), --/* EDP_HPD */ PAD_CFG_NF(GPP_E17, NONE, DEEP, NF1), --/* DDPB_CTRLCLK */ PAD_CFG_NF(GPP_E18, NONE, DEEP, NF1), --/* DDPB_CTRLDATA */ PAD_CFG_NF(GPP_E19, DN_20K, DEEP, NF1), --/* DDPC_CTRLCLK */ PAD_CFG_NF(GPP_E20, NONE, DEEP, NF1), --/* DDPC_CTRLDATA */ PAD_CFG_NF(GPP_E21, DN_20K, DEEP, NF1), --/* DDPD_CTRLCLK */ PAD_CFG_GPI_APIC(GPP_E22, NONE, DEEP), --/* DDPD_CTRLDATA */ PAD_CFG_TERM_GPO(GPP_E23, 1, DN_20K, DEEP), -- --/* I2S2_SCLK */ PAD_CFG_NC(GPP_F0), --/* I2S2_SFRM */ PAD_CFG_NC(GPP_F1), --/* I2S2_TXD */ PAD_CFG_NC(GPP_F2), --/* I2S2_RXD */ PAD_CFG_NC(GPP_F3), --/* I2C2_SDA */ PAD_CFG_NC(GPP_F4), --/* I2C2_SCL */ PAD_CFG_NC(GPP_F5), --/* I2C3_SDA */ PAD_CFG_NC(GPP_F6), --/* I2C3_SCL */ PAD_CFG_NC(GPP_F7), --/* I2C4_SDA */ PAD_CFG_NF_1V8(GPP_F8, NONE, DEEP, NF1), --/* I2C4_SCL */ PAD_CFG_NF_1V8(GPP_F9, NONE, DEEP, NF1), --/* I2C5_SDA */ PAD_CFG_NC(GPP_F10), --/* I2C5_SCL */ PAD_CFG_NC(GPP_F11), --/* EMMC_CMD */ PAD_CFG_NC(GPP_F12), --/* EMMC_DATA0 */ PAD_CFG_NC(GPP_F13), --/* EMMC_DATA1 */ PAD_CFG_NC(GPP_F14), --/* EMMC_DATA2 */ PAD_CFG_NC(GPP_F15), --/* EMMC_DATA3 */ PAD_CFG_NC(GPP_F16), --/* EMMC_DATA4 */ PAD_CFG_NC(GPP_F17), --/* EMMC_DATA5 */ PAD_CFG_NC(GPP_F18), --/* EMMC_DATA6 */ PAD_CFG_NC(GPP_F19), --/* EMMC_DATA7 */ PAD_CFG_NC(GPP_F20), --/* EMMC_RCLK */ PAD_CFG_NC(GPP_F21), --/* EMMC_CLK */ PAD_CFG_NC(GPP_F22), --/* RSVD */ PAD_CFG_NC(GPP_F23), -- --/* SD_CMD */ PAD_CFG_NF(GPP_G0, NONE, DEEP, NF1), --/* SD_DATA0 */ PAD_CFG_NF(GPP_G1, NONE, DEEP, NF1), --/* SD_DATA1 */ PAD_CFG_NF(GPP_G2, NONE, DEEP, NF1), --/* SD_DATA2 */ PAD_CFG_NF(GPP_G3, NONE, DEEP, NF1), --/* SD_DATA3 */ PAD_CFG_NF(GPP_G4, NONE, DEEP, NF1), --/* SD_CD# */ PAD_CFG_NF(GPP_G5, NONE, DEEP, NF1), --/* SD_CLK */ PAD_CFG_NF(GPP_G6, NONE, DEEP, NF1), --/* SD_WP */ PAD_CFG_NF(GPP_G7, UP_20K, DEEP, NF1), -- --/* BATLOW# */ PAD_CFG_NC(GPD0), --/* ACPRESENT */ PAD_CFG_NF(GPD1, NONE, PWROK, NF1), --/* LAN_WAKE# */ PAD_CFG_NC(GPD2), --/* PWRBTN# */ PAD_CFG_NF(GPD3, UP_20K, PWROK, NF1), --/* SLP_S3# */ PAD_CFG_NF(GPD4, NONE, PWROK, NF1), --/* SLP_S4# */ PAD_CFG_NF(GPD5, NONE, PWROK, NF1), --/* SLP_A# */ PAD_CFG_NF(GPD6, NONE, PWROK, NF1), --/* RSVD */ PAD_CFG_NC(GPD7), --/* SUSCLK */ PAD_CFG_NF(GPD8, NONE, PWROK, NF1), --/* SLP_WLAN# */ PAD_CFG_NF(GPD9, NONE, PWROK, NF1), --/* SLP_S5# */ PAD_CFG_NF(GPD10, NONE, PWROK, NF1), --/* LANPHYC */ PAD_CFG_NF(GPD11, NONE, DEEP, NF1), --}; -- --#endif -- --#endif --- -2.14.3 - diff --git a/patches/coreboot-4.7/0006-purism-librem_skl-Explicitely-enable-VMX-and-Intel-S.patch b/patches/coreboot-4.7/0006-purism-librem_skl-Explicitely-enable-VMX-and-Intel-S.patch deleted file mode 100644 index d39f4c3f..00000000 --- a/patches/coreboot-4.7/0006-purism-librem_skl-Explicitely-enable-VMX-and-Intel-S.patch +++ /dev/null @@ -1,40 +0,0 @@ -From e6998f87d8d4c389d86586ea66f0ff20cd7751d2 Mon Sep 17 00:00:00 2001 -From: Youness Alaoui -Date: Fri, 9 Feb 2018 18:44:45 -0500 -Subject: [PATCH 6/9] purism/librem_skl: Explicitely enable VMX and Intel - SpeedStep - -The VMX feature was enabled by default by the FSP but a different -FSP might have it disabled, so this ensures that VMX is explicitely -enabled for the Librem machines. This option however doesn't seem -to work in the FSP since VMX doesn't actually get enabled but as -long as the features MSR remains unlocked, it's not critical. - -Enabling Intel SpeedStep Technology ensures the ACPI tables contain -the C-states/P-states which are required for the xen-acpi-processor -module to be loaded. Without it, the Qubes 4.0-rc4 installer will -complain at boot about modules that could not be loaded. - -Change-Id: I968ef36ec9382a10db13d96fd3a5c0fc904db387 -Signed-off-by: Youness Alaoui ---- - src/mainboard/purism/librem_skl/variants/librem13v2/devicetree.cb | 3 +++ - 1 file changed, 3 insertions(+) - -diff --git a/src/mainboard/purism/librem_skl/variants/librem13v2/devicetree.cb b/src/mainboard/purism/librem_skl/variants/librem13v2/devicetree.cb -index e2e2ac03da..9ce1d91549 100644 ---- a/src/mainboard/purism/librem_skl/variants/librem13v2/devicetree.cb -+++ b/src/mainboard/purism/librem_skl/variants/librem13v2/devicetree.cb -@@ -7,6 +7,9 @@ chip soc/intel/skylake - register "deep_s5_enable_dc" = "0" - register "deep_sx_config" = "DSX_EN_LAN_WAKE_PIN" - -+ register "eist_enable" = "1" -+ register "VmxEnable" = "1" -+ - # GPE configuration - # Note that GPE events called out in ASL code rely on this - # route. i.e. If this route changes then the affected GPE --- -2.14.3 - diff --git a/patches/coreboot-4.7/0009-Add-heads-TPM-measurements-to-Skylake-Kabylake.patch b/patches/coreboot-4.7/0009-Add-heads-TPM-measurements-to-Skylake-Kabylake.patch deleted file mode 100644 index 30944439..00000000 --- a/patches/coreboot-4.7/0009-Add-heads-TPM-measurements-to-Skylake-Kabylake.patch +++ /dev/null @@ -1,60 +0,0 @@ -From 8c6528caa1a2abcd30bbb0c4fdb4663dc70cb7d4 Mon Sep 17 00:00:00 2001 -From: Youness Alaoui -Date: Thu, 22 Feb 2018 20:56:04 -0500 -Subject: [PATCH 9/9] Add heads TPM measurements to Skylake/Kabylake - ---- - src/drivers/intel/fsp2_0/memory_init.c | 20 +++++++++++++++++--- - 1 file changed, 17 insertions(+), 3 deletions(-) - -diff --git a/src/drivers/intel/fsp2_0/memory_init.c b/src/drivers/intel/fsp2_0/memory_init.c -index 575f277466..4160b997a4 100644 ---- a/src/drivers/intel/fsp2_0/memory_init.c -+++ b/src/drivers/intel/fsp2_0/memory_init.c -@@ -33,6 +33,7 @@ - #include - #include - #include -+#include - #include - #include - -@@ -150,12 +151,14 @@ 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_RESUME_PATH_SAME_AS_BOOT) || -- !IS_ENABLED(CONFIG_VBOOT_STARTS_IN_BOOTBLOCK))) -+ (!IS_ENABLED(CONFIG_RESUME_PATH_SAME_AS_BOOT) || -+ !IS_ENABLED(CONFIG_VBOOT_STARTS_IN_BOOTBLOCK)) && -+ !IS_ENABLED(CONFIG_MEASURED_BOOT)) - init_tpm(s3wake); -+ printk(BIOS_DEBUG, "%s: romstage complete\n", __FILE__); - } - - static int mrc_cache_verify_tpm_hash(const uint8_t *data, size_t size) -@@ -484,6 +487,17 @@ 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. */ - prog_segment_loaded(hdr.image_base, hdr.image_size, SEG_FINAL); - --- -2.14.3 - diff --git a/patches/coreboot-4.7/0013-intel-cpu-Fix-SpeedStep-enabling.patch b/patches/coreboot-4.7/0013-intel-cpu-Fix-SpeedStep-enabling.patch deleted file mode 100644 index 130308ee..00000000 --- a/patches/coreboot-4.7/0013-intel-cpu-Fix-SpeedStep-enabling.patch +++ /dev/null @@ -1,37 +0,0 @@ -From 73c4fda90fdc4bd0bc6b383995d15b2c803cc274 Mon Sep 17 00:00:00 2001 -From: Youness Alaoui -Date: Fri, 2 Mar 2018 14:22:14 -0500 -Subject: [PATCH 13/15] intel/cpu: Fix SpeedStep enabling - -The IA32_MISC_ENABLE MSR was being overwritten by its old value -right after enabling SpeedStep (eist) which caused it to revert -the call to cpu_enable_eist(). - -Fixes bug introduced in 6b45ee44. - -Change-Id: Id2ac660bf8ea56d45e8c3f631a586b74106a6cc9 -Signed-off-by: Youness Alaoui ---- - src/soc/intel/skylake/cpu.c | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - -diff --git a/src/soc/intel/skylake/cpu.c b/src/soc/intel/skylake/cpu.c -index 291a40da3e..d09a05667e 100644 ---- a/src/soc/intel/skylake/cpu.c -+++ b/src/soc/intel/skylake/cpu.c -@@ -260,11 +260,11 @@ static void configure_misc(void) - msr = rdmsr(IA32_MISC_ENABLE); - msr.lo |= (1 << 0); /* Fast String enable */ - msr.lo |= (1 << 3); /* TM1/TM2/EMTTM enable */ -+ wrmsr(IA32_MISC_ENABLE, msr); - if (conf->eist_enable) - cpu_enable_eist(); - else - cpu_disable_eist(); -- wrmsr(IA32_MISC_ENABLE, msr); - - /* Disable Thermal interrupts */ - msr.lo = 0; --- -2.14.3 - diff --git a/patches/coreboot-4.7/0014-purism-librem_skl-Set-TCC-Activation-at-95C.patch b/patches/coreboot-4.7/0014-purism-librem_skl-Set-TCC-Activation-at-95C.patch deleted file mode 100644 index c6536c37..00000000 --- a/patches/coreboot-4.7/0014-purism-librem_skl-Set-TCC-Activation-at-95C.patch +++ /dev/null @@ -1,52 +0,0 @@ -From f93f9ac4d9da20749197abc5f272839da5519e1d Mon Sep 17 00:00:00 2001 -From: Youness Alaoui -Date: Fri, 2 Mar 2018 16:12:04 -0500 -Subject: [PATCH 14/15] purism/librem_skl: Set TCC Activation at 95C - -Set the Thermal Control Circuit (TCC) activaction value to 95C -even though FSP integration guide says to set it to 100C for SKL-U -(offset at 0), because when the TCC activates at 100C, the CPU -will have already shut itself down from overheating protection. - -This was tested on Purism Librem 13 v2. A bisect showed that the -immediate shutdowns happened after commit [1] was merged which led -to this solution. - -There is still a temperature ramping problem where a 'stress -c 4' -command will bring the temperature up from 50 to 100C (95C after -this patch) within a few milliseconds, instead of it taking many -dozens of seconds to reach ~80C. A bisect shows this regression -was introduced in commit [2] and still needs to be investigated. -This change may not be necessary anymore once the temperature -ramping problem is fixed, but it is still wise to keep it for -preventing shutdowns in corner cases. - -[1] ec5a947b (soc/intel/skylake: make tcc_offset take effect) -[2] fb1cd095 (purism/librem13v2: migrate from FSP 1.1 to 2.0) - -Change-Id: Idfc001c8e46ed3b07b24150c961c4b9bc9b71a62 -Signed-off-by: Youness Alaoui ---- - src/mainboard/purism/librem_skl/variants/librem13v2/devicetree.cb | 6 ++++++ - 1 file changed, 6 insertions(+) - -diff --git a/src/mainboard/purism/librem_skl/variants/librem13v2/devicetree.cb b/src/mainboard/purism/librem_skl/variants/librem13v2/devicetree.cb -index 9ce1d91549..159d921046 100644 ---- a/src/mainboard/purism/librem_skl/variants/librem13v2/devicetree.cb -+++ b/src/mainboard/purism/librem_skl/variants/librem13v2/devicetree.cb -@@ -10,6 +10,12 @@ chip soc/intel/skylake - register "eist_enable" = "1" - register "VmxEnable" = "1" - -+ # Set the Thermal Control Circuit (TCC) activaction value to 95C -+ # even though FSP integration guide says to set it to 100C for SKL-U -+ # (offset at 0), because when the TCC activates at 100C, the CPU -+ # will have already shut itself down from overheating protection. -+ register "tcc_offset" = "5" # TCC of 95C -+ - # GPE configuration - # Note that GPE events called out in ASL code rely on this - # route. i.e. If this route changes then the affected GPE --- -2.14.3 - diff --git a/patches/coreboot-4.7/0015-purism-librem_skl-Fix-Librem-15-v3-devicetree-config.patch b/patches/coreboot-4.7/0015-purism-librem_skl-Fix-Librem-15-v3-devicetree-config.patch deleted file mode 100644 index ab29dee7..00000000 --- a/patches/coreboot-4.7/0015-purism-librem_skl-Fix-Librem-15-v3-devicetree-config.patch +++ /dev/null @@ -1,39 +0,0 @@ -From bdaef1d8aa7cdfb27122665f951932e6e53d6a3d Mon Sep 17 00:00:00 2001 -From: Youness Alaoui -Date: Fri, 2 Mar 2018 17:03:11 -0500 -Subject: [PATCH 15/15] purism/librem_skl: Fix Librem 15 v3 devicetree - configuration - -Recent changes to devicetree for librem_skl were only applied -to the librem13v2 variant (Enable SpeedStep, VMX, TCC at 95C), -this fixes it by applying the same fixes for the Librem 15 v3. - -Change-Id: I1d5c3ba844c942bd94311f4639612228ff8e07f8 -Signed-off-by: Youness Alaoui ---- - .../purism/librem_skl/variants/librem15v3/devicetree.cb | 9 +++++++++ - 1 file changed, 9 insertions(+) - -diff --git a/src/mainboard/purism/librem_skl/variants/librem15v3/devicetree.cb b/src/mainboard/purism/librem_skl/variants/librem15v3/devicetree.cb -index 6cf183a61f..035db18eff 100644 ---- a/src/mainboard/purism/librem_skl/variants/librem15v3/devicetree.cb -+++ b/src/mainboard/purism/librem_skl/variants/librem15v3/devicetree.cb -@@ -7,6 +7,15 @@ chip soc/intel/skylake - register "deep_s5_enable_dc" = "0" - register "deep_sx_config" = "DSX_EN_LAN_WAKE_PIN" - -+ register "eist_enable" = "1" -+ register "VmxEnable" = "1" -+ -+ # Set the Thermal Control Circuit (TCC) activaction value to 95C -+ # even though FSP integration guide says to set it to 100C for SKL-U -+ # (offset at 0), because when the TCC activates at 100C, the CPU -+ # will have already shut itself down from overheating protection. -+ register "tcc_offset" = "5" # TCC of 95C -+ - # GPE configuration - # Note that GPE events called out in ASL code rely on this - # route. i.e. If this route changes then the affected GPE --- -2.14.3 - diff --git a/patches/coreboot-4.7/0016-purism-librem13v1-librem13v2-liberm15v3-Fix-EC-LPC-I.patch b/patches/coreboot-4.7/0016-purism-librem13v1-librem13v2-liberm15v3-Fix-EC-LPC-I.patch deleted file mode 100644 index c20b1007..00000000 --- a/patches/coreboot-4.7/0016-purism-librem13v1-librem13v2-liberm15v3-Fix-EC-LPC-I.patch +++ /dev/null @@ -1,74 +0,0 @@ -From c6dd40b67a21bda1d8ec6043f19e4606a3695a05 Mon Sep 17 00:00:00 2001 -From: Youness Alaoui -Date: Tue, 13 Mar 2018 16:53:30 -0400 -Subject: [PATCH 1/3] purism/librem13v1, librem13v2, liberm15v3: Fix EC LPC I/O - port - -The LPC I/O ports for communicating with the EC were not set -properly causing ectool to fail to read the Index I/O from the EC. - -The EC Index I/O is on port 0x380 and the LPC I/O port needs to be -decoded by the PCI device for it to be accessible. - -This fixes it for the Librem 13v1, 13v2 and 15v3. - -Change-Id: Ide1d158340eadfabbce5f70ceccddfabb4db188a -Signed-off-by: Youness Alaoui ---- - src/mainboard/purism/librem13v1/devicetree.cb | 4 ++++ - src/mainboard/purism/librem_skl/variants/librem13v2/devicetree.cb | 6 +++--- - src/mainboard/purism/librem_skl/variants/librem15v3/devicetree.cb | 6 +++--- - 3 files changed, 10 insertions(+), 6 deletions(-) - -diff --git a/src/mainboard/purism/librem13v1/devicetree.cb b/src/mainboard/purism/librem13v1/devicetree.cb -index ba38070a55..c916e9a9a4 100644 ---- a/src/mainboard/purism/librem13v1/devicetree.cb -+++ b/src/mainboard/purism/librem13v1/devicetree.cb -@@ -18,6 +18,10 @@ chip soc/intel/broadwell - register "gpu_panel_power_backlight_on_delay" = "2000" # 200ms - register "gpu_panel_power_backlight_off_delay" = "2000" # 200ms - -+ # EC host command ranges are in 0x380-0x383 & 0x80-0x8f -+ register "gen1_dec" = "0x00000381" -+ register "gen2_dec" = "0x000c0081" -+ - # Port 0 is HDD - # Port 3 is M.2 NGFF - register "sata_port_map" = "0x9" -diff --git a/src/mainboard/purism/librem_skl/variants/librem13v2/devicetree.cb b/src/mainboard/purism/librem_skl/variants/librem13v2/devicetree.cb -index 159d921046..da97fb9ea7 100644 ---- a/src/mainboard/purism/librem_skl/variants/librem13v2/devicetree.cb -+++ b/src/mainboard/purism/librem_skl/variants/librem13v2/devicetree.cb -@@ -24,9 +24,9 @@ chip soc/intel/skylake - register "gpe0_dw1" = "GPP_D" - register "gpe0_dw2" = "GPP_E" - -- # EC host command ranges are in 0x800-0x8ff & 0x200-0x20f -- register "gen1_dec" = "0x00fc0801" -- register "gen2_dec" = "0x000c0201" -+ # EC host command ranges are in 0x380-0x383 & 0x80-0x8f -+ register "gen1_dec" = "0x00000381" -+ register "gen2_dec" = "0x000c0081" - - # Enable "Intel Speed Shift Technology" - register "speed_shift_enable" = "1" -diff --git a/src/mainboard/purism/librem_skl/variants/librem15v3/devicetree.cb b/src/mainboard/purism/librem_skl/variants/librem15v3/devicetree.cb -index 035db18eff..deaf3a6deb 100644 ---- a/src/mainboard/purism/librem_skl/variants/librem15v3/devicetree.cb -+++ b/src/mainboard/purism/librem_skl/variants/librem15v3/devicetree.cb -@@ -24,9 +24,9 @@ chip soc/intel/skylake - register "gpe0_dw1" = "GPP_D" - register "gpe0_dw2" = "GPP_E" - -- # EC host command ranges are in 0x800-0x8ff & 0x200-0x20f -- register "gen1_dec" = "0x00fc0801" -- register "gen2_dec" = "0x000c0201" -+ # EC host command ranges are in 0x380-0x383 & 0x80-0x8f -+ register "gen1_dec" = "0x00000381" -+ register "gen2_dec" = "0x000c0081" - - # Enable "Intel Speed Shift Technology" - register "speed_shift_enable" = "1" --- -2.14.3 - diff --git a/patches/coreboot-4.7/0017-ec-purism-Fix-the-CPU-s-PPCM-value-for-Turbo-when-se.patch b/patches/coreboot-4.7/0017-ec-purism-Fix-the-CPU-s-PPCM-value-for-Turbo-when-se.patch deleted file mode 100644 index 77a04725..00000000 --- a/patches/coreboot-4.7/0017-ec-purism-Fix-the-CPU-s-PPCM-value-for-Turbo-when-se.patch +++ /dev/null @@ -1,63 +0,0 @@ -From 7cb5f11eac45c17bfdd096eb10db3115fc782b5b Mon Sep 17 00:00:00 2001 -From: Youness Alaoui -Date: Tue, 13 Mar 2018 16:58:52 -0400 -Subject: [PATCH 2/3] ec/purism: Fix the CPU's PPCM value for Turbo when set by - the EC - -The EC needs to set the PPCM value to 0, 1 or 2 depending on whether -the Turbo is enabled or not and the value differs from Broadwell and -Skylake machines. - -Change-Id: I662dce54415e685c054ffc00b6afde0f1f7765e2 -Signed-off-by: Youness Alaoui ---- - src/ec/purism/librem/acpi/ec.asl | 4 ++-- - src/mainboard/purism/librem13v1/acpi/ec.asl | 2 ++ - src/mainboard/purism/librem_skl/acpi/ec.asl | 2 ++ - 3 files changed, 6 insertions(+), 2 deletions(-) - -diff --git a/src/ec/purism/librem/acpi/ec.asl b/src/ec/purism/librem/acpi/ec.asl -index e95f126c63..ff325aa9a3 100644 ---- a/src/ec/purism/librem/acpi/ec.asl -+++ b/src/ec/purism/librem/acpi/ec.asl -@@ -218,11 +218,11 @@ Device (EC) - * when the system is charging. - */ - If (TURB) { -- Store (Zero, PPCM) -+ Store (PPCM_TURBO, PPCM) - PPCN () - Store (One, EDTB) - } Else { -- Store (One, PPCM) -+ Store (PPCM_NOTURBO, PPCM) - PPCN () - Store (Zero, EDTB) - } -diff --git a/src/mainboard/purism/librem13v1/acpi/ec.asl b/src/mainboard/purism/librem13v1/acpi/ec.asl -index cf8b9a91d9..b2fa5b9924 100644 ---- a/src/mainboard/purism/librem13v1/acpi/ec.asl -+++ b/src/mainboard/purism/librem13v1/acpi/ec.asl -@@ -14,5 +14,7 @@ - */ - - #define EC_SCI_GPI 10 -+#define PPCM_TURBO Zero -+#define PPCM_NOTURBO One - - #include -diff --git a/src/mainboard/purism/librem_skl/acpi/ec.asl b/src/mainboard/purism/librem_skl/acpi/ec.asl -index 4215213737..c667b6c41b 100644 ---- a/src/mainboard/purism/librem_skl/acpi/ec.asl -+++ b/src/mainboard/purism/librem_skl/acpi/ec.asl -@@ -14,5 +14,7 @@ - */ - - #define EC_SCI_GPI 0x50 -+#define PPCM_TURBO One -+#define PPCM_NOTURBO 0x02 - - #include --- -2.14.3 - diff --git a/patches/coreboot-4.7/0018-purism-librem_skl-Add-AC-DC-LoadLine-to-VR-Config.patch b/patches/coreboot-4.7/0018-purism-librem_skl-Add-AC-DC-LoadLine-to-VR-Config.patch deleted file mode 100644 index 0a8926c7..00000000 --- a/patches/coreboot-4.7/0018-purism-librem_skl-Add-AC-DC-LoadLine-to-VR-Config.patch +++ /dev/null @@ -1,194 +0,0 @@ -From 7ac4919b8af16b62fb63592dbdd43ca9215c0cf7 Mon Sep 17 00:00:00 2001 -From: Youness Alaoui -Date: Tue, 20 Mar 2018 18:32:23 -0400 -Subject: [PATCH 3/3] purism/librem_skl: Add AC/DC LoadLine to VR Config - -The FSP 2.0 needs to set the ac_loadline and dc_loadline for -each VR config. Without it, the Loadline is considered to be -0 mOhm and this causes CPU temp to jump all over the place -whenever the CPU is used. - -These values were copied from the Google Poppy devicetree. - -Change-Id: I6aeb6ee521988b94f2ae94a60d1a28b87ba984d4 -Signed-off-by: Youness Alaoui ---- - .../librem_skl/variants/librem13v2/devicetree.cb | 40 ++++++++++++++-------- - .../librem_skl/variants/librem15v3/devicetree.cb | 40 ++++++++++++++-------- - 2 files changed, 50 insertions(+), 30 deletions(-) - -diff --git a/src/mainboard/purism/librem_skl/variants/librem13v2/devicetree.cb b/src/mainboard/purism/librem_skl/variants/librem13v2/devicetree.cb -index da97fb9ea7..a08a3df5f4 100644 ---- a/src/mainboard/purism/librem_skl/variants/librem13v2/devicetree.cb -+++ b/src/mainboard/purism/librem_skl/variants/librem13v2/devicetree.cb -@@ -31,8 +31,8 @@ chip soc/intel/skylake - # Enable "Intel Speed Shift Technology" - register "speed_shift_enable" = "1" - -- # Enable DPTF -- register "dptf_enable" = "1" -+ # Disable DPTF -+ register "dptf_enable" = "0" - - # FSP Configuration - register "ProbelessTrace" = "0" -@@ -82,19 +82,21 @@ chip soc/intel/skylake - register "pirqh_routing" = "PCH_IRQ11" - - # VR Settings Configuration for 4 Domains -- #+----------------+-------+-------+-------------+-------+ -- #| Domain/Setting | SA | IA | GT Unsliced | GT | -- #+----------------+-------+-------+-------------+-------+ -- #| Psi1Threshold | 20A | 20A | 20A | 20A | -- #| Psi2Threshold | 4A | 5A | 5A | 5A | -- #| Psi3Threshold | 1A | 1A | 1A | 1A | -- #| Psi3Enable | 1 | 1 | 1 | 1 | -- #| Psi4Enable | 1 | 1 | 1 | 1 | -- #| ImonSlope | 0 | 0 | 0 | 0 | -- #| ImonOffset | 0 | 0 | 0 | 0 | -- #| IccMax | 7A | 34A | 35A | 35A | -- #| VrVoltageLimit | 1.52V | 1.52V | 1.52V | 1.52V | -- #+----------------+-------+-------+-------------+-------+ -+ #+----------------+-----------+-----------+-------------+----------+ -+ #| Domain/Setting | SA | IA | GT Unsliced | GT | -+ #+----------------+-----------+-----------+-------------+----------+ -+ #| Psi1Threshold | 20A | 20A | 20A | 20A | -+ #| Psi2Threshold | 4A | 5A | 5A | 5A | -+ #| Psi3Threshold | 1A | 1A | 1A | 1A | -+ #| Psi3Enable | 1 | 1 | 1 | 1 | -+ #| Psi4Enable | 1 | 1 | 1 | 1 | -+ #| ImonSlope | 0 | 0 | 0 | 0 | -+ #| ImonOffset | 0 | 0 | 0 | 0 | -+ #| IccMax | 7A | 34A | 35A | 35A | -+ #| VrVoltageLimit | 1.52V | 1.52V | 1.52V | 1.52V | -+ #| AC LoadLine | 15 mOhm | 5.7 mOhm | 5.2 mOhm | 5.2 mOhm | -+ #| DC LoadLine | 14.3 mOhm | 4.83 mOhm | 4.2 mOhm | 4.2 mOhm | -+ #+----------------+-----------+-----------+-------------+----------+ - register "domain_vr_config[VR_SYSTEM_AGENT]" = "{ - .vr_config_enable = 1, - .psi1threshold = VR_CFG_AMP(20), -@@ -106,6 +108,8 @@ chip soc/intel/skylake - .imon_offset = 0x0, - .icc_max = VR_CFG_AMP(7), - .voltage_limit = 1520, -+ .ac_loadline = 1500, -+ .dc_loadline = 1430, - }" - - register "domain_vr_config[VR_IA_CORE]" = "{ -@@ -119,6 +123,8 @@ chip soc/intel/skylake - .imon_offset = 0x0, - .icc_max = VR_CFG_AMP(34), - .voltage_limit = 1520, -+ .ac_loadline = 570, -+ .dc_loadline = 483, - }" - - register "domain_vr_config[VR_GT_UNSLICED]" = "{ -@@ -132,6 +138,8 @@ chip soc/intel/skylake - .imon_offset = 0x0, - .icc_max = VR_CFG_AMP(35), - .voltage_limit = 1520, -+ .ac_loadline = 520, -+ .dc_loadline = 420, - }" - - register "domain_vr_config[VR_GT_SLICED]" = "{ -@@ -145,6 +153,8 @@ chip soc/intel/skylake - .imon_offset = 0x0, - .icc_max = VR_CFG_AMP(35), - .voltage_limit = 1520, -+ .ac_loadline = 520, -+ .dc_loadline = 420, - }" - - # Enable Root Ports 5 and 9 -diff --git a/src/mainboard/purism/librem_skl/variants/librem15v3/devicetree.cb b/src/mainboard/purism/librem_skl/variants/librem15v3/devicetree.cb -index deaf3a6deb..7dff719096 100644 ---- a/src/mainboard/purism/librem_skl/variants/librem15v3/devicetree.cb -+++ b/src/mainboard/purism/librem_skl/variants/librem15v3/devicetree.cb -@@ -31,8 +31,8 @@ chip soc/intel/skylake - # Enable "Intel Speed Shift Technology" - register "speed_shift_enable" = "1" - -- # Enable DPTF -- register "dptf_enable" = "1" -+ # Disable DPTF -+ register "dptf_enable" = "0" - - # FSP Configuration - register "ProbelessTrace" = "0" -@@ -82,19 +82,21 @@ chip soc/intel/skylake - register "pirqh_routing" = "PCH_IRQ11" - - # VR Settings Configuration for 4 Domains -- #+----------------+-------+-------+-------------+-------+ -- #| Domain/Setting | SA | IA | GT Unsliced | GT | -- #+----------------+-------+-------+-------------+-------+ -- #| Psi1Threshold | 20A | 20A | 20A | 20A | -- #| Psi2Threshold | 4A | 5A | 5A | 5A | -- #| Psi3Threshold | 1A | 1A | 1A | 1A | -- #| Psi3Enable | 1 | 1 | 1 | 1 | -- #| Psi4Enable | 1 | 1 | 1 | 1 | -- #| ImonSlope | 0 | 0 | 0 | 0 | -- #| ImonOffset | 0 | 0 | 0 | 0 | -- #| IccMax | 7A | 34A | 35A | 35A | -- #| VrVoltageLimit | 1.52V | 1.52V | 1.52V | 1.52V | -- #+----------------+-------+-------+-------------+-------+ -+ #+----------------+-----------+-----------+-------------+----------+ -+ #| Domain/Setting | SA | IA | GT Unsliced | GT | -+ #+----------------+-----------+-----------+-------------+----------+ -+ #| Psi1Threshold | 20A | 20A | 20A | 20A | -+ #| Psi2Threshold | 4A | 5A | 5A | 5A | -+ #| Psi3Threshold | 1A | 1A | 1A | 1A | -+ #| Psi3Enable | 1 | 1 | 1 | 1 | -+ #| Psi4Enable | 1 | 1 | 1 | 1 | -+ #| ImonSlope | 0 | 0 | 0 | 0 | -+ #| ImonOffset | 0 | 0 | 0 | 0 | -+ #| IccMax | 7A | 34A | 35A | 35A | -+ #| VrVoltageLimit | 1.52V | 1.52V | 1.52V | 1.52V | -+ #| AC LoadLine | 15 mOhm | 5.7 mOhm | 5.2 mOhm | 5.2 mOhm | -+ #| DC LoadLine | 14.3 mOhm | 4.83 mOhm | 4.2 mOhm | 4.2 mOhm | -+ #+----------------+-----------+-----------+-------------+----------+ - register "domain_vr_config[VR_SYSTEM_AGENT]" = "{ - .vr_config_enable = 1, - .psi1threshold = VR_CFG_AMP(20), -@@ -106,6 +108,8 @@ chip soc/intel/skylake - .imon_offset = 0x0, - .icc_max = VR_CFG_AMP(7), - .voltage_limit = 1520, -+ .ac_loadline = 1500, -+ .dc_loadline = 1430, - }" - - register "domain_vr_config[VR_IA_CORE]" = "{ -@@ -119,6 +123,8 @@ chip soc/intel/skylake - .imon_offset = 0x0, - .icc_max = VR_CFG_AMP(34), - .voltage_limit = 1520, -+ .ac_loadline = 570, -+ .dc_loadline = 483, - }" - - register "domain_vr_config[VR_GT_UNSLICED]" = "{ -@@ -132,6 +138,8 @@ chip soc/intel/skylake - .imon_offset = 0x0, - .icc_max = VR_CFG_AMP(35), - .voltage_limit = 1520, -+ .ac_loadline = 520, -+ .dc_loadline = 420, - }" - - register "domain_vr_config[VR_GT_SLICED]" = "{ -@@ -145,6 +153,8 @@ chip soc/intel/skylake - .imon_offset = 0x0, - .icc_max = VR_CFG_AMP(35), - .voltage_limit = 1520, -+ .ac_loadline = 520, -+ .dc_loadline = 420, - }" - - # Enable Root Ports 5 and 9 --- -2.14.3 - diff --git a/patches/coreboot-4.7/0000-measuredboot.patch b/patches/coreboot-4.8.1/0000-measuredboot.patch similarity index 82% rename from patches/coreboot-4.7/0000-measuredboot.patch rename to patches/coreboot-4.8.1/0000-measuredboot.patch index 4dc83857..7731a5ae 100644 --- a/patches/coreboot-4.7/0000-measuredboot.patch +++ b/patches/coreboot-4.8.1/0000-measuredboot.patch @@ -1,8 +1,8 @@ diff --git ./src/Kconfig ./src/Kconfig -index 6896d0e..577bd52 100644 +index 99a704d..004b4a7 100644 --- ./src/Kconfig +++ ./src/Kconfig -@@ -253,6 +253,21 @@ config BOOTSPLASH_FILE +@@ -260,6 +260,21 @@ config BOOTSPLASH_FILE The path and filename of the file to use as graphical bootsplash screen. The file format has to be jpg. @@ -25,7 +25,7 @@ index 6896d0e..577bd52 100644 menu "Mainboard" diff --git ./src/drivers/pc80/tpm/romstage.c ./src/drivers/pc80/tpm/romstage.c -index 5531458..95e65f2 100644 +index b8e4705..7732e66 100644 --- ./src/drivers/pc80/tpm/romstage.c +++ ./src/drivers/pc80/tpm/romstage.c @@ -48,6 +48,12 @@ static const struct { @@ -60,10 +60,10 @@ index 5531458..95e65f2 100644 } tis_close(); -diff --git ./src/drivers/pc80/tpm/tpm.c ./src/drivers/pc80/tpm/tpm.c -index 574d3af..9bdc73f 100644 ---- ./src/drivers/pc80/tpm/tpm.c -+++ ./src/drivers/pc80/tpm/tpm.c +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[] = { @@ -78,7 +78,7 @@ index 574d3af..9bdc73f 100644 #endif {0xffff} diff --git ./src/include/program_loading.h ./src/include/program_loading.h -index 416e2e9..40486cd 100644 +index 7aba302..879c26e 100644 --- ./src/include/program_loading.h +++ ./src/include/program_loading.h @@ -24,6 +24,8 @@ enum { @@ -89,84 +89,12 @@ index 416e2e9..40486cd 100644 + SEG_NO_MEASURE = 1 << 1, }; - enum prog_type { -diff --git ./src/include/sha1.h ./src/include/sha1.h -new file mode 100644 -index 0000000..e7e28e6 ---- /dev/null -+++ ./src/include/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 -+ * found in the LICENSE file. -+ */ -+ -+/* SHA-1 functions */ -+ -+#ifndef _sha1_h_ -+#define _sha1_h_ -+ -+#include -+#include -+ -+#define SHA1_DIGEST_SIZE 20 -+#define SHA1_BLOCK_SIZE 64 -+ -+/* SHA-1 context */ -+struct sha1_ctx { -+ uint32_t count; -+ uint32_t state[5]; -+ union { -+ uint8_t b[SHA1_BLOCK_SIZE]; -+ uint32_t w[DIV_ROUND_UP(SHA1_BLOCK_SIZE, sizeof(uint32_t))]; -+ } buf; -+}; -+ -+void sha1_init(struct sha1_ctx *ctx); -+void sha1_update(struct sha1_ctx *ctx, const uint8_t *data, uint32_t len); -+uint8_t *sha1_final(struct sha1_ctx *ctx); -+ -+#endif /* _sha1_h_ */ -diff --git ./src/include/tpm_lite/tlcl.h ./src/include/tpm_lite/tlcl.h -index 8dd5d80..15fbebf 100644 ---- ./src/include/tpm_lite/tlcl.h -+++ ./src/include/tpm_lite/tlcl.h -@@ -147,6 +147,11 @@ uint32_t tlcl_extend(int pcr_num, const uint8_t *in_digest, - uint8_t *out_digest); - - /** -+ * 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); -+ -+/** - * Get the entire set of permanent flags. - */ - uint32_t tlcl_get_permanent_flags(TPM_PERMANENT_FLAGS *pflags); -diff --git ./src/lib/Makefile.inc ./src/lib/Makefile.inc -index 25537d2..5248483 100644 ---- ./src/lib/Makefile.inc -+++ ./src/lib/Makefile.inc -@@ -57,8 +57,13 @@ verstage-$(CONFIG_TPM) += tlcl.c - verstage-$(CONFIG_TPM2) += tpm2_marshaling.c - verstage-$(CONFIG_TPM2) += tpm2_tlcl.c - --ifeq ($(CONFIG_VBOOT_SEPARATE_VERSTAGE),y) -+# Add the TPM support into the ROM stage for measuring the bootblock - romstage-$(CONFIG_TPM) += tlcl.c -+romstage-$(CONFIG_TPM) += sha1.c -+ramstage-$(CONFIG_TPM) += tlcl.c -+ramstage-$(CONFIG_TPM) += sha1.c -+ -+ifeq ($(CONFIG_VBOOT_SEPARATE_VERSTAGE),y) - romstage-$(CONFIG_TPM2) += tpm2_marshaling.c - romstage-$(CONFIG_TPM2) += tpm2_tlcl.c - endif # CONFIG_VBOOT_SEPARATE_VERSTAGE + // 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 596abc5..f1928ce 100644 +index 87ab387..708d321 100644 --- ./src/lib/cbfs.c +++ ./src/lib/cbfs.c -@@ -69,7 +69,13 @@ void *cbfs_boot_map_with_leak(const char *name, uint32_t type, size_t *size) +@@ -70,7 +70,13 @@ void *cbfs_boot_map_with_leak(const char *name, uint32_t type, size_t *size) if (size != NULL) *size = fsize; @@ -181,7 +109,7 @@ index 596abc5..f1928ce 100644 } int cbfs_locate_file_in_region(struct cbfsf *fh, const char *region_name, -@@ -97,7 +101,8 @@ size_t cbfs_load_and_decompress(const struct region_device *rdev, size_t offset, +@@ -98,7 +104,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; @@ -191,7 +119,7 @@ index 596abc5..f1928ce 100644 case CBFS_COMPRESS_LZ4: if ((ENV_BOOTBLOCK || ENV_VERSTAGE) && -@@ -115,7 +120,7 @@ size_t cbfs_load_and_decompress(const struct region_device *rdev, size_t offset, +@@ -116,7 +123,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); @@ -200,7 +128,7 @@ index 596abc5..f1928ce 100644 case CBFS_COMPRESS_LZMA: if (ENV_BOOTBLOCK || ENV_VERSTAGE) -@@ -134,11 +139,15 @@ size_t cbfs_load_and_decompress(const struct region_device *rdev, size_t offset, +@@ -135,11 +142,15 @@ size_t cbfs_load_and_decompress(const struct region_device *rdev, size_t offset, rdev_munmap(rdev, map); @@ -218,18 +146,18 @@ index 596abc5..f1928ce 100644 static inline int tohex4(unsigned int c) diff --git ./src/lib/hardwaremain.c ./src/lib/hardwaremain.c -index 0deab4b..eee5415 100644 +index 6fd55d7..b5b7d91 100644 --- ./src/lib/hardwaremain.c +++ ./src/lib/hardwaremain.c -@@ -32,6 +32,7 @@ +@@ -33,6 +33,7 @@ #include #include #include -+#include ++#include #include #if IS_ENABLED(CONFIG_HAVE_ACPI_RESUME) #include -@@ -544,3 +545,13 @@ void boot_state_current_unblock(void) +@@ -545,3 +546,13 @@ void boot_state_current_unblock(void) { boot_state_unblock(current_phase.state_id, current_phase.seq); } @@ -256,11 +184,31 @@ index 66d5120..b50afe7 100644 return 0; } -diff --git ./src/lib/sha1.c ./src/lib/sha1.c +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 + ++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 ++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 new file mode 100644 -index 0000000..506907f +index 0000000..6b154f8 --- /dev/null -+++ ./src/lib/sha1.c ++++ ./src/security/tpm/sha1.c @@ -0,0 +1,175 @@ +/* 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 @@ -270,7 +218,7 @@ index 0000000..506907f + * Open Source Project (platorm/system/core.git/libmincrypt/sha.c + */ + -+#include "sha1.h" ++#include +#include + +static uint32_t ror27(uint32_t val) @@ -437,19 +385,72 @@ index 0000000..506907f + ctx->state[4] = 0xC3D2E1F0; + ctx->count = 0; +} -diff --git ./src/lib/tlcl.c ./src/lib/tlcl.c -index 49854cb..32eb128 100644 ---- ./src/lib/tlcl.c -+++ ./src/lib/tlcl.c -@@ -19,6 +19,7 @@ +diff --git ./src/security/tpm/sha1.h ./src/security/tpm/sha1.h +new file mode 100644 +index 0000000..e7e28e6 +--- /dev/null ++++ ./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 ++ * found in the LICENSE file. ++ */ ++ ++/* SHA-1 functions */ ++ ++#ifndef _sha1_h_ ++#define _sha1_h_ ++ ++#include ++#include ++ ++#define SHA1_DIGEST_SIZE 20 ++#define SHA1_BLOCK_SIZE 64 ++ ++/* SHA-1 context */ ++struct sha1_ctx { ++ uint32_t count; ++ uint32_t state[5]; ++ union { ++ uint8_t b[SHA1_BLOCK_SIZE]; ++ uint32_t w[DIV_ROUND_UP(SHA1_BLOCK_SIZE, sizeof(uint32_t))]; ++ } buf; ++}; ++ ++void sha1_init(struct sha1_ctx *ctx); ++void sha1_update(struct sha1_ctx *ctx, const uint8_t *data, uint32_t len); ++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); + + /** ++ * 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); ++ ++/** + * 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 +@@ -17,6 +17,7 @@ + #include + #include #include - #include - #include -+#include ++#include + #include #include - #include "tlcl_internal.h" - #include "tlcl_structures.h" -@@ -351,3 +352,23 @@ uint32_t tlcl_extend(int pcr_num, const uint8_t *in_digest, + #include +@@ -354,3 +355,23 @@ uint32_t tlcl_extend(int pcr_num, const uint8_t *in_digest, kPcrDigestLength); return result; } diff --git a/patches/coreboot-4.7/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 similarity index 100% rename from patches/coreboot-4.7/0007-intel-fsp-fsp2_0-Fix-FSP-2.0-headers-to-match-github.patch rename to patches/coreboot-4.8.1/0007-intel-fsp-fsp2_0-Fix-FSP-2.0-headers-to-match-github.patch 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 new file mode 100644 index 00000000..9b3898e7 --- /dev/null +++ b/patches/coreboot-4.8.1/0009-Add-heads-TPM-measurements-to-Skylake-Kabylake.patch @@ -0,0 +1,132 @@ +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.7/0020-kgpe-d16.patch b/patches/coreboot-4.8.1/0020-kgpe-d16.patch similarity index 100% rename from patches/coreboot-4.7/0020-kgpe-d16.patch rename to patches/coreboot-4.8.1/0020-kgpe-d16.patch diff --git a/patches/coreboot-4.7/0030-sandybridge.patch b/patches/coreboot-4.8.1/0030-sandybridge.patch similarity index 91% rename from patches/coreboot-4.7/0030-sandybridge.patch rename to patches/coreboot-4.8.1/0030-sandybridge.patch index 87ce79b4..8559b409 100644 --- a/patches/coreboot-4.7/0030-sandybridge.patch +++ b/patches/coreboot-4.8.1/0030-sandybridge.patch @@ -1,12 +1,12 @@ diff --git ./src/northbridge/intel/sandybridge/romstage.c ./src/northbridge/intel/sandybridge/romstage.c -index 8608d5a..dac90ee 100644 +index 0426b83..d348b9e 100644 --- ./src/northbridge/intel/sandybridge/romstage.c +++ ./src/northbridge/intel/sandybridge/romstage.c @@ -29,6 +29,8 @@ #include #include - #include -+#include + #include ++#include +#include #include #include "southbridge/intel/bd82x6x/pch.h" @@ -31,7 +31,7 @@ index 8608d5a..dac90ee 100644 /* USB is initialized in MRC if MRC is used. */ if (CONFIG_USE_NATIVE_RAMINIT) { early_usb_init(mainboard_usb_ports); -@@ -116,9 +131,23 @@ void mainboard_romstage_entry(unsigned long bist) +@@ -117,9 +132,23 @@ void mainboard_romstage_entry(unsigned long bist) northbridge_romstage_finalize(s3resume); 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 new file mode 100644 index 00000000..52ee66c6 --- /dev/null +++ b/patches/coreboot-4.8.1/0050-buildgcc-Do-not-try-to-install-GCC-if-build-failed.patch @@ -0,0 +1,44 @@ +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 new file mode 100644 index 00000000..729e3549 --- /dev/null +++ b/patches/coreboot-4.8.1/0051-buildgcc-Update-IASL-to-20180531.patch @@ -0,0 +1,130 @@ +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 new file mode 100644 index 00000000..1b229622 --- /dev/null +++ b/patches/coreboot-4.8.1/0052-crossgcc-Update-to-clang-6.0-cmake-3.11.3.patch @@ -0,0 +1,132 @@ +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 new file mode 100644 index 00000000..97ee389b --- /dev/null +++ b/patches/coreboot-4.8.1/0053-src-Get-rid-of-unneeded-whitespace.patch @@ -0,0 +1,55 @@ +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 new file mode 100644 index 00000000..8d46818c --- /dev/null +++ b/patches/coreboot-4.8.1/0054-util-crossgcc-Allow-building-a-new-gcc-against-new-b.patch @@ -0,0 +1,54 @@ +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 new file mode 100644 index 00000000..8a0635f9 --- /dev/null +++ b/patches/coreboot-4.8.1/0055-crosgcc-patches-Add-make-patch-for-GLIBC-glob-interf.patch @@ -0,0 +1,46 @@ +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 new file mode 100644 index 00000000..81ab35f4 --- /dev/null +++ b/patches/coreboot-4.8.1/0056-util-crossgcc-update-to-gcc-8.1.0-and-binutils-2.30.patch @@ -0,0 +1,131728 @@ +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 new file mode 100644 index 00000000..eeaac14e --- /dev/null +++ b/patches/coreboot-4.8.1/0057-util-crosgcc-patches-update-make-4.2.1-patches.patch @@ -0,0 +1,156 @@ +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 new file mode 100644 index 00000000..82c653b6 --- /dev/null +++ b/patches/coreboot-4.8.1/0058-util-crosgcc-Fix-most-shellcheck-errors-in-buildgcc.patch @@ -0,0 +1,826 @@ +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 new file mode 100644 index 00000000..608b6b68 --- /dev/null +++ b/patches/coreboot-4.8.1/0059-util-Add-description.md-to-each-util.patch @@ -0,0 +1,29 @@ +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 +