From 4ea175838f336cb86017db998aed49caba9312c0 Mon Sep 17 00:00:00 2001 From: Martin Kepplinger Date: Mon, 4 Jun 2018 09:02:22 +0200 Subject: [PATCH 001/102] x230: remove 4M and 8M split-images from the build The bios regions of the 12M coreboot image is 7M: 4M and 3 of the 8M split image. The rest of the 8M image _generated_ with fake data and not usable on real systems! It's dangerous to create them and suggest flashing them externally. That's exactly why the x230-flash build target is there: To have a self-contained 4M image and enable easy unlocking of the 8M image using the _original_ data. the heads-wiki project is updated accordingly. Closes #307 Closes #302 --- boards/x230/x230.config | 14 +++----------- 1 file changed, 3 insertions(+), 11 deletions(-) diff --git a/boards/x230/x230.config b/boards/x230/x230.config index e479f5a1b..0ded661a8 100644 --- a/boards/x230/x230.config +++ b/boards/x230/x230.config @@ -33,14 +33,6 @@ export CONFIG_USB_BOOT_DEV="/dev/sdb1" # the ME image and part of the coreboot image, and a 4 MB one that # has the rest of the coreboot and the reset vector. # -# When flashing via an external programmer it is easiest to have -# to separate files for these pieces. -all: $(build)/$(BOARD)/$(BOARD)-8.rom -$(build)/$(BOARD)/$(BOARD)-8.rom: $(build)/$(BOARD)/coreboot.rom - $(call do,DD 8MB,$@,dd of=$@ if=$< bs=65536 count=128 skip=0 status=none) - @sha256sum $@ - -all: $(build)/$(BOARD)/$(BOARD)-4.rom -$(build)/$(BOARD)/$(BOARD)-4.rom: $(build)/$(BOARD)/coreboot.rom - $(call do,DD 4MB,$@,dd of=$@ if=$< bs=65536 count=64 skip=128 status=none) - @sha256sum $@ +# Only flashing to the bios region is safe to do. The easiest is to +# flash internally when the IFD is unlocked for writing, and x230-flash +# is installed first. From 31cf85b7074a6e9a9da93faf0d5c4d1beaacb97e Mon Sep 17 00:00:00 2001 From: Kyle Rankin Date: Tue, 19 Jun 2018 12:27:27 -0700 Subject: [PATCH 002/102] Add Librem Key support to Heads The Librem Key is a custom device USB-based security token Nitrokey is producing for Purism and among other things it has custom firmware created for use with Heads. In particular, when a board is configured with CONFIG_LIBREMKEY, this custom firmware allows Heads to use the sealed TOTP secret to also send an HOTP authentication to the Librem Key. If the HOTP code is successful, the Librem Key will blink a green LED, if unsuccessful it will blink red, thereby informing the user that Heads has been tampered with without requiring them to use a phone to validate the TOTP secret. Heads will still use and show the TOTP secret, in case the user wants to validate both codes (in case the Librem Key was lost or is no longer trusted). It will also show the result of the HOTP verification (but not the code itself), even though the user should trust only what the Librem Key displays, so the user can confirm that both the device and Heads are in sync. If HOTP is enabled, Heads will maintain a new TPM counter separate from the Heads TPM counter that will increment each time HOTP codes are checked. This change also modifies the routines that update TOTP so that if the Librem Key executables are present it will also update HOTP codes and synchronize them with a Librem Key. --- Makefile | 2 +- boards/librem13v2/librem13v2.config | 1 + boards/librem15v3/librem15v3.config | 1 + initrd/bin/gui-init | 90 +++++++++++++++-------- initrd/bin/seal-libremkey | 84 +++++++++++++++++++++ initrd/bin/unseal-hotp | 63 ++++++++++++++++ initrd/etc/functions | 9 +-- modules/libremkey-hotp-verification | 19 +++++ patches/libremkey-hotp-verification.patch | 21 ++++++ 9 files changed, 253 insertions(+), 37 deletions(-) create mode 100755 initrd/bin/seal-libremkey create mode 100755 initrd/bin/unseal-hotp create mode 100644 modules/libremkey-hotp-verification create mode 100644 patches/libremkey-hotp-verification.patch diff --git a/Makefile b/Makefile index e77ecc56b..b1049b9e8 100644 --- a/Makefile +++ b/Makefile @@ -395,7 +395,7 @@ bin_modules-$(CONFIG_FLASHTOOLS) += flashtools bin_modules-$(CONFIG_NEWT) += newt bin_modules-$(CONFIG_CAIRO) += cairo bin_modules-$(CONFIG_FBWHIPTAIL) += fbwhiptail -bin_modules-$(CONFIG_NITROKEY) += nitrokey-hotp-verification +bin_modules-$(CONFIG_LIBREMKEY) += libremkey-hotp-verification $(foreach m, $(bin_modules-y), \ $(call map,initrd_bin_add,$(call bins,$m)) \ diff --git a/boards/librem13v2/librem13v2.config b/boards/librem13v2/librem13v2.config index 616a94724..699d591b8 100644 --- a/boards/librem13v2/librem13v2.config +++ b/boards/librem13v2/librem13v2.config @@ -20,6 +20,7 @@ CONFIG_TPMTOTP=y #CONFIG_NEWT=y CONFIG_CAIRO=y CONFIG_FBWHIPTAIL=y +CONFIG_LIBREMKEY=y CONFIG_LINUX_USB=y diff --git a/boards/librem15v3/librem15v3.config b/boards/librem15v3/librem15v3.config index a9a194be3..61c17042c 100644 --- a/boards/librem15v3/librem15v3.config +++ b/boards/librem15v3/librem15v3.config @@ -22,6 +22,7 @@ CONFIG_TPMTOTP=y #CONFIG_NEWT=y CONFIG_CAIRO=y CONFIG_FBWHIPTAIL=y +CONFIG_LIBREMKEY=y CONFIG_LINUX_USB=y diff --git a/initrd/bin/gui-init b/initrd/bin/gui-init index 4577dd635..27654cdc5 100755 --- a/initrd/bin/gui-init +++ b/initrd/bin/gui-init @@ -75,12 +75,7 @@ update_checksums() # We don't need them after the user decides to sign rm -f /boot/kexec_package_trigger* - # sign and auto-roll config counter - extparam= - if [ "$CONFIG_TPM" = "y" ]; then - extparam=-u - fi - kexec-sign-config -p /boot $extparam \ + kexec-sign-config -p /boot \ || die "Failed to sign default config" # switch back to ro mode @@ -89,6 +84,20 @@ update_checksums() echo "Returning to the main menu" fi } +update_totp() +{ + echo "Scan the QR code to add the new TOTP secret" + /bin/seal-totp + if [ -x /bin/libremkey_hotp_verification ]; then + echo "Once you have scanned the QR code, hit Enter to configure your Librem Key" + read + /bin/seal-libremkey + else + echo "Once you have scanned the QR code, hit Enter to reboot" + read + fi + /bin/reboot +} last_half=X while true; do @@ -106,7 +115,7 @@ while true; do if [ $? -ne 0 ]; then whiptail $CONFIG_ERROR_BG_COLOR --clear --title "ERROR: TOTP Generation Failed!" \ --menu "ERROR: Heads couldn't generate the TOTP code.\n\nIf you just reflashed your BIOS, you'll need to generate a new TOTP secret.\n\nIf you have not just reflashed your BIOS, THIS COULD INDICATE TAMPERING!\n\nIf this is the first time the system has booted, you should reset the TPM\nand set your own password\n\nHow would you like to proceed?" 30 90 4 \ - 'g' ' Generate new TOTP secret' \ + 'g' ' Generate new TOTP/HOTP secret' \ 'i' ' Ignore error and continue to default boot menu' \ 'p' ' Reset the TPM' \ 'x' ' Exit to recovery shell' \ @@ -117,11 +126,30 @@ while true; do fi if [ "$totp_confirm" = "i" -o -z "$totp_confirm" ]; then + if [ -x /bin/libremkey_hotp_verification ]; then + HOTP=`unseal-hotp` + enable_usb + # Don't output HOTP codes to screen, so as to make replay attacks harder + libremkey_hotp_verification check $HOTP + case "$?" in + 0 ) + HOTP="success" + ;; + 4 ) + HOTP="invalid code" + ;; + * ) + HOTP="error checking code" + ;; + esac + else + HOTP='N/A' + fi + whiptail --clear --title "$CONFIG_BOOT_GUI_MENU_NAME" \ - --menu "$date\nTOTP code: $TOTP" 20 90 10 \ + --menu "$date\nTOTP: $TOTP | HOTP: $HOTP" 20 90 10 \ 'y' ' Default boot' \ - 'r' ' TOTP does not match, refresh code' \ - 'n' ' TOTP does not match after refresh, troubleshoot' \ + 'r' ' TOTP/HOTP does not match, refresh code' \ 'o' ' Other Boot Options -->' \ 'a' ' Advanced Settings -->' \ 'x' ' Exit to recovery shell' \ @@ -145,10 +173,11 @@ while true; do if [ "$totp_confirm" = "a" ]; then whiptail --clear --title "Advanced Settings" \ --menu "Configure Advanced Settings" 20 90 10 \ - 'g' ' Generate new TOTP secret' \ - 'p' ' Reset the TPM' \ + 'g' ' Generate new TOTP/HOTP secret' \ 's' ' Update checksums and sign all files in /boot' \ 'f' ' Flash/Update the BIOS -->' \ + 'p' ' Reset the TPM' \ + 'n' ' TOTP/HOTP does not match after refresh, troubleshoot' \ 'r' ' <-- Return to main menu' \ 2>/tmp/whiptail || recovery "GUI menu failed" @@ -164,14 +193,14 @@ while true; do fi if [ "$totp_confirm" = "n" ]; then - if (whiptail $CONFIG_WARNING_BG_COLOR --title "TOTP code mismatched" \ - --yesno "TOTP code mismatches could indicate either TPM tampering or clock drift:\n\nTo correct clock drift: 'date -s HH:MM:SS'\nand save it to the RTC: 'hwclock -w'\nthen reboot and try again.\n\nWould you like to exit to a recovery console?" 30 90) then + if (whiptail $CONFIG_WARNING_BG_COLOR --title "TOTP/HOTP code mismatched" \ + --yesno "TOTP/HOTP code mismatches could indicate either TPM tampering or clock drift:\n\nTo correct clock drift: 'date -s HH:MM:SS'\nand save it to the RTC: 'hwclock -w'\nthen reboot and try again.\n\nWould you like to exit to a recovery console?" 30 90) then echo "" echo "To correct clock drift: 'date -s HH:MM:SS'" echo "and save it to the RTC: 'hwclock -w'" echo "then reboot and try again" echo "" - recovery "TOTP mismatch" + recovery "TOTP/HOTP mismatch" else continue fi @@ -183,13 +212,9 @@ while true; do fi if [ "$totp_confirm" = "g" ]; then - if (whiptail --title 'Generate new TOTP secret' \ + if (whiptail --title 'Generate new TOTP/HOTP secret' \ --yesno "This will erase your old secret and replace it with a new one!\n\nDo you want to proceed?" 16 90) then - echo "Scan the QR code to add the new TOTP secret" - /bin/seal-totp - echo "Once you have scanned the QR code, hit Enter to reboot" - read - /bin/reboot + update_totp else echo "Returning to the main menu" fi @@ -198,20 +223,27 @@ while true; do if [ "$totp_confirm" = "p" ]; then if (whiptail --title 'Reset the TPM' \ - --yesno "This will clear the TPM, erase the old TPM password and replace it with a new one!\n\nDo you want to proceed?" 16 90) then + --yesno "This will clear the TPM and TPM password, replace them with new ones!\n\nDo you want to proceed?" 16 90) then /bin/tpm-reset - # now that the TPM is reset, remove invalid kexec_rollback.txt file + # now that the TPM is reset, remove invalid TPM counter files mount_boot mount -o rw,remount /boot - rm -f /boot/kexec_rollback.txt + rm -f /boot/kexec_rollback.txt /boot/kexec_hotp_counter + + # create Heads TPM counter before any others + check_tpm_counter /boot/kexec_rollback.txt \ + || die "Unable to find/create tpm counter" + counter="$TPM_COUNTER" + + increment_tpm_counter $counter \ + || die "Unable to increment tpm counter" + + sha256sum /tmp/counter-$counter > /boot/kexec_rollback.txt \ + || die "Unable to create rollback file" mount -o ro,remount /boot - echo "Scan the QR code to add the new TOTP secret" - /bin/seal-totp - echo "Once you have scanned the QR code, hit Enter to reboot" - read - /bin/reboot + update_totp else echo "Returning to the main menu" fi diff --git a/initrd/bin/seal-libremkey b/initrd/bin/seal-libremkey new file mode 100755 index 000000000..2b7da4005 --- /dev/null +++ b/initrd/bin/seal-libremkey @@ -0,0 +1,84 @@ +#!/bin/sh +# Retrieve the sealed TOTP secret and initialize a Librem Key with it + +. /etc/functions + +HOTP_SEALED="/tmp/secret/hotp.sealed" +HOTP_SECRET="/tmp/secret/hotp.key" +HOTP_COUNTER="/boot/kexec_hotp_counter" + +mount_boot() +{ + # Mount local disk if it is not already mounted + if ! grep -q /boot /proc/mounts ; then + mount -o ro /boot \ + || recovery "Unable to mount /boot" + fi +} + +tpm nv_readvalue \ + -in 4d47 \ + -sz 312 \ + -of "$HOTP_SEALED" \ +|| die "Unable to retrieve sealed file from TPM NV" + +tpm unsealfile \ + -hk 40000000 \ + -if "$HOTP_SEALED" \ + -of "$HOTP_SECRET" \ +|| die "Unable to unseal HOTP secret" + +rm -f "$HOTP_SEALED" +secret="`cat $HOTP_SECRET`" +rm -f "$HOTP_SECRET" + +# get current value of HOTP counter in TPM, create if absent +mount_boot + +check_tpm_counter $HOTP_COUNTER hotp \ +|| die "Unable to find/create TPM counter" +counter="$TPM_COUNTER" + +counter_value=$(read_tpm_counter $counter | cut -f2 -d ' ' | awk 'gsub("^000e","")') + +if [ "$counter_value" == "" ]; then + die "Unable to read HOTP TPM counter" +fi + +counter_value=$(printf "%d" 0x${counter_value}) + +enable_usb +if ! libremkey_hotp_verification info ; then + echo "Insert your Librem Key and press Enter to configure it" + read + libremkey_hotp_verification info \ + || die "Unable to find Librem Key" +fi + +read -s -p "Enter your Librem Key Admin PIN" admin_pin +echo + +libremkey_hotp_initialize $admin_pin $secret $counter_value +if [ $? -ne 0 ]; then + read -s -p "Error setting HOTP secret, re-enter Admin PIN and try again:" admin_pin + libremkey_hotp_initialize $admin_pin $secret $counter_value \ + || die "Setting HOTP secret failed" +fi + +secret="" + +# Make sure our counter is incremented ahead of the next check +increment_tpm_counter $counter > /dev/null \ +|| die "Unable to increment tpm counter" +increment_tpm_counter $counter > /dev/null \ +|| die "Unable to increment tpm counter" + +mount -o remount,rw /boot +sha256sum /tmp/counter-$counter > $HOTP_COUNTER \ +|| die "Unable to create hotp counter file" +mount -o remount,ro /boot + +echo "Librem Key initialized successfully. Press Enter to continue." +read + +exit 0 diff --git a/initrd/bin/unseal-hotp b/initrd/bin/unseal-hotp new file mode 100755 index 000000000..5d7d225d0 --- /dev/null +++ b/initrd/bin/unseal-hotp @@ -0,0 +1,63 @@ +#!/bin/sh +# Retrieve the sealed file and counter from the NVRAM, unseal it and compute the hotp + +. /etc/functions + +HOTP_SEALED="/tmp/secret/hotp.sealed" +HOTP_SECRET="/tmp/secret/hotp.key" +HOTP_COUNTER="/boot/kexec_hotp_counter" + +mount_boot() +{ + # Mount local disk if it is not already mounted + if ! grep -q /boot /proc/mounts ; then + mount -o ro /boot \ + || recovery "Unable to mount /boot" + fi +} + +tpm nv_readvalue \ + -in 4d47 \ + -sz 312 \ + -of "$HOTP_SEALED" \ +|| die "Unable to retrieve sealed file from TPM NV" + +tpm unsealfile \ + -hk 40000000 \ + -if "$HOTP_SEALED" \ + -of "$HOTP_SECRET" \ +|| die "Unable to unseal HOTP secret" + +rm -f "$HOTP_SEALED" + +# get current value of HOTP counter in TPM, create if absent +mount_boot + +check_tpm_counter $HOTP_COUNTER hotp \ +|| die "Unable to find/create TPM counter" +counter="$TPM_COUNTER" + +counter_value=$(read_tpm_counter $counter | cut -f2 -d ' ' | awk 'gsub("^000e","")') + +if [ "$counter_value" == "" ]; then + die "Unable to read HOTP TPM counter" +fi + +counter_value=$(printf "%d" 0x${counter_value}) + +if ! hotp $counter_value < "$HOTP_SECRET"; then + rm -f "$HOTP_SECRET" + die 'Unable to compute HOTP hash?' +fi + +rm -f "$HOTP_SECRET" + +increment_tpm_counter $counter > /dev/null \ +|| die "Unable to increment tpm counter" + +mount -o remount,rw /boot +sha256sum /tmp/counter-$counter > $HOTP_COUNTER \ +|| die "Unable to create hotp counter file" +mount -o remount,ro /boot + +exit 0 diff --git a/initrd/etc/functions b/initrd/etc/functions index 17a81c277..4488476a4 100755 --- a/initrd/etc/functions +++ b/initrd/etc/functions @@ -138,18 +138,13 @@ confirm_gpg_card() check_tpm_counter() { + LABEL=${2:-3135106223} # if the /boot.hashes file already exists, read the TPM counter ID # from it. if [ -r "$1" ]; then TPM_COUNTER=`grep counter- "$1" | cut -d- -f2` else - # Initialize label to default if not set - if [ "$2" != "" ]; then - LABEL=$2 - else - LABEL=3135106223 - fi - warn "$BOOT_HASHES does not exist; creating new TPM counter" + warn "$1 does not exist; creating new TPM counter" read -s -p "TPM Owner password: " tpm_password echo tpm counter_create \ diff --git a/modules/libremkey-hotp-verification b/modules/libremkey-hotp-verification new file mode 100644 index 000000000..c9b9d45ab --- /dev/null +++ b/modules/libremkey-hotp-verification @@ -0,0 +1,19 @@ +modules-$(CONFIG_LIBREMKEY) += libremkey-hotp-verification + +libremkey-hotp-verification_depends := libusb $(musl_dep) + +libremkey-hotp-verification_version := git +libremkey-hotp-verification_dir := libremkey-hotp-verification +libremkey-hotp-verification_repo := --recursive https://github.com/Nitrokey/nitrokey-hotp-verification + +libremkey-hotp-verification_target := \ + $(MAKE_JOBS) \ + $(CROSS_TOOLS) \ + +libremkey-hotp-verification_output := \ + libremkey_hotp_verification \ + libremkey_hotp_initialize + +libremkey-hotp-verification_configure := \ + INSTALL="$(INSTALL)" \ + cmake -DCMAKE_TOOLCHAIN_FILE=./Toolchain-heads.cmake -DCMAKE_AR="$(CROSS)ar" . diff --git a/patches/libremkey-hotp-verification.patch b/patches/libremkey-hotp-verification.patch new file mode 100644 index 000000000..13ad08610 --- /dev/null +++ b/patches/libremkey-hotp-verification.patch @@ -0,0 +1,21 @@ +--- nitrokey-hotp-verification-a/Toolchain-heads.cmake 2018-05-22 09:55:46.907209235 -0700 ++++ nitrokey-hotp-verification-b/Toolchain-heads.cmake 2018-05-22 09:55:26.659371966 -0700 +@@ -0,0 +1,18 @@ ++SET(CMAKE_SYSTEM_NAME Linux) ++SET(CMAKE_SYSTEM_VERSION 1) ++ ++# Specify the cross compiler ++SET(CMAKE_C_COMPILER $ENV{INSTALL}/bin/musl-gcc) ++SET(CMAKE_CXX_COMPILER $ENV{INSTALL}/bin/musl-gcc) ++ ++# Where is the target environment ++SET(CMAKE_FIND_ROOT_PATH $ENV{INSTALL}) ++ ++# Search for programs only in the build host directories ++SET(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER) ++ ++# Search for libraries and headers only in the target directories ++SET(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ONLY) ++SET(CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ONLY) ++ ++INCLUDE_DIRECTORIES(hidapi) From 2cacb1572971b50923c9844e19e48bcc9e139a15 Mon Sep 17 00:00:00 2001 From: Kyle Rankin Date: Tue, 19 Jun 2018 13:03:01 -0700 Subject: [PATCH 003/102] Add back TPM config counter section to gui-init The section in gui-init that modifies the Heads TPM counter when signing config was accidentally removed. This change adds that section back. --- initrd/bin/gui-init | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/initrd/bin/gui-init b/initrd/bin/gui-init index 27654cdc5..aaa47da86 100755 --- a/initrd/bin/gui-init +++ b/initrd/bin/gui-init @@ -75,7 +75,12 @@ update_checksums() # We don't need them after the user decides to sign rm -f /boot/kexec_package_trigger* - kexec-sign-config -p /boot \ + # sign and auto-roll config counter + extparam= + if [ "$CONFIG_TPM" = "y" ]; then + extparam=-u + fi + kexec-sign-config -p /boot $extparam \ || die "Failed to sign default config" # switch back to ro mode From c42084406d47409ccce5ac6ddd717b576b693eb3 Mon Sep 17 00:00:00 2001 From: Kyle Rankin Date: Tue, 19 Jun 2018 16:18:10 -0700 Subject: [PATCH 004/102] Use HOTP TPM counter instead of Heads when signing, if present TPM v1.2 has a limitation in that only a single monotonic counter can be incremented between reboots [1]. So in the event we are using HOTP monotonic counters, we need to reference those for the Heads rollback counter when we update file signatures in /boot, otherwise the increment stage at kexec-sign-config will fail since at each boot, the HOTP monotonic counter has already been incremented. [1] https://projects.csail.mit.edu/tc/tpmj/UsersGuide.html#inccounter --- initrd/bin/gui-init | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/initrd/bin/gui-init b/initrd/bin/gui-init index aaa47da86..1f4e3dcf4 100755 --- a/initrd/bin/gui-init +++ b/initrd/bin/gui-init @@ -78,7 +78,14 @@ update_checksums() # sign and auto-roll config counter extparam= if [ "$CONFIG_TPM" = "y" ]; then - extparam=-u + if [ -x /bin/libremkey_hotp_verification ]; then + check_tpm_counter /boot/kexec_hotp_counter hotp \ + || die "Unable to find/create TPM counter" + counter="$TPM_COUNTER" + extparam="-c $counter" + else + extparam=-u + fi fi kexec-sign-config -p /boot $extparam \ || die "Failed to sign default config" @@ -241,9 +248,6 @@ while true; do || die "Unable to find/create tpm counter" counter="$TPM_COUNTER" - increment_tpm_counter $counter \ - || die "Unable to increment tpm counter" - sha256sum /tmp/counter-$counter > /boot/kexec_rollback.txt \ || die "Unable to create rollback file" mount -o ro,remount /boot From 7dde5c2aca74c19195a71338324743bf3bf4d952 Mon Sep 17 00:00:00 2001 From: Kyle Rankin Date: Tue, 19 Jun 2018 16:28:37 -0700 Subject: [PATCH 005/102] Revert "Use HOTP TPM counter instead of Heads when signing, if present" This reverts commit c42084406d47409ccce5ac6ddd717b576b693eb3. --- initrd/bin/gui-init | 12 ++++-------- 1 file changed, 4 insertions(+), 8 deletions(-) diff --git a/initrd/bin/gui-init b/initrd/bin/gui-init index 1f4e3dcf4..aaa47da86 100755 --- a/initrd/bin/gui-init +++ b/initrd/bin/gui-init @@ -78,14 +78,7 @@ update_checksums() # sign and auto-roll config counter extparam= if [ "$CONFIG_TPM" = "y" ]; then - if [ -x /bin/libremkey_hotp_verification ]; then - check_tpm_counter /boot/kexec_hotp_counter hotp \ - || die "Unable to find/create TPM counter" - counter="$TPM_COUNTER" - extparam="-c $counter" - else - extparam=-u - fi + extparam=-u fi kexec-sign-config -p /boot $extparam \ || die "Failed to sign default config" @@ -248,6 +241,9 @@ while true; do || die "Unable to find/create tpm counter" counter="$TPM_COUNTER" + increment_tpm_counter $counter \ + || die "Unable to increment tpm counter" + sha256sum /tmp/counter-$counter > /boot/kexec_rollback.txt \ || die "Unable to create rollback file" mount -o ro,remount /boot From fe34aba719073ef3710b25627b0acbbb5236815d Mon Sep 17 00:00:00 2001 From: Kyle Rankin Date: Wed, 20 Jun 2018 09:20:39 -0700 Subject: [PATCH 006/102] Store HOTP counter directly in /boot instead of TPM The HOTP counter isn't a secret but is just used to prevent replay attacks (the time-based counter in TOTP isn't a secret either) so it doesn't need to be protected in the TPM and storing it as a TPM monotonic counter was causing conflicts with the Heads configuration counter as TPM 1.2 can only increment one counter per reboot. This change moves the HOTP counter into the file in /boot that was previously keeping track of the TPM counter id. --- initrd/bin/gui-init | 2 +- initrd/bin/seal-libremkey | 36 ++++++++++++++++++++++-------------- initrd/bin/unseal-hotp | 28 +++++++++++++++++++--------- 3 files changed, 42 insertions(+), 24 deletions(-) diff --git a/initrd/bin/gui-init b/initrd/bin/gui-init index aaa47da86..64122b72a 100755 --- a/initrd/bin/gui-init +++ b/initrd/bin/gui-init @@ -234,7 +234,7 @@ while true; do # now that the TPM is reset, remove invalid TPM counter files mount_boot mount -o rw,remount /boot - rm -f /boot/kexec_rollback.txt /boot/kexec_hotp_counter + rm -f /boot/kexec_rollback.txt # create Heads TPM counter before any others check_tpm_counter /boot/kexec_rollback.txt \ diff --git a/initrd/bin/seal-libremkey b/initrd/bin/seal-libremkey index 2b7da4005..ddee9e979 100755 --- a/initrd/bin/seal-libremkey +++ b/initrd/bin/seal-libremkey @@ -32,20 +32,23 @@ rm -f "$HOTP_SEALED" secret="`cat $HOTP_SECRET`" rm -f "$HOTP_SECRET" +# Store counter in file instead of TPM for now, as it conflicts with Heads +# config TPM counter as TPM 1.2 can only increment one counter between reboots # get current value of HOTP counter in TPM, create if absent mount_boot -check_tpm_counter $HOTP_COUNTER hotp \ -|| die "Unable to find/create TPM counter" -counter="$TPM_COUNTER" +#check_tpm_counter $HOTP_COUNTER hotp \ +#|| die "Unable to find/create TPM counter" +#counter="$TPM_COUNTER" +# +#counter_value=$(read_tpm_counter $counter | cut -f2 -d ' ' | awk 'gsub("^000e","")') +#if [ "$counter_value" == "" ]; then +# die "Unable to read HOTP counter" +#fi -counter_value=$(read_tpm_counter $counter | cut -f2 -d ' ' | awk 'gsub("^000e","")') +#counter_value=$(printf "%d" 0x${counter_value}) -if [ "$counter_value" == "" ]; then - die "Unable to read HOTP TPM counter" -fi - -counter_value=$(printf "%d" 0x${counter_value}) +counter_value=1 enable_usb if ! libremkey_hotp_verification info ; then @@ -68,14 +71,19 @@ fi secret="" # Make sure our counter is incremented ahead of the next check -increment_tpm_counter $counter > /dev/null \ -|| die "Unable to increment tpm counter" -increment_tpm_counter $counter > /dev/null \ -|| die "Unable to increment tpm counter" +#increment_tpm_counter $counter > /dev/null \ +#|| die "Unable to increment tpm counter" +#increment_tpm_counter $counter > /dev/null \ +#|| die "Unable to increment tpm counter" mount -o remount,rw /boot -sha256sum /tmp/counter-$counter > $HOTP_COUNTER \ + +counter_value=`expr $counter_value + 1` +echo $counter_value > $HOTP_COUNTER \ || die "Unable to create hotp counter file" + +#sha256sum /tmp/counter-$counter > $HOTP_COUNTER \ +#|| die "Unable to create hotp counter file" mount -o remount,ro /boot echo "Librem Key initialized successfully. Press Enter to continue." diff --git a/initrd/bin/unseal-hotp b/initrd/bin/unseal-hotp index 5d7d225d0..8d4ef192f 100755 --- a/initrd/bin/unseal-hotp +++ b/initrd/bin/unseal-hotp @@ -30,20 +30,25 @@ tpm unsealfile \ rm -f "$HOTP_SEALED" +# Store counter in file instead of TPM for now, as it conflicts with Heads +# config TPM counter as TPM 1.2 can only increment one counter between reboots # get current value of HOTP counter in TPM, create if absent mount_boot -check_tpm_counter $HOTP_COUNTER hotp \ -|| die "Unable to find/create TPM counter" -counter="$TPM_COUNTER" +#check_tpm_counter $HOTP_COUNTER hotp \ +#|| die "Unable to find/create TPM counter" +#counter="$TPM_COUNTER" +# +#counter_value=$(read_tpm_counter $counter | cut -f2 -d ' ' | awk 'gsub("^000e","")') +# -counter_value=$(read_tpm_counter $counter | cut -f2 -d ' ' | awk 'gsub("^000e","")') +counter_value=$(cat $HOTP_COUNTER) if [ "$counter_value" == "" ]; then - die "Unable to read HOTP TPM counter" + die "Unable to read HOTP counter" fi -counter_value=$(printf "%d" 0x${counter_value}) +#counter_value=$(printf "%d" 0x${counter_value}) if ! hotp $counter_value < "$HOTP_SECRET"; then rm -f "$HOTP_SECRET" @@ -52,12 +57,17 @@ fi rm -f "$HOTP_SECRET" -increment_tpm_counter $counter > /dev/null \ -|| die "Unable to increment tpm counter" +#increment_tpm_counter $counter > /dev/null \ +#|| die "Unable to increment tpm counter" mount -o remount,rw /boot -sha256sum /tmp/counter-$counter > $HOTP_COUNTER \ + +counter_value=`expr $counter_value + 1` +echo $counter_value > $HOTP_COUNTER \ || die "Unable to create hotp counter file" + +#sha256sum /tmp/counter-$counter > $HOTP_COUNTER \ +#|| die "Unable to create hotp counter file" mount -o remount,ro /boot exit 0 From ec3248dbc948ded7ea115fd2d24599d9ad852043 Mon Sep 17 00:00:00 2001 From: Kyle Rankin Date: Wed, 20 Jun 2018 16:20:15 -0700 Subject: [PATCH 007/102] Shorten timeout for Librem Key Currently the Librem Key tests will time out after 40 seconds, which adds to the boot time significantly if the user wants to boot without inserting it. This patch changes that timeout to one second. --- patches/libremkey-hotp-verification.patch | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/patches/libremkey-hotp-verification.patch b/patches/libremkey-hotp-verification.patch index 13ad08610..5376da03b 100644 --- a/patches/libremkey-hotp-verification.patch +++ b/patches/libremkey-hotp-verification.patch @@ -19,3 +19,14 @@ +SET(CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ONLY) + +INCLUDE_DIRECTORIES(hidapi) +--- libremkey-hotp-verification/device.c 2018-06-20 16:13:36.417804210 -0700 ++++ libremkey-hotp-verification-b/device.c 2018-06-20 16:14:34.532367723 -0700 +@@ -34,7 +34,7 @@ + const unsigned short m_vid = 0x20a0; + const unsigned short m_pid = 0x4108; + +-static const int CONNECTION_ATTEMPTS_COUNT = 80; ++static const int CONNECTION_ATTEMPTS_COUNT = 2; + + static const int CONNECTION_ATTEMPT_DELAY_MICRO_SECONDS = 1000*1000/2; + From be665ac4f9f9c4054b9cbbdf55d124e5aee4f002 Mon Sep 17 00:00:00 2001 From: Kyle Rankin Date: Thu, 21 Jun 2018 16:04:46 -0700 Subject: [PATCH 008/102] Show red background when HOTP code is invalid Granted the user should really be using the Librem Key/phone to check for tampering (since an attacker could control the Heads background color) but this provides another visual queue for the user with the GUI menu to catch less sophisticated tampering. --- initrd/bin/gui-init | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/initrd/bin/gui-init b/initrd/bin/gui-init index 64122b72a..7424b13fd 100755 --- a/initrd/bin/gui-init +++ b/initrd/bin/gui-init @@ -107,6 +107,7 @@ update_totp() last_half=X while true; do MAIN_MENU_OPTIONS="" + MAIN_MENU_BG_COLOR="" unset totp_confirm # update the TOTP code every thirty seconds date=`date "+%Y-%m-%d %H:%M:%S"` @@ -142,6 +143,7 @@ while true; do ;; 4 ) HOTP="invalid code" + MAIN_MENU_BG_COLOR=$CONFIG_ERROR_BG_COLOR ;; * ) HOTP="error checking code" @@ -151,7 +153,7 @@ while true; do HOTP='N/A' fi - whiptail --clear --title "$CONFIG_BOOT_GUI_MENU_NAME" \ + whiptail $MAIN_MENU_BG_COLOR --clear --title "$CONFIG_BOOT_GUI_MENU_NAME" \ --menu "$date\nTOTP: $TOTP | HOTP: $HOTP" 20 90 10 \ 'y' ' Default boot' \ 'r' ' TOTP/HOTP does not match, refresh code' \ From acb2b34873e641dfc5d94c6de6ee62422ae8809a Mon Sep 17 00:00:00 2001 From: Kyle Rankin Date: Thu, 21 Jun 2018 16:30:35 -0700 Subject: [PATCH 009/102] Show warning bg color in main menu when HOTP key not found --- initrd/bin/gui-init | 1 + 1 file changed, 1 insertion(+) diff --git a/initrd/bin/gui-init b/initrd/bin/gui-init index 7424b13fd..9e75b42a3 100755 --- a/initrd/bin/gui-init +++ b/initrd/bin/gui-init @@ -147,6 +147,7 @@ while true; do ;; * ) HOTP="error checking code" + MAIN_MENU_BG_COLOR=$CONFIG_WARNING_BG_COLOR ;; esac else From fd99d160e83550518b754fd1eb7f9b4925c08ae0 Mon Sep 17 00:00:00 2001 From: Kyle Rankin Date: Tue, 3 Jul 2018 12:40:52 -0700 Subject: [PATCH 010/102] Improve status messages for Librem Key HOTP output --- initrd/bin/gui-init | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/initrd/bin/gui-init b/initrd/bin/gui-init index 9e75b42a3..957ebba41 100755 --- a/initrd/bin/gui-init +++ b/initrd/bin/gui-init @@ -139,14 +139,14 @@ while true; do libremkey_hotp_verification check $HOTP case "$?" in 0 ) - HOTP="success" + HOTP="Success" ;; 4 ) - HOTP="invalid code" + HOTP="Invalid code" MAIN_MENU_BG_COLOR=$CONFIG_ERROR_BG_COLOR ;; * ) - HOTP="error checking code" + HOTP="Error checking code, Insert Librem Key and retry" MAIN_MENU_BG_COLOR=$CONFIG_WARNING_BG_COLOR ;; esac From 95748a82d775636f2f6d97df4f4f5e4b6331a768 Mon Sep 17 00:00:00 2001 From: tlaurion Date: Mon, 3 Sep 2018 12:03:19 -0400 Subject: [PATCH 011/102] Typo correction in .ash_history --- initrd/.ash_history | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/initrd/.ash_history b/initrd/.ash_history index 7efa5ffd2..0fb274ebf 100644 --- a/initrd/.ash_history +++ b/initrd/.ash_history @@ -3,8 +3,8 @@ mount -o remount,rw /boot rm /boot/kexec_* usb-scan mount -o rw $CONFIG_USB_BOOT_DEV /media -mkdir /media/gpg_keys -gpg --home=/media/gpg_keys --edit-card +mkdir -p /media/gpg_keys +gpg --home=/media/gpg_keys --card-edit gpg --home=/media/gpg_keys --export --armor e@mail.address > /media/gpg_keys/public.key gpg --home=/media/gpg_keys --export-secret-keys --armor e@mail.address > /media/gpg_keys/private.key cbfs -o /media/coreboot.rom -a "heads/initrd/.gnupg/keys/public.key" -f /media/gpg_keys/public.key From c0aeb614ec3c00daf673b2a537ea8a470cb9a946 Mon Sep 17 00:00:00 2001 From: tlaurion Date: Thu, 4 Oct 2018 22:01:54 -0400 Subject: [PATCH 012/102] Update .ash_history mount-usb is better --- initrd/.ash_history | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/initrd/.ash_history b/initrd/.ash_history index 0fb274ebf..d7acdebe9 100644 --- a/initrd/.ash_history +++ b/initrd/.ash_history @@ -1,8 +1,7 @@ mount /dev/sda1 /boot mount -o remount,rw /boot rm /boot/kexec_* -usb-scan -mount -o rw $CONFIG_USB_BOOT_DEV /media +mount-usb mkdir -p /media/gpg_keys gpg --home=/media/gpg_keys --card-edit gpg --home=/media/gpg_keys --export --armor e@mail.address > /media/gpg_keys/public.key From 1d2fb0266812d97c969b6226a300280706f659ee Mon Sep 17 00:00:00 2001 From: Thierry Laurion Date: Mon, 8 Oct 2018 16:26:20 -0400 Subject: [PATCH 013/102] Adding cryptsetup-reencrypt support --- modules/cryptsetup | 2 ++ 1 file changed, 2 insertions(+) diff --git a/modules/cryptsetup b/modules/cryptsetup index e81d356d4..4cea7f359 100644 --- a/modules/cryptsetup +++ b/modules/cryptsetup @@ -15,6 +15,7 @@ cryptsetup_configure := ./configure \ --host i386-elf-linux \ --prefix "/" \ --disable-gcrypt-pbkdf2 \ + --enable-cryptsetup-reencrypt \ --with-crypto_backend=kernel \ # but after building, replace prefix so that they will be installed @@ -28,6 +29,7 @@ cryptsetup_target := \ cryptsetup_output := \ src/.libs/cryptsetup \ + src/.libs/cryptsetup-reencrypt \ src/.libs/veritysetup \ cryptsetup_libraries := \ From 255181c02f15354a8b1968dbc847321913eb4ea7 Mon Sep 17 00:00:00 2001 From: Martin Kepplinger Date: Thu, 18 Oct 2018 13:44:44 +0200 Subject: [PATCH 014/102] fix the fbwhiptail source URL The current source URL is not available anymore. kakaroto changed his copy of heads to point to his own github account's fbwhiptail: https://github.com/kakaroto/heads/commit/b13cc5e68d9d77ef9bfd6623b812f4205698dafb But it seems that source.puri.sm/coreboot is a more accessible home for the project. --- modules/fbwhiptail | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modules/fbwhiptail b/modules/fbwhiptail index dbf40dbaa..f54a62d82 100644 --- a/modules/fbwhiptail +++ b/modules/fbwhiptail @@ -4,7 +4,7 @@ fbwhiptail_depends := cairo $(musl_dep) fbwhiptail_version := git fbwhiptail_dir := fbwhiptail -fbwhiptail_repo := https://code.puri.sm/kakaroto/fbwhiptail.git +fbwhiptail_repo := https://source.puri.sm/coreboot/fbwhiptail.git fbwhiptail_target := \ $(MAKE_JOBS) \ From 3755ddb47a5aece00b02c186bc87850e8dc8ffd8 Mon Sep 17 00:00:00 2001 From: Thierry Laurion Date: Mon, 22 Oct 2018 11:01:05 -0400 Subject: [PATCH 015/102] $TMP_MENU_FILE is an unknown variable. Replaced with /tmp/iso_menu.txt so usb-scan works. --- initrd/bin/usb-scan | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/initrd/bin/usb-scan b/initrd/bin/usb-scan index 66de9555d..57f6879b0 100755 --- a/initrd/bin/usb-scan +++ b/initrd/bin/usb-scan @@ -26,7 +26,7 @@ get_menu_option() { n=`expr $n + 1` option=$(echo $option | tr " " "_") MENU_OPTIONS="$MENU_OPTIONS $n ${option}" - done < $TMP_MENU_FILE + done < /tmp/iso_menu.txt whiptail --clear --title "Select your ISO boot option" \ --menu "Choose the ISO boot option [1-$n, s for standard boot, a to abort]:" 20 120 8 \ From 72c42fa5ea1e7831fd3250993879b4cda032e507 Mon Sep 17 00:00:00 2001 From: Trammell Hudson Date: Wed, 24 Oct 2018 14:28:34 -0400 Subject: [PATCH 016/102] qemu-linuxboot: enable cgroups for u-root --- config/linux-qemu.config | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) diff --git a/config/linux-qemu.config b/config/linux-qemu.config index 71a6dc259..a76f37f3f 100644 --- a/config/linux-qemu.config +++ b/config/linux-qemu.config @@ -6,6 +6,18 @@ CONFIG_KERNEL_XZ=y # CONFIG_USELIB is not set CONFIG_NO_HZ_IDLE=y CONFIG_LOG_BUF_SHIFT=18 +CONFIG_CGROUPS=y +CONFIG_MEMCG=y +CONFIG_BLK_CGROUP=y +CONFIG_CGROUP_SCHED=y +CONFIG_CGROUP_PIDS=y +CONFIG_CGROUP_RDMA=y +CONFIG_CGROUP_FREEZER=y +CONFIG_CPUSETS=y +CONFIG_CGROUP_DEVICE=y +CONFIG_CGROUP_CPUACCT=y +CONFIG_CGROUP_PERF=y +CONFIG_CGROUP_DEBUG=y CONFIG_BLK_DEV_INITRD=y CONFIG_INITRAMFS_SOURCE="../../../blobs/dev.cpio" # CONFIG_RD_GZIP is not set @@ -19,7 +31,6 @@ CONFIG_CC_OPTIMIZE_FOR_SIZE=y # CONFIG_BASE_FULL is not set # CONFIG_SIGNALFD is not set # CONFIG_TIMERFD is not set -# CONFIG_EVENTFD is not set # CONFIG_AIO is not set # CONFIG_MEMBARRIER is not set CONFIG_EMBEDDED=y @@ -69,6 +80,7 @@ CONFIG_PCI_PRI=y CONFIG_IA32_EMULATION=y CONFIG_NET=y CONFIG_PACKET=y +CONFIG_UNIX=y CONFIG_INET=y CONFIG_SYN_COOKIES=y # CONFIG_INET_XFRM_MODE_TRANSPORT is not set From c326ff62c7efe7198d503974f6aa142ad7bb11e2 Mon Sep 17 00:00:00 2001 From: Francis Lam Date: Sun, 20 May 2018 16:05:07 -0700 Subject: [PATCH 017/102] Start updating to coreboot 4.8.1 missing librem patches --- config/coreboot-kgpe-d16.config | 69 ++- config/coreboot-qemu.config | 61 ++- config/coreboot-x220.config | 74 ++- config/coreboot-x230-flash.config | 72 ++- config/coreboot-x230.config | 72 ++- modules/coreboot | 6 +- .../coreboot-4.8.1/0000-measuredboot.patch | 474 ++++++++++++++++++ patches/coreboot-4.8.1/0020-kgpe-d16.patch | 152 ++++++ patches/coreboot-4.8.1/0030-sandybridge.patch | 58 +++ 9 files changed, 909 insertions(+), 129 deletions(-) create mode 100644 patches/coreboot-4.8.1/0000-measuredboot.patch create mode 100644 patches/coreboot-4.8.1/0020-kgpe-d16.patch create mode 100644 patches/coreboot-4.8.1/0030-sandybridge.patch diff --git a/config/coreboot-kgpe-d16.config b/config/coreboot-kgpe-d16.config index e294e9444..adc415020 100644 --- a/config/coreboot-kgpe-d16.config +++ b/config/coreboot-kgpe-d16.config @@ -35,9 +35,7 @@ CONFIG_INCLUDE_CONFIG_FILE=y # # 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 @@ -48,18 +46,14 @@ CONFIG_INCLUDE_CONFIG_FILE=y # 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 @@ -72,40 +66,34 @@ CONFIG_VENDOR_ASUS=y # 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_OCP 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_SCALEWAY is not set # CONFIG_VENDOR_SIEMENS is not set -# CONFIG_VENDOR_SOYO is not set +# CONFIG_VENDOR_SIFIVE 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" @@ -134,7 +122,6 @@ CONFIG_MAINBOARD_SMBIOS_MANUFACTURER="ASUS" # 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 @@ -150,8 +137,7 @@ CONFIG_BOARD_ASUS_KGPE_D16=y # 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_MAXIMUS_IV_GENE_Z 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 @@ -159,7 +145,6 @@ CONFIG_BOARD_ASUS_KGPE_D16=y # 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 @@ -167,7 +152,7 @@ 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_MMCONF_BASE_ADDRESS=0xc0000000 CONFIG_POST_DEVICE=y # CONFIG_VBOOT is not set CONFIG_TPM_PIRQ=0x0 @@ -185,6 +170,7 @@ CONFIG_MAINBOARD_VERSION="1.0" CONFIG_DRIVERS_PS2_KEYBOARD=y CONFIG_PCIEXP_L1_SUB_STATE=y # CONFIG_NO_POST is not set +CONFIG_SMBIOS_ENCLOSURE_TYPE=0x03 CONFIG_BOARD_ROMSIZE_KB_2048=y # CONFIG_COREBOOT_ROMSIZE_KB_64 is not set # CONFIG_COREBOOT_ROMSIZE_KB_128 is not set @@ -201,7 +187,6 @@ CONFIG_COREBOOT_ROMSIZE_KB_16384=y # 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 @@ -235,7 +220,6 @@ 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 @@ -245,6 +229,7 @@ CONFIG_TTYS0_BAUD=115200 # CONFIG_SOC_NVIDIA_TEGRA210 is not set # CONFIG_SOC_QC_IPQ40XX is not set # CONFIG_SOC_QC_IPQ806X is not set +# CONFIG_SOC_QUALCOMM_SDM845 is not set # CONFIG_SOC_ROCKCHIP_RK3288 is not set # CONFIG_SOC_ROCKCHIP_RK3399 is not set # CONFIG_CPU_SAMSUNG_EXYNOS5250 is not set @@ -341,6 +326,7 @@ CONFIG_LIMIT_HT_UP_WIDTH_16=y # CONFIG_NORTHBRIDGE_AMD_PI is not set # CONFIG_NORTHBRIDGE_INTEL_COMMON_MRC_CACHE is not set CONFIG_HPET_ADDRESS=0xfed00000 +CONFIG_HPET_MIN_TICKS=0x14 CONFIG_MAX_PIRQ_LINKS=4 # @@ -363,6 +349,7 @@ CONFIG_SOUTHBRIDGE_AMD_SR5650=y # 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_COMMON_SMM is not set # # Super I/O @@ -378,6 +365,11 @@ CONFIG_SUPERIO_WINBOND_W83667HG_A=y # CONFIG_GOOGLE_SMBIOS_MAINBOARD_VERSION is not set # CONFIG_UEFI_2_4_BINDING is not set # CONFIG_UDK_2015_BINDING is not set +# CONFIG_UDK_2017_BINDING is not set +CONFIG_UDK_2013_VERSION=2013 +CONFIG_UDK_2015_VERSION=2015 +CONFIG_UDK_2017_VERSION=2017 +CONFIG_UDK_VERSION=2013 # CONFIG_USE_SIEMENS_HWILIB is not set # CONFIG_ARCH_ARM is not set # CONFIG_ARCH_BOOTBLOCK_ARM is not set @@ -408,6 +400,8 @@ CONFIG_SUPERIO_WINBOND_W83667HG_A=y # 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_ARCH_ARMV8_EXTENSION=0 +# CONFIG_ARM64_USE_ARCH_TIMER is not set # CONFIG_ARM64_A53_ERRATUM_843419 is not set # CONFIG_ARCH_MIPS is not set # CONFIG_ARCH_BOOTBLOCK_MIPS is not set @@ -420,6 +414,7 @@ CONFIG_SUPERIO_WINBOND_W83667HG_A=y # CONFIG_ARCH_ROMSTAGE_POWER8 is not set # CONFIG_ARCH_RAMSTAGE_POWER8 is not set # CONFIG_ARCH_RISCV is not set +# CONFIG_ARCH_RISCV_COMPRESSED is not set # CONFIG_ARCH_BOOTBLOCK_RISCV is not set # CONFIG_ARCH_VERSTAGE_RISCV is not set # CONFIG_ARCH_ROMSTAGE_RISCV is not set @@ -447,21 +442,30 @@ 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_ID_SECTION_OFFSET=0x80 # 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" +# CONFIG_PAGING_IN_CACHE_AS_RAM is not set +# CONFIG_IDT_IN_EVERY_STAGE is not set # # Devices # +CONFIG_HAVE_VGA_TEXT_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_SMBUS_HAS_AUX_CHANNELS=y CONFIG_PCI=y CONFIG_MMCONF_SUPPORT=y @@ -518,7 +522,9 @@ CONFIG_HAVE_USBDEBUG_OPTIONS=y CONFIG_DRIVERS_ASPEED_AST2050=y CONFIG_DRIVERS_ASPEED_AST_COMMON=y # CONFIG_SMBIOS_PROVIDED_BY_MOBO is not set +# CONFIG_DRIVERS_I2C_MAX98373 is not set # CONFIG_DRIVERS_I2C_MAX98927 is not set +# CONFIG_DRIVERS_I2C_PCA9538 is not set # CONFIG_DRIVERS_I2C_PCF8523 is not set # CONFIG_DRIVERS_I2C_RT5663 is not set # CONFIG_DRIVERS_I2C_RTD2132 is not set @@ -527,11 +533,13 @@ CONFIG_DRIVERS_ASPEED_AST_COMMON=y # CONFIG_MAINBOARD_HAS_I2C_TPM_ATMEL is not set # CONFIG_MAINBOARD_HAS_I2C_TPM_CR50 is not set CONFIG_DRIVERS_I2C_W83795=y +# CONFIG_PLATFORM_USES_FSP2_0 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_INTEL_GMA_SWSMISCI 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 @@ -541,12 +549,12 @@ CONFIG_DRIVERS_I2C_W83795=y # 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_TPM_RDRESP_NEED_DELAY is not set CONFIG_VGA=y # CONFIG_DRIVERS_RICOH_RCE822 is not set # CONFIG_DRIVER_SIEMENS_NC_FPGA is not set @@ -567,6 +575,16 @@ CONFIG_VGA=y # # Verified Boot (vboot) # + +# +# Trusted Platform Module +# +# CONFIG_TPM is not set +CONFIG_TPM2=y +# CONFIG_DEBUG_TPM is not set +# CONFIG_MAINBOARD_HAS_TPM_CR50 is not set +CONFIG_MAINBOARD_HAS_LPC_TPM=y +# CONFIG_MAINBOARD_HAS_TPM2 is not set # 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 @@ -575,9 +593,6 @@ 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 @@ -669,6 +684,7 @@ CONFIG_PAYLOAD_OPTIONS="" 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 +CONFIG_COMPRESS_SECONDARY_PAYLOAD=y # # Secondary Payloads @@ -693,7 +709,6 @@ 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 diff --git a/config/coreboot-qemu.config b/config/coreboot-qemu.config index 33d632da9..0bc29750a 100644 --- a/config/coreboot-qemu.config +++ b/config/coreboot-qemu.config @@ -15,9 +15,11 @@ CONFIG_COMPILER_GCC=y # 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=y +# CONFIG_TIMESTAMPS_ON_CONSOLE is not set # CONFIG_USE_BLOBS is not set # CONFIG_COVERAGE is not set # CONFIG_UBSAN is not set @@ -32,9 +34,7 @@ CONFIG_COLLECT_TIMESTAMPS=y # # 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 @@ -45,18 +45,14 @@ CONFIG_COLLECT_TIMESTAMPS=y # 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 @@ -69,40 +65,34 @@ CONFIG_VENDOR_EMULATION=y # 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_OCP 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_SCALEWAY is not set # CONFIG_VENDOR_SIEMENS is not set -# CONFIG_VENDOR_SOYO is not set +# CONFIG_VENDOR_SIFIVE 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" @@ -117,12 +107,10 @@ 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 @@ -130,6 +118,7 @@ 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_MMCONF_BASE_ADDRESS=0xb0000000 # CONFIG_POST_DEVICE is not set # CONFIG_VBOOT is not set CONFIG_FMDFILE="" @@ -143,6 +132,7 @@ 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_SMBIOS_ENCLOSURE_TYPE=0x03 CONFIG_BOARD_ROMSIZE_KB_2048=y # CONFIG_COREBOOT_ROMSIZE_KB_64 is not set # CONFIG_COREBOOT_ROMSIZE_KB_128 is not set @@ -159,7 +149,6 @@ CONFIG_COREBOOT_ROMSIZE_KB_8192=y # 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 @@ -188,7 +177,6 @@ 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 @@ -197,6 +185,7 @@ CONFIG_HPET_MIN_TICKS=0x80 # CONFIG_SOC_NVIDIA_TEGRA210 is not set # CONFIG_SOC_QC_IPQ40XX is not set # CONFIG_SOC_QC_IPQ806X is not set +# CONFIG_SOC_QUALCOMM_SDM845 is not set # CONFIG_SOC_ROCKCHIP_RK3288 is not set # CONFIG_SOC_ROCKCHIP_RK3399 is not set # CONFIG_CPU_SAMSUNG_EXYNOS5250 is not set @@ -256,6 +245,7 @@ CONFIG_CPU_UCODE_BINARIES="" # CONFIG_NORTHBRIDGE_AMD_PI is not set # CONFIG_NORTHBRIDGE_INTEL_COMMON_MRC_CACHE is not set CONFIG_HPET_ADDRESS=0xfed00000 +CONFIG_HPET_MIN_TICKS=0x80 CONFIG_MAX_PIRQ_LINKS=4 # @@ -271,6 +261,7 @@ CONFIG_SOUTHBRIDGE_INTEL_COMMON_SMBUS=y # 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_COMMON_SMM is not set CONFIG_SOUTHBRIDGE_INTEL_I82801IX=y # @@ -285,6 +276,11 @@ CONFIG_SOUTHBRIDGE_INTEL_I82801IX=y # CONFIG_GOOGLE_SMBIOS_MAINBOARD_VERSION is not set # CONFIG_UEFI_2_4_BINDING is not set # CONFIG_UDK_2015_BINDING is not set +# CONFIG_UDK_2017_BINDING is not set +CONFIG_UDK_2013_VERSION=2013 +CONFIG_UDK_2015_VERSION=2015 +CONFIG_UDK_2017_VERSION=2017 +CONFIG_UDK_VERSION=2013 # CONFIG_USE_SIEMENS_HWILIB is not set # CONFIG_ARCH_ARM is not set # CONFIG_ARCH_BOOTBLOCK_ARM is not set @@ -315,6 +311,8 @@ CONFIG_SOUTHBRIDGE_INTEL_I82801IX=y # 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_ARCH_ARMV8_EXTENSION=0 +# CONFIG_ARM64_USE_ARCH_TIMER is not set # CONFIG_ARM64_A53_ERRATUM_843419 is not set # CONFIG_ARCH_MIPS is not set # CONFIG_ARCH_BOOTBLOCK_MIPS is not set @@ -327,6 +325,7 @@ CONFIG_SOUTHBRIDGE_INTEL_I82801IX=y # CONFIG_ARCH_ROMSTAGE_POWER8 is not set # CONFIG_ARCH_RAMSTAGE_POWER8 is not set # CONFIG_ARCH_RISCV is not set +# CONFIG_ARCH_RISCV_COMPRESSED is not set # CONFIG_ARCH_BOOTBLOCK_RISCV is not set # CONFIG_ARCH_VERSTAGE_RISCV is not set # CONFIG_ARCH_ROMSTAGE_RISCV is not set @@ -350,13 +349,19 @@ CONFIG_ARCH_RAMSTAGE_X86_32=y CONFIG_PC80_SYSTEM=y # CONFIG_BOOTBLOCK_DEBUG_SPINLOOP is not set # CONFIG_BOOTBLOCK_SAVE_BIST_AND_TIMESTAMP is not set +# CONFIG_HAVE_CMOS_DEFAULT is not set CONFIG_IOAPIC_INTERRUPTS_ON_APIC_SERIAL_BUS=y +CONFIG_ID_SECTION_OFFSET=0x80 # 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" +# CONFIG_COLLECT_TIMESTAMPS_NO_TSC is not set +CONFIG_COLLECT_TIMESTAMPS_TSC=y +# CONFIG_PAGING_IN_CACHE_AS_RAM is not set +# CONFIG_IDT_IN_EVERY_STAGE is not set # # Devices @@ -414,18 +419,22 @@ 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_MAX98373 is not set # CONFIG_DRIVERS_I2C_MAX98927 is not set +# CONFIG_DRIVERS_I2C_PCA9538 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_PLATFORM_USES_FSP2_0 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_INTEL_GMA_SWSMISCI is not set # CONFIG_DRIVER_INTEL_I210 is not set # CONFIG_DRIVERS_INTEL_MIPI_CAMERA is not set CONFIG_DRIVERS_INTEL_WIFI=y @@ -435,7 +444,6 @@ CONFIG_DRIVERS_INTEL_WIFI=y # 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 @@ -455,6 +463,14 @@ CONFIG_VGA=y # # Verified Boot (vboot) # + +# +# Trusted Platform Module +# +# CONFIG_TPM is not set +# CONFIG_MAINBOARD_HAS_TPM_CR50 is not set +# CONFIG_MAINBOARD_HAS_LPC_TPM is not set +# CONFIG_MAINBOARD_HAS_TPM2 is not set # 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 @@ -463,8 +479,6 @@ 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 @@ -499,7 +513,7 @@ CONFIG_HAVE_HARD_RESET=y # 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_HAVE_OPTION_TABLE=y # CONFIG_PIRQ_ROUTE is not set CONFIG_HAVE_SMI_HANDLER=y # CONFIG_PCI_IO_CFG_EXT is not set @@ -535,6 +549,7 @@ CONFIG_PAYLOAD_OPTIONS="" CONFIG_LINUX_COMMAND_LINE="" CONFIG_LINUX_INITRD="../../build/qemu-coreboot/initrd.cpio.xz" # CONFIG_PAYLOAD_IS_FLAT_BINARY is not set +CONFIG_COMPRESS_SECONDARY_PAYLOAD=y # # Secondary Payloads diff --git a/config/coreboot-x220.config b/config/coreboot-x220.config index 3effe48ac..5e8d7346c 100644 --- a/config/coreboot-x220.config +++ b/config/coreboot-x220.config @@ -23,6 +23,7 @@ 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 @@ -34,9 +35,7 @@ CONFIG_MEASURED_BOOT=y # # 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 @@ -47,18 +46,14 @@ CONFIG_MEASURED_BOOT=y # 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 @@ -71,40 +66,34 @@ CONFIG_MEASURED_BOOT=y # 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_OCP 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_SCALEWAY is not set # CONFIG_VENDOR_SIEMENS is not set -# CONFIG_VENDOR_SOYO is not set +# CONFIG_VENDOR_SIFIVE 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" @@ -124,12 +113,11 @@ 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_HAVE_GBE_BIN=y +CONFIG_MMCONF_BASE_ADDRESS=0xf0000000 # CONFIG_VBOOT is not set CONFIG_TPM_PIRQ=0x0 CONFIG_BOOT_DEVICE_SPI_FLASH_BUS=0 @@ -149,6 +137,7 @@ CONFIG_ME_BIN_PATH="../../blobs/x220/me.bin" # CONFIG_BOARD_LENOVO_T430S is not set # CONFIG_BOARD_LENOVO_T500 is not set # CONFIG_BOARD_LENOVO_T520 is not set +# CONFIG_BOARD_LENOVO_W520 is not set # CONFIG_BOARD_LENOVO_T530 is not set # CONFIG_BOARD_LENOVO_T60 is not set # CONFIG_BOARD_LENOVO_X131E is not set @@ -160,12 +149,14 @@ CONFIG_BOARD_LENOVO_X220=y # CONFIG_BOARD_LENOVO_X230 is not set # CONFIG_BOARD_LENOVO_X60 is not set # CONFIG_BOARD_LENOVO_Z61T is not set +# CONFIG_BOARD_LENOVO_BASEBOARD_T520 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_SMBIOS_ENCLOSURE_TYPE=0x09 CONFIG_BOARD_ROMSIZE_KB_8192=y # CONFIG_COREBOOT_ROMSIZE_KB_64 is not set # CONFIG_COREBOOT_ROMSIZE_KB_128 is not set @@ -182,7 +173,6 @@ CONFIG_COREBOOT_ROMSIZE_KB_8192=y # 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 @@ -200,6 +190,7 @@ CONFIG_RAMBASE=0x100000 CONFIG_EHCI_BAR=0xfef00000 CONFIG_SERIRQ_CONTINUOUS_MODE=y CONFIG_SMM_TSEG_SIZE=0x800000 +CONFIG_SMM_RESERVED_SIZE=0x100000 CONFIG_ACPI_CPU_STRING="\\_PR.CP%02d" # CONFIG_SOC_BROADCOM_CYGNUS is not set CONFIG_BOOTBLOCK_CPU_INIT="cpu/intel/model_206ax/bootblock.c" @@ -211,6 +202,7 @@ 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_IED_REGION_SIZE=0x400000 CONFIG_PCIEXP_ASPM=y CONFIG_PCIEXP_COMMON_CLOCK=y # CONFIG_PCIEXP_CLK_PM is not set @@ -220,7 +212,6 @@ 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 @@ -229,6 +220,7 @@ CONFIG_HPET_MIN_TICKS=0x80 # CONFIG_SOC_NVIDIA_TEGRA210 is not set # CONFIG_SOC_QC_IPQ40XX is not set # CONFIG_SOC_QC_IPQ806X is not set +# CONFIG_SOC_QUALCOMM_SDM845 is not set # CONFIG_SOC_ROCKCHIP_RK3288 is not set # CONFIG_SOC_ROCKCHIP_RK3399 is not set # CONFIG_CPU_SAMSUNG_EXYNOS5250 is not set @@ -296,8 +288,7 @@ CONFIG_CPU_UCODE_BINARIES="" # 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_COMMON_MRC_CACHE is not set CONFIG_NORTHBRIDGE_INTEL_SANDYBRIDGE=y CONFIG_USE_NATIVE_RAMINIT=y # CONFIG_NATIVE_RAMINIT_IGNORE_MAX_MEM_FUSES is not set @@ -305,6 +296,7 @@ CONFIG_USE_NATIVE_RAMINIT=y CONFIG_SANDYBRIDGE_IVYBRIDGE_LVDS=y CONFIG_IF_NATIVE_VGA_INIT=y CONFIG_HPET_ADDRESS=0xfed00000 +CONFIG_HPET_MIN_TICKS=0x80 CONFIG_MAX_PIRQ_LINKS=4 # @@ -325,6 +317,7 @@ 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_SOUTHBRIDGE_INTEL_COMMON_SMM=y CONFIG_INTEL_CHIPSET_LOCKDOWN=y # CONFIG_LOCK_MANAGEMENT_ENGINE is not set @@ -356,6 +349,11 @@ CONFIG_GBE_BIN_PATH="../../blobs/x220/gbe.bin" # CONFIG_GOOGLE_SMBIOS_MAINBOARD_VERSION is not set # CONFIG_UEFI_2_4_BINDING is not set # CONFIG_UDK_2015_BINDING is not set +# CONFIG_UDK_2017_BINDING is not set +CONFIG_UDK_2013_VERSION=2013 +CONFIG_UDK_2015_VERSION=2015 +CONFIG_UDK_2017_VERSION=2017 +CONFIG_UDK_VERSION=2013 # CONFIG_USE_SIEMENS_HWILIB is not set # CONFIG_ARCH_ARM is not set # CONFIG_ARCH_BOOTBLOCK_ARM is not set @@ -386,6 +384,8 @@ CONFIG_GBE_BIN_PATH="../../blobs/x220/gbe.bin" # 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_ARCH_ARMV8_EXTENSION=0 +# CONFIG_ARM64_USE_ARCH_TIMER is not set # CONFIG_ARM64_A53_ERRATUM_843419 is not set # CONFIG_ARCH_MIPS is not set # CONFIG_ARCH_BOOTBLOCK_MIPS is not set @@ -398,6 +398,7 @@ CONFIG_GBE_BIN_PATH="../../blobs/x220/gbe.bin" # CONFIG_ARCH_ROMSTAGE_POWER8 is not set # CONFIG_ARCH_RAMSTAGE_POWER8 is not set # CONFIG_ARCH_RISCV is not set +# CONFIG_ARCH_RISCV_COMPRESSED is not set # CONFIG_ARCH_BOOTBLOCK_RISCV is not set # CONFIG_ARCH_VERSTAGE_RISCV is not set # CONFIG_ARCH_ROMSTAGE_RISCV is not set @@ -425,12 +426,15 @@ 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_ID_SECTION_OFFSET=0x80 # 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" +# CONFIG_PAGING_IN_CACHE_AS_RAM is not set +# CONFIG_IDT_IN_EVERY_STAGE is not set # # Devices @@ -472,6 +476,13 @@ CONFIG_SUBSYSTEM_DEVICE_ID=0x0000 # 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_SIZE=0x10000 +# CONFIG_MRC_SETTINGS_PROTECT is not set +# 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_MRC_WRITE_NV_LATE is not set # CONFIG_RT8168_GET_MAC_FROM_VPD is not set # CONFIG_RT8168_SET_LED_MODE is not set CONFIG_SPI_FLASH=y @@ -506,7 +517,9 @@ 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_MAX98373 is not set # CONFIG_DRIVERS_I2C_MAX98927 is not set +# CONFIG_DRIVERS_I2C_PCA9538 is not set # CONFIG_DRIVERS_I2C_PCF8523 is not set # CONFIG_DRIVERS_I2C_RT5663 is not set # CONFIG_DRIVERS_I2C_RTD2132 is not set @@ -514,11 +527,13 @@ CONFIG_SMBIOS_PROVIDED_BY_MOBO=y # 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_PLATFORM_USES_FSP2_0 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_INTEL_GMA_SWSMISCI is not set CONFIG_GFX_GMA=y CONFIG_GFX_GMA_CPU="Sandybridge" CONFIG_GFX_GMA_CPU_VARIANT="Normal" @@ -535,12 +550,12 @@ CONFIG_DRIVERS_INTEL_WIFI=y # 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_TPM_RDRESP_NEED_DELAY is not set CONFIG_VGA=y CONFIG_DRIVERS_RICOH_RCE822=y # CONFIG_DRIVER_SIEMENS_NC_FPGA is not set @@ -560,6 +575,15 @@ CONFIG_DRIVERS_RICOH_RCE822=y # # Verified Boot (vboot) # + +# +# Trusted Platform Module +# +CONFIG_TPM=y +# CONFIG_DEBUG_TPM is not set +# CONFIG_MAINBOARD_HAS_TPM_CR50 is not set +CONFIG_MAINBOARD_HAS_LPC_TPM=y +# CONFIG_MAINBOARD_HAS_TPM2 is not set CONFIG_ACPI_SATA_GENERATOR=y CONFIG_ACPI_INTEL_HARDWARE_SLEEP_VALUES=y # CONFIG_ACPI_AMD_HARDWARE_SLEEP_VALUES is not set @@ -568,8 +592,6 @@ 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 @@ -638,6 +660,7 @@ CONFIG_PAYLOAD_OPTIONS="" CONFIG_LINUX_COMMAND_LINE="quiet" CONFIG_LINUX_INITRD="../../build/x220/initrd.cpio.xz" # CONFIG_PAYLOAD_IS_FLAT_BINARY is not set +CONFIG_COMPRESS_SECONDARY_PAYLOAD=y # # Secondary Payloads @@ -661,7 +684,6 @@ CONFIG_HAVE_DEBUG_SMBUS=y 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 diff --git a/config/coreboot-x230-flash.config b/config/coreboot-x230-flash.config index f15c29e51..d29629239 100644 --- a/config/coreboot-x230-flash.config +++ b/config/coreboot-x230-flash.config @@ -23,6 +23,7 @@ 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 @@ -34,9 +35,7 @@ CONFIG_MEASURED_BOOT=y # # 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 @@ -47,18 +46,14 @@ CONFIG_MEASURED_BOOT=y # 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 @@ -71,40 +66,34 @@ CONFIG_MEASURED_BOOT=y # 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_OCP 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_SCALEWAY is not set # CONFIG_VENDOR_SIEMENS is not set -# CONFIG_VENDOR_SOYO is not set +# CONFIG_VENDOR_SIFIVE 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" @@ -125,12 +114,11 @@ 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_MMCONF_BASE_ADDRESS=0xf0000000 # CONFIG_POST_DEVICE is not set CONFIG_IFD_BIOS_SECTION="" CONFIG_IFD_ME_SECTION="" @@ -153,6 +141,7 @@ CONFIG_IFD_GBE_SECTION="" # CONFIG_BOARD_LENOVO_T430S is not set # CONFIG_BOARD_LENOVO_T500 is not set # CONFIG_BOARD_LENOVO_T520 is not set +# CONFIG_BOARD_LENOVO_W520 is not set # CONFIG_BOARD_LENOVO_T530 is not set # CONFIG_BOARD_LENOVO_T60 is not set # CONFIG_BOARD_LENOVO_X131E is not set @@ -164,12 +153,14 @@ CONFIG_IFD_GBE_SECTION="" CONFIG_BOARD_LENOVO_X230=y # CONFIG_BOARD_LENOVO_X60 is not set # CONFIG_BOARD_LENOVO_Z61T is not set +# CONFIG_BOARD_LENOVO_BASEBOARD_T520 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_SMBIOS_ENCLOSURE_TYPE=0x09 CONFIG_BOARD_ROMSIZE_KB_12288=y # CONFIG_COREBOOT_ROMSIZE_KB_64 is not set # CONFIG_COREBOOT_ROMSIZE_KB_128 is not set @@ -186,7 +177,6 @@ CONFIG_COREBOOT_ROMSIZE_KB_12288=y # 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 @@ -204,6 +194,7 @@ CONFIG_RAMBASE=0x100000 CONFIG_EHCI_BAR=0xfef00000 CONFIG_SERIRQ_CONTINUOUS_MODE=y CONFIG_SMM_TSEG_SIZE=0x800000 +CONFIG_SMM_RESERVED_SIZE=0x100000 CONFIG_ACPI_CPU_STRING="\\_PR.CP%02d" # CONFIG_SOC_BROADCOM_CYGNUS is not set CONFIG_BOOTBLOCK_CPU_INIT="cpu/intel/model_206ax/bootblock.c" @@ -215,6 +206,7 @@ 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_IED_REGION_SIZE=0x400000 CONFIG_PCIEXP_ASPM=y CONFIG_PCIEXP_COMMON_CLOCK=y # CONFIG_PCIEXP_CLK_PM is not set @@ -225,7 +217,6 @@ 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 @@ -235,6 +226,7 @@ CONFIG_TTYS0_BAUD=115200 # CONFIG_SOC_NVIDIA_TEGRA210 is not set # CONFIG_SOC_QC_IPQ40XX is not set # CONFIG_SOC_QC_IPQ806X is not set +# CONFIG_SOC_QUALCOMM_SDM845 is not set # CONFIG_SOC_ROCKCHIP_RK3288 is not set # CONFIG_SOC_ROCKCHIP_RK3399 is not set # CONFIG_CPU_SAMSUNG_EXYNOS5250 is not set @@ -302,8 +294,7 @@ CONFIG_CPU_UCODE_BINARIES="" # 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_COMMON_MRC_CACHE is not set CONFIG_NORTHBRIDGE_INTEL_IVYBRIDGE=y CONFIG_USE_NATIVE_RAMINIT=y # CONFIG_NATIVE_RAMINIT_IGNORE_MAX_MEM_FUSES is not set @@ -311,6 +302,7 @@ CONFIG_USE_NATIVE_RAMINIT=y CONFIG_SANDYBRIDGE_IVYBRIDGE_LVDS=y CONFIG_IF_NATIVE_VGA_INIT=y CONFIG_HPET_ADDRESS=0xfed00000 +CONFIG_HPET_MIN_TICKS=0x80 CONFIG_MAX_PIRQ_LINKS=4 # @@ -331,6 +323,7 @@ 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_SOUTHBRIDGE_INTEL_COMMON_SMM=y CONFIG_INTEL_CHIPSET_LOCKDOWN=y # CONFIG_LOCK_MANAGEMENT_ENGINE is not set @@ -358,6 +351,11 @@ CONFIG_IFD_PLATFORM_SECTION="" # CONFIG_GOOGLE_SMBIOS_MAINBOARD_VERSION is not set # CONFIG_UEFI_2_4_BINDING is not set # CONFIG_UDK_2015_BINDING is not set +# CONFIG_UDK_2017_BINDING is not set +CONFIG_UDK_2013_VERSION=2013 +CONFIG_UDK_2015_VERSION=2015 +CONFIG_UDK_2017_VERSION=2017 +CONFIG_UDK_VERSION=2013 # CONFIG_USE_SIEMENS_HWILIB is not set # CONFIG_ARCH_ARM is not set # CONFIG_ARCH_BOOTBLOCK_ARM is not set @@ -388,6 +386,8 @@ CONFIG_IFD_PLATFORM_SECTION="" # 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_ARCH_ARMV8_EXTENSION=0 +# CONFIG_ARM64_USE_ARCH_TIMER is not set # CONFIG_ARM64_A53_ERRATUM_843419 is not set # CONFIG_ARCH_MIPS is not set # CONFIG_ARCH_BOOTBLOCK_MIPS is not set @@ -400,6 +400,7 @@ CONFIG_IFD_PLATFORM_SECTION="" # CONFIG_ARCH_ROMSTAGE_POWER8 is not set # CONFIG_ARCH_RAMSTAGE_POWER8 is not set # CONFIG_ARCH_RISCV is not set +# CONFIG_ARCH_RISCV_COMPRESSED is not set # CONFIG_ARCH_BOOTBLOCK_RISCV is not set # CONFIG_ARCH_VERSTAGE_RISCV is not set # CONFIG_ARCH_ROMSTAGE_RISCV is not set @@ -427,12 +428,15 @@ 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_ID_SECTION_OFFSET=0x80 # 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" +# CONFIG_PAGING_IN_CACHE_AS_RAM is not set +# CONFIG_IDT_IN_EVERY_STAGE is not set # # Devices @@ -474,6 +478,13 @@ CONFIG_SUBSYSTEM_DEVICE_ID=0x0000 # 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_SIZE=0x10000 +# CONFIG_MRC_SETTINGS_PROTECT is not set +# 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_MRC_WRITE_NV_LATE is not set # CONFIG_RT8168_GET_MAC_FROM_VPD is not set # CONFIG_RT8168_SET_LED_MODE is not set CONFIG_SPI_FLASH=y @@ -509,7 +520,9 @@ 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_MAX98373 is not set # CONFIG_DRIVERS_I2C_MAX98927 is not set +# CONFIG_DRIVERS_I2C_PCA9538 is not set # CONFIG_DRIVERS_I2C_PCF8523 is not set # CONFIG_DRIVERS_I2C_RT5663 is not set # CONFIG_DRIVERS_I2C_RTD2132 is not set @@ -517,11 +530,13 @@ CONFIG_SMBIOS_PROVIDED_BY_MOBO=y # 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_PLATFORM_USES_FSP2_0 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_INTEL_GMA_SWSMISCI is not set CONFIG_GFX_GMA=y CONFIG_GFX_GMA_CPU="Ivybridge" CONFIG_GFX_GMA_CPU_VARIANT="Normal" @@ -538,12 +553,12 @@ CONFIG_DRIVERS_INTEL_WIFI=y # 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_TPM_RDRESP_NEED_DELAY is not set CONFIG_VGA=y CONFIG_DRIVERS_RICOH_RCE822=y # CONFIG_DRIVER_SIEMENS_NC_FPGA is not set @@ -563,6 +578,15 @@ CONFIG_DRIVERS_RICOH_RCE822=y # # Verified Boot (vboot) # + +# +# Trusted Platform Module +# +CONFIG_TPM=y +# CONFIG_DEBUG_TPM is not set +# CONFIG_MAINBOARD_HAS_TPM_CR50 is not set +CONFIG_MAINBOARD_HAS_LPC_TPM=y +# CONFIG_MAINBOARD_HAS_TPM2 is not set CONFIG_ACPI_SATA_GENERATOR=y CONFIG_ACPI_INTEL_HARDWARE_SLEEP_VALUES=y # CONFIG_ACPI_AMD_HARDWARE_SLEEP_VALUES is not set @@ -571,8 +595,6 @@ 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 @@ -659,6 +681,7 @@ CONFIG_PAYLOAD_OPTIONS="" CONFIG_LINUX_COMMAND_LINE="" CONFIG_LINUX_INITRD="../../build/x230-flash/initrd.cpio.xz" # CONFIG_PAYLOAD_IS_FLAT_BINARY is not set +CONFIG_COMPRESS_SECONDARY_PAYLOAD=y # # Secondary Payloads @@ -683,7 +706,6 @@ CONFIG_HAVE_DEBUG_SMBUS=y 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 diff --git a/config/coreboot-x230.config b/config/coreboot-x230.config index 7edc29996..8510b7ca4 100644 --- a/config/coreboot-x230.config +++ b/config/coreboot-x230.config @@ -23,6 +23,7 @@ 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 @@ -34,9 +35,7 @@ CONFIG_MEASURED_BOOT=y # # 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 @@ -47,18 +46,14 @@ CONFIG_MEASURED_BOOT=y # 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 @@ -71,40 +66,34 @@ CONFIG_MEASURED_BOOT=y # 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_OCP 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_SCALEWAY is not set # CONFIG_VENDOR_SIEMENS is not set -# CONFIG_VENDOR_SOYO is not set +# CONFIG_VENDOR_SIFIVE 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" @@ -124,12 +113,11 @@ 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_MMCONF_BASE_ADDRESS=0xf0000000 # CONFIG_POST_DEVICE is not set CONFIG_IFD_BIOS_SECTION="" CONFIG_IFD_ME_SECTION="" @@ -151,6 +139,7 @@ CONFIG_IFD_GBE_SECTION="" # CONFIG_BOARD_LENOVO_T430S is not set # CONFIG_BOARD_LENOVO_T500 is not set # CONFIG_BOARD_LENOVO_T520 is not set +# CONFIG_BOARD_LENOVO_W520 is not set # CONFIG_BOARD_LENOVO_T530 is not set # CONFIG_BOARD_LENOVO_T60 is not set # CONFIG_BOARD_LENOVO_X131E is not set @@ -162,12 +151,14 @@ CONFIG_IFD_GBE_SECTION="" CONFIG_BOARD_LENOVO_X230=y # CONFIG_BOARD_LENOVO_X60 is not set # CONFIG_BOARD_LENOVO_Z61T is not set +# CONFIG_BOARD_LENOVO_BASEBOARD_T520 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_SMBIOS_ENCLOSURE_TYPE=0x09 CONFIG_BOARD_ROMSIZE_KB_12288=y # CONFIG_COREBOOT_ROMSIZE_KB_64 is not set # CONFIG_COREBOOT_ROMSIZE_KB_128 is not set @@ -184,7 +175,6 @@ CONFIG_COREBOOT_ROMSIZE_KB_12288=y # 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 @@ -202,6 +192,7 @@ CONFIG_RAMBASE=0x100000 CONFIG_EHCI_BAR=0xfef00000 CONFIG_SERIRQ_CONTINUOUS_MODE=y CONFIG_SMM_TSEG_SIZE=0x800000 +CONFIG_SMM_RESERVED_SIZE=0x100000 CONFIG_ACPI_CPU_STRING="\\_PR.CP%02d" # CONFIG_SOC_BROADCOM_CYGNUS is not set CONFIG_BOOTBLOCK_CPU_INIT="cpu/intel/model_206ax/bootblock.c" @@ -213,6 +204,7 @@ 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_IED_REGION_SIZE=0x400000 CONFIG_PCIEXP_ASPM=y CONFIG_PCIEXP_COMMON_CLOCK=y # CONFIG_PCIEXP_CLK_PM is not set @@ -222,7 +214,6 @@ 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 @@ -231,6 +222,7 @@ CONFIG_HPET_MIN_TICKS=0x80 # CONFIG_SOC_NVIDIA_TEGRA210 is not set # CONFIG_SOC_QC_IPQ40XX is not set # CONFIG_SOC_QC_IPQ806X is not set +# CONFIG_SOC_QUALCOMM_SDM845 is not set # CONFIG_SOC_ROCKCHIP_RK3288 is not set # CONFIG_SOC_ROCKCHIP_RK3399 is not set # CONFIG_CPU_SAMSUNG_EXYNOS5250 is not set @@ -298,8 +290,7 @@ CONFIG_CPU_UCODE_BINARIES="" # 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_COMMON_MRC_CACHE is not set CONFIG_NORTHBRIDGE_INTEL_IVYBRIDGE=y CONFIG_USE_NATIVE_RAMINIT=y # CONFIG_NATIVE_RAMINIT_IGNORE_MAX_MEM_FUSES is not set @@ -307,6 +298,7 @@ CONFIG_USE_NATIVE_RAMINIT=y CONFIG_SANDYBRIDGE_IVYBRIDGE_LVDS=y CONFIG_IF_NATIVE_VGA_INIT=y CONFIG_HPET_ADDRESS=0xfed00000 +CONFIG_HPET_MIN_TICKS=0x80 CONFIG_MAX_PIRQ_LINKS=4 # @@ -327,6 +319,7 @@ 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_SOUTHBRIDGE_INTEL_COMMON_SMM=y CONFIG_INTEL_CHIPSET_LOCKDOWN=y # CONFIG_LOCK_MANAGEMENT_ENGINE is not set @@ -354,6 +347,11 @@ CONFIG_IFD_PLATFORM_SECTION="" # CONFIG_GOOGLE_SMBIOS_MAINBOARD_VERSION is not set # CONFIG_UEFI_2_4_BINDING is not set # CONFIG_UDK_2015_BINDING is not set +# CONFIG_UDK_2017_BINDING is not set +CONFIG_UDK_2013_VERSION=2013 +CONFIG_UDK_2015_VERSION=2015 +CONFIG_UDK_2017_VERSION=2017 +CONFIG_UDK_VERSION=2013 # CONFIG_USE_SIEMENS_HWILIB is not set # CONFIG_ARCH_ARM is not set # CONFIG_ARCH_BOOTBLOCK_ARM is not set @@ -384,6 +382,8 @@ CONFIG_IFD_PLATFORM_SECTION="" # 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_ARCH_ARMV8_EXTENSION=0 +# CONFIG_ARM64_USE_ARCH_TIMER is not set # CONFIG_ARM64_A53_ERRATUM_843419 is not set # CONFIG_ARCH_MIPS is not set # CONFIG_ARCH_BOOTBLOCK_MIPS is not set @@ -396,6 +396,7 @@ CONFIG_IFD_PLATFORM_SECTION="" # CONFIG_ARCH_ROMSTAGE_POWER8 is not set # CONFIG_ARCH_RAMSTAGE_POWER8 is not set # CONFIG_ARCH_RISCV is not set +# CONFIG_ARCH_RISCV_COMPRESSED is not set # CONFIG_ARCH_BOOTBLOCK_RISCV is not set # CONFIG_ARCH_VERSTAGE_RISCV is not set # CONFIG_ARCH_ROMSTAGE_RISCV is not set @@ -423,12 +424,15 @@ 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_ID_SECTION_OFFSET=0x80 # 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" +# CONFIG_PAGING_IN_CACHE_AS_RAM is not set +# CONFIG_IDT_IN_EVERY_STAGE is not set # # Devices @@ -470,6 +474,13 @@ CONFIG_SUBSYSTEM_DEVICE_ID=0x0000 # 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_SIZE=0x10000 +# CONFIG_MRC_SETTINGS_PROTECT is not set +# 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_MRC_WRITE_NV_LATE is not set # CONFIG_RT8168_GET_MAC_FROM_VPD is not set # CONFIG_RT8168_SET_LED_MODE is not set CONFIG_SPI_FLASH=y @@ -505,7 +516,9 @@ 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_MAX98373 is not set # CONFIG_DRIVERS_I2C_MAX98927 is not set +# CONFIG_DRIVERS_I2C_PCA9538 is not set # CONFIG_DRIVERS_I2C_PCF8523 is not set # CONFIG_DRIVERS_I2C_RT5663 is not set # CONFIG_DRIVERS_I2C_RTD2132 is not set @@ -513,11 +526,13 @@ CONFIG_SMBIOS_PROVIDED_BY_MOBO=y # 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_PLATFORM_USES_FSP2_0 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_INTEL_GMA_SWSMISCI is not set CONFIG_GFX_GMA=y CONFIG_GFX_GMA_CPU="Ivybridge" CONFIG_GFX_GMA_CPU_VARIANT="Normal" @@ -534,12 +549,12 @@ CONFIG_DRIVERS_INTEL_WIFI=y # 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_TPM_RDRESP_NEED_DELAY is not set CONFIG_VGA=y CONFIG_DRIVERS_RICOH_RCE822=y # CONFIG_DRIVER_SIEMENS_NC_FPGA is not set @@ -559,6 +574,15 @@ CONFIG_DRIVERS_RICOH_RCE822=y # # Verified Boot (vboot) # + +# +# Trusted Platform Module +# +CONFIG_TPM=y +# CONFIG_DEBUG_TPM is not set +# CONFIG_MAINBOARD_HAS_TPM_CR50 is not set +CONFIG_MAINBOARD_HAS_LPC_TPM=y +# CONFIG_MAINBOARD_HAS_TPM2 is not set CONFIG_ACPI_SATA_GENERATOR=y CONFIG_ACPI_INTEL_HARDWARE_SLEEP_VALUES=y # CONFIG_ACPI_AMD_HARDWARE_SLEEP_VALUES is not set @@ -567,8 +591,6 @@ 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 @@ -640,6 +662,7 @@ CONFIG_PAYLOAD_OPTIONS="" CONFIG_LINUX_COMMAND_LINE="quiet" CONFIG_LINUX_INITRD="../../build/x230/initrd.cpio.xz" # CONFIG_PAYLOAD_IS_FLAT_BINARY is not set +CONFIG_COMPRESS_SECONDARY_PAYLOAD=y # # Secondary Payloads @@ -663,7 +686,6 @@ CONFIG_HAVE_DEBUG_SMBUS=y 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 diff --git a/modules/coreboot b/modules/coreboot index d785abbc4..99637f635 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 @@ -79,7 +79,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/patches/coreboot-4.8.1/0000-measuredboot.patch b/patches/coreboot-4.8.1/0000-measuredboot.patch new file mode 100644 index 000000000..4bd843ebf --- /dev/null +++ b/patches/coreboot-4.8.1/0000-measuredboot.patch @@ -0,0 +1,474 @@ +diff --git ./src/Kconfig ./src/Kconfig +index 99a704d..004b4a7 100644 +--- ./src/Kconfig ++++ ./src/Kconfig +@@ -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. + ++config MEASURED_BOOT ++ bool "Enable TPM measured boot" ++ default n ++ select TPM ++ depends on MAINBOARD_HAS_LPC_TPM ++ depends on !VBOOT ++ help ++ Enable this option to measure the bootblock, romstage and ++ CBFS files into TPM PCRs. This does not verify these values ++ (that is the job of something like vboot), but makes it possible ++ for the payload to validate the boot path and allow something ++ like Heads to attest to the user that the system is likely safe. ++ ++ You probably want to say N. ++ + endmenu + + menu "Mainboard" +diff --git ./src/drivers/pc80/tpm/romstage.c ./src/drivers/pc80/tpm/romstage.c +index b8e4705..7732e66 100644 +--- ./src/drivers/pc80/tpm/romstage.c ++++ ./src/drivers/pc80/tpm/romstage.c +@@ -48,6 +48,12 @@ static const struct { + + static const struct { + u8 buffer[12]; ++} tpm2_startup_cmd = { ++ {0x80, 0x01, 0x0, 0x0, 0x0, 0xc, 0x0, 0x0, 0x01, 0x44, 0x0, 0x0 } ++}; ++ ++static const struct { ++ u8 buffer[12]; + } tpm_deactivate_cmd = { + {0x0, 0xc1, 0x0, 0x0, 0x0, 0xc, 0x0, 0x0, 0x0, 0x99, 0x0, 0x3 } + }; +@@ -229,9 +235,15 @@ void init_tpm(int s3resume) + return; + } + } else { +- printk(BIOS_SPEW, "TPM: Startup\n"); +- result = TlclSendReceive(tpm_startup_cmd.buffer, +- response, sizeof(response)); ++ if (IS_ENABLED(CONFIG_TPM2)) { ++ printk(BIOS_SPEW, "TPM2: Startup\n"); ++ result = TlclSendReceive(tpm2_startup_cmd.buffer, ++ response, sizeof(response)); ++ } else { ++ printk(BIOS_SPEW, "TPM: Startup\n"); ++ result = TlclSendReceive(tpm_startup_cmd.buffer, ++ response, sizeof(response)); ++ } + } + + tis_close(); +diff --git ./src/drivers/pc80/tpm/tis.c ./src/drivers/pc80/tpm/tis.c +index 3549173..11fc027 100644 +--- ./src/drivers/pc80/tpm/tis.c ++++ ./src/drivers/pc80/tpm/tis.c +@@ -125,10 +125,11 @@ static const struct device_name atmel_devices[] = { + + static const struct device_name infineon_devices[] = { + {0x000b, "SLB9635 TT 1.2"}, +- {0x001a, "SLB9660 TT 1.2"}, + #if IS_ENABLED(CONFIG_TPM2) ++ {0x001a, "SLB9665 TT 2.0"}, + {0x001b, "SLB9670 TT 2.0"}, + #else ++ {0x001a, "SLB9660 TT 1.2"}, + {0x001b, "SLB9670 TT 1.2"}, + #endif + {0xffff} +diff --git ./src/include/program_loading.h ./src/include/program_loading.h +index 7aba302..879c26e 100644 +--- ./src/include/program_loading.h ++++ ./src/include/program_loading.h +@@ -24,6 +24,8 @@ enum { + /* Last segment of program. Can be used to take different actions for + * cache maintenance of a program load. */ + SEG_FINAL = 1 << 0, ++ /* Indicate that the program segment should not be measured */ ++ SEG_NO_MEASURE = 1 << 1, + }; + + // The prog_type is a bit mask, so that in searches one can find, e.g., +diff --git ./src/lib/cbfs.c ./src/lib/cbfs.c +index 87ab387..708d321 100644 +--- ./src/lib/cbfs.c ++++ ./src/lib/cbfs.c +@@ -70,7 +70,13 @@ void *cbfs_boot_map_with_leak(const char *name, uint32_t type, size_t *size) + if (size != NULL) + *size = fsize; + +- return rdev_mmap(&fh.data, 0, fsize); ++ void * buffer = rdev_mmap(&fh.data, 0, fsize); ++ ++#ifndef __SMM__ ++ prog_segment_loaded((uintptr_t)buffer, fsize, 0); ++#endif ++ ++ return buffer; + } + + int cbfs_locate_file_in_region(struct cbfsf *fh, const char *region_name, +@@ -98,7 +104,8 @@ size_t cbfs_load_and_decompress(const struct region_device *rdev, size_t offset, + return 0; + if (rdev_readat(rdev, buffer, offset, in_size) != in_size) + return 0; +- return in_size; ++ out_size = in_size; ++ break; + + case CBFS_COMPRESS_LZ4: + if ((ENV_BOOTBLOCK || ENV_VERSTAGE) && +@@ -116,7 +123,7 @@ size_t cbfs_load_and_decompress(const struct region_device *rdev, size_t offset, + timestamp_add_now(TS_START_ULZ4F); + out_size = ulz4fn(compr_start, in_size, buffer, buffer_size); + timestamp_add_now(TS_END_ULZ4F); +- return out_size; ++ break; + + case CBFS_COMPRESS_LZMA: + if (ENV_BOOTBLOCK || ENV_VERSTAGE) +@@ -135,11 +142,15 @@ size_t cbfs_load_and_decompress(const struct region_device *rdev, size_t offset, + + rdev_munmap(rdev, map); + +- return out_size; ++ break; + + default: + return 0; + } ++ ++ prog_segment_loaded((uintptr_t)buffer, out_size, 0); ++ ++ return out_size; + } + + static inline int tohex4(unsigned int c) +diff --git ./src/lib/hardwaremain.c ./src/lib/hardwaremain.c +index 6fd55d7..edcc668 100644 +--- ./src/lib/hardwaremain.c ++++ ./src/lib/hardwaremain.c +@@ -33,6 +33,7 @@ + #include + #include + #include ++#include + #include + #if IS_ENABLED(CONFIG_HAVE_ACPI_RESUME) + #include +@@ -545,3 +546,13 @@ void boot_state_current_unblock(void) + { + boot_state_unblock(current_phase.state_id, current_phase.seq); + } ++ ++// ramstage measurements go into PCR3 if we are doing measured boot ++void platform_segment_loaded(uintptr_t start, size_t size, int flags) ++{ ++ if (IS_ENABLED(CONFIG_MEASURED_BOOT) && !(flags & SEG_NO_MEASURE)) ++ { ++ tlcl_measure(3, (const void*) start, size); ++ } ++} ++ +diff --git ./src/lib/rmodule.c ./src/lib/rmodule.c +index 66d5120..b50afe7 100644 +--- ./src/lib/rmodule.c ++++ ./src/lib/rmodule.c +@@ -198,7 +198,7 @@ int rmodule_load(void *base, struct rmodule *module) + rmodule_clear_bss(module); + + prog_segment_loaded((uintptr_t)module->location, +- rmodule_memory_size(module), SEG_FINAL); ++ rmodule_memory_size(module), SEG_FINAL | SEG_NO_MEASURE); + + return 0; + } +diff --git ./src/security/tpm/Makefile.inc ./src/security/tpm/Makefile.inc +index 2385635..52d088c 100644 +--- ./src/security/tpm/Makefile.inc ++++ ./src/security/tpm/Makefile.inc +@@ -4,8 +4,12 @@ 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_VBOOT_SEPARATE_VERSTAGE),y) + romstage-$(CONFIG_TPM) += tss/tcg-1.2/tss.c ++romstage-$(CONFIG_TPM) += sha1.c ++ramstage-$(CONFIG_TPM) += tss/tcg-1.2/tss.c ++ramstage-$(CONFIG_TPM) += sha1.c ++ ++ifeq ($(CONFIG_VBOOT_SEPARATE_VERSTAGE),y) + romstage-$(CONFIG_TPM2) += tss/tcg-2.0/tss_marshaling.c + romstage-$(CONFIG_TPM2) += tss/tcg-2.0/tss.c + endif # CONFIG_VBOOT_SEPARATE_VERSTAGE +diff --git ./src/security/tpm/sha1.c ./src/security/tpm/sha1.c +new file mode 100644 +index 0000000..506907f +--- /dev/null ++++ ./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 ++ * found in the LICENSE file. ++ * ++ * SHA-1 implementation largely based on libmincrypt in the the Android ++ * Open Source Project (platorm/system/core.git/libmincrypt/sha.c ++ */ ++ ++#include ++#include ++ ++static uint32_t ror27(uint32_t val) ++{ ++ return (val >> 27) | (val << 5); ++} ++static uint32_t ror2(uint32_t val) ++{ ++ return (val >> 2) | (val << 30); ++} ++static uint32_t ror31(uint32_t val) ++{ ++ return (val >> 31) | (val << 1); ++} ++ ++static void sha1_transform(struct sha1_ctx *ctx) ++{ ++ uint32_t W[80]; ++ register uint32_t A, B, C, D, E; ++ int t; ++ ++ A = ctx->state[0]; ++ B = ctx->state[1]; ++ C = ctx->state[2]; ++ D = ctx->state[3]; ++ E = ctx->state[4]; ++ ++#define SHA_F1(A, B, C, D, E, t) \ ++ E += ror27(A) + \ ++ (W[t] = __builtin_bswap32(ctx->buf.w[t])) + \ ++ (D^(B&(C^D))) + 0x5A827999; \ ++ B = ror2(B); ++ ++ for (t = 0; t < 15; t += 5) { ++ SHA_F1(A, B, C, D, E, t + 0); ++ SHA_F1(E, A, B, C, D, t + 1); ++ SHA_F1(D, E, A, B, C, t + 2); ++ SHA_F1(C, D, E, A, B, t + 3); ++ SHA_F1(B, C, D, E, A, t + 4); ++ } ++ SHA_F1(A, B, C, D, E, t + 0); /* 16th one, t == 15 */ ++ ++#undef SHA_F1 ++ ++#define SHA_F1(A, B, C, D, E, t) \ ++ E += ror27(A) + \ ++ (W[t] = ror31(W[t-3] ^ W[t-8] ^ W[t-14] ^ W[t-16])) + \ ++ (D^(B&(C^D))) + 0x5A827999; \ ++ B = ror2(B); ++ ++ SHA_F1(E, A, B, C, D, t + 1); ++ SHA_F1(D, E, A, B, C, t + 2); ++ SHA_F1(C, D, E, A, B, t + 3); ++ SHA_F1(B, C, D, E, A, t + 4); ++ ++#undef SHA_F1 ++ ++#define SHA_F2(A, B, C, D, E, t) \ ++ E += ror27(A) + \ ++ (W[t] = ror31(W[t-3] ^ W[t-8] ^ W[t-14] ^ W[t-16])) + \ ++ (B^C^D) + 0x6ED9EBA1; \ ++ B = ror2(B); ++ ++ for (t = 20; t < 40; t += 5) { ++ SHA_F2(A, B, C, D, E, t + 0); ++ SHA_F2(E, A, B, C, D, t + 1); ++ SHA_F2(D, E, A, B, C, t + 2); ++ SHA_F2(C, D, E, A, B, t + 3); ++ SHA_F2(B, C, D, E, A, t + 4); ++ } ++ ++#undef SHA_F2 ++ ++#define SHA_F3(A, B, C, D, E, t) \ ++ E += ror27(A) + \ ++ (W[t] = ror31(W[t-3] ^ W[t-8] ^ W[t-14] ^ W[t-16])) + \ ++ ((B&C)|(D&(B|C))) + 0x8F1BBCDC; \ ++ B = ror2(B); ++ ++ for (; t < 60; t += 5) { ++ SHA_F3(A, B, C, D, E, t + 0); ++ SHA_F3(E, A, B, C, D, t + 1); ++ SHA_F3(D, E, A, B, C, t + 2); ++ SHA_F3(C, D, E, A, B, t + 3); ++ SHA_F3(B, C, D, E, A, t + 4); ++ } ++ ++#undef SHA_F3 ++ ++#define SHA_F4(A, B, C, D, E, t) \ ++ E += ror27(A) + \ ++ (W[t] = ror31(W[t-3] ^ W[t-8] ^ W[t-14] ^ W[t-16])) + \ ++ (B^C^D) + 0xCA62C1D6; \ ++ B = ror2(B); ++ ++ for (; t < 80; t += 5) { ++ SHA_F4(A, B, C, D, E, t + 0); ++ SHA_F4(E, A, B, C, D, t + 1); ++ SHA_F4(D, E, A, B, C, t + 2); ++ SHA_F4(C, D, E, A, B, t + 3); ++ SHA_F4(B, C, D, E, A, t + 4); ++ } ++ ++#undef SHA_F4 ++ ++ ctx->state[0] += A; ++ ctx->state[1] += B; ++ ctx->state[2] += C; ++ ctx->state[3] += D; ++ ctx->state[4] += E; ++} ++ ++void sha1_update(struct sha1_ctx *ctx, const uint8_t *data, uint32_t len) ++{ ++ int i = ctx->count % sizeof(ctx->buf); ++ const uint8_t *p = (const uint8_t *)data; ++ ++ ctx->count += len; ++ ++ while (len > sizeof(ctx->buf) - i) { ++ memcpy(&ctx->buf.b[i], p, sizeof(ctx->buf) - i); ++ len -= sizeof(ctx->buf) - i; ++ p += sizeof(ctx->buf) - i; ++ sha1_transform(ctx); ++ i = 0; ++ } ++ ++ while (len--) { ++ ctx->buf.b[i++] = *p++; ++ if (i == sizeof(ctx->buf)) { ++ sha1_transform(ctx); ++ i = 0; ++ } ++ } ++} ++ ++ ++uint8_t *sha1_final(struct sha1_ctx *ctx) ++{ ++ uint32_t cnt = ctx->count * 8; ++ int i; ++ ++ sha1_update(ctx, (uint8_t *)"\x80", 1); ++ while ((ctx->count % sizeof(ctx->buf)) != (sizeof(ctx->buf) - 8)) ++ sha1_update(ctx, (uint8_t *)"\0", 1); ++ ++ for (i = 0; i < 8; ++i) { ++ uint8_t tmp = cnt >> ((7 - i) * 8); ++ sha1_update(ctx, &tmp, 1); ++ } ++ ++ for (i = 0; i < 5; i++) ++ ctx->buf.w[i] = __builtin_bswap32(ctx->state[i]); ++ ++ return ctx->buf.b; ++} ++ ++void sha1_init(struct sha1_ctx *ctx) ++{ ++ ctx->state[0] = 0x67452301; ++ ctx->state[1] = 0xEFCDAB89; ++ ctx->state[2] = 0x98BADCFE; ++ ctx->state[3] = 0x10325476; ++ ctx->state[4] = 0xC3D2E1F0; ++ ctx->count = 0; ++} +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..4577ec4 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 +@@ -354,3 +355,23 @@ uint32_t tlcl_extend(int pcr_num, const uint8_t *in_digest, + kPcrDigestLength); + return result; + } ++ ++ ++uint32_t tlcl_measure(int pcr_num, const void * start, size_t len) ++{ ++ VBDEBUG("TPM: pcr %d measure %p @ %zu: ", pcr_num, start, len); ++ ++ struct sha1_ctx sha; ++ sha1_init(&sha); ++ sha1_update(&sha, start, len); ++ ++ const uint8_t * hash = sha1_final(&sha); ++ for(unsigned i = 0 ; i < SHA1_DIGEST_SIZE ; i++) ++ VBDEBUG("%02x", hash[i]); ++ VBDEBUG("\n"); ++ ++ //hexdump(start, 128); ++ ++ return tlcl_extend(pcr_num, hash, NULL); ++} ++ diff --git a/patches/coreboot-4.8.1/0020-kgpe-d16.patch b/patches/coreboot-4.8.1/0020-kgpe-d16.patch new file mode 100644 index 000000000..5c719b0db --- /dev/null +++ b/patches/coreboot-4.8.1/0020-kgpe-d16.patch @@ -0,0 +1,152 @@ +diff --git ./src/mainboard/asus/kgpe-d16/Kconfig ./src/mainboard/asus/kgpe-d16/Kconfig +index 531ba4f..5227d28 100644 +--- ./src/mainboard/asus/kgpe-d16/Kconfig ++++ ./src/mainboard/asus/kgpe-d16/Kconfig +@@ -28,6 +28,7 @@ config BOARD_SPECIFIC_OPTIONS # dummy + select BOARD_ROMSIZE_KB_2048 + select ENABLE_APIC_EXT_ID + select SPI_FLASH ++ select TPM2 + select MAINBOARD_HAS_LPC_TPM + select HAVE_ACPI_RESUME + select DRIVERS_I2C_W83795 +diff --git ./src/mainboard/asus/kgpe-d16/devicetree.cb ./src/mainboard/asus/kgpe-d16/devicetree.cb +index 9039f6d..0ea4216 100644 +--- ./src/mainboard/asus/kgpe-d16/devicetree.cb ++++ ./src/mainboard/asus/kgpe-d16/devicetree.cb +@@ -217,6 +217,9 @@ chip northbridge/amd/amdfam10/root_complex # Root complex + chip drivers/pc80/tpm + device pnp 4e.0 on end # TPM module + end ++ chip drivers/generic/generic # BMC KCS ++ device pnp ca2.0 on end ++ end + end + device pci 14.4 on # Bridge + device pci 1.0 on end # VGA +diff --git ./src/mainboard/asus/kgpe-d16/dsdt.asl ./src/mainboard/asus/kgpe-d16/dsdt.asl +index 6a25b4d..cfcbc98 100644 +--- ./src/mainboard/asus/kgpe-d16/dsdt.asl ++++ ./src/mainboard/asus/kgpe-d16/dsdt.asl +@@ -50,6 +50,9 @@ DefinitionBlock ( + /* HPET enable */ + Name (HPTE, 0x1) + ++ /* IPMI KCS enable */ ++ Name (KCSE, 0x1) ++ + #include + + /* The _PIC method is called by the OS to choose between interrupt +@@ -485,6 +488,13 @@ DefinitionBlock ( + Name (_HID, EisaId ("PNP0A05")) + Name (_ADR, 0x00140003) + ++ OperationRegion(BMRG, SystemIO, 0xca2, 0x02) /* BMC KCS registers */ ++ Field(BMRG, AnyAcc, NoLock, Preserve) ++ { ++ BMRI, 8, /* Index */ ++ BMRD, 8, /* Data */ ++ } ++ + /* Real Time Clock Device */ + Device(RTC0) { + Name(_HID, EISAID("PNP0B00")) /* AT Real Time Clock (not PIIX4 compatible) */ +@@ -606,6 +616,27 @@ DefinitionBlock ( + }) + } + } ++ ++ Device(KCS1) { /* IPMI KCS */ ++ Name(_HID,EISAID("IPI0001")) /* ASpeed BMC */ ++ Method (_STA, 0, NotSerialized) { ++ If(KCSE) { /* Detection enabled */ ++ If(LNotEqual(BMRD, 0xff)) { ++ Return(0x0f) /* Device present */ ++ } ++ Return(Zero) ++ } ++ Return(Zero) ++ } ++ Method(_CRS, 0) { ++ Return(ResourceTemplate() { ++ IO(Decode16, 0x0ca2, 0x0ca2, 0x01, 0x02) ++ }) ++ } ++ Method (_IFT, 0, NotSerialized) { /* Interface type */ ++ Return(One) /* KCS interface */ ++ } ++ } + } + + /* High Precision Event Timer */ +diff --git ./src/mainboard/asus/kgpe-d16/mainboard.c ./src/mainboard/asus/kgpe-d16/mainboard.c +index 65029d4..8ee3a5e 100644 +--- ./src/mainboard/asus/kgpe-d16/mainboard.c ++++ ./src/mainboard/asus/kgpe-d16/mainboard.c +@@ -70,6 +70,13 @@ static void mainboard_enable(device_t dev) + + set_pcie_dereset(); + /* get_ide_dma66(); */ ++ ++ /* Enable access to the BMC IPMI via KCS */ ++ device_t lpc_sio_dev = dev_find_slot_pnp(0xca2, 0); ++ struct resource *res = new_resource(lpc_sio_dev, 0xca2); ++ res->base = 0xca2; ++ res->size = 1; ++ res->flags = IORESOURCE_IO | IORESOURCE_ASSIGNED | IORESOURCE_FIXED; + } + + /* override the default SATA PHY setup */ +diff --git ./src/mainboard/asus/kgpe-d16/romstage.c ./src/mainboard/asus/kgpe-d16/romstage.c +index 63b93c1..bb4f181 100644 +--- ./src/mainboard/asus/kgpe-d16/romstage.c ++++ ./src/mainboard/asus/kgpe-d16/romstage.c +@@ -88,6 +88,47 @@ static void switch_spd_mux(uint8_t channel) + byte &= ~0xc0; /* Enable SPD mux GPIO output drivers */ + byte |= (channel << 2) & 0xc; /* Set SPD mux GPIOs */ + pci_write_config8(PCI_DEV(0, 0x14, 0), 0x54, byte); ++ ++ /* Temporary AST PCI mapping */ ++ uint32_t base_memory = 0xfc000000; ++ uint32_t memory_limit = 0xfc800000; ++ ++ /* Temporarily enable the SP5100 PCI bridge */ ++ uint16_t prev_sec_cfg = pci_read_config16(PCI_DEV(0, 0x14, 4), 0x04); ++ uint8_t prev_sec_bus = pci_read_config8(PCI_DEV(0, 0x14, 4), 0x19); ++ uint8_t prev_sec_sub_bus = pci_read_config8(PCI_DEV(0, 0x14, 4), 0x1a); ++ uint16_t prev_sec_mem_base = pci_read_config16(PCI_DEV(0, 0x14, 4), 0x20); ++ uint16_t prev_sec_mem_limit = pci_read_config16(PCI_DEV(0, 0x14, 4), 0x22); ++ pci_write_config8(PCI_DEV(0, 0x14, 4), 0x19, 0x01); ++ pci_write_config8(PCI_DEV(0, 0x14, 4), 0x1a, 0xff); ++ pci_write_config16(PCI_DEV(0, 0x14, 4), 0x20, (base_memory >> 20)); ++ pci_write_config16(PCI_DEV(0, 0x14, 4), 0x22, (memory_limit >> 20)); ++ pci_write_config16(PCI_DEV(0, 0x14, 4), 0x04, 0x2); ++ ++ /* Temporarily enable AST BAR1 */ ++ uint32_t prev_ast_cfg = pci_read_config32(PCI_DEV(1, 0x1, 0), 0x04); ++ uint32_t prev_ast_bar1 = pci_read_config32(PCI_DEV(1, 0x1, 0), 0x14); ++ pci_write_config32(PCI_DEV(1, 0x1, 0), 0x14, base_memory); ++ pci_write_config32(PCI_DEV(1, 0x1, 0), 0x04, 0x02100002); ++ ++ /* Use the P2A bridge to set ASpeed SPD mux GPIOs to the same values as the SP5100 */ ++ void* ast_bar1 = (void*)base_memory; ++ write32(ast_bar1 + 0xf004, 0x1e780000); /* Enable access to GPIO controller */ ++ write32(ast_bar1 + 0xf000, 0x1); ++ write32(ast_bar1 + 0x10024, read32(ast_bar1 + 0x10024) | 0x3000); /* Enable SPD mux GPIO output drivers */ ++ write32(ast_bar1 + 0x10020, (read32(ast_bar1 + 0x10020) & ~0x3000) | ((channel & 0x3) << 12)); /* Set SPD mux GPIOs */ ++ write32(ast_bar1 + 0xf000, 0x0); ++ ++ /* Deconfigure AST BAR1 */ ++ pci_write_config32(PCI_DEV(1, 0x1, 0), 0x04, prev_ast_cfg); ++ pci_write_config32(PCI_DEV(1, 0x1, 0), 0x14, prev_ast_bar1); ++ ++ /* Deconfigure SP5100 PCI bridge */ ++ pci_write_config16(PCI_DEV(0, 0x14, 4), 0x04, prev_sec_cfg); ++ pci_write_config16(PCI_DEV(0, 0x14, 4), 0x22, prev_sec_mem_limit); ++ pci_write_config16(PCI_DEV(0, 0x14, 4), 0x20, prev_sec_mem_base); ++ pci_write_config8(PCI_DEV(0, 0x14, 4), 0x1a, prev_sec_sub_bus); ++ pci_write_config8(PCI_DEV(0, 0x14, 4), 0x19, prev_sec_bus); + } + + static const uint8_t spd_addr_fam15[] = { diff --git a/patches/coreboot-4.8.1/0030-sandybridge.patch b/patches/coreboot-4.8.1/0030-sandybridge.patch new file mode 100644 index 000000000..8559b4090 --- /dev/null +++ b/patches/coreboot-4.8.1/0030-sandybridge.patch @@ -0,0 +1,58 @@ +diff --git ./src/northbridge/intel/sandybridge/romstage.c ./src/northbridge/intel/sandybridge/romstage.c +index 0426b83..d348b9e 100644 +--- ./src/northbridge/intel/sandybridge/romstage.c ++++ ./src/northbridge/intel/sandybridge/romstage.c +@@ -29,6 +29,8 @@ + #include + #include + #include ++#include ++#include + #include + #include "southbridge/intel/bd82x6x/pch.h" + #include +@@ -72,6 +74,19 @@ void mainboard_romstage_entry(unsigned long bist) + /* Initialize superio */ + mainboard_config_superio(); + ++ if (IS_ENABLED(CONFIG_MEASURED_BOOT) && IS_ENABLED(CONFIG_LPC_TPM)) { ++ // we don't know if we are coming out of a resume ++ // at this point, but want to setup the tpm ASAP ++ init_tpm(0); ++ tlcl_lib_init(); ++ const void * const bootblock = (const void*) 0xFFFFF800; ++ const unsigned bootblock_size = 0x800; ++ tlcl_measure(0, bootblock, bootblock_size); ++ ++ extern char _romstage, _eromstage; ++ tlcl_measure(1, &_romstage, &_eromstage - &_romstage); ++ } ++ + /* USB is initialized in MRC if MRC is used. */ + if (CONFIG_USE_NATIVE_RAMINIT) { + early_usb_init(mainboard_usb_ports); +@@ -117,9 +132,23 @@ void mainboard_romstage_entry(unsigned long bist) + + northbridge_romstage_finalize(s3resume); + +- if (IS_ENABLED(CONFIG_LPC_TPM)) { ++ // the normal TPM init happens here, if we haven't already ++ // set it up as part of the measured boot. ++ if (!IS_ENABLED(CONFIG_MEASURED_BOOT) && IS_ENABLED(CONFIG_LPC_TPM)) { + init_tpm(s3resume); + } + ++ printk(BIOS_DEBUG, "%s: romstage complete\n", __FILE__); ++ + post_code(0x3f); + } ++ ++ ++void platform_segment_loaded(uintptr_t start, size_t size, int flags) ++{ ++ if (IS_ENABLED(CONFIG_MEASURED_BOOT) && !(flags & SEG_NO_MEASURE)) ++ { ++ tlcl_measure(2, (const void*) start, size); ++ } ++} ++ From dd3ae6ee069515bcd447f3c91b1d76ca979ab946 Mon Sep 17 00:00:00 2001 From: Francis Lam Date: Tue, 29 May 2018 13:17:56 -0700 Subject: [PATCH 018/102] Update patches for librem boards --- config/coreboot-librem13v2.config | 79 +-- config/coreboot-librem15v3.config | 79 +-- patches/coreboot-4.7/0000-measuredboot.patch | 475 ------------------ ...M-initialization-when-vboot-is-disab.patch | 72 --- ...intel-skylake-Enable-VT-d-and-X2APIC.patch | 173 ------- ...tel-skylake-Generate-ACPI-DMAR-table.patch | 154 ------ ...purism-librem_skl-Enable-TPM-support.patch | 341 ------------- ...l-Explicitely-enable-VMX-and-Intel-S.patch | 40 -- ...TPM-measurements-to-Skylake-Kabylake.patch | 60 --- ...013-intel-cpu-Fix-SpeedStep-enabling.patch | 37 -- ...librem_skl-Set-TCC-Activation-at-95C.patch | 52 -- ...l-Fix-Librem-15-v3-devicetree-config.patch | 39 -- ...1-librem13v2-liberm15v3-Fix-EC-LPC-I.patch | 74 --- ...e-CPU-s-PPCM-value-for-Turbo-when-se.patch | 63 --- ..._skl-Add-AC-DC-LoadLine-to-VR-Config.patch | 194 ------- patches/coreboot-4.7/0020-kgpe-d16.patch | 152 ------ patches/coreboot-4.7/0030-sandybridge.patch | 58 --- ...-Fix-FSP-2.0-headers-to-match-github.patch | 0 ...TPM-measurements-to-Skylake-Kabylake.patch | 181 +++++++ 19 files changed, 281 insertions(+), 2042 deletions(-) delete mode 100644 patches/coreboot-4.7/0000-measuredboot.patch delete mode 100644 patches/coreboot-4.7/0001-intel-fsp-Fix-TPM-initialization-when-vboot-is-disab.patch delete mode 100644 patches/coreboot-4.7/0003-soc-intel-skylake-Enable-VT-d-and-X2APIC.patch delete mode 100644 patches/coreboot-4.7/0004-soc-intel-skylake-Generate-ACPI-DMAR-table.patch delete mode 100644 patches/coreboot-4.7/0005-purism-librem_skl-Enable-TPM-support.patch delete mode 100644 patches/coreboot-4.7/0006-purism-librem_skl-Explicitely-enable-VMX-and-Intel-S.patch delete mode 100644 patches/coreboot-4.7/0009-Add-heads-TPM-measurements-to-Skylake-Kabylake.patch delete mode 100644 patches/coreboot-4.7/0013-intel-cpu-Fix-SpeedStep-enabling.patch delete mode 100644 patches/coreboot-4.7/0014-purism-librem_skl-Set-TCC-Activation-at-95C.patch delete mode 100644 patches/coreboot-4.7/0015-purism-librem_skl-Fix-Librem-15-v3-devicetree-config.patch delete mode 100644 patches/coreboot-4.7/0016-purism-librem13v1-librem13v2-liberm15v3-Fix-EC-LPC-I.patch delete mode 100644 patches/coreboot-4.7/0017-ec-purism-Fix-the-CPU-s-PPCM-value-for-Turbo-when-se.patch delete mode 100644 patches/coreboot-4.7/0018-purism-librem_skl-Add-AC-DC-LoadLine-to-VR-Config.patch delete mode 100644 patches/coreboot-4.7/0020-kgpe-d16.patch delete mode 100644 patches/coreboot-4.7/0030-sandybridge.patch rename patches/{coreboot-4.7 => coreboot-4.8.1}/0007-intel-fsp-fsp2_0-Fix-FSP-2.0-headers-to-match-github.patch (100%) create mode 100644 patches/coreboot-4.8.1/0009-Add-heads-TPM-measurements-to-Skylake-Kabylake.patch diff --git a/config/coreboot-librem13v2.config b/config/coreboot-librem13v2.config index 74c4a5658..5cc22eee0 100644 --- a/config/coreboot-librem13v2.config +++ b/config/coreboot-librem13v2.config @@ -18,6 +18,7 @@ CONFIG_COMPILER_GCC=y CONFIG_COMPRESS_RAMSTAGE=y CONFIG_INCLUDE_CONFIG_FILE=y CONFIG_COLLECT_TIMESTAMPS=y +# CONFIG_TIMESTAMPS_ON_CONSOLE is not set CONFIG_USE_BLOBS=y # CONFIG_COVERAGE is not set # CONFIG_UBSAN is not set @@ -34,9 +35,7 @@ CONFIG_MEASURED_BOOT=y # # 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 @@ -47,18 +46,14 @@ CONFIG_MEASURED_BOOT=y # 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 @@ -71,40 +66,34 @@ CONFIG_MEASURED_BOOT=y # 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_OCP 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_SCALEWAY is not set # CONFIG_VENDOR_SIEMENS is not set -# CONFIG_VENDOR_SOYO is not set +# CONFIG_VENDOR_SIFIVE 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 @@ -123,12 +112,11 @@ 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_MMCONF_BASE_ADDRESS=0xe0000000 # CONFIG_POST_DEVICE is not set CONFIG_VARIANT_DIR="librem13v2" # CONFIG_VBOOT is not set @@ -152,13 +140,16 @@ 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_LIBREM15_V2 is not set CONFIG_BOARD_PURISM_LIBREM13_V2=y # CONFIG_BOARD_PURISM_LIBREM15_V3 is not set +# CONFIG_BOARD_PURISM_BASEBOARD_LIBREM_BDW 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_SMBIOS_ENCLOSURE_TYPE=0x09 CONFIG_BOARD_ROMSIZE_KB_16384=y # CONFIG_COREBOOT_ROMSIZE_KB_64 is not set # CONFIG_COREBOOT_ROMSIZE_KB_128 is not set @@ -175,7 +166,6 @@ CONFIG_COREBOOT_ROMSIZE_KB_16384=y # 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 @@ -200,7 +190,7 @@ CONFIG_DRIVERS_I2C_DESIGNWARE_CLOCK_MHZ=120 # 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_SOC_INTEL_COMMON_BLOCK_GSPI_CLOCK_MHZ=120 CONFIG_C_ENV_BOOTBLOCK_SIZE=0xC000 CONFIG_X86_TOP4G_BOOTMEDIA_MAP=y CONFIG_ROMSTAGE_ADDR=0x2000000 @@ -208,9 +198,11 @@ 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_IFD_CHIPSET="sklkbl" 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_SOC_INTEL_COMMON_BLOCK_GSPI_MAX=2 # CONFIG_RESET_ON_INVALID_RAMSTAGE_CACHE is not set CONFIG_CHIPSET_BOOTBLOCK_INCLUDE="soc/intel/skylake/bootblock/timestamp.inc" CONFIG_IED_REGION_SIZE=0x400000 @@ -219,8 +211,8 @@ CONFIG_PCIEXP_COMMON_CLOCK=y CONFIG_PCIEXP_CLK_PM=y # CONFIG_SERIAL_CPU_INIT is not set # CONFIG_UART_DEBUG is not set +# CONFIG_NHLT_MAX98373 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 @@ -238,7 +230,7 @@ CONFIG_BOOTBLOCK_RESETS="soc/intel/common/reset.c" # 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_CAR_NEM_ENHANCED=y # CONFIG_USE_SKYLAKE_FSP_CAR is not set CONFIG_SKIP_FSP_CAR=y # CONFIG_NO_FADT_8042 is not set @@ -284,6 +276,7 @@ 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_PMC_INVALID_READ_AFTER_WRITE is not set CONFIG_SOC_INTEL_COMMON_BLOCK_RTC=y CONFIG_SOC_INTEL_COMMON_BLOCK_SATA=y CONFIG_SOC_INTEL_COMMON_BLOCK_SCS=y @@ -291,6 +284,7 @@ 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_SMM_S5_DELAY_MS=0 CONFIG_SOC_INTEL_COMMON_BLOCK_SPI=y CONFIG_SOC_INTEL_COMMON_BLOCK_SA=y CONFIG_SA_PCIEX_LENGTH=0x4000000 @@ -299,13 +293,14 @@ CONFIG_PCIEX_LENGTH_64MB=y CONFIG_SA_ENABLE_DPR=y CONFIG_SOC_INTEL_COMMON_BLOCK_TIMER=y CONFIG_SOC_INTEL_COMMON_BLOCK_UART=y +CONFIG_SOC_INTEL_COMMON_BLOCK_VMX=y +CONFIG_SOC_INTEL_COMMON_BLOCK_XDCI=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 @@ -316,6 +311,7 @@ CONFIG_SOC_INTEL_COMMON_NHLT=y # CONFIG_SOC_NVIDIA_TEGRA210 is not set # CONFIG_SOC_QC_IPQ40XX is not set # CONFIG_SOC_QC_IPQ806X is not set +# CONFIG_SOC_QUALCOMM_SDM845 is not set # CONFIG_SOC_ROCKCHIP_RK3288 is not set # CONFIG_SOC_ROCKCHIP_RK3399 is not set # CONFIG_CPU_SAMSUNG_EXYNOS5250 is not set @@ -394,6 +390,7 @@ CONFIG_MAX_PIRQ_LINKS=4 # 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_COMMON_SMM is not set # CONFIG_LOCK_MANAGEMENT_ENGINE is not set # @@ -417,6 +414,11 @@ CONFIG_HAVE_INTEL_FIRMWARE=y # CONFIG_GOOGLE_SMBIOS_MAINBOARD_VERSION is not set # CONFIG_UEFI_2_4_BINDING is not set CONFIG_UDK_2015_BINDING=y +# CONFIG_UDK_2017_BINDING is not set +CONFIG_UDK_2013_VERSION=2013 +CONFIG_UDK_2015_VERSION=2015 +CONFIG_UDK_2017_VERSION=2017 +CONFIG_UDK_VERSION=2015 # CONFIG_USE_SIEMENS_HWILIB is not set # CONFIG_ARCH_ARM is not set # CONFIG_ARCH_BOOTBLOCK_ARM is not set @@ -447,6 +449,8 @@ CONFIG_UDK_2015_BINDING=y # 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_ARCH_ARMV8_EXTENSION=0 +# CONFIG_ARM64_USE_ARCH_TIMER is not set # CONFIG_ARM64_A53_ERRATUM_843419 is not set # CONFIG_ARCH_MIPS is not set # CONFIG_ARCH_BOOTBLOCK_MIPS is not set @@ -459,6 +463,7 @@ CONFIG_UDK_2015_BINDING=y # CONFIG_ARCH_ROMSTAGE_POWER8 is not set # CONFIG_ARCH_RAMSTAGE_POWER8 is not set # CONFIG_ARCH_RISCV is not set +# CONFIG_ARCH_RISCV_COMPRESSED is not set # CONFIG_ARCH_BOOTBLOCK_RISCV is not set # CONFIG_ARCH_VERSTAGE_RISCV is not set # CONFIG_ARCH_ROMSTAGE_RISCV is not set @@ -484,12 +489,17 @@ CONFIG_PC80_SYSTEM=y # 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_ID_SECTION_OFFSET=0x80 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" +# CONFIG_COLLECT_TIMESTAMPS_NO_TSC is not set +CONFIG_COLLECT_TIMESTAMPS_TSC=y +# CONFIG_PAGING_IN_CACHE_AS_RAM is not set +# CONFIG_IDT_IN_EVERY_STAGE is not set # # Devices @@ -497,8 +507,8 @@ CONFIG_BOOTBLOCK_SOURCE="bootblock_simple.c" 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_RUN_FSP_GOP is not set CONFIG_NO_GFX_INIT=y # CONFIG_MULTIPLE_VGA_ADAPTERS is not set # CONFIG_SMBUS_HAS_AUX_CHANNELS is not set @@ -525,12 +535,12 @@ CONFIG_INTEL_GMA_VBT_FILE="../../blobs/librem_skl/vbt.bin" # 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_MRC_WRITE_NV_LATE is not set # CONFIG_RT8168_GET_MAC_FROM_VPD is not set # CONFIG_RT8168_SET_LED_MODE is not set CONFIG_SPI_FLASH=y @@ -557,7 +567,9 @@ CONFIG_BOOT_DEVICE_SPI_FLASH_RW_NOMMAP_EARLY=y # CONFIG_SMBIOS_PROVIDED_BY_MOBO is not set CONFIG_DRIVERS_I2C_DESIGNWARE=y # CONFIG_DRIVERS_I2C_DESIGNWARE_DEBUG is not set +# CONFIG_DRIVERS_I2C_MAX98373 is not set # CONFIG_DRIVERS_I2C_MAX98927 is not set +# CONFIG_DRIVERS_I2C_PCA9538 is not set # CONFIG_DRIVERS_I2C_PCF8523 is not set # CONFIG_DRIVERS_I2C_RT5663 is not set # CONFIG_DRIVERS_I2C_RTD2132 is not set @@ -574,12 +586,14 @@ CONFIG_DISPLAY_FSP_CALLS_AND_STATUS=y # CONFIG_FSP_CAR is not set CONFIG_FSP_M_XIP=y # CONFIG_VERIFY_HOBS is not set +# CONFIG_DISPLAY_FSP_VERSION_INFO 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_ACPI=y # CONFIG_INTEL_GMA_SSC_ALTERNATE_REF is not set +# CONFIG_INTEL_GMA_SWSMISCI 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 @@ -589,12 +603,12 @@ CONFIG_FSP_M_XIP=y # 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_TPM_RDRESP_NEED_DELAY 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 @@ -613,6 +627,15 @@ CONFIG_TPM_TIS_BASE_ADDRESS=0xfed40000 # # Verified Boot (vboot) # + +# +# Trusted Platform Module +# +CONFIG_TPM=y +# CONFIG_DEBUG_TPM is not set +# CONFIG_MAINBOARD_HAS_TPM_CR50 is not set +CONFIG_MAINBOARD_HAS_LPC_TPM=y +# CONFIG_MAINBOARD_HAS_TPM2 is not set # CONFIG_ACPI_SATA_GENERATOR is not set CONFIG_ACPI_INTEL_HARDWARE_SLEEP_VALUES=y # CONFIG_ACPI_AMD_HARDWARE_SLEEP_VALUES is not set @@ -621,8 +644,6 @@ 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 @@ -694,6 +715,7 @@ CONFIG_PAYLOAD_OPTIONS="" 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 +CONFIG_COMPRESS_SECONDARY_PAYLOAD=y # # Secondary Payloads @@ -717,7 +739,6 @@ CONFIG_MEMTEST_STABLE=y # 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 diff --git a/config/coreboot-librem15v3.config b/config/coreboot-librem15v3.config index 7d6f16da5..5e340add7 100644 --- a/config/coreboot-librem15v3.config +++ b/config/coreboot-librem15v3.config @@ -18,6 +18,7 @@ CONFIG_COMPILER_GCC=y CONFIG_COMPRESS_RAMSTAGE=y CONFIG_INCLUDE_CONFIG_FILE=y CONFIG_COLLECT_TIMESTAMPS=y +# CONFIG_TIMESTAMPS_ON_CONSOLE is not set CONFIG_USE_BLOBS=y # CONFIG_COVERAGE is not set # CONFIG_UBSAN is not set @@ -34,9 +35,7 @@ CONFIG_MEASURED_BOOT=y # # 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 @@ -47,18 +46,14 @@ CONFIG_MEASURED_BOOT=y # 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 @@ -71,40 +66,34 @@ CONFIG_MEASURED_BOOT=y # 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_OCP 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_SCALEWAY is not set # CONFIG_VENDOR_SIEMENS is not set -# CONFIG_VENDOR_SOYO is not set +# CONFIG_VENDOR_SIFIVE 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 @@ -123,12 +112,11 @@ 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_MMCONF_BASE_ADDRESS=0xe0000000 # CONFIG_POST_DEVICE is not set CONFIG_VARIANT_DIR="librem15v3" # CONFIG_VBOOT is not set @@ -152,13 +140,16 @@ 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_LIBREM15_V2 is not set # CONFIG_BOARD_PURISM_LIBREM13_V2 is not set CONFIG_BOARD_PURISM_LIBREM15_V3=y +# CONFIG_BOARD_PURISM_BASEBOARD_LIBREM_BDW 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_SMBIOS_ENCLOSURE_TYPE=0x09 CONFIG_BOARD_ROMSIZE_KB_16384=y # CONFIG_COREBOOT_ROMSIZE_KB_64 is not set # CONFIG_COREBOOT_ROMSIZE_KB_128 is not set @@ -175,7 +166,6 @@ CONFIG_COREBOOT_ROMSIZE_KB_16384=y # 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 @@ -200,7 +190,7 @@ CONFIG_DRIVERS_I2C_DESIGNWARE_CLOCK_MHZ=120 # 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_SOC_INTEL_COMMON_BLOCK_GSPI_CLOCK_MHZ=120 CONFIG_C_ENV_BOOTBLOCK_SIZE=0xC000 CONFIG_X86_TOP4G_BOOTMEDIA_MAP=y CONFIG_ROMSTAGE_ADDR=0x2000000 @@ -208,9 +198,11 @@ 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_IFD_CHIPSET="sklkbl" 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_SOC_INTEL_COMMON_BLOCK_GSPI_MAX=2 # CONFIG_RESET_ON_INVALID_RAMSTAGE_CACHE is not set CONFIG_CHIPSET_BOOTBLOCK_INCLUDE="soc/intel/skylake/bootblock/timestamp.inc" CONFIG_IED_REGION_SIZE=0x400000 @@ -219,8 +211,8 @@ CONFIG_PCIEXP_COMMON_CLOCK=y CONFIG_PCIEXP_CLK_PM=y # CONFIG_SERIAL_CPU_INIT is not set # CONFIG_UART_DEBUG is not set +# CONFIG_NHLT_MAX98373 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 @@ -238,7 +230,7 @@ CONFIG_BOOTBLOCK_RESETS="soc/intel/common/reset.c" # 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_CAR_NEM_ENHANCED=y # CONFIG_USE_SKYLAKE_FSP_CAR is not set CONFIG_SKIP_FSP_CAR=y # CONFIG_NO_FADT_8042 is not set @@ -284,6 +276,7 @@ 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_PMC_INVALID_READ_AFTER_WRITE is not set CONFIG_SOC_INTEL_COMMON_BLOCK_RTC=y CONFIG_SOC_INTEL_COMMON_BLOCK_SATA=y CONFIG_SOC_INTEL_COMMON_BLOCK_SCS=y @@ -291,6 +284,7 @@ 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_SMM_S5_DELAY_MS=0 CONFIG_SOC_INTEL_COMMON_BLOCK_SPI=y CONFIG_SOC_INTEL_COMMON_BLOCK_SA=y CONFIG_SA_PCIEX_LENGTH=0x4000000 @@ -299,13 +293,14 @@ CONFIG_PCIEX_LENGTH_64MB=y CONFIG_SA_ENABLE_DPR=y CONFIG_SOC_INTEL_COMMON_BLOCK_TIMER=y CONFIG_SOC_INTEL_COMMON_BLOCK_UART=y +CONFIG_SOC_INTEL_COMMON_BLOCK_VMX=y +CONFIG_SOC_INTEL_COMMON_BLOCK_XDCI=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 @@ -316,6 +311,7 @@ CONFIG_SOC_INTEL_COMMON_NHLT=y # CONFIG_SOC_NVIDIA_TEGRA210 is not set # CONFIG_SOC_QC_IPQ40XX is not set # CONFIG_SOC_QC_IPQ806X is not set +# CONFIG_SOC_QUALCOMM_SDM845 is not set # CONFIG_SOC_ROCKCHIP_RK3288 is not set # CONFIG_SOC_ROCKCHIP_RK3399 is not set # CONFIG_CPU_SAMSUNG_EXYNOS5250 is not set @@ -394,6 +390,7 @@ CONFIG_MAX_PIRQ_LINKS=4 # 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_COMMON_SMM is not set # CONFIG_LOCK_MANAGEMENT_ENGINE is not set # @@ -417,6 +414,11 @@ CONFIG_HAVE_INTEL_FIRMWARE=y # CONFIG_GOOGLE_SMBIOS_MAINBOARD_VERSION is not set # CONFIG_UEFI_2_4_BINDING is not set CONFIG_UDK_2015_BINDING=y +# CONFIG_UDK_2017_BINDING is not set +CONFIG_UDK_2013_VERSION=2013 +CONFIG_UDK_2015_VERSION=2015 +CONFIG_UDK_2017_VERSION=2017 +CONFIG_UDK_VERSION=2015 # CONFIG_USE_SIEMENS_HWILIB is not set # CONFIG_ARCH_ARM is not set # CONFIG_ARCH_BOOTBLOCK_ARM is not set @@ -447,6 +449,8 @@ CONFIG_UDK_2015_BINDING=y # 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_ARCH_ARMV8_EXTENSION=0 +# CONFIG_ARM64_USE_ARCH_TIMER is not set # CONFIG_ARM64_A53_ERRATUM_843419 is not set # CONFIG_ARCH_MIPS is not set # CONFIG_ARCH_BOOTBLOCK_MIPS is not set @@ -459,6 +463,7 @@ CONFIG_UDK_2015_BINDING=y # CONFIG_ARCH_ROMSTAGE_POWER8 is not set # CONFIG_ARCH_RAMSTAGE_POWER8 is not set # CONFIG_ARCH_RISCV is not set +# CONFIG_ARCH_RISCV_COMPRESSED is not set # CONFIG_ARCH_BOOTBLOCK_RISCV is not set # CONFIG_ARCH_VERSTAGE_RISCV is not set # CONFIG_ARCH_ROMSTAGE_RISCV is not set @@ -484,12 +489,17 @@ CONFIG_PC80_SYSTEM=y # 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_ID_SECTION_OFFSET=0x80 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" +# CONFIG_COLLECT_TIMESTAMPS_NO_TSC is not set +CONFIG_COLLECT_TIMESTAMPS_TSC=y +# CONFIG_PAGING_IN_CACHE_AS_RAM is not set +# CONFIG_IDT_IN_EVERY_STAGE is not set # # Devices @@ -497,8 +507,8 @@ CONFIG_BOOTBLOCK_SOURCE="bootblock_simple.c" 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_RUN_FSP_GOP is not set CONFIG_NO_GFX_INIT=y # CONFIG_MULTIPLE_VGA_ADAPTERS is not set # CONFIG_SMBUS_HAS_AUX_CHANNELS is not set @@ -525,12 +535,12 @@ CONFIG_INTEL_GMA_VBT_FILE="../../blobs/librem_skl/vbt.bin" # 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_MRC_WRITE_NV_LATE is not set # CONFIG_RT8168_GET_MAC_FROM_VPD is not set # CONFIG_RT8168_SET_LED_MODE is not set CONFIG_SPI_FLASH=y @@ -557,7 +567,9 @@ CONFIG_BOOT_DEVICE_SPI_FLASH_RW_NOMMAP_EARLY=y # CONFIG_SMBIOS_PROVIDED_BY_MOBO is not set CONFIG_DRIVERS_I2C_DESIGNWARE=y # CONFIG_DRIVERS_I2C_DESIGNWARE_DEBUG is not set +# CONFIG_DRIVERS_I2C_MAX98373 is not set # CONFIG_DRIVERS_I2C_MAX98927 is not set +# CONFIG_DRIVERS_I2C_PCA9538 is not set # CONFIG_DRIVERS_I2C_PCF8523 is not set # CONFIG_DRIVERS_I2C_RT5663 is not set # CONFIG_DRIVERS_I2C_RTD2132 is not set @@ -574,12 +586,14 @@ CONFIG_DISPLAY_FSP_CALLS_AND_STATUS=y # CONFIG_FSP_CAR is not set CONFIG_FSP_M_XIP=y # CONFIG_VERIFY_HOBS is not set +# CONFIG_DISPLAY_FSP_VERSION_INFO 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_ACPI=y # CONFIG_INTEL_GMA_SSC_ALTERNATE_REF is not set +# CONFIG_INTEL_GMA_SWSMISCI 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 @@ -589,12 +603,12 @@ CONFIG_FSP_M_XIP=y # 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_TPM_RDRESP_NEED_DELAY 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 @@ -613,6 +627,15 @@ CONFIG_TPM_TIS_BASE_ADDRESS=0xfed40000 # # Verified Boot (vboot) # + +# +# Trusted Platform Module +# +CONFIG_TPM=y +# CONFIG_DEBUG_TPM is not set +# CONFIG_MAINBOARD_HAS_TPM_CR50 is not set +CONFIG_MAINBOARD_HAS_LPC_TPM=y +# CONFIG_MAINBOARD_HAS_TPM2 is not set # CONFIG_ACPI_SATA_GENERATOR is not set CONFIG_ACPI_INTEL_HARDWARE_SLEEP_VALUES=y # CONFIG_ACPI_AMD_HARDWARE_SLEEP_VALUES is not set @@ -621,8 +644,6 @@ 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 @@ -694,6 +715,7 @@ CONFIG_PAYLOAD_OPTIONS="" 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 +CONFIG_COMPRESS_SECONDARY_PAYLOAD=y # # Secondary Payloads @@ -717,7 +739,6 @@ CONFIG_MEMTEST_STABLE=y # 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 diff --git a/patches/coreboot-4.7/0000-measuredboot.patch b/patches/coreboot-4.7/0000-measuredboot.patch deleted file mode 100644 index 4dc838578..000000000 --- a/patches/coreboot-4.7/0000-measuredboot.patch +++ /dev/null @@ -1,475 +0,0 @@ -diff --git ./src/Kconfig ./src/Kconfig -index 6896d0e..577bd52 100644 ---- ./src/Kconfig -+++ ./src/Kconfig -@@ -253,6 +253,21 @@ config BOOTSPLASH_FILE - The path and filename of the file to use as graphical bootsplash - screen. The file format has to be jpg. - -+config MEASURED_BOOT -+ bool "Enable TPM measured boot" -+ default n -+ select TPM -+ depends on MAINBOARD_HAS_LPC_TPM -+ depends on !VBOOT -+ help -+ Enable this option to measure the bootblock, romstage and -+ CBFS files into TPM PCRs. This does not verify these values -+ (that is the job of something like vboot), but makes it possible -+ for the payload to validate the boot path and allow something -+ like Heads to attest to the user that the system is likely safe. -+ -+ You probably want to say N. -+ - endmenu - - menu "Mainboard" -diff --git ./src/drivers/pc80/tpm/romstage.c ./src/drivers/pc80/tpm/romstage.c -index 5531458..95e65f2 100644 ---- ./src/drivers/pc80/tpm/romstage.c -+++ ./src/drivers/pc80/tpm/romstage.c -@@ -48,6 +48,12 @@ static const struct { - - static const struct { - u8 buffer[12]; -+} tpm2_startup_cmd = { -+ {0x80, 0x01, 0x0, 0x0, 0x0, 0xc, 0x0, 0x0, 0x01, 0x44, 0x0, 0x0 } -+}; -+ -+static const struct { -+ u8 buffer[12]; - } tpm_deactivate_cmd = { - {0x0, 0xc1, 0x0, 0x0, 0x0, 0xc, 0x0, 0x0, 0x0, 0x99, 0x0, 0x3 } - }; -@@ -229,9 +235,15 @@ void init_tpm(int s3resume) - return; - } - } else { -- printk(BIOS_SPEW, "TPM: Startup\n"); -- result = TlclSendReceive(tpm_startup_cmd.buffer, -- response, sizeof(response)); -+ if (IS_ENABLED(CONFIG_TPM2)) { -+ printk(BIOS_SPEW, "TPM2: Startup\n"); -+ result = TlclSendReceive(tpm2_startup_cmd.buffer, -+ response, sizeof(response)); -+ } else { -+ printk(BIOS_SPEW, "TPM: Startup\n"); -+ result = TlclSendReceive(tpm_startup_cmd.buffer, -+ response, sizeof(response)); -+ } - } - - tis_close(); -diff --git ./src/drivers/pc80/tpm/tpm.c ./src/drivers/pc80/tpm/tpm.c -index 574d3af..9bdc73f 100644 ---- ./src/drivers/pc80/tpm/tpm.c -+++ ./src/drivers/pc80/tpm/tpm.c -@@ -125,10 +125,11 @@ static const struct device_name atmel_devices[] = { - - static const struct device_name infineon_devices[] = { - {0x000b, "SLB9635 TT 1.2"}, -- {0x001a, "SLB9660 TT 1.2"}, - #if IS_ENABLED(CONFIG_TPM2) -+ {0x001a, "SLB9665 TT 2.0"}, - {0x001b, "SLB9670 TT 2.0"}, - #else -+ {0x001a, "SLB9660 TT 1.2"}, - {0x001b, "SLB9670 TT 1.2"}, - #endif - {0xffff} -diff --git ./src/include/program_loading.h ./src/include/program_loading.h -index 416e2e9..40486cd 100644 ---- ./src/include/program_loading.h -+++ ./src/include/program_loading.h -@@ -24,6 +24,8 @@ enum { - /* Last segment of program. Can be used to take different actions for - * cache maintenance of a program load. */ - SEG_FINAL = 1 << 0, -+ /* Indicate that the program segment should not be measured */ -+ 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 -diff --git ./src/lib/cbfs.c ./src/lib/cbfs.c -index 596abc5..f1928ce 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) - if (size != NULL) - *size = fsize; - -- return rdev_mmap(&fh.data, 0, fsize); -+ void * buffer = rdev_mmap(&fh.data, 0, fsize); -+ -+#ifndef __SMM__ -+ prog_segment_loaded((uintptr_t)buffer, fsize, 0); -+#endif -+ -+ return buffer; - } - - 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, - return 0; - if (rdev_readat(rdev, buffer, offset, in_size) != in_size) - return 0; -- return in_size; -+ out_size = in_size; -+ break; - - 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, - timestamp_add_now(TS_START_ULZ4F); - out_size = ulz4fn(compr_start, in_size, buffer, buffer_size); - timestamp_add_now(TS_END_ULZ4F); -- return out_size; -+ break; - - 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, - - rdev_munmap(rdev, map); - -- return out_size; -+ break; - - default: - return 0; - } -+ -+ prog_segment_loaded((uintptr_t)buffer, out_size, 0); -+ -+ return out_size; - } - - static inline int tohex4(unsigned int c) -diff --git ./src/lib/hardwaremain.c ./src/lib/hardwaremain.c -index 0deab4b..eee5415 100644 ---- ./src/lib/hardwaremain.c -+++ ./src/lib/hardwaremain.c -@@ -32,6 +32,7 @@ - #include - #include - #include -+#include - #include - #if IS_ENABLED(CONFIG_HAVE_ACPI_RESUME) - #include -@@ -544,3 +545,13 @@ void boot_state_current_unblock(void) - { - boot_state_unblock(current_phase.state_id, current_phase.seq); - } -+ -+// ramstage measurements go into PCR3 if we are doing measured boot -+void platform_segment_loaded(uintptr_t start, size_t size, int flags) -+{ -+ if (IS_ENABLED(CONFIG_MEASURED_BOOT) && !(flags & SEG_NO_MEASURE)) -+ { -+ tlcl_measure(3, (const void*) start, size); -+ } -+} -+ -diff --git ./src/lib/rmodule.c ./src/lib/rmodule.c -index 66d5120..b50afe7 100644 ---- ./src/lib/rmodule.c -+++ ./src/lib/rmodule.c -@@ -198,7 +198,7 @@ int rmodule_load(void *base, struct rmodule *module) - rmodule_clear_bss(module); - - prog_segment_loaded((uintptr_t)module->location, -- rmodule_memory_size(module), SEG_FINAL); -+ rmodule_memory_size(module), SEG_FINAL | SEG_NO_MEASURE); - - return 0; - } -diff --git ./src/lib/sha1.c ./src/lib/sha1.c -new file mode 100644 -index 0000000..506907f ---- /dev/null -+++ ./src/lib/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 -+ * found in the LICENSE file. -+ * -+ * SHA-1 implementation largely based on libmincrypt in the the Android -+ * Open Source Project (platorm/system/core.git/libmincrypt/sha.c -+ */ -+ -+#include "sha1.h" -+#include -+ -+static uint32_t ror27(uint32_t val) -+{ -+ return (val >> 27) | (val << 5); -+} -+static uint32_t ror2(uint32_t val) -+{ -+ return (val >> 2) | (val << 30); -+} -+static uint32_t ror31(uint32_t val) -+{ -+ return (val >> 31) | (val << 1); -+} -+ -+static void sha1_transform(struct sha1_ctx *ctx) -+{ -+ uint32_t W[80]; -+ register uint32_t A, B, C, D, E; -+ int t; -+ -+ A = ctx->state[0]; -+ B = ctx->state[1]; -+ C = ctx->state[2]; -+ D = ctx->state[3]; -+ E = ctx->state[4]; -+ -+#define SHA_F1(A, B, C, D, E, t) \ -+ E += ror27(A) + \ -+ (W[t] = __builtin_bswap32(ctx->buf.w[t])) + \ -+ (D^(B&(C^D))) + 0x5A827999; \ -+ B = ror2(B); -+ -+ for (t = 0; t < 15; t += 5) { -+ SHA_F1(A, B, C, D, E, t + 0); -+ SHA_F1(E, A, B, C, D, t + 1); -+ SHA_F1(D, E, A, B, C, t + 2); -+ SHA_F1(C, D, E, A, B, t + 3); -+ SHA_F1(B, C, D, E, A, t + 4); -+ } -+ SHA_F1(A, B, C, D, E, t + 0); /* 16th one, t == 15 */ -+ -+#undef SHA_F1 -+ -+#define SHA_F1(A, B, C, D, E, t) \ -+ E += ror27(A) + \ -+ (W[t] = ror31(W[t-3] ^ W[t-8] ^ W[t-14] ^ W[t-16])) + \ -+ (D^(B&(C^D))) + 0x5A827999; \ -+ B = ror2(B); -+ -+ SHA_F1(E, A, B, C, D, t + 1); -+ SHA_F1(D, E, A, B, C, t + 2); -+ SHA_F1(C, D, E, A, B, t + 3); -+ SHA_F1(B, C, D, E, A, t + 4); -+ -+#undef SHA_F1 -+ -+#define SHA_F2(A, B, C, D, E, t) \ -+ E += ror27(A) + \ -+ (W[t] = ror31(W[t-3] ^ W[t-8] ^ W[t-14] ^ W[t-16])) + \ -+ (B^C^D) + 0x6ED9EBA1; \ -+ B = ror2(B); -+ -+ for (t = 20; t < 40; t += 5) { -+ SHA_F2(A, B, C, D, E, t + 0); -+ SHA_F2(E, A, B, C, D, t + 1); -+ SHA_F2(D, E, A, B, C, t + 2); -+ SHA_F2(C, D, E, A, B, t + 3); -+ SHA_F2(B, C, D, E, A, t + 4); -+ } -+ -+#undef SHA_F2 -+ -+#define SHA_F3(A, B, C, D, E, t) \ -+ E += ror27(A) + \ -+ (W[t] = ror31(W[t-3] ^ W[t-8] ^ W[t-14] ^ W[t-16])) + \ -+ ((B&C)|(D&(B|C))) + 0x8F1BBCDC; \ -+ B = ror2(B); -+ -+ for (; t < 60; t += 5) { -+ SHA_F3(A, B, C, D, E, t + 0); -+ SHA_F3(E, A, B, C, D, t + 1); -+ SHA_F3(D, E, A, B, C, t + 2); -+ SHA_F3(C, D, E, A, B, t + 3); -+ SHA_F3(B, C, D, E, A, t + 4); -+ } -+ -+#undef SHA_F3 -+ -+#define SHA_F4(A, B, C, D, E, t) \ -+ E += ror27(A) + \ -+ (W[t] = ror31(W[t-3] ^ W[t-8] ^ W[t-14] ^ W[t-16])) + \ -+ (B^C^D) + 0xCA62C1D6; \ -+ B = ror2(B); -+ -+ for (; t < 80; t += 5) { -+ SHA_F4(A, B, C, D, E, t + 0); -+ SHA_F4(E, A, B, C, D, t + 1); -+ SHA_F4(D, E, A, B, C, t + 2); -+ SHA_F4(C, D, E, A, B, t + 3); -+ SHA_F4(B, C, D, E, A, t + 4); -+ } -+ -+#undef SHA_F4 -+ -+ ctx->state[0] += A; -+ ctx->state[1] += B; -+ ctx->state[2] += C; -+ ctx->state[3] += D; -+ ctx->state[4] += E; -+} -+ -+void sha1_update(struct sha1_ctx *ctx, const uint8_t *data, uint32_t len) -+{ -+ int i = ctx->count % sizeof(ctx->buf); -+ const uint8_t *p = (const uint8_t *)data; -+ -+ ctx->count += len; -+ -+ while (len > sizeof(ctx->buf) - i) { -+ memcpy(&ctx->buf.b[i], p, sizeof(ctx->buf) - i); -+ len -= sizeof(ctx->buf) - i; -+ p += sizeof(ctx->buf) - i; -+ sha1_transform(ctx); -+ i = 0; -+ } -+ -+ while (len--) { -+ ctx->buf.b[i++] = *p++; -+ if (i == sizeof(ctx->buf)) { -+ sha1_transform(ctx); -+ i = 0; -+ } -+ } -+} -+ -+ -+uint8_t *sha1_final(struct sha1_ctx *ctx) -+{ -+ uint32_t cnt = ctx->count * 8; -+ int i; -+ -+ sha1_update(ctx, (uint8_t *)"\x80", 1); -+ while ((ctx->count % sizeof(ctx->buf)) != (sizeof(ctx->buf) - 8)) -+ sha1_update(ctx, (uint8_t *)"\0", 1); -+ -+ for (i = 0; i < 8; ++i) { -+ uint8_t tmp = cnt >> ((7 - i) * 8); -+ sha1_update(ctx, &tmp, 1); -+ } -+ -+ for (i = 0; i < 5; i++) -+ ctx->buf.w[i] = __builtin_bswap32(ctx->state[i]); -+ -+ return ctx->buf.b; -+} -+ -+void sha1_init(struct sha1_ctx *ctx) -+{ -+ ctx->state[0] = 0x67452301; -+ ctx->state[1] = 0xEFCDAB89; -+ ctx->state[2] = 0x98BADCFE; -+ ctx->state[3] = 0x10325476; -+ 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 @@ - #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, - kPcrDigestLength); - return result; - } -+ -+ -+uint32_t tlcl_measure(int pcr_num, const void * start, size_t len) -+{ -+ VBDEBUG("TPM: pcr %d measure %p @ %zu: ", pcr_num, start, len); -+ -+ struct sha1_ctx sha; -+ sha1_init(&sha); -+ sha1_update(&sha, start, len); -+ -+ const uint8_t * hash = sha1_final(&sha); -+ for(unsigned i = 0 ; i < SHA1_DIGEST_SIZE ; i++) -+ VBDEBUG("%02x", hash[i]); -+ VBDEBUG("\n"); -+ -+ //hexdump(start, 128); -+ -+ return tlcl_extend(pcr_num, hash, NULL); -+} -+ 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 ac34a7372..000000000 --- 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 6cc0303ab..000000000 --- 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 9b6d6e197..000000000 --- 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 37c1ed080..000000000 --- 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 d39f4c3f8..000000000 --- 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 309444399..000000000 --- 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 130308ee4..000000000 --- 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 c6536c371..000000000 --- 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 ab29dee75..000000000 --- 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 c20b10070..000000000 --- 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 77a047255..000000000 --- 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 0a8926c78..000000000 --- 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/0020-kgpe-d16.patch b/patches/coreboot-4.7/0020-kgpe-d16.patch deleted file mode 100644 index 5c719b0db..000000000 --- a/patches/coreboot-4.7/0020-kgpe-d16.patch +++ /dev/null @@ -1,152 +0,0 @@ -diff --git ./src/mainboard/asus/kgpe-d16/Kconfig ./src/mainboard/asus/kgpe-d16/Kconfig -index 531ba4f..5227d28 100644 ---- ./src/mainboard/asus/kgpe-d16/Kconfig -+++ ./src/mainboard/asus/kgpe-d16/Kconfig -@@ -28,6 +28,7 @@ config BOARD_SPECIFIC_OPTIONS # dummy - select BOARD_ROMSIZE_KB_2048 - select ENABLE_APIC_EXT_ID - select SPI_FLASH -+ select TPM2 - select MAINBOARD_HAS_LPC_TPM - select HAVE_ACPI_RESUME - select DRIVERS_I2C_W83795 -diff --git ./src/mainboard/asus/kgpe-d16/devicetree.cb ./src/mainboard/asus/kgpe-d16/devicetree.cb -index 9039f6d..0ea4216 100644 ---- ./src/mainboard/asus/kgpe-d16/devicetree.cb -+++ ./src/mainboard/asus/kgpe-d16/devicetree.cb -@@ -217,6 +217,9 @@ chip northbridge/amd/amdfam10/root_complex # Root complex - chip drivers/pc80/tpm - device pnp 4e.0 on end # TPM module - end -+ chip drivers/generic/generic # BMC KCS -+ device pnp ca2.0 on end -+ end - end - device pci 14.4 on # Bridge - device pci 1.0 on end # VGA -diff --git ./src/mainboard/asus/kgpe-d16/dsdt.asl ./src/mainboard/asus/kgpe-d16/dsdt.asl -index 6a25b4d..cfcbc98 100644 ---- ./src/mainboard/asus/kgpe-d16/dsdt.asl -+++ ./src/mainboard/asus/kgpe-d16/dsdt.asl -@@ -50,6 +50,9 @@ DefinitionBlock ( - /* HPET enable */ - Name (HPTE, 0x1) - -+ /* IPMI KCS enable */ -+ Name (KCSE, 0x1) -+ - #include - - /* The _PIC method is called by the OS to choose between interrupt -@@ -485,6 +488,13 @@ DefinitionBlock ( - Name (_HID, EisaId ("PNP0A05")) - Name (_ADR, 0x00140003) - -+ OperationRegion(BMRG, SystemIO, 0xca2, 0x02) /* BMC KCS registers */ -+ Field(BMRG, AnyAcc, NoLock, Preserve) -+ { -+ BMRI, 8, /* Index */ -+ BMRD, 8, /* Data */ -+ } -+ - /* Real Time Clock Device */ - Device(RTC0) { - Name(_HID, EISAID("PNP0B00")) /* AT Real Time Clock (not PIIX4 compatible) */ -@@ -606,6 +616,27 @@ DefinitionBlock ( - }) - } - } -+ -+ Device(KCS1) { /* IPMI KCS */ -+ Name(_HID,EISAID("IPI0001")) /* ASpeed BMC */ -+ Method (_STA, 0, NotSerialized) { -+ If(KCSE) { /* Detection enabled */ -+ If(LNotEqual(BMRD, 0xff)) { -+ Return(0x0f) /* Device present */ -+ } -+ Return(Zero) -+ } -+ Return(Zero) -+ } -+ Method(_CRS, 0) { -+ Return(ResourceTemplate() { -+ IO(Decode16, 0x0ca2, 0x0ca2, 0x01, 0x02) -+ }) -+ } -+ Method (_IFT, 0, NotSerialized) { /* Interface type */ -+ Return(One) /* KCS interface */ -+ } -+ } - } - - /* High Precision Event Timer */ -diff --git ./src/mainboard/asus/kgpe-d16/mainboard.c ./src/mainboard/asus/kgpe-d16/mainboard.c -index 65029d4..8ee3a5e 100644 ---- ./src/mainboard/asus/kgpe-d16/mainboard.c -+++ ./src/mainboard/asus/kgpe-d16/mainboard.c -@@ -70,6 +70,13 @@ static void mainboard_enable(device_t dev) - - set_pcie_dereset(); - /* get_ide_dma66(); */ -+ -+ /* Enable access to the BMC IPMI via KCS */ -+ device_t lpc_sio_dev = dev_find_slot_pnp(0xca2, 0); -+ struct resource *res = new_resource(lpc_sio_dev, 0xca2); -+ res->base = 0xca2; -+ res->size = 1; -+ res->flags = IORESOURCE_IO | IORESOURCE_ASSIGNED | IORESOURCE_FIXED; - } - - /* override the default SATA PHY setup */ -diff --git ./src/mainboard/asus/kgpe-d16/romstage.c ./src/mainboard/asus/kgpe-d16/romstage.c -index 63b93c1..bb4f181 100644 ---- ./src/mainboard/asus/kgpe-d16/romstage.c -+++ ./src/mainboard/asus/kgpe-d16/romstage.c -@@ -88,6 +88,47 @@ static void switch_spd_mux(uint8_t channel) - byte &= ~0xc0; /* Enable SPD mux GPIO output drivers */ - byte |= (channel << 2) & 0xc; /* Set SPD mux GPIOs */ - pci_write_config8(PCI_DEV(0, 0x14, 0), 0x54, byte); -+ -+ /* Temporary AST PCI mapping */ -+ uint32_t base_memory = 0xfc000000; -+ uint32_t memory_limit = 0xfc800000; -+ -+ /* Temporarily enable the SP5100 PCI bridge */ -+ uint16_t prev_sec_cfg = pci_read_config16(PCI_DEV(0, 0x14, 4), 0x04); -+ uint8_t prev_sec_bus = pci_read_config8(PCI_DEV(0, 0x14, 4), 0x19); -+ uint8_t prev_sec_sub_bus = pci_read_config8(PCI_DEV(0, 0x14, 4), 0x1a); -+ uint16_t prev_sec_mem_base = pci_read_config16(PCI_DEV(0, 0x14, 4), 0x20); -+ uint16_t prev_sec_mem_limit = pci_read_config16(PCI_DEV(0, 0x14, 4), 0x22); -+ pci_write_config8(PCI_DEV(0, 0x14, 4), 0x19, 0x01); -+ pci_write_config8(PCI_DEV(0, 0x14, 4), 0x1a, 0xff); -+ pci_write_config16(PCI_DEV(0, 0x14, 4), 0x20, (base_memory >> 20)); -+ pci_write_config16(PCI_DEV(0, 0x14, 4), 0x22, (memory_limit >> 20)); -+ pci_write_config16(PCI_DEV(0, 0x14, 4), 0x04, 0x2); -+ -+ /* Temporarily enable AST BAR1 */ -+ uint32_t prev_ast_cfg = pci_read_config32(PCI_DEV(1, 0x1, 0), 0x04); -+ uint32_t prev_ast_bar1 = pci_read_config32(PCI_DEV(1, 0x1, 0), 0x14); -+ pci_write_config32(PCI_DEV(1, 0x1, 0), 0x14, base_memory); -+ pci_write_config32(PCI_DEV(1, 0x1, 0), 0x04, 0x02100002); -+ -+ /* Use the P2A bridge to set ASpeed SPD mux GPIOs to the same values as the SP5100 */ -+ void* ast_bar1 = (void*)base_memory; -+ write32(ast_bar1 + 0xf004, 0x1e780000); /* Enable access to GPIO controller */ -+ write32(ast_bar1 + 0xf000, 0x1); -+ write32(ast_bar1 + 0x10024, read32(ast_bar1 + 0x10024) | 0x3000); /* Enable SPD mux GPIO output drivers */ -+ write32(ast_bar1 + 0x10020, (read32(ast_bar1 + 0x10020) & ~0x3000) | ((channel & 0x3) << 12)); /* Set SPD mux GPIOs */ -+ write32(ast_bar1 + 0xf000, 0x0); -+ -+ /* Deconfigure AST BAR1 */ -+ pci_write_config32(PCI_DEV(1, 0x1, 0), 0x04, prev_ast_cfg); -+ pci_write_config32(PCI_DEV(1, 0x1, 0), 0x14, prev_ast_bar1); -+ -+ /* Deconfigure SP5100 PCI bridge */ -+ pci_write_config16(PCI_DEV(0, 0x14, 4), 0x04, prev_sec_cfg); -+ pci_write_config16(PCI_DEV(0, 0x14, 4), 0x22, prev_sec_mem_limit); -+ pci_write_config16(PCI_DEV(0, 0x14, 4), 0x20, prev_sec_mem_base); -+ pci_write_config8(PCI_DEV(0, 0x14, 4), 0x1a, prev_sec_sub_bus); -+ pci_write_config8(PCI_DEV(0, 0x14, 4), 0x19, prev_sec_bus); - } - - static const uint8_t spd_addr_fam15[] = { diff --git a/patches/coreboot-4.7/0030-sandybridge.patch b/patches/coreboot-4.7/0030-sandybridge.patch deleted file mode 100644 index 87ce79b48..000000000 --- a/patches/coreboot-4.7/0030-sandybridge.patch +++ /dev/null @@ -1,58 +0,0 @@ -diff --git ./src/northbridge/intel/sandybridge/romstage.c ./src/northbridge/intel/sandybridge/romstage.c -index 8608d5a..dac90ee 100644 ---- ./src/northbridge/intel/sandybridge/romstage.c -+++ ./src/northbridge/intel/sandybridge/romstage.c -@@ -29,6 +29,8 @@ - #include - #include - #include -+#include -+#include - #include - #include "southbridge/intel/bd82x6x/pch.h" - #include -@@ -72,6 +74,19 @@ void mainboard_romstage_entry(unsigned long bist) - /* Initialize superio */ - mainboard_config_superio(); - -+ if (IS_ENABLED(CONFIG_MEASURED_BOOT) && IS_ENABLED(CONFIG_LPC_TPM)) { -+ // we don't know if we are coming out of a resume -+ // at this point, but want to setup the tpm ASAP -+ init_tpm(0); -+ tlcl_lib_init(); -+ const void * const bootblock = (const void*) 0xFFFFF800; -+ const unsigned bootblock_size = 0x800; -+ tlcl_measure(0, bootblock, bootblock_size); -+ -+ extern char _romstage, _eromstage; -+ tlcl_measure(1, &_romstage, &_eromstage - &_romstage); -+ } -+ - /* 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) - - northbridge_romstage_finalize(s3resume); - -- if (IS_ENABLED(CONFIG_LPC_TPM)) { -+ // the normal TPM init happens here, if we haven't already -+ // set it up as part of the measured boot. -+ if (!IS_ENABLED(CONFIG_MEASURED_BOOT) && IS_ENABLED(CONFIG_LPC_TPM)) { - init_tpm(s3resume); - } - -+ printk(BIOS_DEBUG, "%s: romstage complete\n", __FILE__); -+ - post_code(0x3f); - } -+ -+ -+void platform_segment_loaded(uintptr_t start, size_t size, int flags) -+{ -+ if (IS_ENABLED(CONFIG_MEASURED_BOOT) && !(flags & SEG_NO_MEASURE)) -+ { -+ tlcl_measure(2, (const void*) start, size); -+ } -+} -+ 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 000000000..c3ab47312 --- /dev/null +++ b/patches/coreboot-4.8.1/0009-Add-heads-TPM-measurements-to-Skylake-Kabylake.patch @@ -0,0 +1,181 @@ +diff --git ./src/arch/x86/acpi.c ./src/arch/x86/acpi.c +index 8b6b2c1..fca4a76 100644 +--- ./src/arch/x86/acpi.c ++++ ./src/arch/x86/acpi.c +@@ -48,6 +48,7 @@ + #include + #include + #include ++#include + + u8 acpi_checksum(u8 *table, u32 length) + { +@@ -1020,6 +1021,10 @@ unsigned long write_acpi_tables(unsigned long start) + return current; + } + ++ if (IS_ENABLED(CONFIG_MEASURED_BOOT)) { ++ tlcl_measure(2, (const void*) dsdt_file, dsdt_size); ++ } ++ + slic_file = cbfs_boot_map_with_leak(CONFIG_CBFS_PREFIX "/slic", + CBFS_TYPE_RAW, &slic_size); + if (slic_file +diff --git ./src/arch/x86/postcar.c ./src/arch/x86/postcar.c +index 6497b73..e846b69 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..124d3fa 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,33 @@ 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); ++ } ++ ++ if (IS_ENABLED(CONFIG_MEASURED_BOOT)) { ++ tlcl_measure(1, (const void*) hdr.image_base, hdr.image_size); ++ } ++ + /* Signal that FSP component has been loaded. */ +- prog_segment_loaded(hdr.image_base, hdr.image_size, SEG_FINAL); ++ // Don't measure since it is relocated at this point ++ prog_segment_loaded(hdr.image_base, hdr.image_size, SEG_FINAL | SEG_NO_MEASURE); + + 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..49220af 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/intel/gma/opregion.c ./src/drivers/intel/gma/opregion.c +index 70cbccc..e2cad8f 100644 +--- ./src/drivers/intel/gma/opregion.c ++++ ./src/drivers/intel/gma/opregion.c +@@ -24,6 +24,7 @@ + #include + #include + #include ++#include + #include "intel_bios.h" + #include "opregion.h" + +@@ -57,6 +58,10 @@ void *locate_vbt(size_t *vbt_size) + if (vbt_size) + *vbt_size = file_size; + ++ if (IS_ENABLED(CONFIG_MEASURED_BOOT)) { ++ tlcl_measure(2, (const void*) vbt_data, file_size); ++ } ++ + memcpy(&vbtsig, vbt_data, sizeof(vbtsig)); + if (vbtsig != VBT_SIGNATURE) { + printk(BIOS_ERR, "Missing/invalid signature in VBT data file!\n"); +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..01a70b3 100644 +--- ./src/security/tpm/Makefile.inc ++++ ./src/security/tpm/Makefile.inc +@@ -4,6 +4,9 @@ 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 + ++postcar-$(CONFIG_TPM) += tss/tcg-1.2/tss.c ++postcar-$(CONFIG_TPM) += sha1.c ++ + 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 From 8601268a1f731a373ac8a33c315ec24018348696 Mon Sep 17 00:00:00 2001 From: Francis Lam Date: Sat, 2 Jun 2018 09:46:57 -0700 Subject: [PATCH 019/102] Remove duplicate measurements on librem components also fix indentation issues --- ...TPM-measurements-to-Skylake-Kabylake.patch | 71 +++---------------- 1 file changed, 10 insertions(+), 61 deletions(-) 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 index c3ab47312..75ac4cf26 100644 --- 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 @@ -1,28 +1,5 @@ -diff --git ./src/arch/x86/acpi.c ./src/arch/x86/acpi.c -index 8b6b2c1..fca4a76 100644 ---- ./src/arch/x86/acpi.c -+++ ./src/arch/x86/acpi.c -@@ -48,6 +48,7 @@ - #include - #include - #include -+#include - - u8 acpi_checksum(u8 *table, u32 length) - { -@@ -1020,6 +1021,10 @@ unsigned long write_acpi_tables(unsigned long start) - return current; - } - -+ if (IS_ENABLED(CONFIG_MEASURED_BOOT)) { -+ tlcl_measure(2, (const void*) dsdt_file, dsdt_size); -+ } -+ - slic_file = cbfs_boot_map_with_leak(CONFIG_CBFS_PREFIX "/slic", - CBFS_TYPE_RAW, &slic_size); - if (slic_file diff --git ./src/arch/x86/postcar.c ./src/arch/x86/postcar.c -index 6497b73..e846b69 100644 +index 6497b73..485b051 100644 --- ./src/arch/x86/postcar.c +++ ./src/arch/x86/postcar.c @@ -19,6 +19,7 @@ @@ -41,12 +18,12 @@ index 6497b73..e846b69 100644 +void platform_segment_loaded(uintptr_t start, size_t size, int flags) +{ + if (IS_ENABLED(CONFIG_MEASURED_BOOT) && !(flags & SEG_NO_MEASURE)) { -+ tlcl_measure(2, (const void*) start, size); ++ 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..124d3fa 100644 +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) @@ -58,12 +35,12 @@ index 30987ce..124d3fa 100644 */ 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)) ++ !IS_ENABLED(CONFIG_VBOOT_STARTS_IN_BOOTBLOCK) && ++ !IS_ENABLED(CONFIG_MEASURED_BOOT)) init_tpm(s3wake); } -@@ -483,8 +484,33 @@ void fsp_memory_init(bool s3wake) +@@ -483,8 +484,29 @@ void fsp_memory_init(bool s3wake) if (status != CB_SUCCESS) die("Loading FSPM failed!\n"); @@ -78,15 +55,10 @@ index 30987ce..124d3fa 100644 + + tlcl_measure(1, _romstage, _eromstage - _romstage); + } -+ -+ if (IS_ENABLED(CONFIG_MEASURED_BOOT)) { -+ tlcl_measure(1, (const void*) hdr.image_base, hdr.image_size); -+ } + /* Signal that FSP component has been loaded. */ -- prog_segment_loaded(hdr.image_base, hdr.image_size, SEG_FINAL); + // Don't measure since it is relocated at this point -+ prog_segment_loaded(hdr.image_base, hdr.image_size, SEG_FINAL | SEG_NO_MEASURE); + prog_segment_loaded(hdr.image_base, hdr.image_size, SEG_FINAL); do_fsp_memory_init(&hdr, s3wake, &memmap); } @@ -94,12 +66,12 @@ index 30987ce..124d3fa 100644 +void platform_segment_loaded(uintptr_t start, size_t size, int flags) +{ + if (IS_ENABLED(CONFIG_MEASURED_BOOT) && !(flags & SEG_NO_MEASURE)) { -+ tlcl_measure(1, (const void*) start, size); ++ 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..49220af 100644 +index bda88d1..49568f6 100644 --- ./src/drivers/intel/fsp2_0/silicon_init.c +++ ./src/drivers/intel/fsp2_0/silicon_init.c @@ -18,6 +18,7 @@ @@ -115,7 +87,7 @@ index bda88d1..49220af 100644 die("Failed to read FSPS!\n"); + if (IS_ENABLED(CONFIG_MEASURED_BOOT)) { -+ tlcl_measure(1, (const void*) dest, size); ++ tlcl_measure(1, (const void*) dest, size); + } + if (fsp_component_relocate((uintptr_t)dest, dest, size) < 0) @@ -130,29 +102,6 @@ index bda88d1..49220af 100644 load_done = 1; } -diff --git ./src/drivers/intel/gma/opregion.c ./src/drivers/intel/gma/opregion.c -index 70cbccc..e2cad8f 100644 ---- ./src/drivers/intel/gma/opregion.c -+++ ./src/drivers/intel/gma/opregion.c -@@ -24,6 +24,7 @@ - #include - #include - #include -+#include - #include "intel_bios.h" - #include "opregion.h" - -@@ -57,6 +58,10 @@ void *locate_vbt(size_t *vbt_size) - if (vbt_size) - *vbt_size = file_size; - -+ if (IS_ENABLED(CONFIG_MEASURED_BOOT)) { -+ tlcl_measure(2, (const void*) vbt_data, file_size); -+ } -+ - memcpy(&vbtsig, vbt_data, sizeof(vbtsig)); - if (vbtsig != VBT_SIGNATURE) { - printk(BIOS_ERR, "Missing/invalid signature in VBT data file!\n"); diff --git ./src/drivers/pc80/tpm/Makefile.inc ./src/drivers/pc80/tpm/Makefile.inc index 9d428b5..1d2364f 100644 --- ./src/drivers/pc80/tpm/Makefile.inc From 0113ecc806b167d12d877e141d7d387af1a677e2 Mon Sep 17 00:00:00 2001 From: Francis Lam Date: Fri, 8 Jun 2018 10:39:36 -0700 Subject: [PATCH 020/102] Update coreboot patches condition on CONFIG_MEASURED_BOOT --- .../coreboot-4.8.1/0000-measuredboot.patch | 22 ++++++++++--------- ...TPM-measurements-to-Skylake-Kabylake.patch | 6 +++-- 2 files changed, 16 insertions(+), 12 deletions(-) diff --git a/patches/coreboot-4.8.1/0000-measuredboot.patch b/patches/coreboot-4.8.1/0000-measuredboot.patch index 4bd843ebf..7731a5aef 100644 --- a/patches/coreboot-4.8.1/0000-measuredboot.patch +++ b/patches/coreboot-4.8.1/0000-measuredboot.patch @@ -146,7 +146,7 @@ index 87ab387..708d321 100644 static inline int tohex4(unsigned int c) diff --git ./src/lib/hardwaremain.c ./src/lib/hardwaremain.c -index 6fd55d7..edcc668 100644 +index 6fd55d7..b5b7d91 100644 --- ./src/lib/hardwaremain.c +++ ./src/lib/hardwaremain.c @@ -33,6 +33,7 @@ @@ -185,26 +185,28 @@ index 66d5120..b50afe7 100644 return 0; } diff --git ./src/security/tpm/Makefile.inc ./src/security/tpm/Makefile.inc -index 2385635..52d088c 100644 +index 2385635..0743a84 100644 --- ./src/security/tpm/Makefile.inc +++ ./src/security/tpm/Makefile.inc -@@ -4,8 +4,12 @@ verstage-$(CONFIG_TPM) += tss/tcg-1.2/tss.c +@@ -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_VBOOT_SEPARATE_VERSTAGE),y) - romstage-$(CONFIG_TPM) += tss/tcg-1.2/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) + 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 - romstage-$(CONFIG_TPM2) += tss/tcg-2.0/tss.c - endif # CONFIG_VBOOT_SEPARATE_VERSTAGE 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/security/tpm/sha1.c @@ -0,0 +1,175 @@ @@ -437,7 +439,7 @@ index 8f3f1cb..5c569cb 100644 */ 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..4577ec4 100644 +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 @@ 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 index 75ac4cf26..9b3898e72 100644 --- 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 @@ -115,15 +115,17 @@ index 9d428b5..1d2364f 100644 endif diff --git ./src/security/tpm/Makefile.inc ./src/security/tpm/Makefile.inc -index 2385635..01a70b3 100644 +index 2385635..7ef24cc 100644 --- ./src/security/tpm/Makefile.inc +++ ./src/security/tpm/Makefile.inc -@@ -4,6 +4,9 @@ verstage-$(CONFIG_TPM) += tss/tcg-1.2/tss.c +@@ -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 From 0bb78d343f4ab0e72caa1e834bb818d6bb245b5a Mon Sep 17 00:00:00 2001 From: Trammell hudson Date: Mon, 13 Aug 2018 10:26:08 -0400 Subject: [PATCH 021/102] Use defconfig for coreboot builds --- modules/coreboot | 25 +++++++++++++++++-------- 1 file changed, 17 insertions(+), 8 deletions(-) diff --git a/modules/coreboot b/modules/coreboot index 99637f635..137697e01 100644 --- a/modules/coreboot +++ b/modules/coreboot @@ -19,18 +19,18 @@ $(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)" \ 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)" \ BUILD_TIMELESS=1 \ CFLAGS_x86_32="$(EXTRA_FLAGS)" \ CFLAGS_x86_64="$(EXTRA_FLAGS)" \ @@ -64,9 +64,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 From 79c14346106818769df5befd7708d7b724a61fb0 Mon Sep 17 00:00:00 2001 From: Francis Lam Date: Sat, 27 Oct 2018 14:03:45 -0700 Subject: [PATCH 022/102] Fix DOTCONFIG in coreboot module and clean up configs --- config/coreboot-kgpe-d16.config | 715 ----------------------------- config/coreboot-librem13v2.config | 731 ------------------------------ config/coreboot-librem15v3.config | 731 ------------------------------ config/coreboot-qemu.config | 574 ----------------------- config/coreboot-x220.config | 680 --------------------------- config/coreboot-x230-flash.config | 709 ----------------------------- config/coreboot-x230.config | 686 ---------------------------- modules/coreboot | 2 + 8 files changed, 2 insertions(+), 4826 deletions(-) diff --git a/config/coreboot-kgpe-d16.config b/config/coreboot-kgpe-d16.config index adc415020..4be5a04b7 100644 --- a/config/coreboot-kgpe-d16.config +++ b/config/coreboot-kgpe-d16.config @@ -1,729 +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_AAEON 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_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_COMPULAB is not set -# CONFIG_VENDOR_CUBIETECH is not set -# CONFIG_VENDOR_DIGITALLOGIC 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_IWILL is not set -# CONFIG_VENDOR_JETWAY is not set -# CONFIG_VENDOR_KONTRON 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_MSI is not set -# CONFIG_VENDOR_NVIDIA is not set -# CONFIG_VENDOR_OCP is not set -# CONFIG_VENDOR_PACKARDBELL is not set -# CONFIG_VENDOR_PCENGINES is not set -# CONFIG_VENDOR_PURISM is not set -# CONFIG_VENDOR_RODA is not set -# CONFIG_VENDOR_SAMSUNG is not set -# CONFIG_VENDOR_SAPPHIRE is not set -# CONFIG_VENDOR_SCALEWAY is not set -# CONFIG_VENDOR_SIEMENS is not set -# CONFIG_VENDOR_SIFIVE is not set -# CONFIG_VENDOR_SUNW is not set -# CONFIG_VENDOR_SUPERMICRO is not set -# CONFIG_VENDOR_TECHNEXION 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_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_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_MAXIMUS_IV_GENE_Z 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_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_MMCONF_BASE_ADDRESS=0xc0000000 -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_SMBIOS_ENCLOSURE_TYPE=0x03 -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_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_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_QUALCOMM_SDM845 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_HPET_MIN_TICKS=0x14 -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 -# CONFIG_SOUTHBRIDGE_INTEL_COMMON_SMM 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_UDK_2017_BINDING is not set -CONFIG_UDK_2013_VERSION=2013 -CONFIG_UDK_2015_VERSION=2015 -CONFIG_UDK_2017_VERSION=2017 -CONFIG_UDK_VERSION=2013 -# 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_ARCH_ARMV8_EXTENSION=0 -# CONFIG_ARM64_USE_ARCH_TIMER 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_RISCV_COMPRESSED 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_ID_SECTION_OFFSET=0x80 -# 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" -# CONFIG_PAGING_IN_CACHE_AS_RAM is not set -# CONFIG_IDT_IN_EVERY_STAGE is not set - -# -# Devices -# -CONFIG_HAVE_VGA_TEXT_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_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_MAX98373 is not set -# CONFIG_DRIVERS_I2C_MAX98927 is not set -# CONFIG_DRIVERS_I2C_PCA9538 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_PLATFORM_USES_FSP2_0 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_INTEL_GMA_SWSMISCI 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_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_TPM_RDRESP_NEED_DELAY 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) -# - -# -# Trusted Platform Module -# -# CONFIG_TPM is not set -CONFIG_TPM2=y -# CONFIG_DEBUG_TPM is not set -# CONFIG_MAINBOARD_HAS_TPM_CR50 is not set -CONFIG_MAINBOARD_HAS_LPC_TPM=y -# CONFIG_MAINBOARD_HAS_TPM2 is not set -# 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 - -# -# 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 -CONFIG_COMPRESS_SECONDARY_PAYLOAD=y - -# -# 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_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 5cc22eee0..f05c1d120 100644 --- a/config/coreboot-librem13v2.config +++ b/config/coreboot-librem13v2.config @@ -1,763 +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_TIMESTAMPS_ON_CONSOLE is not set 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_AAEON 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_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_COMPULAB is not set -# CONFIG_VENDOR_CUBIETECH is not set -# CONFIG_VENDOR_DIGITALLOGIC 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_IWILL is not set -# CONFIG_VENDOR_JETWAY is not set -# CONFIG_VENDOR_KONTRON 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_MSI is not set -# CONFIG_VENDOR_NVIDIA is not set -# CONFIG_VENDOR_OCP is not set -# CONFIG_VENDOR_PACKARDBELL is not set -# CONFIG_VENDOR_PCENGINES is not set CONFIG_VENDOR_PURISM=y -# CONFIG_VENDOR_RODA is not set -# CONFIG_VENDOR_SAMSUNG is not set -# CONFIG_VENDOR_SAPPHIRE is not set -# CONFIG_VENDOR_SCALEWAY is not set -# CONFIG_VENDOR_SIEMENS is not set -# CONFIG_VENDOR_SIFIVE is not set -# CONFIG_VENDOR_SUNW is not set -# CONFIG_VENDOR_SUPERMICRO is not set -# CONFIG_VENDOR_TECHNEXION 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_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_POST_IO is not set -CONFIG_DEVICETREE="variants/librem13v2/devicetree.cb" -CONFIG_MAX_REBOOT_CNT=3 -# CONFIG_HAVE_GBE_BIN is not set -CONFIG_MMCONF_BASE_ADDRESS=0xe0000000 # 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_LIBREM15_V2 is not set CONFIG_BOARD_PURISM_LIBREM13_V2=y -# CONFIG_BOARD_PURISM_LIBREM15_V3 is not set -# CONFIG_BOARD_PURISM_BASEBOARD_LIBREM_BDW 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_SMBIOS_ENCLOSURE_TYPE=0x09 -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_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_BLOCK_GSPI_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_IFD_CHIPSET="sklkbl" -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_SOC_INTEL_COMMON_BLOCK_GSPI_MAX=2 -# 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_NHLT_MAX98373 is not set -CONFIG_MAX_ROOT_PORTS=24 -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_USE_SKYLAKE_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_PMC_INVALID_READ_AFTER_WRITE 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_SMM_S5_DELAY_MS=0 -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_VMX=y -CONFIG_SOC_INTEL_COMMON_BLOCK_XDCI=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_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_QUALCOMM_SDM845 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_SOUTHBRIDGE_INTEL_COMMON_SMM 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_UDK_2017_BINDING is not set -CONFIG_UDK_2013_VERSION=2013 -CONFIG_UDK_2015_VERSION=2015 -CONFIG_UDK_2017_VERSION=2017 -CONFIG_UDK_VERSION=2015 -# 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_ARCH_ARMV8_EXTENSION=0 -# CONFIG_ARM64_USE_ARCH_TIMER 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_RISCV_COMPRESSED 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_ID_SECTION_OFFSET=0x80 -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" -# CONFIG_COLLECT_TIMESTAMPS_NO_TSC is not set -CONFIG_COLLECT_TIMESTAMPS_TSC=y -# CONFIG_PAGING_IN_CACHE_AS_RAM is not set -# CONFIG_IDT_IN_EVERY_STAGE is not set - -# -# Devices -# -CONFIG_HAVE_FSP_GOP=y -# CONFIG_MAINBOARD_HAS_NATIVE_VGA_INIT is not set -# CONFIG_MAINBOARD_HAS_LIBGFXINIT is not set -# CONFIG_VGA_ROM_RUN is not set -# CONFIG_RUN_FSP_GOP 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_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_MRC_WRITE_NV_LATE 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_MAX98373 is not set -# CONFIG_DRIVERS_I2C_MAX98927 is not set -# CONFIG_DRIVERS_I2C_PCA9538 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_DISPLAY_FSP_VERSION_INFO 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=y -# CONFIG_INTEL_GMA_SSC_ALTERNATE_REF is not set -# CONFIG_INTEL_GMA_SWSMISCI 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_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_TPM_RDRESP_NEED_DELAY 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) -# - -# -# Trusted Platform Module -# -CONFIG_TPM=y -# CONFIG_DEBUG_TPM is not set -# CONFIG_MAINBOARD_HAS_TPM_CR50 is not set -CONFIG_MAINBOARD_HAS_LPC_TPM=y -# CONFIG_MAINBOARD_HAS_TPM2 is not set -# 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 - -# -# 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 -CONFIG_COMPRESS_SECONDARY_PAYLOAD=y - -# -# 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_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 5e340add7..53d196b58 100644 --- a/config/coreboot-librem15v3.config +++ b/config/coreboot-librem15v3.config @@ -1,763 +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_TIMESTAMPS_ON_CONSOLE is not set 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_AAEON 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_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_COMPULAB is not set -# CONFIG_VENDOR_CUBIETECH is not set -# CONFIG_VENDOR_DIGITALLOGIC 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_IWILL is not set -# CONFIG_VENDOR_JETWAY is not set -# CONFIG_VENDOR_KONTRON 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_MSI is not set -# CONFIG_VENDOR_NVIDIA is not set -# CONFIG_VENDOR_OCP is not set -# CONFIG_VENDOR_PACKARDBELL is not set -# CONFIG_VENDOR_PCENGINES is not set CONFIG_VENDOR_PURISM=y -# CONFIG_VENDOR_RODA is not set -# CONFIG_VENDOR_SAMSUNG is not set -# CONFIG_VENDOR_SAPPHIRE is not set -# CONFIG_VENDOR_SCALEWAY is not set -# CONFIG_VENDOR_SIEMENS is not set -# CONFIG_VENDOR_SIFIVE is not set -# CONFIG_VENDOR_SUNW is not set -# CONFIG_VENDOR_SUPERMICRO is not set -# CONFIG_VENDOR_TECHNEXION 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_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_POST_IO is not set -CONFIG_DEVICETREE="variants/librem15v3/devicetree.cb" -CONFIG_MAX_REBOOT_CNT=3 -# CONFIG_HAVE_GBE_BIN is not set -CONFIG_MMCONF_BASE_ADDRESS=0xe0000000 # 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_LIBREM15_V2 is not set -# CONFIG_BOARD_PURISM_LIBREM13_V2 is not set CONFIG_BOARD_PURISM_LIBREM15_V3=y -# CONFIG_BOARD_PURISM_BASEBOARD_LIBREM_BDW 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_SMBIOS_ENCLOSURE_TYPE=0x09 -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_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_BLOCK_GSPI_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_IFD_CHIPSET="sklkbl" -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_SOC_INTEL_COMMON_BLOCK_GSPI_MAX=2 -# 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_NHLT_MAX98373 is not set -CONFIG_MAX_ROOT_PORTS=24 -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_USE_SKYLAKE_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_PMC_INVALID_READ_AFTER_WRITE 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_SMM_S5_DELAY_MS=0 -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_VMX=y -CONFIG_SOC_INTEL_COMMON_BLOCK_XDCI=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_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_QUALCOMM_SDM845 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_SOUTHBRIDGE_INTEL_COMMON_SMM 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_UDK_2017_BINDING is not set -CONFIG_UDK_2013_VERSION=2013 -CONFIG_UDK_2015_VERSION=2015 -CONFIG_UDK_2017_VERSION=2017 -CONFIG_UDK_VERSION=2015 -# 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_ARCH_ARMV8_EXTENSION=0 -# CONFIG_ARM64_USE_ARCH_TIMER 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_RISCV_COMPRESSED 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_ID_SECTION_OFFSET=0x80 -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" -# CONFIG_COLLECT_TIMESTAMPS_NO_TSC is not set -CONFIG_COLLECT_TIMESTAMPS_TSC=y -# CONFIG_PAGING_IN_CACHE_AS_RAM is not set -# CONFIG_IDT_IN_EVERY_STAGE is not set - -# -# Devices -# -CONFIG_HAVE_FSP_GOP=y -# CONFIG_MAINBOARD_HAS_NATIVE_VGA_INIT is not set -# CONFIG_MAINBOARD_HAS_LIBGFXINIT is not set -# CONFIG_VGA_ROM_RUN is not set -# CONFIG_RUN_FSP_GOP 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_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_MRC_WRITE_NV_LATE 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_MAX98373 is not set -# CONFIG_DRIVERS_I2C_MAX98927 is not set -# CONFIG_DRIVERS_I2C_PCA9538 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_DISPLAY_FSP_VERSION_INFO 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=y -# CONFIG_INTEL_GMA_SSC_ALTERNATE_REF is not set -# CONFIG_INTEL_GMA_SWSMISCI 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_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_TPM_RDRESP_NEED_DELAY 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) -# - -# -# Trusted Platform Module -# -CONFIG_TPM=y -# CONFIG_DEBUG_TPM is not set -# CONFIG_MAINBOARD_HAS_TPM_CR50 is not set -CONFIG_MAINBOARD_HAS_LPC_TPM=y -# CONFIG_MAINBOARD_HAS_TPM2 is not set -# 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 - -# -# 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 -CONFIG_COMPRESS_SECONDARY_PAYLOAD=y - -# -# 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_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 0bc29750a..cfccf5269 100644 --- a/config/coreboot-qemu.config +++ b/config/coreboot-qemu.config @@ -1,591 +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_USE_OPTION_TABLE is not set -CONFIG_COMPRESS_RAMSTAGE=y # CONFIG_INCLUDE_CONFIG_FILE is not set -CONFIG_COLLECT_TIMESTAMPS=y -# CONFIG_TIMESTAMPS_ON_CONSOLE 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 - -# -# Mainboard -# - -# -# Important: Run 'make distclean' before switching boards -# -# CONFIG_VENDOR_AAEON 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_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_COMPULAB is not set -# CONFIG_VENDOR_CUBIETECH is not set -# CONFIG_VENDOR_DIGITALLOGIC 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_IWILL is not set -# CONFIG_VENDOR_JETWAY is not set -# CONFIG_VENDOR_KONTRON 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_MSI is not set -# CONFIG_VENDOR_NVIDIA is not set -# CONFIG_VENDOR_OCP is not set -# CONFIG_VENDOR_PACKARDBELL is not set -# CONFIG_VENDOR_PCENGINES is not set -# CONFIG_VENDOR_PURISM is not set -# CONFIG_VENDOR_RODA is not set -# CONFIG_VENDOR_SAMSUNG is not set -# CONFIG_VENDOR_SAPPHIRE is not set -# CONFIG_VENDOR_SCALEWAY is not set -# CONFIG_VENDOR_SIEMENS is not set -# CONFIG_VENDOR_SIFIVE is not set -# CONFIG_VENDOR_SUNW is not set -# CONFIG_VENDOR_SUPERMICRO is not set -# CONFIG_VENDOR_TECHNEXION 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_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_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_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_MMCONF_BASE_ADDRESS=0xb0000000 # 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_SMBIOS_ENCLOSURE_TYPE=0x03 -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_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_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_QUALCOMM_SDM845 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_HPET_MIN_TICKS=0x80 -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_COMMON_SMM 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_UDK_2017_BINDING is not set -CONFIG_UDK_2013_VERSION=2013 -CONFIG_UDK_2015_VERSION=2015 -CONFIG_UDK_2017_VERSION=2017 -CONFIG_UDK_VERSION=2013 -# 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_ARCH_ARMV8_EXTENSION=0 -# CONFIG_ARM64_USE_ARCH_TIMER 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_RISCV_COMPRESSED 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 is not set -CONFIG_IOAPIC_INTERRUPTS_ON_APIC_SERIAL_BUS=y -CONFIG_ID_SECTION_OFFSET=0x80 -# 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" -# CONFIG_COLLECT_TIMESTAMPS_NO_TSC is not set -CONFIG_COLLECT_TIMESTAMPS_TSC=y -# CONFIG_PAGING_IN_CACHE_AS_RAM is not set -# CONFIG_IDT_IN_EVERY_STAGE is not set - -# -# 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_MAX98373 is not set -# CONFIG_DRIVERS_I2C_MAX98927 is not set -# CONFIG_DRIVERS_I2C_PCA9538 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_PLATFORM_USES_FSP2_0 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_INTEL_GMA_SWSMISCI 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_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) -# - -# -# Trusted Platform Module -# -# CONFIG_TPM is not set -# CONFIG_MAINBOARD_HAS_TPM_CR50 is not set -# CONFIG_MAINBOARD_HAS_LPC_TPM is not set -# CONFIG_MAINBOARD_HAS_TPM2 is not set -# 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 - -# -# 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=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 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 -CONFIG_COMPRESS_SECONDARY_PAYLOAD=y - -# -# 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 5e8d7346c..a91aef7dc 100644 --- a/config/coreboot-x220.config +++ b/config/coreboot-x220.config @@ -1,705 +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_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_AAEON 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_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_COMPULAB is not set -# CONFIG_VENDOR_CUBIETECH is not set -# CONFIG_VENDOR_DIGITALLOGIC 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_IWILL is not set -# CONFIG_VENDOR_JETWAY is not set -# CONFIG_VENDOR_KONTRON 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_MSI is not set -# CONFIG_VENDOR_NVIDIA is not set -# CONFIG_VENDOR_OCP is not set -# CONFIG_VENDOR_PACKARDBELL is not set -# CONFIG_VENDOR_PCENGINES is not set -# CONFIG_VENDOR_PURISM is not set -# CONFIG_VENDOR_RODA is not set -# CONFIG_VENDOR_SAMSUNG is not set -# CONFIG_VENDOR_SAPPHIRE is not set -# CONFIG_VENDOR_SCALEWAY is not set -# CONFIG_VENDOR_SIEMENS is not set -# CONFIG_VENDOR_SIFIVE is not set -# CONFIG_VENDOR_SUNW is not set -# CONFIG_VENDOR_SUPERMICRO is not set -# CONFIG_VENDOR_TECHNEXION 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_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_DEVICETREE="devicetree.cb" -CONFIG_MAX_REBOOT_CNT=3 -CONFIG_USBDEBUG_HCD_INDEX=2 CONFIG_HAVE_GBE_BIN=y -CONFIG_MMCONF_BASE_ADDRESS=0xf0000000 -# 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_W520 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_BOARD_LENOVO_BASEBOARD_T520 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_SMBIOS_ENCLOSURE_TYPE=0x09 -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_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_SMM_RESERVED_SIZE=0x100000 -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_IED_REGION_SIZE=0x400000 -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_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_QUALCOMM_SDM845 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 is not set -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_HPET_MIN_TICKS=0x80 -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_SOUTHBRIDGE_INTEL_COMMON_SMM=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_UDK_2017_BINDING is not set -CONFIG_UDK_2013_VERSION=2013 -CONFIG_UDK_2015_VERSION=2015 -CONFIG_UDK_2017_VERSION=2017 -CONFIG_UDK_VERSION=2013 -# 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_ARCH_ARMV8_EXTENSION=0 -# CONFIG_ARM64_USE_ARCH_TIMER 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_RISCV_COMPRESSED 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_ID_SECTION_OFFSET=0x80 -# 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" -# CONFIG_PAGING_IN_CACHE_AS_RAM is not set -# CONFIG_IDT_IN_EVERY_STAGE is not set - -# -# 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_CACHE_MRC_SETTINGS=y -CONFIG_MRC_SETTINGS_CACHE_SIZE=0x10000 -# CONFIG_MRC_SETTINGS_PROTECT is not set -# 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_MRC_WRITE_NV_LATE 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_MAX98373 is not set -# CONFIG_DRIVERS_I2C_MAX98927 is not set -# CONFIG_DRIVERS_I2C_PCA9538 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_PLATFORM_USES_FSP2_0 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_INTEL_GMA_SWSMISCI 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_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_TPM_RDRESP_NEED_DELAY 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) -# - -# -# Trusted Platform Module -# -CONFIG_TPM=y -# CONFIG_DEBUG_TPM is not set -# CONFIG_MAINBOARD_HAS_TPM_CR50 is not set -CONFIG_MAINBOARD_HAS_LPC_TPM=y -# CONFIG_MAINBOARD_HAS_TPM2 is not set -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 - -# -# 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 -CONFIG_COMPRESS_SECONDARY_PAYLOAD=y - -# -# 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_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 d29629239..66f3a53cb 100644 --- a/config/coreboot-x230-flash.config +++ b/config/coreboot-x230-flash.config @@ -1,727 +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_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_AAEON 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_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_COMPULAB is not set -# CONFIG_VENDOR_CUBIETECH is not set -# CONFIG_VENDOR_DIGITALLOGIC 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_IWILL is not set -# CONFIG_VENDOR_JETWAY is not set -# CONFIG_VENDOR_KONTRON 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_MSI is not set -# CONFIG_VENDOR_NVIDIA is not set -# CONFIG_VENDOR_OCP is not set -# CONFIG_VENDOR_PACKARDBELL is not set -# CONFIG_VENDOR_PCENGINES is not set -# CONFIG_VENDOR_PURISM is not set -# CONFIG_VENDOR_RODA is not set -# CONFIG_VENDOR_SAMSUNG is not set -# CONFIG_VENDOR_SAPPHIRE is not set -# CONFIG_VENDOR_SCALEWAY is not set -# CONFIG_VENDOR_SIEMENS is not set -# CONFIG_VENDOR_SIFIVE is not set -# CONFIG_VENDOR_SUNW is not set -# CONFIG_VENDOR_SUPERMICRO is not set -# CONFIG_VENDOR_TECHNEXION 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_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_POST_IO=y -CONFIG_DEVICETREE="devicetree.cb" -CONFIG_MAX_REBOOT_CNT=3 -CONFIG_USBDEBUG_HCD_INDEX=2 -CONFIG_MMCONF_BASE_ADDRESS=0xf0000000 # 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_W520 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_BOARD_LENOVO_BASEBOARD_T520 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_SMBIOS_ENCLOSURE_TYPE=0x09 -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_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_SMM_RESERVED_SIZE=0x100000 -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_IED_REGION_SIZE=0x400000 -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_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_QUALCOMM_SDM845 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 is not set -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_HPET_MIN_TICKS=0x80 -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_SOUTHBRIDGE_INTEL_COMMON_SMM=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_UDK_2017_BINDING is not set -CONFIG_UDK_2013_VERSION=2013 -CONFIG_UDK_2015_VERSION=2015 -CONFIG_UDK_2017_VERSION=2017 -CONFIG_UDK_VERSION=2013 -# 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_ARCH_ARMV8_EXTENSION=0 -# CONFIG_ARM64_USE_ARCH_TIMER 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_RISCV_COMPRESSED 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_ID_SECTION_OFFSET=0x80 -# 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" -# CONFIG_PAGING_IN_CACHE_AS_RAM is not set -# CONFIG_IDT_IN_EVERY_STAGE is not set - -# -# 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_CACHE_MRC_SETTINGS=y -CONFIG_MRC_SETTINGS_CACHE_SIZE=0x10000 -# CONFIG_MRC_SETTINGS_PROTECT is not set -# 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_MRC_WRITE_NV_LATE 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_MAX98373 is not set -# CONFIG_DRIVERS_I2C_MAX98927 is not set -# CONFIG_DRIVERS_I2C_PCA9538 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_PLATFORM_USES_FSP2_0 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_INTEL_GMA_SWSMISCI 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_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_TPM_RDRESP_NEED_DELAY 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) -# - -# -# Trusted Platform Module -# -CONFIG_TPM=y -# CONFIG_DEBUG_TPM is not set -# CONFIG_MAINBOARD_HAS_TPM_CR50 is not set -CONFIG_MAINBOARD_HAS_LPC_TPM=y -# CONFIG_MAINBOARD_HAS_TPM2 is not set -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 - -# -# 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 -CONFIG_COMPRESS_SECONDARY_PAYLOAD=y - -# -# 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_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 8510b7ca4..61e9dd9db 100644 --- a/config/coreboot-x230.config +++ b/config/coreboot-x230.config @@ -1,707 +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_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_AAEON 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_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_COMPULAB is not set -# CONFIG_VENDOR_CUBIETECH is not set -# CONFIG_VENDOR_DIGITALLOGIC 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_IWILL is not set -# CONFIG_VENDOR_JETWAY is not set -# CONFIG_VENDOR_KONTRON 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_MSI is not set -# CONFIG_VENDOR_NVIDIA is not set -# CONFIG_VENDOR_OCP is not set -# CONFIG_VENDOR_PACKARDBELL is not set -# CONFIG_VENDOR_PCENGINES is not set -# CONFIG_VENDOR_PURISM is not set -# CONFIG_VENDOR_RODA is not set -# CONFIG_VENDOR_SAMSUNG is not set -# CONFIG_VENDOR_SAPPHIRE is not set -# CONFIG_VENDOR_SCALEWAY is not set -# CONFIG_VENDOR_SIEMENS is not set -# CONFIG_VENDOR_SIFIVE is not set -# CONFIG_VENDOR_SUNW is not set -# CONFIG_VENDOR_SUPERMICRO is not set -# CONFIG_VENDOR_TECHNEXION 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_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_POST_IO is not set -CONFIG_DEVICETREE="devicetree.cb" -CONFIG_MAX_REBOOT_CNT=3 -CONFIG_USBDEBUG_HCD_INDEX=2 -CONFIG_MMCONF_BASE_ADDRESS=0xf0000000 # 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_W520 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_BOARD_LENOVO_BASEBOARD_T520 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_SMBIOS_ENCLOSURE_TYPE=0x09 -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_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_SMM_RESERVED_SIZE=0x100000 -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_IED_REGION_SIZE=0x400000 -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_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_QUALCOMM_SDM845 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 is not set -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_HPET_MIN_TICKS=0x80 -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_SOUTHBRIDGE_INTEL_COMMON_SMM=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_UDK_2017_BINDING is not set -CONFIG_UDK_2013_VERSION=2013 -CONFIG_UDK_2015_VERSION=2015 -CONFIG_UDK_2017_VERSION=2017 -CONFIG_UDK_VERSION=2013 -# 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_ARCH_ARMV8_EXTENSION=0 -# CONFIG_ARM64_USE_ARCH_TIMER 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_RISCV_COMPRESSED 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_ID_SECTION_OFFSET=0x80 -# 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" -# CONFIG_PAGING_IN_CACHE_AS_RAM is not set -# CONFIG_IDT_IN_EVERY_STAGE is not set - -# -# 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_CACHE_MRC_SETTINGS=y -CONFIG_MRC_SETTINGS_CACHE_SIZE=0x10000 -# CONFIG_MRC_SETTINGS_PROTECT is not set -# 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_MRC_WRITE_NV_LATE 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_MAX98373 is not set -# CONFIG_DRIVERS_I2C_MAX98927 is not set -# CONFIG_DRIVERS_I2C_PCA9538 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_PLATFORM_USES_FSP2_0 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_INTEL_GMA_SWSMISCI 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_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_TPM_RDRESP_NEED_DELAY 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) -# - -# -# Trusted Platform Module -# -CONFIG_TPM=y -# CONFIG_DEBUG_TPM is not set -# CONFIG_MAINBOARD_HAS_TPM_CR50 is not set -CONFIG_MAINBOARD_HAS_LPC_TPM=y -# CONFIG_MAINBOARD_HAS_TPM2 is not set -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 - -# -# 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 -CONFIG_COMPRESS_SECONDARY_PAYLOAD=y - -# -# 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_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 137697e01..7081fe086 100644 --- a/modules/coreboot +++ b/modules/coreboot @@ -24,6 +24,7 @@ coreboot_configure := \ && $(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)" \ @@ -31,6 +32,7 @@ coreboot_configure := \ coreboot_target := \ -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)" \ From 03a09a1e1a7dcf633ddb2736ff66e8129f1bef2f Mon Sep 17 00:00:00 2001 From: Youness Alaoui Date: Fri, 27 Jul 2018 20:34:56 -0400 Subject: [PATCH 023/102] Add patches to update coreboot crossgcc to v1.52 crossgcc is now using gcc 8.1.0 which will compile without issues if your host system has gcc 8.x This is required if we are to build on a new system (such as latest Fedora) --- ...t-try-to-install-GCC-if-build-failed.patch | 44 + ...051-buildgcc-Update-IASL-to-20180531.patch | 130 + ...gcc-Update-to-clang-6.0-cmake-3.11.3.patch | 132 + ...3-src-Get-rid-of-unneeded-whitespace.patch | 55 + ...low-building-a-new-gcc-against-new-b.patch | 54 + ...Add-make-patch-for-GLIBC-glob-interf.patch | 46 + ...pdate-to-gcc-8.1.0-and-binutils-2.30.patch | 131728 +++++++++++++++ ...cc-patches-update-make-4.2.1-patches.patch | 156 + ...x-most-shellcheck-errors-in-buildgcc.patch | 826 + ...util-Add-description.md-to-each-util.patch | 29 + 10 files changed, 133200 insertions(+) create mode 100644 patches/coreboot-4.8.1/0050-buildgcc-Do-not-try-to-install-GCC-if-build-failed.patch create mode 100644 patches/coreboot-4.8.1/0051-buildgcc-Update-IASL-to-20180531.patch create mode 100644 patches/coreboot-4.8.1/0052-crossgcc-Update-to-clang-6.0-cmake-3.11.3.patch create mode 100644 patches/coreboot-4.8.1/0053-src-Get-rid-of-unneeded-whitespace.patch create mode 100644 patches/coreboot-4.8.1/0054-util-crossgcc-Allow-building-a-new-gcc-against-new-b.patch create mode 100644 patches/coreboot-4.8.1/0055-crosgcc-patches-Add-make-patch-for-GLIBC-glob-interf.patch create mode 100644 patches/coreboot-4.8.1/0056-util-crossgcc-update-to-gcc-8.1.0-and-binutils-2.30.patch create mode 100644 patches/coreboot-4.8.1/0057-util-crosgcc-patches-update-make-4.2.1-patches.patch create mode 100644 patches/coreboot-4.8.1/0058-util-crosgcc-Fix-most-shellcheck-errors-in-buildgcc.patch create mode 100644 patches/coreboot-4.8.1/0059-util-Add-description.md-to-each-util.patch 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 000000000..52ee66c6a --- /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 000000000..729e35490 --- /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 000000000..1b2296222 --- /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 000000000..97ee389bf --- /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 000000000..8d46818c1 --- /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 000000000..8a0635f92 --- /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 000000000..81ab35f47 --- /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 000000000..eeaac14ec --- /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 000000000..82c653b6e --- /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 000000000..608b6b68a --- /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 + From fe0f957bfc3db1f6113d908c608404ef5751bd3a Mon Sep 17 00:00:00 2001 From: Francis Lam Date: Sun, 28 Oct 2018 10:59:33 -0700 Subject: [PATCH 024/102] Make lvm and slang build reproducibly again --- modules/lvm2 | 2 ++ modules/slang | 2 ++ 2 files changed, 4 insertions(+) diff --git a/modules/lvm2 b/modules/lvm2 index ed7a0866e..91f0f53f0 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 69226390e..a4ac84bca 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 \ From 79a09e7424c67fc3168fef95a0352292a9bcf8eb Mon Sep 17 00:00:00 2001 From: Kyle Rankin Date: Wed, 7 Nov 2018 13:27:52 -0800 Subject: [PATCH 025/102] Ignore PCR5 when sealing key when Librem Key is enabled When the Librem Key is enabled, the kernel loads USB modules at boot, this causes PCR5 to change and breaks unsealing the LUKS key (if set). This change retains the protection of the PCR5 check unless Librem Key is enabled. --- initrd/bin/kexec-seal-key | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/initrd/bin/kexec-seal-key b/initrd/bin/kexec-seal-key index 5f6ab6b39..da5a187e2 100755 --- a/initrd/bin/kexec-seal-key +++ b/initrd/bin/kexec-seal-key @@ -84,6 +84,14 @@ cat "$KEY_DEVICES" | cut -d\ -f1 | xargs /bin/qubes-measure-luks \ || die "Unable to measure the LUKS headers" luks_pcr=`tpm calcfuturepcr -ix 16 -if /tmp/luksDump.txt` +# Librem Key loads USB modules which changes PCR5. +# In the event Librem Key is enabled, skip verification of PCR5 +if [ -x /bin/libremkey_hotp_verification ]; then + pcr_5="X" +else + pcr_5="0000000000000000000000000000000000000000" +fi + # Note that PCR 4 needs to be set with the "normal-boot" # path value, which we do not have right now since we are # in a recovery shell. @@ -104,7 +112,7 @@ tpm sealfile2 \ -ix 2 X \ -ix 3 X \ -ix 4 0000000000000000000000000000000000000000 \ - -ix 5 0000000000000000000000000000000000000000 \ + -ix 5 $pcr_5 \ -ix 6 $luks_pcr \ -ix 7 X \ || die "Unable to seal secret" From f20d45a42638b11d7ca046b0e379150e3e932cde Mon Sep 17 00:00:00 2001 From: Kyle Rankin Date: Thu, 8 Nov 2018 09:18:26 -0800 Subject: [PATCH 026/102] Update Librem get_blobs.sh script to point to proper upstream URLs --- blobs/librem_skl/get_blobs.sh | 29 ++++++++++++++++++++--------- blobs/librem_skl/readme.md | 2 ++ 2 files changed, 22 insertions(+), 9 deletions(-) mode change 100755 => 100644 blobs/librem_skl/get_blobs.sh diff --git a/blobs/librem_skl/get_blobs.sh b/blobs/librem_skl/get_blobs.sh old mode 100755 new mode 100644 index b36abe698..fd44002c3 --- a/blobs/librem_skl/get_blobs.sh +++ b/blobs/librem_skl/get_blobs.sh @@ -1,5 +1,5 @@ #!/bin/bash -e -# depends on : wget sha256sum python2.7 bspatch +# depends on : wget sha256sum python2.7 bspatch pv # Librem 13 v2 and Librem 15 v3 binary blob hashes SKL_UCODE_SHA="9c84936df700d74612a99e6ab581640ecf423d25a0b74a1ea23a6d9872349213" @@ -20,16 +20,20 @@ SKL_FSP_SPLIT_SHA="f654f6363de68ad78b1baf8b8e573b53715c3bc76f7f3c23562641e49a703 ME_CLEANER_URL="https://github.com/corna/me_cleaner/raw/9e1611fdf21426d66a29a5ea62b7e30d512859e6/me_cleaner.py" ME_CLEANER_SHA="412e95538c46d6d4d456987a8897b3d0ad1df118c51378a350540eef51c242d4" -SKL_DESCRIPTOR_URL="https://code.puri.sm/kakaroto/coreboot-files/raw/master/descriptor-skl.bin" -SKL_ME_PATCH_URL="https://code.puri.sm/kakaroto/coreboot-files/raw/master/me11.0.18_config.bspatch" +SKL_DESCRIPTOR_URL="https://source.puri.sm/coreboot/coreboot-files/raw/master/descriptor-skl.bin" +SKL_ME_PATCH_URL="https://source.puri.sm/coreboot/coreboot-files/raw/master/me11.0.18_config.bspatch" SKL_ME_PATCH_SHA="49019f89206d6371b1377cf738426c3b0ac60c4b1bb89d5d5de00481e7e4fece" # Link found on : http://www.win-raid.com/t832f39-Intel-Engine-Firmware-Repositories.html # Update link if it changes and becomes invalid. -SKL_ME_RAR_URL="http://www.mediafire.com/file/1angqt361xdf8k0/" +SKL_ME_RAR_URL="https://mega.nz/#!DNdDVQ7I!hronBMVN8m82JciiT6UQwtwh-LVlHXIo-NzTB0324rk" SKL_ME_FILENAME="11.0.18.1002_CON_LP_C0_NPDM_PRD_RGN.bin" -SKL_ME_FULL_FILENAME="Intel CSME 11.0 Firmware Repository Pack r50/$SKL_ME_FILENAME" -SKL_ME_RAR_SHA="11a9c199065c513a93c19269ffbb4bb094f8642a97686082e8cd2974673c599d" +SKL_ME_FULL_FILENAME="Intel CSME 11.0 Firmware Repository Pack r52/$SKL_ME_FILENAME" +SKL_ME_RAR_SHA="28b7c31ae6888623d2271f0c74cb7bbca55a56af73b26f9796742467a841441a" + +# Needed to download SKL_ME_RAR_URL +MEGADOWN_URL="https://github.com/tonikelope/megadown.git" +MEGADOWN_GOOD_COMMIT="83c53ddad1c32bf6d35c61fcd12a2fa94271ff77" # Might be required to compile unrar in case unrar-nonfree is not installed RAR_NONFREE_SOURCE_URL="https://www.rarlab.com/rar/unrarsrc-5.5.8.tar.gz" @@ -157,8 +161,16 @@ get_and_patch_me_11 () { unrar="`pwd`/unrar/unrar" fi if [ "$sha" != "$SKL_ME_RAR_SHA" ]; then - DIRECT_LINK=$(wget -O - "$SKL_ME_RAR_URL" 2>/dev/null | grep -o -e 'http://download.*.rar' | head -n 1) - wget -O "$rar_filename" "$DIRECT_LINK" + if [ ! -d megadown ]; then + git clone $MEGADOWN_URL + fi + ( + cd megadown + git checkout $MEGADOWN_GOOD_COMMIT + echo -e "\n\nDownloading ME 11 Repository from $SKL_ME_RAR_URL" + echo "Please be patient while the download finishes..." + ./megadown "$SKL_ME_RAR_URL" -o ../$rar_filename 2>/dev/null + ) sha=$(sha256sum "$rar_filename" | awk '{print $1}') if [ "$sha" != "$SKL_ME_RAR_SHA" ]; then # We'll assume the rar file was updated again @@ -215,4 +227,3 @@ check_binary fspm.bin $SKL_FSPM_SHA check_binary fsps.bin $SKL_FSPS_SHA check_and_get_url vbt.bin $SKL_VBT_URL $SKL_VBT_SHA "Video BIOS Table" check_and_get_url cpu_microcode_blob.bin $SKL_UCODE_URL $SKL_UCODE_SHA "Intel Microcode Update" - diff --git a/blobs/librem_skl/readme.md b/blobs/librem_skl/readme.md index 4862f130e..3c210f624 100644 --- a/blobs/librem_skl/readme.md +++ b/blobs/librem_skl/readme.md @@ -9,6 +9,8 @@ we need to have the following files in this folder: To get the binaries, run the get_blobs.sh script which will download and verify all of the files' hashes, then run me_cleaner on the descriptor.bin and me.bin. +The script depends on: wget sha256sum python2.7 bspatch pv + You can now compile the image with: ``` From e3343b5aff8f44fa3407529a8f662ccaa203a4c2 Mon Sep 17 00:00:00 2001 From: Kyle Rankin Date: Thu, 8 Nov 2018 09:22:24 -0800 Subject: [PATCH 027/102] Fix permissions on get_blobs.sh --- blobs/librem_skl/get_blobs.sh | 0 1 file changed, 0 insertions(+), 0 deletions(-) mode change 100644 => 100755 blobs/librem_skl/get_blobs.sh diff --git a/blobs/librem_skl/get_blobs.sh b/blobs/librem_skl/get_blobs.sh old mode 100644 new mode 100755 From fd3d69cdac8b32bb6252bc670f9e20c08e5bb5ad Mon Sep 17 00:00:00 2001 From: Francis Lam Date: Sun, 18 Nov 2018 10:49:37 -0800 Subject: [PATCH 028/102] update tails distro signing key --- initrd/etc/distro/keys/tails.key | 213 ++++++++++++++++++------------- 1 file changed, 124 insertions(+), 89 deletions(-) diff --git a/initrd/etc/distro/keys/tails.key b/initrd/etc/distro/keys/tails.key index cbc13a558..b43b9a543 100644 --- a/initrd/etc/distro/keys/tails.key +++ b/initrd/etc/distro/keys/tails.key @@ -14,32 +14,32 @@ NMWZ5vBShQ+bpBXh55fu3F7axequpWzocRfH+mfvBh5yvZnjDRGC3UZ06CFWN6JP 8wDFR+o8ZHSsq0Gx/2mIXVsJT6h0mF92Q1iqH2SQhFeRL3M+RcED6Bx33QARAQAB tEJUYWlscyBkZXZlbG9wZXJzIChvZmZsaW5lIGxvbmctdGVybSBpZGVudGl0eSBr ZXkpIDx0YWlsc0Bib3VtLm9yZz6JAlQEEwEKAD4CGwEFCwkIBwMFFQoJCAsFFgID -AQACHgECF4AWIQSkkND00xGkFT4rt8rbuAKyWKzYTwUCWb/Z7gUJB3zpXwAKCRDb -uAKyWKzYT9ldD/0QUUWDkAvnGf7FwdrXzyW9r7/mk9Hsy+5RcpJmk3W4l9c3Zsy1 -BJxsE/j+ZpIzhYOLf9mQdH71KOBot+yqtBTM9HimQEVaLKI8isCwgW9jqgehJJYq -HqTpooWjArbTuj2O/EMSJZclmeezzfbiEjWPggurKk+AYJQCGx/AC8/9cz1DEyNL -7oCkyh0wZoeukuniFszP0v5eRN2Tk1L6FMwNOxnCUxkc107ybk8bfAKB1EjPBGw6 -6PZDrvgTeE7iHjAs5OQoWI4E5zrTzcgwJeAzBmexEREb1Z9ektDMwZou0Ifok+P/ -zwi50PfVXIvxIYyaNzsRjsQg1FdQinGCWL1j8ipEp18mVH84Hs2j7EPEKmxtyQrQ -rWCfNP/NkanxsmHrXd617PjLo7DEWH9Bv8rBg02lHSLW+r0nbHU9/V1pVx9YisKE -dfN4pqymxdzCeTFZR6lJW9mVvt4oz8eaRettWCSlfq6qEJ1GHT4NGk2qzJotjzH5 -VN7h33gStRZbGdCQq+IA4ojSYMXg6+xMOTguGE4JZ1mWcJ7I6UYRxTWLb83K8lLk -QN2h9y54H33ZPPBzE43AF5/06m67XrDPeDkFiKFc3kJMHmcb7cQiq4YoEPxQhfsv -Kzy4c/YU71TCc2vd9eMmEeBQTMq0PucCtDD/D3IjVkXyMHpwT0HEH1vRerQhVGFp +AQACHgECF4AWIQSkkND00xGkFT4rt8rbuAKyWKzYTwUCW4f3egUJCV4TZAAKCRDb +uAKyWKzYTy6iEACJ2vlgJLNN/IYTH1b3rBwRJDreicvOnOYjo8E1fWhsMv+ATs3G +0KgxOz6FzwERqmdbYAf+J39k+uQ8s+bBSgZ2J8YTQnF0unlrVQwCCxWOB2jpBUj+ +yhmFrtP3pcDYf42OFO3TjidIGzOwweYsavRFi66otgCtdCCp6NczLUNasBFlWGeT +QET9RSzhYlJypPTh2WJqTohn1eXqKesWao9B25JlTKosSWgc9v25fBslMZvWpb+V +cm/ePHcDz/8iiUBxZYCTYzmxHfS+j2gSZaphEEC2i5ftJzaRAOQ5JaRYHbpuoOhL +L4lEzGD5vEYg8mSUCUEJlx+fAUviJJ8fQR74mosdU1/7z2CeMzBbccQfhmq4wD0R +89YKmQUrLy+BTB8IqWCBco6Ht8AahIFMUK/ZjquOaPEPQU3iVPhuHv/hOE4mFWNC +/+GKzRnVv3mmZ49BG5tjjPlukJ6N9gV+3xTnjTseZAWGhySuk8+F66+OYHGnFUv+ +/fA9AqQOnNGVVhUpmIpC+V9xw5h6hr72V8zQ9gBdmFHGJjx2ua3AFItQgrJK05JV +64yApq9BjmqMlFfDmcbjNyq4/HY/ibLhzlswofJAwOy5Up3Y3EGxe2fmDO9ktlEY +extaMjQNcgik+e+FbqPDEbxJQ3Z/F4gf4YziHlxN31CE46g53UO2CdRv9rQhVGFp bHMgZGV2ZWxvcGVycyA8dGFpbHNAYm91bS5vcmc+iQJUBBMBCgA+AhsBBQsJCAcD -BRUKCQgLBRYCAwEAAh4BAheAFiEEpJDQ9NMRpBU+K7fK27gCslis2E8FAlm/2fIF -CQd86V8ACgkQ27gCslis2E/v0w//czYYflmKrgZ8nFNtO+KndhNGWREh8QTRl3Po -UN0zSHUOGJahPWKHqi//n1g+rr2wN/G9FsRxuA/5Gjmr/V4lnAMAWNJa6qe8BU5d -QY3/14dhzzM9xDXylxW/9TW0bL1+QRZQLrXgBDcUdu8LEw19l09CPTnfeogyTgyc -MdQHEmr3sk5eSEA2hH9U/+WUvXd8pcPCOgzxr8t+OjKYVC/RN6DfQisUeWQ9/eCt -Qmpea1Z0IIU18ZLFBolpD6q9Wp+Qdfq8syNvgWAfJnBYqVY88aZklDBHOiPFA649 -1uwDonJ0fm2EJqnqy9K8YWCs26haPN+NQbCLgGpcV11GAUXUBwbxRCRFGzvCvTTG -TI7YDChxpIXC4uH7/My8F40XyCijs6o8L4K6Eh3YQYNpldnqlJoTaf4UqpIKKmGj -v8cU6pNwGrl/WKQ55G22fQI8A2KycbQEESIyRiiBqHdNHkG241HfsXtJcgm0YrRE -kkkCG1ZDil0/LjwhE8azDOoMcTASw88iXw9/mzqhIUn1NbbWBOaNzVKZ73LCXH5q -1Ne8VTOJ4F/ogqekKGV+M095k8QB4vldBFnKW9XfL/aankYem5PcAdauRRkaNnzo -omrO68AU4awRqATqRXOJTpElDWWHUABjWaPm/9HVK+Ug4qSzlSdFtahZ6c6LWGIw -7zgbIhm5Ag0EVLvR7AEQAN/E325mECH9+a8jCu0yHu5s5GOT9MOjyChyAFuont9Y +BRUKCQgLBRYCAwEAAh4BAheAFiEEpJDQ9NMRpBU+K7fK27gCslis2E8FAluH93MF +CQleE2QACgkQ27gCslis2E+R2Q/+JE4gEhi+e/EMnDRflMYjiCdwssr8ZovyoxWQ +6Cz1AsWuLmRzTIWlMjkfQxs+fAXK/+yys85jiXzzDJkiw13BXTESdWpe7WAZImNy +GLe7lA0A+UMfD52FIjjkcuestH/J1CadykACyARZCL7l2eqY2UZL+oLRH4uNAqK4 +YRs9dey2bEQsZk4fvbEGf5RxY3799AHtcucIkJIzZjiUWZcKtYAW8FrspBj0cX5T +Lyd298or61lQf1IixnHyD2dxy1yTx3SwWyxAF5YFFvwkvTrPiyQSQEhQyUcLzOs5 +v69zd09MOfR+atyxpeG/p6HnOtsAuCc/hvghvsYalGK8eq/Ods6h97xPb01UOCgZ +bcXcy798KZzu9MM1ZZIqz+M+SvCCpch/dKH8yyZUipR+dR8ABYA7noZFdyAwlTzk +PaHwBzJ7g3CuABH8KA2KpP8POIAgyVosxm7q/73NdoH0ngRlx5oTBwblNRNxjd4Z ++FhZsrqN+NVlOOOFQRMeI9SAsXFHEsvZnRUbEwoeroFUUymJfQm5okXz99EZY6pM +Wd79Tr3fLNuBM+sUc8yx/wX31NwQRCrW+RwZj5TfKHTt99M9EIiLlSqUz6Gj5GYC +nf97bq4PqqF7/kGkkaNV+k/T4+mkvHW4IVyvuqhqna0E2WeoSRsSDq/pR0MGDyFZ +pP7t0hy5Ag0EVLvR7AEQAN/E325mECH9+a8jCu0yHu5s5GOT9MOjyChyAFuont9Y KiUj+1f3Eu65rHmuGDAjAz6NZS9ONENzIcDvrKvTcQbtfggtQJ5ExUPt6n2X7xdN FW53KkonS+DjXwTQrr2vpnImb42XsNnZVBjaSzqpbxWF6rXWgTMeICWVuvkRfRab 8qNLh4ugPuC+dqVermt98uTf6eKa2sssBw4m36/sPXqoJ/TWahoCglob/uKbh3mr @@ -198,30 +198,30 @@ Z+0fex3DsVwXMdyMS78zfnm21bMpsgfJx7YZI1gFQXAKtVlEWPHajyjd2tCysYHy 1AnbehkHRIsYVqXV1AwF2bSN2rKf+nCTjvNgt5VNAiJGy4N+QuXFy5X4NdgMdYq7 vYT66IeZwlT9HV0wEB1jsX1y+50faxfn2YOPFpKXzNd7VOQDDx19J1IsNw2Q7gnr 4woqqJw+bLG7ClRuNfN861Dlxc52sH6rjdceiFsLKBj7T1mQFAUZB7TCMIvK2rry -lc5iXQARAQABiQRyBBgBCgAmFiEEpJDQ9NMRpBU+K7fK27gCslis2E8FAlmkPJYC -GwIFCQKUf4ACQAkQ27gCslis2E/BdCAEGQEKAB0WIQQFRp+4Xq1libQ9QdPSHa04 -rygcCwUCWaQ8lgAKCRDSHa04rygcC8+PD/44DOURFzZIeKFthhwtmXzzIrqRddc0 -wSlriK7Iy81ITiKjMqWygwQEH6lfk0mpekU772R0MWFMWpODiv07Ywy+O18xxkJs -2WxZ3R+Nl1TrmpA+XU9kr/uaFjUmQ8/mJP9bYOGkQg9TKgEzw+zdjvGO/jRVNnbU -C1djD2v+9CvxZi4l5kIBn4SsbqlgRXacdsTZaSKQjxJ5DYMX8VA1uBmq939XhwDr -greR7bbq2ohyA5p7is+vHqV9j1awPM7YzeeuL5XW6De33+RdKVG0vyY+HHKMzhnR -IN4LdeS2Nng+Hw9aF9R0sH6hbweeIEpQkmF+J5H15I4nddwowGAH2iG4QmeHLp4r -zA/aIObCtGRk1NHxj+k003mXYHu8I83WSY/RKAYHJXOR+zHCJLhmE2k6qMHutd+L -OltmwyeALBpI0YIUbr+l7II1M9d+4DZE9j/jzTgVdfbE1d4Ws+IuoAa9fNMb77Tg -K8D9b08ZwGvj5rPWybelutDzupI1pg15z8pMKu36ZiO6oCdrL5akXCzdxkS1923N -IwqbKVBFgIqtiUD93o09kJjRfBhQiE0EgeuFW/mjgRN2onwY7fNpPikr8vz/IJDw -nN37MXWEoJ3rK5OhJ4AO7zjP8fbp5t8jzHLaU9pCmr/8YdCGEHbMhekF/0nCpd5L -7kbdy05Me53fy1SHEACFn6UdCUVP2X7ra69vkFUPvFgFkUIywMT2PjzsNG9Ovt2v -xawmetKAVL3nuFcsW0ZYQl/8HDliip1/hoePY7hSMYJTu6mH/GQiEmPRicLk45Tl -N49sLofEtFPrQSXMHi/YwLBV99gV4AYsSvNxOtvDMSeXFiycoQavSQgAGoPri+K+ -8l5/ht937E9gHPbNNuEWdCbFUE7ju5wjH0C13/QgmV1o7rC1xGXF4aZsYzXmqeYv -vAxIKP8r4z+Z3Xa5iRsTxGDs77uhiTOQLJtjESftXlJIDp2hg7za+ZWs9UuG8eYm -zwxQD7zN9aj13KFm0dsjft7guwVgfjSbiCQg0tQjAcogY/7gBFwdV/hOWrHR7msu -OaGkYGhX2GXsTAKbWi1enHw18/7EpAE+SJU3WwiquKNpupzM+VBdf8TgL5xw32+K -QdztvrL7lWGk+/1gZ5oFvWEe/o12pkQIChFRvZzszuQ1r9XALqYCuMUtFxBt1B6h -ERRFGvztzPqiaOUxi/K68j7i0h23q3BA4IP9baPCVzBuUNGMVxj3DBdllvB2agxR -rnxsp4+d2KKwPjAbu8VCG+NsyKoRNNr5KzoTgSSWEu+uHASDCjKmE/6xh/8IPC51 -L2IiBztPi2GKXM0xFrQSYOBc56q69BOo4XiAW1qhcUuPXFl/qbQZ5lim2GSgQLkC +lc5iXQARAQABiQRyBBgBCgAmAhsCFiEEpJDQ9NMRpBU+K7fK27gCslis2E8FAluH ++M8FCQR1mLkCQMF0IAQZAQoAHRYhBAVGn7herWWJtD1B09IdrTivKBwLBQJZpDyW +AAoJENIdrTivKBwLz48P/jgM5REXNkh4oW2GHC2ZfPMiupF11zTBKWuIrsjLzUhO +IqMypbKDBAQfqV+TSal6RTvvZHQxYUxak4OK/TtjDL47XzHGQmzZbFndH42XVOua +kD5dT2Sv+5oWNSZDz+Yk/1tg4aRCD1MqATPD7N2O8Y7+NFU2dtQLV2MPa/70K/Fm +LiXmQgGfhKxuqWBFdpx2xNlpIpCPEnkNgxfxUDW4Gar3f1eHAOuCt5HtturaiHID +mnuKz68epX2PVrA8ztjN564vldboN7ff5F0pUbS/Jj4ccozOGdEg3gt15LY2eD4f +D1oX1HSwfqFvB54gSlCSYX4nkfXkjid13CjAYAfaIbhCZ4cunivMD9og5sK0ZGTU +0fGP6TTTeZdge7wjzdZJj9EoBgclc5H7McIkuGYTaTqowe6134s6W2bDJ4AsGkjR +ghRuv6XsgjUz137gNkT2P+PNOBV19sTV3haz4i6gBr180xvvtOArwP1vTxnAa+Pm +s9bJt6W60PO6kjWmDXnPykwq7fpmI7qgJ2svlqRcLN3GRLX3bc0jCpspUEWAiq2J +QP3ejT2QmNF8GFCITQSB64Vb+aOBE3aifBjt82k+KSvy/P8gkPCc3fsxdYSgnesr +k6EngA7vOM/x9unm3yPMctpT2kKav/xh0IYQdsyF6QX/ScKl3kvuRt3LTkx7nd/L +CRDbuAKyWKzYT7FlD/4m0ohmF5KffUQGW0L514b5uU1BkmhLv5kFEPPB3qxClfP/ +SzxdiiCyZHCSOqsGwepf3E+1X1KJEMt2Hv1XAAxLbfgyPv+uBrSjxqi1LWE8+2UB +W2zVAvGksKbzVn/GnGevKxknkvmxN9GEqiRTXdtMCNY/PtG1jISAYM9Li2TmL/IE +mmZlSHhxbaVfrIrsI5Sx20Xwp/WhQ5+ZDMLZEUQ9a1ptVsCHLgs/rJhyCfrZc8VT +KfTklb4dMWYg+8QdUO9YkzSdpwLulfVIYD3wIOZPKLzaxiXxP9lJWEiEuXvt+HAG +kWn1yeIBBqlBFRDF57EN58xPxNJ2Gq6RYW9vb3/h4GWpC6znoHeHYOwJAFPL7Jr3 +7G1YPlYEJWcprLoGsJpiHFixluopp+LVMmqoa6td2JRl4HIjsJy9Ocw/suVX+EXs +hgRfyKEkuODqayHeiP1Pof89/WvMqCC305LvBlT104CA3p4RqBho88tcJQDpVYib +FJOiuOTZn1NE8COo5Uu0j19R/amI4pLOrtfEDy63kaTVmfOrFkdGxDxikyt2DgXG +i41HNbWc0PiinSt5NGoR1oXyV4ouEYWuNEQe90hPtiuOXP5cHcekjUAgofhhtP06 +uUtwaDwLzno/gL/xChXWGboT58+c01lxBpis7grO3dW2siCtXC3HNat+WVn1gbkC DQRZpDyvARAAtfnSrtM7lNxN5FPfT0V8cUpXW5D3jhM6mC6NUSvKSDAeITNdQ5Rv o+k2GaN2dORrFSTRlBnGlF2DDpXY128zcvJakG3jadgGvAMflrpTDbFN52591u/+ JGbZ3rhTSKb0a+Vmo4MxDPKWF6ic69Ktk2NMze8pgJMpaqBSOqjWGnVpQw/eE/aO @@ -233,45 +233,80 @@ ef7D52q8Kt+DyfLSBjudGV0g7mRXEGDpJxBPhbkGJMwCoXTWlV5mPafpNIk1HR6i gC8ndBGxNk/yENfSGQpAHmVR9LzfXwFBdoDgUL1CzAu0iGfiRO62rGMlx0ZkUADL REpeLqZexYmQ3DJ1G/czh9f6aA1CDbD37kZ83St8GcDSFI+jvud5Dn7/zfOp+B61 Ykn3Zm5dHQ8BO07LbbqyAH+312aBlCWdsj8sIGF4KcxQSzuj1tuCLUUAEQEAAYkE -cgQYAQoAJhYhBKSQ0PTTEaQVPiu3ytu4ArJYrNhPBQJZpDyvAhsCBQkClH+AAkAJ -ENu4ArJYrNhPwXQgBBkBCgAdFiEEL6+boNZbs3HwvC1GMCCnqcK3JzMFAlmkPK8A -CgkQMCCnqcK3JzMVihAAo6ZOHpS9IbDsoMB2lopVMBiFpzP7PCfwjnmeGjyWC9Lg -UXeHbr3sBxH+3FrPTf+vR0WNZuaNcCP5QTigd9kFzGmi1Vw7jJLl62WjZE/Q+FnQ -ie9fYs4ZAUOOXTlib6KvGib/0NtWYkBeCqjKW4KCH/yzK/TU0euKXN49Fu0CpbYL -TMMyvpk/HTEvsaW7GrOE+0jJsz7kinBhxYGPcgpz1KeTgSl7HoD5oHK2y9jJEFk8 -s4lIs8vtzJ6+BKyr6hdhyj2c3qUoa0tnZ8qJEYRVC30u4FeaUZRzFH2q/kr1GR8U -hEnJmhPQDUw3xi74NO4PyQPafPupQZZjFJAu6eM4oXFCKDV3oXxbLpkXhXmuas0J -+1VjkBGEzcLb//65mIl7Ughhktybe2VO4L4jpJp5jn5KQt4WsSQGE0K08aCFaA6g -C1xFNj4NYzYlpRSle5EQRnLZx7jmII5oCsSMJlDurnwOYK6xNeqXmIZES3jePpvq -ThvbMFMLb1Xc0u82NEKtKj+c1q4fT9d85x2/M3sXfQ2n4CBmz+5Sajz9S4dvynOu -+v0qck/tgPLXoLBXZXO8lNHxwDnG4TqTHHF5GDRo6swFJ6mNytez4uCRxyjNMR2J -kZWWFidn2W+SDeeBDNLBj2bDnCGtaoO/as462PHqdFyTiytwzFyk45Vlvs8YWZQc -5A/+NPUAl2bJO03NvwaYONVOZbl70e+PRRYkOTjCksjfFyT/b2kXX2D4PSgjPLQP -gCdfm3sDO8ZSCYFqrEYoHS8PpeNju541briA/abpb42ECJjnVpL3y99kcPVKJUb+ -T2PQCRxONkfXtUNTZDvUrVXAaRkGwMT133SUw/SPnykllyrPHuCOdXKzQ1SYL1sa -GZFP14uokscYPiQw3oqZH8L8UxqR6wBBtYuheDWzmRb7ynDvXYLuaDL3V20w0/CT -s9liXw5yVB+XzNPfjyrMKoZemwCtna2iWM6+YULR1v+C6MAzRQik0wka/f0NT4rA -qKcFLDLZOS8RAz45B9h6lP4z6lnVXRerOXkGieuCf7GcAPp/nc+ctuE33PwlGRDo -Jq/WAqUSGyibj7Y0Bzz8AuqxbklVjbCak3Z9Z6aceRoDeZLRf/sFS2aoc9Z/MNTJ -UXNGwU5lkpRTatEFCfIDu3VHiMGoi4q8gGbMP6F/hiRXOvynbghB/71OstNPFoF9 -RSKQvKg56ETiHWmJVFP2ArjdlBnBWBoZV6/QVf2JiNtgGfWvW5FeuS+D59Ve4Y/3 -Aizx/gaWbYgwW9Gty8ZdjYN/nRS152abeQsPtxB+XK80uRMdUMORqDRfq2+MbIDn -Ol03XDaaumzJ3KEm0wQvv1QURGrz/uq2FW+NCNFEiifwrZ+4MwRZpCe2FgkrBgEE +cgQYAQoAJgIbAhYhBKSQ0PTTEaQVPiu3ytu4ArJYrNhPBQJbh/jPBQkEdZigAkDB +dCAEGQEKAB0WIQQvr5ug1luzcfC8LUYwIKepwrcnMwUCWaQ8rwAKCRAwIKepwrcn +MxWKEACjpk4elL0hsOygwHaWilUwGIWnM/s8J/COeZ4aPJYL0uBRd4duvewHEf7c +Ws9N/69HRY1m5o1wI/lBOKB32QXMaaLVXDuMkuXrZaNkT9D4WdCJ719izhkBQ45d +OWJvoq8aJv/Q21ZiQF4KqMpbgoIf/LMr9NTR64pc3j0W7QKltgtMwzK+mT8dMS+x +pbsas4T7SMmzPuSKcGHFgY9yCnPUp5OBKXsegPmgcrbL2MkQWTyziUizy+3Mnr4E +rKvqF2HKPZzepShrS2dnyokRhFULfS7gV5pRlHMUfar+SvUZHxSEScmaE9ANTDfG +Lvg07g/JA9p8+6lBlmMUkC7p4zihcUIoNXehfFsumReFea5qzQn7VWOQEYTNwtv/ +/rmYiXtSCGGS3Jt7ZU7gviOkmnmOfkpC3haxJAYTQrTxoIVoDqALXEU2Pg1jNiWl +FKV7kRBGctnHuOYgjmgKxIwmUO6ufA5grrE16peYhkRLeN4+m+pOG9swUwtvVdzS +7zY0Qq0qP5zWrh9P13znHb8zexd9DafgIGbP7lJqPP1Lh2/Kc676/SpyT+2A8teg +sFdlc7yU0fHAOcbhOpMccXkYNGjqzAUnqY3K17Pi4JHHKM0xHYmRlZYWJ2fZb5IN +54EM0sGPZsOcIa1qg79qzjrY8ep0XJOLK3DMXKTjlWW+zxhZlAkQ27gCslis2E8X +AA/8CqeuxtsKzSosGloWVUkK7YrhwgMAMVxjdqCSetsO5oTB3OWAHAPlYoTaPcJh +69/Aixib6Ijs0sAf5nUlFRXeMON+gWo+52YW4HYf4+B87KUPye8XL8S9fsibxJ6V +rR5kRAoqxSUfpUhxUoNvaJhGD11SSCnMELxvpm86z1uAEkJH4cZ4vZtrdmD5gQNB +d9Xi58xV8Skzpu2W9PypFupM8K/9z/JfzAnm6HFAOVItAkv8S9sT0F5LGdS/G6Qc +SfDZGZUUSmNwy1+igCQdzReWkSFzzB2UJxX2Ap/b8gy7v8BLeP/VTG7BTZfKLrPv +i1V7Z0+w7iGW+tksP9ElK4cHSLMglcWoebY3DC9r98vBYmPTKHzB99LLcFnJHDJp +wqAUJIvw1NggjkFjNKSMQhJhuo1I4Rg+x/i8zPxcpCMCRol1vWC9Kts1cHDMwlrT +9v3W69gcOkVcfpD0MAE3xLCApR7C0Aky2BgWvQt00O38SCnOzdK/Thja61lSbPij +xmUL52K5d5v3WKKCo9vBCr/hqXwJxDApgn3YMLbndw0skmZ1sWKEGLJisYfrZTCQ +QmgBdN/C7RGf67XaXHjj966XOleBYI9QjciavBl0eX+nIJV1oSa41+/zLXYD90f0 +OPd1CpCoFgq+quk8lv6xlr8jsCLKZp8RNx7tj8UGBV9Bn0W4MwRZpCe2FgkrBgEE AdpHDwEBB0DtqAgreIYCHrjvjYlBdMOugNUQhW+E0ko4ynwSUi10l4kCswQYAQoA -JhYhBKSQ0PTTEaQVPiu3ytu4ArJYrNhPBQJZpCe2AhsCBQkClH+AAIEJENu4ArJY -rNhPdiAEGRYKAB0WIQTNTUNRr6aTP1dKmvuQsrS9eu0jXwUCWaQntgAKCRCQsrS9 -eu0jXyzHAP4h8sfcFn4DgB5Ua3+5VqZOTheQRzUq06iWsvjogDiRtgD/TwPqDxpn -a91maX+jnFnP1L87u1cxGOFKK0T6bdLBCgYcSQ//fZ+SRYXE9oewmEkINdUW8k1N -dIkHiv1ILO3RaxFg8ZV9qDWZlo1+/oadlRg03bj75p38rSNYt/7ZqIV5UrTKu7VF -i2kH9CVtQGSfpI37TUCqIYafGUgUOD1TutlTxs2sXloAbveK3boAwkZHD8O1ADpt -cHRZHJ/qbxstlNrfJDx8kWTRExdCvWZNg0AxPg43X+XPLQjAn8bXT/WxhlBY6QKL -1OoUd/h7wAnqWY9QGANOvDRlXV0c5w2IY5+hTpHnbq7KzsCaGKqG3GKaFnPvqnmI -XAZTovFXXgDUjQJxge/FRJZB3oIuGCDcr5KTipcCe55D/3TW4U+QINmCav+XLdl/ -OUfi04ihcAfHOlOqa4RPXRChNLabV4DwJkr4JK4ez0v8JYgIzwO8VmAptcLkCKbR -zRRAUDxtvXJgWL/J0PEl6hQfNFc6HEpZnQo9LjmOq/0uo/V4K6jdK9revRNsOVaV -0USv9KR5xVomhZB4zpSa5PMsL/Iae6GihjCC8pNfcO+YQxE5UIxDDT9jztwLCTZP -j10VQNvkI/za/CSYsm70YNR9QAxKC1a4ngUFEJ0SvaocZWNnUJYj3yC+arlIWtlT -CHQGDGvFQ3z7vtHjl8lxxgCQrXxmdPgJjX6MybnQBYttLW0aOzQDtlHyaF1SYQZ2 -xu/XTq1+ri7qrkughyk= -=srmm +JgIbAhYhBKSQ0PTTEaQVPiu3ytu4ArJYrNhPBQJbh/jPBQkEda2ZAIF2IAQZFgoA +HRYhBM1NQ1GvppM/V0qa+5CytL167SNfBQJZpCe2AAoJEJCytL167SNfLMcA/iHy +x9wWfgOAHlRrf7lWpk5OF5BHNSrTqJay+OiAOJG2AP9PA+oPGmdr3WZpf6OcWc/U +vzu7VzEY4UorRPpt0sEKBgkQ27gCslis2E9pPxAAiCSmy+UOcnMzvtXQqczXPUys +OFmJBZI/AIxa67NtOWPHmbii2KA2YnoHxbXoUJVmq25EHjJQITjOhEM7GvDknkHq +Gq7+bcjvPTQURK/LL+5VEAfapUHHRrlEOJaUBhA5TXIHYMi6ND+IRG1o4e4ljLMp +oHyS4Nl8yqWmjr/mUWXUpw/D4K7+Xy9CCNA7PT7NLgtHp83sdLZ7DR1jUX1GTXNl +vEoILlFEtqSL/cp8nbIvnhPX6LmGoIq1Mh7UtdAp93b+JPDzobZBtRI73jPAxesm +b6Ipnju3jH6Pj6ig88OV9ah3eHmpplti0b/R41oq+JZONxs+e1Mp/T9/QGHH9L+n +j2uPdsFQ+x1FM2HeYjl68RLX1iP1TFUTlHBAIjKzVc1gFMO6mx2dsrhZR/4462/Z +lZg/EhtHK6lIIC0rsM2z5DY2jdvbKvNc24DVxFCtTy74/fuJWmClNVwLz/TstAUK +nVhTM33U/qUwelF63tPvYnna/Iq0NkAAB8UpcEuh0Vmzo/rSokeiuNStJp3eRVHN +PmIt58YVo+kTQSvNYAmXYEFjj4dmv1WaZbi4qdl8Eqq+Y9UXS5QO2GjDZs8+/NkA +fWIjjzHwa/blm0C03b5PkvzUv2qfkFHuYVYvlcEA7F0DyJcHcQlWthB6HEDTwx0L +8yYhRA/TeCS394jPwxe5Ag0EW4f3OwEQAL9qkAF7ImnL8bakmqQ640hqsh4SLjjF +E4XJb/VzXZmYJGbTDBDmNhQUpupyn2W6vJ7HRzW/cCOKZ4IpHxF3qoBYiLMQybjS +cSEZcbvxBdhgxxWcPZXsdCnmq70+a3mUa1qODYjR8iAhyibDXZodPkpVSOCa1WSt +opJ48EopahUBOkYwa3K/uM/SnCGvMV8iFbnVPfKA0VlJrbi/0jS2lbrOVSJTKxaI +DwWbflyPkbIS6Q5xgKDgpCVT/n/Gp2gD9N0Q49dvYjmT5aTTXfElz9mKYA2KmrPR +wWVoY0dq3HS0WH/BC4R9oT4euD/7177t8mLpCkFOiTPyn16cfgyubdRB6bXJMiNW +/7QKuYjJtoj8xZ8mTzGQEF6RFlmsdbCUcovMi/9BgExd8mBYYpqN1L46NiyHe1cP +7JPE5R7cw6OCxb6KjLq+vaQRFxgyFhZyb/qDewq0jSfG8AjErK7AVU9rJg9zTSLF +jq1vMUNfceZnfR1tLdUEdKbgveIsR4VdNvVqBhwpRvzETa7ansTh9ifdPXIV5Cy+ +Q5UJaguDGcHUGIE+QbGE52Wqu7s9MWiO904d4VUt6avJpF7g8Khvf+f6ccltIqS3 +zQE+E5f74WmWsjEjGlpSpPo9rptYIGtCV11qyUfrEb1oYGCwn1y8TjqCE6oCkEaM +9n7dCClfYEv/ABEBAAGJBHIEGAEKACYWIQSkkND00xGkFT4rt8rbuAKyWKzYTwUC +W4f3OwIbAgUJApHcgAJACRDbuAKyWKzYT8F0IAQZAQoAHRYhBP4CnLSq1HiOHXgo +6Kiw9ORbG1DiBQJbh/c7AAoJEKiw9ORbG1DiPlsP/3SW95eFOmne+DNYROtGzPba +n3NCY2IkYMaZZgb2PvtnhRFTekCai/W0iemueOupPbNVdapkHADU+kO2RmnJshw+ +agKV/qDsWxldIaaTIiRIKv5yCDV3vNMFaZ/JcxTA7aLU+mWYNmWL0diIWVFqS62/ +1NTmpu2A0mwBNnNVChOH+R8AAgOIc5bc1cVaX6GTInbJMcuBFR3upziO0o4qSEEy +M6nQVNzM8Ejbi0k1OVtToF83oJ8n7ScaVxp8JGeHYXxLBQ/tzhIaM8KiIQo3Au75 +hmVwKTt2oA1swyZ4uBvttmk8DzduyoaCwmWjC556cGAhurDrB2e5Rs4CrzNbqQBa +WMpI/+92679l/Zg5Iw1mOU6qbidciLi70ZkZzbYUV7RXZU6XUKDo54WoEOR3jmGp +m5QTY7XSY5ZFPnAXt8So+YL/MrRC3ncwlKR2LRLa32pytTx3a/Ama8HWaySdnR7d +VQYljMZuNniD1FRjBiJXu/dvRKMyJQv2mU15m+/wAiwuKG70Q4CzkxRZFv/Y184U +57GVx7yiR5m5Og/VWRid2uno1Q+8XrXkyf5yYSEXaA0BUlmltRqiuMl4nEayKj7k +vP9AUVUkv5NbiFOuF7VRMi2hafiUfIowM9fTyV+tCBxk+/nx4O9pM60TSxo8TRQY +pNJ3jTN3WblMfOJ8vK2yXwcP/3EuXy+Wnc0oQ3B3X+riPohxPep6OX6NC6s80Y1N +7nHPP9BUlSTgNGxR4VoHzrRxuAgQeEM0faw0OjmXmaI9KqeJFU4RyMuZaGyOVzxg +jCOeJfxogkVmPpS7IHMOSWkagPaRymBXBZgNMxnLxMew1EnfngvMCV5tJQ1Uv0pP +sBnmdf1+TQnhZyaHUA3VYyC8lA9ZuQhtXzjuCdA4F5w9kIx27CnSAtyqNobyHGke +aB62qPobjIU1Ek7BGrvUDFXPTwr8SM4wbnmwky7eQ9UL6t++/I5d4QMzVp8WRW71 +2KeAgTmO3VGhJ1F1hFz5f2ENOQ/5nt0fvNBsDrigc6XouZDCkYY877TRCBvKr7gN +X5xCpLMRJecyezctAZSegySOWqv/ODmZ7r8Nmf9PMuWeAbGJktUPCHkcKkTT7IoX +cTtxyP5SJ6Pj5BArkX/RGt3RX0JWclqckJ1Lr5U7xFft79nXAmvVHahXJwYNFefv +/sJIGTDaAavQdiujiuxWemtqli3jjII0rrxKEb+WlqhWq4gK6epjixuiKEfyUbEZ +cBEB3KAiwLudRfKp7+7c9j/+Q6/JXdIJ0oCnI/tMndqdBHlWJUHMJGyutg91MfHd +qdDoafsIclj3n7qzixWlJ1iqcfnCK17cOhHGrI5JLz10irjz6hMu4LOUNGWeDO2O +zerI +=B0uR -----END PGP PUBLIC KEY BLOCK----- From 371b65ff5827e1048511b91be1f9ce656040cb9d Mon Sep 17 00:00:00 2001 From: Martin Kepplinger Date: Wed, 21 Nov 2018 14:24:54 +0100 Subject: [PATCH 029/102] fix install directory handling for git and builds The install directly should basically behave like the "build" directory. Since it's tracked by git, containing a gitignore file, we shouldn't have it in the toplevel gitignore (just like the build directory). But then, the toplevel Makefile's real.clean target removes the install directory. This is changed so that only it's content is being removed. --- .gitignore | 1 - Makefile | 2 +- 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/.gitignore b/.gitignore index 0133b837b..951c0fc6c 100644 --- a/.gitignore +++ b/.gitignore @@ -15,7 +15,6 @@ config/*.old *.log *~ crossgcc -install clean *.map *.sec diff --git a/Makefile b/Makefile index d6b266b1d..cad491c3a 100644 --- a/Makefile +++ b/Makefile @@ -545,7 +545,7 @@ real.clean: rm -rf "build/$$dir"; \ fi; \ done - rm -rf ./install + cd install && rm -rf -- * else From c559d71725d530355da5c61ff8a9e3b8231ceb0b Mon Sep 17 00:00:00 2001 From: Francis Lam Date: Sat, 24 Nov 2018 09:12:41 -0800 Subject: [PATCH 030/102] cairo: restore reproducibility libtool needs to be patched to not write rpath to targets --- modules/cairo | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/modules/cairo b/modules/cairo index bab702210..647ed2ca7 100644 --- a/modules/cairo +++ b/modules/cairo @@ -15,7 +15,13 @@ cairo_configure := \ --disable-xlib --disable-xcb --disable-pdf \ --disable-ps --disable-svg --disable-script \ --disable-ft --disable-fc --disable-pthread \ - --disable-glib --disable-gobject + --disable-gobject \ + && sed \ + -e 's/^hardcode_libdir_flag_spec.*/hardcode_libdir_flag_spec=" -D__LIBTOOL_RPATH_DISABLE__ "/' \ + < libtool \ + > libtool-2 \ + && mv libtool-2 libtool \ + && chmod 755 libtool cairo_target := \ $(MAKE_JOBS) \ From 7f8738d6d82f1f500f5efc74b6d38a8eff1a5fff Mon Sep 17 00:00:00 2001 From: Kyle Rankin Date: Fri, 30 Nov 2018 15:32:29 -0800 Subject: [PATCH 031/102] Add empty keyring detection, clean up main menu To help with onboarding new users to Heads, this change will detect when Heads does not have any keys in its keyring and will guide the user through adding a key to the running BIOS. It's important that this happen *before* guiding them through setting up an initial TOTP/HOTP secret because adding a GPG key changes the BIOS, so the user would have to generate TOTP/HOTP secrets 2x unless we handle the keyring case first. In addition to this change I've simplified the main menu so that the majority of the options appear under an 'advanced' menu. --- initrd/bin/gui-init | 54 +++++++++++++++++++++++++++------------------ 1 file changed, 32 insertions(+), 22 deletions(-) diff --git a/initrd/bin/gui-init b/initrd/bin/gui-init index 957ebba41..d00a98de7 100755 --- a/initrd/bin/gui-init +++ b/initrd/bin/gui-init @@ -119,14 +119,24 @@ while true; do last_half=$half; TOTP=`unseal-totp` if [ $? -ne 0 ]; then - whiptail $CONFIG_ERROR_BG_COLOR --clear --title "ERROR: TOTP Generation Failed!" \ - --menu "ERROR: Heads couldn't generate the TOTP code.\n\nIf you just reflashed your BIOS, you'll need to generate a new TOTP secret.\n\nIf you have not just reflashed your BIOS, THIS COULD INDICATE TAMPERING!\n\nIf this is the first time the system has booted, you should reset the TPM\nand set your own password\n\nHow would you like to proceed?" 30 90 4 \ - 'g' ' Generate new TOTP/HOTP secret' \ - 'i' ' Ignore error and continue to default boot menu' \ - 'p' ' Reset the TPM' \ - 'x' ' Exit to recovery shell' \ - 2>/tmp/whiptail || recovery "GUI menu failed" - + # detect whether any GPG keys exist in the keyring, if not, initialize that first + GPG_KEY_COUNT=`gpg -k 2>/dev/null | wc -l` + if [ $GPG_KEY_COUNT -eq 0 ]; then + whiptail $CONFIG_ERROR_BG_COLOR --clear --title "ERROR: GPG keyring empty!" \ + --menu "ERROR: Heads couldn't find any GPG keys in your keyring.\n\nIf this is the first time the system has booted, you should add a public GPG key to the BIOS now.\n\nIf you just reflashed a new BIOS, you'll need to add at least one public key to the keyring.\n\nIf you have not just reflashed your BIOS, THIS COULD INDICATE TAMPERING!\n\nHow would you like to proceed?" 30 90 4 \ + 'f' ' Add a GPG key to the running BIOS' \ + 'i' ' Ignore error and continue to default boot menu' \ + 'x' ' Exit to recovery shell' \ + 2>/tmp/whiptail || recovery "GUI menu failed" + else + whiptail $CONFIG_ERROR_BG_COLOR --clear --title "ERROR: TOTP Generation Failed!" \ + --menu "ERROR: Heads couldn't generate the TOTP code.\n\nIf this is the first time the system has booted, you should reset the TPM\nand set your own password\n\nIf you just reflashed your BIOS, you'll need to generate a new TOTP secret.\n\nIf you have not just reflashed your BIOS, THIS COULD INDICATE TAMPERING!\n\nHow would you like to proceed?" 30 90 4 \ + 'g' ' Generate new TOTP/HOTP secret' \ + 'i' ' Ignore error and continue to default boot menu' \ + 'p' ' Reset the TPM' \ + 'x' ' Exit to recovery shell' \ + 2>/tmp/whiptail || recovery "GUI menu failed" + fi totp_confirm=$(cat /tmp/whiptail) fi fi @@ -157,8 +167,6 @@ while true; do whiptail $MAIN_MENU_BG_COLOR --clear --title "$CONFIG_BOOT_GUI_MENU_NAME" \ --menu "$date\nTOTP: $TOTP | HOTP: $HOTP" 20 90 10 \ 'y' ' Default boot' \ - 'r' ' TOTP/HOTP does not match, refresh code' \ - 'o' ' Other Boot Options -->' \ 'a' ' Advanced Settings -->' \ 'x' ' Exit to recovery shell' \ 2>/tmp/whiptail || recovery "GUI menu failed" @@ -166,21 +174,11 @@ while true; do totp_confirm=$(cat /tmp/whiptail) fi - if [ "$totp_confirm" = "o" ]; then - whiptail --clear --title "Other Boot Options" \ - --menu "Select A Boot Option" 20 90 10 \ - 'm' ' Show OS boot menu' \ - 'u' ' USB boot' \ - 'i' ' Ignore tampering and force a boot (Unsafe!)' \ - 'r' ' <-- Return to main menu' \ - 2>/tmp/whiptail || recovery "GUI menu failed" - - totp_confirm=$(cat /tmp/whiptail) - fi - if [ "$totp_confirm" = "a" ]; then whiptail --clear --title "Advanced Settings" \ --menu "Configure Advanced Settings" 20 90 10 \ + 'o' ' Other Boot Options -->' \ + 'r' ' TOTP/HOTP does not match, refresh code' \ 'g' ' Generate new TOTP/HOTP secret' \ 's' ' Update checksums and sign all files in /boot' \ 'f' ' Flash/Update the BIOS -->' \ @@ -192,6 +190,18 @@ while true; do totp_confirm=$(cat /tmp/whiptail) fi + if [ "$totp_confirm" = "o" ]; then + whiptail --clear --title "Other Boot Options" \ + --menu "Select A Boot Option" 20 90 10 \ + 'm' ' Show OS boot menu' \ + 'u' ' USB boot' \ + 'i' ' Ignore tampering and force a boot (Unsafe!)' \ + 'r' ' <-- Return to main menu' \ + 2>/tmp/whiptail || recovery "GUI menu failed" + + totp_confirm=$(cat /tmp/whiptail) + fi + if [ "$totp_confirm" = "x" ]; then recovery "User requested recovery shell" fi From a14a4fb4191cae7093be5337cd3165606125de3a Mon Sep 17 00:00:00 2001 From: Francis Lam Date: Sat, 1 Dec 2018 10:10:04 -0800 Subject: [PATCH 032/102] qemu-coreboot: change configs to enable gui-init testing --- boards/qemu-coreboot/qemu-coreboot.config | 6 +++--- config/linux-qemu.config | 5 +++-- 2 files changed, 6 insertions(+), 5 deletions(-) diff --git a/boards/qemu-coreboot/qemu-coreboot.config b/boards/qemu-coreboot/qemu-coreboot.config index 9427a2ac3..89bbb0492 100644 --- a/boards/qemu-coreboot/qemu-coreboot.config +++ b/boards/qemu-coreboot/qemu-coreboot.config @@ -21,8 +21,8 @@ CONFIG_GPG=y CONFIG_LVM2=y CONFIG_MBEDTLS=y CONFIG_DROPBEAR=y -CONFIG_NEWT=y -CONFIG_SLANG=y +CONFIG_CAIRO=y +CONFIG_FBWHIPTAIL=y endif CONFIG_LINUX_ATA=y @@ -30,7 +30,7 @@ CONFIG_LINUX_AHCI=y CONFIG_LINUX_USB=y CONFIG_LINUX_E1000=y -export CONFIG_BOOTSCRIPT=/bin/generic-init +export CONFIG_BOOTSCRIPT=/bin/gui-init export CONFIG_TPM=n export CONFIG_BOOT_DEV="/dev/sda1" diff --git a/config/linux-qemu.config b/config/linux-qemu.config index a76f37f3f..84d691107 100644 --- a/config/linux-qemu.config +++ b/config/linux-qemu.config @@ -211,14 +211,12 @@ CONFIG_TCG_ATMEL=y CONFIG_TCG_INFINEON=y CONFIG_TCG_CRB=y CONFIG_TCG_TIS_ST33ZP24_I2C=y -CONFIG_I2C=y # CONFIG_I2C_COMPAT is not set CONFIG_I2C_CHARDEV=y CONFIG_I2C_MUX=m CONFIG_I2C_MUX_PCA9541=m CONFIG_I2C_MUX_REG=m # CONFIG_I2C_HELPER_AUTO is not set -CONFIG_I2C_ALGOBIT=y CONFIG_I2C_I801=y CONFIG_I2C_SCMI=y CONFIG_I2C_SLAVE=y @@ -229,6 +227,9 @@ CONFIG_INT340X_THERMAL=y CONFIG_INTEL_PCH_THERMAL=y CONFIG_MFD_SYSCON=y # CONFIG_VGA_ARB is not set +CONFIG_DRM=y +CONFIG_DRM_BOCHS=y +CONFIG_FRAMEBUFFER_CONSOLE=y CONFIG_USB=y CONFIG_USB_XHCI_HCD=m CONFIG_USB_XHCI_PLATFORM=m From 2195977c23a72b0136724e423eec609fdf5e5732 Mon Sep 17 00:00:00 2001 From: Kyle Rankin Date: Mon, 3 Dec 2018 16:09:55 -0800 Subject: [PATCH 033/102] Move GPG check outside TPM failure We want to catch the missing GPG keyring error regardless of TPM failure or even in the case of a system without a TPM at all so we need to move that section up above the TPM check. --- initrd/bin/gui-init | 46 ++++++++++++++++++++++++--------------------- 1 file changed, 25 insertions(+), 21 deletions(-) diff --git a/initrd/bin/gui-init b/initrd/bin/gui-init index d00a98de7..35b32fad6 100755 --- a/initrd/bin/gui-init +++ b/initrd/bin/gui-init @@ -109,26 +109,29 @@ while true; do MAIN_MENU_OPTIONS="" MAIN_MENU_BG_COLOR="" unset totp_confirm - # update the TOTP code every thirty seconds - date=`date "+%Y-%m-%d %H:%M:%S"` - seconds=`date "+%s"` - half=`expr \( $seconds % 60 \) / 30` - if [ "$CONFIG_TPM" = n ]; then - TOTP="NO TPM" - elif [ "$half" != "$last_half" ]; then - last_half=$half; - TOTP=`unseal-totp` - if [ $? -ne 0 ]; then - # detect whether any GPG keys exist in the keyring, if not, initialize that first - GPG_KEY_COUNT=`gpg -k 2>/dev/null | wc -l` - if [ $GPG_KEY_COUNT -eq 0 ]; then - whiptail $CONFIG_ERROR_BG_COLOR --clear --title "ERROR: GPG keyring empty!" \ - --menu "ERROR: Heads couldn't find any GPG keys in your keyring.\n\nIf this is the first time the system has booted, you should add a public GPG key to the BIOS now.\n\nIf you just reflashed a new BIOS, you'll need to add at least one public key to the keyring.\n\nIf you have not just reflashed your BIOS, THIS COULD INDICATE TAMPERING!\n\nHow would you like to proceed?" 30 90 4 \ - 'f' ' Add a GPG key to the running BIOS' \ - 'i' ' Ignore error and continue to default boot menu' \ - 'x' ' Exit to recovery shell' \ - 2>/tmp/whiptail || recovery "GUI menu failed" - else + # detect whether any GPG keys exist in the keyring, if not, initialize that first + GPG_KEY_COUNT=`gpg -k 2>/dev/null | wc -l` + if [ $GPG_KEY_COUNT -eq 0 ]; then + whiptail $CONFIG_ERROR_BG_COLOR --clear --title "ERROR: GPG keyring empty!" \ + --menu "ERROR: Heads couldn't find any GPG keys in your keyring.\n\nIf this is the first time the system has booted, you should add a public GPG key to the BIOS now.\n\nIf you just reflashed a new BIOS, you'll need to add at least one public key to the keyring.\n\nIf you have not just reflashed your BIOS, THIS COULD INDICATE TAMPERING!\n\nHow would you like to proceed?" 30 90 4 \ + 'f' ' Add a GPG key to the running BIOS' \ + 'i' ' Ignore error and continue to default boot menu' \ + 'x' ' Exit to recovery shell' \ + 2>/tmp/whiptail || recovery "GUI menu failed" + + totp_confirm=$(cat /tmp/whiptail) + fi + if [ "$totp_confirm" = "i" -o -z "$totp_confirm" ]; then + # update the TOTP code every thirty seconds + date=`date "+%Y-%m-%d %H:%M:%S"` + seconds=`date "+%s"` + half=`expr \( $seconds % 60 \) / 30` + if [ "$CONFIG_TPM" = n ]; then + TOTP="NO TPM" + elif [ "$half" != "$last_half" ]; then + last_half=$half; + TOTP=`unseal-totp` + if [ $? -ne 0 ]; then whiptail $CONFIG_ERROR_BG_COLOR --clear --title "ERROR: TOTP Generation Failed!" \ --menu "ERROR: Heads couldn't generate the TOTP code.\n\nIf this is the first time the system has booted, you should reset the TPM\nand set your own password\n\nIf you just reflashed your BIOS, you'll need to generate a new TOTP secret.\n\nIf you have not just reflashed your BIOS, THIS COULD INDICATE TAMPERING!\n\nHow would you like to proceed?" 30 90 4 \ 'g' ' Generate new TOTP/HOTP secret' \ @@ -136,8 +139,9 @@ while true; do 'p' ' Reset the TPM' \ 'x' ' Exit to recovery shell' \ 2>/tmp/whiptail || recovery "GUI menu failed" + + totp_confirm=$(cat /tmp/whiptail) fi - totp_confirm=$(cat /tmp/whiptail) fi fi From 57b487c38cbc014bbe2e3d6a477b9a5651967b46 Mon Sep 17 00:00:00 2001 From: Kyle Rankin Date: Wed, 5 Dec 2018 14:51:53 -0800 Subject: [PATCH 034/102] Update version #s for Librem coreboot, add Librem Key detection dialog The Librem coreboot is labeled with the current version and is visible from dmidecode and is supposed to reflect the current version of coreboot, however it was out of date and reflected 4.7 when Heads has moved on to 4.8.1. I've also added a simple change to further simplify onboarding by warning users who have Librem Key configured when they boot without it being inserted. --- config/coreboot-librem13v2.config | 4 ++-- config/coreboot-librem15v3.config | 4 ++-- initrd/bin/gui-init | 3 +++ 3 files changed, 7 insertions(+), 4 deletions(-) diff --git a/config/coreboot-librem13v2.config b/config/coreboot-librem13v2.config index f05c1d120..fad72db67 100644 --- a/config/coreboot-librem13v2.config +++ b/config/coreboot-librem13v2.config @@ -1,4 +1,4 @@ -CONFIG_LOCALVERSION="4.7-Purism-4-heads" +CONFIG_LOCALVERSION="4.8.1-Purism-1-heads-beta" CONFIG_USE_BLOBS=y CONFIG_MEASURED_BOOT=y CONFIG_VENDOR_PURISM=y @@ -26,7 +26,7 @@ CONFIG_FSP_M_XIP=y CONFIG_DEFAULT_CONSOLE_LOGLEVEL_8=y CONFIG_PAYLOAD_LINUX=y CONFIG_PAYLOAD_FILE="../../build/librem13v2/bzImage" -CONFIG_LINUX_COMMAND_LINE="intel_iommu=on iommu=pt" +CONFIG_LINUX_COMMAND_LINE="intel_iommu=on iommu=pt quiet loglevel=3" CONFIG_LINUX_INITRD="../../build/librem13v2/initrd.cpio.xz" CONFIG_COREINFO_SECONDARY_PAYLOAD=y CONFIG_MEMTEST_SECONDARY_PAYLOAD=y diff --git a/config/coreboot-librem15v3.config b/config/coreboot-librem15v3.config index 53d196b58..218ea5f7c 100644 --- a/config/coreboot-librem15v3.config +++ b/config/coreboot-librem15v3.config @@ -1,4 +1,4 @@ -CONFIG_LOCALVERSION="4.7-Purism-4-heads" +CONFIG_LOCALVERSION="4.8.1-Purism-1-heads-beta" CONFIG_USE_BLOBS=y CONFIG_MEASURED_BOOT=y CONFIG_VENDOR_PURISM=y @@ -26,7 +26,7 @@ CONFIG_FSP_M_XIP=y CONFIG_DEFAULT_CONSOLE_LOGLEVEL_8=y CONFIG_PAYLOAD_LINUX=y CONFIG_PAYLOAD_FILE="../../build/librem15v3/bzImage" -CONFIG_LINUX_COMMAND_LINE="intel_iommu=on iommu=pt" +CONFIG_LINUX_COMMAND_LINE="intel_iommu=on iommu=pt quiet loglevel=3" CONFIG_LINUX_INITRD="../../build/librem15v3/initrd.cpio.xz" CONFIG_COREINFO_SECONDARY_PAYLOAD=y CONFIG_MEMTEST_SECONDARY_PAYLOAD=y diff --git a/initrd/bin/gui-init b/initrd/bin/gui-init index 35b32fad6..692c382d2 100755 --- a/initrd/bin/gui-init +++ b/initrd/bin/gui-init @@ -149,6 +149,9 @@ while true; do if [ -x /bin/libremkey_hotp_verification ]; then HOTP=`unseal-hotp` enable_usb + if ! libremkey_hotp_verification info ; then + whiptail $CONFIG_WARNING_BG_COLOR --clear --title 'WARNING: Please Insert Your Librem Key' --msgbox "Your Librem Key was not detected.\n\nPlease insert your Librem Key" 30 90 + fi # Don't output HOTP codes to screen, so as to make replay attacks harder libremkey_hotp_verification check $HOTP case "$?" in From 2f9c201f3e9f20c93e432326c0ddfdb19229b02a Mon Sep 17 00:00:00 2001 From: Kyle Rankin Date: Thu, 6 Dec 2018 10:43:34 -0800 Subject: [PATCH 035/102] Add a configuration GUI script This change will add a new GUI script that will allow users to change their running configuration (currently just /boot and USB boot options) and optionally persist that modified configuration with reflashing the BIOS with a modified cbfs. --- initrd/bin/config-gui.sh | 135 +++++++++++++++++++++++++++++++++++++++ initrd/bin/gui-init | 6 ++ 2 files changed, 141 insertions(+) create mode 100755 initrd/bin/config-gui.sh diff --git a/initrd/bin/config-gui.sh b/initrd/bin/config-gui.sh new file mode 100755 index 000000000..c716a77d1 --- /dev/null +++ b/initrd/bin/config-gui.sh @@ -0,0 +1,135 @@ +#!/bin/sh +# +set -e -o pipefail +. /etc/functions +. /etc/config + +file_selector() { + FILE="" + FILE_LIST=$1 + MENU_MSG=${2:-"Choose the file"} +# create file menu options + if [ `cat "$FILE_LIST" | wc -l` -gt 0 ]; then + option="" + while [ -z "$option" ] + do + MENU_OPTIONS="" + n=0 + while read option + do + n=`expr $n + 1` + option=$(echo $option | tr " " "_") + MENU_OPTIONS="$MENU_OPTIONS $n ${option}" + done < $FILE_LIST + + MENU_OPTIONS="$MENU_OPTIONS a Abort" + whiptail --clear --title "Select your File" \ + --menu "${MENU_MSG} [1-$n, a to abort]:" 20 120 8 \ + -- $MENU_OPTIONS \ + 2>/tmp/whiptail || die "Aborting" + + option_index=$(cat /tmp/whiptail) + + if [ "$option_index" = "a" ]; then + option="a" + return + fi + + option=`head -n $option_index $FILE_LIST | tail -1` + if [ "$option" == "a" ]; then + return + fi + done + if [ -n "$option" ]; then + FILE=$option + fi + else + whiptail $CONFIG_ERROR_BG_COLOR --title 'ERROR: No Files Found' \ + --msgbox "No Files found matching the pattern. Aborting." 16 60 + exit 1 + fi +} +replace_config() { + CONFIG_OPTION=$1 + NEW_SETTING=$2 + + awk "gsub(\"^export ${CONFIG_OPTION}=.*\",\"export ${CONFIG_OPTION}=\\\"${NEW_SETTING}\\\"\")" /etc/config > /tmp/config + awk "gsub(\"^${CONFIG_OPTION}=.*\",\"${CONFIG_OPTION}=\\\"${NEW_SETTING}\\\"\")" /etc/config >> /tmp/config + grep -v "^export ${CONFIG_OPTION}=" /etc/config | grep -v "^${CONFIG_OPTION}=" >> /tmp/config + mv /tmp/config /etc/config +} + +while true; do + unset menu_choice + whiptail --clear --title "Config Management Menu" \ + --menu "This menu lets you change existing configuration options for the existing BIOS session.\n\nIf you want those changes to persist after reboot\n\nyou must also save them to the running BIOS." 20 90 10 \ + 'b' ' Change the /boot device' \ + 'u' ' Change the USB boot device' \ + 's' ' Save the current configuration to the running BIOS' \ + 'x' ' Exit' \ + 2>/tmp/whiptail || recovery "GUI menu failed" + + menu_choice=$(cat /tmp/whiptail) + + case "$menu_choice" in + "x" ) + exit 0 + ;; + "b" ) + CURRENT_OPTION=`grep 'CONFIG_BOOT_DEV=' /etc/config | cut -f2 -d '=' | tr -d '"'` + find /dev -name 'sd*' -o -name 'nvme*' > /tmp/filelist.txt + file_selector "/tmp/filelist.txt" "Choose the default /boot device.\n\nCurrently set to $CURRENT_OPTION." + if [ "$FILE" == "" ]; then + return + else + SELECTED_FILE=$FILE + fi + + replace_config "CONFIG_BOOT_DEV" "$SELECTED_FILE" + + whiptail --title 'Config change successful' \ + --msgbox "The /boot device was successfully changed to $SELECTED_FILE" 16 60 + ;; + "u" ) + CURRENT_OPTION=`grep 'CONFIG_USB_BOOT_DEV=' /etc/config | cut -f2 -d '=' | tr -d '"'` + find /dev -name 'sd*' -o -name 'nvme*' > /tmp/filelist.txt + file_selector "/tmp/filelist.txt" "Choose the default USB boot device.\n\nCurrently set to $CURRENT_OPTION." + if [ "$FILE" == "" ]; then + return + else + SELECTED_FILE=$FILE + fi + + replace_config "CONFIG_USB_BOOT_DEV" "$SELECTED_FILE" + + whiptail --title 'Config change successful' \ + --msgbox "The USB boot device was successfully changed to $SELECTED_FILE" 16 60 + ;; + "s" ) + /bin/flash.sh -r /tmp/config-gui.rom + if [ ! -s /tmp/config-gui.rom ]; then + whiptail $CONFIG_ERROR_BG_COLOR --title 'ERROR: BIOS Read Failed!' \ + --msgbox "Unable to read BIOS" 16 60 + exit 1 + fi + + if (cbfs -o /tmp/config-gui.rom -l | grep -q "heads/initrd/etc/config") then + cbfs -o /tmp/config-gui.rom -d "heads/initrd/etc/config" + fi + cbfs -o /tmp/config-gui.rom -a "heads/initrd/etc/config" -f /etc/config + + if (whiptail --title 'Update ROM?' \ + --yesno "This will reflash your BIOS with the updated version\n\nDo you want to proceed?" 16 90) then + /bin/flash.sh /tmp/config-gui.rom + whiptail --title 'BIOS Updated Successfully' \ + --msgbox "BIOS updated successfully.\n\nIf your keys have changed, be sure to re-sign all files in /boot\nafter you reboot.\n\nPress Enter to reboot" 16 60 + umount /media + /bin/reboot + else + exit 0 + fi + ;; + esac + +done +exit 0 diff --git a/initrd/bin/gui-init b/initrd/bin/gui-init index 957ebba41..20f12280b 100755 --- a/initrd/bin/gui-init +++ b/initrd/bin/gui-init @@ -183,6 +183,7 @@ while true; do --menu "Configure Advanced Settings" 20 90 10 \ 'g' ' Generate new TOTP/HOTP secret' \ 's' ' Update checksums and sign all files in /boot' \ + 'c' ' Change configuration settings -->' \ 'f' ' Flash/Update the BIOS -->' \ 'p' ' Reset the TPM' \ 'n' ' TOTP/HOTP does not match after refresh, troubleshoot' \ @@ -286,6 +287,11 @@ while true; do continue fi + if [ "$totp_confirm" = "c" ]; then + config-gui.sh + continue + fi + if [ "$totp_confirm" = "f" ]; then flash-gui.sh continue From de18c706dcdb3bc6d7b4fa7c53403713356a684c Mon Sep 17 00:00:00 2001 From: Kyle Rankin Date: Thu, 6 Dec 2018 12:56:39 -0800 Subject: [PATCH 036/102] Load USB modules before scanning for USB devices --- initrd/bin/config-gui.sh | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/initrd/bin/config-gui.sh b/initrd/bin/config-gui.sh index c716a77d1..5ce137b03 100755 --- a/initrd/bin/config-gui.sh +++ b/initrd/bin/config-gui.sh @@ -91,6 +91,9 @@ while true; do --msgbox "The /boot device was successfully changed to $SELECTED_FILE" 16 60 ;; "u" ) + whiptail --title 'Insert a USB thumb drive' \ + --msgbox "Insert a USB thumb drive so we can detect the device" 16 60 + enable_usb CURRENT_OPTION=`grep 'CONFIG_USB_BOOT_DEV=' /etc/config | cut -f2 -d '=' | tr -d '"'` find /dev -name 'sd*' -o -name 'nvme*' > /tmp/filelist.txt file_selector "/tmp/filelist.txt" "Choose the default USB boot device.\n\nCurrently set to $CURRENT_OPTION." @@ -123,7 +126,6 @@ while true; do /bin/flash.sh /tmp/config-gui.rom whiptail --title 'BIOS Updated Successfully' \ --msgbox "BIOS updated successfully.\n\nIf your keys have changed, be sure to re-sign all files in /boot\nafter you reboot.\n\nPress Enter to reboot" 16 60 - umount /media /bin/reboot else exit 0 From f47df1edd688ef862564d417064402ab52ad59d0 Mon Sep 17 00:00:00 2001 From: Kyle Rankin Date: Thu, 6 Dec 2018 13:10:45 -0800 Subject: [PATCH 037/102] Use mount-usb instead of enable_usb to find USB drives --- initrd/bin/config-gui.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/initrd/bin/config-gui.sh b/initrd/bin/config-gui.sh index 5ce137b03..941479480 100755 --- a/initrd/bin/config-gui.sh +++ b/initrd/bin/config-gui.sh @@ -93,7 +93,7 @@ while true; do "u" ) whiptail --title 'Insert a USB thumb drive' \ --msgbox "Insert a USB thumb drive so we can detect the device" 16 60 - enable_usb + mount-usb CURRENT_OPTION=`grep 'CONFIG_USB_BOOT_DEV=' /etc/config | cut -f2 -d '=' | tr -d '"'` find /dev -name 'sd*' -o -name 'nvme*' > /tmp/filelist.txt file_selector "/tmp/filelist.txt" "Choose the default USB boot device.\n\nCurrently set to $CURRENT_OPTION." From 49a131fa4b523a33779920a65331169168bdce9d Mon Sep 17 00:00:00 2001 From: Kyle Rankin Date: Thu, 6 Dec 2018 13:51:46 -0800 Subject: [PATCH 038/102] Fix formatting on the default config GUI menu text --- initrd/bin/config-gui.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/initrd/bin/config-gui.sh b/initrd/bin/config-gui.sh index 941479480..67c5fbfaf 100755 --- a/initrd/bin/config-gui.sh +++ b/initrd/bin/config-gui.sh @@ -62,7 +62,7 @@ replace_config() { while true; do unset menu_choice whiptail --clear --title "Config Management Menu" \ - --menu "This menu lets you change existing configuration options for the existing BIOS session.\n\nIf you want those changes to persist after reboot\n\nyou must also save them to the running BIOS." 20 90 10 \ + --menu "This menu lets you change settings for the current BIOS session.\n\nAll changes will revert after a reboot,\n\nunless you also save them to the running BIOS." 20 90 10 \ 'b' ' Change the /boot device' \ 'u' ' Change the USB boot device' \ 's' ' Save the current configuration to the running BIOS' \ From 3eb62eed1a18caae4161ecb956c20b1f203212c3 Mon Sep 17 00:00:00 2001 From: Kyle Rankin Date: Thu, 6 Dec 2018 15:24:28 -0800 Subject: [PATCH 039/102] Use global /tmp/config that combines multiple config files As part of the config gui we want to be able to have the system define new config options without them being lost if the user makes their own changes in CBFS. To allow that this change creates a function initiated in init that combines all /etc/config* files into /tmp/config. All existing scripts have been changed to source /tmp/config instead of /etc/config. The config-gui.sh script now uses /etc/config.user to hold user configuration options but the combine_configs function will allow that to expand as others want to split configuration out further. As it stands here are the current config files: /etc/config -- Compiled-in configuration options /etc/config.user -- User preferences that override /etc/config /tmp/config -- Running config referenced by the BIOS, combination of existing configs --- initrd/bin/config-gui.sh | 27 ++++++++++----------------- initrd/bin/flash-gui.sh | 2 +- initrd/bin/flash.sh | 2 +- initrd/bin/generic-init | 2 +- initrd/bin/gui-init | 2 +- initrd/bin/kexec-boot | 2 +- initrd/bin/kexec-iso-init | 2 +- initrd/bin/kexec-save-default | 2 +- initrd/bin/kexec-seal-key | 2 +- initrd/bin/kexec-select-boot | 2 +- initrd/bin/kexec-sign-config | 2 +- initrd/bin/usb-init | 2 +- initrd/bin/usb-scan | 2 +- initrd/bin/x230-flash.init | 2 +- initrd/etc/functions | 17 +++++++++++++++++ initrd/init | 3 ++- 16 files changed, 42 insertions(+), 31 deletions(-) diff --git a/initrd/bin/config-gui.sh b/initrd/bin/config-gui.sh index 67c5fbfaf..55b3831c4 100755 --- a/initrd/bin/config-gui.sh +++ b/initrd/bin/config-gui.sh @@ -2,7 +2,7 @@ # set -e -o pipefail . /etc/functions -. /etc/config +. /tmp/config file_selector() { FILE="" @@ -49,15 +49,6 @@ file_selector() { exit 1 fi } -replace_config() { - CONFIG_OPTION=$1 - NEW_SETTING=$2 - - awk "gsub(\"^export ${CONFIG_OPTION}=.*\",\"export ${CONFIG_OPTION}=\\\"${NEW_SETTING}\\\"\")" /etc/config > /tmp/config - awk "gsub(\"^${CONFIG_OPTION}=.*\",\"${CONFIG_OPTION}=\\\"${NEW_SETTING}\\\"\")" /etc/config >> /tmp/config - grep -v "^export ${CONFIG_OPTION}=" /etc/config | grep -v "^${CONFIG_OPTION}=" >> /tmp/config - mv /tmp/config /etc/config -} while true; do unset menu_choice @@ -76,7 +67,7 @@ while true; do exit 0 ;; "b" ) - CURRENT_OPTION=`grep 'CONFIG_BOOT_DEV=' /etc/config | cut -f2 -d '=' | tr -d '"'` + CURRENT_OPTION=`grep 'CONFIG_BOOT_DEV=' /tmp/config | cut -f2 -d '=' | tr -d '"'` find /dev -name 'sd*' -o -name 'nvme*' > /tmp/filelist.txt file_selector "/tmp/filelist.txt" "Choose the default /boot device.\n\nCurrently set to $CURRENT_OPTION." if [ "$FILE" == "" ]; then @@ -85,7 +76,8 @@ while true; do SELECTED_FILE=$FILE fi - replace_config "CONFIG_BOOT_DEV" "$SELECTED_FILE" + replace_config /etc/config.user "CONFIG_BOOT_DEV" "$SELECTED_FILE" + combine_configs whiptail --title 'Config change successful' \ --msgbox "The /boot device was successfully changed to $SELECTED_FILE" 16 60 @@ -94,7 +86,7 @@ while true; do whiptail --title 'Insert a USB thumb drive' \ --msgbox "Insert a USB thumb drive so we can detect the device" 16 60 mount-usb - CURRENT_OPTION=`grep 'CONFIG_USB_BOOT_DEV=' /etc/config | cut -f2 -d '=' | tr -d '"'` + CURRENT_OPTION=`grep 'CONFIG_USB_BOOT_DEV=' /tmp/config | cut -f2 -d '=' | tr -d '"'` find /dev -name 'sd*' -o -name 'nvme*' > /tmp/filelist.txt file_selector "/tmp/filelist.txt" "Choose the default USB boot device.\n\nCurrently set to $CURRENT_OPTION." if [ "$FILE" == "" ]; then @@ -103,7 +95,8 @@ while true; do SELECTED_FILE=$FILE fi - replace_config "CONFIG_USB_BOOT_DEV" "$SELECTED_FILE" + replace_config /etc/config.user "CONFIG_USB_BOOT_DEV" "$SELECTED_FILE" + combine_configs whiptail --title 'Config change successful' \ --msgbox "The USB boot device was successfully changed to $SELECTED_FILE" 16 60 @@ -116,10 +109,10 @@ while true; do exit 1 fi - if (cbfs -o /tmp/config-gui.rom -l | grep -q "heads/initrd/etc/config") then - cbfs -o /tmp/config-gui.rom -d "heads/initrd/etc/config" + if (cbfs -o /tmp/config-gui.rom -l | grep -q "heads/initrd/etc/config.user") then + cbfs -o /tmp/config-gui.rom -d "heads/initrd/etc/config.user" fi - cbfs -o /tmp/config-gui.rom -a "heads/initrd/etc/config" -f /etc/config + cbfs -o /tmp/config-gui.rom -a "heads/initrd/etc/config.user" -f /etc/config.user if (whiptail --title 'Update ROM?' \ --yesno "This will reflash your BIOS with the updated version\n\nDo you want to proceed?" 16 90) then diff --git a/initrd/bin/flash-gui.sh b/initrd/bin/flash-gui.sh index 191d977b0..277a4faeb 100755 --- a/initrd/bin/flash-gui.sh +++ b/initrd/bin/flash-gui.sh @@ -2,7 +2,7 @@ # set -e -o pipefail . /etc/functions -. /etc/config +. /tmp/config mount_usb(){ # Mount the USB boot device diff --git a/initrd/bin/flash.sh b/initrd/bin/flash.sh index 4b70ac8ad..e89c9a98c 100755 --- a/initrd/bin/flash.sh +++ b/initrd/bin/flash.sh @@ -4,7 +4,7 @@ # set -e -o pipefail . /etc/functions -. /etc/config +. /tmp/config case "$CONFIG_BOARD" in librem* ) diff --git a/initrd/bin/generic-init b/initrd/bin/generic-init index c0808e48e..b63b0a05c 100755 --- a/initrd/bin/generic-init +++ b/initrd/bin/generic-init @@ -2,7 +2,7 @@ # Boot from a local disk installation . /etc/functions -. /etc/config +. /tmp/config mount_boot() { diff --git a/initrd/bin/gui-init b/initrd/bin/gui-init index 20f12280b..32dfc920d 100755 --- a/initrd/bin/gui-init +++ b/initrd/bin/gui-init @@ -4,7 +4,7 @@ CONFIG_BOOT_GUI_MENU_NAME='Heads Boot Menu' . /etc/functions -. /etc/config +. /tmp/config mount_boot() { diff --git a/initrd/bin/kexec-boot b/initrd/bin/kexec-boot index 7d7d83674..49e48aeef 100755 --- a/initrd/bin/kexec-boot +++ b/initrd/bin/kexec-boot @@ -1,7 +1,7 @@ #!/bin/sh # Launches kexec from saved configuration entries set -e -o pipefail -. /etc/config +. /tmp/config . /etc/functions dryrun="n" diff --git a/initrd/bin/kexec-iso-init b/initrd/bin/kexec-iso-init index 755ebba60..ebe48fe0c 100755 --- a/initrd/bin/kexec-iso-init +++ b/initrd/bin/kexec-iso-init @@ -2,7 +2,7 @@ # Boot from signed ISO set -e -o pipefail . /etc/functions -. /etc/config +. /tmp/config MOUNTED_ISO_PATH="$1" ISO_PATH="$2" diff --git a/initrd/bin/kexec-save-default b/initrd/bin/kexec-save-default index 0bbaa1002..85ac3f27e 100755 --- a/initrd/bin/kexec-save-default +++ b/initrd/bin/kexec-save-default @@ -1,7 +1,7 @@ #!/bin/sh # Save these options to be the persistent default set -e -o pipefail -. /etc/config +. /tmp/config . /etc/functions while getopts "b:d:p:i:" arg; do diff --git a/initrd/bin/kexec-seal-key b/initrd/bin/kexec-seal-key index da5a187e2..f574b5587 100755 --- a/initrd/bin/kexec-seal-key +++ b/initrd/bin/kexec-seal-key @@ -11,7 +11,7 @@ TPM_SEALED="/tmp/secret/secret.sealed" RECOVERY_KEY="/tmp/secret/recovery.key" . /etc/functions -. /etc/config +. /tmp/config paramsdir=$1 if [ -z "$paramsdir" ]; then diff --git a/initrd/bin/kexec-select-boot b/initrd/bin/kexec-select-boot index 4a1f2a73c..ab8002fef 100755 --- a/initrd/bin/kexec-select-boot +++ b/initrd/bin/kexec-select-boot @@ -1,7 +1,7 @@ #!/bin/sh # Generic configurable boot script via kexec set -e -o pipefail -. /etc/config +. /tmp/config . /etc/functions add="" diff --git a/initrd/bin/kexec-sign-config b/initrd/bin/kexec-sign-config index 1ff9f46c9..23cdf28d9 100755 --- a/initrd/bin/kexec-sign-config +++ b/initrd/bin/kexec-sign-config @@ -1,7 +1,7 @@ #!/bin/sh # Sign a valid directory of kexec params set -e -o pipefail -. /etc/config +. /tmp/config . /etc/functions rollback="n" diff --git a/initrd/bin/usb-init b/initrd/bin/usb-init index 5ddfdff12..4a52b262d 100755 --- a/initrd/bin/usb-init +++ b/initrd/bin/usb-init @@ -2,7 +2,7 @@ # Boot a USB installation . /etc/functions -. /etc/config +. /tmp/config if [ "$CONFIG_TPM" = "y" ]; then # Extend PCR4 as soon as possible diff --git a/initrd/bin/usb-scan b/initrd/bin/usb-scan index 57f6879b0..6d3eda27d 100755 --- a/initrd/bin/usb-scan +++ b/initrd/bin/usb-scan @@ -2,7 +2,7 @@ # Scan for USB installation options set -e -o pipefail . /etc/functions -. /etc/config +. /tmp/config # Unmount any previous boot device if grep -q /boot /proc/mounts ; then diff --git a/initrd/bin/x230-flash.init b/initrd/bin/x230-flash.init index a4d22c0fc..e02dcf5d8 100755 --- a/initrd/bin/x230-flash.init +++ b/initrd/bin/x230-flash.init @@ -3,7 +3,7 @@ # invoke a recovery shell and prompt the user for how to proceed . /etc/functions -. /etc/config +. /tmp/config insmod /lib/modules/ehci-hcd.ko insmod /lib/modules/ehci-pci.ko diff --git a/initrd/etc/functions b/initrd/etc/functions index 4488476a4..e556c9607 100755 --- a/initrd/etc/functions +++ b/initrd/etc/functions @@ -217,3 +217,20 @@ preserve_rom() { fi done } +replace_config() { + CONFIG_FILE=$1 + CONFIG_OPTION=$2 + NEW_SETTING=$3 + +# first pull out the existing option from the global config and place in a tmp file + awk "gsub(\"^export ${CONFIG_OPTION}=.*\",\"export ${CONFIG_OPTION}=\\\"${NEW_SETTING}\\\"\")" /tmp/config > ${CONFIG_FILE}.tmp + awk "gsub(\"^${CONFIG_OPTION}=.*\",\"${CONFIG_OPTION}=\\\"${NEW_SETTING}\\\"\")" /tmp/config >> ${CONFIG_FILE}.tmp + +# then copy any remaining settings from the existing config file, minus the option you changed + grep -v "^export ${CONFIG_OPTION}=" ${CONFIG_FILE} | grep -v "^${CONFIG_OPTION}=" >> ${CONFIG_FILE}.tmp + + mv ${CONFIG_FILE}.tmp ${CONFIG_FILE} +} +combine_configs() { + sort /etc/config* | uniq > /tmp/config +} diff --git a/initrd/init b/initrd/init index d489f6ae5..4410c6fbc 100755 --- a/initrd/init +++ b/initrd/init @@ -40,7 +40,8 @@ hwclock -l -s # Read the system configuration parameters . /etc/functions -. /etc/config +combine_configs +. /tmp/config # Add our boot devices into the /etc/fstab, if they are defined # in the configuration file. From dd3f650b81c93f8848c081af1a04d0773b5e9ea7 Mon Sep 17 00:00:00 2001 From: Kyle Rankin Date: Thu, 6 Dec 2018 15:41:20 -0800 Subject: [PATCH 040/102] Just load usb-storage module, not mount, bugfix in replace_config We need to handle the case where the specific config file doesn't exist, or else grep fails, so we touch the file ahead of time. Mounting the usb storage caused problems when you re-enter the menu a second time, so we will just load the storage module. --- initrd/bin/config-gui.sh | 10 +++++++++- initrd/etc/functions | 15 ++++++++------- 2 files changed, 17 insertions(+), 8 deletions(-) diff --git a/initrd/bin/config-gui.sh b/initrd/bin/config-gui.sh index 55b3831c4..5d58e7930 100755 --- a/initrd/bin/config-gui.sh +++ b/initrd/bin/config-gui.sh @@ -85,7 +85,15 @@ while true; do "u" ) whiptail --title 'Insert a USB thumb drive' \ --msgbox "Insert a USB thumb drive so we can detect the device" 16 60 - mount-usb + + enable_usb + + if ! lsmod | grep -q usb_storage; then + insmod /lib/modules/usb-storage.ko \ + || die "usb_storage: module load failed" + sleep 5 + fi + CURRENT_OPTION=`grep 'CONFIG_USB_BOOT_DEV=' /tmp/config | cut -f2 -d '=' | tr -d '"'` find /dev -name 'sd*' -o -name 'nvme*' > /tmp/filelist.txt file_selector "/tmp/filelist.txt" "Choose the default USB boot device.\n\nCurrently set to $CURRENT_OPTION." diff --git a/initrd/etc/functions b/initrd/etc/functions index e556c9607..cd8e1395e 100755 --- a/initrd/etc/functions +++ b/initrd/etc/functions @@ -218,18 +218,19 @@ preserve_rom() { done } replace_config() { - CONFIG_FILE=$1 - CONFIG_OPTION=$2 - NEW_SETTING=$3 + CONFIG_FILE=$1 + CONFIG_OPTION=$2 + NEW_SETTING=$3 + touch $CONFIG_FILE # first pull out the existing option from the global config and place in a tmp file - awk "gsub(\"^export ${CONFIG_OPTION}=.*\",\"export ${CONFIG_OPTION}=\\\"${NEW_SETTING}\\\"\")" /tmp/config > ${CONFIG_FILE}.tmp - awk "gsub(\"^${CONFIG_OPTION}=.*\",\"${CONFIG_OPTION}=\\\"${NEW_SETTING}\\\"\")" /tmp/config >> ${CONFIG_FILE}.tmp + awk "gsub(\"^export ${CONFIG_OPTION}=.*\",\"export ${CONFIG_OPTION}=\\\"${NEW_SETTING}\\\"\")" /tmp/config > ${CONFIG_FILE}.tmp + awk "gsub(\"^${CONFIG_OPTION}=.*\",\"${CONFIG_OPTION}=\\\"${NEW_SETTING}\\\"\")" /tmp/config >> ${CONFIG_FILE}.tmp # then copy any remaining settings from the existing config file, minus the option you changed - grep -v "^export ${CONFIG_OPTION}=" ${CONFIG_FILE} | grep -v "^${CONFIG_OPTION}=" >> ${CONFIG_FILE}.tmp + grep -v "^export ${CONFIG_OPTION}=" ${CONFIG_FILE} | grep -v "^${CONFIG_OPTION}=" >> ${CONFIG_FILE}.tmp - mv ${CONFIG_FILE}.tmp ${CONFIG_FILE} + mv ${CONFIG_FILE}.tmp ${CONFIG_FILE} } combine_configs() { sort /etc/config* | uniq > /tmp/config From 1e9491f98d33b05be030add26359dfbcb75fa0ed Mon Sep 17 00:00:00 2001 From: Kyle Rankin Date: Thu, 6 Dec 2018 16:10:10 -0800 Subject: [PATCH 041/102] Handle the case where grep operates on an empty file There are cases when grepping for an option in the config file where grep will not find it, which is fine in this case, but without adjusting the exit code in that case it can make an entire script bail out. --- initrd/etc/functions | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/initrd/etc/functions b/initrd/etc/functions index cd8e1395e..782e08e80 100755 --- a/initrd/etc/functions +++ b/initrd/etc/functions @@ -228,7 +228,7 @@ replace_config() { awk "gsub(\"^${CONFIG_OPTION}=.*\",\"${CONFIG_OPTION}=\\\"${NEW_SETTING}\\\"\")" /tmp/config >> ${CONFIG_FILE}.tmp # then copy any remaining settings from the existing config file, minus the option you changed - grep -v "^export ${CONFIG_OPTION}=" ${CONFIG_FILE} | grep -v "^${CONFIG_OPTION}=" >> ${CONFIG_FILE}.tmp + grep -v "^export ${CONFIG_OPTION}=" ${CONFIG_FILE} | grep -v "^${CONFIG_OPTION}=" >> ${CONFIG_FILE}.tmp || true mv ${CONFIG_FILE}.tmp ${CONFIG_FILE} } From 64484206ed950b51eed77b74dc491733e97f9443 Mon Sep 17 00:00:00 2001 From: Kyle Rankin Date: Thu, 6 Dec 2018 16:27:36 -0800 Subject: [PATCH 042/102] Load cbfs before combining configs and building fstab --- initrd/init | 15 +++++++++------ 1 file changed, 9 insertions(+), 6 deletions(-) diff --git a/initrd/init b/initrd/init index 4410c6fbc..4b4eefb25 100755 --- a/initrd/init +++ b/initrd/init @@ -40,6 +40,15 @@ hwclock -l -s # Read the system configuration parameters . /etc/functions +. /etc/config + +if [ "$CONFIG_COREBOOT" = "y" ]; then + /bin/cbfs-init +fi +if [ "$CONFIG_LINUXBOOT" = "y" ]; then + /bin/uefi-init +fi + combine_configs . /tmp/config @@ -52,12 +61,6 @@ if [ ! -z "$CONFIG_USB_BOOT_DEV" ]; then echo >> /etc/fstab "$CONFIG_USB_BOOT_DEV /media auto defaults,ro 0 0" fi -if [ "$CONFIG_COREBOOT" = "y" ]; then - /bin/cbfs-init -fi -if [ "$CONFIG_LINUXBOOT" = "y" ]; then - /bin/uefi-init -fi /bin/key-init # Setup recovery serial shell From 8b8be510a26f6b15bb0f5abfc7150a8ecad5ccdf Mon Sep 17 00:00:00 2001 From: Kyle Rankin Date: Thu, 6 Dec 2018 16:29:09 -0800 Subject: [PATCH 043/102] Do not sort config options, just cat to preserve precedence If we sort | uniq config options, then the lowest in the sort will get precedence, when what we want is for user preferences to override system ones. --- initrd/etc/functions | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/initrd/etc/functions b/initrd/etc/functions index 782e08e80..553f4b274 100755 --- a/initrd/etc/functions +++ b/initrd/etc/functions @@ -233,5 +233,5 @@ replace_config() { mv ${CONFIG_FILE}.tmp ${CONFIG_FILE} } combine_configs() { - sort /etc/config* | uniq > /tmp/config + cat /etc/config* > /tmp/config } From ab0f9dd32e1847d784d1cba265d8303ea90ddb7d Mon Sep 17 00:00:00 2001 From: Kyle Rankin Date: Thu, 6 Dec 2018 16:34:47 -0800 Subject: [PATCH 044/102] Move custom configs below recovery shell For safety it would be better if we source any custom configs after the recovery shell in init. That way we can recover from any config mistakes. --- initrd/init | 24 ++++++++++++------------ 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/initrd/init b/initrd/init index 4b4eefb25..a44776743 100755 --- a/initrd/init +++ b/initrd/init @@ -49,18 +49,6 @@ if [ "$CONFIG_LINUXBOOT" = "y" ]; then /bin/uefi-init fi -combine_configs -. /tmp/config - -# Add our boot devices into the /etc/fstab, if they are defined -# in the configuration file. -if [ ! -z "$CONFIG_BOOT_DEV" ]; then - echo >> /etc/fstab "$CONFIG_BOOT_DEV /boot auto defaults,ro 0 0" -fi -if [ ! -z "$CONFIG_USB_BOOT_DEV" ]; then - echo >> /etc/fstab "$CONFIG_USB_BOOT_DEV /media auto defaults,ro 0 0" -fi - /bin/key-init # Setup recovery serial shell @@ -91,6 +79,18 @@ if [ "$boot_option" = "r" ]; then exit fi +combine_configs +. /tmp/config + +# Add our boot devices into the /etc/fstab, if they are defined +# in the configuration file. +if [ ! -z "$CONFIG_BOOT_DEV" ]; then + echo >> /etc/fstab "$CONFIG_BOOT_DEV /boot auto defaults,ro 0 0" +fi +if [ ! -z "$CONFIG_USB_BOOT_DEV" ]; then + echo >> /etc/fstab "$CONFIG_USB_BOOT_DEV /media auto defaults,ro 0 0" +fi + if [ ! -x "$CONFIG_BOOTSCRIPT" -a ! -x "$CONFIG_BOOTSCRIPT_NETWORK" ]; then recovery 'Boot script missing? Entering recovery shell' else From 43a858e25ce325407b63260d0da9ab5420a532e3 Mon Sep 17 00:00:00 2001 From: Kyle Rankin Date: Thu, 6 Dec 2018 16:45:40 -0800 Subject: [PATCH 045/102] Show the last setting for a config option if more than one exist --- initrd/bin/config-gui.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/initrd/bin/config-gui.sh b/initrd/bin/config-gui.sh index 5d58e7930..2a116bee7 100755 --- a/initrd/bin/config-gui.sh +++ b/initrd/bin/config-gui.sh @@ -67,7 +67,7 @@ while true; do exit 0 ;; "b" ) - CURRENT_OPTION=`grep 'CONFIG_BOOT_DEV=' /tmp/config | cut -f2 -d '=' | tr -d '"'` + CURRENT_OPTION=`grep 'CONFIG_BOOT_DEV=' /tmp/config | tail -n1 | cut -f2 -d '=' | tr -d '"'` find /dev -name 'sd*' -o -name 'nvme*' > /tmp/filelist.txt file_selector "/tmp/filelist.txt" "Choose the default /boot device.\n\nCurrently set to $CURRENT_OPTION." if [ "$FILE" == "" ]; then @@ -94,7 +94,7 @@ while true; do sleep 5 fi - CURRENT_OPTION=`grep 'CONFIG_USB_BOOT_DEV=' /tmp/config | cut -f2 -d '=' | tr -d '"'` + CURRENT_OPTION=`grep 'CONFIG_USB_BOOT_DEV=' /tmp/config | tail -n1 | cut -f2 -d '=' | tr -d '"'` find /dev -name 'sd*' -o -name 'nvme*' > /tmp/filelist.txt file_selector "/tmp/filelist.txt" "Choose the default USB boot device.\n\nCurrently set to $CURRENT_OPTION." if [ "$FILE" == "" ]; then From 6ebabc5b94cea6cb94669bdfcbaa6e08ce19dc04 Mon Sep 17 00:00:00 2001 From: Kyle Rankin Date: Thu, 6 Dec 2018 16:51:43 -0800 Subject: [PATCH 046/102] Remove any duplicate config options from config.user --- initrd/etc/functions | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/initrd/etc/functions b/initrd/etc/functions index 553f4b274..1f7896ac2 100755 --- a/initrd/etc/functions +++ b/initrd/etc/functions @@ -229,8 +229,8 @@ replace_config() { # then copy any remaining settings from the existing config file, minus the option you changed grep -v "^export ${CONFIG_OPTION}=" ${CONFIG_FILE} | grep -v "^${CONFIG_OPTION}=" >> ${CONFIG_FILE}.tmp || true - - mv ${CONFIG_FILE}.tmp ${CONFIG_FILE} + sort ${CONFIG_FILE}.tmp | uniq > ${CONFIG_FILE} + rm -f ${CONFIG_FILE}.tmp } combine_configs() { cat /etc/config* > /tmp/config From a809c72f7d82540aaf954d6fd4ea84d5e4f410ca Mon Sep 17 00:00:00 2001 From: Kyle Rankin Date: Wed, 12 Dec 2018 14:09:19 -0800 Subject: [PATCH 047/102] Fix column width for error output --- initrd/bin/gui-init | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/initrd/bin/gui-init b/initrd/bin/gui-init index 692c382d2..fd2876fb4 100755 --- a/initrd/bin/gui-init +++ b/initrd/bin/gui-init @@ -113,7 +113,7 @@ while true; do GPG_KEY_COUNT=`gpg -k 2>/dev/null | wc -l` if [ $GPG_KEY_COUNT -eq 0 ]; then whiptail $CONFIG_ERROR_BG_COLOR --clear --title "ERROR: GPG keyring empty!" \ - --menu "ERROR: Heads couldn't find any GPG keys in your keyring.\n\nIf this is the first time the system has booted, you should add a public GPG key to the BIOS now.\n\nIf you just reflashed a new BIOS, you'll need to add at least one public key to the keyring.\n\nIf you have not just reflashed your BIOS, THIS COULD INDICATE TAMPERING!\n\nHow would you like to proceed?" 30 90 4 \ + --menu "ERROR: Heads couldn't find any GPG keys in your keyring.\n\nIf this is the first time the system has booted,\nyou should add a public GPG key to the BIOS now.\n\nIf you just reflashed a new BIOS, you'll need to add at least one\npublic key to the keyring.\n\nIf you have not just reflashed your BIOS, THIS COULD INDICATE TAMPERING!\n\nHow would you like to proceed?" 30 90 4 \ 'f' ' Add a GPG key to the running BIOS' \ 'i' ' Ignore error and continue to default boot menu' \ 'x' ' Exit to recovery shell' \ From b38e720440b44d8e1161a278121cd8f2c5687e87 Mon Sep 17 00:00:00 2001 From: AJ Jordan Date: Thu, 13 Dec 2018 01:32:37 -0500 Subject: [PATCH 048/102] Use a better GNU mirror URL The new URL automatically redirects to a nearby, current GNU mirror. Also, the fact that it's HTTPS helps with restrictive outbound firewall policies that disallow plaintext traffic (for example, using Qubes' firewall functionality). --- modules/make | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modules/make b/modules/make index 460c0b31c..bcf487484 100644 --- a/modules/make +++ b/modules/make @@ -6,7 +6,7 @@ make_version := 4.2 make_dir := make-$(make_version) make_tar := make-$(make_version).tar.bz2 -make_url := http://gnu.mirror.constant.com/make/$(make_tar) +make_url := https://ftpmirror.gnu.org/make/$(make_tar) make_hash := 4e5ce3b62fe5d75ff8db92b7f6df91e476d10c3aceebf1639796dc5bfece655f # This is built for the local machine, not the target, so it doesn't have any From 6303fbcacc68426a9987706466e0fc7b00b3b678 Mon Sep 17 00:00:00 2001 From: AJ Jordan Date: Thu, 13 Dec 2018 16:07:35 -0500 Subject: [PATCH 049/102] Download most resource from HTTPS As much as possible. --- modules/dropbear | 2 +- modules/popt | 2 +- modules/zlib | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/modules/dropbear b/modules/dropbear index b9e4f4a13..998087c6d 100644 --- a/modules/dropbear +++ b/modules/dropbear @@ -4,7 +4,7 @@ modules-$(CONFIG_DROPBEAR) += dropbear dropbear_version := 2016.74 dropbear_dir := dropbear-$(dropbear_version) dropbear_tar := dropbear-$(dropbear_version).tar.bz2 -dropbear_url := http://matt.ucc.asn.au/dropbear/releases/$(dropbear_tar) +dropbear_url := https://matt.ucc.asn.au/dropbear/releases/$(dropbear_tar) dropbear_hash := 2720ea54ed009af812701bcc290a2a601d5c107d12993e5d92c0f5f81f718891 dropbear_configure := ./configure \ diff --git a/modules/popt b/modules/popt index 0b091543c..776917292 100644 --- a/modules/popt +++ b/modules/popt @@ -3,7 +3,7 @@ modules-$(CONFIG_POPT) += popt popt_version := 1.16 popt_dir := popt-$(popt_version) popt_tar := popt-$(popt_version).tar.gz -popt_url := http://anduin.linuxfromscratch.org/BLFS/popt/$(popt_tar) +popt_url := https://anduin.linuxfromscratch.org/BLFS/popt/$(popt_tar) popt_hash := e728ed296fe9f069a0e005003c3d6b2dde3d9cad453422a10d6558616d304cc8 popt_configure := ./configure \ diff --git a/modules/zlib b/modules/zlib index 3b62e729b..dbdb44e3d 100644 --- a/modules/zlib +++ b/modules/zlib @@ -4,7 +4,7 @@ modules-$(CONFIG_ZLIB) += zlib zlib_version := 1.2.11 zlib_dir := zlib-$(zlib_version) zlib_tar := zlib-$(zlib_version).tar.gz -zlib_url := http://www.zlib.net/$(zlib_tar) +zlib_url := https://www.zlib.net/$(zlib_tar) zlib_hash := c3e5e9fdd5004dcb542feda5ee4f0ff0744628baf8ed2dd5d66f8ca1197cb1a1 zlib_configure := \ From 8b28e4945966b7cad52c712e6c1615df666dd1cf Mon Sep 17 00:00:00 2001 From: AJ Jordan Date: Thu, 13 Dec 2018 16:08:18 -0500 Subject: [PATCH 050/102] Switch popt mirror to Launchpad Launchpad offers HTTPS downloads, whereas other more obvious mirrors (like the one used originally, as well as rpm5.org) do not. Note: it is unclear to whether Launchpad's tarballs will always match the checksum from upstream tarballs. However, at least for 1.16, this condition does indeed seem to hold true. Homebrew, FWIW, lists OpenBSD as a mirror: https://github.com/Homebrew/homebrew-core/blob/master/Formula/popt.rb --- modules/popt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modules/popt b/modules/popt index 776917292..b3b0b045e 100644 --- a/modules/popt +++ b/modules/popt @@ -3,7 +3,7 @@ modules-$(CONFIG_POPT) += popt popt_version := 1.16 popt_dir := popt-$(popt_version) popt_tar := popt-$(popt_version).tar.gz -popt_url := https://anduin.linuxfromscratch.org/BLFS/popt/$(popt_tar) +popt_url := https://launchpad.net/popt/head/$(popt_version)/+download/$(popt_tar) popt_hash := e728ed296fe9f069a0e005003c3d6b2dde3d9cad453422a10d6558616d304cc8 popt_configure := ./configure \ From e274a2c396b008dcdf9dc0ad8edf9680a839a39f Mon Sep 17 00:00:00 2001 From: shamen123 <31340423+shamen123@users.noreply.github.com> Date: Thu, 10 Jan 2019 15:06:40 +0000 Subject: [PATCH 051/102] remove CONFIG_GPG=y Building make BOARD=x230-flash fails due to size. Removal of CONFIG_GPG fixes this. For further details, see https://github.com/osresearch/heads/issues/451 --- boards/x230-flash/x230-flash.config | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/boards/x230-flash/x230-flash.config b/boards/x230-flash/x230-flash.config index 72e1838f4..b10d17aff 100644 --- a/boards/x230-flash/x230-flash.config +++ b/boards/x230-flash/x230-flash.config @@ -3,7 +3,7 @@ BOARD=x230.flash export CONFIG_COREBOOT=y CONFIG_FLASHROM=y -CONFIG_GPG=y +#CONFIG_GPG=y CONFIG_FLASHTOOLS=y CONFIG_PCIUTILS=y #CONFIG_MBEDTLS=y From 7f1288b89c4765bc8ce86ca213bcdbc7535f2084 Mon Sep 17 00:00:00 2001 From: Duncan Guthrie Date: Fri, 5 Jan 2018 21:09:07 +0000 Subject: [PATCH 052/102] Preliminary support for GnuPG2 --- modules/gpg2 | 58 +++++++++++++++++++++++++++++++++++++++++++ modules/libassuan | 24 ++++++++++++++++++ modules/libgcrypt | 24 ++++++++++++++++++ modules/libgpg-error | 26 +++++++++++++++++++ modules/libksba | 24 ++++++++++++++++++ modules/libusb | 13 ++++++---- modules/libusb-compat | 2 ++ modules/npth | 24 ++++++++++++++++++ 8 files changed, 190 insertions(+), 5 deletions(-) create mode 100644 modules/gpg2 create mode 100644 modules/libassuan create mode 100644 modules/libgcrypt create mode 100644 modules/libgpg-error create mode 100644 modules/libksba create mode 100644 modules/npth diff --git a/modules/gpg2 b/modules/gpg2 new file mode 100644 index 000000000..df79d9d5d --- /dev/null +++ b/modules/gpg2 @@ -0,0 +1,58 @@ +modules-$(CONFIG_GPG2) += gpg2 + +gpg2_version := 2.2.4 +gpg2_dir := gnupg-$(gpg2_version) +gpg2_tar := gnupg-$(gpg2_version).tar.bz2 +gpg2_url := https://www.gnupg.org/ftp/gcrypt/gnupg/$(gpg2_tar) +gpg2_hash := 401a3e64780fdfa6d7670de0880aa5c9d589b3db7a7098979d7606cec546f2ec + +# For reproducibility reasons we have to override the exec_prefix +# and datarootdir on the configure line so that the Makefiles will +# be generated with the correct paths, but then re-write them when +# we use the install target so that they will be copied to the correct +# location. +gpg2_configure := ./configure \ + $(CROSS_TOOLS) \ + --host x86_64-linux-musl \ + --with-libusb="$(INSTALL)" \ + --with-libgpg-error-prefix="$(INSTALL)" \ + --with-libgcrypt-prefix="$(INSTALL)" \ + --with-libassuan-prefix="$(INSTALL)" \ + --with-ksba-prefix="$(INSTALL)" \ + --with-npth-prefix="$(INSTALL)" \ + --prefix "/" \ + --enable-scdaemon \ + --enable-ccid-driver \ + --disable-tofu \ + --disable-rpath \ + --disable-regex \ + --disable-doc \ + --disable-bzip2 \ + --disable-asm \ + --disable-exec \ + --disable-photo-viewers \ + --disable-keyserver-helpers \ + --disable-ldap \ + --disable-hkp \ + --disable-finger \ + --disable-dns-srv \ + --disable-dns-cert \ + --disable-regex \ + --disable-nls \ + --disable-all-tests \ + --disable-wks-server \ + --disable-wks-tools \ + --disable-gnutls \ + --disable-dirmgnr \ + +# Run one build to generate the executables with the pre-defined +# exec_prefix and datarootdir, then a second make to install the binaries +# into our actual target location +gpg2_target := $(MAKE_JOBS) \ + && $(MAKE) -C $(build)/$(gpg2_dir) \ + DESTDIR="$(INSTALL)" \ + install + +gpg2_output := g10/gpg + +gpg2_depends := libgpg-error libgcrypt libksba libassuan npth libusb-compat $(musl_dep) diff --git a/modules/libassuan b/modules/libassuan new file mode 100644 index 000000000..0575a97fe --- /dev/null +++ b/modules/libassuan @@ -0,0 +1,24 @@ +modules-$(CONFIG_GPG2) += libassuan +libassuan_version := 2.5.1 +libassuan_dir := libassuan-$(libassuan_version) +libassuan_tar := libassuan-$(libassuan_version).tar.bz2 +libassuan_url := https://gnupg.org/ftp/gcrypt/libassuan/$(libassuan_tar) +libassuan_hash := 47f96c37b4f2aac289f0bc1bacfa8bd8b4b209a488d3d15e2229cb6cc9b26449 + +libassuan_configure := ./configure \ + $(CROSS_TOOLS) \ + --host x86_64-linux-musl \ + --prefix "/" \ + --disable-static \ + --disable-nls \ + --with-libgpg-error-prefix="$(INSTALL)" \ + --disable-asm \ + +libassuan_target := $(MAKE_JOBS) \ + DESTDIR="$(INSTALL)" \ + $(CROSS_TOOLS) \ + install \ + +libassuan_libraries := src/.libs/libassuan.so + +libassuan_depends := libgpg-error $(musl_dep) diff --git a/modules/libgcrypt b/modules/libgcrypt new file mode 100644 index 000000000..aa1e7820d --- /dev/null +++ b/modules/libgcrypt @@ -0,0 +1,24 @@ +modules-$(CONFIG_GPG2) += libgcrypt +libgcrypt_version := 1.8.2 +libgcrypt_dir := libgcrypt-$(libgcrypt_version) +libgcrypt_tar := libgcrypt-$(libgcrypt_version).tar.bz2 +libgcrypt_url := https://gnupg.org/ftp/gcrypt/libgcrypt/$(libgcrypt_tar) +libgcrypt_hash := c8064cae7558144b13ef0eb87093412380efa16c4ee30ad12ecb54886a524c07 + +libgcrypt_configure := ./configure \ + $(CROSS_TOOLS) \ + --host=x86_64-linux-musl \ + --prefix "/" \ + --disable-static \ + --with-libgpg-error-prefix="$(INSTALL)" \ + --disable-asm \ + --disable-nls \ + +libgcrypt_target := $(MAKE_JOBS) \ + DESTDIR="$(INSTALL)" \ + $(CROSS_TOOLS) \ + install \ + +libgcrypt_libraries := src/.libs/libgcrypt.so + +libgcrypt_depends := libgpg-error $(musl_dep) diff --git a/modules/libgpg-error b/modules/libgpg-error new file mode 100644 index 000000000..91974cf58 --- /dev/null +++ b/modules/libgpg-error @@ -0,0 +1,26 @@ +modules-$(CONFIG_GPG2) += libgpg-error +libgpg-error_version := 1.27 +libgpg-error_dir := libgpg-error-$(libgpg-error_version) +libgpg-error_tar := libgpg-error-$(libgpg-error_version).tar.bz2 +libgpg-error_url := https://gnupg.org/ftp/gcrypt/libgpg-error/$(libgpg-error_tar) +libgpg-error_hash := 4f93aac6fecb7da2b92871bb9ee33032be6a87b174f54abf8ddf0911a22d29d2 + +libgpg-error_configure := ./configure \ + $(CROSS_TOOLS) \ + --prefix "/" \ + --host=x86_64-linux-musl \ + --disable-static \ + --disable-nls \ + --disable-languages \ + --disable-doc \ + --disable-tests \ + --disable-asm \ + +libgpg-error_target := $(MAKE_JOBS) \ + DESTDIR="$(INSTALL)" \ + $(CROSS_TOOLS) \ + install \ + +libgpg-error_libraries := src/.libs/libgpg-error.so + +libgpg-error_depends := $(musl_dep) diff --git a/modules/libksba b/modules/libksba new file mode 100644 index 000000000..fa427d33e --- /dev/null +++ b/modules/libksba @@ -0,0 +1,24 @@ +modules-$(CONFIG_GPG2) += libksba +libksba_version := 1.3.5 +libksba_dir := libksba-$(libksba_version) +libksba_tar := libksba-$(libksba_version).tar.bz2 +libksba_url := https://gnupg.org/ftp/gcrypt/libksba/$(libksba_tar) +libksba_hash := 41444fd7a6ff73a79ad9728f985e71c9ba8cd3e5e53358e70d5f066d35c1a340 + +libksba_configure := ./configure \ + $(CROSS_TOOLS) \ + --host x86_64-linux-musl \ + --prefix "/" \ + --disable-static \ + --disable-nls \ + --with-libgpg-error-prefix="$(INSTALL)" \ + --disable-asm \ + +libksba_target := $(MAKE_JOBS) \ + DESTDIR="$(INSTALL)" \ + $(CROSS_TOOLS) \ + install \ + +libksba_libraries := src/.libs/libksba.so + +libksba_depends := libgpg-error $(musl_dep) diff --git a/modules/libusb b/modules/libusb index cd767697b..b7fe959c4 100644 --- a/modules/libusb +++ b/modules/libusb @@ -1,5 +1,6 @@ # GPG with Yubikey support requires libusb modules-$(CONFIG_GPG) += libusb +modules-$(CONFIG_GPG2) += libusb libusb_version := 1.0.21 libusb_dir := libusb-$(libusb_version) @@ -7,15 +8,17 @@ libusb_tar := libusb-$(libusb_version).tar.bz2 libusb_url := https://downloads.sourceforge.net/project/libusb/libusb-1.0/libusb-$(libusb_version)/$(libusb_tar) libusb_hash := 7dce9cce9a81194b7065ee912bcd55eeffebab694ea403ffb91b67db66b1824b -libusb_configure := ./configure \ - $(CROSS_TOOLS) \ - --host i386-elf-linux \ - --prefix "/" \ - --disable-udev \ +libusb_configure := ./configure\ + $(CROSS_TOOLS)\ + --host i386-elf-linux\ + --prefix "/"\ + --disable-udev\ + --disable-tests\ # Run one build to generate the executables with the pre-defined # exec_prefix and datarootdir, then a second make to install the binaries # into our actual target location + libusb_target := $(MAKE_JOBS) \ DESTDIR="$(INSTALL)" \ $(CROSS_TOOLS) \ diff --git a/modules/libusb-compat b/modules/libusb-compat index c09101399..f95854ee1 100644 --- a/modules/libusb-compat +++ b/modules/libusb-compat @@ -1,7 +1,9 @@ # GPG 1.4.21 uses an old version of libusb, which # is emulated with the compatibility library. # This is a bit of a hack to set it up. + modules-$(CONFIG_GPG) += libusb-compat +modules-$(CONFIG_GPG2) += libusb-compat libusb-compat_version := 0.1.5 libusb-compat_dir := libusb-compat-$(libusb-compat_version) diff --git a/modules/npth b/modules/npth new file mode 100644 index 000000000..4ba238a3b --- /dev/null +++ b/modules/npth @@ -0,0 +1,24 @@ +modules-$(CONFIG_GPG2) += npth +npth_version := 1.5 +npth_dir := npth-$(npth_version) +npth_tar := npth-$(npth_version).tar.bz2 +npth_url := https://gnupg.org/ftp/gcrypt/npth/$(npth_tar) +npth_hash := 294a690c1f537b92ed829d867bee537e46be93fbd60b16c04630fbbfcd9db3c2 + +npth_configure := ./configure \ + $(CROSS_TOOLS) \ + --host x86_64-linux-musl \ + --prefix "/" \ + --disable-static \ + --disable-nls \ + --with-libgpg-error-prefix="$(INSTALL)" \ + --disable-asm \ + +npth_target := $(MAKE_JOBS) \ + DESTDIR="$(INSTALL)" \ + $(CROSS_TOOLS) \ + install \ + +npth_libraries := src/.libs/libnpth.so + +npth_depends := libgpg-error $(musl_dep) From c1c615e6775588a9ab039fc19a6cd9c412f251cc Mon Sep 17 00:00:00 2001 From: Trammell hudson Date: Tue, 18 Sep 2018 05:12:47 -0400 Subject: [PATCH 053/102] copy gpg2 executables and pass in the libusb include path --- Makefile | 1 + modules/gpg2 | 1 + 2 files changed, 2 insertions(+) diff --git a/Makefile b/Makefile index cad491c3a..2184e5fbb 100644 --- a/Makefile +++ b/Makefile @@ -393,6 +393,7 @@ bin_modules-$(CONFIG_PCIUTILS) += pciutils bin_modules-$(CONFIG_FLASHROM) += flashrom bin_modules-$(CONFIG_CRYPTSETUP) += cryptsetup bin_modules-$(CONFIG_GPG) += gpg +bin_modules-$(CONFIG_GPG2) += gpg2 bin_modules-$(CONFIG_LVM2) += lvm2 bin_modules-$(CONFIG_DROPBEAR) += dropbear bin_modules-$(CONFIG_FLASHTOOLS) += flashtools diff --git a/modules/gpg2 b/modules/gpg2 index df79d9d5d..96fe3b034 100644 --- a/modules/gpg2 +++ b/modules/gpg2 @@ -13,6 +13,7 @@ gpg2_hash := 401a3e64780fdfa6d7670de0880aa5c9d589b3db7a7098979d7606cec546f2ec # location. gpg2_configure := ./configure \ $(CROSS_TOOLS) \ + CPPFLAGS="-I$(INSTALL)/include/libusb-1.0" \ --host x86_64-linux-musl \ --with-libusb="$(INSTALL)" \ --with-libgpg-error-prefix="$(INSTALL)" \ From d61587c17985248ea8dc6a6385658539fcf3b44a Mon Sep 17 00:00:00 2001 From: Trammell hudson Date: Tue, 18 Sep 2018 05:14:05 -0400 Subject: [PATCH 054/102] switch to gpg2 for qemu targets --- boards/qemu-coreboot/qemu-coreboot.config | 2 +- boards/qemu-linuxboot/qemu-linuxboot.config | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/boards/qemu-coreboot/qemu-coreboot.config b/boards/qemu-coreboot/qemu-coreboot.config index 9427a2ac3..0f1a592ac 100644 --- a/boards/qemu-coreboot/qemu-coreboot.config +++ b/boards/qemu-coreboot/qemu-coreboot.config @@ -17,7 +17,7 @@ CONFIG_FLASHROM=y CONFIG_PCIUTILS=y CONFIG_UTIL_LINUX=y CONFIG_CRYPTSETUP=y -CONFIG_GPG=y +CONFIG_GPG2=y CONFIG_LVM2=y CONFIG_MBEDTLS=y CONFIG_DROPBEAR=y diff --git a/boards/qemu-linuxboot/qemu-linuxboot.config b/boards/qemu-linuxboot/qemu-linuxboot.config index 9b2d8644c..730ce633d 100644 --- a/boards/qemu-linuxboot/qemu-linuxboot.config +++ b/boards/qemu-linuxboot/qemu-linuxboot.config @@ -18,7 +18,7 @@ endif CONFIG_FLASHROM=y CONFIG_FLASHTOOLS=y -CONFIG_GPG=y +CONFIG_GPG2=y CONFIG_KEXEC=y CONFIG_UTIL_LINUX=y CONFIG_DROPBEAR=y From b1736d7cb3f37a64f1575b4aa62f9de49489f6ba Mon Sep 17 00:00:00 2001 From: Trammell hudson Date: Tue, 18 Sep 2018 05:32:46 -0400 Subject: [PATCH 055/102] use full version names on output libraries --- modules/libassuan | 2 +- modules/libgcrypt | 2 +- modules/libgpg-error | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/modules/libassuan b/modules/libassuan index 0575a97fe..3c4e319aa 100644 --- a/modules/libassuan +++ b/modules/libassuan @@ -19,6 +19,6 @@ libassuan_target := $(MAKE_JOBS) \ $(CROSS_TOOLS) \ install \ -libassuan_libraries := src/.libs/libassuan.so +libassuan_libraries := src/.libs/libassuan.so.0 libassuan_depends := libgpg-error $(musl_dep) diff --git a/modules/libgcrypt b/modules/libgcrypt index aa1e7820d..ad7728b81 100644 --- a/modules/libgcrypt +++ b/modules/libgcrypt @@ -19,6 +19,6 @@ libgcrypt_target := $(MAKE_JOBS) \ $(CROSS_TOOLS) \ install \ -libgcrypt_libraries := src/.libs/libgcrypt.so +libgcrypt_libraries := src/.libs/libgcrypt.so.20 libgcrypt_depends := libgpg-error $(musl_dep) diff --git a/modules/libgpg-error b/modules/libgpg-error index 91974cf58..8a58c22b1 100644 --- a/modules/libgpg-error +++ b/modules/libgpg-error @@ -21,6 +21,6 @@ libgpg-error_target := $(MAKE_JOBS) \ $(CROSS_TOOLS) \ install \ -libgpg-error_libraries := src/.libs/libgpg-error.so +libgpg-error_libraries := src/.libs/libgpg-error.so.0 libgpg-error_depends := $(musl_dep) From b89ed83af67e1ee7edc973ecbe217ad2da44cd56 Mon Sep 17 00:00:00 2001 From: Trammell hudson Date: Wed, 19 Sep 2018 06:32:00 -0400 Subject: [PATCH 056/102] enable Unix Domain sockets for gpg-agent --- config/linux-kgpe-d16.config | 1 + config/linux-librem13v2.config | 1 + config/linux-linuxboot.config | 1 + config/linux-x230.config | 1 + 4 files changed, 4 insertions(+) diff --git a/config/linux-kgpe-d16.config b/config/linux-kgpe-d16.config index 2c451e224..c925feb6a 100644 --- a/config/linux-kgpe-d16.config +++ b/config/linux-kgpe-d16.config @@ -64,6 +64,7 @@ CONFIG_PCI_PRI=y # CONFIG_COREDUMP is not set CONFIG_NET=y CONFIG_PACKET=y +CONFIG_UNIX=y CONFIG_INET=y CONFIG_SYN_COOKIES=y # CONFIG_INET_XFRM_MODE_TRANSPORT is not set diff --git a/config/linux-librem13v2.config b/config/linux-librem13v2.config index ebb1dd566..f107eb102 100644 --- a/config/linux-librem13v2.config +++ b/config/linux-librem13v2.config @@ -63,6 +63,7 @@ CONFIG_PCI_PRI=y # CONFIG_COREDUMP is not set CONFIG_NET=y CONFIG_PACKET=y +CONFIG_UNIX=y CONFIG_INET=y CONFIG_SYN_COOKIES=y # CONFIG_INET_XFRM_MODE_TRANSPORT is not set diff --git a/config/linux-linuxboot.config b/config/linux-linuxboot.config index 1074b6ac5..bd692577d 100644 --- a/config/linux-linuxboot.config +++ b/config/linux-linuxboot.config @@ -84,6 +84,7 @@ CONFIG_PCI_PRI=y CONFIG_IA32_EMULATION=y CONFIG_NET=y CONFIG_PACKET=y +CONFIG_UNIX=y CONFIG_INET=y CONFIG_SYN_COOKIES=y # CONFIG_INET_XFRM_MODE_TRANSPORT is not set diff --git a/config/linux-x230.config b/config/linux-x230.config index 3f13d3278..ff9d94add 100644 --- a/config/linux-x230.config +++ b/config/linux-x230.config @@ -64,6 +64,7 @@ CONFIG_PCI_PRI=y # CONFIG_COREDUMP is not set CONFIG_NET=y CONFIG_PACKET=y +CONFIG_UNIX=y CONFIG_INET=y CONFIG_SYN_COOKIES=y # CONFIG_INET_XFRM_MODE_TRANSPORT is not set From 49269f2bb4a5c6668606e087418b1477d985c386 Mon Sep 17 00:00:00 2001 From: tlaurion Date: Wed, 19 Sep 2018 06:33:18 -0400 Subject: [PATCH 057/102] gpg2 library fixes --- modules/gpg2 | 4 ++-- modules/libksba | 2 +- modules/npth | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/modules/gpg2 b/modules/gpg2 index 96fe3b034..ea3ca07ee 100644 --- a/modules/gpg2 +++ b/modules/gpg2 @@ -44,7 +44,7 @@ gpg2_configure := ./configure \ --disable-wks-server \ --disable-wks-tools \ --disable-gnutls \ - --disable-dirmgnr \ + --disable-dirmngr \ # Run one build to generate the executables with the pre-defined # exec_prefix and datarootdir, then a second make to install the binaries @@ -54,6 +54,6 @@ gpg2_target := $(MAKE_JOBS) \ DESTDIR="$(INSTALL)" \ install -gpg2_output := g10/gpg +gpg2_output := g10/gpg agent/gpg-agent scd/scdaemon gpg2_depends := libgpg-error libgcrypt libksba libassuan npth libusb-compat $(musl_dep) diff --git a/modules/libksba b/modules/libksba index fa427d33e..d35291338 100644 --- a/modules/libksba +++ b/modules/libksba @@ -19,6 +19,6 @@ libksba_target := $(MAKE_JOBS) \ $(CROSS_TOOLS) \ install \ -libksba_libraries := src/.libs/libksba.so +libksba_libraries := src/.libs/libksba.so.8 libksba_depends := libgpg-error $(musl_dep) diff --git a/modules/npth b/modules/npth index 4ba238a3b..70708cc65 100644 --- a/modules/npth +++ b/modules/npth @@ -19,6 +19,6 @@ npth_target := $(MAKE_JOBS) \ $(CROSS_TOOLS) \ install \ -npth_libraries := src/.libs/libnpth.so +npth_libraries := src/.libs/libnpth.so.0 npth_depends := libgpg-error $(musl_dep) From c261907ee67575f026d89bad594352be219b7aca Mon Sep 17 00:00:00 2001 From: Trammell hudson Date: Wed, 19 Sep 2018 06:58:08 -0400 Subject: [PATCH 058/102] gpg2 pinentry program is required for passwords or PINs --- Makefile | 1 + modules/pinentry | 39 +++++++++++++++++++++++++++++++++++++++ 2 files changed, 40 insertions(+) create mode 100644 modules/pinentry diff --git a/Makefile b/Makefile index 2184e5fbb..910830dd3 100644 --- a/Makefile +++ b/Makefile @@ -394,6 +394,7 @@ bin_modules-$(CONFIG_FLASHROM) += flashrom bin_modules-$(CONFIG_CRYPTSETUP) += cryptsetup bin_modules-$(CONFIG_GPG) += gpg bin_modules-$(CONFIG_GPG2) += gpg2 +bin_modules-$(CONFIG_PINENTRY) += pinetry bin_modules-$(CONFIG_LVM2) += lvm2 bin_modules-$(CONFIG_DROPBEAR) += dropbear bin_modules-$(CONFIG_FLASHTOOLS) += flashtools diff --git a/modules/pinentry b/modules/pinentry new file mode 100644 index 000000000..ed4da471a --- /dev/null +++ b/modules/pinentry @@ -0,0 +1,39 @@ +# pinentry is required for gpg2 to be able to read user passwords +CONFIG_PINENTRY ?= $(CONFIG_GPG2) +modules-$(CONFIG_PINENTRY) += pinentry + +pinentry_version := 1.1.0 +pinentry_dir := pinentry-$(pinentry_version) +pinentry_tar := pinentry-$(pinentry_version).tar.bz2 +pinentry_url := https://www.gnupg.org/ftp/gcrypt/pinentry/$(pinentry_tar) +pinentry_hash := 68076686fa724a290ea49cdf0d1c0c1500907d1b759a3bcbfbec0293e8f56570 + +# For reproducibility reasons we have to override the exec_prefix +# and datarootdir on the configure line so that the Makefiles will +# be generated with the correct paths, but then re-write them when +# we use the install target so that they will be copied to the correct +# location. +pinentry_configure := ./configure \ + $(CROSS_TOOLS) \ + --host x86_64-linux-musl \ + --prefix "/" \ + --enable-pinentry-tty \ + --disable-pinentry-curses \ + --disable-pinentry-qt5 \ + --disable-pinentry-fltk \ + --disable-pinentry-emacs \ + --with-libgpg-error-prefix="$(INSTALL)" \ + --with-libassuan-prefix="$(INSTALL)" \ + +# Run one build to generate the executables with the pre-defined +# exec_prefix and datarootdir, then a second make to install the binaries +# into our actual target location +pinentry_target := $(MAKE_JOBS) \ + && $(MAKE) -C $(build)/$(pinentry_dir) \ + DESTDIR="$(INSTALL)" \ + install \ + && cp $(build)/$(pinentry_dir)/tty/pinentry-tty $(build)/$(pinentry_dir)/tty/pinentry + +pinentry_output := tty/pinentry + +pinentry_depends := libgpg-error libassuan $(musl_dep) From 82701fb10fb88bb48827dd783448d426f234e4b6 Mon Sep 17 00:00:00 2001 From: Trammell hudson Date: Wed, 19 Sep 2018 07:21:02 -0400 Subject: [PATCH 059/102] typo on pinentry --- Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Makefile b/Makefile index 910830dd3..912a9b53a 100644 --- a/Makefile +++ b/Makefile @@ -394,7 +394,7 @@ bin_modules-$(CONFIG_FLASHROM) += flashrom bin_modules-$(CONFIG_CRYPTSETUP) += cryptsetup bin_modules-$(CONFIG_GPG) += gpg bin_modules-$(CONFIG_GPG2) += gpg2 -bin_modules-$(CONFIG_PINENTRY) += pinetry +bin_modules-$(CONFIG_PINENTRY) += pinentry bin_modules-$(CONFIG_LVM2) += lvm2 bin_modules-$(CONFIG_DROPBEAR) += dropbear bin_modules-$(CONFIG_FLASHTOOLS) += flashtools From 8ba3c3340287d3e501418e91a98a579ca559ed83 Mon Sep 17 00:00:00 2001 From: Thierry Laurion Date: Thu, 4 Oct 2018 21:32:04 -0400 Subject: [PATCH 060/102] required changes to apply on top of osresearch/gpg2 for gpg2 to actually work, tools and libs updated to latest versions --- boards/x230/x230.config | 2 +- initrd/.gnupg/gpg-agent.conf | 1 + modules/gpg2 | 4 ++-- modules/libgcrypt | 4 ++-- modules/libgpg-error | 4 ++-- modules/npth | 4 ++-- modules/pinentry | 1 + 7 files changed, 11 insertions(+), 9 deletions(-) create mode 100644 initrd/.gnupg/gpg-agent.conf diff --git a/boards/x230/x230.config b/boards/x230/x230.config index e479f5a1b..5a4d56a41 100644 --- a/boards/x230/x230.config +++ b/boards/x230/x230.config @@ -6,7 +6,7 @@ CONFIG_LINUX_CONFIG=config/linux-x230.config CONFIG_CRYPTSETUP=y CONFIG_FLASHROM=y CONFIG_FLASHTOOLS=y -CONFIG_GPG=y +CONFIG_GPG2=y CONFIG_KEXEC=y CONFIG_UTIL_LINUX=y CONFIG_LVM2=y diff --git a/initrd/.gnupg/gpg-agent.conf b/initrd/.gnupg/gpg-agent.conf new file mode 100644 index 000000000..db6595868 --- /dev/null +++ b/initrd/.gnupg/gpg-agent.conf @@ -0,0 +1 @@ +scdaemon-program /bin/scdaemon diff --git a/modules/gpg2 b/modules/gpg2 index ea3ca07ee..a386093c9 100644 --- a/modules/gpg2 +++ b/modules/gpg2 @@ -1,10 +1,10 @@ modules-$(CONFIG_GPG2) += gpg2 -gpg2_version := 2.2.4 +gpg2_version := 2.2.10 gpg2_dir := gnupg-$(gpg2_version) gpg2_tar := gnupg-$(gpg2_version).tar.bz2 gpg2_url := https://www.gnupg.org/ftp/gcrypt/gnupg/$(gpg2_tar) -gpg2_hash := 401a3e64780fdfa6d7670de0880aa5c9d589b3db7a7098979d7606cec546f2ec +gpg2_hash := 799dd37a86a1448732e339bd20440f4f5ee6e69755f6fd7a73ee8af30840c915 # For reproducibility reasons we have to override the exec_prefix # and datarootdir on the configure line so that the Makefiles will diff --git a/modules/libgcrypt b/modules/libgcrypt index ad7728b81..aa7e1ef8e 100644 --- a/modules/libgcrypt +++ b/modules/libgcrypt @@ -1,9 +1,9 @@ modules-$(CONFIG_GPG2) += libgcrypt -libgcrypt_version := 1.8.2 +libgcrypt_version := 1.8.3 libgcrypt_dir := libgcrypt-$(libgcrypt_version) libgcrypt_tar := libgcrypt-$(libgcrypt_version).tar.bz2 libgcrypt_url := https://gnupg.org/ftp/gcrypt/libgcrypt/$(libgcrypt_tar) -libgcrypt_hash := c8064cae7558144b13ef0eb87093412380efa16c4ee30ad12ecb54886a524c07 +libgcrypt_hash := 66ec90be036747602f2b48f98312361a9180c97c68a690a5f376fa0f67d0af7c libgcrypt_configure := ./configure \ $(CROSS_TOOLS) \ diff --git a/modules/libgpg-error b/modules/libgpg-error index 8a58c22b1..752e11aad 100644 --- a/modules/libgpg-error +++ b/modules/libgpg-error @@ -1,9 +1,9 @@ modules-$(CONFIG_GPG2) += libgpg-error -libgpg-error_version := 1.27 +libgpg-error_version := 1.32 libgpg-error_dir := libgpg-error-$(libgpg-error_version) libgpg-error_tar := libgpg-error-$(libgpg-error_version).tar.bz2 libgpg-error_url := https://gnupg.org/ftp/gcrypt/libgpg-error/$(libgpg-error_tar) -libgpg-error_hash := 4f93aac6fecb7da2b92871bb9ee33032be6a87b174f54abf8ddf0911a22d29d2 +libgpg-error_hash := c345c5e73cc2332f8d50db84a2280abfb1d8f6d4f1858b9daa30404db44540ca libgpg-error_configure := ./configure \ $(CROSS_TOOLS) \ diff --git a/modules/npth b/modules/npth index 70708cc65..e0f30c69e 100644 --- a/modules/npth +++ b/modules/npth @@ -1,9 +1,9 @@ modules-$(CONFIG_GPG2) += npth -npth_version := 1.5 +npth_version := 1.6 npth_dir := npth-$(npth_version) npth_tar := npth-$(npth_version).tar.bz2 npth_url := https://gnupg.org/ftp/gcrypt/npth/$(npth_tar) -npth_hash := 294a690c1f537b92ed829d867bee537e46be93fbd60b16c04630fbbfcd9db3c2 +npth_hash := 1393abd9adcf0762d34798dc34fdcf4d0d22a8410721e76f1e3afcd1daa4e2d1 npth_configure := ./configure \ $(CROSS_TOOLS) \ diff --git a/modules/pinentry b/modules/pinentry index ed4da471a..691f63c36 100644 --- a/modules/pinentry +++ b/modules/pinentry @@ -22,6 +22,7 @@ pinentry_configure := ./configure \ --disable-pinentry-qt5 \ --disable-pinentry-fltk \ --disable-pinentry-emacs \ + --disable-fallback-curses \ --with-libgpg-error-prefix="$(INSTALL)" \ --with-libassuan-prefix="$(INSTALL)" \ From e5a739e54cdda3c2fcc805a971b8ab3eea131c27 Mon Sep 17 00:00:00 2001 From: Trammell Hudson Date: Wed, 17 Oct 2018 17:42:43 -0400 Subject: [PATCH 061/102] use /bin for libexecdir and disable curses pinentry --- modules/gpg2 | 1 + modules/pinentry | 1 + 2 files changed, 2 insertions(+) diff --git a/modules/gpg2 b/modules/gpg2 index a386093c9..318a4cd11 100644 --- a/modules/gpg2 +++ b/modules/gpg2 @@ -22,6 +22,7 @@ gpg2_configure := ./configure \ --with-ksba-prefix="$(INSTALL)" \ --with-npth-prefix="$(INSTALL)" \ --prefix "/" \ + --libexecdir "/bin" \ --enable-scdaemon \ --enable-ccid-driver \ --disable-tofu \ diff --git a/modules/pinentry b/modules/pinentry index 691f63c36..e6e440dd7 100644 --- a/modules/pinentry +++ b/modules/pinentry @@ -18,6 +18,7 @@ pinentry_configure := ./configure \ --host x86_64-linux-musl \ --prefix "/" \ --enable-pinentry-tty \ + --disable-fallback-curses \ --disable-pinentry-curses \ --disable-pinentry-qt5 \ --disable-pinentry-fltk \ From 6335ece90244452bb26c477556c34bdb2d96eee2 Mon Sep 17 00:00:00 2001 From: Thierry Laurion Date: Wed, 14 Nov 2018 19:39:11 -0500 Subject: [PATCH 062/102] gpg2 pubring extension change from gpg to kbx --- initrd/bin/flash-gui.sh | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/initrd/bin/flash-gui.sh b/initrd/bin/flash-gui.sh index 191d977b0..7a7ec46a5 100755 --- a/initrd/bin/flash-gui.sh +++ b/initrd/bin/flash-gui.sh @@ -139,10 +139,10 @@ while true; do cat $PUBKEY | gpg --import cp $ROM /tmp/gpg-gui.rom - if (cbfs -o /tmp/gpg-gui.rom -l | grep -q "heads/initrd/.gnupg/pubring.gpg") then - cbfs -o /tmp/gpg-gui.rom -d "heads/initrd/.gnupg/pubring.gpg" + if (cbfs -o /tmp/gpg-gui.rom -l | grep -q "heads/initrd/.gnupg/pubring.kbx") then + cbfs -o /tmp/gpg-gui.rom -d "heads/initrd/.gnupg/pubring.kbx" fi - cbfs -o /tmp/gpg-gui.rom -a "heads/initrd/.gnupg/pubring.gpg" -f /.gnupg/pubring.gpg + cbfs -o /tmp/gpg-gui.rom -a "heads/initrd/.gnupg/pubring.kbx" -f /.gnupg/pubring.kbx if (cbfs -o /tmp/gpg-gui.rom -l | grep -q "heads/initrd/.gnupg/trustdb.gpg") then cbfs -o /tmp/gpg-gui.rom -d "heads/initrd/.gnupg/trustdb.gpg" @@ -180,10 +180,10 @@ while true; do fi cat $PUBKEY | gpg --import - if (cbfs -o /tmp/gpg-gui.rom -l | grep -q "heads/initrd/.gnupg/pubring.gpg") then - cbfs -o /tmp/gpg-gui.rom -d "heads/initrd/.gnupg/pubring.gpg" + if (cbfs -o /tmp/gpg-gui.rom -l | grep -q "heads/initrd/.gnupg/pubring.kbx") then + cbfs -o /tmp/gpg-gui.rom -d "heads/initrd/.gnupg/pubring.kbx" fi - cbfs -o /tmp/gpg-gui.rom -a "heads/initrd/.gnupg/pubring.gpg" -f /.gnupg/pubring.gpg + cbfs -o /tmp/gpg-gui.rom -a "heads/initrd/.gnupg/pubring.kbx" -f /.gnupg/pubring.kbx if (cbfs -o /tmp/gpg-gui.rom -l | grep -q "heads/initrd/.gnupg/trustdb.gpg") then cbfs -o /tmp/gpg-gui.rom -d "heads/initrd/.gnupg/trustdb.gpg" From 44d566a72ac51d25692928ad3f35c9b553848056 Mon Sep 17 00:00:00 2001 From: Thierry Laurion Date: Wed, 14 Nov 2018 19:41:02 -0500 Subject: [PATCH 063/102] pinentry-tty path needs to be known from gpg-agent --- initrd/.gnupg/gpg-agent.conf | 2 ++ modules/pinentry | 2 +- 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/initrd/.gnupg/gpg-agent.conf b/initrd/.gnupg/gpg-agent.conf index db6595868..eba090d1d 100644 --- a/initrd/.gnupg/gpg-agent.conf +++ b/initrd/.gnupg/gpg-agent.conf @@ -1 +1,3 @@ scdaemon-program /bin/scdaemon +pinentry-program /bin/pinentry-tty +daemon diff --git a/modules/pinentry b/modules/pinentry index e6e440dd7..c59b70430 100644 --- a/modules/pinentry +++ b/modules/pinentry @@ -36,6 +36,6 @@ pinentry_target := $(MAKE_JOBS) \ install \ && cp $(build)/$(pinentry_dir)/tty/pinentry-tty $(build)/$(pinentry_dir)/tty/pinentry -pinentry_output := tty/pinentry +pinentry_output := tty/pinentry-tty pinentry_depends := libgpg-error libassuan $(musl_dep) From c77b560300b196b9dee8c1c72333bb4ddb9b5ee0 Mon Sep 17 00:00:00 2001 From: Kyle Rankin Date: Mon, 28 Jan 2019 09:26:23 -0800 Subject: [PATCH 064/102] Update ME repository links/filenames/hashes The current links to the ME blob have expired. This updates the links along with the resulting file names and hashes. --- blobs/librem_skl/get_blobs.sh | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/blobs/librem_skl/get_blobs.sh b/blobs/librem_skl/get_blobs.sh index fd44002c3..c94afd76f 100755 --- a/blobs/librem_skl/get_blobs.sh +++ b/blobs/librem_skl/get_blobs.sh @@ -26,10 +26,10 @@ SKL_ME_PATCH_SHA="49019f89206d6371b1377cf738426c3b0ac60c4b1bb89d5d5de00481e7e4fe # Link found on : http://www.win-raid.com/t832f39-Intel-Engine-Firmware-Repositories.html # Update link if it changes and becomes invalid. -SKL_ME_RAR_URL="https://mega.nz/#!DNdDVQ7I!hronBMVN8m82JciiT6UQwtwh-LVlHXIo-NzTB0324rk" -SKL_ME_FILENAME="11.0.18.1002_CON_LP_C0_NPDM_PRD_RGN.bin" -SKL_ME_FULL_FILENAME="Intel CSME 11.0 Firmware Repository Pack r52/$SKL_ME_FILENAME" -SKL_ME_RAR_SHA="28b7c31ae6888623d2271f0c74cb7bbca55a56af73b26f9796742467a841441a" +SKL_ME_RAR_URL="https://mega.nz/#!2ElyFQDT!cC0gTlH8rB9EWD4MGX0mVElT94BauqFn-dBKuoEselc" +SKL_ME_FILENAME="11.0.18.1002_CON_LP_C_NPDM_PRD_RGN.bin" +SKL_ME_FULL_FILENAME="Intel CSME 11.0 Firmware Repository Pack r53/$SKL_ME_FILENAME" +SKL_ME_RAR_SHA="1450d7ea985fbcf0ea79ba61bdc71ed3c5de52a6a82f14c07120b6b321e97352" # Needed to download SKL_ME_RAR_URL MEGADOWN_URL="https://github.com/tonikelope/megadown.git" From fb3e2066b8ee33b29c3fbc387a1b707956c646f3 Mon Sep 17 00:00:00 2001 From: Thierry Laurion Date: Wed, 14 Nov 2018 19:45:44 -0500 Subject: [PATCH 065/102] GPG_TTY is forced to /dev/console under init. Ash console is never called; trying to get console tty from the tty returns "no console". NEEDs BETTER FIX. --- initrd/init | 3 +++ 1 file changed, 3 insertions(+) diff --git a/initrd/init b/initrd/init index d489f6ae5..305d05af7 100755 --- a/initrd/init +++ b/initrd/init @@ -5,6 +5,9 @@ echo "hello world" > /dev/ttyprintk # Setup our path export PATH=/sbin:/bin:/usr/sbin:/usr/bin:/usr/local/bin +#export GPG_TTY STATICALLY (NEED TO FIX) +export GPG_TTY=/dev/console + # This is the very first script invoked by the Linux kernel and is # running out of the ram disk. There are no fileysstems mounted. # It is important to have a way to invoke a recovery shell in case From 46ddc20f74b84d20b3d87c2b0d64bfe7bc0cfff4 Mon Sep 17 00:00:00 2001 From: Thierry Laurion Date: Wed, 14 Nov 2018 19:46:46 -0500 Subject: [PATCH 066/102] instruct gpg to use gpg-agent. --- initrd/.gnupg/gpg.conf | 1 + 1 file changed, 1 insertion(+) create mode 100644 initrd/.gnupg/gpg.conf diff --git a/initrd/.gnupg/gpg.conf b/initrd/.gnupg/gpg.conf new file mode 100644 index 000000000..d53cb13d6 --- /dev/null +++ b/initrd/.gnupg/gpg.conf @@ -0,0 +1 @@ +use-agent From 75c11481f689c51c2dbf07beb4715bfb5989241b Mon Sep 17 00:00:00 2001 From: Thierry Laurion Date: Wed, 14 Nov 2018 19:47:24 -0500 Subject: [PATCH 067/102] Port gpg1 patch to gpg2 to force crosscompiling and output to stderr. --- patches/gpg2-2.2.10.patch | 27 +++++++++++++++++++++++++++ 1 file changed, 27 insertions(+) create mode 100644 patches/gpg2-2.2.10.patch diff --git a/patches/gpg2-2.2.10.patch b/patches/gpg2-2.2.10.patch new file mode 100644 index 000000000..ed940b1b3 --- /dev/null +++ b/patches/gpg2-2.2.10.patch @@ -0,0 +1,27 @@ +diff -u --recursive /home/tlaurion/build/clean/gnupg-2.2.10/configure gnupg-2.2.10/configure +--- /home/tlaurion/build/clean/gnupg-2.2.10/configure 2016-08-17 09:20:25.000000000 -0400 ++++ gnupg-2.2.10/configure 2018-01-20 16:55:14.502067084 -0500 +@@ -572,7 +572,7 @@ + ac_clean_files= + ac_config_libobj_dir=. + LIBOBJS= +-cross_compiling=no ++cross_compiling=yes + subdirs= + MFLAGS= + MAKEFLAGS= +diff -u --recursive gnupg-2.2.10/common/ttyio.c gnupg-2.2.10/common/ttyio.c.mod +--- gnupg-2.2.10/common/ttyio.c 2017-08-28 06:22:54.000000000 -0400 ++++ gnupg-2.2.10/common/ttyio.c.mod 2018-09-18 23:00:07.386250017 -0400 +@@ -190,7 +190,9 @@ + #elif defined (HAVE_W32CE_SYSTEM) + ttyfp = stderr; + #else +- ttyfp = batchmode? stderr : fopen (tty_get_ttyname (), "r+"); ++ //ttyfp = batchmode? stderr : fopen( tty_get_ttyname (), "r+"); ++ ttyfp = stderr; ++ + if( !ttyfp ) { + log_error("cannot open '%s': %s\n", tty_get_ttyname (), + strerror(errno) ); + From ca3a5fd2eb57090dbce1d94a67ace3258c0b829f Mon Sep 17 00:00:00 2001 From: Jason Andryuk Date: Sat, 1 Dec 2018 08:37:34 -0500 Subject: [PATCH 068/102] Set GPG_TTY before calling gpg in key-init gpg2 needs GPG_TTY set to function properly. We set it in /init so it is inherited by all children. The call to $(tty) must be after /dev and (preferably) /dev/pts are mounted. Signed-off-by: Jason Andryuk --- initrd/init | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/initrd/init b/initrd/init index 305d05af7..6775f9795 100755 --- a/initrd/init +++ b/initrd/init @@ -5,9 +5,6 @@ echo "hello world" > /dev/ttyprintk # Setup our path export PATH=/sbin:/bin:/usr/sbin:/usr/bin:/usr/local/bin -#export GPG_TTY STATICALLY (NEED TO FIX) -export GPG_TTY=/dev/console - # This is the very first script invoked by the Linux kernel and is # running out of the ram disk. There are no fileysstems mounted. # It is important to have a way to invoke a recovery shell in case @@ -60,6 +57,10 @@ fi if [ "$CONFIG_LINUXBOOT" = "y" ]; then /bin/uefi-init fi + +# Set GPG_TTY before calling gpg in key-init +export GPG_TTY=$(tty) + /bin/key-init # Setup recovery serial shell From 92c547c0d41294acb1fd3d90b7dd27a677d8bf81 Mon Sep 17 00:00:00 2001 From: Itay Grudev Date: Fri, 4 Jan 2019 09:21:44 +0200 Subject: [PATCH 069/102] Enabled GPG2 in the Librem board config --- boards/librem13v2/librem13v2.config | 1 + boards/librem15v3/librem15v3.config | 1 + 2 files changed, 2 insertions(+) diff --git a/boards/librem13v2/librem13v2.config b/boards/librem13v2/librem13v2.config index 699d591b8..92b2e8c38 100644 --- a/boards/librem13v2/librem13v2.config +++ b/boards/librem13v2/librem13v2.config @@ -7,6 +7,7 @@ CONFIG_CRYPTSETUP=y CONFIG_FLASHROM=y CONFIG_FLASHTOOLS=y CONFIG_GPG=y +CONFIG_GPG2=y CONFIG_KEXEC=y CONFIG_UTIL_LINUX=y CONFIG_LVM2=y diff --git a/boards/librem15v3/librem15v3.config b/boards/librem15v3/librem15v3.config index 61c17042c..8387d9cc9 100644 --- a/boards/librem15v3/librem15v3.config +++ b/boards/librem15v3/librem15v3.config @@ -9,6 +9,7 @@ CONFIG_CRYPTSETUP=y CONFIG_FLASHROM=y CONFIG_FLASHTOOLS=y CONFIG_GPG=y +CONFIG_GPG2=y CONFIG_KEXEC=y CONFIG_UTIL_LINUX=y CONFIG_LVM2=y From 3bc79495bb078ff1d9d83171ba40abcb8311d6f9 Mon Sep 17 00:00:00 2001 From: Itay Grudev Date: Fri, 4 Jan 2019 09:33:13 +0200 Subject: [PATCH 070/102] Disabled libsecret support in the pinentry module --- modules/pinentry | 1 + 1 file changed, 1 insertion(+) diff --git a/modules/pinentry b/modules/pinentry index c59b70430..7de67e203 100644 --- a/modules/pinentry +++ b/modules/pinentry @@ -18,6 +18,7 @@ pinentry_configure := ./configure \ --host x86_64-linux-musl \ --prefix "/" \ --enable-pinentry-tty \ + --disable-libsecret \ --disable-fallback-curses \ --disable-pinentry-curses \ --disable-pinentry-qt5 \ From 4f75da7ea79f2fb3ea73f215a062388a29f476a7 Mon Sep 17 00:00:00 2001 From: Thierry Laurion Date: Sat, 26 Jan 2019 12:16:53 -0500 Subject: [PATCH 071/102] Removing CONFIG_GPG in librem boards --- boards/librem13v2/librem13v2.config | 1 - boards/librem15v3/librem15v3.config | 1 - 2 files changed, 2 deletions(-) diff --git a/boards/librem13v2/librem13v2.config b/boards/librem13v2/librem13v2.config index 92b2e8c38..5d5db1cb5 100644 --- a/boards/librem13v2/librem13v2.config +++ b/boards/librem13v2/librem13v2.config @@ -6,7 +6,6 @@ export CONFIG_COREBOOT=y CONFIG_CRYPTSETUP=y CONFIG_FLASHROM=y CONFIG_FLASHTOOLS=y -CONFIG_GPG=y CONFIG_GPG2=y CONFIG_KEXEC=y CONFIG_UTIL_LINUX=y diff --git a/boards/librem15v3/librem15v3.config b/boards/librem15v3/librem15v3.config index 8387d9cc9..8cb378e3d 100644 --- a/boards/librem15v3/librem15v3.config +++ b/boards/librem15v3/librem15v3.config @@ -8,7 +8,6 @@ export CONFIG_COREBOOT=y CONFIG_CRYPTSETUP=y CONFIG_FLASHROM=y CONFIG_FLASHTOOLS=y -CONFIG_GPG=y CONFIG_GPG2=y CONFIG_KEXEC=y CONFIG_UTIL_LINUX=y From 5eee5aa296ce388dd6ccc9c856af2a0b45584520 Mon Sep 17 00:00:00 2001 From: Thierry Laurion Date: Sat, 26 Jan 2019 12:20:31 -0500 Subject: [PATCH 072/102] GPG2 required changes for key and trustdb generation and inclusion in rom .ash_history: add examples to generate keys and otrust in rom flash-gui: export otrust and import it in rom key-init: import otrust.txt if present to supress warning about user public key being untrusted --- initrd/.ash_history | 27 +++++++++++++++------------ initrd/bin/flash-gui.sh | 8 +++++++- initrd/bin/key-init | 7 ++++++- 3 files changed, 28 insertions(+), 14 deletions(-) diff --git a/initrd/.ash_history b/initrd/.ash_history index d7acdebe9..996900531 100644 --- a/initrd/.ash_history +++ b/initrd/.ash_history @@ -1,14 +1,17 @@ -mount /dev/sda1 /boot -mount -o remount,rw /boot -rm /boot/kexec_* -mount-usb -mkdir -p /media/gpg_keys -gpg --home=/media/gpg_keys --card-edit -gpg --home=/media/gpg_keys --export --armor e@mail.address > /media/gpg_keys/public.key -gpg --home=/media/gpg_keys --export-secret-keys --armor e@mail.address > /media/gpg_keys/private.key -cbfs -o /media/coreboot.rom -a "heads/initrd/.gnupg/keys/public.key" -f /media/gpg_keys/public.key -cbfs -o /media/coreboot.rom -a "heads/initrd/.gnupg/keys/private.key" -f /media/gpg_keys/private.key -mount -o remount,ro /media -flash.sh /media/coreboot.com +#remove invalid kexec_* signed files +mount /dev/sda1 /boot && mount -o remount,rw /boot && rm /boot/kexec* && mount -o remount,ro /boot +#Generate keys from GPG smartcard: +mount-usb && gpg --home=/.gnupg/ --card-edit +#Copy generated public key, private_subkey, trustdb and artifacts to external media for backup: +mount -o remount,rw /media && mkdir -p /media/gpg_keys; gpg --export-secret-keys --armor email@address.com > /media/gpg_keys/private.key && gpg --export --armor email@address.com > /media/gpg_keys/public.key && gpg --export-ownertrust > /media/gpg_keys/otrust.txt && cp -r ./.gnupg/* /media/gpg_keys/ 2> /dev/null +#Insert public key and trustdb export into reproducible rom: +cbfs -o /media/coreboot.rom -a "heads/initrd/.gnupg/keys/public.key" -f /media/gpg_keys/public.key && cbfs -o /media/coreboot.rom -a "heads/initrd/.gnupg/keys/otrust.txt" -f /media/gpg_keys/otrust.txt +#Flush changes to external media: +mount -o,remount ro /media +#Flash modified reproducible rom with inserted public key and trustdb export from precedent step. Flushes actual rom's keys (-c: clean): +flash.sh -c /media/coreboot.rom +#Attest integrity of firmware as it is +seal-totp +#Verify Intel ME state: cbmem --console | grep '^ME' cbmem --console | less diff --git a/initrd/bin/flash-gui.sh b/initrd/bin/flash-gui.sh index 7a7ec46a5..6c121746d 100755 --- a/initrd/bin/flash-gui.sh +++ b/initrd/bin/flash-gui.sh @@ -143,12 +143,18 @@ while true; do cbfs -o /tmp/gpg-gui.rom -d "heads/initrd/.gnupg/pubring.kbx" fi cbfs -o /tmp/gpg-gui.rom -a "heads/initrd/.gnupg/pubring.kbx" -f /.gnupg/pubring.kbx - + + #TODO: Remove this? Not useful in GPG2 if (cbfs -o /tmp/gpg-gui.rom -l | grep -q "heads/initrd/.gnupg/trustdb.gpg") then cbfs -o /tmp/gpg-gui.rom -d "heads/initrd/.gnupg/trustdb.gpg" fi cbfs -o /tmp/gpg-gui.rom -a "heads/initrd/.gnupg/trustdb.gpg" -f /.gnupg/trustdb.gpg + if (cbfs -o /tmp/gpg-gui.rom -l | grep -q "heads/initrd/.gnupg/otrust.txt") then + cbfs -o /tmp/gpg-gui.rom -d "heads/initrd/.gnupg/otrust.txt" + fi + cbfs -o /tmp/gpg-gui.rom -a "heads/initrd/.gnupg/otrust.txt" -f /.gnupg/otrust.txt + if (whiptail --title 'Flash ROM?' \ --yesno "This will replace your old ROM with $ROM\n\nDo you want to proceed?" 16 90) then /bin/flash.sh /tmp/gpg-gui.rom diff --git a/initrd/bin/key-init b/initrd/bin/key-init index f59d302e8..545a774ff 100755 --- a/initrd/bin/key-init +++ b/initrd/bin/key-init @@ -5,7 +5,12 @@ set -e -o pipefail # Post processing of keys # Import user's keys -gpg --import /.gnupg/keys/* 2>/dev/null || true +gpg --import /.gnupg/keys/*.key 2>/dev/null || true + +#Import trustdb if it exists +if [ -s /.gnupg/keys/otrust.txt ]; then + gpg --import-ownertrust /.gnupg/keys/otrust.txt +fi # Import trusted distro keys allowed for ISO signing gpg --homedir=/etc/distro/ --import /etc/distro/keys/* 2>/dev/null || true From 8dd1082808f8479f5b9eb5c9827deca53e6b4164 Mon Sep 17 00:00:00 2001 From: Thierry Laurion Date: Sat, 26 Jan 2019 12:52:37 -0500 Subject: [PATCH 073/102] module/pinentry: disable-pinentry-qt instead of qt5 else: make[4]: Entering directory '/home/user/heads/build/pinentry-1.1.0/qt' g++ -DHAVE_CONFIG_H -I. -I.. -I//include -I//include -I.. -I../secmem -I../pinentry -Wall -I/home/user/heads/install/usr/include -I/home/user/heads/install/usr/include/QtCore -I/home/user/heads/install/usr/include/QtGui -DQT_SHARED -g -O2 -MT pinentrydialog.o -MD -MP -MF .deps/pinentrydialog.Tpo -c -o pinentrydialog.o pinentrydialog.cpp In file included from pinentrydialog.cpp:24: pinentrydialog.h:27:10: fatal error: QDialog: No such file or directory --- modules/pinentry | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modules/pinentry b/modules/pinentry index 7de67e203..1981f6eae 100644 --- a/modules/pinentry +++ b/modules/pinentry @@ -21,7 +21,7 @@ pinentry_configure := ./configure \ --disable-libsecret \ --disable-fallback-curses \ --disable-pinentry-curses \ - --disable-pinentry-qt5 \ + --disable-pinentry-qt \ --disable-pinentry-fltk \ --disable-pinentry-emacs \ --disable-fallback-curses \ From ae408922058194077a1d4c890bbdd0eb4d3b23ac Mon Sep 17 00:00:00 2001 From: Martin Kepplinger Date: Thu, 11 Oct 2018 13:06:33 +0200 Subject: [PATCH 074/102] x230: use fbwhiptail and gui-init instead of generic-init This changes Heads' bootscript for the x230 to gui-init and adds config options needed for it. The config is very similar to the librem13v2 config. My comparison of startup-time from a power-button press shows 2.5 seconds more with these changes applied. That said, the experience is smooth, the GUI is beautiful and easier to use than the shell and text menu, especially during setup. That's what we buy with startup time here. --- boards/x230/x230.config | 10 ++++++++-- config/coreboot-x230.config | 5 ++++- config/linux-x230.config | 1 + 3 files changed, 13 insertions(+), 3 deletions(-) diff --git a/boards/x230/x230.config b/boards/x230/x230.config index e479f5a1b..4bd868e25 100644 --- a/boards/x230/x230.config +++ b/boards/x230/x230.config @@ -17,17 +17,23 @@ CONFIG_QRENCODE=y CONFIG_TPMTOTP=y CONFIG_DROPBEAR=y +CONFIG_CAIRO=y +CONFIG_FBWHIPTAIL=y + CONFIG_LINUX_USB=y CONFIG_LINUX_E1000E=y export CONFIG_TPM=y -export CONFIG_BOOTSCRIPT=/bin/generic-init +export CONFIG_BOOTSCRIPT=/bin/gui-init export CONFIG_BOOT_REQ_HASH=n export CONFIG_BOOT_REQ_ROLLBACK=n -export CONFIG_BOOT_KERNEL_ADD="intel_iommu=on" +export CONFIG_BOOT_KERNEL_ADD="intel_iommu=on intel_iommu=igfx_off" export CONFIG_BOOT_KERNEL_REMOVE="quiet" export CONFIG_BOOT_DEV="/dev/sda1" +export CONFIG_BOOT_GUI_MENU_NAME="Thinkpad X230 Heads Boot Menu" export CONFIG_USB_BOOT_DEV="/dev/sdb1" +export CONFIG_WARNING_BG_COLOR="--background-gradient 0 0 0 150 125 0" +export CONFIG_ERROR_BG_COLOR="--background-gradient 0 0 0 150 0 0" # This board has two SPI flash chips, an 8 MB that holds the IFD, # the ME image and part of the coreboot image, and a 4 MB one that diff --git a/config/coreboot-x230.config b/config/coreboot-x230.config index 61e9dd9db..65b13b581 100644 --- a/config/coreboot-x230.config +++ b/config/coreboot-x230.config @@ -11,11 +11,14 @@ CONFIG_DRIVERS_UART_8250IO=y CONFIG_BOARD_LENOVO_X230=y CONFIG_DRIVERS_PS2_KEYBOARD=y CONFIG_UART_PCI_ADDR=0 +CONFIG_NO_GFX_INIT=y # CONFIG_CONSOLE_SERIAL is not set CONFIG_CONSOLE_CBMEM_BUFFER_SIZE=0x80000 CONFIG_DEFAULT_CONSOLE_LOGLEVEL_5=y CONFIG_PAYLOAD_LINUX=y CONFIG_PAYLOAD_FILE="../../build/x230/bzImage" -CONFIG_LINUX_COMMAND_LINE="quiet" +CONFIG_PAYLOAD_OPTIONS="" +# CONFIG_PXE is not set +CONFIG_LINUX_COMMAND_LINE="intel_iommu=igfx_off quiet" CONFIG_LINUX_INITRD="../../build/x230/initrd.cpio.xz" CONFIG_DEBUG_SMM_RELOCATION=y diff --git a/config/linux-x230.config b/config/linux-x230.config index 3f13d3278..728d3b879 100644 --- a/config/linux-x230.config +++ b/config/linux-x230.config @@ -181,6 +181,7 @@ CONFIG_PTP_1588_CLOCK=y # CONFIG_X86_PKG_TEMP_THERMAL is not set CONFIG_MFD_SYSCON=y CONFIG_DRM=y +CONFIG_DRM_I915=y CONFIG_FB_VESA=y CONFIG_BACKLIGHT_LCD_SUPPORT=y # CONFIG_LCD_CLASS_DEVICE is not set From 005a19eeda7267d8a731fffe3a91ee0696a0df9a Mon Sep 17 00:00:00 2001 From: Thierry Laurion Date: Fri, 8 Feb 2019 12:38:38 -0500 Subject: [PATCH 075/102] properly deal with trusting keys to supress UX confusion about trusted keys key-init makes sure trustdb is updated at run time and user and distro keys are ultimately trusted. Each time a file is signed, the related public key is showed without error on it's trustability. flash-gui deals with gpg1 to gpg2 migration. If pubring.kbx is found, pubring.gpg is deleted from running rom dump. --- initrd/bin/flash-gui.sh | 66 ++++++++++++++++++++++++++++++++++------- initrd/bin/key-init | 11 ++++--- 2 files changed, 60 insertions(+), 17 deletions(-) diff --git a/initrd/bin/flash-gui.sh b/initrd/bin/flash-gui.sh index 6c121746d..734b78c70 100755 --- a/initrd/bin/flash-gui.sh +++ b/initrd/bin/flash-gui.sh @@ -101,9 +101,9 @@ while true; do if (whiptail --title 'Flash ROM?' \ --yesno "This will replace your old ROM with $ROM\n\nDo you want to proceed?" 16 90) then if [ "$menu_choice" == "c" ]; then - /bin/flash.sh -c $ROM + /bin/flash.sh -c "$ROM" else - /bin/flash.sh $ROM + /bin/flash.sh "$ROM" fi whiptail --title 'ROM Flashed Successfully' \ --msgbox "$ROM flashed successfully. Press Enter to reboot" 16 60 @@ -137,23 +137,42 @@ while true; do ROM=$FILE fi - cat $PUBKEY | gpg --import - cp $ROM /tmp/gpg-gui.rom - if (cbfs -o /tmp/gpg-gui.rom -l | grep -q "heads/initrd/.gnupg/pubring.kbx") then + cat "$PUBKEY" | gpg --import + #update /.gnupg/trustdb.gpg to ultimately trust all user provided public keys + gpg --list-keys --fingerprint --with-colons |sed -E -n -e 's/^fpr:::::::::([0-9A-F]+):$/\1:6:/p' |gpg --import-ownertrust + gpg --update-trust + + cp "$ROM" /tmp/gpg-gui.rom + if (cbfs -o /tmp/gpg-gui.rom -l | grep -q "heads/initrd/.gnupg/pubring.kbx"); then cbfs -o /tmp/gpg-gui.rom -d "heads/initrd/.gnupg/pubring.kbx" + if (cbfs -o /tmp/gpg-gui.rom -l | grep -q "heads/initrd/.gnupg/pubring.gpg"); then + cbfs -o /tmp/gpg-gui.rom -d "heads/initrd/.gnupg/pubring.gpg" + if [ -e /.gnupg/pubring.gpg ];then + rm /.gnupg/pubring.gpg + fi + fi fi - cbfs -o /tmp/gpg-gui.rom -a "heads/initrd/.gnupg/pubring.kbx" -f /.gnupg/pubring.kbx - #TODO: Remove this? Not useful in GPG2 + #to be compatible with gpgv1 + if [ -e /.gnupg/pubring.kbx ];then + cbfs -o /tmp/gpg-gui.rom -a "heads/initrd/.gnupg/pubring.kbx" -f /.gnupg/pubring.kbx + if [ -e /.gnupg/pubring.gpg ];then + rm /.gnupg/pubring.gpg + fi + fi + if [ -e /.gnupg/pubring.gpg ];then + cbfs -o /tmp/gpg-gui.rom -a "heads/initrd/.gnupg/pubring.gpg" -f /.gnupg/pubring.gpg + fi + if (cbfs -o /tmp/gpg-gui.rom -l | grep -q "heads/initrd/.gnupg/trustdb.gpg") then cbfs -o /tmp/gpg-gui.rom -d "heads/initrd/.gnupg/trustdb.gpg" fi cbfs -o /tmp/gpg-gui.rom -a "heads/initrd/.gnupg/trustdb.gpg" -f /.gnupg/trustdb.gpg + #Remove old method owner trust exported file if (cbfs -o /tmp/gpg-gui.rom -l | grep -q "heads/initrd/.gnupg/otrust.txt") then cbfs -o /tmp/gpg-gui.rom -d "heads/initrd/.gnupg/otrust.txt" fi - cbfs -o /tmp/gpg-gui.rom -a "heads/initrd/.gnupg/otrust.txt" -f /.gnupg/otrust.txt if (whiptail --title 'Flash ROM?' \ --yesno "This will replace your old ROM with $ROM\n\nDo you want to proceed?" 16 90) then @@ -185,17 +204,42 @@ while true; do exit 1 fi - cat $PUBKEY | gpg --import - if (cbfs -o /tmp/gpg-gui.rom -l | grep -q "heads/initrd/.gnupg/pubring.kbx") then + cat "$PUBKEY" | gpg --import + #update /.gnupg/trustdb.gpg to ultimately trust all user provided public keys + gpg --list-keys --fingerprint --with-colons |sed -E -n -e 's/^fpr:::::::::([0-9A-F]+):$/\1:6:/p' |gpg --import-ownertrust + gpg --update-trust + + if (cbfs -o /tmp/gpg-gui.rom -l | grep -q "heads/initrd/.gnupg/pubring.kbx"); then cbfs -o /tmp/gpg-gui.rom -d "heads/initrd/.gnupg/pubring.kbx" + if (cbfs -o /tmp/gpg-gui.rom -l | grep -q "heads/initrd/.gnupg/pubring.gpg"); then + cbfs -o /tmp/gpg-gui.rom -d "heads/initrd/.gnupg/pubring.gpg" + if [ -e /.gnupg/pubring.gpg ];then + rm /.gnupg/pubring.gpg + fi + fi + fi + + #to be compatible with gpgv1 + if [ -e /.gnupg/pubring.kbx ];then + cbfs -o /tmp/gpg-gui.rom -a "heads/initrd/.gnupg/pubring.kbx" -f /.gnupg/pubring.kbx + if [ -e /.gnupg/pubring.gpg ];then + rm /.gnupg/pubring.gpg + fi + fi + if [ -e /.gnupg/pubring.gpg ];then + cbfs -o /tmp/gpg-gui.rom -a "heads/initrd/.gnupg/pubring.gpg" -f /.gnupg/pubring.gpg fi - cbfs -o /tmp/gpg-gui.rom -a "heads/initrd/.gnupg/pubring.kbx" -f /.gnupg/pubring.kbx if (cbfs -o /tmp/gpg-gui.rom -l | grep -q "heads/initrd/.gnupg/trustdb.gpg") then cbfs -o /tmp/gpg-gui.rom -d "heads/initrd/.gnupg/trustdb.gpg" fi cbfs -o /tmp/gpg-gui.rom -a "heads/initrd/.gnupg/trustdb.gpg" -f /.gnupg/trustdb.gpg + #Remove old method owner trust exported file + if (cbfs -o /tmp/gpg-gui.rom -l | grep -q "heads/initrd/.gnupg/otrust.txt") then + cbfs -o /tmp/gpg-gui.rom -d "heads/initrd/.gnupg/otrust.txt" + fi + if (whiptail --title 'Update ROM?' \ --yesno "This will reflash your BIOS with the updated version\n\nDo you want to proceed?" 16 90) then /bin/flash.sh /tmp/gpg-gui.rom diff --git a/initrd/bin/key-init b/initrd/bin/key-init index 545a774ff..bb4c1b5c9 100755 --- a/initrd/bin/key-init +++ b/initrd/bin/key-init @@ -5,14 +5,13 @@ set -e -o pipefail # Post processing of keys # Import user's keys -gpg --import /.gnupg/keys/*.key 2>/dev/null || true - -#Import trustdb if it exists -if [ -s /.gnupg/keys/otrust.txt ]; then - gpg --import-ownertrust /.gnupg/keys/otrust.txt -fi +gpg --import /.gnupg/keys/*.key /.gnupg/keys/*.asc 2>/dev/null || true # Import trusted distro keys allowed for ISO signing gpg --homedir=/etc/distro/ --import /etc/distro/keys/* 2>/dev/null || true +#Set distro keys trust level to ultimate (trust anything that was signed with these keys) +gpg --homedir=/etc/distro/ --list-keys --fingerprint --with-colons|sed -E -n -e 's/^fpr:::::::::([0-9A-F]+):$/\1:6:/p' |gpg --homedir=/etc/distro/ --import-ownertrust 2>/dev/null || true +gpg --homedir=/etc/distro/ --update-trust 2>/dev/null || true + # Add user's keys to the list of trusted keys for ISO signing gpg --export | gpg --homedir=/etc/distro/ --import 2>/dev/null || true From 181c621c843e7c0c3f6ebcf91d127fb77cb60639 Mon Sep 17 00:00:00 2001 From: Kyle Rankin Date: Fri, 8 Feb 2019 10:25:12 -0800 Subject: [PATCH 076/102] Touch /tmp/config when entering recovery mode --- initrd/etc/functions | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/initrd/etc/functions b/initrd/etc/functions index 1f7896ac2..8913870ec 100755 --- a/initrd/etc/functions +++ b/initrd/etc/functions @@ -17,6 +17,10 @@ recovery() { # but recreate the directory so that new tools can use it. rm -rf /tmp/secret mkdir -p /tmp/secret + + # ensure /tmp/config exists for recovery scripts that depend on it + touch /tmp/config + if [ "$CONFIG_TPM" = y ]; then tpm extend -ix 4 -ic recovery fi From be12506d7c6e9aab48afc445228b81c340d61f40 Mon Sep 17 00:00:00 2001 From: Thierry Laurion Date: Sat, 9 Feb 2019 12:15:20 -0500 Subject: [PATCH 077/102] GPG2 branch required sed sed is required to import owner trust information in trustdb when keys are imported into pubkey.kbx/pubkey.gpg --- config/busybox.config | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/config/busybox.config b/config/busybox.config index b9bc0c9ac..3cf4ef5a2 100644 --- a/config/busybox.config +++ b/config/busybox.config @@ -404,7 +404,7 @@ CONFIG_FEATURE_AWK_GNU_EXTENSIONS=y # CONFIG_FEATURE_DIFF_DIR is not set # CONFIG_ED is not set # CONFIG_PATCH is not set -# CONFIG_SED is not set +CONFIG_SED=y CONFIG_VI=y CONFIG_FEATURE_VI_MAX_LEN=4096 # CONFIG_FEATURE_VI_8BIT is not set From c31421218ae52563bfe39dbd6e877d8a111ce177 Mon Sep 17 00:00:00 2001 From: Kyle Rankin Date: Mon, 11 Feb 2019 14:29:13 -0800 Subject: [PATCH 078/102] Add GPG GUI It makes more logical sense for GPG functions to be split out into their own menu instead of being part of the "Flash" menu. This creates a gpg-gui.sh script and moves GPG options there while adding a few additional features (like listing keys and initial smartcard key generation support). --- initrd/bin/flash-gui.sh | 150 ------------------------ initrd/bin/gpg-gui.sh | 244 ++++++++++++++++++++++++++++++++++++++++ initrd/bin/gui-init | 26 ++++- 3 files changed, 265 insertions(+), 155 deletions(-) create mode 100755 initrd/bin/gpg-gui.sh diff --git a/initrd/bin/flash-gui.sh b/initrd/bin/flash-gui.sh index 775826e05..b8de9a23c 100755 --- a/initrd/bin/flash-gui.sh +++ b/initrd/bin/flash-gui.sh @@ -74,8 +74,6 @@ while true; do --menu 'Select the BIOS function to perform' 20 90 10 \ 'f' ' Flash the BIOS with a new ROM' \ 'c' ' Flash the BIOS with a new cleaned ROM' \ - 'a' ' Add GPG key to BIOS image' \ - 'r' ' Add GPG key to running BIOS' \ 'x' ' Exit' \ 2>/tmp/whiptail || recovery "GUI menu failed" @@ -115,154 +113,6 @@ while true; do fi fi ;; - "a" ) - if (whiptail --title 'ROM and GPG public key required' \ - --yesno "This requires you insert a USB drive containing:\n* Your GPG public key (*.key or *.asc)\n* Your BIOS image (*.rom)\n\nAfter you select these files, this program will reflash your BIOS\n\nDo you want to proceed?" 16 90) then - mount_usb - if grep -q /media /proc/mounts ; then - find /media -name '*.key' > /tmp/filelist.txt - find /media -name '*.asc' >> /tmp/filelist.txt - file_selector "/tmp/filelist.txt" "Choose your GPG public key" - if [ "$FILE" == "" ]; then - return - else - PUBKEY=$FILE - fi - - find /media -name '*.rom' > /tmp/filelist.txt - file_selector "/tmp/filelist.txt" "Choose the ROM to load your key onto" - if [ "$FILE" == "" ]; then - return - else - ROM=$FILE - fi - - cat "$PUBKEY" | gpg --import - #update /.gnupg/trustdb.gpg to ultimately trust all user provided public keys - gpg --list-keys --fingerprint --with-colons |sed -E -n -e 's/^fpr:::::::::([0-9A-F]+):$/\1:6:/p' |gpg --import-ownertrust - gpg --update-trust - - cp "$ROM" /tmp/gpg-gui.rom - if (cbfs -o /tmp/gpg-gui.rom -l | grep -q "heads/initrd/.gnupg/pubring.kbx"); then - cbfs -o /tmp/gpg-gui.rom -d "heads/initrd/.gnupg/pubring.kbx" - if (cbfs -o /tmp/gpg-gui.rom -l | grep -q "heads/initrd/.gnupg/pubring.gpg"); then - cbfs -o /tmp/gpg-gui.rom -d "heads/initrd/.gnupg/pubring.gpg" - if [ -e /.gnupg/pubring.gpg ];then - rm /.gnupg/pubring.gpg - fi - fi - fi - - #to be compatible with gpgv1 - if [ -e /.gnupg/pubring.kbx ];then - cbfs -o /tmp/gpg-gui.rom -a "heads/initrd/.gnupg/pubring.kbx" -f /.gnupg/pubring.kbx - if [ -e /.gnupg/pubring.gpg ];then - rm /.gnupg/pubring.gpg - fi - fi - if [ -e /.gnupg/pubring.gpg ];then - cbfs -o /tmp/gpg-gui.rom -a "heads/initrd/.gnupg/pubring.gpg" -f /.gnupg/pubring.gpg - fi - - if (cbfs -o /tmp/gpg-gui.rom -l | grep -q "heads/initrd/.gnupg/trustdb.gpg") then - cbfs -o /tmp/gpg-gui.rom -d "heads/initrd/.gnupg/trustdb.gpg" - fi - cbfs -o /tmp/gpg-gui.rom -a "heads/initrd/.gnupg/trustdb.gpg" -f /.gnupg/trustdb.gpg - - #Remove old method owner trust exported file - if (cbfs -o /tmp/gpg-gui.rom -l | grep -q "heads/initrd/.gnupg/otrust.txt") then - cbfs -o /tmp/gpg-gui.rom -d "heads/initrd/.gnupg/otrust.txt" - fi - - if (whiptail --title 'Flash ROM?' \ - --yesno "This will replace your old ROM with $ROM\n\nDo you want to proceed?" 16 90) then - /bin/flash.sh /tmp/gpg-gui.rom - whiptail --title 'ROM Flashed Successfully' \ - --msgbox "$ROM flashed successfully.\n\nIf your keys have changed, be sure to re-sign all files in /boot\nafter you reboot.\n\nPress Enter to reboot" 16 60 - umount /media - /bin/reboot - else - exit 0 - fi - fi - fi - ;; - "r" ) - if (whiptail --title 'GPG public key required' \ - --yesno "Flashing the running BIOS requires you insert a USB drive containing:\n* Your GPG public key (*.key or *.asc)\n\nAfter you select this file, this program will copy and reflash your BIOS\n\nDo you want to proceed?" 16 90) then - mount_usb - if grep -q /media /proc/mounts ; then - find /media -name '*.key' > /tmp/filelist.txt - find /media -name '*.asc' >> /tmp/filelist.txt - file_selector "/tmp/filelist.txt" "Choose your GPG public key" - PUBKEY=$FILE - - /bin/flash.sh -r /tmp/gpg-gui.rom - if [ ! -s /tmp/gpg-gui.rom ]; then - whiptail $CONFIG_ERROR_BG_COLOR --title 'ERROR: BIOS Read Failed!' \ - --msgbox "Unable to read BIOS" 16 60 - exit 1 - fi - - cat "$PUBKEY" | gpg --import - #update /.gnupg/trustdb.gpg to ultimately trust all user provided public keys - gpg --list-keys --fingerprint --with-colons |sed -E -n -e 's/^fpr:::::::::([0-9A-F]+):$/\1:6:/p' |gpg --import-ownertrust - gpg --update-trust - - if (cbfs -o /tmp/gpg-gui.rom -l | grep -q "heads/initrd/.gnupg/pubring.kbx"); then - cbfs -o /tmp/gpg-gui.rom -d "heads/initrd/.gnupg/pubring.kbx" - if (cbfs -o /tmp/gpg-gui.rom -l | grep -q "heads/initrd/.gnupg/pubring.gpg"); then - cbfs -o /tmp/gpg-gui.rom -d "heads/initrd/.gnupg/pubring.gpg" - if [ -e /.gnupg/pubring.gpg ];then - rm /.gnupg/pubring.gpg - fi - fi - fi - - #to be compatible with gpgv1 - if [ -e /.gnupg/pubring.kbx ];then - cbfs -o /tmp/gpg-gui.rom -a "heads/initrd/.gnupg/pubring.kbx" -f /.gnupg/pubring.kbx - if [ -e /.gnupg/pubring.gpg ];then - rm /.gnupg/pubring.gpg - fi - fi - if [ -e /.gnupg/pubring.gpg ];then - cbfs -o /tmp/gpg-gui.rom -a "heads/initrd/.gnupg/pubring.gpg" -f /.gnupg/pubring.gpg - fi - - if (cbfs -o /tmp/gpg-gui.rom -l | grep -q "heads/initrd/.gnupg/trustdb.gpg") then - cbfs -o /tmp/gpg-gui.rom -d "heads/initrd/.gnupg/trustdb.gpg" - fi - cbfs -o /tmp/gpg-gui.rom -a "heads/initrd/.gnupg/trustdb.gpg" -f /.gnupg/trustdb.gpg - - #Remove old method owner trust exported file - if (cbfs -o /tmp/gpg-gui.rom -l | grep -q "heads/initrd/.gnupg/otrust.txt") then - cbfs -o /tmp/gpg-gui.rom -d "heads/initrd/.gnupg/otrust.txt" - fi - - if (whiptail --title 'Update ROM?' \ - --yesno "This will reflash your BIOS with the updated version\n\nDo you want to proceed?" 16 90) then - /bin/flash.sh /tmp/gpg-gui.rom - whiptail --title 'BIOS Updated Successfully' \ - --msgbox "BIOS updated successfully.\n\nIf your keys have changed, be sure to re-sign all files in /boot\nafter you reboot.\n\nPress Enter to reboot" 16 60 - umount /media - /bin/reboot - else - exit 0 - fi - fi - fi - ;; - "g" ) - confirm_gpg_card - echo "********************************************************************************" - echo "*" - echo "* INSTRUCTIONS:" - echo "* Type 'admin' and then 'generate' and follow the prompts to generate a GPG key." - echo "*" - echo "********************************************************************************" - gpg --card-edit - ;; esac done diff --git a/initrd/bin/gpg-gui.sh b/initrd/bin/gpg-gui.sh new file mode 100755 index 000000000..f75661075 --- /dev/null +++ b/initrd/bin/gpg-gui.sh @@ -0,0 +1,244 @@ +#!/bin/sh +# +set -e -o pipefail +. /etc/functions +. /tmp/config + +mount_usb(){ +# Mount the USB boot device + if ! grep -q /media /proc/mounts ; then + mount-usb "$CONFIG_USB_BOOT_DEV" || USB_FAILED=1 + if [ $USB_FAILED -ne 0 ]; then + if [ ! -e "$CONFIG_USB_BOOT_DEV" ]; then + whiptail --title 'USB Drive Missing' \ + --msgbox "Insert your USB drive and press Enter to continue." 16 60 USB_FAILED=0 + mount-usb "$CONFIG_USB_BOOT_DEV" || USB_FAILED=1 + fi + if [ $USB_FAILED -ne 0 ]; then + whiptail $CONFIG_ERROR_BG_COLOR --title 'ERROR: Mounting /media Failed' \ + --msgbox "Unable to mount $CONFIG_USB_BOOT_DEV" 16 60 + fi + fi + fi +} + +file_selector() { + FILE="" + FILE_LIST=$1 + MENU_MSG=${2:-"Choose the file"} +# create file menu options + if [ `cat "$FILE_LIST" | wc -l` -gt 0 ]; then + option="" + while [ -z "$option" ] + do + MENU_OPTIONS="" + n=0 + while read option + do + n=`expr $n + 1` + option=$(echo $option | tr " " "_") + MENU_OPTIONS="$MENU_OPTIONS $n ${option}" + done < $FILE_LIST + + MENU_OPTIONS="$MENU_OPTIONS a Abort" + whiptail --clear --title "Select your File" \ + --menu "${MENU_MSG} [1-$n, a to abort]:" 20 120 8 \ + -- $MENU_OPTIONS \ + 2>/tmp/whiptail || die "Aborting" + + option_index=$(cat /tmp/whiptail) + + if [ "$option_index" = "a" ]; then + option="a" + return + fi + + option=`head -n $option_index $FILE_LIST | tail -1` + if [ "$option" == "a" ]; then + return + fi + done + if [ -n "$option" ]; then + FILE=$option + fi + else + whiptail $CONFIG_ERROR_BG_COLOR --title 'ERROR: No Files Found' \ + --msgbox "No Files found matching the pattern. Aborting." 16 60 + exit 1 + fi +} + +while true; do + unset menu_choice + whiptail --clear --title "GPG Management Menu" \ + --menu 'Select the GPG function to perform' 20 90 10 \ + 'r' ' Add GPG key to running BIOS + reflash' \ + 'a' ' Add GPG key to standalone BIOS image + flash' \ + 'l' ' List GPG keys in your keyring' \ + 'g' ' Generate GPG keys on a USB security token' \ + 'x' ' Exit' \ + 2>/tmp/whiptail || recovery "GUI menu failed" + + menu_choice=$(cat /tmp/whiptail) + + case "$menu_choice" in + "x" ) + exit 0 + ;; + "a" ) + if (whiptail --title 'ROM and GPG public key required' \ + --yesno "This requires you insert a USB drive containing:\n* Your GPG public key (*.key or *.asc)\n* Your BIOS image (*.rom)\n\nAfter you select these files, this program will reflash your BIOS\n\nDo you want to proceed?" 16 90) then + mount_usb + if grep -q /media /proc/mounts ; then + find /media -name '*.key' > /tmp/filelist.txt + find /media -name '*.asc' >> /tmp/filelist.txt + file_selector "/tmp/filelist.txt" "Choose your GPG public key" + if [ "$FILE" == "" ]; then + return + else + PUBKEY=$FILE + fi + + find /media -name '*.rom' > /tmp/filelist.txt + file_selector "/tmp/filelist.txt" "Choose the ROM to load your key onto" + if [ "$FILE" == "" ]; then + return + else + ROM=$FILE + fi + + cat "$PUBKEY" | gpg --import + #update /.gnupg/trustdb.gpg to ultimately trust all user provided public keys + gpg --list-keys --fingerprint --with-colons |sed -E -n -e 's/^fpr:::::::::([0-9A-F]+):$/\1:6:/p' |gpg --import-ownertrust + gpg --update-trust + + cp "$ROM" /tmp/gpg-gui.rom + if (cbfs -o /tmp/gpg-gui.rom -l | grep -q "heads/initrd/.gnupg/pubring.kbx"); then + cbfs -o /tmp/gpg-gui.rom -d "heads/initrd/.gnupg/pubring.kbx" + if (cbfs -o /tmp/gpg-gui.rom -l | grep -q "heads/initrd/.gnupg/pubring.gpg"); then + cbfs -o /tmp/gpg-gui.rom -d "heads/initrd/.gnupg/pubring.gpg" + if [ -e /.gnupg/pubring.gpg ];then + rm /.gnupg/pubring.gpg + fi + fi + fi + + #to be compatible with gpgv1 + if [ -e /.gnupg/pubring.kbx ];then + cbfs -o /tmp/gpg-gui.rom -a "heads/initrd/.gnupg/pubring.kbx" -f /.gnupg/pubring.kbx + if [ -e /.gnupg/pubring.gpg ];then + rm /.gnupg/pubring.gpg + fi + fi + if [ -e /.gnupg/pubring.gpg ];then + cbfs -o /tmp/gpg-gui.rom -a "heads/initrd/.gnupg/pubring.gpg" -f /.gnupg/pubring.gpg + fi + + if (cbfs -o /tmp/gpg-gui.rom -l | grep -q "heads/initrd/.gnupg/trustdb.gpg") then + cbfs -o /tmp/gpg-gui.rom -d "heads/initrd/.gnupg/trustdb.gpg" + fi + cbfs -o /tmp/gpg-gui.rom -a "heads/initrd/.gnupg/trustdb.gpg" -f /.gnupg/trustdb.gpg + + #Remove old method owner trust exported file + if (cbfs -o /tmp/gpg-gui.rom -l | grep -q "heads/initrd/.gnupg/otrust.txt") then + cbfs -o /tmp/gpg-gui.rom -d "heads/initrd/.gnupg/otrust.txt" + fi + + if (whiptail --title 'Flash ROM?' \ + --yesno "This will replace your old ROM with $ROM\n\nDo you want to proceed?" 16 90) then + /bin/flash.sh /tmp/gpg-gui.rom + whiptail --title 'ROM Flashed Successfully' \ + --msgbox "$ROM flashed successfully.\n\nIf your keys have changed, be sure to re-sign all files in /boot\nafter you reboot.\n\nPress Enter to reboot" 16 60 + umount /media + /bin/reboot + else + exit 0 + fi + fi + fi + ;; + "r" ) + if (whiptail --title 'GPG public key required' \ + --yesno "This requires you insert a USB drive containing:\n* Your GPG public key (*.key or *.asc)\n\nAfter you select this file, this program will copy and reflash your BIOS\n\nDo you want to proceed?" 16 90) then + mount_usb + if grep -q /media /proc/mounts ; then + find /media -name '*.key' > /tmp/filelist.txt + find /media -name '*.asc' >> /tmp/filelist.txt + file_selector "/tmp/filelist.txt" "Choose your GPG public key" + PUBKEY=$FILE + + /bin/flash.sh -r /tmp/gpg-gui.rom + if [ ! -s /tmp/gpg-gui.rom ]; then + whiptail $CONFIG_ERROR_BG_COLOR --title 'ERROR: BIOS Read Failed!' \ + --msgbox "Unable to read BIOS" 16 60 + exit 1 + fi + + cat "$PUBKEY" | gpg --import + #update /.gnupg/trustdb.gpg to ultimately trust all user provided public keys + gpg --list-keys --fingerprint --with-colons |sed -E -n -e 's/^fpr:::::::::([0-9A-F]+):$/\1:6:/p' |gpg --import-ownertrust + gpg --update-trust + + if (cbfs -o /tmp/gpg-gui.rom -l | grep -q "heads/initrd/.gnupg/pubring.kbx"); then + cbfs -o /tmp/gpg-gui.rom -d "heads/initrd/.gnupg/pubring.kbx" + if (cbfs -o /tmp/gpg-gui.rom -l | grep -q "heads/initrd/.gnupg/pubring.gpg"); then + cbfs -o /tmp/gpg-gui.rom -d "heads/initrd/.gnupg/pubring.gpg" + if [ -e /.gnupg/pubring.gpg ];then + rm /.gnupg/pubring.gpg + fi + fi + fi + + #to be compatible with gpgv1 + if [ -e /.gnupg/pubring.kbx ];then + cbfs -o /tmp/gpg-gui.rom -a "heads/initrd/.gnupg/pubring.kbx" -f /.gnupg/pubring.kbx + if [ -e /.gnupg/pubring.gpg ];then + rm /.gnupg/pubring.gpg + fi + fi + if [ -e /.gnupg/pubring.gpg ];then + cbfs -o /tmp/gpg-gui.rom -a "heads/initrd/.gnupg/pubring.gpg" -f /.gnupg/pubring.gpg + fi + + if (cbfs -o /tmp/gpg-gui.rom -l | grep -q "heads/initrd/.gnupg/trustdb.gpg") then + cbfs -o /tmp/gpg-gui.rom -d "heads/initrd/.gnupg/trustdb.gpg" + fi + cbfs -o /tmp/gpg-gui.rom -a "heads/initrd/.gnupg/trustdb.gpg" -f /.gnupg/trustdb.gpg + + #Remove old method owner trust exported file + if (cbfs -o /tmp/gpg-gui.rom -l | grep -q "heads/initrd/.gnupg/otrust.txt") then + cbfs -o /tmp/gpg-gui.rom -d "heads/initrd/.gnupg/otrust.txt" + fi + + if (whiptail --title 'Update ROM?' \ + --yesno "This will reflash your BIOS with the updated version\n\nDo you want to proceed?" 16 90) then + /bin/flash.sh /tmp/gpg-gui.rom + whiptail --title 'BIOS Updated Successfully' \ + --msgbox "BIOS updated successfully.\n\nIf your keys have changed, be sure to re-sign all files in /boot\nafter you reboot.\n\nPress Enter to reboot" 16 60 + umount /media + /bin/reboot + else + exit 0 + fi + fi + fi + ;; + "l" ) + GPG_KEYRING=`gpg -k` + whiptail --title 'GPG Keyring' \ + --msgbox "${GPG_KEYRING}" 16 60 + ;; + "g" ) + confirm_gpg_card + echo "********************************************************************************" + echo "*" + echo "* INSTRUCTIONS:" + echo "* Type 'admin' and then 'generate' and follow the prompts to generate a GPG key." + echo "*" + echo "********************************************************************************" + gpg --card-edit + ;; + esac + +done +exit 0 diff --git a/initrd/bin/gui-init b/initrd/bin/gui-init index 39b3c486f..7a07bbea8 100755 --- a/initrd/bin/gui-init +++ b/initrd/bin/gui-init @@ -114,7 +114,7 @@ while true; do if [ $GPG_KEY_COUNT -eq 0 ]; then whiptail $CONFIG_ERROR_BG_COLOR --clear --title "ERROR: GPG keyring empty!" \ --menu "ERROR: Heads couldn't find any GPG keys in your keyring.\n\nIf this is the first time the system has booted,\nyou should add a public GPG key to the BIOS now.\n\nIf you just reflashed a new BIOS, you'll need to add at least one\npublic key to the keyring.\n\nIf you have not just reflashed your BIOS, THIS COULD INDICATE TAMPERING!\n\nHow would you like to proceed?" 30 90 4 \ - 'f' ' Add a GPG key to the running BIOS' \ + 'G' ' Add a GPG key to the running BIOS' \ 'i' ' Ignore error and continue to default boot menu' \ 'x' ' Exit to recovery shell' \ 2>/tmp/whiptail || recovery "GUI menu failed" @@ -185,13 +185,11 @@ while true; do whiptail --clear --title "Advanced Settings" \ --menu "Configure Advanced Settings" 20 90 10 \ 'o' ' Other Boot Options -->' \ - 'r' ' TOTP/HOTP does not match, refresh code' \ - 'g' ' Generate new TOTP/HOTP secret' \ + 't' ' TPM/TOTP/HOTP Options -->' \ 's' ' Update checksums and sign all files in /boot' \ 'c' ' Change configuration settings -->' \ 'f' ' Flash/Update the BIOS -->' \ - 'p' ' Reset the TPM' \ - 'n' ' TOTP/HOTP does not match after refresh, troubleshoot' \ + 'G' ' GPG Options -->' \ 'r' ' <-- Return to main menu' \ 2>/tmp/whiptail || recovery "GUI menu failed" @@ -210,6 +208,19 @@ while true; do totp_confirm=$(cat /tmp/whiptail) fi + if [ "$totp_confirm" = "t" ]; then + whiptail --clear --title "TPM/TOTP/HOTP Options" \ + --menu "Select An Option" 20 90 10 \ + 'g' ' Generate new TOTP/HOTP secret' \ + 'p' ' Reset the TPM' \ + 'r' ' TOTP/HOTP does not match, refresh code' \ + 'n' ' TOTP/HOTP does not match after refresh, troubleshoot' \ + 'r' ' <-- Return to main menu' \ + 2>/tmp/whiptail || recovery "GUI menu failed" + + totp_confirm=$(cat /tmp/whiptail) + fi + if [ "$totp_confirm" = "x" ]; then recovery "User requested recovery shell" fi @@ -314,6 +325,11 @@ while true; do continue fi + if [ "$totp_confirm" = "G" ]; then + gpg-gui.sh + continue + fi + if [ "$totp_confirm" = "y" -o -n "$totp_confirm" ]; then # Try to boot the default mount_boot From 428561c11e303f0a0c3a2b1014801033de069a5e Mon Sep 17 00:00:00 2001 From: Matt DeVillier Date: Wed, 30 Jan 2019 16:40:39 -0600 Subject: [PATCH 079/102] librem_skl/readme: remove reference to 15v4 15v4 isn't a skylake-based device Signed-off-by: Matt DeVillier --- blobs/librem_skl/readme.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/blobs/librem_skl/readme.md b/blobs/librem_skl/readme.md index 3c210f624..01d2596b2 100644 --- a/blobs/librem_skl/readme.md +++ b/blobs/librem_skl/readme.md @@ -1,4 +1,4 @@ -To build for the Librem 2nd generation (Librem 13 v2/v3 and Librem 15 v3/v4), +To build for the Librem 2nd generation (Librem 13 v2/v3 and Librem 15 v3), we need to have the following files in this folder: * cpu_microcode_blob.bin - CPU Microcode * descriptor.bin - The Intel Flash Descriptor From 81bf58d96d404954663a28e9a354b525b3606436 Mon Sep 17 00:00:00 2001 From: Matt DeVillier Date: Wed, 30 Jan 2019 17:39:12 -0600 Subject: [PATCH 080/102] blobs/librem_kbl: clone from librem_skl, adjust for v4 Librem 13v4/15v4 use Kabylake SoC, have different set of blobs required from Skylake-based v3 boards. Signed-off-by: Matt DeVillier --- blobs/librem_kbl/get_blobs.sh | 238 ++++++++++++++++++++++++++++++++++ blobs/librem_kbl/readme.md | 20 +++ 2 files changed, 258 insertions(+) create mode 100755 blobs/librem_kbl/get_blobs.sh create mode 100644 blobs/librem_kbl/readme.md diff --git a/blobs/librem_kbl/get_blobs.sh b/blobs/librem_kbl/get_blobs.sh new file mode 100755 index 000000000..90dc002ab --- /dev/null +++ b/blobs/librem_kbl/get_blobs.sh @@ -0,0 +1,238 @@ +#!/bin/bash -e +# depends on : wget sha256sum python2.7 bspatch pv + +# Librem 13 v4 and Librem 15 v4 binary blob hashes +KBL_UCODE_SHA="a420274eecca369fcca465cc46725d61c0ae8ca2e18f201b1751faf9e081fb2e" +KBL_ME_NOCONF_SHA="912271bb3ff2cf0e2e27ccfb94337baaca027e6c90b4245f9807a592c8a652e1" +KBL_ME_SHA="9c91052d457890c4a451c6ab69aabeeac98c95dce50cf462aa5c179236a27ba1" +KBL_FSP_SHA="74e579604bdc3eb6527f7add384d6b18e16eee76953748b226fe05129d83b419" +KBL_FSPM_SHA="b6431369b921df1c3ec01498e04e9dab331aa5b5fc4fbbb67b03ea87de27cd96" +KBL_FSPS_SHA="c81ffa40df0b6cd6cfde4f476d452a1f6f2217bc96a3b98a4fa4a037ee7039cf" +KBL_VBT_SHA="0ba40c1b8c0fb030a0e1a789eda8b2a7369339a410ad8c4620719e451ea69b98" + +# Microcode, FSP downloadable from Github +KBL_UCODE_URL="https://github.com/platomav/CPUMicrocodes/raw/0d88b2eba0c9930e69180423d3fb9f348d5ca14f/Intel/cpu806E9_platC0_ver0000009A_2018-07-16_PRD_DDFC5B64.bin" +KBL_FSP_URL="https://github.com/IntelFsp/FSP/raw/324ffc02523bf23a907a3ff305b43b5047adf1c5/KabylakeFspBinPkg/Fsp.fd" +KBL_VBT_URL="https://github.com/IntelFsp/FSP/raw/324ffc02523bf23a907a3ff305b43b5047adf1c5/KabylakeFspBinPkg/SampleCode/Vbt/Vbt.bin" +KBL_FSP_SPLIT_URL="https://raw.githubusercontent.com/tianocore/edk2/e8a70885d8f34533b6dd69878fe95a249e9af086/IntelFsp2Pkg/Tools/SplitFspBin.py" +KBL_FSP_SPLIT_SHA="f654f6363de68ad78b1baf8b8e573b53715c3bc76f7f3c23562641e49a7033f3" + +# Firmware descriptor from purism repo +KBL_DESCRIPTOR_URL="https://source.puri.sm/coreboot/coreboot-files/raw/master/descriptor-skl.bin" +KBL_DESCRIPTOR_SHA="d5110807c9d67cea6d546ac62125d87042a868177241be4ae17a2dbedef10017" + +# ME Cleaner from github +ME_CLEANER_URL="https://github.com/corna/me_cleaner/raw/9e1611fdf21426d66a29a5ea62b7e30d512859e6/me_cleaner.py" +ME_CLEANER_SHA="412e95538c46d6d4d456987a8897b3d0ad1df118c51378a350540eef51c242d4" + +# Intel ME binaries (unconfigured) +# Link found on : http://www.win-raid.com/t832f39-Intel-Engine-Firmware-Repositories.html +# Update link if it changes and becomes invalid. +KBL_ME_RAR_URL="https://mega.nz/#!6JlAla6a!hvulc0ZYCj19OzOZoyKimZSh8bxHw9Qmy6bQ8h_xKTU" +KBL_ME_FILENAME="11.6.0.1126_CON_LP_C_NPDM_PRD_RGN.bin" +KBL_ME_FULL_FILENAME="Intel CSME 11.6 Firmware Repository Pack r28/$KBL_ME_FILENAME" +KBL_ME_RAR_SHA="3c23134fca8de7c9b47dd4d62498bcde549ad07565d158c69f4ed33f9bda8270" +KBL_ME_PATCH="me11.6.0.1126_config.bspatch" +KBL_ME_PATCH_URL="https://source.puri.sm/coreboot/coreboot-files/raw/master/$KBL_ME_PATCH" +KBL_ME_PATCH_SHA="63a245326979777b102da8df2f278c590c60c2cd6b4911d3ac430d3feb02646e" + +# Needed to download KBL_ME_RAR_URL +MEGADOWN_URL="https://github.com/tonikelope/megadown.git" +MEGADOWN_GOOD_COMMIT="83c53ddad1c32bf6d35c61fcd12a2fa94271ff77" + +# Might be required to compile unrar in case unrar-nonfree is not installed +RAR_NONFREE_SOURCE_URL="https://www.rarlab.com/rar/unrarsrc-5.5.8.tar.gz" +RAR_NONFREE_SOURCE_SHA="9b66e4353a9944bc140eb2a919ff99482dd548f858f5e296d809e8f7cdb2fcf4" + +die () { + local msg=$1 + + echo "" + echo "$msg" + exit 1 +} + +check_binary () { + local filename=$1 + local hash=$2 + + if [ ! -f "$filename" ]; then + die "Binary blob file '$filename' does not exist" + fi + sha=$(sha256sum "$filename" | awk '{print $1}') + if [ "$sha" != "$hash" ]; then + die "Extracted binary '$filename' has the wrong SHA256 hash" + fi +} + +check_and_get_url () { + filename=$1 + url=$2 + hash=$3 + description=$4 + + if [ -f "$filename" ]; then + sha=$(sha256sum "$filename" | awk '{print $1}') + fi + if [ "$sha" != "$hash" ]; then + wget -O "$filename" "$url" + sha=$(sha256sum "$filename" | awk '{print $1}') + if [ "$sha" != "$hash" ]; then + die "Downloaded $description has the wrong SHA256 hash" + fi + fi + +} + +get_and_split_fsp () { + fsp="fsp.fd" + fsp_M="fsp_M.fd" + fsp_S="fsp_S.fd" + fsp_T="fsp_T.fd" + fspm="fspm.bin" + fsps="fsps.bin" + fsp_split="SplitFspBin.py" + + if [ -f "$fspm" ]; then + fspm_sha=$(sha256sum "$fspm" | awk '{print $1}') + fi + if [ -f "$fsps" ]; then + fsps_sha=$(sha256sum "$fsps" | awk '{print $1}') + fi + # No FSP-M or FSP-S + if [ "$fspm_sha" != "$KBL_FSPM_SHA" ] || [ "$fsps_sha" != "$KBL_FSPS_SHA" ]; then + if [ -f "$fsp" ]; then + fsp_sha=$(sha256sum "$fsp" | awk '{print $1}') + fi + # No FSP.fd + if [ "$fsp_sha" != "$KBL_FSP_SHA" ]; then + wget -O "$fsp" "$KBL_FSP_URL" + fsp_sha=$(sha256sum "$fsp" | awk '{print $1}') + if [ "$fsp_sha" != "$KBL_FSP_SHA" ]; then + die "Downloaded FSP image has the wrong SHA256 hash" + fi + fi + # No FspSplit + if [ -f "$fsp_split" ]; then + split_sha=$(sha256sum "$fsp_split" | awk '{print $1}') + fi + if [ "$split_sha" != "$KBL_FSP_SHA" ]; then + wget -O "$fsp_split" "$KBL_FSP_SPLIT_URL" + split_sha=$(sha256sum "$fsp_split" | awk '{print $1}') + if [ "$split_sha" != "$KBL_FSP_SPLIT_SHA" ]; then + die "Downloaded FSP Split Tool has the wrong SHA256 hash" + fi + fi + python2 "$fsp_split" split -f "$fsp" + if [ -f "$fsp_M" ]; then + mv "$fsp_M" "$fspm" + fi + if [ -f "$fsp_S" ]; then + mv "$fsp_S" "$fsps" + fi + fspm_sha=$(sha256sum "$fspm" | awk '{print $1}') + fsps_sha=$(sha256sum "$fsps" | awk '{print $1}') + if [ "$fspm_sha" != "$KBL_FSPM_SHA" ] || [ "$fsps_sha" != "$KBL_FSPS_SHA" ]; then + die "Extracted FSP images have the wrong SHA256 hash" + fi + rm -f "$fsp" + rm -f "$fsp_split" + rm -f "$fsp_T" + fi +} + +get_and_patch_me_11 () { + if [ -f "me.bin" ]; then + sha=$(sha256sum "me.bin" | awk '{print $1}') + fi + if [ "$sha" != "$KBL_ME_SHA" ]; then + local rar_filename=me_11_repository.rar + local unrar='unrar-nonfree' + + if [ -f "$rar_filename" ]; then + sha=$(sha256sum "$rar_filename" | awk '{print $1}') + fi + if ! type "$unrar" &> /dev/null; then + wget -O unrar.tar.gz "$RAR_NONFREE_SOURCE_URL" + sha=$(sha256sum unrar.tar.gz | awk '{print $1}') + if [ "$sha" != "$RAR_NONFREE_SOURCE_SHA" ]; then + die "Unrar source package has the wrong SHA256 hash" + fi + tar -xzvf unrar.tar.gz + ( + cd unrar + make + ) + unrar="`pwd`/unrar/unrar" + fi + if [ "$sha" != "$KBL_ME_RAR_SHA" ]; then + if [ ! -d megadown ]; then + git clone $MEGADOWN_URL + fi + ( + cd megadown + git checkout $MEGADOWN_GOOD_COMMIT + echo -e "\n\nDownloading ME 11 Repository from $KBL_ME_RAR_URL" + echo "Please be patient while the download finishes..." + rm -f ../$rar_filename 2> /dev/null + ./megadown "$KBL_ME_RAR_URL" -o ../$rar_filename 2>/dev/null + ) + sha=$(sha256sum "$rar_filename" | awk '{print $1}') + if [ "$sha" != "$KBL_ME_RAR_SHA" ]; then + # We'll assume the rar file was updated again + me_dirname=$("$unrar" l "$rar_filename" | grep '\.\.\.D\.\.\.' | tr -s [:blank:] | cut -d' ' -f 6-) + KBL_ME_FULL_FILENAME="$me_dirname/$KBL_ME_FILENAME" + fi + fi + if type "$unrar" &> /dev/null; then + "$unrar" e -y "$rar_filename" "$KBL_ME_FULL_FILENAME" + else + die "Couldn't extract ME image. Requires unrar-nonfree" + fi + sha="" + if [ -f "$KBL_ME_FILENAME" ]; then + sha=$(sha256sum "$KBL_ME_FILENAME" | awk '{print $1}') + fi + if [ "$sha" != "$KBL_ME_NOCONF_SHA" ]; then + die "Couldn't extract ME image with the correct SHA256 hash" + fi + check_and_get_url $KBL_ME_PATCH $KBL_ME_PATCH_URL $KBL_ME_PATCH_SHA "ME Patch" + bspatch "$KBL_ME_FILENAME" "me.bin" "$KBL_ME_PATCH" + rm -f "$KBL_ME_PATCH" + rm -f "$KBL_ME_FILENAME" + rm -f "$rar_filename" + fi +} + +apply_me_cleaner() { + if [ -f "me_cleaner.py" ]; then + sha=$(sha256sum "me_cleaner.py" | awk '{print $1}') + fi + if [ "$sha" != "$ME_CLEANER_SHA" ]; then + wget -O "me_cleaner.py" "$ME_CLEANER_URL" + sha=$(sha256sum "me_cleaner.py" | awk '{print $1}') + if [ "$sha" != "$ME_CLEANER_SHA" ]; then + die "Downloaded ME Cleaner has the wrong SHA256 hash" + fi + fi + cat descriptor.bin me.bin > desc_me.bin + python2 "me_cleaner.py" -s desc_me.bin + python2 "me_cleaner.py" -w "MFS" me.bin + dd if=desc_me.bin of=descriptor.bin bs=4096 count=1 + rm -f desc_me.bin + rm -f me_cleaner.py +} + +check_and_get_url descriptor.bin $KBL_DESCRIPTOR_URL $KBL_DESCRIPTOR_SHA "Intel Flash Descriptor" +check_binary descriptor.bin $KBL_DESCRIPTOR_SHA +get_and_patch_me_11 +check_binary me.bin $KBL_ME_SHA +apply_me_cleaner +get_and_split_fsp +check_binary fspm.bin $KBL_FSPM_SHA +check_binary fsps.bin $KBL_FSPS_SHA +check_and_get_url vbt.bin $KBL_VBT_URL $KBL_VBT_SHA "Video BIOS Table" +check_and_get_url cpu_microcode_blob.bin $KBL_UCODE_URL $KBL_UCODE_SHA "Intel Microcode Update" + +echo "" +echo "Blobs have been downloaded/verified and are ready for use" diff --git a/blobs/librem_kbl/readme.md b/blobs/librem_kbl/readme.md new file mode 100644 index 000000000..427af8650 --- /dev/null +++ b/blobs/librem_kbl/readme.md @@ -0,0 +1,20 @@ +To build for the Librem 3rd generation (Librem 13 v4 and Librem 15 vv4), +we need to have the following files in this folder: +* cpu_microcode_blob.bin - CPU Microcode +* descriptor.bin - The Intel Flash Descriptor +* fspm.bin - FSP 2.0 Memory Init blob +* fsps.bin - FSP 2.0 Silicon Init blob +* me.bin - Intel Management Engine + +To get the binaries, run the get_blobs.sh script which will download and +verify all of the files' hashes, then run me_cleaner on the descriptor.bin and me.bin. + +The script depends on: wget sha256sum python2.7 bspatch pv + +You can now compile the image with: + +``` +make BOARD=librem13v4 +or +make BOARD=librem15v4 +``` From da2d2672208992f3e323d2c8a3a21598cad3fc84 Mon Sep 17 00:00:00 2001 From: Matt DeVillier Date: Wed, 30 Jan 2019 21:17:08 -0600 Subject: [PATCH 081/102] patches/coreboot: add support for librem 13v4/15v4 boards Signed-off-by: Matt DeVillier --- ..._skl-add-support-for-13v4-15v4-board.patch | 92 +++++++++++++++++++ 1 file changed, 92 insertions(+) create mode 100644 patches/coreboot-4.8.1/0001-mb-purism-librem_skl-add-support-for-13v4-15v4-board.patch diff --git a/patches/coreboot-4.8.1/0001-mb-purism-librem_skl-add-support-for-13v4-15v4-board.patch b/patches/coreboot-4.8.1/0001-mb-purism-librem_skl-add-support-for-13v4-15v4-board.patch new file mode 100644 index 000000000..798fd8462 --- /dev/null +++ b/patches/coreboot-4.8.1/0001-mb-purism-librem_skl-add-support-for-13v4-15v4-board.patch @@ -0,0 +1,92 @@ +From f45b4209ecbd231e3f5077eb90ce29bdc83bd6b3 Mon Sep 17 00:00:00 2001 +From: Matt DeVillier +Date: Fri, 18 Jan 2019 22:57:33 -0600 +Subject: [PATCH 1/2] mb/purism/librem_skl: add support for 13v4/15v4 boards + +Add support for Kabylake Librem 13v4/15v4 boards, reusing existing 13v2/15v3 +variants since board design unchanged (only SoC). +Adjust identification strings, add Kabylake VGA PCI ID. + +Signed-off-by: Matt DeVillier +--- + src/mainboard/purism/librem_skl/Kconfig | 16 +++++++++++++--- + src/mainboard/purism/librem_skl/Kconfig.name | 8 ++++++++ + 2 files changed, 21 insertions(+), 3 deletions(-) + +diff --git a/src/mainboard/purism/librem_skl/Kconfig b/src/mainboard/purism/librem_skl/Kconfig +index bbb6b7443f..36fe04da06 100644 +--- a/src/mainboard/purism/librem_skl/Kconfig ++++ b/src/mainboard/purism/librem_skl/Kconfig +@@ -25,6 +25,8 @@ config VARIANT_DIR + string + default "librem13v2" if BOARD_PURISM_LIBREM13_V2 + default "librem15v3" if BOARD_PURISM_LIBREM15_V3 ++ default "librem13v2" if BOARD_PURISM_LIBREM13_V4 ++ default "librem15v3" if BOARD_PURISM_LIBREM15_V4 + + config MAINBOARD_VENDOR + string +@@ -34,16 +36,22 @@ config MAINBOARD_FAMILY + string + default "Librem 13" if BOARD_PURISM_LIBREM13_V2 + default "Librem 15" if BOARD_PURISM_LIBREM15_V3 ++ default "Librem 13" if BOARD_PURISM_LIBREM13_V4 ++ default "Librem 15" if BOARD_PURISM_LIBREM15_V4 + + config MAINBOARD_PART_NUMBER + string + default "Librem 13 v2" if BOARD_PURISM_LIBREM13_V2 + default "Librem 15 v3" if BOARD_PURISM_LIBREM15_V3 ++ default "Librem 13 v4" if BOARD_PURISM_LIBREM13_V4 ++ default "Librem 15 v4" if BOARD_PURISM_LIBREM15_V4 + + config MAINBOARD_VERSION + string + default "2.0" if BOARD_PURISM_LIBREM13_V2 + default "3.0" if BOARD_PURISM_LIBREM15_V3 ++ default "4.0" if BOARD_PURISM_LIBREM13_V4 ++ default "4.0" if BOARD_PURISM_LIBREM15_V4 + + config MAINBOARD_DIR + string +@@ -51,8 +59,7 @@ config MAINBOARD_DIR + + config DEVICETREE + string +- default "variants/librem13v2/devicetree.cb" if BOARD_PURISM_LIBREM13_V2 +- default "variants/librem15v3/devicetree.cb" if BOARD_PURISM_LIBREM15_V3 ++ default "variants/$(CONFIG_VARIANT_DIR)/devicetree.cb" + + config MAX_CPUS + int +@@ -66,7 +73,10 @@ config NO_POST + + config VGA_BIOS_ID + string +- default "8086,1916" ++ default "8086,1916" if BOARD_PURISM_LIBREM13_V2 ++ default "8086,1916" if BOARD_PURISM_LIBREM15_V3 ++ default "8086,5916" if BOARD_PURISM_LIBREM13_V4 ++ default "8086,5916" if BOARD_PURISM_LIBREM15_V4 + + config DIMM_MAX + int +diff --git a/src/mainboard/purism/librem_skl/Kconfig.name b/src/mainboard/purism/librem_skl/Kconfig.name +index 3f43f68752..6a66e45950 100644 +--- a/src/mainboard/purism/librem_skl/Kconfig.name ++++ b/src/mainboard/purism/librem_skl/Kconfig.name +@@ -5,3 +5,11 @@ config BOARD_PURISM_LIBREM13_V2 + config BOARD_PURISM_LIBREM15_V3 + bool "Librem 15 v3" + select BOARD_PURISM_BASEBOARD_LIBREM_SKL ++ ++config BOARD_PURISM_LIBREM13_V4 ++ bool "Librem 13 v4" ++ select BOARD_PURISM_BASEBOARD_LIBREM_SKL ++ ++config BOARD_PURISM_LIBREM15_V4 ++ bool "Librem 15 v4" ++ select BOARD_PURISM_BASEBOARD_LIBREM_SKL +-- +2.19.1 + From 9aaa25c882369bbe30f56d63cef8d49feac1bb13 Mon Sep 17 00:00:00 2001 From: Matt DeVillier Date: Wed, 30 Jan 2019 20:18:33 -0600 Subject: [PATCH 082/102] coreboot/config: add librem 13v4/15v4 as clones of 13v2/15v3 Adjust blobs paths for kbl vs skl, adjust board names Signed-off-by: Matt DeVillier --- config/coreboot-librem13v4.config | 32 +++++++++++++++++++++++++++++++ config/coreboot-librem15v4.config | 32 +++++++++++++++++++++++++++++++ 2 files changed, 64 insertions(+) create mode 100644 config/coreboot-librem13v4.config create mode 100644 config/coreboot-librem15v4.config diff --git a/config/coreboot-librem13v4.config b/config/coreboot-librem13v4.config new file mode 100644 index 000000000..809e095a4 --- /dev/null +++ b/config/coreboot-librem13v4.config @@ -0,0 +1,32 @@ +CONFIG_LOCALVERSION="4.8.1-Purism-1-heads-beta" +CONFIG_USE_BLOBS=y +CONFIG_MEASURED_BOOT=y +CONFIG_VENDOR_PURISM=y +CONFIG_CBFS_SIZE=0xe00000 +CONFIG_MAINBOARD_SERIAL_NUMBER="Unknown Serial Number" +CONFIG_HAVE_IFD_BIN=y +CONFIG_HAVE_ME_BIN=y +# CONFIG_POST_IO is not set +# CONFIG_POST_DEVICE is not set +# CONFIG_DRIVERS_UART_8250IO is not set +CONFIG_IFD_BIN_PATH="../../blobs/librem_kbl/descriptor.bin" +CONFIG_ME_BIN_PATH="../../blobs/librem_kbl/me.bin" +CONFIG_ADD_FSP_BINARIES=y +CONFIG_FSP_M_FILE="../../blobs/librem_kbl/fspm.bin" +CONFIG_FSP_S_FILE="../../blobs/librem_kbl/fsps.bin" +CONFIG_BOARD_PURISM_LIBREM13_V4=y +# CONFIG_NO_POST is not set +CONFIG_CPU_UCODE_BINARIES="../../blobs/librem_kbl/cpu_microcode_blob.bin" +CONFIG_NO_GFX_INIT=y +CONFIG_INTEL_GMA_ADD_VBT_DATA_FILE=y +CONFIG_INTEL_GMA_VBT_FILE="../../blobs/librem_kbl/vbt.bin" +CONFIG_DISPLAY_FSP_CALLS_AND_STATUS=y +CONFIG_FSP_M_XIP=y +# CONFIG_DRIVERS_INTEL_WIFI is not set +CONFIG_DEFAULT_CONSOLE_LOGLEVEL_8=y +CONFIG_PAYLOAD_LINUX=y +CONFIG_PAYLOAD_FILE="../../build/librem13v4/bzImage" +CONFIG_LINUX_COMMAND_LINE="intel_iommu=on iommu=pt quiet loglevel=3" +CONFIG_LINUX_INITRD="../../build/librem13v4/initrd.cpio.xz" +CONFIG_COREINFO_SECONDARY_PAYLOAD=y +CONFIG_MEMTEST_SECONDARY_PAYLOAD=y diff --git a/config/coreboot-librem15v4.config b/config/coreboot-librem15v4.config new file mode 100644 index 000000000..12b51fa7e --- /dev/null +++ b/config/coreboot-librem15v4.config @@ -0,0 +1,32 @@ +CONFIG_LOCALVERSION="4.8.1-Purism-1-heads-beta" +CONFIG_USE_BLOBS=y +CONFIG_MEASURED_BOOT=y +CONFIG_VENDOR_PURISM=y +CONFIG_CBFS_SIZE=0xe00000 +CONFIG_MAINBOARD_SERIAL_NUMBER="Unknown Serial Number" +CONFIG_HAVE_IFD_BIN=y +CONFIG_HAVE_ME_BIN=y +# CONFIG_POST_IO is not set +# CONFIG_POST_DEVICE is not set +# CONFIG_DRIVERS_UART_8250IO is not set +CONFIG_IFD_BIN_PATH="../../blobs/librem_kbl/descriptor.bin" +CONFIG_ME_BIN_PATH="../../blobs/librem_kbl/me.bin" +CONFIG_ADD_FSP_BINARIES=y +CONFIG_FSP_M_FILE="../../blobs/librem_kbl/fspm.bin" +CONFIG_FSP_S_FILE="../../blobs/librem_kbl/fsps.bin" +CONFIG_BOARD_PURISM_LIBREM15_V4=y +# CONFIG_NO_POST is not set +CONFIG_CPU_UCODE_BINARIES="../../blobs/librem_kbl/cpu_microcode_blob.bin" +CONFIG_NO_GFX_INIT=y +CONFIG_INTEL_GMA_ADD_VBT_DATA_FILE=y +CONFIG_INTEL_GMA_VBT_FILE="../../blobs/librem_kbl/vbt.bin" +CONFIG_DISPLAY_FSP_CALLS_AND_STATUS=y +CONFIG_FSP_M_XIP=y +# CONFIG_DRIVERS_INTEL_WIFI is not set +CONFIG_DEFAULT_CONSOLE_LOGLEVEL_8=y +CONFIG_PAYLOAD_LINUX=y +CONFIG_PAYLOAD_FILE="../../build/librem15v4/bzImage" +CONFIG_LINUX_COMMAND_LINE="intel_iommu=on iommu=pt quiet loglevel=3" +CONFIG_LINUX_INITRD="../../build/librem15v4/initrd.cpio.xz" +CONFIG_COREINFO_SECONDARY_PAYLOAD=y +CONFIG_MEMTEST_SECONDARY_PAYLOAD=y From 398f75f19f2c5fe9d3d2132fadd7e6d9c6f1075e Mon Sep 17 00:00:00 2001 From: Matt DeVillier Date: Wed, 30 Jan 2019 20:19:25 -0600 Subject: [PATCH 083/102] heads/config: add librem 13v4/15v4 as clones of 13v2/15v3 Signed-off-by: Matt DeVillier --- boards/librem13v4/librem13v4.config | 37 +++++++++++++++++++++++++++++ boards/librem15v4/librem15v4.config | 37 +++++++++++++++++++++++++++++ 2 files changed, 74 insertions(+) create mode 100644 boards/librem13v4/librem13v4.config create mode 100644 boards/librem15v4/librem15v4.config diff --git a/boards/librem13v4/librem13v4.config b/boards/librem13v4/librem13v4.config new file mode 100644 index 000000000..56db420a6 --- /dev/null +++ b/boards/librem13v4/librem13v4.config @@ -0,0 +1,37 @@ +# Configuration for a librem13v4 +CONFIG_LINUX_CONFIG=config/linux-librem13v2.config +CONFIG_COREBOOT_CONFIG=config/coreboot-librem13v4.config + +export CONFIG_COREBOOT=y +CONFIG_CRYPTSETUP=y +CONFIG_FLASHROM=y +CONFIG_FLASHTOOLS=y +CONFIG_GPG2=y +CONFIG_KEXEC=y +CONFIG_UTIL_LINUX=y +CONFIG_LVM2=y +CONFIG_MBEDTLS=y +CONFIG_PCIUTILS=y +CONFIG_POPT=y +CONFIG_QRENCODE=y +CONFIG_TPMTOTP=y + +#CONFIG_SLANG=y +#CONFIG_NEWT=y +CONFIG_CAIRO=y +CONFIG_FBWHIPTAIL=y +CONFIG_LIBREMKEY=y + +CONFIG_LINUX_USB=y + +export CONFIG_TPM=y +export CONFIG_BOOTSCRIPT=/bin/gui-init +export CONFIG_BOOT_REQ_HASH=n +export CONFIG_BOOT_REQ_ROLLBACK=n +export CONFIG_BOOT_KERNEL_ADD="iommu=pt" +export CONFIG_BOOT_KERNEL_REMOVE="" +export CONFIG_BOOT_DEV="/dev/sda1" +export CONFIG_BOOT_GUI_MENU_NAME="Purism Librem 13v2 Heads Boot Menu" +export CONFIG_USB_BOOT_DEV="/dev/sdb1" +export CONFIG_WARNING_BG_COLOR="--background-gradient 0 0 0 150 125 0" +export CONFIG_ERROR_BG_COLOR="--background-gradient 0 0 0 150 0 0" diff --git a/boards/librem15v4/librem15v4.config b/boards/librem15v4/librem15v4.config new file mode 100644 index 000000000..7e29826c2 --- /dev/null +++ b/boards/librem15v4/librem15v4.config @@ -0,0 +1,37 @@ +# Configuration for a librem15v4 + +# The L15v4 Linux config is the same as the L13v2 linux config +CONFIG_LINUX_CONFIG=config/linux-librem13v2.config +CONFIG_COREBOOT_CONFIG=config/coreboot-librem15v4.config + +export CONFIG_COREBOOT=y +CONFIG_CRYPTSETUP=y +CONFIG_FLASHROM=y +CONFIG_FLASHTOOLS=y +CONFIG_GPG2=y +CONFIG_KEXEC=y +CONFIG_UTIL_LINUX=y +CONFIG_LVM2=y +CONFIG_MBEDTLS=y +CONFIG_PCIUTILS=y +CONFIG_POPT=y +CONFIG_QRENCODE=y +CONFIG_TPMTOTP=y + +#CONFIG_SLANG=y +#CONFIG_NEWT=y +CONFIG_CAIRO=y +CONFIG_FBWHIPTAIL=y +CONFIG_LIBREMKEY=y + +CONFIG_LINUX_USB=y + +export CONFIG_TPM=y +export CONFIG_BOOTSCRIPT=/bin/gui-init +export CONFIG_BOOT_REQ_HASH=n +export CONFIG_BOOT_REQ_ROLLBACK=n +export CONFIG_BOOT_KERNEL_ADD="iommu=pt" +export CONFIG_BOOT_KERNEL_REMOVE="" +export CONFIG_BOOT_DEV="/dev/sda1" +export CONFIG_BOOT_GUI_MENU_NAME="Purism Librem 15v4 Heads Boot Menu" +export CONFIG_USB_BOOT_DEV="/dev/sdb1" From f5355815d920f7c77421a5c392d49fcc4d89ec7e Mon Sep 17 00:00:00 2001 From: Matt DeVillier Date: Wed, 30 Jan 2019 23:27:30 -0600 Subject: [PATCH 084/102] patches/coreboot: add proper IOMMU/RMRR support These two patches add the capability for coreboot to generate the RMRR ACPI tables needed for proper IOMMU support. These patches allow us to use 'intel_iommu=on' vs 'iommu=pt' Signed-off-by: Matt DeVillier --- ...-acpi-Add-DMAR-RMRR-helper-functions.patch | 357 ++++++++++++++++++ ...tel-skylake-Generate-ACPI-RMRR-table.patch | 80 ++++ 2 files changed, 437 insertions(+) create mode 100644 patches/coreboot-4.8.1/0002-arch-x86-acpi-Add-DMAR-RMRR-helper-functions.patch create mode 100644 patches/coreboot-4.8.1/0003-soc-intel-skylake-Generate-ACPI-RMRR-table.patch diff --git a/patches/coreboot-4.8.1/0002-arch-x86-acpi-Add-DMAR-RMRR-helper-functions.patch b/patches/coreboot-4.8.1/0002-arch-x86-acpi-Add-DMAR-RMRR-helper-functions.patch new file mode 100644 index 000000000..128e609d4 --- /dev/null +++ b/patches/coreboot-4.8.1/0002-arch-x86-acpi-Add-DMAR-RMRR-helper-functions.patch @@ -0,0 +1,357 @@ +From e40c2710e715fc7fed344189227bd048652268f1 Mon Sep 17 00:00:00 2001 +From: Matt DeVillier +Date: Thu, 29 Mar 2018 14:59:57 +0200 +Subject: [PATCH 2/2] arch/x86/acpi: Add DMAR RMRR helper functions + +Add DMAR RMRR table entry and helper functions, using the existing +DRHD functions as a model. As the DRHD device scope (DS) functions +aren't DRHD-specific, genericize them to be used with RMRR tables as +well. Correct DRHD bar size to match table entry in creator function, +as noted in comments from patchset below. + +Adapted from/supersedes https://review.coreboot.org/25445 + +Change-Id: I912b1d7244ca4dd911bb6629533d453b1b4a06be +Signed-off-by: Matt DeVillier +Reviewed-on: https://review.coreboot.org/27269 +Reviewed-by: Youness Alaoui +Reviewed-by: Nico Huber +Reviewed-by: Jay Talbott +Tested-by: build bot (Jenkins) +--- + src/arch/x86/acpi.c | 40 ++++++++++++++++++------ + src/arch/x86/include/arch/acpi.h | 22 ++++++++++--- + src/northbridge/intel/gm45/acpi.c | 14 ++++----- + src/northbridge/intel/haswell/acpi.c | 6 ++-- + src/northbridge/intel/sandybridge/acpi.c | 8 ++--- + src/soc/intel/broadwell/acpi.c | 6 ++-- + src/soc/intel/fsp_broadwell_de/acpi.c | 8 ++--- + src/soc/intel/skylake/acpi.c | 6 ++-- + 8 files changed, 71 insertions(+), 39 deletions(-) + +diff --git a/src/arch/x86/acpi.c b/src/arch/x86/acpi.c +index 8b6b2c1d28..60d2879219 100644 +--- a/src/arch/x86/acpi.c ++++ b/src/arch/x86/acpi.c +@@ -449,7 +449,7 @@ void acpi_create_dmar(acpi_dmar_t *dmar, enum dmar_flags flags, + } + + unsigned long acpi_create_dmar_drhd(unsigned long current, u8 flags, +- u16 segment, u32 bar) ++ u16 segment, u64 bar) + { + dmar_entry_t *drhd = (dmar_entry_t *)current; + memset(drhd, 0, sizeof(*drhd)); +@@ -462,6 +462,20 @@ unsigned long acpi_create_dmar_drhd(unsigned long current, u8 flags, + return drhd->length; + } + ++unsigned long acpi_create_dmar_rmrr(unsigned long current, u16 segment, ++ u64 bar, u64 limit) ++{ ++ dmar_rmrr_entry_t *rmrr = (dmar_rmrr_entry_t *)current; ++ memset(rmrr, 0, sizeof(*rmrr)); ++ rmrr->type = DMAR_RMRR; ++ rmrr->length = sizeof(*rmrr); /* will be fixed up later */ ++ rmrr->segment = segment; ++ rmrr->bar = bar; ++ rmrr->limit = limit; ++ ++ return rmrr->length; ++} ++ + unsigned long acpi_create_dmar_atsr(unsigned long current, u8 flags, + u16 segment) + { +@@ -481,13 +495,19 @@ void acpi_dmar_drhd_fixup(unsigned long base, unsigned long current) + drhd->length = current - base; + } + ++void acpi_dmar_rmrr_fixup(unsigned long base, unsigned long current) ++{ ++ dmar_rmrr_entry_t *rmrr = (dmar_rmrr_entry_t *)base; ++ rmrr->length = current - base; ++} ++ + void acpi_dmar_atsr_fixup(unsigned long base, unsigned long current) + { + dmar_atsr_entry_t *atsr = (dmar_atsr_entry_t *)base; + atsr->length = current - base; + } + +-static unsigned long acpi_create_dmar_drhd_ds(unsigned long current, ++static unsigned long acpi_create_dmar_ds(unsigned long current, + enum dev_scope_type type, u8 enumeration_id, u8 bus, u8 dev, u8 fn) + { + /* we don't support longer paths yet */ +@@ -505,31 +525,31 @@ static unsigned long acpi_create_dmar_drhd_ds(unsigned long current, + return ds->length; + } + +-unsigned long acpi_create_dmar_drhd_ds_pci_br(unsigned long current, u8 bus, ++unsigned long acpi_create_dmar_ds_pci_br(unsigned long current, u8 bus, + u8 dev, u8 fn) + { +- return acpi_create_dmar_drhd_ds(current, ++ return acpi_create_dmar_ds(current, + SCOPE_PCI_SUB, 0, bus, dev, fn); + } + +-unsigned long acpi_create_dmar_drhd_ds_pci(unsigned long current, u8 bus, ++unsigned long acpi_create_dmar_ds_pci(unsigned long current, u8 bus, + u8 dev, u8 fn) + { +- return acpi_create_dmar_drhd_ds(current, ++ return acpi_create_dmar_ds(current, + SCOPE_PCI_ENDPOINT, 0, bus, dev, fn); + } + +-unsigned long acpi_create_dmar_drhd_ds_ioapic(unsigned long current, ++unsigned long acpi_create_dmar_ds_ioapic(unsigned long current, + u8 enumeration_id, u8 bus, u8 dev, u8 fn) + { +- return acpi_create_dmar_drhd_ds(current, ++ return acpi_create_dmar_ds(current, + SCOPE_IOAPIC, enumeration_id, bus, dev, fn); + } + +-unsigned long acpi_create_dmar_drhd_ds_msi_hpet(unsigned long current, ++unsigned long acpi_create_dmar_ds_msi_hpet(unsigned long current, + u8 enumeration_id, u8 bus, u8 dev, u8 fn) + { +- return acpi_create_dmar_drhd_ds(current, ++ return acpi_create_dmar_ds(current, + SCOPE_MSI_HPET, enumeration_id, bus, dev, fn); + } + +diff --git a/src/arch/x86/include/arch/acpi.h b/src/arch/x86/include/arch/acpi.h +index 5480834eb2..5be2e6399e 100644 +--- a/src/arch/x86/include/arch/acpi.h ++++ b/src/arch/x86/include/arch/acpi.h +@@ -331,6 +331,15 @@ typedef struct dmar_entry { + u64 bar; + } __packed dmar_entry_t; + ++typedef struct dmar_rmrr_entry { ++ u16 type; ++ u16 length; ++ u16 reserved; ++ u16 segment; ++ u64 bar; ++ u64 limit; ++} __packed dmar_rmrr_entry_t; ++ + typedef struct dmar_atsr_entry { + u16 type; + u16 length; +@@ -738,19 +747,22 @@ unsigned long acpi_write_dbg2_pci_uart(acpi_rsdp_t *rsdp, unsigned long current, + void acpi_create_dmar(acpi_dmar_t *dmar, enum dmar_flags flags, + unsigned long (*acpi_fill_dmar)(unsigned long)); + unsigned long acpi_create_dmar_drhd(unsigned long current, u8 flags, +- u16 segment, u32 bar); ++ u16 segment, u64 bar); ++unsigned long acpi_create_dmar_rmrr(unsigned long current, u16 segment, ++ u64 bar, u64 limit); + unsigned long acpi_create_dmar_atsr(unsigned long current, u8 flags, + u16 segment); + void acpi_dmar_drhd_fixup(unsigned long base, unsigned long current); ++void acpi_dmar_rmrr_fixup(unsigned long base, unsigned long current); + void acpi_dmar_atsr_fixup(unsigned long base, unsigned long current); +-unsigned long acpi_create_dmar_drhd_ds_pci_br(unsigned long current, ++unsigned long acpi_create_dmar_ds_pci_br(unsigned long current, + u8 bus, u8 dev, u8 fn); +-unsigned long acpi_create_dmar_drhd_ds_pci(unsigned long current, ++unsigned long acpi_create_dmar_ds_pci(unsigned long current, + u8 bus, u8 dev, u8 fn); +-unsigned long acpi_create_dmar_drhd_ds_ioapic(unsigned long current, ++unsigned long acpi_create_dmar_ds_ioapic(unsigned long current, + u8 enumeration_id, + u8 bus, u8 dev, u8 fn); +-unsigned long acpi_create_dmar_drhd_ds_msi_hpet(unsigned long current, ++unsigned long acpi_create_dmar_ds_msi_hpet(unsigned long current, + u8 enumeration_id, + u8 bus, u8 dev, u8 fn); + void acpi_write_hest(acpi_hest_t *hest, +diff --git a/src/northbridge/intel/gm45/acpi.c b/src/northbridge/intel/gm45/acpi.c +index 73b098f610..d208eed4ab 100644 +--- a/src/northbridge/intel/gm45/acpi.c ++++ b/src/northbridge/intel/gm45/acpi.c +@@ -78,24 +78,24 @@ static unsigned long acpi_fill_dmar(unsigned long current) + + unsigned long tmp = current; + current += acpi_create_dmar_drhd(current, 0, 0, IOMMU_BASE1); +- current += acpi_create_dmar_drhd_ds_pci(current, 0, 0x1b, 0); ++ current += acpi_create_dmar_ds_pci(current, 0, 0x1b, 0); + acpi_dmar_drhd_fixup(tmp, current); + + if (stepping != STEPPING_B2) { + tmp = current; + current += acpi_create_dmar_drhd(current, 0, 0, IOMMU_BASE2); +- current += acpi_create_dmar_drhd_ds_pci(current, 0, 0x2, 0); +- current += acpi_create_dmar_drhd_ds_pci(current, 0, 0x2, 1); ++ current += acpi_create_dmar_ds_pci(current, 0, 0x2, 0); ++ current += acpi_create_dmar_ds_pci(current, 0, 0x2, 1); + acpi_dmar_drhd_fixup(tmp, current); + } + + if (me_active) { + tmp = current; + current += acpi_create_dmar_drhd(current, 0, 0, IOMMU_BASE3); +- current += acpi_create_dmar_drhd_ds_pci(current, 0, 0x3, 0); +- current += acpi_create_dmar_drhd_ds_pci(current, 0, 0x3, 1); +- current += acpi_create_dmar_drhd_ds_pci(current, 0, 0x3, 2); +- current += acpi_create_dmar_drhd_ds_pci(current, 0, 0x3, 3); ++ current += acpi_create_dmar_ds_pci(current, 0, 0x3, 0); ++ current += acpi_create_dmar_ds_pci(current, 0, 0x3, 1); ++ current += acpi_create_dmar_ds_pci(current, 0, 0x3, 2); ++ current += acpi_create_dmar_ds_pci(current, 0, 0x3, 3); + acpi_dmar_drhd_fixup(tmp, current); + } + +diff --git a/src/northbridge/intel/haswell/acpi.c b/src/northbridge/intel/haswell/acpi.c +index 9d76ba8ce2..3cd3bc0730 100644 +--- a/src/northbridge/intel/haswell/acpi.c ++++ b/src/northbridge/intel/haswell/acpi.c +@@ -85,7 +85,7 @@ static unsigned long acpi_fill_dmar(unsigned long current) + const unsigned long tmp = current; + + current += acpi_create_dmar_drhd(current, 0, 0, gfxvtbar); +- current += acpi_create_dmar_drhd_ds_pci(current, 0, 2, 0); ++ current += acpi_create_dmar_ds_pci(current, 0, 2, 0); + + acpi_dmar_drhd_fixup(tmp, current); + } +@@ -95,11 +95,11 @@ static unsigned long acpi_fill_dmar(unsigned long current) + const unsigned long tmp = current; + current += acpi_create_dmar_drhd(current, + DRHD_INCLUDE_PCI_ALL, 0, vtvc0bar); +- current += acpi_create_dmar_drhd_ds_ioapic(current, ++ current += acpi_create_dmar_ds_ioapic(current, + 2, PCH_IOAPIC_PCI_BUS, PCH_IOAPIC_PCI_SLOT, 0); + size_t i; + for (i = 0; i < 8; ++i) +- current += acpi_create_dmar_drhd_ds_msi_hpet(current, ++ current += acpi_create_dmar_ds_msi_hpet(current, + 0, PCH_HPET_PCI_BUS, + PCH_HPET_PCI_SLOT, i); + acpi_dmar_drhd_fixup(tmp, current); +diff --git a/src/northbridge/intel/sandybridge/acpi.c b/src/northbridge/intel/sandybridge/acpi.c +index 91ecac5956..88ac2b1e38 100644 +--- a/src/northbridge/intel/sandybridge/acpi.c ++++ b/src/northbridge/intel/sandybridge/acpi.c +@@ -74,19 +74,19 @@ static unsigned long acpi_fill_dmar(unsigned long current) + if (igfx && igfx->enabled) { + const unsigned long tmp = current; + current += acpi_create_dmar_drhd(current, 0, 0, IOMMU_BASE1); +- current += acpi_create_dmar_drhd_ds_pci(current, 0, 2, 0); +- current += acpi_create_dmar_drhd_ds_pci(current, 0, 2, 1); ++ current += acpi_create_dmar_ds_pci(current, 0, 2, 0); ++ current += acpi_create_dmar_ds_pci(current, 0, 2, 1); + acpi_dmar_drhd_fixup(tmp, current); + } + + const unsigned long tmp = current; + current += acpi_create_dmar_drhd(current, + DRHD_INCLUDE_PCI_ALL, 0, IOMMU_BASE2); +- current += acpi_create_dmar_drhd_ds_ioapic(current, ++ current += acpi_create_dmar_ds_ioapic(current, + 2, PCH_IOAPIC_PCI_BUS, PCH_IOAPIC_PCI_SLOT, 0); + size_t i; + for (i = 0; i < 8; ++i) +- current += acpi_create_dmar_drhd_ds_msi_hpet(current, ++ current += acpi_create_dmar_ds_msi_hpet(current, + 0, PCH_HPET_PCI_BUS, PCH_HPET_PCI_SLOT, i); + acpi_dmar_drhd_fixup(tmp, current); + +diff --git a/src/soc/intel/broadwell/acpi.c b/src/soc/intel/broadwell/acpi.c +index 162542fe3e..a1df089fd7 100644 +--- a/src/soc/intel/broadwell/acpi.c ++++ b/src/soc/intel/broadwell/acpi.c +@@ -586,7 +586,7 @@ static unsigned long acpi_fill_dmar(unsigned long current) + const unsigned long tmp = current; + + current += acpi_create_dmar_drhd(current, 0, 0, gfxvtbar); +- current += acpi_create_dmar_drhd_ds_pci(current, 0, 2, 0); ++ current += acpi_create_dmar_ds_pci(current, 0, 2, 0); + + acpi_dmar_drhd_fixup(tmp, current); + } +@@ -596,11 +596,11 @@ static unsigned long acpi_fill_dmar(unsigned long current) + const unsigned long tmp = current; + current += acpi_create_dmar_drhd(current, + DRHD_INCLUDE_PCI_ALL, 0, vtvc0bar); +- current += acpi_create_dmar_drhd_ds_ioapic(current, ++ current += acpi_create_dmar_ds_ioapic(current, + 2, PCH_IOAPIC_PCI_BUS, PCH_IOAPIC_PCI_SLOT, 0); + size_t i; + for (i = 0; i < 8; ++i) +- current += acpi_create_dmar_drhd_ds_msi_hpet(current, ++ current += acpi_create_dmar_ds_msi_hpet(current, + 0, PCH_HPET_PCI_BUS, + PCH_HPET_PCI_SLOT, i); + acpi_dmar_drhd_fixup(tmp, current); +diff --git a/src/soc/intel/fsp_broadwell_de/acpi.c b/src/soc/intel/fsp_broadwell_de/acpi.c +index 4c6417d5d8..8bb4596ff5 100644 +--- a/src/soc/intel/fsp_broadwell_de/acpi.c ++++ b/src/soc/intel/fsp_broadwell_de/acpi.c +@@ -331,12 +331,12 @@ static unsigned long acpi_fill_dmar(unsigned long current) + current += acpi_create_dmar_drhd(current, + DRHD_INCLUDE_PCI_ALL, 0, vtbar); + /* The IIO I/O APIC is fixed on PCI 00:05.4 on Broadwell-DE */ +- current += acpi_create_dmar_drhd_ds_ioapic(current, ++ current += acpi_create_dmar_ds_ioapic(current, + 9, 0, 5, 4); + /* Get the PCI BDF for the PCH I/O APIC */ + dev = dev_find_slot(0, LPC_DEV_FUNC); + bdf = pci_read_config16(dev, 0x6c); +- current += acpi_create_dmar_drhd_ds_ioapic(current, ++ current += acpi_create_dmar_ds_ioapic(current, + 8, (bdf >> 8), PCI_SLOT(bdf), PCI_FUNC(bdf)); + + /* +@@ -365,7 +365,7 @@ static unsigned long acpi_fill_dmar(unsigned long current) + /* Create one HPET entry in DMAR for every unique HPET PCI path. */ + for (i = 0; i < ARRAY_SIZE(hpet_bdf); i++) { + if (hpet_bdf[i]) +- current += acpi_create_dmar_drhd_ds_msi_hpet(current, ++ current += acpi_create_dmar_ds_msi_hpet(current, + 0, (hpet_bdf[i] >> 8), PCI_SLOT(hpet_bdf[i]), + PCI_FUNC(hpet_bdf[i])); + } +@@ -380,7 +380,7 @@ static unsigned long acpi_fill_dmar(unsigned long current) + dev = dev_find_class(PCI_CLASS_BRIDGE_PCI << 8, dev); + if (dev && dev->bus->secondary == 0 && + PCI_SLOT(dev->path.pci.devfn) <= 3) +- current += acpi_create_dmar_drhd_ds_pci_br(current, ++ current += acpi_create_dmar_ds_pci_br(current, + dev->bus->secondary, + PCI_SLOT(dev->path.pci.devfn), + PCI_FUNC(dev->path.pci.devfn)); +diff --git a/src/soc/intel/skylake/acpi.c b/src/soc/intel/skylake/acpi.c +index 914b9d51a3..760be590a3 100644 +--- a/src/soc/intel/skylake/acpi.c ++++ b/src/soc/intel/skylake/acpi.c +@@ -551,7 +551,7 @@ static unsigned long acpi_fill_dmar(unsigned long current) + 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); ++ current += acpi_create_dmar_ds_pci(current, 0, 2, 0); + + acpi_dmar_drhd_fixup(tmp, current); + } +@@ -576,9 +576,9 @@ static unsigned long acpi_fill_dmar(unsigned long current) + + current += acpi_create_dmar_drhd(current, + DRHD_INCLUDE_PCI_ALL, 0, vtvc0bar); +- current += acpi_create_dmar_drhd_ds_ioapic(current, ++ current += acpi_create_dmar_ds_ioapic(current, + 2, ibdf >> 8, PCI_SLOT(ibdf), PCI_FUNC(ibdf)); +- current += acpi_create_dmar_drhd_ds_msi_hpet(current, ++ current += acpi_create_dmar_ds_msi_hpet(current, + 0, hbdf >> 8, PCI_SLOT(hbdf), PCI_FUNC(hbdf)); + + acpi_dmar_drhd_fixup(tmp, current); +-- +2.19.1 + diff --git a/patches/coreboot-4.8.1/0003-soc-intel-skylake-Generate-ACPI-RMRR-table.patch b/patches/coreboot-4.8.1/0003-soc-intel-skylake-Generate-ACPI-RMRR-table.patch new file mode 100644 index 000000000..ca6518160 --- /dev/null +++ b/patches/coreboot-4.8.1/0003-soc-intel-skylake-Generate-ACPI-RMRR-table.patch @@ -0,0 +1,80 @@ +From 7267021c2a36ecd92aafdad2cae9ecab09e7e20d Mon Sep 17 00:00:00 2001 +From: Matt DeVillier +Date: Mon, 25 Jun 2018 14:40:53 -0500 +Subject: [PATCH 3/3] soc/intel/skylake: Generate ACPI RMRR table + +An ACPI RMRR table is requried for IOMMU to work properly with an +iGPU (without using passthrough mode), so create one along with the +DRHD DMAR table if the iGPU is present and enabled. + +Test: build/boot google/chell and purism/librem13v2 with kernel +parameter 'intel_iommu=on' but without 'iommu=pt;' observe integrated +graphics functional without corruption. + +Change-Id: I202fb3eb8618f99d41f3d1c5bbb83b2ec982aca4 +Signed-off-by: Matt DeVillier +Reviewed-on: https://review.coreboot.org/27270 +Tested-by: build bot (Jenkins) +Reviewed-by: Nico Huber +Reviewed-by: Youness Alaoui +--- + .../common/block/include/intelblocks/systemagent.h | 2 ++ + .../intel/common/block/systemagent/systemagent_early.c | 2 +- + src/soc/intel/skylake/acpi.c | 10 +++++++++- + 3 files changed, 12 insertions(+), 2 deletions(-) + +diff --git a/src/soc/intel/common/block/include/intelblocks/systemagent.h b/src/soc/intel/common/block/include/intelblocks/systemagent.h +index a731b9cb0b..babf9cec95 100644 +--- a/src/soc/intel/common/block/include/intelblocks/systemagent.h ++++ b/src/soc/intel/common/block/include/intelblocks/systemagent.h +@@ -77,6 +77,8 @@ void enable_power_aware_intr(void); + uintptr_t sa_get_tolud_base(void); + /* API to get DSM size */ + size_t sa_get_dsm_size(void); ++/* API to get GSM base address */ ++uintptr_t sa_get_gsm_base(void); + /* API to get GSM size */ + size_t sa_get_gsm_size(void); + /* API to get TSEG base address */ +diff --git a/src/soc/intel/common/block/systemagent/systemagent_early.c b/src/soc/intel/common/block/systemagent/systemagent_early.c +index 609e1596c9..c1cef5daf1 100644 +--- a/src/soc/intel/common/block/systemagent/systemagent_early.c ++++ b/src/soc/intel/common/block/systemagent/systemagent_early.c +@@ -174,7 +174,7 @@ size_t sa_get_dsm_size(void) + return (prealloc_memory - 0xEF) * 4*MiB; + } + +-static uintptr_t sa_get_gsm_base(void) ++uintptr_t sa_get_gsm_base(void) + { + /* All regions concerned for have 1 MiB alignment. */ + return ALIGN_DOWN(pci_read_config32(SA_DEV_ROOT, BGSM), 1*MiB); +diff --git a/src/soc/intel/skylake/acpi.c b/src/soc/intel/skylake/acpi.c +index 760be590a3..eac9e0ac91 100644 +--- a/src/soc/intel/skylake/acpi.c ++++ b/src/soc/intel/skylake/acpi.c +@@ -548,12 +548,20 @@ static unsigned long acpi_fill_dmar(unsigned long current) + /* iGFX has to be enabled, GFXVTBAR set and in 32-bit space. */ + if (igfx_dev && igfx_dev->enabled && gfxvten && + gfx_vtbar && !MCHBAR32(GFXVTBAR + 4)) { +- const unsigned long tmp = current; ++ unsigned long tmp = current; + + current += acpi_create_dmar_drhd(current, 0, 0, gfx_vtbar); + current += acpi_create_dmar_ds_pci(current, 0, 2, 0); + + acpi_dmar_drhd_fixup(tmp, current); ++ ++ /* Add RMRR entry */ ++ tmp = current; ++ ++ current += acpi_create_dmar_rmrr(current, 0, ++ sa_get_gsm_base(), sa_get_tolud_base() - 1); ++ current += acpi_create_dmar_ds_pci(current, 0, 2, 0); ++ acpi_dmar_rmrr_fixup(tmp, current); + } + + struct device *const p2sb_dev = dev_find_slot(0, PCH_DEVFN_P2SB); +-- +2.19.1 + From 988724c39d04928f7b397f72ff21564e68945753 Mon Sep 17 00:00:00 2001 From: Matt DeVillier Date: Wed, 30 Jan 2019 23:33:52 -0600 Subject: [PATCH 085/102] configs/coreboot/librem*: remove iommu=pt from linux cmd line No longer needed with addition of IOMMU/RMRR patches Signed-off-by: Matt DeVillier --- config/coreboot-librem13v2.config | 2 +- config/coreboot-librem13v4.config | 2 +- config/coreboot-librem15v3.config | 2 +- config/coreboot-librem15v4.config | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/config/coreboot-librem13v2.config b/config/coreboot-librem13v2.config index fad72db67..b56ba9d32 100644 --- a/config/coreboot-librem13v2.config +++ b/config/coreboot-librem13v2.config @@ -26,7 +26,7 @@ CONFIG_FSP_M_XIP=y CONFIG_DEFAULT_CONSOLE_LOGLEVEL_8=y CONFIG_PAYLOAD_LINUX=y CONFIG_PAYLOAD_FILE="../../build/librem13v2/bzImage" -CONFIG_LINUX_COMMAND_LINE="intel_iommu=on iommu=pt quiet loglevel=3" +CONFIG_LINUX_COMMAND_LINE="intel_iommu=on quiet loglevel=3" CONFIG_LINUX_INITRD="../../build/librem13v2/initrd.cpio.xz" CONFIG_COREINFO_SECONDARY_PAYLOAD=y CONFIG_MEMTEST_SECONDARY_PAYLOAD=y diff --git a/config/coreboot-librem13v4.config b/config/coreboot-librem13v4.config index 809e095a4..c2935736c 100644 --- a/config/coreboot-librem13v4.config +++ b/config/coreboot-librem13v4.config @@ -26,7 +26,7 @@ CONFIG_FSP_M_XIP=y CONFIG_DEFAULT_CONSOLE_LOGLEVEL_8=y CONFIG_PAYLOAD_LINUX=y CONFIG_PAYLOAD_FILE="../../build/librem13v4/bzImage" -CONFIG_LINUX_COMMAND_LINE="intel_iommu=on iommu=pt quiet loglevel=3" +CONFIG_LINUX_COMMAND_LINE="intel_iommu=on quiet loglevel=3" CONFIG_LINUX_INITRD="../../build/librem13v4/initrd.cpio.xz" CONFIG_COREINFO_SECONDARY_PAYLOAD=y CONFIG_MEMTEST_SECONDARY_PAYLOAD=y diff --git a/config/coreboot-librem15v3.config b/config/coreboot-librem15v3.config index 218ea5f7c..bf5a2bc14 100644 --- a/config/coreboot-librem15v3.config +++ b/config/coreboot-librem15v3.config @@ -26,7 +26,7 @@ CONFIG_FSP_M_XIP=y CONFIG_DEFAULT_CONSOLE_LOGLEVEL_8=y CONFIG_PAYLOAD_LINUX=y CONFIG_PAYLOAD_FILE="../../build/librem15v3/bzImage" -CONFIG_LINUX_COMMAND_LINE="intel_iommu=on iommu=pt quiet loglevel=3" +CONFIG_LINUX_COMMAND_LINE="intel_iommu=on quiet loglevel=3" CONFIG_LINUX_INITRD="../../build/librem15v3/initrd.cpio.xz" CONFIG_COREINFO_SECONDARY_PAYLOAD=y CONFIG_MEMTEST_SECONDARY_PAYLOAD=y diff --git a/config/coreboot-librem15v4.config b/config/coreboot-librem15v4.config index 12b51fa7e..541d558a7 100644 --- a/config/coreboot-librem15v4.config +++ b/config/coreboot-librem15v4.config @@ -26,7 +26,7 @@ CONFIG_FSP_M_XIP=y CONFIG_DEFAULT_CONSOLE_LOGLEVEL_8=y CONFIG_PAYLOAD_LINUX=y CONFIG_PAYLOAD_FILE="../../build/librem15v4/bzImage" -CONFIG_LINUX_COMMAND_LINE="intel_iommu=on iommu=pt quiet loglevel=3" +CONFIG_LINUX_COMMAND_LINE="intel_iommu=on quiet loglevel=3" CONFIG_LINUX_INITRD="../../build/librem15v4/initrd.cpio.xz" CONFIG_COREINFO_SECONDARY_PAYLOAD=y CONFIG_MEMTEST_SECONDARY_PAYLOAD=y From 90ec5e9e2afd492af465f9b4bd21fa7d60e5bc03 Mon Sep 17 00:00:00 2001 From: Matt DeVillier Date: Wed, 30 Jan 2019 23:35:50 -0600 Subject: [PATCH 086/102] boards/librem*: replace iommu=pt with intel_iommu=on With addition of IOMMU/RMRR patches, passthru is no longer needed for proper IOMMU functionality Signed-off-by: Matt DeVillier --- boards/librem13v2/librem13v2.config | 2 +- boards/librem13v4/librem13v4.config | 2 +- boards/librem15v3/librem15v3.config | 2 +- boards/librem15v4/librem15v4.config | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/boards/librem13v2/librem13v2.config b/boards/librem13v2/librem13v2.config index 5d5db1cb5..eca005831 100644 --- a/boards/librem13v2/librem13v2.config +++ b/boards/librem13v2/librem13v2.config @@ -28,7 +28,7 @@ export CONFIG_TPM=y export CONFIG_BOOTSCRIPT=/bin/gui-init export CONFIG_BOOT_REQ_HASH=n export CONFIG_BOOT_REQ_ROLLBACK=n -export CONFIG_BOOT_KERNEL_ADD="iommu=pt" +export CONFIG_BOOT_KERNEL_ADD="intel_iommu=on" export CONFIG_BOOT_KERNEL_REMOVE="" export CONFIG_BOOT_DEV="/dev/sda1" export CONFIG_BOOT_GUI_MENU_NAME="Purism Librem 13v2 Heads Boot Menu" diff --git a/boards/librem13v4/librem13v4.config b/boards/librem13v4/librem13v4.config index 56db420a6..12fe04886 100644 --- a/boards/librem13v4/librem13v4.config +++ b/boards/librem13v4/librem13v4.config @@ -28,7 +28,7 @@ export CONFIG_TPM=y export CONFIG_BOOTSCRIPT=/bin/gui-init export CONFIG_BOOT_REQ_HASH=n export CONFIG_BOOT_REQ_ROLLBACK=n -export CONFIG_BOOT_KERNEL_ADD="iommu=pt" +export CONFIG_BOOT_KERNEL_ADD="intel_iommu=on" export CONFIG_BOOT_KERNEL_REMOVE="" export CONFIG_BOOT_DEV="/dev/sda1" export CONFIG_BOOT_GUI_MENU_NAME="Purism Librem 13v2 Heads Boot Menu" diff --git a/boards/librem15v3/librem15v3.config b/boards/librem15v3/librem15v3.config index 8cb378e3d..ee99c0cdf 100644 --- a/boards/librem15v3/librem15v3.config +++ b/boards/librem15v3/librem15v3.config @@ -30,7 +30,7 @@ export CONFIG_TPM=y export CONFIG_BOOTSCRIPT=/bin/gui-init export CONFIG_BOOT_REQ_HASH=n export CONFIG_BOOT_REQ_ROLLBACK=n -export CONFIG_BOOT_KERNEL_ADD="iommu=pt" +export CONFIG_BOOT_KERNEL_ADD="intel_iommu=on" export CONFIG_BOOT_KERNEL_REMOVE="" export CONFIG_BOOT_DEV="/dev/sda1" export CONFIG_BOOT_GUI_MENU_NAME="Purism Librem 15v3 Heads Boot Menu" diff --git a/boards/librem15v4/librem15v4.config b/boards/librem15v4/librem15v4.config index 7e29826c2..38041122e 100644 --- a/boards/librem15v4/librem15v4.config +++ b/boards/librem15v4/librem15v4.config @@ -30,7 +30,7 @@ export CONFIG_TPM=y export CONFIG_BOOTSCRIPT=/bin/gui-init export CONFIG_BOOT_REQ_HASH=n export CONFIG_BOOT_REQ_ROLLBACK=n -export CONFIG_BOOT_KERNEL_ADD="iommu=pt" +export CONFIG_BOOT_KERNEL_ADD="intel_iommu=on" export CONFIG_BOOT_KERNEL_REMOVE="" export CONFIG_BOOT_DEV="/dev/sda1" export CONFIG_BOOT_GUI_MENU_NAME="Purism Librem 15v4 Heads Boot Menu" From cd5d0a0c4bb90feb2b7e8bccc1efdc5e356d6a68 Mon Sep 17 00:00:00 2001 From: Kyle Rankin Date: Fri, 15 Feb 2019 10:16:43 -0800 Subject: [PATCH 087/102] Remove "pipefail" so unmatched greps don't cause script to exit --- initrd/bin/gpg-gui.sh | 1 - 1 file changed, 1 deletion(-) diff --git a/initrd/bin/gpg-gui.sh b/initrd/bin/gpg-gui.sh index f75661075..3025c6f1e 100755 --- a/initrd/bin/gpg-gui.sh +++ b/initrd/bin/gpg-gui.sh @@ -1,6 +1,5 @@ #!/bin/sh # -set -e -o pipefail . /etc/functions . /tmp/config From 1bb8184143d5240843e7fe994282d824bf1b8360 Mon Sep 17 00:00:00 2001 From: Thierry Laurion Date: Mon, 18 Feb 2019 21:10:45 -0500 Subject: [PATCH 088/102] qemu-coreboot board: switch back to generic init in non-FBWhiptail mode --- boards/qemu-coreboot/qemu-coreboot.config | 20 +++++++++++++++++--- 1 file changed, 17 insertions(+), 3 deletions(-) diff --git a/boards/qemu-coreboot/qemu-coreboot.config b/boards/qemu-coreboot/qemu-coreboot.config index 23f22c2f0..d670dc21a 100644 --- a/boards/qemu-coreboot/qemu-coreboot.config +++ b/boards/qemu-coreboot/qemu-coreboot.config @@ -21,8 +21,16 @@ CONFIG_GPG2=y CONFIG_LVM2=y CONFIG_MBEDTLS=y CONFIG_DROPBEAR=y -CONFIG_CAIRO=y -CONFIG_FBWHIPTAIL=y + +#Uncomment only one of the following block +#Required for graphical gui-init (FBWhiptail) +#CONFIG_CAIRO=y +#CONFIG_FBWHIPTAIL=y +# +#text-based init (generic-init and gui-init) +CONFIG_NEWT=y +CONFIG_SLANG=y + endif CONFIG_LINUX_ATA=y @@ -30,7 +38,13 @@ CONFIG_LINUX_AHCI=y CONFIG_LINUX_USB=y CONFIG_LINUX_E1000=y -export CONFIG_BOOTSCRIPT=/bin/gui-init +#Uncomment only one BOOTSCRIPT: +#Whiptail-based init (text-based or FBWhiptail) +#export CONFIG_BOOTSCRIPT=/bin/gui-init +# +#text-based original init: +export CONFIG_BOOTSCRIPT=/bin/generic-init + export CONFIG_TPM=n export CONFIG_BOOT_DEV="/dev/sda1" From 6794e9cdb5b1ea1aa8941297993e315b15628b19 Mon Sep 17 00:00:00 2001 From: "Christopher A. Williamson" Date: Tue, 19 Feb 2019 13:02:52 +0000 Subject: [PATCH 089/102] Add support for EXT2 (via the EXT4 driver) --- config/linux-kgpe-d16.config | 1 + config/linux-librem13v2.config | 1 + config/linux-linuxboot.config | 1 + config/linux-qemu.config | 1 + config/linux-x230.config | 1 + 5 files changed, 5 insertions(+) diff --git a/config/linux-kgpe-d16.config b/config/linux-kgpe-d16.config index c925feb6a..43c43bbc4 100644 --- a/config/linux-kgpe-d16.config +++ b/config/linux-kgpe-d16.config @@ -205,6 +205,7 @@ CONFIG_GENERIC_PHY=y # CONFIG_FIRMWARE_MEMMAP is not set # CONFIG_DMIID is not set CONFIG_EXT4_FS=y +CONFIG_EXT4_USE_FOR_EXT2=y # CONFIG_DNOTIFY is not set # CONFIG_INOTIFY_USER is not set CONFIG_ISO9660_FS=y diff --git a/config/linux-librem13v2.config b/config/linux-librem13v2.config index f107eb102..742841d35 100644 --- a/config/linux-librem13v2.config +++ b/config/linux-librem13v2.config @@ -204,6 +204,7 @@ CONFIG_GENERIC_PHY=y # CONFIG_FIRMWARE_MEMMAP is not set # CONFIG_DMIID is not set CONFIG_EXT4_FS=y +CONFIG_EXT4_USE_FOR_EXT2=y # CONFIG_DNOTIFY is not set # CONFIG_INOTIFY_USER is not set CONFIG_ISO9660_FS=y diff --git a/config/linux-linuxboot.config b/config/linux-linuxboot.config index bd692577d..e7c1555a7 100644 --- a/config/linux-linuxboot.config +++ b/config/linux-linuxboot.config @@ -254,6 +254,7 @@ CONFIG_GENERIC_PHY=y # CONFIG_BTT is not set CONFIG_DMI_SYSFS=y CONFIG_EXT4_FS=y +CONFIG_EXT4_USE_FOR_EXT2=y CONFIG_XFS_FS=y # CONFIG_DNOTIFY is not set # CONFIG_INOTIFY_USER is not set diff --git a/config/linux-qemu.config b/config/linux-qemu.config index 84d691107..5c6e50411 100644 --- a/config/linux-qemu.config +++ b/config/linux-qemu.config @@ -249,6 +249,7 @@ CONFIG_DMI_SYSFS=y CONFIG_GOOGLE_FIRMWARE=y CONFIG_GOOGLE_MEMCONSOLE_X86_LEGACY=y CONFIG_EXT4_FS=y +CONFIG_EXT4_USE_FOR_EXT2=y CONFIG_XFS_FS=y # CONFIG_DNOTIFY is not set # CONFIG_INOTIFY_USER is not set diff --git a/config/linux-x230.config b/config/linux-x230.config index 25855270d..d5aca989a 100644 --- a/config/linux-x230.config +++ b/config/linux-x230.config @@ -208,6 +208,7 @@ CONFIG_GENERIC_PHY=y CONFIG_GOOGLE_FIRMWARE=y CONFIG_GOOGLE_MEMCONSOLE_X86_LEGACY=y CONFIG_EXT4_FS=y +CONFIG_EXT4_USE_FOR_EXT2=y # CONFIG_DNOTIFY is not set # CONFIG_INOTIFY_USER is not set CONFIG_ISO9660_FS=y From cfddb4ed2e6fa481737fb44081f780643e354050 Mon Sep 17 00:00:00 2001 From: Kyle Rankin Date: Mon, 11 Feb 2019 14:29:13 -0800 Subject: [PATCH 090/102] Add GPG GUI It makes more logical sense for GPG functions to be split out into their own menu instead of being part of the "Flash" menu. This creates a gpg-gui.sh script and moves GPG options there while adding a few additional features (like listing keys and initial smartcard key generation support). --- initrd/bin/flash-gui.sh | 150 ------------------------ initrd/bin/gpg-gui.sh | 244 ++++++++++++++++++++++++++++++++++++++++ initrd/bin/gui-init | 26 ++++- 3 files changed, 265 insertions(+), 155 deletions(-) create mode 100755 initrd/bin/gpg-gui.sh diff --git a/initrd/bin/flash-gui.sh b/initrd/bin/flash-gui.sh index 775826e05..b8de9a23c 100755 --- a/initrd/bin/flash-gui.sh +++ b/initrd/bin/flash-gui.sh @@ -74,8 +74,6 @@ while true; do --menu 'Select the BIOS function to perform' 20 90 10 \ 'f' ' Flash the BIOS with a new ROM' \ 'c' ' Flash the BIOS with a new cleaned ROM' \ - 'a' ' Add GPG key to BIOS image' \ - 'r' ' Add GPG key to running BIOS' \ 'x' ' Exit' \ 2>/tmp/whiptail || recovery "GUI menu failed" @@ -115,154 +113,6 @@ while true; do fi fi ;; - "a" ) - if (whiptail --title 'ROM and GPG public key required' \ - --yesno "This requires you insert a USB drive containing:\n* Your GPG public key (*.key or *.asc)\n* Your BIOS image (*.rom)\n\nAfter you select these files, this program will reflash your BIOS\n\nDo you want to proceed?" 16 90) then - mount_usb - if grep -q /media /proc/mounts ; then - find /media -name '*.key' > /tmp/filelist.txt - find /media -name '*.asc' >> /tmp/filelist.txt - file_selector "/tmp/filelist.txt" "Choose your GPG public key" - if [ "$FILE" == "" ]; then - return - else - PUBKEY=$FILE - fi - - find /media -name '*.rom' > /tmp/filelist.txt - file_selector "/tmp/filelist.txt" "Choose the ROM to load your key onto" - if [ "$FILE" == "" ]; then - return - else - ROM=$FILE - fi - - cat "$PUBKEY" | gpg --import - #update /.gnupg/trustdb.gpg to ultimately trust all user provided public keys - gpg --list-keys --fingerprint --with-colons |sed -E -n -e 's/^fpr:::::::::([0-9A-F]+):$/\1:6:/p' |gpg --import-ownertrust - gpg --update-trust - - cp "$ROM" /tmp/gpg-gui.rom - if (cbfs -o /tmp/gpg-gui.rom -l | grep -q "heads/initrd/.gnupg/pubring.kbx"); then - cbfs -o /tmp/gpg-gui.rom -d "heads/initrd/.gnupg/pubring.kbx" - if (cbfs -o /tmp/gpg-gui.rom -l | grep -q "heads/initrd/.gnupg/pubring.gpg"); then - cbfs -o /tmp/gpg-gui.rom -d "heads/initrd/.gnupg/pubring.gpg" - if [ -e /.gnupg/pubring.gpg ];then - rm /.gnupg/pubring.gpg - fi - fi - fi - - #to be compatible with gpgv1 - if [ -e /.gnupg/pubring.kbx ];then - cbfs -o /tmp/gpg-gui.rom -a "heads/initrd/.gnupg/pubring.kbx" -f /.gnupg/pubring.kbx - if [ -e /.gnupg/pubring.gpg ];then - rm /.gnupg/pubring.gpg - fi - fi - if [ -e /.gnupg/pubring.gpg ];then - cbfs -o /tmp/gpg-gui.rom -a "heads/initrd/.gnupg/pubring.gpg" -f /.gnupg/pubring.gpg - fi - - if (cbfs -o /tmp/gpg-gui.rom -l | grep -q "heads/initrd/.gnupg/trustdb.gpg") then - cbfs -o /tmp/gpg-gui.rom -d "heads/initrd/.gnupg/trustdb.gpg" - fi - cbfs -o /tmp/gpg-gui.rom -a "heads/initrd/.gnupg/trustdb.gpg" -f /.gnupg/trustdb.gpg - - #Remove old method owner trust exported file - if (cbfs -o /tmp/gpg-gui.rom -l | grep -q "heads/initrd/.gnupg/otrust.txt") then - cbfs -o /tmp/gpg-gui.rom -d "heads/initrd/.gnupg/otrust.txt" - fi - - if (whiptail --title 'Flash ROM?' \ - --yesno "This will replace your old ROM with $ROM\n\nDo you want to proceed?" 16 90) then - /bin/flash.sh /tmp/gpg-gui.rom - whiptail --title 'ROM Flashed Successfully' \ - --msgbox "$ROM flashed successfully.\n\nIf your keys have changed, be sure to re-sign all files in /boot\nafter you reboot.\n\nPress Enter to reboot" 16 60 - umount /media - /bin/reboot - else - exit 0 - fi - fi - fi - ;; - "r" ) - if (whiptail --title 'GPG public key required' \ - --yesno "Flashing the running BIOS requires you insert a USB drive containing:\n* Your GPG public key (*.key or *.asc)\n\nAfter you select this file, this program will copy and reflash your BIOS\n\nDo you want to proceed?" 16 90) then - mount_usb - if grep -q /media /proc/mounts ; then - find /media -name '*.key' > /tmp/filelist.txt - find /media -name '*.asc' >> /tmp/filelist.txt - file_selector "/tmp/filelist.txt" "Choose your GPG public key" - PUBKEY=$FILE - - /bin/flash.sh -r /tmp/gpg-gui.rom - if [ ! -s /tmp/gpg-gui.rom ]; then - whiptail $CONFIG_ERROR_BG_COLOR --title 'ERROR: BIOS Read Failed!' \ - --msgbox "Unable to read BIOS" 16 60 - exit 1 - fi - - cat "$PUBKEY" | gpg --import - #update /.gnupg/trustdb.gpg to ultimately trust all user provided public keys - gpg --list-keys --fingerprint --with-colons |sed -E -n -e 's/^fpr:::::::::([0-9A-F]+):$/\1:6:/p' |gpg --import-ownertrust - gpg --update-trust - - if (cbfs -o /tmp/gpg-gui.rom -l | grep -q "heads/initrd/.gnupg/pubring.kbx"); then - cbfs -o /tmp/gpg-gui.rom -d "heads/initrd/.gnupg/pubring.kbx" - if (cbfs -o /tmp/gpg-gui.rom -l | grep -q "heads/initrd/.gnupg/pubring.gpg"); then - cbfs -o /tmp/gpg-gui.rom -d "heads/initrd/.gnupg/pubring.gpg" - if [ -e /.gnupg/pubring.gpg ];then - rm /.gnupg/pubring.gpg - fi - fi - fi - - #to be compatible with gpgv1 - if [ -e /.gnupg/pubring.kbx ];then - cbfs -o /tmp/gpg-gui.rom -a "heads/initrd/.gnupg/pubring.kbx" -f /.gnupg/pubring.kbx - if [ -e /.gnupg/pubring.gpg ];then - rm /.gnupg/pubring.gpg - fi - fi - if [ -e /.gnupg/pubring.gpg ];then - cbfs -o /tmp/gpg-gui.rom -a "heads/initrd/.gnupg/pubring.gpg" -f /.gnupg/pubring.gpg - fi - - if (cbfs -o /tmp/gpg-gui.rom -l | grep -q "heads/initrd/.gnupg/trustdb.gpg") then - cbfs -o /tmp/gpg-gui.rom -d "heads/initrd/.gnupg/trustdb.gpg" - fi - cbfs -o /tmp/gpg-gui.rom -a "heads/initrd/.gnupg/trustdb.gpg" -f /.gnupg/trustdb.gpg - - #Remove old method owner trust exported file - if (cbfs -o /tmp/gpg-gui.rom -l | grep -q "heads/initrd/.gnupg/otrust.txt") then - cbfs -o /tmp/gpg-gui.rom -d "heads/initrd/.gnupg/otrust.txt" - fi - - if (whiptail --title 'Update ROM?' \ - --yesno "This will reflash your BIOS with the updated version\n\nDo you want to proceed?" 16 90) then - /bin/flash.sh /tmp/gpg-gui.rom - whiptail --title 'BIOS Updated Successfully' \ - --msgbox "BIOS updated successfully.\n\nIf your keys have changed, be sure to re-sign all files in /boot\nafter you reboot.\n\nPress Enter to reboot" 16 60 - umount /media - /bin/reboot - else - exit 0 - fi - fi - fi - ;; - "g" ) - confirm_gpg_card - echo "********************************************************************************" - echo "*" - echo "* INSTRUCTIONS:" - echo "* Type 'admin' and then 'generate' and follow the prompts to generate a GPG key." - echo "*" - echo "********************************************************************************" - gpg --card-edit - ;; esac done diff --git a/initrd/bin/gpg-gui.sh b/initrd/bin/gpg-gui.sh new file mode 100755 index 000000000..f75661075 --- /dev/null +++ b/initrd/bin/gpg-gui.sh @@ -0,0 +1,244 @@ +#!/bin/sh +# +set -e -o pipefail +. /etc/functions +. /tmp/config + +mount_usb(){ +# Mount the USB boot device + if ! grep -q /media /proc/mounts ; then + mount-usb "$CONFIG_USB_BOOT_DEV" || USB_FAILED=1 + if [ $USB_FAILED -ne 0 ]; then + if [ ! -e "$CONFIG_USB_BOOT_DEV" ]; then + whiptail --title 'USB Drive Missing' \ + --msgbox "Insert your USB drive and press Enter to continue." 16 60 USB_FAILED=0 + mount-usb "$CONFIG_USB_BOOT_DEV" || USB_FAILED=1 + fi + if [ $USB_FAILED -ne 0 ]; then + whiptail $CONFIG_ERROR_BG_COLOR --title 'ERROR: Mounting /media Failed' \ + --msgbox "Unable to mount $CONFIG_USB_BOOT_DEV" 16 60 + fi + fi + fi +} + +file_selector() { + FILE="" + FILE_LIST=$1 + MENU_MSG=${2:-"Choose the file"} +# create file menu options + if [ `cat "$FILE_LIST" | wc -l` -gt 0 ]; then + option="" + while [ -z "$option" ] + do + MENU_OPTIONS="" + n=0 + while read option + do + n=`expr $n + 1` + option=$(echo $option | tr " " "_") + MENU_OPTIONS="$MENU_OPTIONS $n ${option}" + done < $FILE_LIST + + MENU_OPTIONS="$MENU_OPTIONS a Abort" + whiptail --clear --title "Select your File" \ + --menu "${MENU_MSG} [1-$n, a to abort]:" 20 120 8 \ + -- $MENU_OPTIONS \ + 2>/tmp/whiptail || die "Aborting" + + option_index=$(cat /tmp/whiptail) + + if [ "$option_index" = "a" ]; then + option="a" + return + fi + + option=`head -n $option_index $FILE_LIST | tail -1` + if [ "$option" == "a" ]; then + return + fi + done + if [ -n "$option" ]; then + FILE=$option + fi + else + whiptail $CONFIG_ERROR_BG_COLOR --title 'ERROR: No Files Found' \ + --msgbox "No Files found matching the pattern. Aborting." 16 60 + exit 1 + fi +} + +while true; do + unset menu_choice + whiptail --clear --title "GPG Management Menu" \ + --menu 'Select the GPG function to perform' 20 90 10 \ + 'r' ' Add GPG key to running BIOS + reflash' \ + 'a' ' Add GPG key to standalone BIOS image + flash' \ + 'l' ' List GPG keys in your keyring' \ + 'g' ' Generate GPG keys on a USB security token' \ + 'x' ' Exit' \ + 2>/tmp/whiptail || recovery "GUI menu failed" + + menu_choice=$(cat /tmp/whiptail) + + case "$menu_choice" in + "x" ) + exit 0 + ;; + "a" ) + if (whiptail --title 'ROM and GPG public key required' \ + --yesno "This requires you insert a USB drive containing:\n* Your GPG public key (*.key or *.asc)\n* Your BIOS image (*.rom)\n\nAfter you select these files, this program will reflash your BIOS\n\nDo you want to proceed?" 16 90) then + mount_usb + if grep -q /media /proc/mounts ; then + find /media -name '*.key' > /tmp/filelist.txt + find /media -name '*.asc' >> /tmp/filelist.txt + file_selector "/tmp/filelist.txt" "Choose your GPG public key" + if [ "$FILE" == "" ]; then + return + else + PUBKEY=$FILE + fi + + find /media -name '*.rom' > /tmp/filelist.txt + file_selector "/tmp/filelist.txt" "Choose the ROM to load your key onto" + if [ "$FILE" == "" ]; then + return + else + ROM=$FILE + fi + + cat "$PUBKEY" | gpg --import + #update /.gnupg/trustdb.gpg to ultimately trust all user provided public keys + gpg --list-keys --fingerprint --with-colons |sed -E -n -e 's/^fpr:::::::::([0-9A-F]+):$/\1:6:/p' |gpg --import-ownertrust + gpg --update-trust + + cp "$ROM" /tmp/gpg-gui.rom + if (cbfs -o /tmp/gpg-gui.rom -l | grep -q "heads/initrd/.gnupg/pubring.kbx"); then + cbfs -o /tmp/gpg-gui.rom -d "heads/initrd/.gnupg/pubring.kbx" + if (cbfs -o /tmp/gpg-gui.rom -l | grep -q "heads/initrd/.gnupg/pubring.gpg"); then + cbfs -o /tmp/gpg-gui.rom -d "heads/initrd/.gnupg/pubring.gpg" + if [ -e /.gnupg/pubring.gpg ];then + rm /.gnupg/pubring.gpg + fi + fi + fi + + #to be compatible with gpgv1 + if [ -e /.gnupg/pubring.kbx ];then + cbfs -o /tmp/gpg-gui.rom -a "heads/initrd/.gnupg/pubring.kbx" -f /.gnupg/pubring.kbx + if [ -e /.gnupg/pubring.gpg ];then + rm /.gnupg/pubring.gpg + fi + fi + if [ -e /.gnupg/pubring.gpg ];then + cbfs -o /tmp/gpg-gui.rom -a "heads/initrd/.gnupg/pubring.gpg" -f /.gnupg/pubring.gpg + fi + + if (cbfs -o /tmp/gpg-gui.rom -l | grep -q "heads/initrd/.gnupg/trustdb.gpg") then + cbfs -o /tmp/gpg-gui.rom -d "heads/initrd/.gnupg/trustdb.gpg" + fi + cbfs -o /tmp/gpg-gui.rom -a "heads/initrd/.gnupg/trustdb.gpg" -f /.gnupg/trustdb.gpg + + #Remove old method owner trust exported file + if (cbfs -o /tmp/gpg-gui.rom -l | grep -q "heads/initrd/.gnupg/otrust.txt") then + cbfs -o /tmp/gpg-gui.rom -d "heads/initrd/.gnupg/otrust.txt" + fi + + if (whiptail --title 'Flash ROM?' \ + --yesno "This will replace your old ROM with $ROM\n\nDo you want to proceed?" 16 90) then + /bin/flash.sh /tmp/gpg-gui.rom + whiptail --title 'ROM Flashed Successfully' \ + --msgbox "$ROM flashed successfully.\n\nIf your keys have changed, be sure to re-sign all files in /boot\nafter you reboot.\n\nPress Enter to reboot" 16 60 + umount /media + /bin/reboot + else + exit 0 + fi + fi + fi + ;; + "r" ) + if (whiptail --title 'GPG public key required' \ + --yesno "This requires you insert a USB drive containing:\n* Your GPG public key (*.key or *.asc)\n\nAfter you select this file, this program will copy and reflash your BIOS\n\nDo you want to proceed?" 16 90) then + mount_usb + if grep -q /media /proc/mounts ; then + find /media -name '*.key' > /tmp/filelist.txt + find /media -name '*.asc' >> /tmp/filelist.txt + file_selector "/tmp/filelist.txt" "Choose your GPG public key" + PUBKEY=$FILE + + /bin/flash.sh -r /tmp/gpg-gui.rom + if [ ! -s /tmp/gpg-gui.rom ]; then + whiptail $CONFIG_ERROR_BG_COLOR --title 'ERROR: BIOS Read Failed!' \ + --msgbox "Unable to read BIOS" 16 60 + exit 1 + fi + + cat "$PUBKEY" | gpg --import + #update /.gnupg/trustdb.gpg to ultimately trust all user provided public keys + gpg --list-keys --fingerprint --with-colons |sed -E -n -e 's/^fpr:::::::::([0-9A-F]+):$/\1:6:/p' |gpg --import-ownertrust + gpg --update-trust + + if (cbfs -o /tmp/gpg-gui.rom -l | grep -q "heads/initrd/.gnupg/pubring.kbx"); then + cbfs -o /tmp/gpg-gui.rom -d "heads/initrd/.gnupg/pubring.kbx" + if (cbfs -o /tmp/gpg-gui.rom -l | grep -q "heads/initrd/.gnupg/pubring.gpg"); then + cbfs -o /tmp/gpg-gui.rom -d "heads/initrd/.gnupg/pubring.gpg" + if [ -e /.gnupg/pubring.gpg ];then + rm /.gnupg/pubring.gpg + fi + fi + fi + + #to be compatible with gpgv1 + if [ -e /.gnupg/pubring.kbx ];then + cbfs -o /tmp/gpg-gui.rom -a "heads/initrd/.gnupg/pubring.kbx" -f /.gnupg/pubring.kbx + if [ -e /.gnupg/pubring.gpg ];then + rm /.gnupg/pubring.gpg + fi + fi + if [ -e /.gnupg/pubring.gpg ];then + cbfs -o /tmp/gpg-gui.rom -a "heads/initrd/.gnupg/pubring.gpg" -f /.gnupg/pubring.gpg + fi + + if (cbfs -o /tmp/gpg-gui.rom -l | grep -q "heads/initrd/.gnupg/trustdb.gpg") then + cbfs -o /tmp/gpg-gui.rom -d "heads/initrd/.gnupg/trustdb.gpg" + fi + cbfs -o /tmp/gpg-gui.rom -a "heads/initrd/.gnupg/trustdb.gpg" -f /.gnupg/trustdb.gpg + + #Remove old method owner trust exported file + if (cbfs -o /tmp/gpg-gui.rom -l | grep -q "heads/initrd/.gnupg/otrust.txt") then + cbfs -o /tmp/gpg-gui.rom -d "heads/initrd/.gnupg/otrust.txt" + fi + + if (whiptail --title 'Update ROM?' \ + --yesno "This will reflash your BIOS with the updated version\n\nDo you want to proceed?" 16 90) then + /bin/flash.sh /tmp/gpg-gui.rom + whiptail --title 'BIOS Updated Successfully' \ + --msgbox "BIOS updated successfully.\n\nIf your keys have changed, be sure to re-sign all files in /boot\nafter you reboot.\n\nPress Enter to reboot" 16 60 + umount /media + /bin/reboot + else + exit 0 + fi + fi + fi + ;; + "l" ) + GPG_KEYRING=`gpg -k` + whiptail --title 'GPG Keyring' \ + --msgbox "${GPG_KEYRING}" 16 60 + ;; + "g" ) + confirm_gpg_card + echo "********************************************************************************" + echo "*" + echo "* INSTRUCTIONS:" + echo "* Type 'admin' and then 'generate' and follow the prompts to generate a GPG key." + echo "*" + echo "********************************************************************************" + gpg --card-edit + ;; + esac + +done +exit 0 diff --git a/initrd/bin/gui-init b/initrd/bin/gui-init index 39b3c486f..7a07bbea8 100755 --- a/initrd/bin/gui-init +++ b/initrd/bin/gui-init @@ -114,7 +114,7 @@ while true; do if [ $GPG_KEY_COUNT -eq 0 ]; then whiptail $CONFIG_ERROR_BG_COLOR --clear --title "ERROR: GPG keyring empty!" \ --menu "ERROR: Heads couldn't find any GPG keys in your keyring.\n\nIf this is the first time the system has booted,\nyou should add a public GPG key to the BIOS now.\n\nIf you just reflashed a new BIOS, you'll need to add at least one\npublic key to the keyring.\n\nIf you have not just reflashed your BIOS, THIS COULD INDICATE TAMPERING!\n\nHow would you like to proceed?" 30 90 4 \ - 'f' ' Add a GPG key to the running BIOS' \ + 'G' ' Add a GPG key to the running BIOS' \ 'i' ' Ignore error and continue to default boot menu' \ 'x' ' Exit to recovery shell' \ 2>/tmp/whiptail || recovery "GUI menu failed" @@ -185,13 +185,11 @@ while true; do whiptail --clear --title "Advanced Settings" \ --menu "Configure Advanced Settings" 20 90 10 \ 'o' ' Other Boot Options -->' \ - 'r' ' TOTP/HOTP does not match, refresh code' \ - 'g' ' Generate new TOTP/HOTP secret' \ + 't' ' TPM/TOTP/HOTP Options -->' \ 's' ' Update checksums and sign all files in /boot' \ 'c' ' Change configuration settings -->' \ 'f' ' Flash/Update the BIOS -->' \ - 'p' ' Reset the TPM' \ - 'n' ' TOTP/HOTP does not match after refresh, troubleshoot' \ + 'G' ' GPG Options -->' \ 'r' ' <-- Return to main menu' \ 2>/tmp/whiptail || recovery "GUI menu failed" @@ -210,6 +208,19 @@ while true; do totp_confirm=$(cat /tmp/whiptail) fi + if [ "$totp_confirm" = "t" ]; then + whiptail --clear --title "TPM/TOTP/HOTP Options" \ + --menu "Select An Option" 20 90 10 \ + 'g' ' Generate new TOTP/HOTP secret' \ + 'p' ' Reset the TPM' \ + 'r' ' TOTP/HOTP does not match, refresh code' \ + 'n' ' TOTP/HOTP does not match after refresh, troubleshoot' \ + 'r' ' <-- Return to main menu' \ + 2>/tmp/whiptail || recovery "GUI menu failed" + + totp_confirm=$(cat /tmp/whiptail) + fi + if [ "$totp_confirm" = "x" ]; then recovery "User requested recovery shell" fi @@ -314,6 +325,11 @@ while true; do continue fi + if [ "$totp_confirm" = "G" ]; then + gpg-gui.sh + continue + fi + if [ "$totp_confirm" = "y" -o -n "$totp_confirm" ]; then # Try to boot the default mount_boot From 9279d60a1a7685a18b819811d864d195fba2e1fd Mon Sep 17 00:00:00 2001 From: Kyle Rankin Date: Fri, 15 Feb 2019 10:16:43 -0800 Subject: [PATCH 091/102] Remove "pipefail" so unmatched greps don't cause script to exit --- initrd/bin/gpg-gui.sh | 1 - 1 file changed, 1 deletion(-) diff --git a/initrd/bin/gpg-gui.sh b/initrd/bin/gpg-gui.sh index f75661075..3025c6f1e 100755 --- a/initrd/bin/gpg-gui.sh +++ b/initrd/bin/gpg-gui.sh @@ -1,6 +1,5 @@ #!/bin/sh # -set -e -o pipefail . /etc/functions . /tmp/config From 07cf7d757703ec5fefe429520dd01e9df753d0a2 Mon Sep 17 00:00:00 2001 From: Kyle Rankin Date: Tue, 19 Feb 2019 06:48:35 -0800 Subject: [PATCH 092/102] Revert "Remove "pipefail" so unmatched greps don't cause script to exit" This reverts commit 9279d60a1a7685a18b819811d864d195fba2e1fd. --- initrd/bin/gpg-gui.sh | 1 + 1 file changed, 1 insertion(+) diff --git a/initrd/bin/gpg-gui.sh b/initrd/bin/gpg-gui.sh index 3025c6f1e..f75661075 100755 --- a/initrd/bin/gpg-gui.sh +++ b/initrd/bin/gpg-gui.sh @@ -1,5 +1,6 @@ #!/bin/sh # +set -e -o pipefail . /etc/functions . /tmp/config From 70f809187bc66cc3bb5d7bbff146461425b57de8 Mon Sep 17 00:00:00 2001 From: "Christopher A. Williamson" Date: Tue, 19 Feb 2019 21:16:52 +0000 Subject: [PATCH 093/102] Disable EXT2 standard driver (replaced by EXT4 driver) --- config/linux-kgpe-d16.config | 1 + config/linux-librem13v2.config | 1 + config/linux-linuxboot.config | 1 + config/linux-qemu.config | 1 + config/linux-x230.config | 1 + 5 files changed, 5 insertions(+) diff --git a/config/linux-kgpe-d16.config b/config/linux-kgpe-d16.config index 43c43bbc4..bef4cfb4d 100644 --- a/config/linux-kgpe-d16.config +++ b/config/linux-kgpe-d16.config @@ -204,6 +204,7 @@ CONFIG_GENERIC_PHY=y # CONFIG_BTT is not set # CONFIG_FIRMWARE_MEMMAP is not set # CONFIG_DMIID is not set +# CONFIG_EXT2_FS is not set CONFIG_EXT4_FS=y CONFIG_EXT4_USE_FOR_EXT2=y # CONFIG_DNOTIFY is not set diff --git a/config/linux-librem13v2.config b/config/linux-librem13v2.config index 742841d35..35a3f5ed5 100644 --- a/config/linux-librem13v2.config +++ b/config/linux-librem13v2.config @@ -203,6 +203,7 @@ CONFIG_GENERIC_PHY=y # CONFIG_BTT is not set # CONFIG_FIRMWARE_MEMMAP is not set # CONFIG_DMIID is not set +# CONFIG_EXT2_FS is not set CONFIG_EXT4_FS=y CONFIG_EXT4_USE_FOR_EXT2=y # CONFIG_DNOTIFY is not set diff --git a/config/linux-linuxboot.config b/config/linux-linuxboot.config index e7c1555a7..a454a0962 100644 --- a/config/linux-linuxboot.config +++ b/config/linux-linuxboot.config @@ -253,6 +253,7 @@ CONFIG_GENERIC_PHY=y # CONFIG_ND_BLK is not set # CONFIG_BTT is not set CONFIG_DMI_SYSFS=y +# CONFIG_EXT2_FS is not set CONFIG_EXT4_FS=y CONFIG_EXT4_USE_FOR_EXT2=y CONFIG_XFS_FS=y diff --git a/config/linux-qemu.config b/config/linux-qemu.config index 5c6e50411..bb4939180 100644 --- a/config/linux-qemu.config +++ b/config/linux-qemu.config @@ -248,6 +248,7 @@ CONFIG_GENERIC_PHY=y CONFIG_DMI_SYSFS=y CONFIG_GOOGLE_FIRMWARE=y CONFIG_GOOGLE_MEMCONSOLE_X86_LEGACY=y +# CONFIG_EXT2_FS is not set CONFIG_EXT4_FS=y CONFIG_EXT4_USE_FOR_EXT2=y CONFIG_XFS_FS=y diff --git a/config/linux-x230.config b/config/linux-x230.config index d5aca989a..44bd5ac6b 100644 --- a/config/linux-x230.config +++ b/config/linux-x230.config @@ -207,6 +207,7 @@ CONFIG_GENERIC_PHY=y # CONFIG_DMIID is not set CONFIG_GOOGLE_FIRMWARE=y CONFIG_GOOGLE_MEMCONSOLE_X86_LEGACY=y +# CONFIG_EXT2_FS is not set CONFIG_EXT4_FS=y CONFIG_EXT4_USE_FOR_EXT2=y # CONFIG_DNOTIFY is not set From 0722d42d659ee99006f06e6e2b5d091f9b017dbe Mon Sep 17 00:00:00 2001 From: Thierry Laurion Date: Sat, 16 Feb 2019 12:26:51 -0500 Subject: [PATCH 094/102] using shred instead of rm on secret related files. --- initrd/bin/kexec-unseal-key | 2 +- initrd/bin/seal-libremkey | 4 ++-- initrd/bin/seal-totp | 4 ++-- initrd/bin/unseal-hotp | 6 +++--- initrd/bin/unseal-totp | 6 +++--- initrd/etc/functions | 3 ++- 6 files changed, 13 insertions(+), 12 deletions(-) diff --git a/initrd/bin/kexec-unseal-key b/initrd/bin/kexec-unseal-key index 122ede4d4..fdacc0c67 100755 --- a/initrd/bin/kexec-unseal-key +++ b/initrd/bin/kexec-unseal-key @@ -38,7 +38,7 @@ for tries in 1 2 3; do -hk 40000000 \ ; then # should be okay if this fails - rm -f /tmp/secret/sealed || true + shred -n 10 -z -u /tmp/secret/sealed || true exit 0 fi diff --git a/initrd/bin/seal-libremkey b/initrd/bin/seal-libremkey index ddee9e979..52d207135 100755 --- a/initrd/bin/seal-libremkey +++ b/initrd/bin/seal-libremkey @@ -28,9 +28,9 @@ tpm unsealfile \ -of "$HOTP_SECRET" \ || die "Unable to unseal HOTP secret" -rm -f "$HOTP_SEALED" +shred -n 10 -z -u "$HOTP_SEALED" secret="`cat $HOTP_SECRET`" -rm -f "$HOTP_SECRET" +shred -n 10 -z -u "$HOTP_SECRET" # Store counter in file instead of TPM for now, as it conflicts with Heads # config TPM counter as TPM 1.2 can only increment one counter between reboots diff --git a/initrd/bin/seal-totp b/initrd/bin/seal-totp index f46f4520b..f34f52269 100755 --- a/initrd/bin/seal-totp +++ b/initrd/bin/seal-totp @@ -43,7 +43,7 @@ if ! tpm sealfile2 \ -ix 4 0000000000000000000000000000000000000000 \ -ix 7 X \ ; then - rm -f "$TOTP_SECRET" + shred -n 10 -z -u "$TOTP_SECRET" die "Unable to seal secret" fi @@ -79,7 +79,7 @@ if ! tpm nv_writevalue \ || die "Unable to write sealed secret to NVRAM" fi -rm -f "$TOTP_SEALED" +shred -n 10 -z -u "$TOTP_SEALED" url="otpauth://totp/$HOST?secret=$secret" secret="" diff --git a/initrd/bin/unseal-hotp b/initrd/bin/unseal-hotp index 8d4ef192f..9e38b4657 100755 --- a/initrd/bin/unseal-hotp +++ b/initrd/bin/unseal-hotp @@ -28,7 +28,7 @@ tpm unsealfile \ -of "$HOTP_SECRET" \ || die "Unable to unseal HOTP secret" -rm -f "$HOTP_SEALED" +shred -n 10 -z -u "$HOTP_SEALED" # Store counter in file instead of TPM for now, as it conflicts with Heads # config TPM counter as TPM 1.2 can only increment one counter between reboots @@ -51,11 +51,11 @@ fi #counter_value=$(printf "%d" 0x${counter_value}) if ! hotp $counter_value < "$HOTP_SECRET"; then - rm -f "$HOTP_SECRET" + shred -n 10 -z -u "$HOTP_SECRET" die 'Unable to compute HOTP hash?' fi -rm -f "$HOTP_SECRET" +shred -n 10 -z -u "$HOTP_SECRET" #increment_tpm_counter $counter > /dev/null \ #|| die "Unable to increment tpm counter" diff --git a/initrd/bin/unseal-totp b/initrd/bin/unseal-totp index c123ba0e7..b499d0bb1 100755 --- a/initrd/bin/unseal-totp +++ b/initrd/bin/unseal-totp @@ -18,12 +18,12 @@ tpm unsealfile \ -of "$TOTP_SECRET" \ || die "Unable to unseal totp secret" -rm -f "$TOTP_SEALED" +shred -n 10 -z -u "$TOTP_SEALED" if ! totp -q < "$TOTP_SECRET"; then - rm -f "$TOTP_SECRET" + shred -n 10 -z -u "$TOTP_SECRET" die 'Unable to compute TOTP hash?' fi -rm -f "$TOTP_SECRET" +shred -n 10 -z -u "$TOTP_SECRET" exit 0 diff --git a/initrd/etc/functions b/initrd/etc/functions index 8913870ec..6e7f136bc 100755 --- a/initrd/etc/functions +++ b/initrd/etc/functions @@ -15,6 +15,7 @@ recovery() { # Remove any temporary secret files that might be hanging around # but recreate the directory so that new tools can use it. + shred -n 10 -z -u /tmp/secret/* 2> /dev/null rm -rf /tmp/secret mkdir -p /tmp/secret @@ -234,7 +235,7 @@ replace_config() { # then copy any remaining settings from the existing config file, minus the option you changed grep -v "^export ${CONFIG_OPTION}=" ${CONFIG_FILE} | grep -v "^${CONFIG_OPTION}=" >> ${CONFIG_FILE}.tmp || true sort ${CONFIG_FILE}.tmp | uniq > ${CONFIG_FILE} - rm -f ${CONFIG_FILE}.tmp + shred -n 10 -z -u ${CONFIG_FILE}.tmp } combine_configs() { cat /etc/config* > /tmp/config From 14c76d062c199f17ff6369091a80d2885cb54914 Mon Sep 17 00:00:00 2001 From: Thierry Laurion Date: Thu, 21 Feb 2019 20:16:02 -0500 Subject: [PATCH 095/102] supress errors on console when files don't exist (equivalent of rm -f) --- initrd/bin/kexec-unseal-key | 2 +- initrd/bin/seal-libremkey | 4 ++-- initrd/bin/seal-totp | 4 ++-- initrd/bin/unseal-hotp | 6 +++--- initrd/bin/unseal-totp | 6 +++--- 5 files changed, 11 insertions(+), 11 deletions(-) diff --git a/initrd/bin/kexec-unseal-key b/initrd/bin/kexec-unseal-key index fdacc0c67..e016f5bdc 100755 --- a/initrd/bin/kexec-unseal-key +++ b/initrd/bin/kexec-unseal-key @@ -38,7 +38,7 @@ for tries in 1 2 3; do -hk 40000000 \ ; then # should be okay if this fails - shred -n 10 -z -u /tmp/secret/sealed || true + shred -n 10 -z -u /tmp/secret/sealed 2> /dev/null || true exit 0 fi diff --git a/initrd/bin/seal-libremkey b/initrd/bin/seal-libremkey index 52d207135..7203b7198 100755 --- a/initrd/bin/seal-libremkey +++ b/initrd/bin/seal-libremkey @@ -28,9 +28,9 @@ tpm unsealfile \ -of "$HOTP_SECRET" \ || die "Unable to unseal HOTP secret" -shred -n 10 -z -u "$HOTP_SEALED" +shred -n 10 -z -u "$HOTP_SEALED" 2> /dev/null secret="`cat $HOTP_SECRET`" -shred -n 10 -z -u "$HOTP_SECRET" +shred -n 10 -z -u "$HOTP_SECRET" 2> /dev/null # Store counter in file instead of TPM for now, as it conflicts with Heads # config TPM counter as TPM 1.2 can only increment one counter between reboots diff --git a/initrd/bin/seal-totp b/initrd/bin/seal-totp index f34f52269..af7896b50 100755 --- a/initrd/bin/seal-totp +++ b/initrd/bin/seal-totp @@ -43,7 +43,7 @@ if ! tpm sealfile2 \ -ix 4 0000000000000000000000000000000000000000 \ -ix 7 X \ ; then - shred -n 10 -z -u "$TOTP_SECRET" + shred -n 10 -z -u "$TOTP_SECRET" 2> /dev/null die "Unable to seal secret" fi @@ -79,7 +79,7 @@ if ! tpm nv_writevalue \ || die "Unable to write sealed secret to NVRAM" fi -shred -n 10 -z -u "$TOTP_SEALED" +shred -n 10 -z -u "$TOTP_SEALED" 2> /dev/null url="otpauth://totp/$HOST?secret=$secret" secret="" diff --git a/initrd/bin/unseal-hotp b/initrd/bin/unseal-hotp index 9e38b4657..5a697f369 100755 --- a/initrd/bin/unseal-hotp +++ b/initrd/bin/unseal-hotp @@ -28,7 +28,7 @@ tpm unsealfile \ -of "$HOTP_SECRET" \ || die "Unable to unseal HOTP secret" -shred -n 10 -z -u "$HOTP_SEALED" +shred -n 10 -z -u "$HOTP_SEALED" 2> /dev/null # Store counter in file instead of TPM for now, as it conflicts with Heads # config TPM counter as TPM 1.2 can only increment one counter between reboots @@ -51,11 +51,11 @@ fi #counter_value=$(printf "%d" 0x${counter_value}) if ! hotp $counter_value < "$HOTP_SECRET"; then - shred -n 10 -z -u "$HOTP_SECRET" + shred -n 10 -z -u "$HOTP_SECRET" 2> /dev/null die 'Unable to compute HOTP hash?' fi -shred -n 10 -z -u "$HOTP_SECRET" +shred -n 10 -z -u "$HOTP_SECRET" 2> /dev/null #increment_tpm_counter $counter > /dev/null \ #|| die "Unable to increment tpm counter" diff --git a/initrd/bin/unseal-totp b/initrd/bin/unseal-totp index b499d0bb1..c9c339b13 100755 --- a/initrd/bin/unseal-totp +++ b/initrd/bin/unseal-totp @@ -18,12 +18,12 @@ tpm unsealfile \ -of "$TOTP_SECRET" \ || die "Unable to unseal totp secret" -shred -n 10 -z -u "$TOTP_SEALED" +shred -n 10 -z -u "$TOTP_SEALED" 2> /dev/null if ! totp -q < "$TOTP_SECRET"; then - shred -n 10 -z -u "$TOTP_SECRET" + shred -n 10 -z -u "$TOTP_SECRET" 2> /dev/null die 'Unable to compute TOTP hash?' fi -shred -n 10 -z -u "$TOTP_SECRET" +shred -n 10 -z -u "$TOTP_SECRET" 2> /dev/null exit 0 From 9fbfb41a71a9889c8c80ab3595e3f513ad613758 Mon Sep 17 00:00:00 2001 From: Thierry Laurion Date: Thu, 21 Feb 2019 20:17:16 -0500 Subject: [PATCH 096/102] reverting shred on a file that is not a secret to be shredded --- initrd/etc/functions | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/initrd/etc/functions b/initrd/etc/functions index 6e7f136bc..453590b84 100755 --- a/initrd/etc/functions +++ b/initrd/etc/functions @@ -235,7 +235,7 @@ replace_config() { # then copy any remaining settings from the existing config file, minus the option you changed grep -v "^export ${CONFIG_OPTION}=" ${CONFIG_FILE} | grep -v "^${CONFIG_OPTION}=" >> ${CONFIG_FILE}.tmp || true sort ${CONFIG_FILE}.tmp | uniq > ${CONFIG_FILE} - shred -n 10 -z -u ${CONFIG_FILE}.tmp + rm -f ${CONFIG_FILE}.tmp } combine_configs() { cat /etc/config* > /tmp/config From b3a6c285c8ac8596a654571023132bcbf5c754c9 Mon Sep 17 00:00:00 2001 From: Thierry Laurion Date: Fri, 22 Feb 2019 10:48:00 -0500 Subject: [PATCH 097/102] also shred LUKS key when done instead of rm it --- initrd/bin/kexec-seal-key | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/initrd/bin/kexec-seal-key b/initrd/bin/kexec-seal-key index f574b5587..c96dc637b 100755 --- a/initrd/bin/kexec-seal-key +++ b/initrd/bin/kexec-seal-key @@ -117,7 +117,7 @@ tpm sealfile2 \ -ix 7 X \ || die "Unable to seal secret" -rm -f "$KEY_FILE" \ +shred -n 10 -z -u "$KEY_FILE" 2> /dev/null \ || die "Failed to delete key file" # try it without the owner password first From 8310a3d62eb3aff2ce39f8c08e6a6e54f9219557 Mon Sep 17 00:00:00 2001 From: Thierry Laurion Date: Fri, 22 Feb 2019 10:52:35 -0500 Subject: [PATCH 098/102] also shred LUKS sealed secret when done instead of rm it --- initrd/bin/kexec-seal-key | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/initrd/bin/kexec-seal-key b/initrd/bin/kexec-seal-key index c96dc637b..46980af8e 100755 --- a/initrd/bin/kexec-seal-key +++ b/initrd/bin/kexec-seal-key @@ -150,5 +150,5 @@ if ! tpm nv_writevalue \ || die "Unable to write sealed secret to NVRAM" fi -rm "$TPM_SEALED" \ +shred -n 10 -z -u "$TPM_SEALED" 2> /dev/null \ || warn "Failed to delete the sealed secret - continuing" From 2740317d67dfe3aa185ff501e6391ba3cf785d6f Mon Sep 17 00:00:00 2001 From: Thierry Laurion Date: Sun, 24 Feb 2019 11:11:00 -0500 Subject: [PATCH 099/102] shred TOTP_SECRET also when generation is successful --- initrd/bin/seal-totp | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/initrd/bin/seal-totp b/initrd/bin/seal-totp index af7896b50..f33449e58 100755 --- a/initrd/bin/seal-totp +++ b/initrd/bin/seal-totp @@ -44,9 +44,11 @@ if ! tpm sealfile2 \ -ix 7 X \ ; then shred -n 10 -z -u "$TOTP_SECRET" 2> /dev/null - die "Unable to seal secret" + die "Unable to seal secret" fi +shred -n 10 -z -u "$TOTP_SECRET" 2> /dev/null + # to create an nvram space we need the TPM owner password # and the TPM physical presence must be asserted. From 92fdb0392b7789cd47db8aeb7460bc0b161c24d5 Mon Sep 17 00:00:00 2001 From: Matt DeVillier Date: Fri, 1 Mar 2019 01:10:09 -0600 Subject: [PATCH 100/102] get_blobs: extract blobs from precompiled Purism coreboot images Rather than download large repositories of files from sources we don't control and patch files as needed, simply extract the files from precompiled, known good Purism coreboot images. This offers multiple advantages: - single source for all blobs, which we control - significantly smaller download requirements for end user - significantly less script complexity - much, much faster Signed-off-by: Matt DeVillier --- blobs/librem_kbl/get_blobs.sh | 278 ++++++++++----------------------- blobs/librem_skl/get_blobs.sh | 281 +++++++++++----------------------- 2 files changed, 170 insertions(+), 389 deletions(-) diff --git a/blobs/librem_kbl/get_blobs.sh b/blobs/librem_kbl/get_blobs.sh index 90dc002ab..7614119f1 100755 --- a/blobs/librem_kbl/get_blobs.sh +++ b/blobs/librem_kbl/get_blobs.sh @@ -1,48 +1,32 @@ #!/bin/bash -e -# depends on : wget sha256sum python2.7 bspatch pv +# depends on : wget sha256sum gunzip + +# Purism source +PURISM_SOURCE="https://source.puri.sm/coreboot/releases/raw/master" # Librem 13 v4 and Librem 15 v4 binary blob hashes KBL_UCODE_SHA="a420274eecca369fcca465cc46725d61c0ae8ca2e18f201b1751faf9e081fb2e" -KBL_ME_NOCONF_SHA="912271bb3ff2cf0e2e27ccfb94337baaca027e6c90b4245f9807a592c8a652e1" -KBL_ME_SHA="9c91052d457890c4a451c6ab69aabeeac98c95dce50cf462aa5c179236a27ba1" -KBL_FSP_SHA="74e579604bdc3eb6527f7add384d6b18e16eee76953748b226fe05129d83b419" -KBL_FSPM_SHA="b6431369b921df1c3ec01498e04e9dab331aa5b5fc4fbbb67b03ea87de27cd96" +KBL_DESCRIPTOR_SHA="642ca36f52aabb5198b82e013bf64a73a5148693a58376fffce322a4d438b524" +KBL_ME_SHA="0eec2e1135193941edd39d0ec0f463e353d0c6c9068867a2f32a72b64334fb34" +KBL_FSPM_SHA="5da3ad7718eb3f6700fb9d97be988d9c8bdd2d8b5910273a80928c49122d5b2d" KBL_FSPS_SHA="c81ffa40df0b6cd6cfde4f476d452a1f6f2217bc96a3b98a4fa4a037ee7039cf" KBL_VBT_SHA="0ba40c1b8c0fb030a0e1a789eda8b2a7369339a410ad8c4620719e451ea69b98" -# Microcode, FSP downloadable from Github -KBL_UCODE_URL="https://github.com/platomav/CPUMicrocodes/raw/0d88b2eba0c9930e69180423d3fb9f348d5ca14f/Intel/cpu806E9_platC0_ver0000009A_2018-07-16_PRD_DDFC5B64.bin" -KBL_FSP_URL="https://github.com/IntelFsp/FSP/raw/324ffc02523bf23a907a3ff305b43b5047adf1c5/KabylakeFspBinPkg/Fsp.fd" -KBL_VBT_URL="https://github.com/IntelFsp/FSP/raw/324ffc02523bf23a907a3ff305b43b5047adf1c5/KabylakeFspBinPkg/SampleCode/Vbt/Vbt.bin" -KBL_FSP_SPLIT_URL="https://raw.githubusercontent.com/tianocore/edk2/e8a70885d8f34533b6dd69878fe95a249e9af086/IntelFsp2Pkg/Tools/SplitFspBin.py" -KBL_FSP_SPLIT_SHA="f654f6363de68ad78b1baf8b8e573b53715c3bc76f7f3c23562641e49a7033f3" - -# Firmware descriptor from purism repo -KBL_DESCRIPTOR_URL="https://source.puri.sm/coreboot/coreboot-files/raw/master/descriptor-skl.bin" -KBL_DESCRIPTOR_SHA="d5110807c9d67cea6d546ac62125d87042a868177241be4ae17a2dbedef10017" - -# ME Cleaner from github -ME_CLEANER_URL="https://github.com/corna/me_cleaner/raw/9e1611fdf21426d66a29a5ea62b7e30d512859e6/me_cleaner.py" -ME_CLEANER_SHA="412e95538c46d6d4d456987a8897b3d0ad1df118c51378a350540eef51c242d4" - -# Intel ME binaries (unconfigured) -# Link found on : http://www.win-raid.com/t832f39-Intel-Engine-Firmware-Repositories.html -# Update link if it changes and becomes invalid. -KBL_ME_RAR_URL="https://mega.nz/#!6JlAla6a!hvulc0ZYCj19OzOZoyKimZSh8bxHw9Qmy6bQ8h_xKTU" -KBL_ME_FILENAME="11.6.0.1126_CON_LP_C_NPDM_PRD_RGN.bin" -KBL_ME_FULL_FILENAME="Intel CSME 11.6 Firmware Repository Pack r28/$KBL_ME_FILENAME" -KBL_ME_RAR_SHA="3c23134fca8de7c9b47dd4d62498bcde549ad07565d158c69f4ed33f9bda8270" -KBL_ME_PATCH="me11.6.0.1126_config.bspatch" -KBL_ME_PATCH_URL="https://source.puri.sm/coreboot/coreboot-files/raw/master/$KBL_ME_PATCH" -KBL_ME_PATCH_SHA="63a245326979777b102da8df2f278c590c60c2cd6b4911d3ac430d3feb02646e" - -# Needed to download KBL_ME_RAR_URL -MEGADOWN_URL="https://github.com/tonikelope/megadown.git" -MEGADOWN_GOOD_COMMIT="83c53ddad1c32bf6d35c61fcd12a2fa94271ff77" - -# Might be required to compile unrar in case unrar-nonfree is not installed -RAR_NONFREE_SOURCE_URL="https://www.rarlab.com/rar/unrarsrc-5.5.8.tar.gz" -RAR_NONFREE_SOURCE_SHA="9b66e4353a9944bc140eb2a919ff99482dd548f858f5e296d809e8f7cdb2fcf4" +# cbfstool, ifdtool, coreboot image from Purism repo +CBFSTOOL_FILE="cbfstool.gz" +CBFSTOOL_URL="$PURISM_SOURCE/tools/$CBFSTOOL_FILE" +CBFSTOOL_SHA="3994cba01a51dd34388c8be89fd329f91575c12e499dfe1b81975d9fd115ce58" +CBFSTOOL_BIN="./cbfstool" + +IFDTOOL_FILE="ifdtool.gz" +IFDTOOL_URL="$PURISM_SOURCE/tools/$IFDTOOL_FILE" +IFDTOOL_SHA="08228ece4968794499ebd49a851f7d3f7f1b81352da8cd6e0c7916ac931a7d72" +IFDTOOL_BIN="./ifdtool" + +COREBOOT_IMAGE="coreboot-l13v4.rom" +COREBOOT_IMAGE_FILE="$COREBOOT_IMAGE.gz" +COREBOOT_IMAGE_URL="$PURISM_SOURCE/librem_13v4/$COREBOOT_IMAGE_FILE" +COREBOOT_IMAGE_SHA="4491efd0a8b2de5a88fd7491a5d2605884ed956c3d271d7761906269b4cfb601" die () { local msg=$1 @@ -52,187 +36,89 @@ die () { exit 1 } -check_binary () { - local filename=$1 - local hash=$2 - - if [ ! -f "$filename" ]; then - die "Binary blob file '$filename' does not exist" - fi - sha=$(sha256sum "$filename" | awk '{print $1}') - if [ "$sha" != "$hash" ]; then - die "Extracted binary '$filename' has the wrong SHA256 hash" - fi -} - check_and_get_url () { - filename=$1 - url=$2 - hash=$3 - description=$4 + local filename=$1 + local url=$2 + local hash=$3 + local description=$4 if [ -f "$filename" ]; then sha=$(sha256sum "$filename" | awk '{print $1}') fi if [ "$sha" != "$hash" ]; then - wget -O "$filename" "$url" + echo " Downloading $description..." + wget -O "$filename" "$url" >/dev/null 2>&1 sha=$(sha256sum "$filename" | awk '{print $1}') if [ "$sha" != "$hash" ]; then die "Downloaded $description has the wrong SHA256 hash" fi + if [ "${filename: -3}" == ".gz" ]; then + gunzip -k $filename + fi fi } -get_and_split_fsp () { - fsp="fsp.fd" - fsp_M="fsp_M.fd" - fsp_S="fsp_S.fd" - fsp_T="fsp_T.fd" - fspm="fspm.bin" - fsps="fsps.bin" - fsp_split="SplitFspBin.py" - - if [ -f "$fspm" ]; then - fspm_sha=$(sha256sum "$fspm" | awk '{print $1}') - fi - if [ -f "$fsps" ]; then - fsps_sha=$(sha256sum "$fsps" | awk '{print $1}') - fi - # No FSP-M or FSP-S - if [ "$fspm_sha" != "$KBL_FSPM_SHA" ] || [ "$fsps_sha" != "$KBL_FSPS_SHA" ]; then - if [ -f "$fsp" ]; then - fsp_sha=$(sha256sum "$fsp" | awk '{print $1}') - fi - # No FSP.fd - if [ "$fsp_sha" != "$KBL_FSP_SHA" ]; then - wget -O "$fsp" "$KBL_FSP_URL" - fsp_sha=$(sha256sum "$fsp" | awk '{print $1}') - if [ "$fsp_sha" != "$KBL_FSP_SHA" ]; then - die "Downloaded FSP image has the wrong SHA256 hash" - fi - fi - # No FspSplit - if [ -f "$fsp_split" ]; then - split_sha=$(sha256sum "$fsp_split" | awk '{print $1}') - fi - if [ "$split_sha" != "$KBL_FSP_SHA" ]; then - wget -O "$fsp_split" "$KBL_FSP_SPLIT_URL" - split_sha=$(sha256sum "$fsp_split" | awk '{print $1}') - if [ "$split_sha" != "$KBL_FSP_SPLIT_SHA" ]; then - die "Downloaded FSP Split Tool has the wrong SHA256 hash" - fi - fi - python2 "$fsp_split" split -f "$fsp" - if [ -f "$fsp_M" ]; then - mv "$fsp_M" "$fspm" - fi - if [ -f "$fsp_S" ]; then - mv "$fsp_S" "$fsps" - fi - fspm_sha=$(sha256sum "$fspm" | awk '{print $1}') - fsps_sha=$(sha256sum "$fsps" | awk '{print $1}') - if [ "$fspm_sha" != "$KBL_FSPM_SHA" ] || [ "$fsps_sha" != "$KBL_FSPS_SHA" ]; then - die "Extracted FSP images have the wrong SHA256 hash" - fi - rm -f "$fsp" - rm -f "$fsp_split" - rm -f "$fsp_T" - fi -} +check_and_get_blob () { + local filename=$1 + local hash=$2 + local description=$3 -get_and_patch_me_11 () { - if [ -f "me.bin" ]; then - sha=$(sha256sum "me.bin" | awk '{print $1}') + echo "Checking $filename" + if [ -f "$filename" ]; then + sha=$(sha256sum "$filename" | awk '{print $1}') fi - if [ "$sha" != "$KBL_ME_SHA" ]; then - local rar_filename=me_11_repository.rar - local unrar='unrar-nonfree' - - if [ -f "$rar_filename" ]; then - sha=$(sha256sum "$rar_filename" | awk '{print $1}') - fi - if ! type "$unrar" &> /dev/null; then - wget -O unrar.tar.gz "$RAR_NONFREE_SOURCE_URL" - sha=$(sha256sum unrar.tar.gz | awk '{print $1}') - if [ "$sha" != "$RAR_NONFREE_SOURCE_SHA" ]; then - die "Unrar source package has the wrong SHA256 hash" - fi - tar -xzvf unrar.tar.gz - ( - cd unrar - make - ) - unrar="`pwd`/unrar/unrar" - fi - if [ "$sha" != "$KBL_ME_RAR_SHA" ]; then - if [ ! -d megadown ]; then - git clone $MEGADOWN_URL - fi - ( - cd megadown - git checkout $MEGADOWN_GOOD_COMMIT - echo -e "\n\nDownloading ME 11 Repository from $KBL_ME_RAR_URL" - echo "Please be patient while the download finishes..." - rm -f ../$rar_filename 2> /dev/null - ./megadown "$KBL_ME_RAR_URL" -o ../$rar_filename 2>/dev/null - ) - sha=$(sha256sum "$rar_filename" | awk '{print $1}') - if [ "$sha" != "$KBL_ME_RAR_SHA" ]; then - # We'll assume the rar file was updated again - me_dirname=$("$unrar" l "$rar_filename" | grep '\.\.\.D\.\.\.' | tr -s [:blank:] | cut -d' ' -f 6-) - KBL_ME_FULL_FILENAME="$me_dirname/$KBL_ME_FILENAME" - fi - fi - if type "$unrar" &> /dev/null; then - "$unrar" e -y "$rar_filename" "$KBL_ME_FULL_FILENAME" + if [ "$sha" != "$hash" ]; then + # get tools + check_and_get_tools + # extract from coreboot image + check_and_get_url $COREBOOT_IMAGE_FILE $COREBOOT_IMAGE_URL $COREBOOT_IMAGE_SHA "precompiled coreboot image" + echo "Extracting $filename" + if [ $filename = "descriptor.bin" ]; then + $IFDTOOL_BIN -x $COREBOOT_IMAGE >/dev/null 2>&1 + mv flashregion_0_flashdescriptor.bin descriptor.bin + echo "Extracting me.bin" + mv flashregion_2_intel_me.bin me.bin + rm flashregion_* > /dev/null 2>&1 + elif [ $filename = "me.bin" ]; then + $IFDTOOL_BIN -x $COREBOOT_IMAGE >/dev/null 2>&1 + mv flashregion_2_intel_me.bin me.bin + rm flashregion_* > /dev/null 2>&1 else - die "Couldn't extract ME image. Requires unrar-nonfree" + $CBFSTOOL_BIN $COREBOOT_IMAGE extract -n $filename -f $filename >/dev/null 2>&1 fi - sha="" - if [ -f "$KBL_ME_FILENAME" ]; then - sha=$(sha256sum "$KBL_ME_FILENAME" | awk '{print $1}') - fi - if [ "$sha" != "$KBL_ME_NOCONF_SHA" ]; then - die "Couldn't extract ME image with the correct SHA256 hash" + sha=$(sha256sum "$filename" | awk '{print $1}') + if [ "$sha" != "$hash" ]; then + die "Downloaded $description has the wrong SHA256 hash" fi - check_and_get_url $KBL_ME_PATCH $KBL_ME_PATCH_URL $KBL_ME_PATCH_SHA "ME Patch" - bspatch "$KBL_ME_FILENAME" "me.bin" "$KBL_ME_PATCH" - rm -f "$KBL_ME_PATCH" - rm -f "$KBL_ME_FILENAME" - rm -f "$rar_filename" fi } -apply_me_cleaner() { - if [ -f "me_cleaner.py" ]; then - sha=$(sha256sum "me_cleaner.py" | awk '{print $1}') - fi - if [ "$sha" != "$ME_CLEANER_SHA" ]; then - wget -O "me_cleaner.py" "$ME_CLEANER_URL" - sha=$(sha256sum "me_cleaner.py" | awk '{print $1}') - if [ "$sha" != "$ME_CLEANER_SHA" ]; then - die "Downloaded ME Cleaner has the wrong SHA256 hash" - fi - fi - cat descriptor.bin me.bin > desc_me.bin - python2 "me_cleaner.py" -s desc_me.bin - python2 "me_cleaner.py" -w "MFS" me.bin - dd if=desc_me.bin of=descriptor.bin bs=4096 count=1 - rm -f desc_me.bin - rm -f me_cleaner.py +echo "" + +check_and_get_tools() { + check_and_get_url $CBFSTOOL_FILE $CBFSTOOL_URL $CBFSTOOL_SHA "cbfstool" + chmod +x $CBFSTOOL_BIN + check_and_get_url $IFDTOOL_FILE $IFDTOOL_URL $IFDTOOL_SHA "ifdtool" + chmod +x $IFDTOOL_BIN } -check_and_get_url descriptor.bin $KBL_DESCRIPTOR_URL $KBL_DESCRIPTOR_SHA "Intel Flash Descriptor" -check_binary descriptor.bin $KBL_DESCRIPTOR_SHA -get_and_patch_me_11 -check_binary me.bin $KBL_ME_SHA -apply_me_cleaner -get_and_split_fsp -check_binary fspm.bin $KBL_FSPM_SHA -check_binary fsps.bin $KBL_FSPS_SHA -check_and_get_url vbt.bin $KBL_VBT_URL $KBL_VBT_SHA "Video BIOS Table" -check_and_get_url cpu_microcode_blob.bin $KBL_UCODE_URL $KBL_UCODE_SHA "Intel Microcode Update" +# get tools for extraction +#check_and_get_tools + +# get/verify blobs +check_and_get_blob descriptor.bin $KBL_DESCRIPTOR_SHA "Intel Flash Descriptor" +check_and_get_blob me.bin $KBL_ME_SHA "Intel ME firmware" +check_and_get_blob fspm.bin $KBL_FSPM_SHA "FSP-M" +check_and_get_blob fsps.bin $KBL_FSPS_SHA "FSP-S" +check_and_get_blob vbt.bin $KBL_VBT_SHA "Video BIOS Table" +check_and_get_blob cpu_microcode_blob.bin $KBL_UCODE_SHA "Intel Microcode Update" + +#clean up after ourselves +rm -f $CBFSTOOL_BIN >/dev/null 2>&1 +rm -f $IFDTOOL_BIN >/dev/null 2>&1 +rm -f $COREBOOT_IMAGE >/dev/null 2>&1 +rm -f *.gz >/dev/null 2>&1 echo "" -echo "Blobs have been downloaded/verified and are ready for use" +echo "All blobs have been verified and are ready for use" \ No newline at end of file diff --git a/blobs/librem_skl/get_blobs.sh b/blobs/librem_skl/get_blobs.sh index c94afd76f..02ffad77d 100755 --- a/blobs/librem_skl/get_blobs.sh +++ b/blobs/librem_skl/get_blobs.sh @@ -1,43 +1,32 @@ #!/bin/bash -e -# depends on : wget sha256sum python2.7 bspatch pv +# depends on : wget sha256sum gunzip -# Librem 13 v2 and Librem 15 v3 binary blob hashes +# Purism source +PURISM_SOURCE="https://source.puri.sm/coreboot/releases/raw/master" + +# Librem 13 v2/v3 and Librem 15 v3 binary blob hashes SKL_UCODE_SHA="9c84936df700d74612a99e6ab581640ecf423d25a0b74a1ea23a6d9872349213" -SKL_DESCRIPTOR_SHA="d5110807c9d67cea6d546ac62125d87042a868177241be4ae17a2dbedef10017" -SKL_ME_NOCONF_SHA="70f07be7934bdbb215c66455a2b0d32651f3b2ecaf2519d83d8ca9cf475cc366" -SKL_ME_SHA="3042150c7f655293a69bcf886836732fc451439ae551a2babf3173f4f0d9a8d3" -SKL_FSP_SHA="a7dfec436f5a21a66b5a455775599d73a95170a3446849a34e89a64a2bb69820" -SKL_FSPM_SHA="7a1acc72073969e6753bbfe145f06c3f4d35e2516cb241641eae968705e2cc46" -SKL_FSPS_SHA="0dac94d249473e9d366597fd1f96a0232fb7bf045a3d08f16784961273351822" -SKL_VBT_SHA="51fa214ca44a61b171662d4c2ca6adc1aa3dc6c3d7a24bf9ae5f249f012d61c0" - -# FSP downloadable from Github -SKL_UCODE_URL="https://github.com/platomav/CPUMicrocodes/raw/bfb23e48eb84dff1495d1c8789f133a1b684de27/Intel/cpu406E3_platC0_ver000000C2_2017-11-16_PRD_C6C6F699.bin" -SKL_FSP_URL="https://github.com/IntelFsp/FSP/raw/8267cde09763c0c699704fbae10e6bd121f01b6a/KabylakeFspBinPkg/Fsp.fd" -SKL_VBT_URL="https://github.com/IntelFsp/FSP/raw/8267cde09763c0c699704fbae10e6bd121f01b6a/KabylakeFspBinPkg/SampleCode/Vbt/Vbt.bin" -SKL_FSP_SPLIT_URL="https://raw.githubusercontent.com/tianocore/edk2/e8a70885d8f34533b6dd69878fe95a249e9af086/IntelFsp2Pkg/Tools/SplitFspBin.py" -SKL_FSP_SPLIT_SHA="f654f6363de68ad78b1baf8b8e573b53715c3bc76f7f3c23562641e49a7033f3" -ME_CLEANER_URL="https://github.com/corna/me_cleaner/raw/9e1611fdf21426d66a29a5ea62b7e30d512859e6/me_cleaner.py" -ME_CLEANER_SHA="412e95538c46d6d4d456987a8897b3d0ad1df118c51378a350540eef51c242d4" - -SKL_DESCRIPTOR_URL="https://source.puri.sm/coreboot/coreboot-files/raw/master/descriptor-skl.bin" -SKL_ME_PATCH_URL="https://source.puri.sm/coreboot/coreboot-files/raw/master/me11.0.18_config.bspatch" -SKL_ME_PATCH_SHA="49019f89206d6371b1377cf738426c3b0ac60c4b1bb89d5d5de00481e7e4fece" - -# Link found on : http://www.win-raid.com/t832f39-Intel-Engine-Firmware-Repositories.html -# Update link if it changes and becomes invalid. -SKL_ME_RAR_URL="https://mega.nz/#!2ElyFQDT!cC0gTlH8rB9EWD4MGX0mVElT94BauqFn-dBKuoEselc" -SKL_ME_FILENAME="11.0.18.1002_CON_LP_C_NPDM_PRD_RGN.bin" -SKL_ME_FULL_FILENAME="Intel CSME 11.0 Firmware Repository Pack r53/$SKL_ME_FILENAME" -SKL_ME_RAR_SHA="1450d7ea985fbcf0ea79ba61bdc71ed3c5de52a6a82f14c07120b6b321e97352" - -# Needed to download SKL_ME_RAR_URL -MEGADOWN_URL="https://github.com/tonikelope/megadown.git" -MEGADOWN_GOOD_COMMIT="83c53ddad1c32bf6d35c61fcd12a2fa94271ff77" - -# Might be required to compile unrar in case unrar-nonfree is not installed -RAR_NONFREE_SOURCE_URL="https://www.rarlab.com/rar/unrarsrc-5.5.8.tar.gz" -RAR_NONFREE_SOURCE_SHA="9b66e4353a9944bc140eb2a919ff99482dd548f858f5e296d809e8f7cdb2fcf4" +SKL_DESCRIPTOR_SHA="642ca36f52aabb5198b82e013bf64a73a5148693a58376fffce322a4d438b524" +SKL_ME_SHA="cf06d3eb8b24490a1ab46fd988b6cef822e5347cd6a2e92bc332cb4a376eb8bc" +SKL_FSPM_SHA="5da3ad7718eb3f6700fb9d97be988d9c8bdd2d8b5910273a80928c49122d5b2d" +SKL_FSPS_SHA="c81ffa40df0b6cd6cfde4f476d452a1f6f2217bc96a3b98a4fa4a037ee7039cf" +SKL_VBT_SHA="0ba40c1b8c0fb030a0e1a789eda8b2a7369339a410ad8c4620719e451ea69b98" + +# cbfstool, ifdtool, coreboot image from Purism repo +CBFSTOOL_FILE="cbfstool.gz" +CBFSTOOL_URL="$PURISM_SOURCE/tools/$CBFSTOOL_FILE" +CBFSTOOL_SHA="3994cba01a51dd34388c8be89fd329f91575c12e499dfe1b81975d9fd115ce58" +CBFSTOOL_BIN="./cbfstool" + +IFDTOOL_FILE="ifdtool.gz" +IFDTOOL_URL="$PURISM_SOURCE/tools/$IFDTOOL_FILE" +IFDTOOL_SHA="08228ece4968794499ebd49a851f7d3f7f1b81352da8cd6e0c7916ac931a7d72" +IFDTOOL_BIN="./ifdtool" + +COREBOOT_IMAGE="coreboot-l13v3.rom" +COREBOOT_IMAGE_FILE="$COREBOOT_IMAGE.gz" +COREBOOT_IMAGE_URL="$PURISM_SOURCE/librem_13v3/$COREBOOT_IMAGE_FILE" +COREBOOT_IMAGE_SHA="34276a7b82624cfb29aed688df7f2b4e747a9e951196e376732e972c8575ece6" die () { local msg=$1 @@ -47,183 +36,89 @@ die () { exit 1 } -check_binary () { - local filename=$1 - local hash=$2 - - if [ ! -f "$filename" ]; then - die "Binary blob file '$filename' does not exist" - fi - sha=$(sha256sum "$filename" | awk '{print $1}') - if [ "$sha" != "$hash" ]; then - die "Extracted binary '$filename' has the wrong SHA256 hash" - fi -} - check_and_get_url () { - filename=$1 - url=$2 - hash=$3 - description=$4 + local filename=$1 + local url=$2 + local hash=$3 + local description=$4 if [ -f "$filename" ]; then sha=$(sha256sum "$filename" | awk '{print $1}') fi if [ "$sha" != "$hash" ]; then - wget -O "$filename" "$url" + echo " Downloading $description..." + wget -O "$filename" "$url" >/dev/null 2>&1 sha=$(sha256sum "$filename" | awk '{print $1}') if [ "$sha" != "$hash" ]; then die "Downloaded $description has the wrong SHA256 hash" fi + if [ "${filename: -3}" == ".gz" ]; then + gunzip -k $filename + fi fi } -get_and_split_fsp () { - fsp="fsp.fd" - fsp_M="fsp_M.fd" - fsp_S="fsp_S.fd" - fsp_T="fsp_T.fd" - fspm="fspm.bin" - fsps="fsps.bin" - fsp_split="SplitFspBin.py" - - if [ -f "$fspm" ]; then - fspm_sha=$(sha256sum "$fspm" | awk '{print $1}') - fi - if [ -f "$fsps" ]; then - fsps_sha=$(sha256sum "$fsps" | awk '{print $1}') - fi - # No FSP-M or FSP-S - if [ "$fspm_sha" != "$SKL_FSPM_SHA" ] || [ "$fsps_sha" != "$SKL_FSPS_SHA" ]; then - if [ -f "$fsp" ]; then - fsp_sha=$(sha256sum "$fsp" | awk '{print $1}') - fi - # No FSP.fd - if [ "$fsp_sha" != "$SKL_FSP_SHA" ]; then - wget -O "$fsp" "$SKL_FSP_URL" - fsp_sha=$(sha256sum "$fsp" | awk '{print $1}') - if [ "$fsp_sha" != "$SKL_FSP_SHA" ]; then - die "Downloaded FSP image has the wrong SHA256 hash" - fi - fi - # No FspSplit - if [ -f "$fsp_split" ]; then - split_sha=$(sha256sum "$fsp_split" | awk '{print $1}') - fi - if [ "$split_sha" != "$SKL_FSP_SHA" ]; then - wget -O "$fsp_split" "$SKL_FSP_SPLIT_URL" - split_sha=$(sha256sum "$fsp_split" | awk '{print $1}') - if [ "$split_sha" != "$SKL_FSP_SPLIT_SHA" ]; then - die "Downloaded FSP Split Tool has the wrong SHA256 hash" - fi - fi - python2 "$fsp_split" split -f "$fsp" - if [ -f "$fsp_M" ]; then - mv "$fsp_M" "$fspm" - fi - if [ -f "$fsp_S" ]; then - mv "$fsp_S" "$fsps" - fi - fspm_sha=$(sha256sum "$fspm" | awk '{print $1}') - fsps_sha=$(sha256sum "$fsps" | awk '{print $1}') - if [ "$fspm_sha" != "$SKL_FSPM_SHA" ] || [ "$fsps_sha" != "$SKL_FSPS_SHA" ]; then - die "Extracted FSP images have the wrong SHA256 hash" - fi - rm -f "$fsp" - rm -f "$fsp_split" - rm -f "$fsp_T" - fi -} +check_and_get_blob () { + local filename=$1 + local hash=$2 + local description=$3 -get_and_patch_me_11 () { - if [ -f "me.bin" ]; then - sha=$(sha256sum "me.bin" | awk '{print $1}') + echo "Checking $filename" + if [ -f "$filename" ]; then + sha=$(sha256sum "$filename" | awk '{print $1}') fi - if [ "$sha" != "$SKL_ME_SHA" ]; then - local rar_filename=me_11_repository.rar - local unrar='unrar-nonfree' - - if [ -f "$rar_filename" ]; then - sha=$(sha256sum "$rar_filename" | awk '{print $1}') - fi - if ! type "$unrar" &> /dev/null; then - wget -O unrar.tar.gz "$RAR_NONFREE_SOURCE_URL" - sha=$(sha256sum unrar.tar.gz | awk '{print $1}') - if [ "$sha" != "$RAR_NONFREE_SOURCE_SHA" ]; then - die "Unrar source package has the wrong SHA256 hash" - fi - tar -xzvf unrar.tar.gz - ( - cd unrar - make - ) - unrar="`pwd`/unrar/unrar" - fi - if [ "$sha" != "$SKL_ME_RAR_SHA" ]; then - if [ ! -d megadown ]; then - git clone $MEGADOWN_URL - fi - ( - cd megadown - git checkout $MEGADOWN_GOOD_COMMIT - echo -e "\n\nDownloading ME 11 Repository from $SKL_ME_RAR_URL" - echo "Please be patient while the download finishes..." - ./megadown "$SKL_ME_RAR_URL" -o ../$rar_filename 2>/dev/null - ) - sha=$(sha256sum "$rar_filename" | awk '{print $1}') - if [ "$sha" != "$SKL_ME_RAR_SHA" ]; then - # We'll assume the rar file was updated again - me_dirname=$("$unrar" l "$rar_filename" | grep '\.\.\.D\.\.\.' | tr -s [:blank:] | cut -d' ' -f 6-) - SKL_ME_FULL_FILENAME="$me_dirname/$SKL_ME_FILENAME" - fi - fi - if type "$unrar" &> /dev/null; then - "$unrar" e -y "$rar_filename" "$SKL_ME_FULL_FILENAME" + if [ "$sha" != "$hash" ]; then + # get tools + check_and_get_tools + # extract from coreboot image + check_and_get_url $COREBOOT_IMAGE_FILE $COREBOOT_IMAGE_URL $COREBOOT_IMAGE_SHA "precompiled coreboot image" + echo "Extracting $filename" + if [ $filename = "descriptor.bin" ]; then + $IFDTOOL_BIN -x $COREBOOT_IMAGE >/dev/null 2>&1 + mv flashregion_0_flashdescriptor.bin descriptor.bin + echo "Extracting me.bin" + mv flashregion_2_intel_me.bin me.bin + rm flashregion_* > /dev/null 2>&1 + elif [ $filename = "me.bin" ]; then + $IFDTOOL_BIN -x $COREBOOT_IMAGE >/dev/null 2>&1 + mv flashregion_2_intel_me.bin me.bin + rm flashregion_* > /dev/null 2>&1 else - die "Couldn't extract ME image. Requires unrar-nonfree" - fi - sha="" - if [ -f "$SKL_ME_FILENAME" ]; then - sha=$(sha256sum "$SKL_ME_FILENAME" | awk '{print $1}') + $CBFSTOOL_BIN $COREBOOT_IMAGE extract -n $filename -f $filename >/dev/null 2>&1 fi - if [ "$sha" != "$SKL_ME_NOCONF_SHA" ]; then - die "Couldn't extract ME image with the correct SHA256 hash" + sha=$(sha256sum "$filename" | awk '{print $1}') + if [ "$sha" != "$hash" ]; then + die "Downloaded $description has the wrong SHA256 hash" fi - check_and_get_url me11.0.18_config.bspatch $SKL_ME_PATCH_URL $SKL_ME_PATCH_SHA "ME Patch" - bspatch "$SKL_ME_FILENAME" "me.bin" me11.0.18_config.bspatch - rm -f me11.0.18_config.bspatch - rm -f "$SKL_ME_FILENAME" - rm -f "$rar_filename" fi } -apply_me_cleaner() { - if [ -f "me_cleaner.py" ]; then - sha=$(sha256sum "me_cleaner.py" | awk '{print $1}') - fi - if [ "$sha" != "$ME_CLEANER_SHA" ]; then - wget -O "me_cleaner.py" "$ME_CLEANER_URL" - sha=$(sha256sum "me_cleaner.py" | awk '{print $1}') - if [ "$sha" != "$ME_CLEANER_SHA" ]; then - die "Downloaded ME Cleaner has the wrong SHA256 hash" - fi - fi - cat descriptor.bin me.bin > desc_me.bin - python2 "me_cleaner.py" -s desc_me.bin - python2 "me_cleaner.py" -w "MFS" me.bin - dd if=desc_me.bin of=descriptor.bin bs=4096 count=1 - rm -f desc_me.bin - rm -f me_cleaner.py +echo "" + +check_and_get_tools() { + check_and_get_url $CBFSTOOL_FILE $CBFSTOOL_URL $CBFSTOOL_SHA "cbfstool" + chmod +x $CBFSTOOL_BIN + check_and_get_url $IFDTOOL_FILE $IFDTOOL_URL $IFDTOOL_SHA "ifdtool" + chmod +x $IFDTOOL_BIN } -check_and_get_url descriptor.bin $SKL_DESCRIPTOR_URL $SKL_DESCRIPTOR_SHA "Intel Flash Descriptor" -check_binary descriptor.bin $SKL_DESCRIPTOR_SHA -get_and_patch_me_11 -check_binary me.bin $SKL_ME_SHA -apply_me_cleaner -get_and_split_fsp -check_binary fspm.bin $SKL_FSPM_SHA -check_binary fsps.bin $SKL_FSPS_SHA -check_and_get_url vbt.bin $SKL_VBT_URL $SKL_VBT_SHA "Video BIOS Table" -check_and_get_url cpu_microcode_blob.bin $SKL_UCODE_URL $SKL_UCODE_SHA "Intel Microcode Update" +# get tools for extraction +#check_and_get_tools + +# get/verify blobs +check_and_get_blob descriptor.bin $SKL_DESCRIPTOR_SHA "Intel Flash Descriptor" +check_and_get_blob me.bin $SKL_ME_SHA "Intel ME firmware" +check_and_get_blob fspm.bin $SKL_FSPM_SHA "FSP-M" +check_and_get_blob fsps.bin $SKL_FSPS_SHA "FSP-S" +check_and_get_blob vbt.bin $SKL_VBT_SHA "Video BIOS Table" +check_and_get_blob cpu_microcode_blob.bin $SKL_UCODE_SHA "Intel Microcode Update" + +#clean up after ourselves +rm -f $CBFSTOOL_BIN >/dev/null 2>&1 +rm -f $IFDTOOL_BIN >/dev/null 2>&1 +rm -f $COREBOOT_IMAGE >/dev/null 2>&1 +rm -f *.gz >/dev/null 2>&1 + +echo "" +echo "All blobs have been verified and are ready for use" \ No newline at end of file From 1fda1fffb03ee9091701902f30591a5ff485fd1b Mon Sep 17 00:00:00 2001 From: Thierry Laurion Date: Sun, 17 Mar 2019 19:33:55 -0400 Subject: [PATCH 101/102] Keep Xen cmdline arguments while appending Heads required ones. Fixes #536 --- initrd/bin/kexec-boot | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/initrd/bin/kexec-boot b/initrd/bin/kexec-boot index 49e48aeef..fb9e9edef 100755 --- a/initrd/bin/kexec-boot +++ b/initrd/bin/kexec-boot @@ -70,7 +70,7 @@ do if [ "$kexectype" = "xen" ]; then # always use xen with custom arguments kexeccmd="$kexeccmd -l $filepath" - kexeccmd="$kexeccmd --command-line \"no-real-mode reboot=no vga=current\"" + kexeccmd="$kexeccmd --command-line \"$restval no-real-mode reboot=no vga=current\"" elif [ "$kexectype" = "multiboot" ]; then kexeccmd="$kexeccmd -l $filepath" kexeccmd="$kexeccmd --command-line \"$restval\"" From 553cf0958b1c8122c8415540e422aba224bbbdd3 Mon Sep 17 00:00:00 2001 From: Kyle Rankin Date: Fri, 19 Apr 2019 14:11:45 -0700 Subject: [PATCH 102/102] Add dynamic USB device detection Instead of relying on a hard-coded USB disk, it would be better if the mount script attempted to dynamically detect available USB disks. This modification to the USB mount script attempts to handle the common case of a single USB disk but can also handle the case of multiple disks where it will present the user with all available USB disks --- initrd/bin/flash-gui.sh | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/initrd/bin/flash-gui.sh b/initrd/bin/flash-gui.sh index b8de9a23c..3780051a1 100755 --- a/initrd/bin/flash-gui.sh +++ b/initrd/bin/flash-gui.sh @@ -70,10 +70,10 @@ file_selector() { while true; do unset menu_choice - whiptail --clear --title "BIOS Management Menu" \ - --menu 'Select the BIOS function to perform' 20 90 10 \ - 'f' ' Flash the BIOS with a new ROM' \ - 'c' ' Flash the BIOS with a new cleaned ROM' \ + whiptail --clear --title "Firmware Management Menu" \ + --menu "Select the firmware function to perform\n\nRetaining settings copies existing settings to the new firmware:\n* Keeps your GPG keyring\n* Keeps changes to the default /boot device\n\nErasing settings uses the new firmware as-is:\n* Erases any existing GPG keyring\n* Restores firmware to default factory settings\n\nIf you are just updating your firmware, you probably want to retain\nyour settings." 20 90 10 \ + 'f' ' Flash the firmware with a new ROM, retain settings' \ + 'c' ' Flash the firmware with a new ROM, erase settings' \ 'x' ' Exit' \ 2>/tmp/whiptail || recovery "GUI menu failed" @@ -104,7 +104,7 @@ while true; do /bin/flash.sh "$ROM" fi whiptail --title 'ROM Flashed Successfully' \ - --msgbox "$ROM flashed successfully. Press Enter to reboot" 16 60 + --msgbox "$ROM flashed successfully.\nPress Enter to reboot" 16 60 umount /media /bin/reboot else