diff options
author | Martin Liska <mliska@suse.cz> | 2022-01-14 16:56:44 +0100 |
---|---|---|
committer | Martin Liska <mliska@suse.cz> | 2022-01-17 22:12:04 +0100 |
commit | 5c69acb32329d49e58c26fa41ae74229a52b9106 (patch) | |
tree | ddb05f9d73afb6f998457d2ac4b720e3b3b60483 /gcc/config/nds32/nds32.c | |
parent | 490e23032baaece71f2ec09fa1805064b150fbc2 (diff) | |
download | gcc-5c69acb32329d49e58c26fa41ae74229a52b9106.zip gcc-5c69acb32329d49e58c26fa41ae74229a52b9106.tar.gz gcc-5c69acb32329d49e58c26fa41ae74229a52b9106.tar.bz2 |
Rename .c files to .cc files.
gcc/ada/ChangeLog:
* adadecode.c: Moved to...
* adadecode.cc: ...here.
* affinity.c: Moved to...
* affinity.cc: ...here.
* argv-lynxos178-raven-cert.c: Moved to...
* argv-lynxos178-raven-cert.cc: ...here.
* argv.c: Moved to...
* argv.cc: ...here.
* aux-io.c: Moved to...
* aux-io.cc: ...here.
* cio.c: Moved to...
* cio.cc: ...here.
* cstreams.c: Moved to...
* cstreams.cc: ...here.
* env.c: Moved to...
* env.cc: ...here.
* exit.c: Moved to...
* exit.cc: ...here.
* expect.c: Moved to...
* expect.cc: ...here.
* final.c: Moved to...
* final.cc: ...here.
* gcc-interface/cuintp.c: Moved to...
* gcc-interface/cuintp.cc: ...here.
* gcc-interface/decl.c: Moved to...
* gcc-interface/decl.cc: ...here.
* gcc-interface/misc.c: Moved to...
* gcc-interface/misc.cc: ...here.
* gcc-interface/targtyps.c: Moved to...
* gcc-interface/targtyps.cc: ...here.
* gcc-interface/trans.c: Moved to...
* gcc-interface/trans.cc: ...here.
* gcc-interface/utils.c: Moved to...
* gcc-interface/utils.cc: ...here.
* gcc-interface/utils2.c: Moved to...
* gcc-interface/utils2.cc: ...here.
* init.c: Moved to...
* init.cc: ...here.
* initialize.c: Moved to...
* initialize.cc: ...here.
* libgnarl/thread.c: Moved to...
* libgnarl/thread.cc: ...here.
* link.c: Moved to...
* link.cc: ...here.
* locales.c: Moved to...
* locales.cc: ...here.
* mkdir.c: Moved to...
* mkdir.cc: ...here.
* raise.c: Moved to...
* raise.cc: ...here.
* rtfinal.c: Moved to...
* rtfinal.cc: ...here.
* rtinit.c: Moved to...
* rtinit.cc: ...here.
* seh_init.c: Moved to...
* seh_init.cc: ...here.
* sigtramp-armdroid.c: Moved to...
* sigtramp-armdroid.cc: ...here.
* sigtramp-ios.c: Moved to...
* sigtramp-ios.cc: ...here.
* sigtramp-qnx.c: Moved to...
* sigtramp-qnx.cc: ...here.
* sigtramp-vxworks.c: Moved to...
* sigtramp-vxworks.cc: ...here.
* socket.c: Moved to...
* socket.cc: ...here.
* tracebak.c: Moved to...
* tracebak.cc: ...here.
* version.c: Moved to...
* version.cc: ...here.
* vx_stack_info.c: Moved to...
* vx_stack_info.cc: ...here.
gcc/ChangeLog:
* adjust-alignment.c: Moved to...
* adjust-alignment.cc: ...here.
* alias.c: Moved to...
* alias.cc: ...here.
* alloc-pool.c: Moved to...
* alloc-pool.cc: ...here.
* asan.c: Moved to...
* asan.cc: ...here.
* attribs.c: Moved to...
* attribs.cc: ...here.
* auto-inc-dec.c: Moved to...
* auto-inc-dec.cc: ...here.
* auto-profile.c: Moved to...
* auto-profile.cc: ...here.
* bb-reorder.c: Moved to...
* bb-reorder.cc: ...here.
* bitmap.c: Moved to...
* bitmap.cc: ...here.
* btfout.c: Moved to...
* btfout.cc: ...here.
* builtins.c: Moved to...
* builtins.cc: ...here.
* caller-save.c: Moved to...
* caller-save.cc: ...here.
* calls.c: Moved to...
* calls.cc: ...here.
* ccmp.c: Moved to...
* ccmp.cc: ...here.
* cfg.c: Moved to...
* cfg.cc: ...here.
* cfganal.c: Moved to...
* cfganal.cc: ...here.
* cfgbuild.c: Moved to...
* cfgbuild.cc: ...here.
* cfgcleanup.c: Moved to...
* cfgcleanup.cc: ...here.
* cfgexpand.c: Moved to...
* cfgexpand.cc: ...here.
* cfghooks.c: Moved to...
* cfghooks.cc: ...here.
* cfgloop.c: Moved to...
* cfgloop.cc: ...here.
* cfgloopanal.c: Moved to...
* cfgloopanal.cc: ...here.
* cfgloopmanip.c: Moved to...
* cfgloopmanip.cc: ...here.
* cfgrtl.c: Moved to...
* cfgrtl.cc: ...here.
* cgraph.c: Moved to...
* cgraph.cc: ...here.
* cgraphbuild.c: Moved to...
* cgraphbuild.cc: ...here.
* cgraphclones.c: Moved to...
* cgraphclones.cc: ...here.
* cgraphunit.c: Moved to...
* cgraphunit.cc: ...here.
* collect-utils.c: Moved to...
* collect-utils.cc: ...here.
* collect2-aix.c: Moved to...
* collect2-aix.cc: ...here.
* collect2.c: Moved to...
* collect2.cc: ...here.
* combine-stack-adj.c: Moved to...
* combine-stack-adj.cc: ...here.
* combine.c: Moved to...
* combine.cc: ...here.
* common/common-targhooks.c: Moved to...
* common/common-targhooks.cc: ...here.
* common/config/aarch64/aarch64-common.c: Moved to...
* common/config/aarch64/aarch64-common.cc: ...here.
* common/config/alpha/alpha-common.c: Moved to...
* common/config/alpha/alpha-common.cc: ...here.
* common/config/arc/arc-common.c: Moved to...
* common/config/arc/arc-common.cc: ...here.
* common/config/arm/arm-common.c: Moved to...
* common/config/arm/arm-common.cc: ...here.
* common/config/avr/avr-common.c: Moved to...
* common/config/avr/avr-common.cc: ...here.
* common/config/bfin/bfin-common.c: Moved to...
* common/config/bfin/bfin-common.cc: ...here.
* common/config/bpf/bpf-common.c: Moved to...
* common/config/bpf/bpf-common.cc: ...here.
* common/config/c6x/c6x-common.c: Moved to...
* common/config/c6x/c6x-common.cc: ...here.
* common/config/cr16/cr16-common.c: Moved to...
* common/config/cr16/cr16-common.cc: ...here.
* common/config/cris/cris-common.c: Moved to...
* common/config/cris/cris-common.cc: ...here.
* common/config/csky/csky-common.c: Moved to...
* common/config/csky/csky-common.cc: ...here.
* common/config/default-common.c: Moved to...
* common/config/default-common.cc: ...here.
* common/config/epiphany/epiphany-common.c: Moved to...
* common/config/epiphany/epiphany-common.cc: ...here.
* common/config/fr30/fr30-common.c: Moved to...
* common/config/fr30/fr30-common.cc: ...here.
* common/config/frv/frv-common.c: Moved to...
* common/config/frv/frv-common.cc: ...here.
* common/config/gcn/gcn-common.c: Moved to...
* common/config/gcn/gcn-common.cc: ...here.
* common/config/h8300/h8300-common.c: Moved to...
* common/config/h8300/h8300-common.cc: ...here.
* common/config/i386/i386-common.c: Moved to...
* common/config/i386/i386-common.cc: ...here.
* common/config/ia64/ia64-common.c: Moved to...
* common/config/ia64/ia64-common.cc: ...here.
* common/config/iq2000/iq2000-common.c: Moved to...
* common/config/iq2000/iq2000-common.cc: ...here.
* common/config/lm32/lm32-common.c: Moved to...
* common/config/lm32/lm32-common.cc: ...here.
* common/config/m32r/m32r-common.c: Moved to...
* common/config/m32r/m32r-common.cc: ...here.
* common/config/m68k/m68k-common.c: Moved to...
* common/config/m68k/m68k-common.cc: ...here.
* common/config/mcore/mcore-common.c: Moved to...
* common/config/mcore/mcore-common.cc: ...here.
* common/config/microblaze/microblaze-common.c: Moved to...
* common/config/microblaze/microblaze-common.cc: ...here.
* common/config/mips/mips-common.c: Moved to...
* common/config/mips/mips-common.cc: ...here.
* common/config/mmix/mmix-common.c: Moved to...
* common/config/mmix/mmix-common.cc: ...here.
* common/config/mn10300/mn10300-common.c: Moved to...
* common/config/mn10300/mn10300-common.cc: ...here.
* common/config/msp430/msp430-common.c: Moved to...
* common/config/msp430/msp430-common.cc: ...here.
* common/config/nds32/nds32-common.c: Moved to...
* common/config/nds32/nds32-common.cc: ...here.
* common/config/nios2/nios2-common.c: Moved to...
* common/config/nios2/nios2-common.cc: ...here.
* common/config/nvptx/nvptx-common.c: Moved to...
* common/config/nvptx/nvptx-common.cc: ...here.
* common/config/or1k/or1k-common.c: Moved to...
* common/config/or1k/or1k-common.cc: ...here.
* common/config/pa/pa-common.c: Moved to...
* common/config/pa/pa-common.cc: ...here.
* common/config/pdp11/pdp11-common.c: Moved to...
* common/config/pdp11/pdp11-common.cc: ...here.
* common/config/pru/pru-common.c: Moved to...
* common/config/pru/pru-common.cc: ...here.
* common/config/riscv/riscv-common.c: Moved to...
* common/config/riscv/riscv-common.cc: ...here.
* common/config/rs6000/rs6000-common.c: Moved to...
* common/config/rs6000/rs6000-common.cc: ...here.
* common/config/rx/rx-common.c: Moved to...
* common/config/rx/rx-common.cc: ...here.
* common/config/s390/s390-common.c: Moved to...
* common/config/s390/s390-common.cc: ...here.
* common/config/sh/sh-common.c: Moved to...
* common/config/sh/sh-common.cc: ...here.
* common/config/sparc/sparc-common.c: Moved to...
* common/config/sparc/sparc-common.cc: ...here.
* common/config/tilegx/tilegx-common.c: Moved to...
* common/config/tilegx/tilegx-common.cc: ...here.
* common/config/tilepro/tilepro-common.c: Moved to...
* common/config/tilepro/tilepro-common.cc: ...here.
* common/config/v850/v850-common.c: Moved to...
* common/config/v850/v850-common.cc: ...here.
* common/config/vax/vax-common.c: Moved to...
* common/config/vax/vax-common.cc: ...here.
* common/config/visium/visium-common.c: Moved to...
* common/config/visium/visium-common.cc: ...here.
* common/config/xstormy16/xstormy16-common.c: Moved to...
* common/config/xstormy16/xstormy16-common.cc: ...here.
* common/config/xtensa/xtensa-common.c: Moved to...
* common/config/xtensa/xtensa-common.cc: ...here.
* compare-elim.c: Moved to...
* compare-elim.cc: ...here.
* config/aarch64/aarch64-bti-insert.c: Moved to...
* config/aarch64/aarch64-bti-insert.cc: ...here.
* config/aarch64/aarch64-builtins.c: Moved to...
* config/aarch64/aarch64-builtins.cc: ...here.
* config/aarch64/aarch64-c.c: Moved to...
* config/aarch64/aarch64-c.cc: ...here.
* config/aarch64/aarch64-d.c: Moved to...
* config/aarch64/aarch64-d.cc: ...here.
* config/aarch64/aarch64.c: Moved to...
* config/aarch64/aarch64.cc: ...here.
* config/aarch64/cortex-a57-fma-steering.c: Moved to...
* config/aarch64/cortex-a57-fma-steering.cc: ...here.
* config/aarch64/driver-aarch64.c: Moved to...
* config/aarch64/driver-aarch64.cc: ...here.
* config/aarch64/falkor-tag-collision-avoidance.c: Moved to...
* config/aarch64/falkor-tag-collision-avoidance.cc: ...here.
* config/aarch64/host-aarch64-darwin.c: Moved to...
* config/aarch64/host-aarch64-darwin.cc: ...here.
* config/alpha/alpha.c: Moved to...
* config/alpha/alpha.cc: ...here.
* config/alpha/driver-alpha.c: Moved to...
* config/alpha/driver-alpha.cc: ...here.
* config/arc/arc-c.c: Moved to...
* config/arc/arc-c.cc: ...here.
* config/arc/arc.c: Moved to...
* config/arc/arc.cc: ...here.
* config/arc/driver-arc.c: Moved to...
* config/arc/driver-arc.cc: ...here.
* config/arm/aarch-common.c: Moved to...
* config/arm/aarch-common.cc: ...here.
* config/arm/arm-builtins.c: Moved to...
* config/arm/arm-builtins.cc: ...here.
* config/arm/arm-c.c: Moved to...
* config/arm/arm-c.cc: ...here.
* config/arm/arm-d.c: Moved to...
* config/arm/arm-d.cc: ...here.
* config/arm/arm.c: Moved to...
* config/arm/arm.cc: ...here.
* config/arm/driver-arm.c: Moved to...
* config/arm/driver-arm.cc: ...here.
* config/avr/avr-c.c: Moved to...
* config/avr/avr-c.cc: ...here.
* config/avr/avr-devices.c: Moved to...
* config/avr/avr-devices.cc: ...here.
* config/avr/avr-log.c: Moved to...
* config/avr/avr-log.cc: ...here.
* config/avr/avr.c: Moved to...
* config/avr/avr.cc: ...here.
* config/avr/driver-avr.c: Moved to...
* config/avr/driver-avr.cc: ...here.
* config/avr/gen-avr-mmcu-specs.c: Moved to...
* config/avr/gen-avr-mmcu-specs.cc: ...here.
* config/avr/gen-avr-mmcu-texi.c: Moved to...
* config/avr/gen-avr-mmcu-texi.cc: ...here.
* config/bfin/bfin.c: Moved to...
* config/bfin/bfin.cc: ...here.
* config/bpf/bpf.c: Moved to...
* config/bpf/bpf.cc: ...here.
* config/bpf/coreout.c: Moved to...
* config/bpf/coreout.cc: ...here.
* config/c6x/c6x.c: Moved to...
* config/c6x/c6x.cc: ...here.
* config/cr16/cr16.c: Moved to...
* config/cr16/cr16.cc: ...here.
* config/cris/cris.c: Moved to...
* config/cris/cris.cc: ...here.
* config/csky/csky.c: Moved to...
* config/csky/csky.cc: ...here.
* config/darwin-c.c: Moved to...
* config/darwin-c.cc: ...here.
* config/darwin-d.c: Moved to...
* config/darwin-d.cc: ...here.
* config/darwin-driver.c: Moved to...
* config/darwin-driver.cc: ...here.
* config/darwin-f.c: Moved to...
* config/darwin-f.cc: ...here.
* config/darwin.c: Moved to...
* config/darwin.cc: ...here.
* config/default-c.c: Moved to...
* config/default-c.cc: ...here.
* config/default-d.c: Moved to...
* config/default-d.cc: ...here.
* config/dragonfly-d.c: Moved to...
* config/dragonfly-d.cc: ...here.
* config/epiphany/epiphany.c: Moved to...
* config/epiphany/epiphany.cc: ...here.
* config/epiphany/mode-switch-use.c: Moved to...
* config/epiphany/mode-switch-use.cc: ...here.
* config/epiphany/resolve-sw-modes.c: Moved to...
* config/epiphany/resolve-sw-modes.cc: ...here.
* config/fr30/fr30.c: Moved to...
* config/fr30/fr30.cc: ...here.
* config/freebsd-d.c: Moved to...
* config/freebsd-d.cc: ...here.
* config/frv/frv.c: Moved to...
* config/frv/frv.cc: ...here.
* config/ft32/ft32.c: Moved to...
* config/ft32/ft32.cc: ...here.
* config/gcn/driver-gcn.c: Moved to...
* config/gcn/driver-gcn.cc: ...here.
* config/gcn/gcn-run.c: Moved to...
* config/gcn/gcn-run.cc: ...here.
* config/gcn/gcn-tree.c: Moved to...
* config/gcn/gcn-tree.cc: ...here.
* config/gcn/gcn.c: Moved to...
* config/gcn/gcn.cc: ...here.
* config/gcn/mkoffload.c: Moved to...
* config/gcn/mkoffload.cc: ...here.
* config/glibc-c.c: Moved to...
* config/glibc-c.cc: ...here.
* config/glibc-d.c: Moved to...
* config/glibc-d.cc: ...here.
* config/h8300/h8300.c: Moved to...
* config/h8300/h8300.cc: ...here.
* config/host-darwin.c: Moved to...
* config/host-darwin.cc: ...here.
* config/host-hpux.c: Moved to...
* config/host-hpux.cc: ...here.
* config/host-linux.c: Moved to...
* config/host-linux.cc: ...here.
* config/host-netbsd.c: Moved to...
* config/host-netbsd.cc: ...here.
* config/host-openbsd.c: Moved to...
* config/host-openbsd.cc: ...here.
* config/host-solaris.c: Moved to...
* config/host-solaris.cc: ...here.
* config/i386/djgpp.c: Moved to...
* config/i386/djgpp.cc: ...here.
* config/i386/driver-i386.c: Moved to...
* config/i386/driver-i386.cc: ...here.
* config/i386/driver-mingw32.c: Moved to...
* config/i386/driver-mingw32.cc: ...here.
* config/i386/gnu-property.c: Moved to...
* config/i386/gnu-property.cc: ...here.
* config/i386/host-cygwin.c: Moved to...
* config/i386/host-cygwin.cc: ...here.
* config/i386/host-i386-darwin.c: Moved to...
* config/i386/host-i386-darwin.cc: ...here.
* config/i386/host-mingw32.c: Moved to...
* config/i386/host-mingw32.cc: ...here.
* config/i386/i386-builtins.c: Moved to...
* config/i386/i386-builtins.cc: ...here.
* config/i386/i386-c.c: Moved to...
* config/i386/i386-c.cc: ...here.
* config/i386/i386-d.c: Moved to...
* config/i386/i386-d.cc: ...here.
* config/i386/i386-expand.c: Moved to...
* config/i386/i386-expand.cc: ...here.
* config/i386/i386-features.c: Moved to...
* config/i386/i386-features.cc: ...here.
* config/i386/i386-options.c: Moved to...
* config/i386/i386-options.cc: ...here.
* config/i386/i386.c: Moved to...
* config/i386/i386.cc: ...here.
* config/i386/intelmic-mkoffload.c: Moved to...
* config/i386/intelmic-mkoffload.cc: ...here.
* config/i386/msformat-c.c: Moved to...
* config/i386/msformat-c.cc: ...here.
* config/i386/winnt-cxx.c: Moved to...
* config/i386/winnt-cxx.cc: ...here.
* config/i386/winnt-d.c: Moved to...
* config/i386/winnt-d.cc: ...here.
* config/i386/winnt-stubs.c: Moved to...
* config/i386/winnt-stubs.cc: ...here.
* config/i386/winnt.c: Moved to...
* config/i386/winnt.cc: ...here.
* config/i386/x86-tune-sched-atom.c: Moved to...
* config/i386/x86-tune-sched-atom.cc: ...here.
* config/i386/x86-tune-sched-bd.c: Moved to...
* config/i386/x86-tune-sched-bd.cc: ...here.
* config/i386/x86-tune-sched-core.c: Moved to...
* config/i386/x86-tune-sched-core.cc: ...here.
* config/i386/x86-tune-sched.c: Moved to...
* config/i386/x86-tune-sched.cc: ...here.
* config/ia64/ia64-c.c: Moved to...
* config/ia64/ia64-c.cc: ...here.
* config/ia64/ia64.c: Moved to...
* config/ia64/ia64.cc: ...here.
* config/iq2000/iq2000.c: Moved to...
* config/iq2000/iq2000.cc: ...here.
* config/linux.c: Moved to...
* config/linux.cc: ...here.
* config/lm32/lm32.c: Moved to...
* config/lm32/lm32.cc: ...here.
* config/m32c/m32c-pragma.c: Moved to...
* config/m32c/m32c-pragma.cc: ...here.
* config/m32c/m32c.c: Moved to...
* config/m32c/m32c.cc: ...here.
* config/m32r/m32r.c: Moved to...
* config/m32r/m32r.cc: ...here.
* config/m68k/m68k.c: Moved to...
* config/m68k/m68k.cc: ...here.
* config/mcore/mcore.c: Moved to...
* config/mcore/mcore.cc: ...here.
* config/microblaze/microblaze-c.c: Moved to...
* config/microblaze/microblaze-c.cc: ...here.
* config/microblaze/microblaze.c: Moved to...
* config/microblaze/microblaze.cc: ...here.
* config/mips/driver-native.c: Moved to...
* config/mips/driver-native.cc: ...here.
* config/mips/frame-header-opt.c: Moved to...
* config/mips/frame-header-opt.cc: ...here.
* config/mips/mips-d.c: Moved to...
* config/mips/mips-d.cc: ...here.
* config/mips/mips.c: Moved to...
* config/mips/mips.cc: ...here.
* config/mmix/mmix.c: Moved to...
* config/mmix/mmix.cc: ...here.
* config/mn10300/mn10300.c: Moved to...
* config/mn10300/mn10300.cc: ...here.
* config/moxie/moxie.c: Moved to...
* config/moxie/moxie.cc: ...here.
* config/msp430/driver-msp430.c: Moved to...
* config/msp430/driver-msp430.cc: ...here.
* config/msp430/msp430-c.c: Moved to...
* config/msp430/msp430-c.cc: ...here.
* config/msp430/msp430-devices.c: Moved to...
* config/msp430/msp430-devices.cc: ...here.
* config/msp430/msp430.c: Moved to...
* config/msp430/msp430.cc: ...here.
* config/nds32/nds32-cost.c: Moved to...
* config/nds32/nds32-cost.cc: ...here.
* config/nds32/nds32-fp-as-gp.c: Moved to...
* config/nds32/nds32-fp-as-gp.cc: ...here.
* config/nds32/nds32-intrinsic.c: Moved to...
* config/nds32/nds32-intrinsic.cc: ...here.
* config/nds32/nds32-isr.c: Moved to...
* config/nds32/nds32-isr.cc: ...here.
* config/nds32/nds32-md-auxiliary.c: Moved to...
* config/nds32/nds32-md-auxiliary.cc: ...here.
* config/nds32/nds32-memory-manipulation.c: Moved to...
* config/nds32/nds32-memory-manipulation.cc: ...here.
* config/nds32/nds32-pipelines-auxiliary.c: Moved to...
* config/nds32/nds32-pipelines-auxiliary.cc: ...here.
* config/nds32/nds32-predicates.c: Moved to...
* config/nds32/nds32-predicates.cc: ...here.
* config/nds32/nds32-relax-opt.c: Moved to...
* config/nds32/nds32-relax-opt.cc: ...here.
* config/nds32/nds32-utils.c: Moved to...
* config/nds32/nds32-utils.cc: ...here.
* config/nds32/nds32.c: Moved to...
* config/nds32/nds32.cc: ...here.
* config/netbsd-d.c: Moved to...
* config/netbsd-d.cc: ...here.
* config/netbsd.c: Moved to...
* config/netbsd.cc: ...here.
* config/nios2/nios2.c: Moved to...
* config/nios2/nios2.cc: ...here.
* config/nvptx/mkoffload.c: Moved to...
* config/nvptx/mkoffload.cc: ...here.
* config/nvptx/nvptx-c.c: Moved to...
* config/nvptx/nvptx-c.cc: ...here.
* config/nvptx/nvptx.c: Moved to...
* config/nvptx/nvptx.cc: ...here.
* config/openbsd-d.c: Moved to...
* config/openbsd-d.cc: ...here.
* config/or1k/or1k.c: Moved to...
* config/or1k/or1k.cc: ...here.
* config/pa/pa-d.c: Moved to...
* config/pa/pa-d.cc: ...here.
* config/pa/pa.c: Moved to...
* config/pa/pa.cc: ...here.
* config/pdp11/pdp11.c: Moved to...
* config/pdp11/pdp11.cc: ...here.
* config/pru/pru-passes.c: Moved to...
* config/pru/pru-passes.cc: ...here.
* config/pru/pru-pragma.c: Moved to...
* config/pru/pru-pragma.cc: ...here.
* config/pru/pru.c: Moved to...
* config/pru/pru.cc: ...here.
* config/riscv/riscv-builtins.c: Moved to...
* config/riscv/riscv-builtins.cc: ...here.
* config/riscv/riscv-c.c: Moved to...
* config/riscv/riscv-c.cc: ...here.
* config/riscv/riscv-d.c: Moved to...
* config/riscv/riscv-d.cc: ...here.
* config/riscv/riscv-shorten-memrefs.c: Moved to...
* config/riscv/riscv-shorten-memrefs.cc: ...here.
* config/riscv/riscv-sr.c: Moved to...
* config/riscv/riscv-sr.cc: ...here.
* config/riscv/riscv.c: Moved to...
* config/riscv/riscv.cc: ...here.
* config/rl78/rl78-c.c: Moved to...
* config/rl78/rl78-c.cc: ...here.
* config/rl78/rl78.c: Moved to...
* config/rl78/rl78.cc: ...here.
* config/rs6000/driver-rs6000.c: Moved to...
* config/rs6000/driver-rs6000.cc: ...here.
* config/rs6000/host-darwin.c: Moved to...
* config/rs6000/host-darwin.cc: ...here.
* config/rs6000/host-ppc64-darwin.c: Moved to...
* config/rs6000/host-ppc64-darwin.cc: ...here.
* config/rs6000/rbtree.c: Moved to...
* config/rs6000/rbtree.cc: ...here.
* config/rs6000/rs6000-c.c: Moved to...
* config/rs6000/rs6000-c.cc: ...here.
* config/rs6000/rs6000-call.c: Moved to...
* config/rs6000/rs6000-call.cc: ...here.
* config/rs6000/rs6000-d.c: Moved to...
* config/rs6000/rs6000-d.cc: ...here.
* config/rs6000/rs6000-gen-builtins.c: Moved to...
* config/rs6000/rs6000-gen-builtins.cc: ...here.
* config/rs6000/rs6000-linux.c: Moved to...
* config/rs6000/rs6000-linux.cc: ...here.
* config/rs6000/rs6000-logue.c: Moved to...
* config/rs6000/rs6000-logue.cc: ...here.
* config/rs6000/rs6000-p8swap.c: Moved to...
* config/rs6000/rs6000-p8swap.cc: ...here.
* config/rs6000/rs6000-pcrel-opt.c: Moved to...
* config/rs6000/rs6000-pcrel-opt.cc: ...here.
* config/rs6000/rs6000-string.c: Moved to...
* config/rs6000/rs6000-string.cc: ...here.
* config/rs6000/rs6000.c: Moved to...
* config/rs6000/rs6000.cc: ...here.
* config/rx/rx.c: Moved to...
* config/rx/rx.cc: ...here.
* config/s390/driver-native.c: Moved to...
* config/s390/driver-native.cc: ...here.
* config/s390/s390-c.c: Moved to...
* config/s390/s390-c.cc: ...here.
* config/s390/s390-d.c: Moved to...
* config/s390/s390-d.cc: ...here.
* config/s390/s390.c: Moved to...
* config/s390/s390.cc: ...here.
* config/sh/divtab-sh4-300.c: Moved to...
* config/sh/divtab-sh4-300.cc: ...here.
* config/sh/divtab-sh4.c: Moved to...
* config/sh/divtab-sh4.cc: ...here.
* config/sh/divtab.c: Moved to...
* config/sh/divtab.cc: ...here.
* config/sh/sh-c.c: Moved to...
* config/sh/sh-c.cc: ...here.
* config/sh/sh.c: Moved to...
* config/sh/sh.cc: ...here.
* config/sol2-c.c: Moved to...
* config/sol2-c.cc: ...here.
* config/sol2-cxx.c: Moved to...
* config/sol2-cxx.cc: ...here.
* config/sol2-d.c: Moved to...
* config/sol2-d.cc: ...here.
* config/sol2-stubs.c: Moved to...
* config/sol2-stubs.cc: ...here.
* config/sol2.c: Moved to...
* config/sol2.cc: ...here.
* config/sparc/driver-sparc.c: Moved to...
* config/sparc/driver-sparc.cc: ...here.
* config/sparc/sparc-c.c: Moved to...
* config/sparc/sparc-c.cc: ...here.
* config/sparc/sparc-d.c: Moved to...
* config/sparc/sparc-d.cc: ...here.
* config/sparc/sparc.c: Moved to...
* config/sparc/sparc.cc: ...here.
* config/stormy16/stormy16.c: Moved to...
* config/stormy16/stormy16.cc: ...here.
* config/tilegx/mul-tables.c: Moved to...
* config/tilegx/mul-tables.cc: ...here.
* config/tilegx/tilegx-c.c: Moved to...
* config/tilegx/tilegx-c.cc: ...here.
* config/tilegx/tilegx.c: Moved to...
* config/tilegx/tilegx.cc: ...here.
* config/tilepro/mul-tables.c: Moved to...
* config/tilepro/mul-tables.cc: ...here.
* config/tilepro/tilepro-c.c: Moved to...
* config/tilepro/tilepro-c.cc: ...here.
* config/tilepro/tilepro.c: Moved to...
* config/tilepro/tilepro.cc: ...here.
* config/v850/v850-c.c: Moved to...
* config/v850/v850-c.cc: ...here.
* config/v850/v850.c: Moved to...
* config/v850/v850.cc: ...here.
* config/vax/vax.c: Moved to...
* config/vax/vax.cc: ...here.
* config/visium/visium.c: Moved to...
* config/visium/visium.cc: ...here.
* config/vms/vms-c.c: Moved to...
* config/vms/vms-c.cc: ...here.
* config/vms/vms-f.c: Moved to...
* config/vms/vms-f.cc: ...here.
* config/vms/vms.c: Moved to...
* config/vms/vms.cc: ...here.
* config/vxworks-c.c: Moved to...
* config/vxworks-c.cc: ...here.
* config/vxworks.c: Moved to...
* config/vxworks.cc: ...here.
* config/winnt-c.c: Moved to...
* config/winnt-c.cc: ...here.
* config/xtensa/xtensa.c: Moved to...
* config/xtensa/xtensa.cc: ...here.
* context.c: Moved to...
* context.cc: ...here.
* convert.c: Moved to...
* convert.cc: ...here.
* coverage.c: Moved to...
* coverage.cc: ...here.
* cppbuiltin.c: Moved to...
* cppbuiltin.cc: ...here.
* cppdefault.c: Moved to...
* cppdefault.cc: ...here.
* cprop.c: Moved to...
* cprop.cc: ...here.
* cse.c: Moved to...
* cse.cc: ...here.
* cselib.c: Moved to...
* cselib.cc: ...here.
* ctfc.c: Moved to...
* ctfc.cc: ...here.
* ctfout.c: Moved to...
* ctfout.cc: ...here.
* data-streamer-in.c: Moved to...
* data-streamer-in.cc: ...here.
* data-streamer-out.c: Moved to...
* data-streamer-out.cc: ...here.
* data-streamer.c: Moved to...
* data-streamer.cc: ...here.
* dbgcnt.c: Moved to...
* dbgcnt.cc: ...here.
* dbxout.c: Moved to...
* dbxout.cc: ...here.
* dce.c: Moved to...
* dce.cc: ...here.
* ddg.c: Moved to...
* ddg.cc: ...here.
* debug.c: Moved to...
* debug.cc: ...here.
* df-core.c: Moved to...
* df-core.cc: ...here.
* df-problems.c: Moved to...
* df-problems.cc: ...here.
* df-scan.c: Moved to...
* df-scan.cc: ...here.
* dfp.c: Moved to...
* dfp.cc: ...here.
* diagnostic-color.c: Moved to...
* diagnostic-color.cc: ...here.
* diagnostic-show-locus.c: Moved to...
* diagnostic-show-locus.cc: ...here.
* diagnostic-spec.c: Moved to...
* diagnostic-spec.cc: ...here.
* diagnostic.c: Moved to...
* diagnostic.cc: ...here.
* dojump.c: Moved to...
* dojump.cc: ...here.
* dominance.c: Moved to...
* dominance.cc: ...here.
* domwalk.c: Moved to...
* domwalk.cc: ...here.
* double-int.c: Moved to...
* double-int.cc: ...here.
* dse.c: Moved to...
* dse.cc: ...here.
* dumpfile.c: Moved to...
* dumpfile.cc: ...here.
* dwarf2asm.c: Moved to...
* dwarf2asm.cc: ...here.
* dwarf2cfi.c: Moved to...
* dwarf2cfi.cc: ...here.
* dwarf2ctf.c: Moved to...
* dwarf2ctf.cc: ...here.
* dwarf2out.c: Moved to...
* dwarf2out.cc: ...here.
* early-remat.c: Moved to...
* early-remat.cc: ...here.
* edit-context.c: Moved to...
* edit-context.cc: ...here.
* emit-rtl.c: Moved to...
* emit-rtl.cc: ...here.
* errors.c: Moved to...
* errors.cc: ...here.
* et-forest.c: Moved to...
* et-forest.cc: ...here.
* except.c: Moved to...
* except.cc: ...here.
* explow.c: Moved to...
* explow.cc: ...here.
* expmed.c: Moved to...
* expmed.cc: ...here.
* expr.c: Moved to...
* expr.cc: ...here.
* fibonacci_heap.c: Moved to...
* fibonacci_heap.cc: ...here.
* file-find.c: Moved to...
* file-find.cc: ...here.
* file-prefix-map.c: Moved to...
* file-prefix-map.cc: ...here.
* final.c: Moved to...
* final.cc: ...here.
* fixed-value.c: Moved to...
* fixed-value.cc: ...here.
* fold-const-call.c: Moved to...
* fold-const-call.cc: ...here.
* fold-const.c: Moved to...
* fold-const.cc: ...here.
* fp-test.c: Moved to...
* fp-test.cc: ...here.
* function-tests.c: Moved to...
* function-tests.cc: ...here.
* function.c: Moved to...
* function.cc: ...here.
* fwprop.c: Moved to...
* fwprop.cc: ...here.
* gcc-ar.c: Moved to...
* gcc-ar.cc: ...here.
* gcc-main.c: Moved to...
* gcc-main.cc: ...here.
* gcc-rich-location.c: Moved to...
* gcc-rich-location.cc: ...here.
* gcc.c: Moved to...
* gcc.cc: ...here.
* gcov-dump.c: Moved to...
* gcov-dump.cc: ...here.
* gcov-io.c: Moved to...
* gcov-io.cc: ...here.
* gcov-tool.c: Moved to...
* gcov-tool.cc: ...here.
* gcov.c: Moved to...
* gcov.cc: ...here.
* gcse-common.c: Moved to...
* gcse-common.cc: ...here.
* gcse.c: Moved to...
* gcse.cc: ...here.
* genattr-common.c: Moved to...
* genattr-common.cc: ...here.
* genattr.c: Moved to...
* genattr.cc: ...here.
* genattrtab.c: Moved to...
* genattrtab.cc: ...here.
* genautomata.c: Moved to...
* genautomata.cc: ...here.
* gencfn-macros.c: Moved to...
* gencfn-macros.cc: ...here.
* gencheck.c: Moved to...
* gencheck.cc: ...here.
* genchecksum.c: Moved to...
* genchecksum.cc: ...here.
* gencodes.c: Moved to...
* gencodes.cc: ...here.
* genconditions.c: Moved to...
* genconditions.cc: ...here.
* genconfig.c: Moved to...
* genconfig.cc: ...here.
* genconstants.c: Moved to...
* genconstants.cc: ...here.
* genemit.c: Moved to...
* genemit.cc: ...here.
* genenums.c: Moved to...
* genenums.cc: ...here.
* generic-match-head.c: Moved to...
* generic-match-head.cc: ...here.
* genextract.c: Moved to...
* genextract.cc: ...here.
* genflags.c: Moved to...
* genflags.cc: ...here.
* gengenrtl.c: Moved to...
* gengenrtl.cc: ...here.
* gengtype-parse.c: Moved to...
* gengtype-parse.cc: ...here.
* gengtype-state.c: Moved to...
* gengtype-state.cc: ...here.
* gengtype.c: Moved to...
* gengtype.cc: ...here.
* genhooks.c: Moved to...
* genhooks.cc: ...here.
* genmatch.c: Moved to...
* genmatch.cc: ...here.
* genmddeps.c: Moved to...
* genmddeps.cc: ...here.
* genmddump.c: Moved to...
* genmddump.cc: ...here.
* genmodes.c: Moved to...
* genmodes.cc: ...here.
* genopinit.c: Moved to...
* genopinit.cc: ...here.
* genoutput.c: Moved to...
* genoutput.cc: ...here.
* genpeep.c: Moved to...
* genpeep.cc: ...here.
* genpreds.c: Moved to...
* genpreds.cc: ...here.
* genrecog.c: Moved to...
* genrecog.cc: ...here.
* gensupport.c: Moved to...
* gensupport.cc: ...here.
* gentarget-def.c: Moved to...
* gentarget-def.cc: ...here.
* genversion.c: Moved to...
* genversion.cc: ...here.
* ggc-common.c: Moved to...
* ggc-common.cc: ...here.
* ggc-none.c: Moved to...
* ggc-none.cc: ...here.
* ggc-page.c: Moved to...
* ggc-page.cc: ...here.
* ggc-tests.c: Moved to...
* ggc-tests.cc: ...here.
* gimple-builder.c: Moved to...
* gimple-builder.cc: ...here.
* gimple-expr.c: Moved to...
* gimple-expr.cc: ...here.
* gimple-fold.c: Moved to...
* gimple-fold.cc: ...here.
* gimple-iterator.c: Moved to...
* gimple-iterator.cc: ...here.
* gimple-laddress.c: Moved to...
* gimple-laddress.cc: ...here.
* gimple-loop-jam.c: Moved to...
* gimple-loop-jam.cc: ...here.
* gimple-low.c: Moved to...
* gimple-low.cc: ...here.
* gimple-match-head.c: Moved to...
* gimple-match-head.cc: ...here.
* gimple-pretty-print.c: Moved to...
* gimple-pretty-print.cc: ...here.
* gimple-ssa-backprop.c: Moved to...
* gimple-ssa-backprop.cc: ...here.
* gimple-ssa-evrp-analyze.c: Moved to...
* gimple-ssa-evrp-analyze.cc: ...here.
* gimple-ssa-evrp.c: Moved to...
* gimple-ssa-evrp.cc: ...here.
* gimple-ssa-isolate-paths.c: Moved to...
* gimple-ssa-isolate-paths.cc: ...here.
* gimple-ssa-nonnull-compare.c: Moved to...
* gimple-ssa-nonnull-compare.cc: ...here.
* gimple-ssa-split-paths.c: Moved to...
* gimple-ssa-split-paths.cc: ...here.
* gimple-ssa-sprintf.c: Moved to...
* gimple-ssa-sprintf.cc: ...here.
* gimple-ssa-store-merging.c: Moved to...
* gimple-ssa-store-merging.cc: ...here.
* gimple-ssa-strength-reduction.c: Moved to...
* gimple-ssa-strength-reduction.cc: ...here.
* gimple-ssa-warn-alloca.c: Moved to...
* gimple-ssa-warn-alloca.cc: ...here.
* gimple-ssa-warn-restrict.c: Moved to...
* gimple-ssa-warn-restrict.cc: ...here.
* gimple-streamer-in.c: Moved to...
* gimple-streamer-in.cc: ...here.
* gimple-streamer-out.c: Moved to...
* gimple-streamer-out.cc: ...here.
* gimple-walk.c: Moved to...
* gimple-walk.cc: ...here.
* gimple-warn-recursion.c: Moved to...
* gimple-warn-recursion.cc: ...here.
* gimple.c: Moved to...
* gimple.cc: ...here.
* gimplify-me.c: Moved to...
* gimplify-me.cc: ...here.
* gimplify.c: Moved to...
* gimplify.cc: ...here.
* godump.c: Moved to...
* godump.cc: ...here.
* graph.c: Moved to...
* graph.cc: ...here.
* graphds.c: Moved to...
* graphds.cc: ...here.
* graphite-dependences.c: Moved to...
* graphite-dependences.cc: ...here.
* graphite-isl-ast-to-gimple.c: Moved to...
* graphite-isl-ast-to-gimple.cc: ...here.
* graphite-optimize-isl.c: Moved to...
* graphite-optimize-isl.cc: ...here.
* graphite-poly.c: Moved to...
* graphite-poly.cc: ...here.
* graphite-scop-detection.c: Moved to...
* graphite-scop-detection.cc: ...here.
* graphite-sese-to-poly.c: Moved to...
* graphite-sese-to-poly.cc: ...here.
* graphite.c: Moved to...
* graphite.cc: ...here.
* haifa-sched.c: Moved to...
* haifa-sched.cc: ...here.
* hash-map-tests.c: Moved to...
* hash-map-tests.cc: ...here.
* hash-set-tests.c: Moved to...
* hash-set-tests.cc: ...here.
* hash-table.c: Moved to...
* hash-table.cc: ...here.
* hooks.c: Moved to...
* hooks.cc: ...here.
* host-default.c: Moved to...
* host-default.cc: ...here.
* hw-doloop.c: Moved to...
* hw-doloop.cc: ...here.
* hwint.c: Moved to...
* hwint.cc: ...here.
* ifcvt.c: Moved to...
* ifcvt.cc: ...here.
* inchash.c: Moved to...
* inchash.cc: ...here.
* incpath.c: Moved to...
* incpath.cc: ...here.
* init-regs.c: Moved to...
* init-regs.cc: ...here.
* input.c: Moved to...
* input.cc: ...here.
* internal-fn.c: Moved to...
* internal-fn.cc: ...here.
* intl.c: Moved to...
* intl.cc: ...here.
* ipa-comdats.c: Moved to...
* ipa-comdats.cc: ...here.
* ipa-cp.c: Moved to...
* ipa-cp.cc: ...here.
* ipa-devirt.c: Moved to...
* ipa-devirt.cc: ...here.
* ipa-fnsummary.c: Moved to...
* ipa-fnsummary.cc: ...here.
* ipa-icf-gimple.c: Moved to...
* ipa-icf-gimple.cc: ...here.
* ipa-icf.c: Moved to...
* ipa-icf.cc: ...here.
* ipa-inline-analysis.c: Moved to...
* ipa-inline-analysis.cc: ...here.
* ipa-inline-transform.c: Moved to...
* ipa-inline-transform.cc: ...here.
* ipa-inline.c: Moved to...
* ipa-inline.cc: ...here.
* ipa-modref-tree.c: Moved to...
* ipa-modref-tree.cc: ...here.
* ipa-modref.c: Moved to...
* ipa-modref.cc: ...here.
* ipa-param-manipulation.c: Moved to...
* ipa-param-manipulation.cc: ...here.
* ipa-polymorphic-call.c: Moved to...
* ipa-polymorphic-call.cc: ...here.
* ipa-predicate.c: Moved to...
* ipa-predicate.cc: ...here.
* ipa-profile.c: Moved to...
* ipa-profile.cc: ...here.
* ipa-prop.c: Moved to...
* ipa-prop.cc: ...here.
* ipa-pure-const.c: Moved to...
* ipa-pure-const.cc: ...here.
* ipa-ref.c: Moved to...
* ipa-ref.cc: ...here.
* ipa-reference.c: Moved to...
* ipa-reference.cc: ...here.
* ipa-split.c: Moved to...
* ipa-split.cc: ...here.
* ipa-sra.c: Moved to...
* ipa-sra.cc: ...here.
* ipa-utils.c: Moved to...
* ipa-utils.cc: ...here.
* ipa-visibility.c: Moved to...
* ipa-visibility.cc: ...here.
* ipa.c: Moved to...
* ipa.cc: ...here.
* ira-build.c: Moved to...
* ira-build.cc: ...here.
* ira-color.c: Moved to...
* ira-color.cc: ...here.
* ira-conflicts.c: Moved to...
* ira-conflicts.cc: ...here.
* ira-costs.c: Moved to...
* ira-costs.cc: ...here.
* ira-emit.c: Moved to...
* ira-emit.cc: ...here.
* ira-lives.c: Moved to...
* ira-lives.cc: ...here.
* ira.c: Moved to...
* ira.cc: ...here.
* jump.c: Moved to...
* jump.cc: ...here.
* langhooks.c: Moved to...
* langhooks.cc: ...here.
* lcm.c: Moved to...
* lcm.cc: ...here.
* lists.c: Moved to...
* lists.cc: ...here.
* loop-doloop.c: Moved to...
* loop-doloop.cc: ...here.
* loop-init.c: Moved to...
* loop-init.cc: ...here.
* loop-invariant.c: Moved to...
* loop-invariant.cc: ...here.
* loop-iv.c: Moved to...
* loop-iv.cc: ...here.
* loop-unroll.c: Moved to...
* loop-unroll.cc: ...here.
* lower-subreg.c: Moved to...
* lower-subreg.cc: ...here.
* lra-assigns.c: Moved to...
* lra-assigns.cc: ...here.
* lra-coalesce.c: Moved to...
* lra-coalesce.cc: ...here.
* lra-constraints.c: Moved to...
* lra-constraints.cc: ...here.
* lra-eliminations.c: Moved to...
* lra-eliminations.cc: ...here.
* lra-lives.c: Moved to...
* lra-lives.cc: ...here.
* lra-remat.c: Moved to...
* lra-remat.cc: ...here.
* lra-spills.c: Moved to...
* lra-spills.cc: ...here.
* lra.c: Moved to...
* lra.cc: ...here.
* lto-cgraph.c: Moved to...
* lto-cgraph.cc: ...here.
* lto-compress.c: Moved to...
* lto-compress.cc: ...here.
* lto-opts.c: Moved to...
* lto-opts.cc: ...here.
* lto-section-in.c: Moved to...
* lto-section-in.cc: ...here.
* lto-section-out.c: Moved to...
* lto-section-out.cc: ...here.
* lto-streamer-in.c: Moved to...
* lto-streamer-in.cc: ...here.
* lto-streamer-out.c: Moved to...
* lto-streamer-out.cc: ...here.
* lto-streamer.c: Moved to...
* lto-streamer.cc: ...here.
* lto-wrapper.c: Moved to...
* lto-wrapper.cc: ...here.
* main.c: Moved to...
* main.cc: ...here.
* mcf.c: Moved to...
* mcf.cc: ...here.
* mode-switching.c: Moved to...
* mode-switching.cc: ...here.
* modulo-sched.c: Moved to...
* modulo-sched.cc: ...here.
* multiple_target.c: Moved to...
* multiple_target.cc: ...here.
* omp-expand.c: Moved to...
* omp-expand.cc: ...here.
* omp-general.c: Moved to...
* omp-general.cc: ...here.
* omp-low.c: Moved to...
* omp-low.cc: ...here.
* omp-offload.c: Moved to...
* omp-offload.cc: ...here.
* omp-simd-clone.c: Moved to...
* omp-simd-clone.cc: ...here.
* opt-suggestions.c: Moved to...
* opt-suggestions.cc: ...here.
* optabs-libfuncs.c: Moved to...
* optabs-libfuncs.cc: ...here.
* optabs-query.c: Moved to...
* optabs-query.cc: ...here.
* optabs-tree.c: Moved to...
* optabs-tree.cc: ...here.
* optabs.c: Moved to...
* optabs.cc: ...here.
* opts-common.c: Moved to...
* opts-common.cc: ...here.
* opts-global.c: Moved to...
* opts-global.cc: ...here.
* opts.c: Moved to...
* opts.cc: ...here.
* passes.c: Moved to...
* passes.cc: ...here.
* plugin.c: Moved to...
* plugin.cc: ...here.
* postreload-gcse.c: Moved to...
* postreload-gcse.cc: ...here.
* postreload.c: Moved to...
* postreload.cc: ...here.
* predict.c: Moved to...
* predict.cc: ...here.
* prefix.c: Moved to...
* prefix.cc: ...here.
* pretty-print.c: Moved to...
* pretty-print.cc: ...here.
* print-rtl-function.c: Moved to...
* print-rtl-function.cc: ...here.
* print-rtl.c: Moved to...
* print-rtl.cc: ...here.
* print-tree.c: Moved to...
* print-tree.cc: ...here.
* profile-count.c: Moved to...
* profile-count.cc: ...here.
* profile.c: Moved to...
* profile.cc: ...here.
* read-md.c: Moved to...
* read-md.cc: ...here.
* read-rtl-function.c: Moved to...
* read-rtl-function.cc: ...here.
* read-rtl.c: Moved to...
* read-rtl.cc: ...here.
* real.c: Moved to...
* real.cc: ...here.
* realmpfr.c: Moved to...
* realmpfr.cc: ...here.
* recog.c: Moved to...
* recog.cc: ...here.
* ree.c: Moved to...
* ree.cc: ...here.
* reg-stack.c: Moved to...
* reg-stack.cc: ...here.
* regcprop.c: Moved to...
* regcprop.cc: ...here.
* reginfo.c: Moved to...
* reginfo.cc: ...here.
* regrename.c: Moved to...
* regrename.cc: ...here.
* regstat.c: Moved to...
* regstat.cc: ...here.
* reload.c: Moved to...
* reload.cc: ...here.
* reload1.c: Moved to...
* reload1.cc: ...here.
* reorg.c: Moved to...
* reorg.cc: ...here.
* resource.c: Moved to...
* resource.cc: ...here.
* rtl-error.c: Moved to...
* rtl-error.cc: ...here.
* rtl-tests.c: Moved to...
* rtl-tests.cc: ...here.
* rtl.c: Moved to...
* rtl.cc: ...here.
* rtlanal.c: Moved to...
* rtlanal.cc: ...here.
* rtlhash.c: Moved to...
* rtlhash.cc: ...here.
* rtlhooks.c: Moved to...
* rtlhooks.cc: ...here.
* rtx-vector-builder.c: Moved to...
* rtx-vector-builder.cc: ...here.
* run-rtl-passes.c: Moved to...
* run-rtl-passes.cc: ...here.
* sancov.c: Moved to...
* sancov.cc: ...here.
* sanopt.c: Moved to...
* sanopt.cc: ...here.
* sbitmap.c: Moved to...
* sbitmap.cc: ...here.
* sched-deps.c: Moved to...
* sched-deps.cc: ...here.
* sched-ebb.c: Moved to...
* sched-ebb.cc: ...here.
* sched-rgn.c: Moved to...
* sched-rgn.cc: ...here.
* sel-sched-dump.c: Moved to...
* sel-sched-dump.cc: ...here.
* sel-sched-ir.c: Moved to...
* sel-sched-ir.cc: ...here.
* sel-sched.c: Moved to...
* sel-sched.cc: ...here.
* selftest-diagnostic.c: Moved to...
* selftest-diagnostic.cc: ...here.
* selftest-rtl.c: Moved to...
* selftest-rtl.cc: ...here.
* selftest-run-tests.c: Moved to...
* selftest-run-tests.cc: ...here.
* selftest.c: Moved to...
* selftest.cc: ...here.
* sese.c: Moved to...
* sese.cc: ...here.
* shrink-wrap.c: Moved to...
* shrink-wrap.cc: ...here.
* simplify-rtx.c: Moved to...
* simplify-rtx.cc: ...here.
* sparseset.c: Moved to...
* sparseset.cc: ...here.
* spellcheck-tree.c: Moved to...
* spellcheck-tree.cc: ...here.
* spellcheck.c: Moved to...
* spellcheck.cc: ...here.
* sreal.c: Moved to...
* sreal.cc: ...here.
* stack-ptr-mod.c: Moved to...
* stack-ptr-mod.cc: ...here.
* statistics.c: Moved to...
* statistics.cc: ...here.
* stmt.c: Moved to...
* stmt.cc: ...here.
* stor-layout.c: Moved to...
* stor-layout.cc: ...here.
* store-motion.c: Moved to...
* store-motion.cc: ...here.
* streamer-hooks.c: Moved to...
* streamer-hooks.cc: ...here.
* stringpool.c: Moved to...
* stringpool.cc: ...here.
* substring-locations.c: Moved to...
* substring-locations.cc: ...here.
* symtab.c: Moved to...
* symtab.cc: ...here.
* target-globals.c: Moved to...
* target-globals.cc: ...here.
* targhooks.c: Moved to...
* targhooks.cc: ...here.
* timevar.c: Moved to...
* timevar.cc: ...here.
* toplev.c: Moved to...
* toplev.cc: ...here.
* tracer.c: Moved to...
* tracer.cc: ...here.
* trans-mem.c: Moved to...
* trans-mem.cc: ...here.
* tree-affine.c: Moved to...
* tree-affine.cc: ...here.
* tree-call-cdce.c: Moved to...
* tree-call-cdce.cc: ...here.
* tree-cfg.c: Moved to...
* tree-cfg.cc: ...here.
* tree-cfgcleanup.c: Moved to...
* tree-cfgcleanup.cc: ...here.
* tree-chrec.c: Moved to...
* tree-chrec.cc: ...here.
* tree-complex.c: Moved to...
* tree-complex.cc: ...here.
* tree-data-ref.c: Moved to...
* tree-data-ref.cc: ...here.
* tree-dfa.c: Moved to...
* tree-dfa.cc: ...here.
* tree-diagnostic.c: Moved to...
* tree-diagnostic.cc: ...here.
* tree-dump.c: Moved to...
* tree-dump.cc: ...here.
* tree-eh.c: Moved to...
* tree-eh.cc: ...here.
* tree-emutls.c: Moved to...
* tree-emutls.cc: ...here.
* tree-if-conv.c: Moved to...
* tree-if-conv.cc: ...here.
* tree-inline.c: Moved to...
* tree-inline.cc: ...here.
* tree-into-ssa.c: Moved to...
* tree-into-ssa.cc: ...here.
* tree-iterator.c: Moved to...
* tree-iterator.cc: ...here.
* tree-loop-distribution.c: Moved to...
* tree-loop-distribution.cc: ...here.
* tree-nested.c: Moved to...
* tree-nested.cc: ...here.
* tree-nrv.c: Moved to...
* tree-nrv.cc: ...here.
* tree-object-size.c: Moved to...
* tree-object-size.cc: ...here.
* tree-outof-ssa.c: Moved to...
* tree-outof-ssa.cc: ...here.
* tree-parloops.c: Moved to...
* tree-parloops.cc: ...here.
* tree-phinodes.c: Moved to...
* tree-phinodes.cc: ...here.
* tree-predcom.c: Moved to...
* tree-predcom.cc: ...here.
* tree-pretty-print.c: Moved to...
* tree-pretty-print.cc: ...here.
* tree-profile.c: Moved to...
* tree-profile.cc: ...here.
* tree-scalar-evolution.c: Moved to...
* tree-scalar-evolution.cc: ...here.
* tree-sra.c: Moved to...
* tree-sra.cc: ...here.
* tree-ssa-address.c: Moved to...
* tree-ssa-address.cc: ...here.
* tree-ssa-alias.c: Moved to...
* tree-ssa-alias.cc: ...here.
* tree-ssa-ccp.c: Moved to...
* tree-ssa-ccp.cc: ...here.
* tree-ssa-coalesce.c: Moved to...
* tree-ssa-coalesce.cc: ...here.
* tree-ssa-copy.c: Moved to...
* tree-ssa-copy.cc: ...here.
* tree-ssa-dce.c: Moved to...
* tree-ssa-dce.cc: ...here.
* tree-ssa-dom.c: Moved to...
* tree-ssa-dom.cc: ...here.
* tree-ssa-dse.c: Moved to...
* tree-ssa-dse.cc: ...here.
* tree-ssa-forwprop.c: Moved to...
* tree-ssa-forwprop.cc: ...here.
* tree-ssa-ifcombine.c: Moved to...
* tree-ssa-ifcombine.cc: ...here.
* tree-ssa-live.c: Moved to...
* tree-ssa-live.cc: ...here.
* tree-ssa-loop-ch.c: Moved to...
* tree-ssa-loop-ch.cc: ...here.
* tree-ssa-loop-im.c: Moved to...
* tree-ssa-loop-im.cc: ...here.
* tree-ssa-loop-ivcanon.c: Moved to...
* tree-ssa-loop-ivcanon.cc: ...here.
* tree-ssa-loop-ivopts.c: Moved to...
* tree-ssa-loop-ivopts.cc: ...here.
* tree-ssa-loop-manip.c: Moved to...
* tree-ssa-loop-manip.cc: ...here.
* tree-ssa-loop-niter.c: Moved to...
* tree-ssa-loop-niter.cc: ...here.
* tree-ssa-loop-prefetch.c: Moved to...
* tree-ssa-loop-prefetch.cc: ...here.
* tree-ssa-loop-split.c: Moved to...
* tree-ssa-loop-split.cc: ...here.
* tree-ssa-loop-unswitch.c: Moved to...
* tree-ssa-loop-unswitch.cc: ...here.
* tree-ssa-loop.c: Moved to...
* tree-ssa-loop.cc: ...here.
* tree-ssa-math-opts.c: Moved to...
* tree-ssa-math-opts.cc: ...here.
* tree-ssa-operands.c: Moved to...
* tree-ssa-operands.cc: ...here.
* tree-ssa-phiopt.c: Moved to...
* tree-ssa-phiopt.cc: ...here.
* tree-ssa-phiprop.c: Moved to...
* tree-ssa-phiprop.cc: ...here.
* tree-ssa-pre.c: Moved to...
* tree-ssa-pre.cc: ...here.
* tree-ssa-propagate.c: Moved to...
* tree-ssa-propagate.cc: ...here.
* tree-ssa-reassoc.c: Moved to...
* tree-ssa-reassoc.cc: ...here.
* tree-ssa-sccvn.c: Moved to...
* tree-ssa-sccvn.cc: ...here.
* tree-ssa-scopedtables.c: Moved to...
* tree-ssa-scopedtables.cc: ...here.
* tree-ssa-sink.c: Moved to...
* tree-ssa-sink.cc: ...here.
* tree-ssa-strlen.c: Moved to...
* tree-ssa-strlen.cc: ...here.
* tree-ssa-structalias.c: Moved to...
* tree-ssa-structalias.cc: ...here.
* tree-ssa-tail-merge.c: Moved to...
* tree-ssa-tail-merge.cc: ...here.
* tree-ssa-ter.c: Moved to...
* tree-ssa-ter.cc: ...here.
* tree-ssa-threadbackward.c: Moved to...
* tree-ssa-threadbackward.cc: ...here.
* tree-ssa-threadedge.c: Moved to...
* tree-ssa-threadedge.cc: ...here.
* tree-ssa-threadupdate.c: Moved to...
* tree-ssa-threadupdate.cc: ...here.
* tree-ssa-uncprop.c: Moved to...
* tree-ssa-uncprop.cc: ...here.
* tree-ssa-uninit.c: Moved to...
* tree-ssa-uninit.cc: ...here.
* tree-ssa.c: Moved to...
* tree-ssa.cc: ...here.
* tree-ssanames.c: Moved to...
* tree-ssanames.cc: ...here.
* tree-stdarg.c: Moved to...
* tree-stdarg.cc: ...here.
* tree-streamer-in.c: Moved to...
* tree-streamer-in.cc: ...here.
* tree-streamer-out.c: Moved to...
* tree-streamer-out.cc: ...here.
* tree-streamer.c: Moved to...
* tree-streamer.cc: ...here.
* tree-switch-conversion.c: Moved to...
* tree-switch-conversion.cc: ...here.
* tree-tailcall.c: Moved to...
* tree-tailcall.cc: ...here.
* tree-vect-data-refs.c: Moved to...
* tree-vect-data-refs.cc: ...here.
* tree-vect-generic.c: Moved to...
* tree-vect-generic.cc: ...here.
* tree-vect-loop-manip.c: Moved to...
* tree-vect-loop-manip.cc: ...here.
* tree-vect-loop.c: Moved to...
* tree-vect-loop.cc: ...here.
* tree-vect-patterns.c: Moved to...
* tree-vect-patterns.cc: ...here.
* tree-vect-slp-patterns.c: Moved to...
* tree-vect-slp-patterns.cc: ...here.
* tree-vect-slp.c: Moved to...
* tree-vect-slp.cc: ...here.
* tree-vect-stmts.c: Moved to...
* tree-vect-stmts.cc: ...here.
* tree-vector-builder.c: Moved to...
* tree-vector-builder.cc: ...here.
* tree-vectorizer.c: Moved to...
* tree-vectorizer.cc: ...here.
* tree-vrp.c: Moved to...
* tree-vrp.cc: ...here.
* tree.c: Moved to...
* tree.cc: ...here.
* tsan.c: Moved to...
* tsan.cc: ...here.
* typed-splay-tree.c: Moved to...
* typed-splay-tree.cc: ...here.
* ubsan.c: Moved to...
* ubsan.cc: ...here.
* valtrack.c: Moved to...
* valtrack.cc: ...here.
* value-prof.c: Moved to...
* value-prof.cc: ...here.
* var-tracking.c: Moved to...
* var-tracking.cc: ...here.
* varasm.c: Moved to...
* varasm.cc: ...here.
* varpool.c: Moved to...
* varpool.cc: ...here.
* vec-perm-indices.c: Moved to...
* vec-perm-indices.cc: ...here.
* vec.c: Moved to...
* vec.cc: ...here.
* vmsdbgout.c: Moved to...
* vmsdbgout.cc: ...here.
* vr-values.c: Moved to...
* vr-values.cc: ...here.
* vtable-verify.c: Moved to...
* vtable-verify.cc: ...here.
* web.c: Moved to...
* web.cc: ...here.
* xcoffout.c: Moved to...
* xcoffout.cc: ...here.
gcc/c-family/ChangeLog:
* c-ada-spec.c: Moved to...
* c-ada-spec.cc: ...here.
* c-attribs.c: Moved to...
* c-attribs.cc: ...here.
* c-common.c: Moved to...
* c-common.cc: ...here.
* c-cppbuiltin.c: Moved to...
* c-cppbuiltin.cc: ...here.
* c-dump.c: Moved to...
* c-dump.cc: ...here.
* c-format.c: Moved to...
* c-format.cc: ...here.
* c-gimplify.c: Moved to...
* c-gimplify.cc: ...here.
* c-indentation.c: Moved to...
* c-indentation.cc: ...here.
* c-lex.c: Moved to...
* c-lex.cc: ...here.
* c-omp.c: Moved to...
* c-omp.cc: ...here.
* c-opts.c: Moved to...
* c-opts.cc: ...here.
* c-pch.c: Moved to...
* c-pch.cc: ...here.
* c-ppoutput.c: Moved to...
* c-ppoutput.cc: ...here.
* c-pragma.c: Moved to...
* c-pragma.cc: ...here.
* c-pretty-print.c: Moved to...
* c-pretty-print.cc: ...here.
* c-semantics.c: Moved to...
* c-semantics.cc: ...here.
* c-ubsan.c: Moved to...
* c-ubsan.cc: ...here.
* c-warn.c: Moved to...
* c-warn.cc: ...here.
* cppspec.c: Moved to...
* cppspec.cc: ...here.
* stub-objc.c: Moved to...
* stub-objc.cc: ...here.
gcc/c/ChangeLog:
* c-aux-info.c: Moved to...
* c-aux-info.cc: ...here.
* c-convert.c: Moved to...
* c-convert.cc: ...here.
* c-decl.c: Moved to...
* c-decl.cc: ...here.
* c-errors.c: Moved to...
* c-errors.cc: ...here.
* c-fold.c: Moved to...
* c-fold.cc: ...here.
* c-lang.c: Moved to...
* c-lang.cc: ...here.
* c-objc-common.c: Moved to...
* c-objc-common.cc: ...here.
* c-parser.c: Moved to...
* c-parser.cc: ...here.
* c-typeck.c: Moved to...
* c-typeck.cc: ...here.
* gccspec.c: Moved to...
* gccspec.cc: ...here.
* gimple-parser.c: Moved to...
* gimple-parser.cc: ...here.
gcc/cp/ChangeLog:
* call.c: Moved to...
* call.cc: ...here.
* class.c: Moved to...
* class.cc: ...here.
* constexpr.c: Moved to...
* constexpr.cc: ...here.
* cp-gimplify.c: Moved to...
* cp-gimplify.cc: ...here.
* cp-lang.c: Moved to...
* cp-lang.cc: ...here.
* cp-objcp-common.c: Moved to...
* cp-objcp-common.cc: ...here.
* cp-ubsan.c: Moved to...
* cp-ubsan.cc: ...here.
* cvt.c: Moved to...
* cvt.cc: ...here.
* cxx-pretty-print.c: Moved to...
* cxx-pretty-print.cc: ...here.
* decl.c: Moved to...
* decl.cc: ...here.
* decl2.c: Moved to...
* decl2.cc: ...here.
* dump.c: Moved to...
* dump.cc: ...here.
* error.c: Moved to...
* error.cc: ...here.
* except.c: Moved to...
* except.cc: ...here.
* expr.c: Moved to...
* expr.cc: ...here.
* friend.c: Moved to...
* friend.cc: ...here.
* g++spec.c: Moved to...
* g++spec.cc: ...here.
* init.c: Moved to...
* init.cc: ...here.
* lambda.c: Moved to...
* lambda.cc: ...here.
* lex.c: Moved to...
* lex.cc: ...here.
* mangle.c: Moved to...
* mangle.cc: ...here.
* method.c: Moved to...
* method.cc: ...here.
* name-lookup.c: Moved to...
* name-lookup.cc: ...here.
* optimize.c: Moved to...
* optimize.cc: ...here.
* parser.c: Moved to...
* parser.cc: ...here.
* pt.c: Moved to...
* pt.cc: ...here.
* ptree.c: Moved to...
* ptree.cc: ...here.
* rtti.c: Moved to...
* rtti.cc: ...here.
* search.c: Moved to...
* search.cc: ...here.
* semantics.c: Moved to...
* semantics.cc: ...here.
* tree.c: Moved to...
* tree.cc: ...here.
* typeck.c: Moved to...
* typeck.cc: ...here.
* typeck2.c: Moved to...
* typeck2.cc: ...here.
* vtable-class-hierarchy.c: Moved to...
* vtable-class-hierarchy.cc: ...here.
gcc/fortran/ChangeLog:
* arith.c: Moved to...
* arith.cc: ...here.
* array.c: Moved to...
* array.cc: ...here.
* bbt.c: Moved to...
* bbt.cc: ...here.
* check.c: Moved to...
* check.cc: ...here.
* class.c: Moved to...
* class.cc: ...here.
* constructor.c: Moved to...
* constructor.cc: ...here.
* convert.c: Moved to...
* convert.cc: ...here.
* cpp.c: Moved to...
* cpp.cc: ...here.
* data.c: Moved to...
* data.cc: ...here.
* decl.c: Moved to...
* decl.cc: ...here.
* dependency.c: Moved to...
* dependency.cc: ...here.
* dump-parse-tree.c: Moved to...
* dump-parse-tree.cc: ...here.
* error.c: Moved to...
* error.cc: ...here.
* expr.c: Moved to...
* expr.cc: ...here.
* f95-lang.c: Moved to...
* f95-lang.cc: ...here.
* frontend-passes.c: Moved to...
* frontend-passes.cc: ...here.
* gfortranspec.c: Moved to...
* gfortranspec.cc: ...here.
* interface.c: Moved to...
* interface.cc: ...here.
* intrinsic.c: Moved to...
* intrinsic.cc: ...here.
* io.c: Moved to...
* io.cc: ...here.
* iresolve.c: Moved to...
* iresolve.cc: ...here.
* match.c: Moved to...
* match.cc: ...here.
* matchexp.c: Moved to...
* matchexp.cc: ...here.
* misc.c: Moved to...
* misc.cc: ...here.
* module.c: Moved to...
* module.cc: ...here.
* openmp.c: Moved to...
* openmp.cc: ...here.
* options.c: Moved to...
* options.cc: ...here.
* parse.c: Moved to...
* parse.cc: ...here.
* primary.c: Moved to...
* primary.cc: ...here.
* resolve.c: Moved to...
* resolve.cc: ...here.
* scanner.c: Moved to...
* scanner.cc: ...here.
* simplify.c: Moved to...
* simplify.cc: ...here.
* st.c: Moved to...
* st.cc: ...here.
* symbol.c: Moved to...
* symbol.cc: ...here.
* target-memory.c: Moved to...
* target-memory.cc: ...here.
* trans-array.c: Moved to...
* trans-array.cc: ...here.
* trans-common.c: Moved to...
* trans-common.cc: ...here.
* trans-const.c: Moved to...
* trans-const.cc: ...here.
* trans-decl.c: Moved to...
* trans-decl.cc: ...here.
* trans-expr.c: Moved to...
* trans-expr.cc: ...here.
* trans-intrinsic.c: Moved to...
* trans-intrinsic.cc: ...here.
* trans-io.c: Moved to...
* trans-io.cc: ...here.
* trans-openmp.c: Moved to...
* trans-openmp.cc: ...here.
* trans-stmt.c: Moved to...
* trans-stmt.cc: ...here.
* trans-types.c: Moved to...
* trans-types.cc: ...here.
* trans.c: Moved to...
* trans.cc: ...here.
gcc/go/ChangeLog:
* go-backend.c: Moved to...
* go-backend.cc: ...here.
* go-lang.c: Moved to...
* go-lang.cc: ...here.
* gospec.c: Moved to...
* gospec.cc: ...here.
gcc/jit/ChangeLog:
* dummy-frontend.c: Moved to...
* dummy-frontend.cc: ...here.
* jit-builtins.c: Moved to...
* jit-builtins.cc: ...here.
* jit-logging.c: Moved to...
* jit-logging.cc: ...here.
* jit-playback.c: Moved to...
* jit-playback.cc: ...here.
* jit-recording.c: Moved to...
* jit-recording.cc: ...here.
* jit-result.c: Moved to...
* jit-result.cc: ...here.
* jit-spec.c: Moved to...
* jit-spec.cc: ...here.
* jit-tempdir.c: Moved to...
* jit-tempdir.cc: ...here.
* jit-w32.c: Moved to...
* jit-w32.cc: ...here.
* libgccjit.c: Moved to...
* libgccjit.cc: ...here.
gcc/lto/ChangeLog:
* common.c: Moved to...
* common.cc: ...here.
* lto-common.c: Moved to...
* lto-common.cc: ...here.
* lto-dump.c: Moved to...
* lto-dump.cc: ...here.
* lto-lang.c: Moved to...
* lto-lang.cc: ...here.
* lto-object.c: Moved to...
* lto-object.cc: ...here.
* lto-partition.c: Moved to...
* lto-partition.cc: ...here.
* lto-symtab.c: Moved to...
* lto-symtab.cc: ...here.
* lto.c: Moved to...
* lto.cc: ...here.
gcc/objc/ChangeLog:
* objc-act.c: Moved to...
* objc-act.cc: ...here.
* objc-encoding.c: Moved to...
* objc-encoding.cc: ...here.
* objc-gnu-runtime-abi-01.c: Moved to...
* objc-gnu-runtime-abi-01.cc: ...here.
* objc-lang.c: Moved to...
* objc-lang.cc: ...here.
* objc-map.c: Moved to...
* objc-map.cc: ...here.
* objc-next-runtime-abi-01.c: Moved to...
* objc-next-runtime-abi-01.cc: ...here.
* objc-next-runtime-abi-02.c: Moved to...
* objc-next-runtime-abi-02.cc: ...here.
* objc-runtime-shared-support.c: Moved to...
* objc-runtime-shared-support.cc: ...here.
gcc/objcp/ChangeLog:
* objcp-decl.c: Moved to...
* objcp-decl.cc: ...here.
* objcp-lang.c: Moved to...
* objcp-lang.cc: ...here.
libcpp/ChangeLog:
* charset.c: Moved to...
* charset.cc: ...here.
* directives.c: Moved to...
* directives.cc: ...here.
* errors.c: Moved to...
* errors.cc: ...here.
* expr.c: Moved to...
* expr.cc: ...here.
* files.c: Moved to...
* files.cc: ...here.
* identifiers.c: Moved to...
* identifiers.cc: ...here.
* init.c: Moved to...
* init.cc: ...here.
* lex.c: Moved to...
* lex.cc: ...here.
* line-map.c: Moved to...
* line-map.cc: ...here.
* macro.c: Moved to...
* macro.cc: ...here.
* makeucnid.c: Moved to...
* makeucnid.cc: ...here.
* mkdeps.c: Moved to...
* mkdeps.cc: ...here.
* pch.c: Moved to...
* pch.cc: ...here.
* symtab.c: Moved to...
* symtab.cc: ...here.
* traditional.c: Moved to...
* traditional.cc: ...here.
Diffstat (limited to 'gcc/config/nds32/nds32.c')
-rw-r--r-- | gcc/config/nds32/nds32.c | 5895 |
1 files changed, 0 insertions, 5895 deletions
diff --git a/gcc/config/nds32/nds32.c b/gcc/config/nds32/nds32.c deleted file mode 100644 index 7cf060b..0000000 --- a/gcc/config/nds32/nds32.c +++ /dev/null @@ -1,5895 +0,0 @@ -/* Subroutines used for code generation of Andes NDS32 cpu for GNU compiler - Copyright (C) 2012-2022 Free Software Foundation, Inc. - Contributed by Andes Technology Corporation. - - This file is part of GCC. - - GCC is free software; you can redistribute it and/or modify it - under the terms of the GNU General Public License as published - by the Free Software Foundation; either version 3, or (at your - option) any later version. - - GCC is distributed in the hope that it will be useful, but WITHOUT - 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 - <http://www.gnu.org/licenses/>. */ - -/* ------------------------------------------------------------------------ */ - -#define IN_TARGET_CODE 1 - -#include "config.h" -#include "system.h" -#include "coretypes.h" -#include "backend.h" -#include "target.h" -#include "rtl.h" -#include "tree.h" -#include "tree-pass.h" -#include "stringpool.h" -#include "attribs.h" -#include "df.h" -#include "memmodel.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 "stor-layout.h" -#include "varasm.h" -#include "calls.h" -#include "output.h" -#include "explow.h" -#include "expr.h" -#include "tm-constrs.h" -#include "builtins.h" -#include "cpplib.h" -#include "context.h" - -/* This file should be included last. */ -#include "target-def.h" - -/* ------------------------------------------------------------------------ */ - -/* This file is divided into five parts: - - PART 1: Auxiliary static variable definitions and - target hook static variable definitions. - - PART 2: Auxiliary static function definitions. - - PART 3: Implement target hook stuff definitions. - - PART 4: Implemet extern function definitions, - the prototype is in nds32-protos.h. - - PART 5: Initialize target hook structure and definitions. */ - -/* ------------------------------------------------------------------------ */ - -/* PART 1: 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 - 'enum nds32_intrinsic_registers' data type values. - NOTE that the base value starting from 1024. */ -static const char * const nds32_intrinsic_register_names[] = -{ - "$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, affects_type_identity, handler, - exclude } */ - - /* The interrupt vid: [0-63]+ (actual vector number starts from 9 to 72). */ - { "interrupt", 1, 64, false, false, false, false, NULL, NULL }, - /* The exception vid: [1-8]+ (actual vector number starts from 1 to 8). */ - { "exception", 1, 8, false, false, false, false, NULL, NULL }, - /* Argument is user's interrupt numbers. The vector number is always 0. */ - { "reset", 1, 1, false, false, false, false, NULL, NULL }, - - /* The attributes describing isr nested type. */ - { "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 }, - { "partial_save", 0, 0, false, false, false, false, NULL, NULL }, - - /* The attributes used by reset attribute. */ - { "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 } -}; - - -/* ------------------------------------------------------------------------ */ - -/* PART 2: Auxiliary static function definitions. */ - -/* Function to save and restore machine-specific function data. */ -static struct machine_function * -nds32_init_machine_status (void) -{ - struct machine_function *machine; - machine = ggc_cleared_alloc<machine_function> (); - - /* 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; - - return machine; -} - -/* Function to compute stack frame size and - store into cfun->machine structure. */ -static void -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); - cfun->machine->va_args_last_regno - = NDS32_GPR_ARG_FIRST_REGNUM + NDS32_MAX_GPR_REGS_FOR_ARGS - 1; - } - else - { - cfun->machine->va_args_first_regno = SP_REGNUM; - cfun->machine->va_args_last_regno = SP_REGNUM; - } - - /* Important: We need to make sure that varargs area is 8-byte alignment. */ - block_size = cfun->machine->va_args_size; - if (!NDS32_DOUBLE_WORD_ALIGN_P (block_size)) - { - cfun->machine->va_args_area_padding_bytes - = NDS32_ROUND_UP_DOUBLE_WORD (block_size) - block_size; - } - - /* Get local variables, incoming variables, and temporary variables size. - Note that we need to make sure it is 8-byte alignment because - there may be no padding bytes if we are using LRA. */ - cfun->machine->local_size = NDS32_ROUND_UP_DOUBLE_WORD (get_frame_size ()); - - /* Get outgoing arguments size. */ - cfun->machine->out_args_size = crtl->outgoing_args_size; - - /* If $fp value is required to be saved on stack, it needs 4 bytes space. - Check whether $fp is ever live. */ - cfun->machine->fp_size = (df_regs_ever_live_p (FP_REGNUM)) ? 4 : 0; - - /* 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 && 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 - = (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; - - /* Calculate the bytes of saving callee-saved registers on stack. */ - 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++) - { - if (NDS32_REQUIRED_CALLEE_SAVED_P (r)) - { - /* Mark the first required callee-saved register - (only need to set it once). - If first regno == SP_REGNUM, we can tell that - it is the first time to be here. */ - if (cfun->machine->callee_saved_first_gpr_regno == SP_REGNUM) - cfun->machine->callee_saved_first_gpr_regno = r; - /* Mark the last required callee-saved register. */ - cfun->machine->callee_saved_last_gpr_regno = r; - } - } - - /* 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 '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. - 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. - condition 3: There is no local_size, which means - 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 - && !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. */ - 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. */ - 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. */ - if (flag_stack_usage_info) - current_function_static_stack_size = 0; - - /* No need to do following adjustment, return immediately. */ - 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 - located on $r6, $r8, $r10, or $r14. - 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 (v3pushpop_p) - { - /* Recompute: - 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; - cfun->machine->gp_size = 4; - cfun->machine->lp_size = 4; - - /* Remember to set Rb = $r6. */ - cfun->machine->callee_saved_first_gpr_regno = 6; - - if (cfun->machine->callee_saved_last_gpr_regno <= 6) - { - /* Re = $r6 */ - cfun->machine->callee_saved_last_gpr_regno = 6; - } - else if (cfun->machine->callee_saved_last_gpr_regno <= 8) - { - /* Re = $r8 */ - cfun->machine->callee_saved_last_gpr_regno = 8; - } - else if (cfun->machine->callee_saved_last_gpr_regno <= 10) - { - /* Re = $r10 */ - cfun->machine->callee_saved_last_gpr_regno = 10; - } - else if (cfun->machine->callee_saved_last_gpr_regno <= 14) - { - /* Re = $r14 */ - cfun->machine->callee_saved_last_gpr_regno = 14; - } - else if (cfun->machine->callee_saved_last_gpr_regno == SP_REGNUM) - { - /* If last_regno is SP_REGNUM, which means - it is never changed, so set it to Re = $r6. */ - cfun->machine->callee_saved_last_gpr_regno = 6; - } - else - { - /* The program flow should not go here. */ - gcc_unreachable (); - } - } - - 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 - && sp_adjust == 0 - && !frame_pointer_needed) - { - block_size = cfun->machine->fp_size - + cfun->machine->gp_size - + cfun->machine->lp_size; - - if (cfun->machine->callee_saved_last_gpr_regno != SP_REGNUM) - block_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. */ - cfun->machine->callee_saved_gpr_regs_size - = 4 * (cfun->machine->callee_saved_last_gpr_regno - - cfun->machine->callee_saved_first_gpr_regno - + 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_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 - + cfun->machine->callee_saved_gpr_regs_size; - if (!NDS32_DOUBLE_WORD_ALIGN_P (block_size)) - { - cfun->machine->callee_saved_area_gpr_padding_bytes - = NDS32_ROUND_UP_DOUBLE_WORD (block_size) - block_size; - } - - /* If stack usage computation is required, - we need to provide the static stack size. */ - if (flag_stack_usage_info) - { - current_function_static_stack_size - = NDS32_ROUND_UP_DOUBLE_WORD (block_size) - + cfun->machine->local_size - + cfun->machine->out_args_size; - } -} - -/* Function to create a parallel rtx pattern - which presents stack push multiple behavior. - The overall concept are: - "push registers to memory", - "adjust stack pointer". */ -static void -nds32_emit_stack_push_multiple (unsigned Rb, unsigned Re, - bool save_fp_p, bool save_gp_p, bool save_lp_p, - bool vaarg_p) -{ - unsigned regno; - int extra_count; - int num_use_regs; - int par_index; - int offset; - - rtx reg; - rtx mem; - rtx push_rtx; - rtx adjust_sp_rtx; - rtx parallel_insn; - rtx dwarf; - - /* We need to provide a customized rtx which contains - 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)))]) */ - - /* Calculate the number of registers that will be pushed. */ - extra_count = 0; - if (save_fp_p) - extra_count++; - if (save_gp_p) - extra_count++; - if (save_lp_p) - extra_count++; - /* Note that Rb and Re may be SP_REGNUM. DO NOT count it in. */ - if (Rb == SP_REGNUM && Re == SP_REGNUM) - num_use_regs = extra_count; - else - num_use_regs = Re - Rb + 1 + extra_count; - - /* In addition to used registers, - we need one more space for (set sp sp-x) rtx. */ - parallel_insn = gen_rtx_PARALLEL (VOIDmode, - rtvec_alloc (num_use_regs + 1)); - par_index = 0; - - /* Initialize offset and start to create push behavior. */ - offset = -(num_use_regs * 4); - - /* Create (set mem regX) from Rb, Rb+1 up to Re. */ - for (regno = Rb; regno <= Re; regno++) - { - /* Rb and Re may be SP_REGNUM. - We need to break this loop immediately. */ - if (regno == SP_REGNUM) - break; - - reg = gen_rtx_REG (SImode, regno); - mem = gen_frame_mem (SImode, plus_constant (Pmode, - stack_pointer_rtx, - offset)); - push_rtx = gen_rtx_SET (mem, reg); - XVECEXP (parallel_insn, 0, par_index) = push_rtx; - RTX_FRAME_RELATED_P (push_rtx) = 1; - offset = offset + 4; - par_index++; - } - - /* Create (set mem fp), (set mem gp), and (set mem lp) if necessary. */ - if (save_fp_p) - { - reg = gen_rtx_REG (SImode, FP_REGNUM); - mem = gen_frame_mem (SImode, plus_constant (Pmode, - stack_pointer_rtx, - offset)); - push_rtx = gen_rtx_SET (mem, reg); - XVECEXP (parallel_insn, 0, par_index) = push_rtx; - RTX_FRAME_RELATED_P (push_rtx) = 1; - offset = offset + 4; - par_index++; - } - if (save_gp_p) - { - reg = gen_rtx_REG (SImode, GP_REGNUM); - mem = gen_frame_mem (SImode, plus_constant (Pmode, - stack_pointer_rtx, - offset)); - push_rtx = gen_rtx_SET (mem, reg); - XVECEXP (parallel_insn, 0, par_index) = push_rtx; - RTX_FRAME_RELATED_P (push_rtx) = 1; - offset = offset + 4; - par_index++; - } - if (save_lp_p) - { - reg = gen_rtx_REG (SImode, LP_REGNUM); - mem = gen_frame_mem (SImode, plus_constant (Pmode, - stack_pointer_rtx, - offset)); - push_rtx = gen_rtx_SET (mem, reg); - XVECEXP (parallel_insn, 0, par_index) = push_rtx; - RTX_FRAME_RELATED_P (push_rtx) = 1; - offset = offset + 4; - par_index++; - } - - /* Create (set sp sp-x). */ - - /* We need to re-calculate the offset value again for adjustment. */ - offset = -(num_use_regs * 4); - adjust_sp_rtx - = gen_rtx_SET (stack_pointer_rtx, - plus_constant (Pmode, stack_pointer_rtx, offset)); - XVECEXP (parallel_insn, 0, par_index) = adjust_sp_rtx; - RTX_FRAME_RELATED_P (adjust_sp_rtx) = 1; - - parallel_insn = emit_insn (parallel_insn); - - /* The insn rtx 'parallel_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 (parallel_insn) = 1; - - /* Don't use GCC's logic for CFI info if we are generate a push for VAARG - since we will not restore those register at epilogue. */ - if (vaarg_p) - { - dwarf = alloc_reg_note (REG_CFA_ADJUST_CFA, - copy_rtx (adjust_sp_rtx), NULL_RTX); - REG_NOTES (parallel_insn) = dwarf; - } -} - -/* Function to create a parallel rtx pattern - which presents stack pop multiple behavior. - The overall concept are: - "pop registers from memory", - "adjust stack pointer". */ -static void -nds32_emit_stack_pop_multiple (unsigned Rb, unsigned Re, - bool save_fp_p, bool save_gp_p, bool save_lp_p) -{ - unsigned regno; - int extra_count; - int num_use_regs; - int par_index; - int offset; - - rtx reg; - rtx mem; - rtx pop_rtx; - rtx adjust_sp_rtx; - rtx parallel_insn; - rtx dwarf = NULL_RTX; - - /* We need to provide a customized rtx which contains - 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)))]) */ - - /* Calculate the number of registers that will be poped. */ - extra_count = 0; - if (save_fp_p) - extra_count++; - if (save_gp_p) - extra_count++; - if (save_lp_p) - extra_count++; - /* Note that Rb and Re may be SP_REGNUM. DO NOT count it in. */ - if (Rb == SP_REGNUM && Re == SP_REGNUM) - num_use_regs = extra_count; - else - num_use_regs = Re - Rb + 1 + extra_count; - - /* In addition to used registers, - we need one more space for (set sp sp+x) rtx. */ - parallel_insn = gen_rtx_PARALLEL (VOIDmode, - rtvec_alloc (num_use_regs + 1)); - par_index = 0; - - /* Initialize offset and start to create pop behavior. */ - offset = 0; - - /* Create (set regX mem) from Rb, Rb+1 up to Re. */ - for (regno = Rb; regno <= Re; regno++) - { - /* Rb and Re may be SP_REGNUM. - We need to break this loop immediately. */ - if (regno == SP_REGNUM) - break; - - reg = gen_rtx_REG (SImode, regno); - mem = gen_frame_mem (SImode, plus_constant (Pmode, - stack_pointer_rtx, - offset)); - pop_rtx = gen_rtx_SET (reg, mem); - XVECEXP (parallel_insn, 0, par_index) = pop_rtx; - RTX_FRAME_RELATED_P (pop_rtx) = 1; - offset = offset + 4; - par_index++; - - dwarf = alloc_reg_note (REG_CFA_RESTORE, reg, dwarf); - } - - /* Create (set fp mem), (set gp mem), and (set lp mem) if necessary. */ - if (save_fp_p) - { - reg = gen_rtx_REG (SImode, FP_REGNUM); - mem = gen_frame_mem (SImode, plus_constant (Pmode, - stack_pointer_rtx, - offset)); - pop_rtx = gen_rtx_SET (reg, mem); - XVECEXP (parallel_insn, 0, par_index) = pop_rtx; - RTX_FRAME_RELATED_P (pop_rtx) = 1; - offset = offset + 4; - par_index++; - - dwarf = alloc_reg_note (REG_CFA_RESTORE, reg, dwarf); - } - if (save_gp_p) - { - reg = gen_rtx_REG (SImode, GP_REGNUM); - mem = gen_frame_mem (SImode, plus_constant (Pmode, - stack_pointer_rtx, - offset)); - pop_rtx = gen_rtx_SET (reg, mem); - XVECEXP (parallel_insn, 0, par_index) = pop_rtx; - RTX_FRAME_RELATED_P (pop_rtx) = 1; - offset = offset + 4; - par_index++; - - dwarf = alloc_reg_note (REG_CFA_RESTORE, reg, dwarf); - } - if (save_lp_p) - { - reg = gen_rtx_REG (SImode, LP_REGNUM); - mem = gen_frame_mem (SImode, plus_constant (Pmode, - stack_pointer_rtx, - offset)); - pop_rtx = gen_rtx_SET (reg, mem); - XVECEXP (parallel_insn, 0, par_index) = pop_rtx; - RTX_FRAME_RELATED_P (pop_rtx) = 1; - offset = offset + 4; - par_index++; - - dwarf = alloc_reg_note (REG_CFA_RESTORE, reg, dwarf); - } - - /* Create (set sp sp+x). */ - - /* The offset value is already in place. No need to re-calculate it. */ - adjust_sp_rtx - = gen_rtx_SET (stack_pointer_rtx, - plus_constant (Pmode, stack_pointer_rtx, offset)); - 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); - - parallel_insn = emit_insn (parallel_insn); - - /* The insn rtx 'parallel_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 (parallel_insn) = 1; - - /* Add CFI info by manual. */ - REG_NOTES (parallel_insn) = dwarf; -} - -/* Function to create a parallel rtx pattern - which presents stack v3push behavior. - The overall concept are: - "push registers to memory", - "adjust stack pointer". */ -static void -nds32_emit_stack_v3push (unsigned Rb, - unsigned Re, - unsigned imm8u) -{ - unsigned regno; - int num_use_regs; - int par_index; - int offset; - - rtx reg; - rtx mem; - rtx push_rtx; - rtx adjust_sp_rtx; - rtx parallel_insn; - - /* We need to provide a customized rtx which contains - 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)))]) */ - - /* 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 = Re - Rb + 1 + 3; - - /* In addition to used registers, - we need one more space for (set sp sp-x-imm8u) rtx. */ - parallel_insn = gen_rtx_PARALLEL (VOIDmode, - rtvec_alloc (num_use_regs + 1)); - par_index = 0; - - /* Initialize offset and start to create push behavior. */ - offset = -(num_use_regs * 4); - - /* 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 = Rb; regno <= Re; regno++) - { - reg = gen_rtx_REG (SImode, regno); - mem = gen_frame_mem (SImode, plus_constant (Pmode, - stack_pointer_rtx, - offset)); - push_rtx = gen_rtx_SET (mem, reg); - XVECEXP (parallel_insn, 0, par_index) = push_rtx; - RTX_FRAME_RELATED_P (push_rtx) = 1; - offset = offset + 4; - par_index++; - } - - /* Create (set mem fp). */ - reg = gen_rtx_REG (SImode, FP_REGNUM); - mem = gen_frame_mem (SImode, plus_constant (Pmode, - stack_pointer_rtx, - offset)); - push_rtx = gen_rtx_SET (mem, reg); - XVECEXP (parallel_insn, 0, par_index) = push_rtx; - RTX_FRAME_RELATED_P (push_rtx) = 1; - offset = offset + 4; - par_index++; - /* Create (set mem gp). */ - reg = gen_rtx_REG (SImode, GP_REGNUM); - mem = gen_frame_mem (SImode, plus_constant (Pmode, - stack_pointer_rtx, - offset)); - push_rtx = gen_rtx_SET (mem, reg); - XVECEXP (parallel_insn, 0, par_index) = push_rtx; - RTX_FRAME_RELATED_P (push_rtx) = 1; - offset = offset + 4; - par_index++; - /* Create (set mem lp). */ - reg = gen_rtx_REG (SImode, LP_REGNUM); - mem = gen_frame_mem (SImode, plus_constant (Pmode, - stack_pointer_rtx, - offset)); - push_rtx = gen_rtx_SET (mem, reg); - XVECEXP (parallel_insn, 0, par_index) = push_rtx; - RTX_FRAME_RELATED_P (push_rtx) = 1; - offset = offset + 4; - par_index++; - - /* Create (set sp sp-x-imm8u). */ - - /* We need to re-calculate the offset value again for adjustment. */ - offset = -(num_use_regs * 4); - adjust_sp_rtx - = gen_rtx_SET (stack_pointer_rtx, - plus_constant (Pmode, - stack_pointer_rtx, - offset - imm8u)); - XVECEXP (parallel_insn, 0, par_index) = adjust_sp_rtx; - RTX_FRAME_RELATED_P (adjust_sp_rtx) = 1; - - parallel_insn = emit_insn (parallel_insn); - - /* The insn rtx 'parallel_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 (parallel_insn) = 1; -} - -/* Function to create a parallel rtx pattern - which presents stack v3pop behavior. - The overall concept are: - "pop registers from memory", - "adjust stack pointer". */ -static void -nds32_emit_stack_v3pop (unsigned Rb, - unsigned Re, - unsigned imm8u) -{ - unsigned regno; - int num_use_regs; - int par_index; - int offset; - - rtx reg; - rtx mem; - rtx pop_rtx; - rtx adjust_sp_rtx; - rtx parallel_insn; - rtx dwarf = NULL_RTX; - - /* We need to provide a customized rtx which contains - 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)))]) */ - - /* 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 = Re - Rb + 1 + 3; - - /* In addition to used registers, - we need one more space for (set sp sp+x+imm8u) rtx. */ - parallel_insn = gen_rtx_PARALLEL (VOIDmode, - rtvec_alloc (num_use_regs + 1)); - par_index = 0; - - /* Initialize offset and start to create pop behavior. */ - offset = 0; - - /* 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 = Rb; regno <= Re; regno++) - { - reg = gen_rtx_REG (SImode, regno); - mem = gen_frame_mem (SImode, plus_constant (Pmode, - stack_pointer_rtx, - offset)); - pop_rtx = gen_rtx_SET (reg, mem); - XVECEXP (parallel_insn, 0, par_index) = pop_rtx; - RTX_FRAME_RELATED_P (pop_rtx) = 1; - offset = offset + 4; - par_index++; - - dwarf = alloc_reg_note (REG_CFA_RESTORE, reg, dwarf); - } - - /* Create (set fp mem). */ - reg = gen_rtx_REG (SImode, FP_REGNUM); - mem = gen_frame_mem (SImode, plus_constant (Pmode, - stack_pointer_rtx, - offset)); - pop_rtx = gen_rtx_SET (reg, mem); - XVECEXP (parallel_insn, 0, par_index) = pop_rtx; - RTX_FRAME_RELATED_P (pop_rtx) = 1; - offset = offset + 4; - par_index++; - dwarf = alloc_reg_note (REG_CFA_RESTORE, reg, dwarf); - - /* Create (set gp mem). */ - reg = gen_rtx_REG (SImode, GP_REGNUM); - mem = gen_frame_mem (SImode, plus_constant (Pmode, - stack_pointer_rtx, - offset)); - pop_rtx = gen_rtx_SET (reg, mem); - XVECEXP (parallel_insn, 0, par_index) = pop_rtx; - RTX_FRAME_RELATED_P (pop_rtx) = 1; - offset = offset + 4; - par_index++; - dwarf = alloc_reg_note (REG_CFA_RESTORE, reg, dwarf); - - /* Create (set lp mem ). */ - reg = gen_rtx_REG (SImode, LP_REGNUM); - mem = gen_frame_mem (SImode, plus_constant (Pmode, - stack_pointer_rtx, - offset)); - pop_rtx = gen_rtx_SET (reg, mem); - XVECEXP (parallel_insn, 0, par_index) = pop_rtx; - RTX_FRAME_RELATED_P (pop_rtx) = 1; - offset = offset + 4; - par_index++; - dwarf = alloc_reg_note (REG_CFA_RESTORE, reg, dwarf); - - /* Create (set sp sp+x+imm8u). */ - - /* The offset value is already in place. No need to re-calculate it. */ - adjust_sp_rtx - = gen_rtx_SET (stack_pointer_rtx, - plus_constant (Pmode, - stack_pointer_rtx, - offset + imm8u)); - XVECEXP (parallel_insn, 0, par_index) = adjust_sp_rtx; - - 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); - - /* The insn rtx 'parallel_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 (parallel_insn) = 1; - - /* Add CFI info by manual. */ - 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. - - In nds32 target, 'addi' can be used for stack pointer - adjustment in prologue/epilogue stage. - However, sometimes there are too many local variables so that - 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. */ -static void -nds32_emit_adjust_frame (rtx to_reg, rtx from_reg, int adjust_value) -{ - rtx tmp_reg; - rtx frame_adjust_insn; - rtx adjust_value_rtx = GEN_INT (adjust_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. */ - - /* $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, adjust_value_rtx); - - /* Create new 'add' rtx. */ - frame_adjust_insn = gen_addsi3 (to_reg, - from_reg, - tmp_reg); - /* Emit rtx into insn list and receive its transformed insn rtx. */ - frame_adjust_insn = emit_insn (frame_adjust_insn); - - /* Because (tmp_reg <- full_value) may be split into two - rtl patterns, we cannot 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; - - 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 - { - /* 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) -{ - unsigned int align; - - /* Pick up the alignment according to the mode or type. */ - align = NDS32_MODE_TYPE_ALIGN (mode, type); - - return (align > PARM_BOUNDARY); -} - -/* Return true if FUNC is a naked function. */ -bool -nds32_naked_function_p (tree func) -{ - /* 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 (); - - /* 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_naked != NULL_TREE) || (t_no_prologue != NULL_TREE)); -} - -/* Function that determine whether a load postincrement is a good thing to use - for a given mode. */ -bool -nds32_use_load_post_increment (machine_mode mode) -{ - return (GET_MODE_SIZE (mode) <= GET_MODE_SIZE(E_DImode)); -} - -/* Function that check if 'X' is a valid address register. - The variable 'STRICT' is very important to - make decision for register number. - - STRICT : true - => We are in reload pass or after reload pass. - The register number should be strictly limited in general registers. - - STRICT : false - => Before reload pass, we are free to use any register number. */ -static bool -nds32_address_register_rtx_p (rtx x, bool strict) -{ - int regno; - - if (GET_CODE (x) != REG) - return false; - - regno = REGNO (x); - - if (strict) - return REGNO_OK_FOR_BASE_P (regno); - else - return true; -} - -/* 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. - STRICT : If it is true, we are in reload pass or after reload pass. */ -static bool -nds32_legitimate_index_p (machine_mode outer_mode, - rtx index, - bool strict) -{ - int regno; - rtx op0; - rtx op1; - - switch (GET_CODE (index)) - { - case REG: - regno = REGNO (index); - /* If we are in reload pass or after reload pass, - we need to limit it to general register. */ - if (strict) - return REGNO_OK_FOR_INDEX_P (regno); - else - return true; - - case CONST_INT: - /* The alignment of the integer value is determined by 'outer_mode'. */ - 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 true; - break; - - case 2: - /* Further check if the value is legal for the 'outer_mode'. */ - 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; - - case 4: - /* Further check if the value is legal for the 'outer_mode'. */ - 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; - - 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; - - default: - return false; - } - - return false; - - case MULT: - op0 = XEXP (index, 0); - op1 = XEXP (index, 1); - - if (REG_P (op0) && CONST_INT_P (op1)) - { - int multiplier; - multiplier = INTVAL (op1); - - /* 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); - /* Limit it in general registers if we are - in reload pass or after reload pass. */ - if(strict) - return REGNO_OK_FOR_INDEX_P (regno); - else - return true; - } - - return false; - - case ASHIFT: - op0 = XEXP (index, 0); - op1 = XEXP (index, 1); - - if (REG_P (op0) && CONST_INT_P (op1)) - { - int sv; - /* op1 is already the sv value for use to do left shift. */ - sv = INTVAL (op1); - - /* We only allow (ashift reg const_int_0) - 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); - /* Limit it in general registers if we are - in reload pass or after reload pass. */ - if(strict) - return REGNO_OK_FOR_INDEX_P (regno); - else - return true; - } - - return false; - - default: - return false; - } -} - -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); -} - -/* 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"); -} - -/* ------------------------------------------------------------------------ */ - -/* PART 3: 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 unsigned char -nds32_class_max_nregs (reg_class_t rclass ATTRIBUTE_UNUSED, - machine_mode mode) -{ - /* Return the maximum number of consecutive registers - needed to represent "mode" in a register of "rclass". */ - return ((GET_MODE_SIZE (mode) + UNITS_PER_WORD - 1) / UNITS_PER_WORD); -} - -static int -nds32_register_priority (int hard_regno) -{ - /* Encourage to use r0-r7 for LRA when optimize for size. */ - 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; - } -} - -static bool -nds32_can_change_mode_class (machine_mode from, - machine_mode to, - reg_class_t rclass) -{ - /* Don't spill double-precision register to two singal-precision - registers */ - if ((TARGET_FPU_SINGLE || TARGET_FPU_DOUBLE) - && GET_MODE_SIZE (from) != GET_MODE_SIZE (to)) - { - return !reg_classes_intersect_p (rclass, FP_REGS); - } - - return true; -} - - -/* Stack Layout and Calling Conventions. */ - -/* There are three kinds of pointer concepts using in GCC compiler: - - frame pointer: A pointer to the first location of local variables. - stack pointer: A pointer to the top of a stack frame. - argument pointer: A pointer to the incoming arguments. - - In nds32 target calling convention, we are using 8-byte alignment. - Besides, we would like to have each stack frame of a function includes: - - [Block A] - 1. previous hard frame pointer - 2. return address - 3. callee-saved registers - 4. <padding bytes> (we will calculte in nds32_compute_stack_frame() - and save it at - cfun->machine->callee_saved_area_padding_bytes) - - [Block B] - 1. local variables - 2. spilling location - 3. <padding bytes> (it will be calculated by GCC itself) - 4. incoming arguments - 5. <padding bytes> (it will be calculated by GCC itself) - - [Block C] - 1. <padding bytes> (it will be calculated by GCC itself) - 2. outgoing arguments - - We 'wrap' these blocks together with - hard frame pointer ($r28) and stack pointer ($r31). - 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 - | | / - 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 -> ---- - - $SFP and $AP are used to represent frame pointer and arguments pointer, - which will be both eliminated as hard frame pointer. */ - -/* -- Eliminating Frame Pointer and Arg Pointer. */ - -static bool -nds32_can_eliminate (const int from_reg, const int to_reg) -{ - if (from_reg == ARG_POINTER_REGNUM && to_reg == STACK_POINTER_REGNUM) - return true; - - if (from_reg == ARG_POINTER_REGNUM && to_reg == HARD_FRAME_POINTER_REGNUM) - return true; - - if (from_reg == FRAME_POINTER_REGNUM && to_reg == STACK_POINTER_REGNUM) - return true; - - if (from_reg == FRAME_POINTER_REGNUM && to_reg == HARD_FRAME_POINTER_REGNUM) - return true; - - return false; -} - -/* -- Passing Arguments in Registers. */ - -static rtx -nds32_function_arg (cumulative_args_t ca, const function_arg_info &arg) -{ - unsigned int regno; - CUMULATIVE_ARGS *cum = get_cumulative_args (ca); - tree type = arg.type; - machine_mode mode = arg.mode; - - /* The last time this hook is called, - it is called with an end marker. */ - if (arg.end_marker_p ()) - return NULL_RTX; - - /* For nameless arguments, we need to take care it individually. */ - if (!arg.named) - { - /* If we are under hard float abi, we have arguments passed on the - stack and all situation can be handled by GCC itself. */ - if (TARGET_HARD_FLOAT) - return NULL_RTX; - - if (NDS32_ARG_PARTIAL_IN_GPR_REG_P (cum->gpr_offset, mode, type)) - { - /* If we still have enough registers to pass argument, pick up - next available register number. */ - regno - = NDS32_AVAILABLE_REGNUM_FOR_GPR_ARG (cum->gpr_offset, mode, type); - return gen_rtx_REG (mode, regno); - } - - /* No register available, return NULL_RTX. - The compiler will use stack to pass argument instead. */ - return NULL_RTX; - } - - /* The following is to handle named argument. - Note that the strategies of TARGET_HARD_FLOAT and !TARGET_HARD_FLOAT - are different. */ - if (TARGET_HARD_FLOAT) - { - /* 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. */ - if (NDS32_ARG_PARTIAL_IN_GPR_REG_P (cum->gpr_offset, mode, type)) - { - /* Pick up the next available register number. */ - regno - = NDS32_AVAILABLE_REGNUM_FOR_GPR_ARG (cum->gpr_offset, mode, type); - return gen_rtx_REG (mode, regno); - } - - } - - /* No register available, return NULL_RTX. - The compiler will use stack to pass argument instead. */ - return NULL_RTX; -} - -static bool -nds32_must_pass_in_stack (const function_arg_info &arg) -{ - /* Return true if a type must be passed in memory. - If it is NOT using hard float abi, small aggregates can be - passed in a register even we are calling a variadic function. - So there is no need to take padding into consideration. */ - if (TARGET_HARD_FLOAT) - return must_pass_in_stack_var_size_or_pad (arg); - else - return must_pass_in_stack_var_size (arg); -} - -static int -nds32_arg_partial_bytes (cumulative_args_t ca, const function_arg_info &arg) -{ - /* Returns the number of bytes at the beginning of an argument that - must be put in registers. The value must be zero for arguments that are - passed entirely in registers or that are entirely pushed on the stack. - Besides, TARGET_FUNCTION_ARG for these arguments should return the - first register to be used by the caller for this argument. */ - unsigned int needed_reg_count; - unsigned int remaining_reg_count; - CUMULATIVE_ARGS *cum; - - cum = get_cumulative_args (ca); - - /* Under hard float abi, we better have argument entirely passed in - registers or pushed on the stack so that we can reduce the complexity - of dealing with cum->gpr_offset and cum->fpr_offset. */ - if (TARGET_HARD_FLOAT) - return 0; - - /* If we have already runned out of argument registers, return zero - so that the argument will be entirely pushed on the stack. */ - if (NDS32_AVAILABLE_REGNUM_FOR_GPR_ARG (cum->gpr_offset, arg.mode, arg.type) - >= NDS32_GPR_ARG_FIRST_REGNUM + NDS32_MAX_GPR_REGS_FOR_ARGS) - return 0; - - /* Calculate how many registers do we need for this argument. */ - needed_reg_count = NDS32_NEED_N_REGS_FOR_ARG (arg.mode, arg.type); - - /* Calculate how many argument registers have left for passing argument. - Note that we should count it from next available register number. */ - remaining_reg_count - = NDS32_MAX_GPR_REGS_FOR_ARGS - - (NDS32_AVAILABLE_REGNUM_FOR_GPR_ARG (cum->gpr_offset, - arg.mode, arg.type) - - 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) - return remaining_reg_count * UNITS_PER_WORD; - - return 0; -} - -static void -nds32_function_arg_advance (cumulative_args_t ca, - const function_arg_info &arg) -{ - CUMULATIVE_ARGS *cum = get_cumulative_args (ca); - tree type = arg.type; - machine_mode mode = arg.mode; - - if (arg.named) - { - /* We need to further check TYPE and MODE so that we can determine - which kind of register we shall advance. */ - - /* Under hard float abi, we may advance FPR registers. */ - if (TARGET_HARD_FLOAT && GET_MODE_CLASS (mode) == MODE_FLOAT) - { - 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 - { - cum->gpr_offset - = NDS32_AVAILABLE_REGNUM_FOR_GPR_ARG (cum->gpr_offset, mode, type) - - NDS32_GPR_ARG_FIRST_REGNUM - + NDS32_NEED_N_REGS_FOR_ARG (mode, type); - } - } - 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. */ - if (!TARGET_HARD_FLOAT) - { - cum->gpr_offset - = NDS32_AVAILABLE_REGNUM_FOR_GPR_ARG (cum->gpr_offset, mode, type) - - NDS32_GPR_ARG_FIRST_REGNUM - + NDS32_NEED_N_REGS_FOR_ARG (mode, type); - } - } -} - -static unsigned int -nds32_function_arg_boundary (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 (machine_mode mode) -{ - if (mode == V4QImode - || mode == V2HImode) - return NDS32_EXT_DSP_P (); - - return false; -} - -/* -- How Scalar Function Values Are Returned. */ - -static rtx -nds32_function_value (const_tree ret_type, - const_tree fn_decl_or_type ATTRIBUTE_UNUSED, - bool outgoing ATTRIBUTE_UNUSED) -{ - machine_mode mode; - int unsignedp; - - mode = TYPE_MODE (ret_type); - unsignedp = TYPE_UNSIGNED (ret_type); - - if (INTEGRAL_TYPE_P (ret_type)) - mode = promote_mode (ret_type, mode, &unsignedp); - - 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, - 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) -{ - 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. */ - -/* The content produced from this function - will be placed before prologue body. */ -static void -nds32_asm_function_prologue (FILE *file) -{ - int r; - const char *func_name; - tree attrs; - tree name; - - /* All stack frame information is supposed to be - already computed when expanding prologue. - The result is in cfun->machine. - DO NOT call nds32_compute_stack_frame() here - because it may corrupt the essential information. */ - - fprintf (file, "\t! BEGIN PROLOGUE\n"); - fprintf (file, "\t! fp needed: %d\n", frame_pointer_needed); - fprintf (file, "\t! pretend_args: %d\n", cfun->machine->va_args_size); - fprintf (file, "\t! local_size: %d\n", cfun->machine->local_size); - fprintf (file, "\t! out_args_size: %d\n", cfun->machine->out_args_size); - - /* 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 < 65; r++) - { - if (df_regs_ever_live_p (r)) - fprintf (file, "%s, ", reg_names[r]); - } - fputc ('\n', file); - - /* Display the attributes of this function. */ - fprintf (file, "\t! function attributes: "); - /* Get the attributes tree list. - Note that GCC builds attributes list with reverse order. */ - attrs = DECL_ATTRIBUTES (current_function_decl); - - /* If there is no any attribute, print out "None". */ - if (!attrs) - fprintf (file, "None"); - - /* If there are some attributes, try if we need to - construct isr vector information. */ - func_name = IDENTIFIER_POINTER (DECL_NAME (current_function_decl)); - nds32_construct_isr_vectors_information (attrs, func_name); - - /* Display all attributes of this function. */ - while (attrs) - { - name = TREE_PURPOSE (attrs); - fprintf (file, "%s ", IDENTIFIER_POINTER (name)); - - /* Pick up the next attribute. */ - attrs = TREE_CHAIN (attrs); - } - fputc ('\n', file); -} - -/* After rtl prologue has been expanded, this function is used. */ -static void -nds32_asm_function_end_prologue (FILE *file) -{ - fprintf (file, "\t! END PROLOGUE\n"); -} - -/* Before rtl epilogue has been expanded, this function is used. */ -static void -nds32_asm_function_begin_epilogue (FILE *file) -{ - fprintf (file, "\t! BEGIN EPILOGUE\n"); -} - -/* The content produced from this function - will be placed after epilogue body. */ -static void -nds32_asm_function_epilogue (FILE *file) -{ - fprintf (file, "\t! END EPILOGUE\n"); -} - -static void -nds32_asm_output_mi_thunk (FILE *file, tree thunk ATTRIBUTE_UNUSED, - HOST_WIDE_INT delta, - HOST_WIDE_INT vcall_offset ATTRIBUTE_UNUSED, - tree function) -{ - const char *fnname = IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (thunk)); - int this_regno; - - assemble_start_function (thunk, fnname); - /* Make sure unwind info is emitted for the thunk if needed. */ - final_start_function (emit_barrier (), file, 1); - - this_regno = (aggregate_value_p (TREE_TYPE (TREE_TYPE (function)), function) - ? 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, " HOST_WIDE_INT_PRINT_DEC "\n", - this_regno, this_regno, delta); - } - else if (satisfies_constraint_Is20 (GEN_INT (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(" 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); - } - } - - 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 (); - assemble_end_function (thunk, fnname); -} - -/* -- 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. */ - return !nds32_naked_function_p (decl); -} - - -/* Implementing the Varargs Macros. */ - -static void -nds32_setup_incoming_varargs (cumulative_args_t ca, - const function_arg_info &arg, - int *pretend_args_size, - int second_time ATTRIBUTE_UNUSED) -{ - unsigned int total_args_regs; - unsigned int num_of_used_regs; - unsigned int remaining_reg_count; - CUMULATIVE_ARGS *cum; - - /* If we are under hard float abi, we do not need to set *pretend_args_size. - So that all nameless arguments are pushed by caller and all situation - can be handled by GCC itself. */ - if (TARGET_HARD_FLOAT) - return; - - /* We are using NDS32_MAX_GPR_REGS_FOR_ARGS registers, - counting from NDS32_GPR_ARG_FIRST_REGNUM, for saving incoming arguments. - However, for nameless(anonymous) arguments, we should push them on the - stack so that all the nameless arguments appear to have been passed - consecutively in the memory for accessing. Hence, we need to check and - exclude the registers that are used for named arguments. */ - - cum = get_cumulative_args (ca); - - /* ARG describes the last argument. - We need those information to determine the remaining registers - for varargs. */ - total_args_regs - = NDS32_MAX_GPR_REGS_FOR_ARGS + NDS32_GPR_ARG_FIRST_REGNUM; - num_of_used_regs - = NDS32_AVAILABLE_REGNUM_FOR_GPR_ARG (cum->gpr_offset, arg.mode, arg.type) - + NDS32_NEED_N_REGS_FOR_ARG (arg.mode, arg.type); - - remaining_reg_count = total_args_regs - num_of_used_regs; - *pretend_args_size = remaining_reg_count * UNITS_PER_WORD; - - return; -} - -static bool -nds32_strict_argument_naming (cumulative_args_t ca ATTRIBUTE_UNUSED) -{ - /* If this hook returns true, the named argument of FUNCTION_ARG is always - true for named arguments, and false for unnamed arguments. */ - return true; -} - - -/* Trampolines for Nested Functions. */ - -static void -nds32_asm_trampoline_template (FILE *f) -{ - if (TARGET_REDUCED_REGS) - { - /* Trampoline is not supported on reduced-set registers yet. */ - sorry ("a nested function is not supported for reduced registers"); - } - else - { - asm_fprintf (f, "\t! Trampoline code template\n"); - asm_fprintf (f, "\t! This code fragment will be copied " - "into stack on demand\n"); - - asm_fprintf (f, "\tmfusr\t$r16,$pc\n"); - asm_fprintf (f, "\tlwi\t$r15,[$r16 + 20] " - "! load nested function address\n"); - asm_fprintf (f, "\tlwi\t$r16,[$r16 + 16] " - "! load chain_value\n"); - asm_fprintf (f, "\tjr\t$r15\n"); - } - - /* Preserve space ($pc + 16) for saving chain_value, - nds32_trampoline_init will fill the value in this slot. */ - asm_fprintf (f, "\t! space for saving chain_value\n"); - assemble_aligned_integer (UNITS_PER_WORD, const0_rtx); - - /* Preserve space ($pc + 20) for saving nested function address, - nds32_trampoline_init will fill the value in this slot. */ - asm_fprintf (f, "\t! space for saving nested function address\n"); - assemble_aligned_integer (UNITS_PER_WORD, const0_rtx); -} - -/* Emit RTL insns to initialize the variable parts of a trampoline. */ -static void -nds32_trampoline_init (rtx m_tramp, tree fndecl, rtx chain_value) -{ - int i; - - /* Nested function address. */ - rtx fnaddr; - /* The memory rtx that is going to - be filled with chain_value. */ - rtx chain_value_mem; - /* The memory rtx that is going to - be filled with nested function address. */ - rtx nested_func_mem; - - /* Start address of trampoline code in stack, for doing cache sync. */ - rtx sync_cache_addr; - /* Temporary register for sync instruction. */ - rtx tmp_reg; - /* Instruction-cache sync instruction, - requesting an argument as starting address. */ - rtx isync_insn; - /* For convenience reason of doing comparison. */ - int tramp_align_in_bytes; - - /* Trampoline is not supported on reduced-set registers yet. */ - if (TARGET_REDUCED_REGS) - sorry ("a nested function is not supported for reduced registers"); - - /* STEP 1: Copy trampoline code template into stack, - fill up essential data into stack. */ - - /* Extract nested function address rtx. */ - fnaddr = XEXP (DECL_RTL (fndecl), 0); - - /* m_tramp is memory rtx that is going to be filled with trampoline code. - We have nds32_asm_trampoline_template() to emit template pattern. */ - emit_block_move (m_tramp, assemble_trampoline_template (), - GEN_INT (TRAMPOLINE_SIZE), BLOCK_OP_NORMAL); - - /* After copying trampoline code into stack, - fill chain_value into stack. */ - chain_value_mem = adjust_address (m_tramp, SImode, 16); - emit_move_insn (chain_value_mem, chain_value); - /* After copying trampoline code int stack, - fill nested function address into stack. */ - nested_func_mem = adjust_address (m_tramp, SImode, 20); - emit_move_insn (nested_func_mem, fnaddr); - - /* STEP 2: Sync instruction-cache. */ - - /* We have successfully filled trampoline code into stack. - However, in order to execute code in stack correctly, - we must sync instruction cache. */ - sync_cache_addr = XEXP (m_tramp, 0); - tmp_reg = gen_reg_rtx (SImode); - isync_insn = gen_unspec_volatile_isync (tmp_reg); - - /* Because nds32_cache_block_size is in bytes, - we get trampoline alignment in bytes for convenient comparison. */ - tramp_align_in_bytes = TRAMPOLINE_ALIGNMENT / BITS_PER_UNIT; - - if (tramp_align_in_bytes >= nds32_cache_block_size - && (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. */ - for (i = 0; - i < (TRAMPOLINE_SIZE + nds32_cache_block_size - 1) - / nds32_cache_block_size; - i++) - { - emit_move_insn (tmp_reg, - plus_constant (Pmode, sync_cache_addr, - nds32_cache_block_size * i)); - emit_insn (isync_insn); - } - } - 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. */ - for (i = 0; - i < (TRAMPOLINE_SIZE + nds32_cache_block_size - 1) - / nds32_cache_block_size; - i++) - { - emit_move_insn (tmp_reg, - plus_constant (Pmode, sync_cache_addr, - nds32_cache_block_size * i)); - emit_insn (isync_insn); - } - - /* The last element of trampoline template is 4-byte size. */ - emit_move_insn (tmp_reg, - plus_constant (Pmode, sync_cache_addr, - TRAMPOLINE_SIZE - 4)); - emit_insn (isync_insn); - } - 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. */ - - /* 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. */ - emit_move_insn (tmp_reg, - plus_constant (Pmode, sync_cache_addr, - TRAMPOLINE_SIZE - 4)); - emit_insn (isync_insn); - } - - /* Set instruction serialization barrier - to guarantee the correct operations. */ - emit_insn (gen_unspec_volatile_isb ()); -} - - -/* Addressing Modes. */ - -static bool -nds32_legitimate_address_p (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. */ - if (mode == DImode || mode == DFmode) - { - /* Allow [Reg + const_int] addressing mode. */ - if (GET_CODE (x) == PLUS) - { - if (nds32_address_register_rtx_p (XEXP (x, 0), 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 - && GET_CODE (x) != CONST) - return false; - } - - /* Check if 'x' is a valid address. */ - switch (GET_CODE (x)) - { - case REG: - /* (mem (reg A)) => [Ra] */ - return nds32_address_register_rtx_p (x, 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 - && (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. */ - if (TARGET_CMODEL_MEDIUM - && (NDS32_SYMBOL_REF_RODATA_P (x) - || CONSTANT_POOL_ADDRESS_P (x)) - && (reload_completed - || reload_in_progress - || lra_in_progress)) - return false; - - return true; - - case CONST: - /* (mem (const (...))) - => [ + const_addr ], where const_addr = symbol_ref + const_int */ - if (GET_CODE (XEXP (x, 0)) == PLUS) - { - rtx plus_op = XEXP (x, 0); - - rtx op0 = XEXP (plus_op, 0); - rtx op1 = XEXP (plus_op, 1); - - if (GET_CODE (op0) == SYMBOL_REF && CONST_INT_P (op1)) - { - /* 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 - && (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. */ - if (TARGET_CMODEL_MEDIUM - && NDS32_SYMBOL_REF_RODATA_P (op0) - && (reload_completed - || reload_in_progress - || lra_in_progress)) - return false; - - /* At this point we can make sure 'const_addr' is a - valid address. */ - return true; - } - } - - return false; - - case POST_MODIFY: - /* (mem (post_modify (reg) (plus (reg) (reg)))) - => [Ra], Rb */ - /* (mem (post_modify (reg) (plus (reg) (const_int)))) - => [Ra], const_int */ - 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) - && nds32_legitimate_index_p (mode, op1, strict)) - return true; - else - return false; - } - - return false; - - case POST_INC: - case POST_DEC: - /* (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. */ - if (nds32_address_register_rtx_p (XEXP (x, 0), strict)) - return true; - else - return false; - - case PLUS: - /* (mem (plus reg const_int)) - => [Ra + imm] */ - /* (mem (plus reg reg)) - => [Ra + Rb] */ - /* (mem (plus (mult reg const_int) reg)) - => [Ra + Rb << sv] */ - if (nds32_address_register_rtx_p (XEXP (x, 0), strict) - && nds32_legitimate_index_p (mode, XEXP (x, 1), strict)) - return true; - else if (nds32_address_register_rtx_p (XEXP (x, 1), strict) - && nds32_legitimate_index_p (mode, XEXP (x, 0), strict)) - return true; - else - return false; - - case LO_SUM: - /* (mem (lo_sum (reg) (symbol_ref))) */ - /* (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; -} - - -/* 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, - 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 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, - reg_class_t rclass ATTRIBUTE_UNUSED, - bool in ATTRIBUTE_UNUSED) -{ - return 8; -} - -/* 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. */ -static bool -nds32_rtx_costs (rtx x, - machine_mode mode, - int outer_code, - int opno, - int *total, - bool speed) -{ - return nds32_rtx_costs_impl (x, mode, outer_code, opno, total, speed); -} - -static int -nds32_address_cost (rtx address, - machine_mode mode, - addr_space_t as, - bool speed) -{ - return nds32_address_cost_impl (address, mode, as, speed); -} - - -/* Dividing the Output into Sections (Texts, Data, . . . ). */ - -/* If references to a symbol or a constant must be treated differently - depending on something about the variable or function named by the symbol - (such as what section it is in), we use this hook to store flags - in symbol_ref rtx. */ -static void -nds32_encode_section_info (tree decl, rtx rtl, int new_decl_p) -{ - default_encode_section_info (decl, rtl, new_decl_p); - - /* For the memory rtx, if it references to rodata section, we can store - NDS32_SYMBOL_FLAG_RODATA flag into symbol_ref rtx so that the - nds32_legitimate_address_p() can determine how to treat such symbol_ref - based on -mcmodel=X and this information. */ - if (MEM_P (rtl) && MEM_READONLY_P (rtl)) - { - rtx addr = XEXP (rtl, 0); - - if (GET_CODE (addr) == SYMBOL_REF) - { - /* For (mem (symbol_ref X)) case. */ - SYMBOL_REF_FLAGS (addr) |= NDS32_SYMBOL_FLAG_RODATA; - } - else if (GET_CODE (addr) == CONST - && GET_CODE (XEXP (addr, 0)) == PLUS) - { - /* For (mem (const (plus (symbol_ref X) (const_int N)))) case. */ - rtx plus_op = XEXP (addr, 0); - rtx op0 = XEXP (plus_op, 0); - rtx op1 = XEXP (plus_op, 1); - - if (GET_CODE (op0) == SYMBOL_REF && CONST_INT_P (op1)) - SYMBOL_REF_FLAGS (op0) |= NDS32_SYMBOL_FLAG_RODATA; - } - } -} - - -/* Defining the Output Assembler Language. */ - -/* -- The Overall Framework of an Assembler File. */ - -static void -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) - 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"); - - /* 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"); - - if (TARGET_ISA_V2) - fprintf (asm_out_file, "\t! ISA family\t\t: %s\n", "V2"); - if (TARGET_ISA_V3) - fprintf (asm_out_file, "\t! ISA family\t\t: %s\n", "V3"); - 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) - fprintf (asm_out_file, "\t! Code model\t\t: %s\n", "MEDIUM"); - if (TARGET_CMODEL_LARGE) - fprintf (asm_out_file, "\t! Code model\t\t: %s\n", "LARGE"); - - 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"); - - fprintf (asm_out_file, "\t! Use conditional move\t\t: %s\n", - ((TARGET_CMOV) ? "Yes" - : "No")); - fprintf (asm_out_file, "\t! Use performance extension\t: %s\n", - ((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"); - - fprintf (asm_out_file, "\t! V3PUSH instructions\t: %s\n", - ((TARGET_V3PUSH) ? "Yes" - : "No")); - fprintf (asm_out_file, "\t! 16-bit instructions\t: %s\n", - ((TARGET_16_BIT) ? "Yes" - : "No")); - fprintf (asm_out_file, "\t! Reduced registers set\t: %s\n", - ((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); - - fprintf (asm_out_file, "\t! ------------------------------------\n"); - - fprintf (asm_out_file, "\t! Cache block size\t: %d\n", - nds32_cache_block_size); - - fprintf (asm_out_file, "\t! ------------------------------------\n"); - - nds32_asm_file_start_for_isr (); -} - -static void -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 -nds32_asm_globalize_label (FILE *stream, const char *name) -{ - fputs ("\t.global\t", stream); - assemble_name (stream, name); - fputs ("\n", stream); -} - -/* -- Output of Assembler Instructions. */ - -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; - - if (CONST_INT_P (x)) - op_value = INTVAL (x); - - switch (code) - { - case 0 : - /* Do nothing special. */ - break; - - case 'b': - /* Use exact_log2() to search the 0-bit position. */ - gcc_assert (CONST_INT_P (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); - - /* 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 - { - /* If user applies normal way with __NDS32_REG_XXX__ enum data, - we can print out register name. Remember to substract 1024. */ - fprintf (stream, "%s", - nds32_intrinsic_register_names[op_value - 1024]); - } - - /* 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"); - break; - } - - 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. */ - 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); - 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. */ - debug_rtx (x); - gcc_unreachable (); - break; - } -} - -static void -nds32_print_operand_address (FILE *stream, - machine_mode mode ATTRIBUTE_UNUSED, - rtx x) -{ - rtx op0, op1; - - switch (GET_CODE (x)) - { - case SYMBOL_REF: - case CONST: - /* [ + symbol_ref] */ - /* [ + const_addr], where const_addr = symbol_ref + const_int */ - fputs ("[ + ", stream); - output_addr_const (stream, 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. */ - 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)]); - break; - - case PLUS: - op0 = XEXP (x, 0); - op1 = XEXP (x, 1); - - /* Checking op0, forbid using static chain register ($r16) - 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. */ - if (TARGET_REDUCED_REGS - && REG_P (op1) - && REGNO (op1) == STATIC_CHAIN_REGNUM) - sorry ("a nested function is not supported for reduced registers"); - - if (REG_P (op0) && CONST_INT_P (op1)) - { - /* [Ra + imm] */ - fprintf (stream, "[%s + (" HOST_WIDE_INT_PRINT_DEC ")]", - reg_names[REGNO (op0)], INTVAL (op1)); - } - else if (REG_P (op0) && REG_P (op1)) - { - /* [Ra + Rb] */ - fprintf (stream, "[%s + %s]", - reg_names[REGNO (op0)], reg_names[REGNO (op1)]); - } - else if (GET_CODE (op0) == MULT && REG_P (op1)) - { - /* [Ra + Rb << sv] - From observation, the pattern looks like: - (plus:SI (mult:SI (reg:SI 58) - (const_int 4 [0x4])) - (reg/f:SI 57)) */ - int sv; - - /* We need to set sv to output shift value. */ - if (INTVAL (XEXP (op0, 1)) == 1) - sv = 0; - else if (INTVAL (XEXP (op0, 1)) == 2) - sv = 1; - else if (INTVAL (XEXP (op0, 1)) == 4) - sv = 2; - else if (INTVAL (XEXP (op0, 1)) == 8) - sv = 3; - else - gcc_unreachable (); - - fprintf (stream, "[%s + %s << %d]", - reg_names[REGNO (op1)], - 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. */ - debug_rtx (x); - gcc_unreachable (); - } - - break; - - 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. */ - 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. */ - 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. */ - if (TARGET_REDUCED_REGS - && REG_P (op1) - && REGNO (op1) == STATIC_CHAIN_REGNUM) - sorry ("a nested function is not supported for reduced registers"); - - if (REG_P (op0) && REG_P (op1)) - { - /* [Ra], Rb */ - fprintf (stream, "[%s], %s", - reg_names[REGNO (op0)], reg_names[REGNO (op1)]); - } - else if (REG_P (op0) && CONST_INT_P (op1)) - { - /* [Ra], imm */ - fprintf (stream, "[%s], " HOST_WIDE_INT_PRINT_DEC, - reg_names[REGNO (op0)], INTVAL (op1)); - } - else - { - /* The control flow is not supposed to be here. */ - debug_rtx (x); - gcc_unreachable (); - } - - break; - - case POST_INC: - case POST_DEC: - op0 = XEXP (x, 0); - - /* Checking op0, forbid using static chain register ($r16) - 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"); - - if (REG_P (op0)) - { - /* "[Ra], 1/2/4" or "[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. */ - fprintf (stream, "[%s]", reg_names[REGNO (op0)]); - } - else - { - /* The control flow is not supposed to be here. */ - debug_rtx (x); - gcc_unreachable (); - } - - 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. */ - 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; - 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 (GET_MODE_SIZE (mode) <= UNITS_PER_WORD) - { - return NULL_RTX; - } - 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__. */ - -/* Add some checking after merging attributes. */ -static tree -nds32_merge_decl_attributes (tree olddecl, tree newdecl) -{ - tree combined_attrs; - - /* Create combined attributes. */ - combined_attrs = merge_attributes (DECL_ATTRIBUTES (olddecl), - DECL_ATTRIBUTES (newdecl)); - - /* Since newdecl is acutally a duplicate of olddecl, - we can take olddecl for some operations. */ - if (TREE_CODE (olddecl) == FUNCTION_DECL) - { - /* Check isr-specific attributes conflict. */ - nds32_check_isr_attrs_conflict (olddecl, combined_attrs); - } - - return combined_attrs; -} - -/* Add some checking when inserting attributes. */ -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. - 3. Check valid integer value for reset. - 4. Check valid function for nmi/warm. */ - if (TREE_CODE (decl) == FUNCTION_DECL) - { - tree func_attrs; - tree intr, excp, reset; - - /* Pick up function attributes. */ - func_attrs = *attributes; - - /* 1. Call nds32_check_isr_attrs_conflict() to check any conflict. */ - 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(). */ - 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. */ - tree id_list; - unsigned int lower_bound, upper_bound; - - /* The way to handle interrupt or exception is the same, - we just need to take care of actual vector number. - For interrupt(0..63), the actual vector number is (9..72). - For exception(1..8), the actual vector number is (1..8). */ - lower_bound = (intr) ? (0) : (1); - upper_bound = (intr) ? (63) : (8); - - /* Prepare id list so that we can traverse id value. */ - id_list = (intr) ? (TREE_VALUE (intr)) : (TREE_VALUE (excp)); - - /* 2. Check valid integer value for interrupt/exception. */ - while (id_list) - { - tree id; - - /* Pick up each vector id value. */ - id = TREE_VALUE (id_list); - /* Issue error if it is not a valid integer value. */ - if (TREE_CODE (id) != INTEGER_CST - || wi::ltu_p (wi::to_wide (id), lower_bound) - || wi::gtu_p (wi::to_wide (id), upper_bound)) - error ("invalid id value for interrupt/exception attribute"); - - /* Advance to next id. */ - id_list = TREE_CHAIN (id_list); - } - } - else if (reset) - { - /* Deal with reset. */ - tree id_list; - tree id; - tree nmi, warm; - unsigned int lower_bound; - unsigned int upper_bound; - - /* Prepare id_list and identify id value so that - we can check if total number of vectors is valid. */ - id_list = TREE_VALUE (reset); - id = TREE_VALUE (id_list); - - /* The maximum numbers for user's interrupt is 64. */ - lower_bound = 0; - upper_bound = 64; - - /* 3. Check valid integer value for reset. */ - if (TREE_CODE (id) != INTEGER_CST - || wi::ltu_p (wi::to_wide (id), lower_bound) - || wi::gtu_p (wi::to_wide (id), upper_bound)) - error ("invalid id value for reset attribute"); - - /* 4. Check valid function for nmi/warm. */ - nmi = lookup_attribute ("nmi", func_attrs); - warm = lookup_attribute ("warm", func_attrs); - - if (nmi != NULL_TREE) - { - tree nmi_func_list; - tree nmi_func; - - nmi_func_list = TREE_VALUE (nmi); - nmi_func = TREE_VALUE (nmi_func_list); - - /* Issue error if it is not a valid nmi function. */ - if (TREE_CODE (nmi_func) != IDENTIFIER_NODE) - error ("invalid nmi function for reset attribute"); - } - - if (warm != NULL_TREE) - { - tree warm_func_list; - tree warm_func; - - warm_func_list = TREE_VALUE (warm); - warm_func = TREE_VALUE (warm_func_list); - - /* Issue error if it is not a valid warm function. */ - if (TREE_CODE (warm_func) != IDENTIFIER_NODE) - error ("invalid warm function for reset attribute"); - } - } - else - { - /* No interrupt, exception, or reset attribute is set. */ - return; - } - } -} - -static bool -nds32_option_pragma_parse (tree args ATTRIBUTE_UNUSED, - tree pop_target ATTRIBUTE_UNUSED) -{ - /* Currently, we do not parse any pragma target by ourself, - so just simply return false. */ - return false; -} - -static void -nds32_option_override (void) -{ - /* After all the command options have been parsed, - we shall deal with some flags for changing compiler settings. */ - - /* At first, we check if we have to strictly - set some flags based on ISA family. */ - if (TARGET_ISA_V2) - { - /* Under V2 ISA, we need to strictly disable TARGET_V3PUSH. */ - target_flags &= ~MASK_V3PUSH; - } - if (TARGET_ISA_V3) - { - /* 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_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: - $r0~$r5, $r6~$r10, $r15, $r28, $r29, $r30, $r31 - If so, we must forbid using $r11~$r14, $r16~$r27. */ - if (TARGET_REDUCED_REGS) - { - int r; - - /* Prevent register allocator from - 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; - } - - 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_init_rtx_costs (); - - nds32_register_passes (); -} - - -/* Miscellaneous Parameters. */ - -static rtx_insn * -nds32_md_asm_adjust (vec<rtx> &outputs ATTRIBUTE_UNUSED, - vec<rtx> &inputs ATTRIBUTE_UNUSED, - vec<machine_mode> &input_modes ATTRIBUTE_UNUSED, - vec<const char *> &constraints ATTRIBUTE_UNUSED, - vec<rtx> &clobbers, HARD_REG_SET &clobbered_regs, - location_t /*loc*/) -{ - if (!flag_inline_asm_r15) - { - clobbers.safe_push (gen_rtx_REG (SImode, TA_REGNUM)); - SET_HARD_REG_BIT (clobbered_regs, TA_REGNUM); - } - return NULL; -} - -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, - int ignore) -{ - 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); -} - -/* ------------------------------------------------------------------------ */ - -/* PART 4: 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 (TARGET_BIG_ENDIAN) - builtin_define ("__big_endian__"); - - builtin_assert ("cpu=nds32"); - builtin_assert ("machine=nds32"); - - if (TARGET_HARD_FLOAT) - builtin_define ("__NDS32_ABI_2FP_PLUS"); - else - builtin_define ("__NDS32_ABI_2"); - -#undef builtin_define -#undef builtin_assert -} - - -/* Defining Data Structures for Per-function Information. */ - -void -nds32_init_expanders (void) -{ - /* Arrange to initialize and mark the machine per-function status. */ - init_machine_status = nds32_init_machine_status; -} - - -/* 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. */ - -static unsigned -nds32_hard_regno_nregs (unsigned regno ATTRIBUTE_UNUSED, - machine_mode mode) -{ - return ((GET_MODE_SIZE (mode) + UNITS_PER_WORD - 1) / UNITS_PER_WORD); -} - -/* Implement TARGET_HARD_REGNO_MODE_OK. */ - -static bool -nds32_hard_regno_mode_ok (unsigned int regno, 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 (regno <= NDS32_LAST_GPR_REGNUM) - return (targetm.hard_regno_nregs (regno, mode) == 1 - || !((regno) & 1)); - - return false; -} - -/* Implement TARGET_MODES_TIEABLE_P. We can use general registers to - tie QI/HI/SI modes together. */ - -static bool -nds32_modes_tieable_p (machine_mode mode1, 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. */ - -enum reg_class -nds32_regno_reg_class (int regno) -{ - /* Refer to nds32.h for more register class details. */ - - if (regno >= 0 && regno <= 7) - return LOW_REGS; - else if (regno >= 8 && regno <= 11) - return MIDDLE_REGS; - else if (regno >= 12 && regno <= 14) - return HIGH_REGS; - else if (regno == 15) - return R15_TA_REG; - else if (regno >= 16 && regno <= 19) - return MIDDLE_REGS; - else if (regno >= 20 && regno <= 31) - return HIGH_REGS; - else if (regno == 32 || regno == 33) - { - /* $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 - return NO_REGS; -} - - -/* Stack Layout and Calling Conventions. */ - -/* -- 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) -{ - int offset; - rtx addr; - - if (count != 0) - { - /* 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). */ - return get_hard_reg_initial_val (Pmode, LP_REGNUM); -} - -/* -- Eliminating Frame Pointer and Arg Pointer. */ - -HOST_WIDE_INT -nds32_initial_elimination_offset (unsigned int from_reg, unsigned int to_reg) -{ - HOST_WIDE_INT offset; - - /* Compute and setup stack frame size. - The result will be in cfun->machine. */ - nds32_compute_stack_frame (); - - /* Remember to consider - 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->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); - } - else if (from_reg == ARG_POINTER_REGNUM - && to_reg == HARD_FRAME_POINTER_REGNUM) - { - offset = 0; - } - else if (from_reg == FRAME_POINTER_REGNUM - && to_reg == STACK_POINTER_REGNUM) - { - offset = (cfun->machine->local_size + cfun->machine->out_args_size); - } - else if (from_reg == FRAME_POINTER_REGNUM - && to_reg == HARD_FRAME_POINTER_REGNUM) - { - offset = (-1) * (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); - } - else - { - gcc_unreachable (); - } - - return offset; -} - -/* -- Passing Arguments in Registers. */ - -void -nds32_init_cumulative_args (CUMULATIVE_ARGS *cum, - tree fntype ATTRIBUTE_UNUSED, - rtx libname ATTRIBUTE_UNUSED, - tree fndecl ATTRIBUTE_UNUSED, - int n_named_args ATTRIBUTE_UNUSED) -{ - /* 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. */ - -/* Function for normal multiple push prologue. */ -void -nds32_expand_prologue (void) -{ - int fp_adjust; - int sp_adjust; - 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 = 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. */ - if (cfun->machine->va_args_area_padding_bytes) - { - /* Generate sp adjustment instruction. */ - sp_adjust = cfun->machine->va_args_area_padding_bytes; - - 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 && !flag_pic) - return; - - /* Get callee_first_regno and callee_last_regno. */ - 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 (!(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, - 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) - + (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, - -1 * sp_adjust); - - /* 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); - } - } - else - { - /* 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; - - /* 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); - } - - /* 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. */ -void -nds32_expand_epilogue (bool sibcall_p) -{ - int sp_adjust; - unsigned Rb, Re; - - /* Compute and setup stack frame size. - The result will be in cfun->machine. */ - nds32_compute_stack_frame (); - - /* 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. - However, if this function is also a variadic function, - we need to create adjust stack pointer before 'ret' instruction. */ - 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. */ - 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; - - 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(). */ - if (!sibcall_p) - { - /* 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) - { - /* 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, - -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; - - nds32_emit_adjust_frame (stack_pointer_rtx, - hard_frame_pointer_rtx, - -1 * sp_adjust); - } - } - else - { - /* 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. */ - sp_adjust = cfun->machine->local_size - + cfun->machine->out_args_size; - - 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 = 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 (!(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, - 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 - 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; - - 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. */ - if (!sibcall_p) - emit_jump_insn (gen_return_internal ()); -} - -/* Function for v3push prologue. */ -void -nds32_expand_prologue_v3push (void) -{ - int fp_adjust; - int sp_adjust; - 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 && !flag_pic) - return; - - /* Get callee_first_regno and callee_last_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_fpr_regs_size; - - if (satisfies_constraint_Iu08 (GEN_INT (sp_adjust)) - && NDS32_DOUBLE_WORD_ALIGN_P (sp_adjust)) - { - /* We can use 'push25 Re,imm8u'. */ - - /* nds32_emit_stack_v3push(last_regno, 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 (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') - 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. */ - fp_adjust = cfun->machine->fp_size - + cfun->machine->gp_size - + cfun->machine->lp_size - + cfun->machine->callee_saved_gpr_regs_size - + sp_adjust; - - nds32_emit_adjust_frame (hard_frame_pointer_rtx, - stack_pointer_rtx, - fp_adjust); - } - } - else - { - 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. */ - nds32_emit_stack_v3push (Rb, Re, 0); - } - - /* Check frame_pointer_needed to see - 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) - 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. */ - fp_adjust = cfun->machine->fp_size - + cfun->machine->gp_size - + cfun->machine->lp_size - + cfun->machine->callee_saved_gpr_regs_size; - - 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); - } - - 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 ()); -} - -/* Function for v3pop epilogue. */ -void -nds32_expand_epilogue_v3pop (bool sibcall_p) -{ - int sp_adjust; - 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 the function is 'naked', we do not have to generate - epilogue code fragment BUT 'ret' instruction. */ - if (cfun->machine->naked_p) - { - /* Generate return instruction by using 'return_internal' pattern. - Make sure this instruction is after gen_blockage(). - First we need to check this is a function without sibling call. */ - if (!sibcall_p) - { - /* 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 = 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_fpr_regs_size; - - /* 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'. - Of course, the frame_pointer_needed should be nonzero - if the function calls alloca(). */ - if (satisfies_constraint_Iu08 (GEN_INT (sp_adjust)) - && 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. */ - 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. */ - - if (frame_pointer_needed) - { - /* adjust $sp = $fp - 4 ($fp size) - - 4 ($gp size) - - 4 ($lp size) - - (4 * n) (callee-saved 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; - - /* 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, - -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. */ - - /* 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; - - /* 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 - { - /* 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); - } - } - - 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 ()); -} - -/* 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. */ -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 cannot 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. - 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)); -} - -scalar_int_mode -nds32_case_vector_shorten_mode (int min_offset, int max_offset, - rtx body ATTRIBUTE_UNUSED) -{ - if (min_offset < 0 || max_offset >= 0x2000) - return SImode; - else - { - /* 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; - } -} - -/* ------------------------------------------------------------------------ */ - -/* Return alignment for the label. */ -int -nds32_target_alignment (rtx_insn *label) -{ - rtx_insn *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. */ -static HOST_WIDE_INT -nds32_constant_alignment (const_tree constant, - HOST_WIDE_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 ARRAY_TYPE: - case RECORD_TYPE: - case UNION_TYPE: - at_least_align_to_word = true; - break; - default: - at_least_align_to_word = false; - break; - } - if (at_least_align_to_word - && (basic_align < BITS_PER_WORD)) - return BITS_PER_WORD; - else - return basic_align; -} - -bool -nds32_split_double_word_load_store_p(rtx *operands, bool load_p) -{ - 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); - - /* Split double word load store after copy propgation. */ - if (current_pass == NULL) - return false; - - const char *pass_name = current_pass->name; - if (pass_name && ((strcmp (pass_name, "split3") == 0) - || (strcmp (pass_name, "split5") == 0))) - return !satisfies_constraint_Da (mem) || MEM_VOLATILE_P (mem); - - return false; -} - -static bool -nds32_use_blocks_for_constant_p (machine_mode mode, - const_rtx x ATTRIBUTE_UNUSED) -{ - if ((TARGET_FPU_SINGLE || TARGET_FPU_DOUBLE) - && (mode == DFmode || mode == SFmode)) - return true; - else - return false; -} - -/* ------------------------------------------------------------------------ */ - -/* PART 5: Initialize target hook structure and definitions. */ - -/* Controlling the Compilation Driver. */ - - -/* Run-time Target Specification. */ - - -/* Defining Data Structures for Per-function Information. */ - - -/* Storage Layout. */ - -#undef TARGET_PROMOTE_FUNCTION_MODE -#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 - -#undef TARGET_CONSTANT_ALIGNMENT -#define TARGET_CONSTANT_ALIGNMENT nds32_constant_alignment - - -/* Layout of Source Language Data Types. */ - - -/* Register Usage. */ - -/* -- 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. */ - -#undef TARGET_HARD_REGNO_NREGS -#define TARGET_HARD_REGNO_NREGS nds32_hard_regno_nregs - -#undef TARGET_HARD_REGNO_MODE_OK -#define TARGET_HARD_REGNO_MODE_OK nds32_hard_regno_mode_ok - -#undef TARGET_MODES_TIEABLE_P -#define TARGET_MODES_TIEABLE_P nds32_modes_tieable_p - -/* -- Handling Leaf Functions. */ - -/* -- Registers That Form a Stack. */ - - -/* Register Classes. */ - -#undef TARGET_CLASS_MAX_NREGS -#define TARGET_CLASS_MAX_NREGS nds32_class_max_nregs - -#undef TARGET_REGISTER_PRIORITY -#define TARGET_REGISTER_PRIORITY nds32_register_priority - -#undef TARGET_CAN_CHANGE_MODE_CLASS -#define TARGET_CAN_CHANGE_MODE_CLASS nds32_can_change_mode_class - - -/* Obsolete Macros for Defining Constraints. */ - - -/* Stack Layout and Calling Conventions. */ - -/* -- Basic Stack Layout. */ - -/* -- Exception Handling Support. */ - -/* -- Specifying How Stack Checking is Done. */ - -/* -- Registers That Address the Stack Frame. */ - -/* -- Eliminating Frame Pointer and Arg Pointer. */ - -#undef TARGET_CAN_ELIMINATE -#define TARGET_CAN_ELIMINATE nds32_can_eliminate - -/* -- Passing Function Arguments on the Stack. */ - -/* -- Passing Arguments in Registers. */ - -#undef TARGET_FUNCTION_ARG -#define TARGET_FUNCTION_ARG nds32_function_arg - -#undef TARGET_MUST_PASS_IN_STACK -#define TARGET_MUST_PASS_IN_STACK nds32_must_pass_in_stack - -#undef TARGET_ARG_PARTIAL_BYTES -#define TARGET_ARG_PARTIAL_BYTES nds32_arg_partial_bytes - -#undef TARGET_FUNCTION_ARG_ADVANCE -#define TARGET_FUNCTION_ARG_ADVANCE nds32_function_arg_advance - -#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 -#define TARGET_FUNCTION_VALUE nds32_function_value - -#undef TARGET_LIBCALL_VALUE -#define TARGET_LIBCALL_VALUE nds32_libcall_value - -#undef TARGET_FUNCTION_VALUE_REGNO_P -#define TARGET_FUNCTION_VALUE_REGNO_P nds32_function_value_regno_p - -/* -- 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. */ - -#undef TARGET_ASM_FUNCTION_PROLOGUE -#define TARGET_ASM_FUNCTION_PROLOGUE nds32_asm_function_prologue - -#undef TARGET_ASM_FUNCTION_END_PROLOGUE -#define TARGET_ASM_FUNCTION_END_PROLOGUE nds32_asm_function_end_prologue - -#undef TARGET_ASM_FUNCTION_BEGIN_EPILOGUE -#define TARGET_ASM_FUNCTION_BEGIN_EPILOGUE nds32_asm_function_begin_epilogue - -#undef TARGET_ASM_FUNCTION_EPILOGUE -#define TARGET_ASM_FUNCTION_EPILOGUE nds32_asm_function_epilogue - -#undef TARGET_ASM_OUTPUT_MI_THUNK -#define TARGET_ASM_OUTPUT_MI_THUNK nds32_asm_output_mi_thunk - -#undef TARGET_ASM_CAN_OUTPUT_MI_THUNK -#define TARGET_ASM_CAN_OUTPUT_MI_THUNK default_can_output_mi_thunk_no_vcall - -/* -- Generating Code for Profiling. */ - -/* -- 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 - -/* Stack smashing protection. */ - - -/* Implementing the Varargs Macros. */ - -#undef TARGET_SETUP_INCOMING_VARARGS -#define TARGET_SETUP_INCOMING_VARARGS nds32_setup_incoming_varargs - -#undef TARGET_STRICT_ARGUMENT_NAMING -#define TARGET_STRICT_ARGUMENT_NAMING nds32_strict_argument_naming - - -/* Trampolines for Nested Functions. */ - -#undef TARGET_ASM_TRAMPOLINE_TEMPLATE -#define TARGET_ASM_TRAMPOLINE_TEMPLATE nds32_asm_trampoline_template - -#undef TARGET_TRAMPOLINE_INIT -#define TARGET_TRAMPOLINE_INIT nds32_trampoline_init - - -/* Implicit Calls to Library Routines. */ - - -/* Addressing Modes. */ - -#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. */ - - -/* Condition Code Status. */ - -/* -- Representation of condition codes using (cc0). */ - -/* -- Representation of condition codes using registers. */ - -#undef TARGET_CANONICALIZE_COMPARISON -#define TARGET_CANONICALIZE_COMPARISON nds32_canonicalize_comparison - -/* -- Macros to control conditional execution. */ - - -/* Describing Relative Costs of Operations. */ - -#undef TARGET_REGISTER_MOVE_COST -#define TARGET_REGISTER_MOVE_COST nds32_register_move_cost - -#undef TARGET_MEMORY_MOVE_COST -#define TARGET_MEMORY_MOVE_COST nds32_memory_move_cost - -#undef TARGET_RTX_COSTS -#define TARGET_RTX_COSTS nds32_rtx_costs - -#undef TARGET_ADDRESS_COST -#define TARGET_ADDRESS_COST nds32_address_cost - - -/* Adjusting the Instruction Scheduler. */ - - -/* Dividing the Output into Sections (Texts, Data, . . . ). */ - -#undef TARGET_ENCODE_SECTION_INFO -#define TARGET_ENCODE_SECTION_INFO nds32_encode_section_info - - -/* Position Independent Code. */ - - -/* Defining the Output Assembler Language. */ - -/* -- The Overall Framework of an Assembler File. */ - -#undef TARGET_ASM_FILE_START -#define TARGET_ASM_FILE_START nds32_asm_file_start -#undef TARGET_ASM_FILE_END -#define TARGET_ASM_FILE_END nds32_asm_file_end - -/* -- Output of Data. */ - -#undef TARGET_ASM_ALIGNED_HI_OP -#define TARGET_ASM_ALIGNED_HI_OP "\t.hword\t" - -#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. */ - -#undef TARGET_ASM_GLOBALIZE_LABEL -#define TARGET_ASM_GLOBALIZE_LABEL nds32_asm_globalize_label - -/* -- How Initialization Functions Are Handled. */ - -/* -- Macros Controlling Initialization Routines. */ - -/* -- Output of Assembler Instructions. */ - -#undef TARGET_PRINT_OPERAND -#define TARGET_PRINT_OPERAND nds32_print_operand -#undef TARGET_PRINT_OPERAND_ADDRESS -#define TARGET_PRINT_OPERAND_ADDRESS nds32_print_operand_address - -/* -- Output of Dispatch Tables. */ - -/* -- Assembler Commands for Exception Regions. */ - -#undef TARGET_DWARF_REGISTER_SPAN -#define TARGET_DWARF_REGISTER_SPAN nds32_dwarf_register_span - -/* -- Assembler Commands for Alignment. */ - - -/* Controlling Debugging Information Format. */ - -/* -- Macros Affecting All Debugging Formats. */ - -/* -- Specific Options for DBX Output. */ - -/* -- Open-Ended Hooks for DBX Format. */ - -/* -- File Names in DBX Format. */ - -/* -- Macros for DWARF Output. */ - -/* -- Macros for VMS Debug Format. */ - - -/* Cross Compilation and Floating Point. */ - - -/* Mode Switching Instructions. */ - - -/* Defining target-specific uses of __attribute__. */ - -#undef TARGET_ATTRIBUTE_TABLE -#define TARGET_ATTRIBUTE_TABLE nds32_attribute_table - -#undef TARGET_MERGE_DECL_ATTRIBUTES -#define TARGET_MERGE_DECL_ATTRIBUTES nds32_merge_decl_attributes - -#undef TARGET_INSERT_ATTRIBUTES -#define TARGET_INSERT_ATTRIBUTES nds32_insert_attributes - -#undef TARGET_OPTION_PRAGMA_PARSE -#define TARGET_OPTION_PRAGMA_PARSE nds32_option_pragma_parse - -#undef TARGET_OPTION_OVERRIDE -#define TARGET_OPTION_OVERRIDE nds32_option_override - - -/* Emulating TLS. */ - -#undef TARGET_HAVE_TLS -#define TARGET_HAVE_TLS TARGET_LINUX_ABI - - -/* Defining coprocessor specifics for MIPS targets. */ - - -/* Parameters for Precompiled Header Validity Checking. */ - - -/* C++ ABI parameters. */ - - -/* Adding support for named address spaces. */ - - -/* Miscellaneous Parameters. */ - -#undef TARGET_MD_ASM_ADJUST -#define TARGET_MD_ASM_ADJUST nds32_md_asm_adjust - -#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_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 - -#undef TARGET_HAVE_SPECULATION_SAFE_VALUE -#define TARGET_HAVE_SPECULATION_SAFE_VALUE speculation_safe_value_not_needed - - -/* ------------------------------------------------------------------------ */ - -/* Initialize the GCC target structure. */ - -struct gcc_target targetm = TARGET_INITIALIZER; - -/* ------------------------------------------------------------------------ */ |