aboutsummaryrefslogtreecommitdiff
path: root/gcc/config/nds32/nds32.c
diff options
context:
space:
mode:
authorMartin Liska <mliska@suse.cz>2022-01-14 16:56:44 +0100
committerMartin Liska <mliska@suse.cz>2022-01-17 22:12:04 +0100
commit5c69acb32329d49e58c26fa41ae74229a52b9106 (patch)
treeddb05f9d73afb6f998457d2ac4b720e3b3b60483 /gcc/config/nds32/nds32.c
parent490e23032baaece71f2ec09fa1805064b150fbc2 (diff)
downloadgcc-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.c5895
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;
-
-/* ------------------------------------------------------------------------ */