aboutsummaryrefslogtreecommitdiff
path: root/gcc/final.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/final.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/final.c')
-rw-r--r--gcc/final.c4662
1 files changed, 0 insertions, 4662 deletions
diff --git a/gcc/final.c b/gcc/final.c
deleted file mode 100644
index 296a938..0000000
--- a/gcc/final.c
+++ /dev/null
@@ -1,4662 +0,0 @@
-/* Convert RTL to assembler code and output it, for GNU compiler.
- Copyright (C) 1987-2022 Free Software Foundation, Inc.
-
-This file is part of GCC.
-
-GCC is free software; you can redistribute it and/or modify it under
-the terms of the GNU General Public License as published by the Free
-Software Foundation; either version 3, or (at your option) any later
-version.
-
-GCC is distributed in the hope that it will be useful, but WITHOUT ANY
-WARRANTY; without even the implied warranty of MERCHANTABILITY or
-FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
-for more details.
-
-You should have received a copy of the GNU General Public License
-along with GCC; see the file COPYING3. If not see
-<http://www.gnu.org/licenses/>. */
-
-/* This is the final pass of the compiler.
- It looks at the rtl code for a function and outputs assembler code.
-
- Call `final_start_function' to output the assembler code for function entry,
- `final' to output assembler code for some RTL code,
- `final_end_function' to output assembler code for function exit.
- If a function is compiled in several pieces, each piece is
- output separately with `final'.
-
- Some optimizations are also done at this level.
- Move instructions that were made unnecessary by good register allocation
- are detected and omitted from the output. (Though most of these
- are removed by the last jump pass.)
-
- Instructions to set the condition codes are omitted when it can be
- seen that the condition codes already had the desired values.
-
- In some cases it is sufficient if the inherited condition codes
- have related values, but this may require the following insn
- (the one that tests the condition codes) to be modified.
-
- The code for the function prologue and epilogue are generated
- directly in assembler by the target functions function_prologue and
- function_epilogue. Those instructions never exist as rtl. */
-
-#include "config.h"
-#define INCLUDE_ALGORITHM /* reverse */
-#include "system.h"
-#include "coretypes.h"
-#include "backend.h"
-#include "target.h"
-#include "rtl.h"
-#include "tree.h"
-#include "cfghooks.h"
-#include "df.h"
-#include "memmodel.h"
-#include "tm_p.h"
-#include "insn-config.h"
-#include "regs.h"
-#include "emit-rtl.h"
-#include "recog.h"
-#include "cgraph.h"
-#include "tree-pretty-print.h" /* for dump_function_header */
-#include "varasm.h"
-#include "insn-attr.h"
-#include "conditions.h"
-#include "flags.h"
-#include "output.h"
-#include "except.h"
-#include "rtl-error.h"
-#include "toplev.h" /* exact_log2, floor_log2 */
-#include "reload.h"
-#include "intl.h"
-#include "cfgrtl.h"
-#include "debug.h"
-#include "tree-pass.h"
-#include "tree-ssa.h"
-#include "cfgloop.h"
-#include "stringpool.h"
-#include "attribs.h"
-#include "asan.h"
-#include "rtl-iter.h"
-#include "print-rtl.h"
-#include "function-abi.h"
-#include "common/common-target.h"
-
-#ifdef XCOFF_DEBUGGING_INFO
-#include "xcoffout.h" /* Needed for external data declarations. */
-#endif
-
-#include "dwarf2out.h"
-
-#ifdef DBX_DEBUGGING_INFO
-#include "dbxout.h"
-#endif
-
-/* Most ports don't need to define CC_STATUS_INIT.
- So define a null default for it to save conditionalization later. */
-#ifndef CC_STATUS_INIT
-#define CC_STATUS_INIT
-#endif
-
-/* Is the given character a logical line separator for the assembler? */
-#ifndef IS_ASM_LOGICAL_LINE_SEPARATOR
-#define IS_ASM_LOGICAL_LINE_SEPARATOR(C, STR) ((C) == ';')
-#endif
-
-#ifndef JUMP_TABLES_IN_TEXT_SECTION
-#define JUMP_TABLES_IN_TEXT_SECTION 0
-#endif
-
-/* Bitflags used by final_scan_insn. */
-#define SEEN_NOTE 1
-#define SEEN_EMITTED 2
-#define SEEN_NEXT_VIEW 4
-
-/* Last insn processed by final_scan_insn. */
-static rtx_insn *debug_insn;
-rtx_insn *current_output_insn;
-
-/* Line number of last NOTE. */
-static int last_linenum;
-
-/* Column number of last NOTE. */
-static int last_columnnum;
-
-/* Discriminator written to assembly. */
-static int last_discriminator;
-
-/* Discriminator to be written to assembly for current instruction.
- Note: actual usage depends on loc_discriminator_kind setting. */
-static int discriminator;
-static inline int compute_discriminator (location_t loc);
-
-/* Discriminator identifying current basic block among others sharing
- the same locus. */
-static int bb_discriminator;
-
-/* Basic block discriminator for previous instruction. */
-static int last_bb_discriminator;
-
-/* Highest line number in current block. */
-static int high_block_linenum;
-
-/* Likewise for function. */
-static int high_function_linenum;
-
-/* Filename of last NOTE. */
-static const char *last_filename;
-
-/* Override filename, line and column number. */
-static const char *override_filename;
-static int override_linenum;
-static int override_columnnum;
-static int override_discriminator;
-
-/* Whether to force emission of a line note before the next insn. */
-static bool force_source_line = false;
-
-extern const int length_unit_log; /* This is defined in insn-attrtab.c. */
-
-/* Nonzero while outputting an `asm' with operands.
- This means that inconsistencies are the user's fault, so don't die.
- The precise value is the insn being output, to pass to error_for_asm. */
-const rtx_insn *this_is_asm_operands;
-
-/* Number of operands of this insn, for an `asm' with operands. */
-static unsigned int insn_noperands;
-
-/* Compare optimization flag. */
-
-static rtx last_ignored_compare = 0;
-
-/* Assign a unique number to each insn that is output.
- This can be used to generate unique local labels. */
-
-static int insn_counter = 0;
-
-/* Number of unmatched NOTE_INSN_BLOCK_BEG notes we have seen. */
-
-static int block_depth;
-
-/* Nonzero if have enabled APP processing of our assembler output. */
-
-static int app_on;
-
-/* If we are outputting an insn sequence, this contains the sequence rtx.
- Zero otherwise. */
-
-rtx_sequence *final_sequence;
-
-#ifdef ASSEMBLER_DIALECT
-
-/* Number of the assembler dialect to use, starting at 0. */
-static int dialect_number;
-#endif
-
-/* Nonnull if the insn currently being emitted was a COND_EXEC pattern. */
-rtx current_insn_predicate;
-
-/* True if printing into -fdump-final-insns= dump. */
-bool final_insns_dump_p;
-
-/* True if profile_function should be called, but hasn't been called yet. */
-static bool need_profile_function;
-
-static int asm_insn_count (rtx);
-static void profile_function (FILE *);
-static void profile_after_prologue (FILE *);
-static bool notice_source_line (rtx_insn *, bool *);
-static rtx walk_alter_subreg (rtx *, bool *);
-static void output_asm_name (void);
-static void output_alternate_entry_point (FILE *, rtx_insn *);
-static tree get_mem_expr_from_op (rtx, int *);
-static void output_asm_operand_names (rtx *, int *, int);
-#ifdef LEAF_REGISTERS
-static void leaf_renumber_regs (rtx_insn *);
-#endif
-static int align_fuzz (rtx, rtx, int, unsigned);
-static void collect_fn_hard_reg_usage (void);
-
-/* Initialize data in final at the beginning of a compilation. */
-
-void
-init_final (const char *filename ATTRIBUTE_UNUSED)
-{
- app_on = 0;
- final_sequence = 0;
-
-#ifdef ASSEMBLER_DIALECT
- dialect_number = ASSEMBLER_DIALECT;
-#endif
-}
-
-/* Default target function prologue and epilogue assembler output.
-
- If not overridden for epilogue code, then the function body itself
- contains return instructions wherever needed. */
-void
-default_function_pro_epilogue (FILE *)
-{
-}
-
-void
-default_function_switched_text_sections (FILE *file ATTRIBUTE_UNUSED,
- tree decl ATTRIBUTE_UNUSED,
- bool new_is_cold ATTRIBUTE_UNUSED)
-{
-}
-
-/* Default target hook that outputs nothing to a stream. */
-void
-no_asm_to_stream (FILE *file ATTRIBUTE_UNUSED)
-{
-}
-
-/* Enable APP processing of subsequent output.
- Used before the output from an `asm' statement. */
-
-void
-app_enable (void)
-{
- if (! app_on)
- {
- fputs (ASM_APP_ON, asm_out_file);
- app_on = 1;
- }
-}
-
-/* Disable APP processing of subsequent output.
- Called from varasm.c before most kinds of output. */
-
-void
-app_disable (void)
-{
- if (app_on)
- {
- fputs (ASM_APP_OFF, asm_out_file);
- app_on = 0;
- }
-}
-
-/* Return the number of slots filled in the current
- delayed branch sequence (we don't count the insn needing the
- delay slot). Zero if not in a delayed branch sequence. */
-
-int
-dbr_sequence_length (void)
-{
- if (final_sequence != 0)
- return XVECLEN (final_sequence, 0) - 1;
- else
- return 0;
-}
-
-/* The next two pages contain routines used to compute the length of an insn
- and to shorten branches. */
-
-/* Arrays for insn lengths, and addresses. The latter is referenced by
- `insn_current_length'. */
-
-static int *insn_lengths;
-
-vec<int> insn_addresses_;
-
-/* Max uid for which the above arrays are valid. */
-static int insn_lengths_max_uid;
-
-/* Address of insn being processed. Used by `insn_current_length'. */
-int insn_current_address;
-
-/* Address of insn being processed in previous iteration. */
-int insn_last_address;
-
-/* known invariant alignment of insn being processed. */
-int insn_current_align;
-
-/* After shorten_branches, for any insn, uid_align[INSN_UID (insn)]
- gives the next following alignment insn that increases the known
- alignment, or NULL_RTX if there is no such insn.
- For any alignment obtained this way, we can again index uid_align with
- its uid to obtain the next following align that in turn increases the
- alignment, till we reach NULL_RTX; the sequence obtained this way
- for each insn we'll call the alignment chain of this insn in the following
- comments. */
-
-static rtx *uid_align;
-static int *uid_shuid;
-static vec<align_flags> label_align;
-
-/* Indicate that branch shortening hasn't yet been done. */
-
-void
-init_insn_lengths (void)
-{
- if (uid_shuid)
- {
- free (uid_shuid);
- uid_shuid = 0;
- }
- if (insn_lengths)
- {
- free (insn_lengths);
- insn_lengths = 0;
- insn_lengths_max_uid = 0;
- }
- if (HAVE_ATTR_length)
- INSN_ADDRESSES_FREE ();
- if (uid_align)
- {
- free (uid_align);
- uid_align = 0;
- }
-}
-
-/* Obtain the current length of an insn. If branch shortening has been done,
- get its actual length. Otherwise, use FALLBACK_FN to calculate the
- length. */
-static int
-get_attr_length_1 (rtx_insn *insn, int (*fallback_fn) (rtx_insn *))
-{
- rtx body;
- int i;
- int length = 0;
-
- if (!HAVE_ATTR_length)
- return 0;
-
- if (insn_lengths_max_uid > INSN_UID (insn))
- return insn_lengths[INSN_UID (insn)];
- else
- switch (GET_CODE (insn))
- {
- case NOTE:
- case BARRIER:
- case CODE_LABEL:
- case DEBUG_INSN:
- return 0;
-
- case CALL_INSN:
- case JUMP_INSN:
- length = fallback_fn (insn);
- break;
-
- case INSN:
- body = PATTERN (insn);
- if (GET_CODE (body) == USE || GET_CODE (body) == CLOBBER)
- return 0;
-
- else if (GET_CODE (body) == ASM_INPUT || asm_noperands (body) >= 0)
- length = asm_insn_count (body) * fallback_fn (insn);
- else if (rtx_sequence *seq = dyn_cast <rtx_sequence *> (body))
- for (i = 0; i < seq->len (); i++)
- length += get_attr_length_1 (seq->insn (i), fallback_fn);
- else
- length = fallback_fn (insn);
- break;
-
- default:
- break;
- }
-
-#ifdef ADJUST_INSN_LENGTH
- ADJUST_INSN_LENGTH (insn, length);
-#endif
- return length;
-}
-
-/* Obtain the current length of an insn. If branch shortening has been done,
- get its actual length. Otherwise, get its maximum length. */
-int
-get_attr_length (rtx_insn *insn)
-{
- return get_attr_length_1 (insn, insn_default_length);
-}
-
-/* Obtain the current length of an insn. If branch shortening has been done,
- get its actual length. Otherwise, get its minimum length. */
-int
-get_attr_min_length (rtx_insn *insn)
-{
- return get_attr_length_1 (insn, insn_min_length);
-}
-
-/* Code to handle alignment inside shorten_branches. */
-
-/* Here is an explanation how the algorithm in align_fuzz can give
- proper results:
-
- Call a sequence of instructions beginning with alignment point X
- and continuing until the next alignment point `block X'. When `X'
- is used in an expression, it means the alignment value of the
- alignment point.
-
- Call the distance between the start of the first insn of block X, and
- the end of the last insn of block X `IX', for the `inner size of X'.
- This is clearly the sum of the instruction lengths.
-
- Likewise with the next alignment-delimited block following X, which we
- shall call block Y.
-
- Call the distance between the start of the first insn of block X, and
- the start of the first insn of block Y `OX', for the `outer size of X'.
-
- The estimated padding is then OX - IX.
-
- OX can be safely estimated as
-
- if (X >= Y)
- OX = round_up(IX, Y)
- else
- OX = round_up(IX, X) + Y - X
-
- Clearly est(IX) >= real(IX), because that only depends on the
- instruction lengths, and those being overestimated is a given.
-
- Clearly round_up(foo, Z) >= round_up(bar, Z) if foo >= bar, so
- we needn't worry about that when thinking about OX.
-
- When X >= Y, the alignment provided by Y adds no uncertainty factor
- for branch ranges starting before X, so we can just round what we have.
- But when X < Y, we don't know anything about the, so to speak,
- `middle bits', so we have to assume the worst when aligning up from an
- address mod X to one mod Y, which is Y - X. */
-
-#ifndef LABEL_ALIGN
-#define LABEL_ALIGN(LABEL) align_labels
-#endif
-
-#ifndef LOOP_ALIGN
-#define LOOP_ALIGN(LABEL) align_loops
-#endif
-
-#ifndef LABEL_ALIGN_AFTER_BARRIER
-#define LABEL_ALIGN_AFTER_BARRIER(LABEL) 0
-#endif
-
-#ifndef JUMP_ALIGN
-#define JUMP_ALIGN(LABEL) align_jumps
-#endif
-
-#ifndef ADDR_VEC_ALIGN
-static int
-final_addr_vec_align (rtx_jump_table_data *addr_vec)
-{
- int align = GET_MODE_SIZE (addr_vec->get_data_mode ());
-
- if (align > BIGGEST_ALIGNMENT / BITS_PER_UNIT)
- align = BIGGEST_ALIGNMENT / BITS_PER_UNIT;
- return exact_log2 (align);
-
-}
-
-#define ADDR_VEC_ALIGN(ADDR_VEC) final_addr_vec_align (ADDR_VEC)
-#endif
-
-#ifndef INSN_LENGTH_ALIGNMENT
-#define INSN_LENGTH_ALIGNMENT(INSN) length_unit_log
-#endif
-
-#define INSN_SHUID(INSN) (uid_shuid[INSN_UID (INSN)])
-
-static int min_labelno, max_labelno;
-
-#define LABEL_TO_ALIGNMENT(LABEL) \
- (label_align[CODE_LABEL_NUMBER (LABEL) - min_labelno])
-
-/* For the benefit of port specific code do this also as a function. */
-
-align_flags
-label_to_alignment (rtx label)
-{
- if (CODE_LABEL_NUMBER (label) <= max_labelno)
- return LABEL_TO_ALIGNMENT (label);
- return align_flags ();
-}
-
-/* The differences in addresses
- between a branch and its target might grow or shrink depending on
- the alignment the start insn of the range (the branch for a forward
- branch or the label for a backward branch) starts out on; if these
- differences are used naively, they can even oscillate infinitely.
- We therefore want to compute a 'worst case' address difference that
- is independent of the alignment the start insn of the range end
- up on, and that is at least as large as the actual difference.
- The function align_fuzz calculates the amount we have to add to the
- naively computed difference, by traversing the part of the alignment
- chain of the start insn of the range that is in front of the end insn
- of the range, and considering for each alignment the maximum amount
- that it might contribute to a size increase.
-
- For casesi tables, we also want to know worst case minimum amounts of
- address difference, in case a machine description wants to introduce
- some common offset that is added to all offsets in a table.
- For this purpose, align_fuzz with a growth argument of 0 computes the
- appropriate adjustment. */
-
-/* Compute the maximum delta by which the difference of the addresses of
- START and END might grow / shrink due to a different address for start
- which changes the size of alignment insns between START and END.
- KNOWN_ALIGN_LOG is the alignment known for START.
- GROWTH should be ~0 if the objective is to compute potential code size
- increase, and 0 if the objective is to compute potential shrink.
- The return value is undefined for any other value of GROWTH. */
-
-static int
-align_fuzz (rtx start, rtx end, int known_align_log, unsigned int growth)
-{
- int uid = INSN_UID (start);
- rtx align_label;
- int known_align = 1 << known_align_log;
- int end_shuid = INSN_SHUID (end);
- int fuzz = 0;
-
- for (align_label = uid_align[uid]; align_label; align_label = uid_align[uid])
- {
- int align_addr, new_align;
-
- uid = INSN_UID (align_label);
- align_addr = INSN_ADDRESSES (uid) - insn_lengths[uid];
- if (uid_shuid[uid] > end_shuid)
- break;
- align_flags alignment = LABEL_TO_ALIGNMENT (align_label);
- new_align = 1 << alignment.levels[0].log;
- if (new_align < known_align)
- continue;
- fuzz += (-align_addr ^ growth) & (new_align - known_align);
- known_align = new_align;
- }
- return fuzz;
-}
-
-/* Compute a worst-case reference address of a branch so that it
- can be safely used in the presence of aligned labels. Since the
- size of the branch itself is unknown, the size of the branch is
- not included in the range. I.e. for a forward branch, the reference
- address is the end address of the branch as known from the previous
- branch shortening pass, minus a value to account for possible size
- increase due to alignment. For a backward branch, it is the start
- address of the branch as known from the current pass, plus a value
- to account for possible size increase due to alignment.
- NB.: Therefore, the maximum offset allowed for backward branches needs
- to exclude the branch size. */
-
-int
-insn_current_reference_address (rtx_insn *branch)
-{
- rtx dest;
- int seq_uid;
-
- if (! INSN_ADDRESSES_SET_P ())
- return 0;
-
- rtx_insn *seq = NEXT_INSN (PREV_INSN (branch));
- seq_uid = INSN_UID (seq);
- if (!jump_to_label_p (branch))
- /* This can happen for example on the PA; the objective is to know the
- offset to address something in front of the start of the function.
- Thus, we can treat it like a backward branch.
- We assume here that FUNCTION_BOUNDARY / BITS_PER_UNIT is larger than
- any alignment we'd encounter, so we skip the call to align_fuzz. */
- return insn_current_address;
- dest = JUMP_LABEL (branch);
-
- /* BRANCH has no proper alignment chain set, so use SEQ.
- BRANCH also has no INSN_SHUID. */
- if (INSN_SHUID (seq) < INSN_SHUID (dest))
- {
- /* Forward branch. */
- return (insn_last_address + insn_lengths[seq_uid]
- - align_fuzz (seq, dest, length_unit_log, ~0));
- }
- else
- {
- /* Backward branch. */
- return (insn_current_address
- + align_fuzz (dest, seq, length_unit_log, ~0));
- }
-}
-
-/* Compute branch alignments based on CFG profile. */
-
-unsigned int
-compute_alignments (void)
-{
- basic_block bb;
- align_flags max_alignment;
-
- label_align.truncate (0);
-
- max_labelno = max_label_num ();
- min_labelno = get_first_label_num ();
- label_align.safe_grow_cleared (max_labelno - min_labelno + 1, true);
-
- /* If not optimizing or optimizing for size, don't assign any alignments. */
- if (! optimize || optimize_function_for_size_p (cfun))
- return 0;
-
- if (dump_file)
- {
- dump_reg_info (dump_file);
- dump_flow_info (dump_file, TDF_DETAILS);
- flow_loops_dump (dump_file, NULL, 1);
- }
- loop_optimizer_init (AVOID_CFG_MODIFICATIONS);
- profile_count count_threshold = cfun->cfg->count_max.apply_scale
- (1, param_align_threshold);
-
- if (dump_file)
- {
- fprintf (dump_file, "count_max: ");
- cfun->cfg->count_max.dump (dump_file);
- fprintf (dump_file, "\n");
- }
- FOR_EACH_BB_FN (bb, cfun)
- {
- rtx_insn *label = BB_HEAD (bb);
- bool has_fallthru = 0;
- edge e;
- edge_iterator ei;
-
- if (!LABEL_P (label)
- || optimize_bb_for_size_p (bb))
- {
- if (dump_file)
- fprintf (dump_file,
- "BB %4i loop %2i loop_depth %2i skipped.\n",
- bb->index,
- bb->loop_father->num,
- bb_loop_depth (bb));
- continue;
- }
- max_alignment = LABEL_ALIGN (label);
- profile_count fallthru_count = profile_count::zero ();
- profile_count branch_count = profile_count::zero ();
-
- FOR_EACH_EDGE (e, ei, bb->preds)
- {
- if (e->flags & EDGE_FALLTHRU)
- has_fallthru = 1, fallthru_count += e->count ();
- else
- branch_count += e->count ();
- }
- if (dump_file)
- {
- fprintf (dump_file, "BB %4i loop %2i loop_depth"
- " %2i fall ",
- bb->index, bb->loop_father->num,
- bb_loop_depth (bb));
- fallthru_count.dump (dump_file);
- fprintf (dump_file, " branch ");
- branch_count.dump (dump_file);
- if (!bb->loop_father->inner && bb->loop_father->num)
- fprintf (dump_file, " inner_loop");
- if (bb->loop_father->header == bb)
- fprintf (dump_file, " loop_header");
- fprintf (dump_file, "\n");
- }
- if (!fallthru_count.initialized_p () || !branch_count.initialized_p ())
- continue;
-
- /* There are two purposes to align block with no fallthru incoming edge:
- 1) to avoid fetch stalls when branch destination is near cache boundary
- 2) to improve cache efficiency in case the previous block is not executed
- (so it does not need to be in the cache).
-
- We to catch first case, we align frequently executed blocks.
- To catch the second, we align blocks that are executed more frequently
- than the predecessor and the predecessor is likely to not be executed
- when function is called. */
-
- if (!has_fallthru
- && (branch_count > count_threshold
- || (bb->count > bb->prev_bb->count.apply_scale (10, 1)
- && (bb->prev_bb->count
- <= ENTRY_BLOCK_PTR_FOR_FN (cfun)
- ->count.apply_scale (1, 2)))))
- {
- align_flags alignment = JUMP_ALIGN (label);
- if (dump_file)
- fprintf (dump_file, " jump alignment added.\n");
- max_alignment = align_flags::max (max_alignment, alignment);
- }
- /* In case block is frequent and reached mostly by non-fallthru edge,
- align it. It is most likely a first block of loop. */
- if (has_fallthru
- && !(single_succ_p (bb)
- && single_succ (bb) == EXIT_BLOCK_PTR_FOR_FN (cfun))
- && optimize_bb_for_speed_p (bb)
- && branch_count + fallthru_count > count_threshold
- && (branch_count
- > fallthru_count.apply_scale
- (param_align_loop_iterations, 1)))
- {
- align_flags alignment = LOOP_ALIGN (label);
- if (dump_file)
- fprintf (dump_file, " internal loop alignment added.\n");
- max_alignment = align_flags::max (max_alignment, alignment);
- }
- LABEL_TO_ALIGNMENT (label) = max_alignment;
- }
-
- loop_optimizer_finalize ();
- free_dominance_info (CDI_DOMINATORS);
- return 0;
-}
-
-/* Grow the LABEL_ALIGN array after new labels are created. */
-
-static void
-grow_label_align (void)
-{
- int old = max_labelno;
- int n_labels;
- int n_old_labels;
-
- max_labelno = max_label_num ();
-
- n_labels = max_labelno - min_labelno + 1;
- n_old_labels = old - min_labelno + 1;
-
- label_align.safe_grow_cleared (n_labels, true);
-
- /* Range of labels grows monotonically in the function. Failing here
- means that the initialization of array got lost. */
- gcc_assert (n_old_labels <= n_labels);
-}
-
-/* Update the already computed alignment information. LABEL_PAIRS is a vector
- made up of pairs of labels for which the alignment information of the first
- element will be copied from that of the second element. */
-
-void
-update_alignments (vec<rtx> &label_pairs)
-{
- unsigned int i = 0;
- rtx iter, label = NULL_RTX;
-
- if (max_labelno != max_label_num ())
- grow_label_align ();
-
- FOR_EACH_VEC_ELT (label_pairs, i, iter)
- if (i & 1)
- LABEL_TO_ALIGNMENT (label) = LABEL_TO_ALIGNMENT (iter);
- else
- label = iter;
-}
-
-namespace {
-
-const pass_data pass_data_compute_alignments =
-{
- RTL_PASS, /* type */
- "alignments", /* name */
- OPTGROUP_NONE, /* optinfo_flags */
- TV_NONE, /* tv_id */
- 0, /* properties_required */
- 0, /* properties_provided */
- 0, /* properties_destroyed */
- 0, /* todo_flags_start */
- 0, /* todo_flags_finish */
-};
-
-class pass_compute_alignments : public rtl_opt_pass
-{
-public:
- pass_compute_alignments (gcc::context *ctxt)
- : rtl_opt_pass (pass_data_compute_alignments, ctxt)
- {}
-
- /* opt_pass methods: */
- virtual unsigned int execute (function *) { return compute_alignments (); }
-
-}; // class pass_compute_alignments
-
-} // anon namespace
-
-rtl_opt_pass *
-make_pass_compute_alignments (gcc::context *ctxt)
-{
- return new pass_compute_alignments (ctxt);
-}
-
-
-/* Make a pass over all insns and compute their actual lengths by shortening
- any branches of variable length if possible. */
-
-/* shorten_branches might be called multiple times: for example, the SH
- port splits out-of-range conditional branches in MACHINE_DEPENDENT_REORG.
- In order to do this, it needs proper length information, which it obtains
- by calling shorten_branches. This cannot be collapsed with
- shorten_branches itself into a single pass unless we also want to integrate
- reorg.c, since the branch splitting exposes new instructions with delay
- slots. */
-
-void
-shorten_branches (rtx_insn *first)
-{
- rtx_insn *insn;
- int max_uid;
- int i;
- rtx_insn *seq;
- int something_changed = 1;
- char *varying_length;
- rtx body;
- int uid;
- rtx align_tab[MAX_CODE_ALIGN + 1];
-
- /* Compute maximum UID and allocate label_align / uid_shuid. */
- max_uid = get_max_uid ();
-
- /* Free uid_shuid before reallocating it. */
- free (uid_shuid);
-
- uid_shuid = XNEWVEC (int, max_uid);
-
- if (max_labelno != max_label_num ())
- grow_label_align ();
-
- /* Initialize label_align and set up uid_shuid to be strictly
- monotonically rising with insn order. */
- /* We use alignment here to keep track of the maximum alignment we want to
- impose on the next CODE_LABEL (or the current one if we are processing
- the CODE_LABEL itself). */
-
- align_flags max_alignment;
-
- for (insn = get_insns (), i = 1; insn; insn = NEXT_INSN (insn))
- {
- INSN_SHUID (insn) = i++;
- if (INSN_P (insn))
- continue;
-
- if (rtx_code_label *label = dyn_cast <rtx_code_label *> (insn))
- {
- /* Merge in alignments computed by compute_alignments. */
- align_flags alignment = LABEL_TO_ALIGNMENT (label);
- max_alignment = align_flags::max (max_alignment, alignment);
-
- rtx_jump_table_data *table = jump_table_for_label (label);
- if (!table)
- {
- align_flags alignment = LABEL_ALIGN (label);
- max_alignment = align_flags::max (max_alignment, alignment);
- }
- /* ADDR_VECs only take room if read-only data goes into the text
- section. */
- if ((JUMP_TABLES_IN_TEXT_SECTION
- || readonly_data_section == text_section)
- && table)
- {
- align_flags alignment = align_flags (ADDR_VEC_ALIGN (table));
- max_alignment = align_flags::max (max_alignment, alignment);
- }
- LABEL_TO_ALIGNMENT (label) = max_alignment;
- max_alignment = align_flags ();
- }
- else if (BARRIER_P (insn))
- {
- rtx_insn *label;
-
- for (label = insn; label && ! INSN_P (label);
- label = NEXT_INSN (label))
- if (LABEL_P (label))
- {
- align_flags alignment
- = align_flags (LABEL_ALIGN_AFTER_BARRIER (insn));
- max_alignment = align_flags::max (max_alignment, alignment);
- break;
- }
- }
- }
- if (!HAVE_ATTR_length)
- return;
-
- /* Allocate the rest of the arrays. */
- insn_lengths = XNEWVEC (int, max_uid);
- insn_lengths_max_uid = max_uid;
- /* Syntax errors can lead to labels being outside of the main insn stream.
- Initialize insn_addresses, so that we get reproducible results. */
- INSN_ADDRESSES_ALLOC (max_uid);
-
- varying_length = XCNEWVEC (char, max_uid);
-
- /* Initialize uid_align. We scan instructions
- from end to start, and keep in align_tab[n] the last seen insn
- that does an alignment of at least n+1, i.e. the successor
- in the alignment chain for an insn that does / has a known
- alignment of n. */
- uid_align = XCNEWVEC (rtx, max_uid);
-
- for (i = MAX_CODE_ALIGN + 1; --i >= 0;)
- align_tab[i] = NULL_RTX;
- seq = get_last_insn ();
- for (; seq; seq = PREV_INSN (seq))
- {
- int uid = INSN_UID (seq);
- int log;
- log = (LABEL_P (seq) ? LABEL_TO_ALIGNMENT (seq).levels[0].log : 0);
- uid_align[uid] = align_tab[0];
- if (log)
- {
- /* Found an alignment label. */
- gcc_checking_assert (log < MAX_CODE_ALIGN + 1);
- uid_align[uid] = align_tab[log];
- for (i = log - 1; i >= 0; i--)
- align_tab[i] = seq;
- }
- }
-
- /* When optimizing, we start assuming minimum length, and keep increasing
- lengths as we find the need for this, till nothing changes.
- When not optimizing, we start assuming maximum lengths, and
- do a single pass to update the lengths. */
- bool increasing = optimize != 0;
-
-#ifdef CASE_VECTOR_SHORTEN_MODE
- if (optimize)
- {
- /* Look for ADDR_DIFF_VECs, and initialize their minimum and maximum
- label fields. */
-
- int min_shuid = INSN_SHUID (get_insns ()) - 1;
- int max_shuid = INSN_SHUID (get_last_insn ()) + 1;
- int rel;
-
- for (insn = first; insn != 0; insn = NEXT_INSN (insn))
- {
- rtx min_lab = NULL_RTX, max_lab = NULL_RTX, pat;
- int len, i, min, max, insn_shuid;
- int min_align;
- addr_diff_vec_flags flags;
-
- if (! JUMP_TABLE_DATA_P (insn)
- || GET_CODE (PATTERN (insn)) != ADDR_DIFF_VEC)
- continue;
- pat = PATTERN (insn);
- len = XVECLEN (pat, 1);
- gcc_assert (len > 0);
- min_align = MAX_CODE_ALIGN;
- for (min = max_shuid, max = min_shuid, i = len - 1; i >= 0; i--)
- {
- rtx lab = XEXP (XVECEXP (pat, 1, i), 0);
- int shuid = INSN_SHUID (lab);
- if (shuid < min)
- {
- min = shuid;
- min_lab = lab;
- }
- if (shuid > max)
- {
- max = shuid;
- max_lab = lab;
- }
-
- int label_alignment = LABEL_TO_ALIGNMENT (lab).levels[0].log;
- if (min_align > label_alignment)
- min_align = label_alignment;
- }
- XEXP (pat, 2) = gen_rtx_LABEL_REF (Pmode, min_lab);
- XEXP (pat, 3) = gen_rtx_LABEL_REF (Pmode, max_lab);
- insn_shuid = INSN_SHUID (insn);
- rel = INSN_SHUID (XEXP (XEXP (pat, 0), 0));
- memset (&flags, 0, sizeof (flags));
- flags.min_align = min_align;
- flags.base_after_vec = rel > insn_shuid;
- flags.min_after_vec = min > insn_shuid;
- flags.max_after_vec = max > insn_shuid;
- flags.min_after_base = min > rel;
- flags.max_after_base = max > rel;
- ADDR_DIFF_VEC_FLAGS (pat) = flags;
-
- if (increasing)
- PUT_MODE (pat, CASE_VECTOR_SHORTEN_MODE (0, 0, pat));
- }
- }
-#endif /* CASE_VECTOR_SHORTEN_MODE */
-
- /* Compute initial lengths, addresses, and varying flags for each insn. */
- int (*length_fun) (rtx_insn *) = increasing ? insn_min_length : insn_default_length;
-
- for (insn_current_address = 0, insn = first;
- insn != 0;
- insn_current_address += insn_lengths[uid], insn = NEXT_INSN (insn))
- {
- uid = INSN_UID (insn);
-
- insn_lengths[uid] = 0;
-
- if (LABEL_P (insn))
- {
- int log = LABEL_TO_ALIGNMENT (insn).levels[0].log;
- if (log)
- {
- int align = 1 << log;
- int new_address = (insn_current_address + align - 1) & -align;
- insn_lengths[uid] = new_address - insn_current_address;
- }
- }
-
- INSN_ADDRESSES (uid) = insn_current_address + insn_lengths[uid];
-
- if (NOTE_P (insn) || BARRIER_P (insn)
- || LABEL_P (insn) || DEBUG_INSN_P (insn))
- continue;
- if (insn->deleted ())
- continue;
-
- body = PATTERN (insn);
- if (rtx_jump_table_data *table = dyn_cast <rtx_jump_table_data *> (insn))
- {
- /* This only takes room if read-only data goes into the text
- section. */
- if (JUMP_TABLES_IN_TEXT_SECTION
- || readonly_data_section == text_section)
- insn_lengths[uid] = (XVECLEN (body,
- GET_CODE (body) == ADDR_DIFF_VEC)
- * GET_MODE_SIZE (table->get_data_mode ()));
- /* Alignment is handled by ADDR_VEC_ALIGN. */
- }
- else if (GET_CODE (body) == ASM_INPUT || asm_noperands (body) >= 0)
- insn_lengths[uid] = asm_insn_count (body) * insn_default_length (insn);
- else if (rtx_sequence *body_seq = dyn_cast <rtx_sequence *> (body))
- {
- int i;
- int const_delay_slots;
- if (DELAY_SLOTS)
- const_delay_slots = const_num_delay_slots (body_seq->insn (0));
- else
- const_delay_slots = 0;
-
- int (*inner_length_fun) (rtx_insn *)
- = const_delay_slots ? length_fun : insn_default_length;
- /* Inside a delay slot sequence, we do not do any branch shortening
- if the shortening could change the number of delay slots
- of the branch. */
- for (i = 0; i < body_seq->len (); i++)
- {
- rtx_insn *inner_insn = body_seq->insn (i);
- int inner_uid = INSN_UID (inner_insn);
- int inner_length;
-
- if (GET_CODE (PATTERN (inner_insn)) == ASM_INPUT
- || asm_noperands (PATTERN (inner_insn)) >= 0)
- inner_length = (asm_insn_count (PATTERN (inner_insn))
- * insn_default_length (inner_insn));
- else
- inner_length = inner_length_fun (inner_insn);
-
- insn_lengths[inner_uid] = inner_length;
- if (const_delay_slots)
- {
- if ((varying_length[inner_uid]
- = insn_variable_length_p (inner_insn)) != 0)
- varying_length[uid] = 1;
- INSN_ADDRESSES (inner_uid) = (insn_current_address
- + insn_lengths[uid]);
- }
- else
- varying_length[inner_uid] = 0;
- insn_lengths[uid] += inner_length;
- }
- }
- else if (GET_CODE (body) != USE && GET_CODE (body) != CLOBBER)
- {
- insn_lengths[uid] = length_fun (insn);
- varying_length[uid] = insn_variable_length_p (insn);
- }
-
- /* If needed, do any adjustment. */
-#ifdef ADJUST_INSN_LENGTH
- ADJUST_INSN_LENGTH (insn, insn_lengths[uid]);
- if (insn_lengths[uid] < 0)
- fatal_insn ("negative insn length", insn);
-#endif
- }
-
- /* Now loop over all the insns finding varying length insns. For each,
- get the current insn length. If it has changed, reflect the change.
- When nothing changes for a full pass, we are done. */
-
- while (something_changed)
- {
- something_changed = 0;
- insn_current_align = MAX_CODE_ALIGN - 1;
- for (insn_current_address = 0, insn = first;
- insn != 0;
- insn = NEXT_INSN (insn))
- {
- int new_length;
-#ifdef ADJUST_INSN_LENGTH
- int tmp_length;
-#endif
- int length_align;
-
- uid = INSN_UID (insn);
-
- if (rtx_code_label *label = dyn_cast <rtx_code_label *> (insn))
- {
- int log = LABEL_TO_ALIGNMENT (label).levels[0].log;
-
-#ifdef CASE_VECTOR_SHORTEN_MODE
- /* If the mode of a following jump table was changed, we
- may need to update the alignment of this label. */
-
- if (JUMP_TABLES_IN_TEXT_SECTION
- || readonly_data_section == text_section)
- {
- rtx_jump_table_data *table = jump_table_for_label (label);
- if (table)
- {
- int newlog = ADDR_VEC_ALIGN (table);
- if (newlog != log)
- {
- log = newlog;
- LABEL_TO_ALIGNMENT (insn) = log;
- something_changed = 1;
- }
- }
- }
-#endif
-
- if (log > insn_current_align)
- {
- int align = 1 << log;
- int new_address= (insn_current_address + align - 1) & -align;
- insn_lengths[uid] = new_address - insn_current_address;
- insn_current_align = log;
- insn_current_address = new_address;
- }
- else
- insn_lengths[uid] = 0;
- INSN_ADDRESSES (uid) = insn_current_address;
- continue;
- }
-
- length_align = INSN_LENGTH_ALIGNMENT (insn);
- if (length_align < insn_current_align)
- insn_current_align = length_align;
-
- insn_last_address = INSN_ADDRESSES (uid);
- INSN_ADDRESSES (uid) = insn_current_address;
-
-#ifdef CASE_VECTOR_SHORTEN_MODE
- if (optimize
- && JUMP_TABLE_DATA_P (insn)
- && GET_CODE (PATTERN (insn)) == ADDR_DIFF_VEC)
- {
- rtx_jump_table_data *table = as_a <rtx_jump_table_data *> (insn);
- rtx body = PATTERN (insn);
- int old_length = insn_lengths[uid];
- rtx_insn *rel_lab =
- safe_as_a <rtx_insn *> (XEXP (XEXP (body, 0), 0));
- rtx min_lab = XEXP (XEXP (body, 2), 0);
- rtx max_lab = XEXP (XEXP (body, 3), 0);
- int rel_addr = INSN_ADDRESSES (INSN_UID (rel_lab));
- int min_addr = INSN_ADDRESSES (INSN_UID (min_lab));
- int max_addr = INSN_ADDRESSES (INSN_UID (max_lab));
- rtx_insn *prev;
- int rel_align = 0;
- addr_diff_vec_flags flags;
- scalar_int_mode vec_mode;
-
- /* Avoid automatic aggregate initialization. */
- flags = ADDR_DIFF_VEC_FLAGS (body);
-
- /* Try to find a known alignment for rel_lab. */
- for (prev = rel_lab;
- prev
- && ! insn_lengths[INSN_UID (prev)]
- && ! (varying_length[INSN_UID (prev)] & 1);
- prev = PREV_INSN (prev))
- if (varying_length[INSN_UID (prev)] & 2)
- {
- rel_align = LABEL_TO_ALIGNMENT (prev).levels[0].log;
- break;
- }
-
- /* See the comment on addr_diff_vec_flags in rtl.h for the
- meaning of the flags values. base: REL_LAB vec: INSN */
- /* Anything after INSN has still addresses from the last
- pass; adjust these so that they reflect our current
- estimate for this pass. */
- if (flags.base_after_vec)
- rel_addr += insn_current_address - insn_last_address;
- if (flags.min_after_vec)
- min_addr += insn_current_address - insn_last_address;
- if (flags.max_after_vec)
- max_addr += insn_current_address - insn_last_address;
- /* We want to know the worst case, i.e. lowest possible value
- for the offset of MIN_LAB. If MIN_LAB is after REL_LAB,
- its offset is positive, and we have to be wary of code shrink;
- otherwise, it is negative, and we have to be vary of code
- size increase. */
- if (flags.min_after_base)
- {
- /* If INSN is between REL_LAB and MIN_LAB, the size
- changes we are about to make can change the alignment
- within the observed offset, therefore we have to break
- it up into two parts that are independent. */
- if (! flags.base_after_vec && flags.min_after_vec)
- {
- min_addr -= align_fuzz (rel_lab, insn, rel_align, 0);
- min_addr -= align_fuzz (insn, min_lab, 0, 0);
- }
- else
- min_addr -= align_fuzz (rel_lab, min_lab, rel_align, 0);
- }
- else
- {
- if (flags.base_after_vec && ! flags.min_after_vec)
- {
- min_addr -= align_fuzz (min_lab, insn, 0, ~0);
- min_addr -= align_fuzz (insn, rel_lab, 0, ~0);
- }
- else
- min_addr -= align_fuzz (min_lab, rel_lab, 0, ~0);
- }
- /* Likewise, determine the highest lowest possible value
- for the offset of MAX_LAB. */
- if (flags.max_after_base)
- {
- if (! flags.base_after_vec && flags.max_after_vec)
- {
- max_addr += align_fuzz (rel_lab, insn, rel_align, ~0);
- max_addr += align_fuzz (insn, max_lab, 0, ~0);
- }
- else
- max_addr += align_fuzz (rel_lab, max_lab, rel_align, ~0);
- }
- else
- {
- if (flags.base_after_vec && ! flags.max_after_vec)
- {
- max_addr += align_fuzz (max_lab, insn, 0, 0);
- max_addr += align_fuzz (insn, rel_lab, 0, 0);
- }
- else
- max_addr += align_fuzz (max_lab, rel_lab, 0, 0);
- }
- vec_mode = CASE_VECTOR_SHORTEN_MODE (min_addr - rel_addr,
- max_addr - rel_addr, body);
- if (!increasing
- || (GET_MODE_SIZE (vec_mode)
- >= GET_MODE_SIZE (table->get_data_mode ())))
- PUT_MODE (body, vec_mode);
- if (JUMP_TABLES_IN_TEXT_SECTION
- || readonly_data_section == text_section)
- {
- insn_lengths[uid]
- = (XVECLEN (body, 1)
- * GET_MODE_SIZE (table->get_data_mode ()));
- insn_current_address += insn_lengths[uid];
- if (insn_lengths[uid] != old_length)
- something_changed = 1;
- }
-
- continue;
- }
-#endif /* CASE_VECTOR_SHORTEN_MODE */
-
- if (! (varying_length[uid]))
- {
- if (NONJUMP_INSN_P (insn)
- && GET_CODE (PATTERN (insn)) == SEQUENCE)
- {
- int i;
-
- body = PATTERN (insn);
- for (i = 0; i < XVECLEN (body, 0); i++)
- {
- rtx inner_insn = XVECEXP (body, 0, i);
- int inner_uid = INSN_UID (inner_insn);
-
- INSN_ADDRESSES (inner_uid) = insn_current_address;
-
- insn_current_address += insn_lengths[inner_uid];
- }
- }
- else
- insn_current_address += insn_lengths[uid];
-
- continue;
- }
-
- if (NONJUMP_INSN_P (insn) && GET_CODE (PATTERN (insn)) == SEQUENCE)
- {
- rtx_sequence *seqn = as_a <rtx_sequence *> (PATTERN (insn));
- int i;
-
- body = PATTERN (insn);
- new_length = 0;
- for (i = 0; i < seqn->len (); i++)
- {
- rtx_insn *inner_insn = seqn->insn (i);
- int inner_uid = INSN_UID (inner_insn);
- int inner_length;
-
- INSN_ADDRESSES (inner_uid) = insn_current_address;
-
- /* insn_current_length returns 0 for insns with a
- non-varying length. */
- if (! varying_length[inner_uid])
- inner_length = insn_lengths[inner_uid];
- else
- inner_length = insn_current_length (inner_insn);
-
- if (inner_length != insn_lengths[inner_uid])
- {
- if (!increasing || inner_length > insn_lengths[inner_uid])
- {
- insn_lengths[inner_uid] = inner_length;
- something_changed = 1;
- }
- else
- inner_length = insn_lengths[inner_uid];
- }
- insn_current_address += inner_length;
- new_length += inner_length;
- }
- }
- else
- {
- new_length = insn_current_length (insn);
- insn_current_address += new_length;
- }
-
-#ifdef ADJUST_INSN_LENGTH
- /* If needed, do any adjustment. */
- tmp_length = new_length;
- ADJUST_INSN_LENGTH (insn, new_length);
- insn_current_address += (new_length - tmp_length);
-#endif
-
- if (new_length != insn_lengths[uid]
- && (!increasing || new_length > insn_lengths[uid]))
- {
- insn_lengths[uid] = new_length;
- something_changed = 1;
- }
- else
- insn_current_address += insn_lengths[uid] - new_length;
- }
- /* For a non-optimizing compile, do only a single pass. */
- if (!increasing)
- break;
- }
- crtl->max_insn_address = insn_current_address;
- free (varying_length);
-}
-
-/* Given the body of an INSN known to be generated by an ASM statement, return
- the number of machine instructions likely to be generated for this insn.
- This is used to compute its length. */
-
-static int
-asm_insn_count (rtx body)
-{
- const char *templ;
-
- if (GET_CODE (body) == ASM_INPUT)
- templ = XSTR (body, 0);
- else
- templ = decode_asm_operands (body, NULL, NULL, NULL, NULL, NULL);
-
- return asm_str_count (templ);
-}
-
-/* Return the number of machine instructions likely to be generated for the
- inline-asm template. */
-int
-asm_str_count (const char *templ)
-{
- int count = 1;
-
- if (!*templ)
- return 0;
-
- for (; *templ; templ++)
- if (IS_ASM_LOGICAL_LINE_SEPARATOR (*templ, templ)
- || *templ == '\n')
- count++;
-
- return count;
-}
-
-/* Return true if DWARF2 debug info can be emitted for DECL. */
-
-static bool
-dwarf2_debug_info_emitted_p (tree decl)
-{
- /* When DWARF2 debug info is not generated internally. */
- if (!dwarf_debuginfo_p () && !dwarf_based_debuginfo_p ())
- return false;
-
- if (DECL_IGNORED_P (decl))
- return false;
-
- return true;
-}
-
-/* Return scope resulting from combination of S1 and S2. */
-static tree
-choose_inner_scope (tree s1, tree s2)
-{
- if (!s1)
- return s2;
- if (!s2)
- return s1;
- if (BLOCK_NUMBER (s1) > BLOCK_NUMBER (s2))
- return s1;
- return s2;
-}
-
-/* Emit lexical block notes needed to change scope from S1 to S2. */
-
-static void
-change_scope (rtx_insn *orig_insn, tree s1, tree s2)
-{
- rtx_insn *insn = orig_insn;
- tree com = NULL_TREE;
- tree ts1 = s1, ts2 = s2;
- tree s;
-
- while (ts1 != ts2)
- {
- gcc_assert (ts1 && ts2);
- if (BLOCK_NUMBER (ts1) > BLOCK_NUMBER (ts2))
- ts1 = BLOCK_SUPERCONTEXT (ts1);
- else if (BLOCK_NUMBER (ts1) < BLOCK_NUMBER (ts2))
- ts2 = BLOCK_SUPERCONTEXT (ts2);
- else
- {
- ts1 = BLOCK_SUPERCONTEXT (ts1);
- ts2 = BLOCK_SUPERCONTEXT (ts2);
- }
- }
- com = ts1;
-
- /* Close scopes. */
- s = s1;
- while (s != com)
- {
- rtx_note *note = emit_note_before (NOTE_INSN_BLOCK_END, insn);
- NOTE_BLOCK (note) = s;
- s = BLOCK_SUPERCONTEXT (s);
- }
-
- /* Open scopes. */
- s = s2;
- while (s != com)
- {
- insn = emit_note_before (NOTE_INSN_BLOCK_BEG, insn);
- NOTE_BLOCK (insn) = s;
- s = BLOCK_SUPERCONTEXT (s);
- }
-}
-
-/* Rebuild all the NOTE_INSN_BLOCK_BEG and NOTE_INSN_BLOCK_END notes based
- on the scope tree and the newly reordered instructions. */
-
-static void
-reemit_insn_block_notes (void)
-{
- tree cur_block = DECL_INITIAL (cfun->decl);
- rtx_insn *insn;
-
- insn = get_insns ();
- for (; insn; insn = NEXT_INSN (insn))
- {
- tree this_block;
-
- /* Prevent lexical blocks from straddling section boundaries. */
- if (NOTE_P (insn))
- switch (NOTE_KIND (insn))
- {
- case NOTE_INSN_SWITCH_TEXT_SECTIONS:
- {
- for (tree s = cur_block; s != DECL_INITIAL (cfun->decl);
- s = BLOCK_SUPERCONTEXT (s))
- {
- rtx_note *note = emit_note_before (NOTE_INSN_BLOCK_END, insn);
- NOTE_BLOCK (note) = s;
- note = emit_note_after (NOTE_INSN_BLOCK_BEG, insn);
- NOTE_BLOCK (note) = s;
- }
- }
- break;
-
- case NOTE_INSN_BEGIN_STMT:
- case NOTE_INSN_INLINE_ENTRY:
- this_block = LOCATION_BLOCK (NOTE_MARKER_LOCATION (insn));
- goto set_cur_block_to_this_block;
-
- default:
- continue;
- }
-
- if (!active_insn_p (insn))
- continue;
-
- /* Avoid putting scope notes between jump table and its label. */
- if (JUMP_TABLE_DATA_P (insn))
- continue;
-
- this_block = insn_scope (insn);
- /* For sequences compute scope resulting from merging all scopes
- of instructions nested inside. */
- if (rtx_sequence *body = dyn_cast <rtx_sequence *> (PATTERN (insn)))
- {
- int i;
-
- this_block = NULL;
- for (i = 0; i < body->len (); i++)
- this_block = choose_inner_scope (this_block,
- insn_scope (body->insn (i)));
- }
- set_cur_block_to_this_block:
- if (! this_block)
- {
- if (INSN_LOCATION (insn) == UNKNOWN_LOCATION)
- continue;
- else
- this_block = DECL_INITIAL (cfun->decl);
- }
-
- if (this_block != cur_block)
- {
- change_scope (insn, cur_block, this_block);
- cur_block = this_block;
- }
- }
-
- /* change_scope emits before the insn, not after. */
- rtx_note *note = emit_note (NOTE_INSN_DELETED);
- change_scope (note, cur_block, DECL_INITIAL (cfun->decl));
- delete_insn (note);
-
- reorder_blocks ();
-}
-
-static const char *some_local_dynamic_name;
-
-/* Locate some local-dynamic symbol still in use by this function
- so that we can print its name in local-dynamic base patterns.
- Return null if there are no local-dynamic references. */
-
-const char *
-get_some_local_dynamic_name ()
-{
- subrtx_iterator::array_type array;
- rtx_insn *insn;
-
- if (some_local_dynamic_name)
- return some_local_dynamic_name;
-
- for (insn = get_insns (); insn ; insn = NEXT_INSN (insn))
- if (NONDEBUG_INSN_P (insn))
- FOR_EACH_SUBRTX (iter, array, PATTERN (insn), ALL)
- {
- const_rtx x = *iter;
- if (GET_CODE (x) == SYMBOL_REF)
- {
- if (SYMBOL_REF_TLS_MODEL (x) == TLS_MODEL_LOCAL_DYNAMIC)
- return some_local_dynamic_name = XSTR (x, 0);
- if (CONSTANT_POOL_ADDRESS_P (x))
- iter.substitute (get_pool_constant (x));
- }
- }
-
- return 0;
-}
-
-/* Arrange for us to emit a source location note before any further
- real insns or section changes, by setting the SEEN_NEXT_VIEW bit in
- *SEEN, as long as we are keeping track of location views. The bit
- indicates we have referenced the next view at the current PC, so we
- have to emit it. This should be called next to the var_location
- debug hook. */
-
-static inline void
-set_next_view_needed (int *seen)
-{
- if (debug_variable_location_views)
- *seen |= SEEN_NEXT_VIEW;
-}
-
-/* Clear the flag in *SEEN indicating we need to emit the next view.
- This should be called next to the source_line debug hook. */
-
-static inline void
-clear_next_view_needed (int *seen)
-{
- *seen &= ~SEEN_NEXT_VIEW;
-}
-
-/* Test whether we have a pending request to emit the next view in
- *SEEN, and emit it if needed, clearing the request bit. */
-
-static inline void
-maybe_output_next_view (int *seen)
-{
- if ((*seen & SEEN_NEXT_VIEW) != 0)
- {
- clear_next_view_needed (seen);
- (*debug_hooks->source_line) (last_linenum, last_columnnum,
- last_filename, last_discriminator,
- false);
- }
-}
-
-/* We want to emit param bindings (before the first begin_stmt) in the
- initial view, if we are emitting views. To that end, we may
- consume initial notes in the function, processing them in
- final_start_function, before signaling the beginning of the
- prologue, rather than in final.
-
- We don't test whether the DECLs are PARM_DECLs: the assumption is
- that there will be a NOTE_INSN_BEGIN_STMT marker before any
- non-parameter NOTE_INSN_VAR_LOCATION. It's ok if the marker is not
- there, we'll just have more variable locations bound in the initial
- view, which is consistent with their being bound without any code
- that would give them a value. */
-
-static inline bool
-in_initial_view_p (rtx_insn *insn)
-{
- return (!DECL_IGNORED_P (current_function_decl)
- && debug_variable_location_views
- && insn && GET_CODE (insn) == NOTE
- && (NOTE_KIND (insn) == NOTE_INSN_VAR_LOCATION
- || NOTE_KIND (insn) == NOTE_INSN_DELETED));
-}
-
-/* Output assembler code for the start of a function,
- and initialize some of the variables in this file
- for the new function. The label for the function and associated
- assembler pseudo-ops have already been output in `assemble_start_function'.
-
- FIRST is the first insn of the rtl for the function being compiled.
- FILE is the file to write assembler code to.
- SEEN should be initially set to zero, and it may be updated to
- indicate we have references to the next location view, that would
- require us to emit it at the current PC.
- OPTIMIZE_P is nonzero if we should eliminate redundant
- test and compare insns. */
-
-static void
-final_start_function_1 (rtx_insn **firstp, FILE *file, int *seen,
- int optimize_p ATTRIBUTE_UNUSED)
-{
- block_depth = 0;
-
- this_is_asm_operands = 0;
-
- need_profile_function = false;
-
- last_filename = LOCATION_FILE (prologue_location);
- last_linenum = LOCATION_LINE (prologue_location);
- last_columnnum = LOCATION_COLUMN (prologue_location);
- last_discriminator = discriminator = 0;
- last_bb_discriminator = bb_discriminator = 0;
- force_source_line = false;
-
- high_block_linenum = high_function_linenum = last_linenum;
-
- if (flag_sanitize & SANITIZE_ADDRESS)
- asan_function_start ();
-
- rtx_insn *first = *firstp;
- if (in_initial_view_p (first))
- {
- do
- {
- final_scan_insn (first, file, 0, 0, seen);
- first = NEXT_INSN (first);
- }
- while (in_initial_view_p (first));
- *firstp = first;
- }
-
- if (!DECL_IGNORED_P (current_function_decl))
- debug_hooks->begin_prologue (last_linenum, last_columnnum,
- last_filename);
-
- if (!dwarf2_debug_info_emitted_p (current_function_decl))
- dwarf2out_begin_prologue (0, 0, NULL);
-
- if (DECL_IGNORED_P (current_function_decl) && last_linenum && last_filename)
- debug_hooks->set_ignored_loc (last_linenum, last_columnnum, last_filename);
-
-#ifdef LEAF_REG_REMAP
- if (crtl->uses_only_leaf_regs)
- leaf_renumber_regs (first);
-#endif
-
- /* The Sun386i and perhaps other machines don't work right
- if the profiling code comes after the prologue. */
- if (targetm.profile_before_prologue () && crtl->profile)
- {
- if (targetm.asm_out.function_prologue == default_function_pro_epilogue
- && targetm.have_prologue ())
- {
- rtx_insn *insn;
- for (insn = first; insn; insn = NEXT_INSN (insn))
- if (!NOTE_P (insn))
- {
- insn = NULL;
- break;
- }
- else if (NOTE_KIND (insn) == NOTE_INSN_BASIC_BLOCK
- || NOTE_KIND (insn) == NOTE_INSN_FUNCTION_BEG)
- break;
- else if (NOTE_KIND (insn) == NOTE_INSN_DELETED
- || NOTE_KIND (insn) == NOTE_INSN_VAR_LOCATION)
- continue;
- else
- {
- insn = NULL;
- break;
- }
-
- if (insn)
- need_profile_function = true;
- else
- profile_function (file);
- }
- else
- profile_function (file);
- }
-
- /* If debugging, assign block numbers to all of the blocks in this
- function. */
- if (write_symbols)
- {
- reemit_insn_block_notes ();
- number_blocks (current_function_decl);
- /* We never actually put out begin/end notes for the top-level
- block in the function. But, conceptually, that block is
- always needed. */
- TREE_ASM_WRITTEN (DECL_INITIAL (current_function_decl)) = 1;
- }
-
- unsigned HOST_WIDE_INT min_frame_size
- = constant_lower_bound (get_frame_size ());
- if (min_frame_size > (unsigned HOST_WIDE_INT) warn_frame_larger_than_size)
- {
- /* Issue a warning */
- warning (OPT_Wframe_larger_than_,
- "the frame size of %wu bytes is larger than %wu bytes",
- min_frame_size, warn_frame_larger_than_size);
- }
-
- /* First output the function prologue: code to set up the stack frame. */
- targetm.asm_out.function_prologue (file);
-
- /* If the machine represents the prologue as RTL, the profiling code must
- be emitted when NOTE_INSN_PROLOGUE_END is scanned. */
- if (! targetm.have_prologue ())
- profile_after_prologue (file);
-}
-
-/* This is an exported final_start_function_1, callable without SEEN. */
-
-void
-final_start_function (rtx_insn *first, FILE *file,
- int optimize_p ATTRIBUTE_UNUSED)
-{
- int seen = 0;
- final_start_function_1 (&first, file, &seen, optimize_p);
- gcc_assert (seen == 0);
-}
-
-static void
-profile_after_prologue (FILE *file ATTRIBUTE_UNUSED)
-{
- if (!targetm.profile_before_prologue () && crtl->profile)
- profile_function (file);
-}
-
-static void
-profile_function (FILE *file ATTRIBUTE_UNUSED)
-{
-#ifndef NO_PROFILE_COUNTERS
-# define NO_PROFILE_COUNTERS 0
-#endif
-#ifdef ASM_OUTPUT_REG_PUSH
- rtx sval = NULL, chain = NULL;
-
- if (cfun->returns_struct)
- sval = targetm.calls.struct_value_rtx (TREE_TYPE (current_function_decl),
- true);
- if (cfun->static_chain_decl)
- chain = targetm.calls.static_chain (current_function_decl, true);
-#endif /* ASM_OUTPUT_REG_PUSH */
-
- if (! NO_PROFILE_COUNTERS)
- {
- int align = MIN (BIGGEST_ALIGNMENT, LONG_TYPE_SIZE);
- switch_to_section (data_section);
- ASM_OUTPUT_ALIGN (file, floor_log2 (align / BITS_PER_UNIT));
- targetm.asm_out.internal_label (file, "LP", current_function_funcdef_no);
- assemble_integer (const0_rtx, LONG_TYPE_SIZE / BITS_PER_UNIT, align, 1);
- }
-
- switch_to_section (current_function_section ());
-
-#ifdef ASM_OUTPUT_REG_PUSH
- if (sval && REG_P (sval))
- ASM_OUTPUT_REG_PUSH (file, REGNO (sval));
- if (chain && REG_P (chain))
- ASM_OUTPUT_REG_PUSH (file, REGNO (chain));
-#endif
-
- FUNCTION_PROFILER (file, current_function_funcdef_no);
-
-#ifdef ASM_OUTPUT_REG_PUSH
- if (chain && REG_P (chain))
- ASM_OUTPUT_REG_POP (file, REGNO (chain));
- if (sval && REG_P (sval))
- ASM_OUTPUT_REG_POP (file, REGNO (sval));
-#endif
-}
-
-/* Output assembler code for the end of a function.
- For clarity, args are same as those of `final_start_function'
- even though not all of them are needed. */
-
-void
-final_end_function (void)
-{
- app_disable ();
-
- if (!DECL_IGNORED_P (current_function_decl))
- debug_hooks->end_function (high_function_linenum);
-
- /* Finally, output the function epilogue:
- code to restore the stack frame and return to the caller. */
- targetm.asm_out.function_epilogue (asm_out_file);
-
- /* And debug output. */
- if (!DECL_IGNORED_P (current_function_decl))
- debug_hooks->end_epilogue (last_linenum, last_filename);
-
- if (!dwarf2_debug_info_emitted_p (current_function_decl)
- && dwarf2out_do_frame ())
- dwarf2out_end_epilogue (last_linenum, last_filename);
-
- some_local_dynamic_name = 0;
-}
-
-
-/* Dumper helper for basic block information. FILE is the assembly
- output file, and INSN is the instruction being emitted. */
-
-static void
-dump_basic_block_info (FILE *file, rtx_insn *insn, basic_block *start_to_bb,
- basic_block *end_to_bb, int bb_map_size, int *bb_seqn)
-{
- basic_block bb;
-
- if (!flag_debug_asm)
- return;
-
- if (INSN_UID (insn) < bb_map_size
- && (bb = start_to_bb[INSN_UID (insn)]) != NULL)
- {
- edge e;
- edge_iterator ei;
-
- fprintf (file, "%s BLOCK %d", ASM_COMMENT_START, bb->index);
- if (bb->count.initialized_p ())
- {
- fprintf (file, ", count:");
- bb->count.dump (file);
- }
- fprintf (file, " seq:%d", (*bb_seqn)++);
- fprintf (file, "\n%s PRED:", ASM_COMMENT_START);
- FOR_EACH_EDGE (e, ei, bb->preds)
- {
- dump_edge_info (file, e, TDF_DETAILS, 0);
- }
- fprintf (file, "\n");
- }
- if (INSN_UID (insn) < bb_map_size
- && (bb = end_to_bb[INSN_UID (insn)]) != NULL)
- {
- edge e;
- edge_iterator ei;
-
- fprintf (asm_out_file, "%s SUCC:", ASM_COMMENT_START);
- FOR_EACH_EDGE (e, ei, bb->succs)
- {
- dump_edge_info (asm_out_file, e, TDF_DETAILS, 1);
- }
- fprintf (file, "\n");
- }
-}
-
-/* Output assembler code for some insns: all or part of a function.
- For description of args, see `final_start_function', above. */
-
-static void
-final_1 (rtx_insn *first, FILE *file, int seen, int optimize_p)
-{
- rtx_insn *insn, *next;
-
- /* Used for -dA dump. */
- basic_block *start_to_bb = NULL;
- basic_block *end_to_bb = NULL;
- int bb_map_size = 0;
- int bb_seqn = 0;
-
- last_ignored_compare = 0;
-
- init_recog ();
-
- CC_STATUS_INIT;
-
- if (flag_debug_asm)
- {
- basic_block bb;
-
- bb_map_size = get_max_uid () + 1;
- start_to_bb = XCNEWVEC (basic_block, bb_map_size);
- end_to_bb = XCNEWVEC (basic_block, bb_map_size);
-
- /* There is no cfg for a thunk. */
- if (!cfun->is_thunk)
- FOR_EACH_BB_REVERSE_FN (bb, cfun)
- {
- start_to_bb[INSN_UID (BB_HEAD (bb))] = bb;
- end_to_bb[INSN_UID (BB_END (bb))] = bb;
- }
- }
-
- /* Output the insns. */
- for (insn = first; insn;)
- {
- if (HAVE_ATTR_length)
- {
- if ((unsigned) INSN_UID (insn) >= INSN_ADDRESSES_SIZE ())
- {
- /* This can be triggered by bugs elsewhere in the compiler if
- new insns are created after init_insn_lengths is called. */
- gcc_assert (NOTE_P (insn));
- insn_current_address = -1;
- }
- else
- insn_current_address = INSN_ADDRESSES (INSN_UID (insn));
- /* final can be seen as an iteration of shorten_branches that
- does nothing (since a fixed point has already been reached). */
- insn_last_address = insn_current_address;
- }
-
- dump_basic_block_info (file, insn, start_to_bb, end_to_bb,
- bb_map_size, &bb_seqn);
- insn = final_scan_insn (insn, file, optimize_p, 0, &seen);
- }
-
- maybe_output_next_view (&seen);
-
- if (flag_debug_asm)
- {
- free (start_to_bb);
- free (end_to_bb);
- }
-
- /* Remove CFI notes, to avoid compare-debug failures. */
- for (insn = first; insn; insn = next)
- {
- next = NEXT_INSN (insn);
- if (NOTE_P (insn)
- && (NOTE_KIND (insn) == NOTE_INSN_CFI
- || NOTE_KIND (insn) == NOTE_INSN_CFI_LABEL))
- delete_insn (insn);
- }
-}
-
-/* This is an exported final_1, callable without SEEN. */
-
-void
-final (rtx_insn *first, FILE *file, int optimize_p)
-{
- /* Those that use the internal final_start_function_1/final_1 API
- skip initial debug bind notes in final_start_function_1, and pass
- the modified FIRST to final_1. But those that use the public
- final_start_function/final APIs, final_start_function can't move
- FIRST because it's not passed by reference, so if they were
- skipped there, skip them again here. */
- while (in_initial_view_p (first))
- first = NEXT_INSN (first);
-
- final_1 (first, file, 0, optimize_p);
-}
-
-const char *
-get_insn_template (int code, rtx_insn *insn)
-{
- switch (insn_data[code].output_format)
- {
- case INSN_OUTPUT_FORMAT_SINGLE:
- return insn_data[code].output.single;
- case INSN_OUTPUT_FORMAT_MULTI:
- return insn_data[code].output.multi[which_alternative];
- case INSN_OUTPUT_FORMAT_FUNCTION:
- gcc_assert (insn);
- return (*insn_data[code].output.function) (recog_data.operand, insn);
-
- default:
- gcc_unreachable ();
- }
-}
-
-/* Emit the appropriate declaration for an alternate-entry-point
- symbol represented by INSN, to FILE. INSN is a CODE_LABEL with
- LABEL_KIND != LABEL_NORMAL.
-
- The case fall-through in this function is intentional. */
-static void
-output_alternate_entry_point (FILE *file, rtx_insn *insn)
-{
- const char *name = LABEL_NAME (insn);
-
- switch (LABEL_KIND (insn))
- {
- case LABEL_WEAK_ENTRY:
-#ifdef ASM_WEAKEN_LABEL
- ASM_WEAKEN_LABEL (file, name);
- gcc_fallthrough ();
-#endif
- case LABEL_GLOBAL_ENTRY:
- targetm.asm_out.globalize_label (file, name);
- gcc_fallthrough ();
- case LABEL_STATIC_ENTRY:
-#ifdef ASM_OUTPUT_TYPE_DIRECTIVE
- ASM_OUTPUT_TYPE_DIRECTIVE (file, name, "function");
-#endif
- ASM_OUTPUT_LABEL (file, name);
- break;
-
- case LABEL_NORMAL:
- default:
- gcc_unreachable ();
- }
-}
-
-/* Given a CALL_INSN, find and return the nested CALL. */
-static rtx
-call_from_call_insn (rtx_call_insn *insn)
-{
- rtx x;
- gcc_assert (CALL_P (insn));
- x = PATTERN (insn);
-
- while (GET_CODE (x) != CALL)
- {
- switch (GET_CODE (x))
- {
- default:
- gcc_unreachable ();
- case COND_EXEC:
- x = COND_EXEC_CODE (x);
- break;
- case PARALLEL:
- x = XVECEXP (x, 0, 0);
- break;
- case SET:
- x = XEXP (x, 1);
- break;
- }
- }
- return x;
-}
-
-/* Print a comment into the asm showing FILENAME, LINENUM, and the
- corresponding source line, if available. */
-
-static void
-asm_show_source (const char *filename, int linenum)
-{
- if (!filename)
- return;
-
- char_span line = location_get_source_line (filename, linenum);
- if (!line)
- return;
-
- fprintf (asm_out_file, "%s %s:%i: ", ASM_COMMENT_START, filename, linenum);
- /* "line" is not 0-terminated, so we must use its length. */
- fwrite (line.get_buffer (), 1, line.length (), asm_out_file);
- fputc ('\n', asm_out_file);
-}
-
-/* Judge if an absolute jump table is relocatable. */
-
-bool
-jumptable_relocatable (void)
-{
- bool relocatable = false;
-
- if (!CASE_VECTOR_PC_RELATIVE
- && !targetm.asm_out.generate_pic_addr_diff_vec ()
- && targetm_common.have_named_sections)
- relocatable = targetm.asm_out.reloc_rw_mask ();
-
- return relocatable;
-}
-
-/* The final scan for one insn, INSN.
- Args are same as in `final', except that INSN
- is the insn being scanned.
- Value returned is the next insn to be scanned.
-
- NOPEEPHOLES is the flag to disallow peephole processing (currently
- used for within delayed branch sequence output).
-
- SEEN is used to track the end of the prologue, for emitting
- debug information. We force the emission of a line note after
- both NOTE_INSN_PROLOGUE_END and NOTE_INSN_FUNCTION_BEG. */
-
-static rtx_insn *
-final_scan_insn_1 (rtx_insn *insn, FILE *file, int optimize_p ATTRIBUTE_UNUSED,
- int nopeepholes ATTRIBUTE_UNUSED, int *seen)
-{
- rtx_insn *next;
- rtx_jump_table_data *table;
-
- insn_counter++;
-
- /* Ignore deleted insns. These can occur when we split insns (due to a
- template of "#") while not optimizing. */
- if (insn->deleted ())
- return NEXT_INSN (insn);
-
- switch (GET_CODE (insn))
- {
- case NOTE:
- switch (NOTE_KIND (insn))
- {
- case NOTE_INSN_DELETED:
- case NOTE_INSN_UPDATE_SJLJ_CONTEXT:
- break;
-
- case NOTE_INSN_SWITCH_TEXT_SECTIONS:
- maybe_output_next_view (seen);
-
- output_function_exception_table (0);
-
- if (targetm.asm_out.unwind_emit)
- targetm.asm_out.unwind_emit (asm_out_file, insn);
-
- in_cold_section_p = !in_cold_section_p;
-
- gcc_checking_assert (in_cold_section_p);
- if (in_cold_section_p)
- cold_function_name
- = clone_function_name (current_function_decl, "cold");
-
- if (dwarf2out_do_frame ())
- {
- dwarf2out_switch_text_section ();
- if (!dwarf2_debug_info_emitted_p (current_function_decl)
- && !DECL_IGNORED_P (current_function_decl))
- debug_hooks->switch_text_section ();
- }
- else if (!DECL_IGNORED_P (current_function_decl))
- debug_hooks->switch_text_section ();
- if (DECL_IGNORED_P (current_function_decl) && last_linenum
- && last_filename)
- debug_hooks->set_ignored_loc (last_linenum, last_columnnum,
- last_filename);
-
- switch_to_section (current_function_section ());
- targetm.asm_out.function_switched_text_sections (asm_out_file,
- current_function_decl,
- in_cold_section_p);
- /* Emit a label for the split cold section. Form label name by
- suffixing "cold" to the original function's name. */
- if (in_cold_section_p)
- {
-#ifdef ASM_DECLARE_COLD_FUNCTION_NAME
- ASM_DECLARE_COLD_FUNCTION_NAME (asm_out_file,
- IDENTIFIER_POINTER
- (cold_function_name),
- current_function_decl);
-#else
- ASM_OUTPUT_LABEL (asm_out_file,
- IDENTIFIER_POINTER (cold_function_name));
-#endif
- if (dwarf2out_do_frame ()
- && cfun->fde->dw_fde_second_begin != NULL)
- ASM_OUTPUT_LABEL (asm_out_file, cfun->fde->dw_fde_second_begin);
- }
- break;
-
- case NOTE_INSN_BASIC_BLOCK:
- if (need_profile_function)
- {
- profile_function (asm_out_file);
- need_profile_function = false;
- }
-
- if (targetm.asm_out.unwind_emit)
- targetm.asm_out.unwind_emit (asm_out_file, insn);
-
- bb_discriminator = NOTE_BASIC_BLOCK (insn)->discriminator;
- break;
-
- case NOTE_INSN_EH_REGION_BEG:
- ASM_OUTPUT_DEBUG_LABEL (asm_out_file, "LEHB",
- NOTE_EH_HANDLER (insn));
- break;
-
- case NOTE_INSN_EH_REGION_END:
- ASM_OUTPUT_DEBUG_LABEL (asm_out_file, "LEHE",
- NOTE_EH_HANDLER (insn));
- break;
-
- case NOTE_INSN_PROLOGUE_END:
- targetm.asm_out.function_end_prologue (file);
- profile_after_prologue (file);
-
- if ((*seen & (SEEN_EMITTED | SEEN_NOTE)) == SEEN_NOTE)
- {
- *seen |= SEEN_EMITTED;
- force_source_line = true;
- }
- else
- *seen |= SEEN_NOTE;
-
- break;
-
- case NOTE_INSN_EPILOGUE_BEG:
- if (!DECL_IGNORED_P (current_function_decl))
- (*debug_hooks->begin_epilogue) (last_linenum, last_filename);
- targetm.asm_out.function_begin_epilogue (file);
- break;
-
- case NOTE_INSN_CFI:
- dwarf2out_emit_cfi (NOTE_CFI (insn));
- break;
-
- case NOTE_INSN_CFI_LABEL:
- ASM_OUTPUT_DEBUG_LABEL (asm_out_file, "LCFI",
- NOTE_LABEL_NUMBER (insn));
- break;
-
- case NOTE_INSN_FUNCTION_BEG:
- if (need_profile_function)
- {
- profile_function (asm_out_file);
- need_profile_function = false;
- }
-
- app_disable ();
- if (!DECL_IGNORED_P (current_function_decl))
- debug_hooks->end_prologue (last_linenum, last_filename);
-
- if ((*seen & (SEEN_EMITTED | SEEN_NOTE)) == SEEN_NOTE)
- {
- *seen |= SEEN_EMITTED;
- force_source_line = true;
- }
- else
- *seen |= SEEN_NOTE;
-
- break;
-
- case NOTE_INSN_BLOCK_BEG:
- if (debug_info_level >= DINFO_LEVEL_NORMAL
- || dwarf_debuginfo_p ()
- || write_symbols == VMS_DEBUG)
- {
- int n = BLOCK_NUMBER (NOTE_BLOCK (insn));
-
- app_disable ();
- ++block_depth;
- high_block_linenum = last_linenum;
-
- /* Output debugging info about the symbol-block beginning. */
- if (!DECL_IGNORED_P (current_function_decl))
- debug_hooks->begin_block (last_linenum, n);
-
- /* Mark this block as output. */
- TREE_ASM_WRITTEN (NOTE_BLOCK (insn)) = 1;
- BLOCK_IN_COLD_SECTION_P (NOTE_BLOCK (insn)) = in_cold_section_p;
- }
- if (write_symbols == DBX_DEBUG)
- {
- location_t *locus_ptr
- = block_nonartificial_location (NOTE_BLOCK (insn));
-
- if (locus_ptr != NULL)
- {
- override_filename = LOCATION_FILE (*locus_ptr);
- override_linenum = LOCATION_LINE (*locus_ptr);
- override_columnnum = LOCATION_COLUMN (*locus_ptr);
- override_discriminator = compute_discriminator (*locus_ptr);
- }
- }
- break;
-
- case NOTE_INSN_BLOCK_END:
- maybe_output_next_view (seen);
-
- if (debug_info_level >= DINFO_LEVEL_NORMAL
- || dwarf_debuginfo_p ()
- || write_symbols == VMS_DEBUG)
- {
- int n = BLOCK_NUMBER (NOTE_BLOCK (insn));
-
- app_disable ();
-
- /* End of a symbol-block. */
- --block_depth;
- gcc_assert (block_depth >= 0);
-
- if (!DECL_IGNORED_P (current_function_decl))
- debug_hooks->end_block (high_block_linenum, n);
- gcc_assert (BLOCK_IN_COLD_SECTION_P (NOTE_BLOCK (insn))
- == in_cold_section_p);
- }
- if (write_symbols == DBX_DEBUG)
- {
- tree outer_block = BLOCK_SUPERCONTEXT (NOTE_BLOCK (insn));
- location_t *locus_ptr
- = block_nonartificial_location (outer_block);
-
- if (locus_ptr != NULL)
- {
- override_filename = LOCATION_FILE (*locus_ptr);
- override_linenum = LOCATION_LINE (*locus_ptr);
- override_columnnum = LOCATION_COLUMN (*locus_ptr);
- override_discriminator = compute_discriminator (*locus_ptr);
- }
- else
- {
- override_filename = NULL;
- override_linenum = 0;
- override_columnnum = 0;
- override_discriminator = 0;
- }
- }
- break;
-
- case NOTE_INSN_DELETED_LABEL:
- /* Emit the label. We may have deleted the CODE_LABEL because
- the label could be proved to be unreachable, though still
- referenced (in the form of having its address taken. */
- ASM_OUTPUT_DEBUG_LABEL (file, "L", CODE_LABEL_NUMBER (insn));
- break;
-
- case NOTE_INSN_DELETED_DEBUG_LABEL:
- /* Similarly, but need to use different namespace for it. */
- if (CODE_LABEL_NUMBER (insn) != -1)
- ASM_OUTPUT_DEBUG_LABEL (file, "LDL", CODE_LABEL_NUMBER (insn));
- break;
-
- case NOTE_INSN_VAR_LOCATION:
- if (!DECL_IGNORED_P (current_function_decl))
- {
- debug_hooks->var_location (insn);
- set_next_view_needed (seen);
- }
- break;
-
- case NOTE_INSN_BEGIN_STMT:
- gcc_checking_assert (cfun->debug_nonbind_markers);
- if (!DECL_IGNORED_P (current_function_decl)
- && notice_source_line (insn, NULL))
- {
- output_source_line:
- (*debug_hooks->source_line) (last_linenum, last_columnnum,
- last_filename, last_discriminator,
- true);
- clear_next_view_needed (seen);
- }
- break;
-
- case NOTE_INSN_INLINE_ENTRY:
- gcc_checking_assert (cfun->debug_nonbind_markers);
- if (!DECL_IGNORED_P (current_function_decl)
- && notice_source_line (insn, NULL))
- {
- (*debug_hooks->inline_entry) (LOCATION_BLOCK
- (NOTE_MARKER_LOCATION (insn)));
- goto output_source_line;
- }
- break;
-
- default:
- gcc_unreachable ();
- break;
- }
- break;
-
- case BARRIER:
- break;
-
- case CODE_LABEL:
- /* The target port might emit labels in the output function for
- some insn, e.g. sh.c output_branchy_insn. */
- if (CODE_LABEL_NUMBER (insn) <= max_labelno)
- {
- align_flags alignment = LABEL_TO_ALIGNMENT (insn);
- if (alignment.levels[0].log && NEXT_INSN (insn))
- {
-#ifdef ASM_OUTPUT_MAX_SKIP_ALIGN
- /* Output both primary and secondary alignment. */
- ASM_OUTPUT_MAX_SKIP_ALIGN (file, alignment.levels[0].log,
- alignment.levels[0].maxskip);
- ASM_OUTPUT_MAX_SKIP_ALIGN (file, alignment.levels[1].log,
- alignment.levels[1].maxskip);
-#else
-#ifdef ASM_OUTPUT_ALIGN_WITH_NOP
- ASM_OUTPUT_ALIGN_WITH_NOP (file, alignment.levels[0].log);
-#else
- ASM_OUTPUT_ALIGN (file, alignment.levels[0].log);
-#endif
-#endif
- }
- }
- CC_STATUS_INIT;
-
- if (!DECL_IGNORED_P (current_function_decl) && LABEL_NAME (insn))
- debug_hooks->label (as_a <rtx_code_label *> (insn));
-
- app_disable ();
-
- /* If this label is followed by a jump-table, make sure we put
- the label in the read-only section. Also possibly write the
- label and jump table together. */
- table = jump_table_for_label (as_a <rtx_code_label *> (insn));
- if (table)
- {
-#if defined(ASM_OUTPUT_ADDR_VEC) || defined(ASM_OUTPUT_ADDR_DIFF_VEC)
- /* In this case, the case vector is being moved by the
- target, so don't output the label at all. Leave that
- to the back end macros. */
-#else
- if (! JUMP_TABLES_IN_TEXT_SECTION)
- {
- int log_align;
-
- switch_to_section (targetm.asm_out.function_rodata_section
- (current_function_decl,
- jumptable_relocatable ()));
-
-#ifdef ADDR_VEC_ALIGN
- log_align = ADDR_VEC_ALIGN (table);
-#else
- log_align = exact_log2 (BIGGEST_ALIGNMENT / BITS_PER_UNIT);
-#endif
- ASM_OUTPUT_ALIGN (file, log_align);
- }
- else
- switch_to_section (current_function_section ());
-
-#ifdef ASM_OUTPUT_CASE_LABEL
- ASM_OUTPUT_CASE_LABEL (file, "L", CODE_LABEL_NUMBER (insn), table);
-#else
- targetm.asm_out.internal_label (file, "L", CODE_LABEL_NUMBER (insn));
-#endif
-#endif
- break;
- }
- if (LABEL_ALT_ENTRY_P (insn))
- output_alternate_entry_point (file, insn);
- else
- targetm.asm_out.internal_label (file, "L", CODE_LABEL_NUMBER (insn));
- break;
-
- default:
- {
- rtx body = PATTERN (insn);
- int insn_code_number;
- const char *templ;
- bool is_stmt, *is_stmt_p;
-
- if (MAY_HAVE_DEBUG_MARKER_INSNS && cfun->debug_nonbind_markers)
- {
- is_stmt = false;
- is_stmt_p = NULL;
- }
- else
- is_stmt_p = &is_stmt;
-
- /* Reset this early so it is correct for ASM statements. */
- current_insn_predicate = NULL_RTX;
-
- /* An INSN, JUMP_INSN or CALL_INSN.
- First check for special kinds that recog doesn't recognize. */
-
- if (GET_CODE (body) == USE /* These are just declarations. */
- || GET_CODE (body) == CLOBBER)
- break;
-
- /* Detect insns that are really jump-tables
- and output them as such. */
-
- if (JUMP_TABLE_DATA_P (insn))
- {
-#if !(defined(ASM_OUTPUT_ADDR_VEC) || defined(ASM_OUTPUT_ADDR_DIFF_VEC))
- int vlen, idx;
-#endif
-
- if (! JUMP_TABLES_IN_TEXT_SECTION)
- switch_to_section (targetm.asm_out.function_rodata_section
- (current_function_decl,
- jumptable_relocatable ()));
- else
- switch_to_section (current_function_section ());
-
- app_disable ();
-
-#if defined(ASM_OUTPUT_ADDR_VEC) || defined(ASM_OUTPUT_ADDR_DIFF_VEC)
- if (GET_CODE (body) == ADDR_VEC)
- {
-#ifdef ASM_OUTPUT_ADDR_VEC
- ASM_OUTPUT_ADDR_VEC (PREV_INSN (insn), body);
-#else
- gcc_unreachable ();
-#endif
- }
- else
- {
-#ifdef ASM_OUTPUT_ADDR_DIFF_VEC
- ASM_OUTPUT_ADDR_DIFF_VEC (PREV_INSN (insn), body);
-#else
- gcc_unreachable ();
-#endif
- }
-#else
- vlen = XVECLEN (body, GET_CODE (body) == ADDR_DIFF_VEC);
- for (idx = 0; idx < vlen; idx++)
- {
- if (GET_CODE (body) == ADDR_VEC)
- {
-#ifdef ASM_OUTPUT_ADDR_VEC_ELT
- ASM_OUTPUT_ADDR_VEC_ELT
- (file, CODE_LABEL_NUMBER (XEXP (XVECEXP (body, 0, idx), 0)));
-#else
- gcc_unreachable ();
-#endif
- }
- else
- {
-#ifdef ASM_OUTPUT_ADDR_DIFF_ELT
- ASM_OUTPUT_ADDR_DIFF_ELT
- (file,
- body,
- CODE_LABEL_NUMBER (XEXP (XVECEXP (body, 1, idx), 0)),
- CODE_LABEL_NUMBER (XEXP (XEXP (body, 0), 0)));
-#else
- gcc_unreachable ();
-#endif
- }
- }
-#ifdef ASM_OUTPUT_CASE_END
- ASM_OUTPUT_CASE_END (file,
- CODE_LABEL_NUMBER (PREV_INSN (insn)),
- insn);
-#endif
-#endif
-
- switch_to_section (current_function_section ());
-
- if (debug_variable_location_views
- && !DECL_IGNORED_P (current_function_decl))
- debug_hooks->var_location (insn);
-
- break;
- }
- /* Output this line note if it is the first or the last line
- note in a row. */
- if (!DECL_IGNORED_P (current_function_decl)
- && notice_source_line (insn, is_stmt_p))
- {
- if (flag_verbose_asm)
- asm_show_source (last_filename, last_linenum);
- (*debug_hooks->source_line) (last_linenum, last_columnnum,
- last_filename, last_discriminator,
- is_stmt);
- clear_next_view_needed (seen);
- }
- else
- maybe_output_next_view (seen);
-
- gcc_checking_assert (!DEBUG_INSN_P (insn));
-
- if (GET_CODE (body) == PARALLEL
- && GET_CODE (XVECEXP (body, 0, 0)) == ASM_INPUT)
- body = XVECEXP (body, 0, 0);
-
- if (GET_CODE (body) == ASM_INPUT)
- {
- const char *string = XSTR (body, 0);
-
- /* There's no telling what that did to the condition codes. */
- CC_STATUS_INIT;
-
- if (string[0])
- {
- expanded_location loc;
-
- app_enable ();
- loc = expand_location (ASM_INPUT_SOURCE_LOCATION (body));
- if (*loc.file && loc.line)
- fprintf (asm_out_file, "%s %i \"%s\" 1\n",
- ASM_COMMENT_START, loc.line, loc.file);
- fprintf (asm_out_file, "\t%s\n", string);
-#if HAVE_AS_LINE_ZERO
- if (*loc.file && loc.line)
- fprintf (asm_out_file, "%s 0 \"\" 2\n", ASM_COMMENT_START);
-#endif
- }
- break;
- }
-
- /* Detect `asm' construct with operands. */
- if (asm_noperands (body) >= 0)
- {
- unsigned int noperands = asm_noperands (body);
- rtx *ops = XALLOCAVEC (rtx, noperands);
- const char *string;
- location_t loc;
- expanded_location expanded;
-
- /* There's no telling what that did to the condition codes. */
- CC_STATUS_INIT;
-
- /* Get out the operand values. */
- string = decode_asm_operands (body, ops, NULL, NULL, NULL, &loc);
- /* Inhibit dying on what would otherwise be compiler bugs. */
- insn_noperands = noperands;
- this_is_asm_operands = insn;
- expanded = expand_location (loc);
-
-#ifdef FINAL_PRESCAN_INSN
- FINAL_PRESCAN_INSN (insn, ops, insn_noperands);
-#endif
-
- /* Output the insn using them. */
- if (string[0])
- {
- app_enable ();
- if (expanded.file && expanded.line)
- fprintf (asm_out_file, "%s %i \"%s\" 1\n",
- ASM_COMMENT_START, expanded.line, expanded.file);
- output_asm_insn (string, ops);
-#if HAVE_AS_LINE_ZERO
- if (expanded.file && expanded.line)
- fprintf (asm_out_file, "%s 0 \"\" 2\n", ASM_COMMENT_START);
-#endif
- }
-
- if (targetm.asm_out.final_postscan_insn)
- targetm.asm_out.final_postscan_insn (file, insn, ops,
- insn_noperands);
-
- this_is_asm_operands = 0;
- break;
- }
-
- app_disable ();
-
- if (rtx_sequence *seq = dyn_cast <rtx_sequence *> (body))
- {
- /* A delayed-branch sequence */
- int i;
-
- final_sequence = seq;
-
- /* The first insn in this SEQUENCE might be a JUMP_INSN that will
- force the restoration of a comparison that was previously
- thought unnecessary. If that happens, cancel this sequence
- and cause that insn to be restored. */
-
- next = final_scan_insn (seq->insn (0), file, 0, 1, seen);
- if (next != seq->insn (1))
- {
- final_sequence = 0;
- return next;
- }
-
- for (i = 1; i < seq->len (); i++)
- {
- rtx_insn *insn = seq->insn (i);
- rtx_insn *next = NEXT_INSN (insn);
- /* We loop in case any instruction in a delay slot gets
- split. */
- do
- insn = final_scan_insn (insn, file, 0, 1, seen);
- while (insn != next);
- }
-#ifdef DBR_OUTPUT_SEQEND
- DBR_OUTPUT_SEQEND (file);
-#endif
- final_sequence = 0;
-
- /* If the insn requiring the delay slot was a CALL_INSN, the
- insns in the delay slot are actually executed before the
- called function. Hence we don't preserve any CC-setting
- actions in these insns and the CC must be marked as being
- clobbered by the function. */
- if (CALL_P (seq->insn (0)))
- {
- CC_STATUS_INIT;
- }
- break;
- }
-
- /* We have a real machine instruction as rtl. */
-
- body = PATTERN (insn);
-
- /* Do machine-specific peephole optimizations if desired. */
-
- if (HAVE_peephole && optimize_p && !flag_no_peephole && !nopeepholes)
- {
- rtx_insn *next = peephole (insn);
- /* When peepholing, if there were notes within the peephole,
- emit them before the peephole. */
- if (next != 0 && next != NEXT_INSN (insn))
- {
- rtx_insn *note, *prev = PREV_INSN (insn);
-
- for (note = NEXT_INSN (insn); note != next;
- note = NEXT_INSN (note))
- final_scan_insn (note, file, optimize_p, nopeepholes, seen);
-
- /* Put the notes in the proper position for a later
- rescan. For example, the SH target can do this
- when generating a far jump in a delayed branch
- sequence. */
- note = NEXT_INSN (insn);
- SET_PREV_INSN (note) = prev;
- SET_NEXT_INSN (prev) = note;
- SET_NEXT_INSN (PREV_INSN (next)) = insn;
- SET_PREV_INSN (insn) = PREV_INSN (next);
- SET_NEXT_INSN (insn) = next;
- SET_PREV_INSN (next) = insn;
- }
-
- /* PEEPHOLE might have changed this. */
- body = PATTERN (insn);
- }
-
- /* Try to recognize the instruction.
- If successful, verify that the operands satisfy the
- constraints for the instruction. Crash if they don't,
- since `reload' should have changed them so that they do. */
-
- insn_code_number = recog_memoized (insn);
- cleanup_subreg_operands (insn);
-
- /* Dump the insn in the assembly for debugging (-dAP).
- If the final dump is requested as slim RTL, dump slim
- RTL to the assembly file also. */
- if (flag_dump_rtl_in_asm)
- {
- print_rtx_head = ASM_COMMENT_START;
- if (! (dump_flags & TDF_SLIM))
- print_rtl_single (asm_out_file, insn);
- else
- dump_insn_slim (asm_out_file, insn);
- print_rtx_head = "";
- }
-
- if (! constrain_operands_cached (insn, 1))
- fatal_insn_not_found (insn);
-
- /* Some target machines need to prescan each insn before
- it is output. */
-
-#ifdef FINAL_PRESCAN_INSN
- FINAL_PRESCAN_INSN (insn, recog_data.operand, recog_data.n_operands);
-#endif
-
- if (targetm.have_conditional_execution ()
- && GET_CODE (PATTERN (insn)) == COND_EXEC)
- current_insn_predicate = COND_EXEC_TEST (PATTERN (insn));
-
- current_output_insn = debug_insn = insn;
-
- /* Find the proper template for this insn. */
- templ = get_insn_template (insn_code_number, insn);
-
- /* If the C code returns 0, it means that it is a jump insn
- which follows a deleted test insn, and that test insn
- needs to be reinserted. */
- if (templ == 0)
- {
- rtx_insn *prev;
-
- gcc_assert (prev_nonnote_insn (insn) == last_ignored_compare);
-
- /* We have already processed the notes between the setter and
- the user. Make sure we don't process them again, this is
- particularly important if one of the notes is a block
- scope note or an EH note. */
- for (prev = insn;
- prev != last_ignored_compare;
- prev = PREV_INSN (prev))
- {
- if (NOTE_P (prev))
- delete_insn (prev); /* Use delete_note. */
- }
-
- return prev;
- }
-
- /* If the template is the string "#", it means that this insn must
- be split. */
- if (templ[0] == '#' && templ[1] == '\0')
- {
- rtx_insn *new_rtx = try_split (body, insn, 0);
-
- /* If we didn't split the insn, go away. */
- if (new_rtx == insn && PATTERN (new_rtx) == body)
- fatal_insn ("could not split insn", insn);
-
- /* If we have a length attribute, this instruction should have
- been split in shorten_branches, to ensure that we would have
- valid length info for the splitees. */
- gcc_assert (!HAVE_ATTR_length);
-
- return new_rtx;
- }
-
- /* ??? This will put the directives in the wrong place if
- get_insn_template outputs assembly directly. However calling it
- before get_insn_template breaks if the insns is split. */
- if (targetm.asm_out.unwind_emit_before_insn
- && targetm.asm_out.unwind_emit)
- targetm.asm_out.unwind_emit (asm_out_file, insn);
-
- rtx_call_insn *call_insn = dyn_cast <rtx_call_insn *> (insn);
- if (call_insn != NULL)
- {
- rtx x = call_from_call_insn (call_insn);
- x = XEXP (x, 0);
- if (x && MEM_P (x) && GET_CODE (XEXP (x, 0)) == SYMBOL_REF)
- {
- tree t;
- x = XEXP (x, 0);
- t = SYMBOL_REF_DECL (x);
- if (t)
- assemble_external (t);
- }
- }
-
- /* Output assembler code from the template. */
- output_asm_insn (templ, recog_data.operand);
-
- /* Some target machines need to postscan each insn after
- it is output. */
- if (targetm.asm_out.final_postscan_insn)
- targetm.asm_out.final_postscan_insn (file, insn, recog_data.operand,
- recog_data.n_operands);
-
- if (!targetm.asm_out.unwind_emit_before_insn
- && targetm.asm_out.unwind_emit)
- targetm.asm_out.unwind_emit (asm_out_file, insn);
-
- /* Let the debug info back-end know about this call. We do this only
- after the instruction has been emitted because labels that may be
- created to reference the call instruction must appear after it. */
- if ((debug_variable_location_views || call_insn != NULL)
- && !DECL_IGNORED_P (current_function_decl))
- debug_hooks->var_location (insn);
-
- current_output_insn = debug_insn = 0;
- }
- }
- return NEXT_INSN (insn);
-}
-
-/* This is a wrapper around final_scan_insn_1 that allows ports to
- call it recursively without a known value for SEEN. The value is
- saved at the outermost call, and recovered for recursive calls.
- Recursive calls MUST pass NULL, or the same pointer if they can
- otherwise get to it. */
-
-rtx_insn *
-final_scan_insn (rtx_insn *insn, FILE *file, int optimize_p,
- int nopeepholes, int *seen)
-{
- static int *enclosing_seen;
- static int recursion_counter;
-
- gcc_assert (seen || recursion_counter);
- gcc_assert (!recursion_counter || !seen || seen == enclosing_seen);
-
- if (!recursion_counter++)
- enclosing_seen = seen;
- else if (!seen)
- seen = enclosing_seen;
-
- rtx_insn *ret = final_scan_insn_1 (insn, file, optimize_p, nopeepholes, seen);
-
- if (!--recursion_counter)
- enclosing_seen = NULL;
-
- return ret;
-}
-
-
-
-/* Map DECLs to instance discriminators. This is allocated and
- defined in ada/gcc-interfaces/trans.c, when compiling with -gnateS.
- Mappings from this table are saved and restored for LTO, so
- link-time compilation will have this map set, at least in
- partitions containing at least one DECL with an associated instance
- discriminator. */
-
-decl_to_instance_map_t *decl_to_instance_map;
-
-/* Return the instance number assigned to DECL. */
-
-static inline int
-map_decl_to_instance (const_tree decl)
-{
- int *inst;
-
- if (!decl_to_instance_map || !decl || !DECL_P (decl))
- return 0;
-
- inst = decl_to_instance_map->get (decl);
-
- if (!inst)
- return 0;
-
- return *inst;
-}
-
-/* Set DISCRIMINATOR to the appropriate value, possibly derived from LOC. */
-
-static inline int
-compute_discriminator (location_t loc)
-{
- int discriminator;
-
- if (!decl_to_instance_map)
- discriminator = bb_discriminator;
- else
- {
- tree block = LOCATION_BLOCK (loc);
-
- while (block && TREE_CODE (block) == BLOCK
- && !inlined_function_outer_scope_p (block))
- block = BLOCK_SUPERCONTEXT (block);
-
- tree decl;
-
- if (!block)
- decl = current_function_decl;
- else if (DECL_P (block))
- decl = block;
- else
- decl = block_ultimate_origin (block);
-
- discriminator = map_decl_to_instance (decl);
- }
-
- return discriminator;
-}
-
-/* Return whether a source line note needs to be emitted before INSN.
- Sets IS_STMT to TRUE if the line should be marked as a possible
- breakpoint location. */
-
-static bool
-notice_source_line (rtx_insn *insn, bool *is_stmt)
-{
- const char *filename;
- int linenum, columnnum;
-
- if (NOTE_MARKER_P (insn))
- {
- location_t loc = NOTE_MARKER_LOCATION (insn);
- expanded_location xloc = expand_location (loc);
- if (xloc.line == 0
- && (LOCATION_LOCUS (loc) == UNKNOWN_LOCATION
- || LOCATION_LOCUS (loc) == BUILTINS_LOCATION))
- return false;
-
- filename = xloc.file;
- linenum = xloc.line;
- columnnum = xloc.column;
- discriminator = compute_discriminator (loc);
- force_source_line = true;
- }
- else if (override_filename)
- {
- filename = override_filename;
- linenum = override_linenum;
- columnnum = override_columnnum;
- discriminator = override_discriminator;
- }
- else if (INSN_HAS_LOCATION (insn))
- {
- expanded_location xloc = insn_location (insn);
- filename = xloc.file;
- linenum = xloc.line;
- columnnum = xloc.column;
- discriminator = compute_discriminator (INSN_LOCATION (insn));
- }
- else
- {
- filename = NULL;
- linenum = 0;
- columnnum = 0;
- discriminator = 0;
- }
-
- if (filename == NULL)
- return false;
-
- if (force_source_line
- || filename != last_filename
- || last_linenum != linenum
- || (debug_column_info && last_columnnum != columnnum))
- {
- force_source_line = false;
- last_filename = filename;
- last_linenum = linenum;
- last_columnnum = columnnum;
- last_discriminator = discriminator;
- if (is_stmt)
- *is_stmt = true;
- high_block_linenum = MAX (last_linenum, high_block_linenum);
- high_function_linenum = MAX (last_linenum, high_function_linenum);
- return true;
- }
-
- if (SUPPORTS_DISCRIMINATOR && last_discriminator != discriminator)
- {
- /* If the discriminator changed, but the line number did not,
- output the line table entry with is_stmt false so the
- debugger does not treat this as a breakpoint location. */
- last_discriminator = discriminator;
- if (is_stmt)
- *is_stmt = false;
- return true;
- }
-
- return false;
-}
-
-/* For each operand in INSN, simplify (subreg (reg)) so that it refers
- directly to the desired hard register. */
-
-void
-cleanup_subreg_operands (rtx_insn *insn)
-{
- int i;
- bool changed = false;
- extract_insn_cached (insn);
- for (i = 0; i < recog_data.n_operands; i++)
- {
- /* The following test cannot use recog_data.operand when testing
- for a SUBREG: the underlying object might have been changed
- already if we are inside a match_operator expression that
- matches the else clause. Instead we test the underlying
- expression directly. */
- if (GET_CODE (*recog_data.operand_loc[i]) == SUBREG)
- {
- recog_data.operand[i] = alter_subreg (recog_data.operand_loc[i], true);
- changed = true;
- }
- else if (GET_CODE (recog_data.operand[i]) == PLUS
- || GET_CODE (recog_data.operand[i]) == MULT
- || MEM_P (recog_data.operand[i]))
- recog_data.operand[i] = walk_alter_subreg (recog_data.operand_loc[i], &changed);
- }
-
- for (i = 0; i < recog_data.n_dups; i++)
- {
- if (GET_CODE (*recog_data.dup_loc[i]) == SUBREG)
- {
- *recog_data.dup_loc[i] = alter_subreg (recog_data.dup_loc[i], true);
- changed = true;
- }
- else if (GET_CODE (*recog_data.dup_loc[i]) == PLUS
- || GET_CODE (*recog_data.dup_loc[i]) == MULT
- || MEM_P (*recog_data.dup_loc[i]))
- *recog_data.dup_loc[i] = walk_alter_subreg (recog_data.dup_loc[i], &changed);
- }
- if (changed)
- df_insn_rescan (insn);
-}
-
-/* If X is a SUBREG, try to replace it with a REG or a MEM, based on
- the thing it is a subreg of. Do it anyway if FINAL_P. */
-
-rtx
-alter_subreg (rtx *xp, bool final_p)
-{
- rtx x = *xp;
- rtx y = SUBREG_REG (x);
-
- /* simplify_subreg does not remove subreg from volatile references.
- We are required to. */
- if (MEM_P (y))
- {
- poly_int64 offset = SUBREG_BYTE (x);
-
- /* For paradoxical subregs on big-endian machines, SUBREG_BYTE
- contains 0 instead of the proper offset. See simplify_subreg. */
- if (paradoxical_subreg_p (x))
- offset = byte_lowpart_offset (GET_MODE (x), GET_MODE (y));
-
- if (final_p)
- *xp = adjust_address (y, GET_MODE (x), offset);
- else
- *xp = adjust_address_nv (y, GET_MODE (x), offset);
- }
- else if (REG_P (y) && HARD_REGISTER_P (y))
- {
- rtx new_rtx = simplify_subreg (GET_MODE (x), y, GET_MODE (y),
- SUBREG_BYTE (x));
-
- if (new_rtx != 0)
- *xp = new_rtx;
- else if (final_p && REG_P (y))
- {
- /* Simplify_subreg can't handle some REG cases, but we have to. */
- unsigned int regno;
- poly_int64 offset;
-
- regno = subreg_regno (x);
- if (subreg_lowpart_p (x))
- offset = byte_lowpart_offset (GET_MODE (x), GET_MODE (y));
- else
- offset = SUBREG_BYTE (x);
- *xp = gen_rtx_REG_offset (y, GET_MODE (x), regno, offset);
- }
- }
-
- return *xp;
-}
-
-/* Do alter_subreg on all the SUBREGs contained in X. */
-
-static rtx
-walk_alter_subreg (rtx *xp, bool *changed)
-{
- rtx x = *xp;
- switch (GET_CODE (x))
- {
- case PLUS:
- case MULT:
- case AND:
- XEXP (x, 0) = walk_alter_subreg (&XEXP (x, 0), changed);
- XEXP (x, 1) = walk_alter_subreg (&XEXP (x, 1), changed);
- break;
-
- case MEM:
- case ZERO_EXTEND:
- XEXP (x, 0) = walk_alter_subreg (&XEXP (x, 0), changed);
- break;
-
- case SUBREG:
- *changed = true;
- return alter_subreg (xp, true);
-
- default:
- break;
- }
-
- return *xp;
-}
-
-/* Report inconsistency between the assembler template and the operands.
- In an `asm', it's the user's fault; otherwise, the compiler's fault. */
-
-void
-output_operand_lossage (const char *cmsgid, ...)
-{
- char *fmt_string;
- char *new_message;
- const char *pfx_str;
- va_list ap;
-
- va_start (ap, cmsgid);
-
- pfx_str = this_is_asm_operands ? _("invalid 'asm': ") : "output_operand: ";
- fmt_string = xasprintf ("%s%s", pfx_str, _(cmsgid));
- new_message = xvasprintf (fmt_string, ap);
-
- if (this_is_asm_operands)
- error_for_asm (this_is_asm_operands, "%s", new_message);
- else
- internal_error ("%s", new_message);
-
- free (fmt_string);
- free (new_message);
- va_end (ap);
-}
-
-/* Output of assembler code from a template, and its subroutines. */
-
-/* Annotate the assembly with a comment describing the pattern and
- alternative used. */
-
-static void
-output_asm_name (void)
-{
- if (debug_insn)
- {
- fprintf (asm_out_file, "\t%s %d\t",
- ASM_COMMENT_START, INSN_UID (debug_insn));
-
- fprintf (asm_out_file, "[c=%d",
- insn_cost (debug_insn, optimize_insn_for_speed_p ()));
- if (HAVE_ATTR_length)
- fprintf (asm_out_file, " l=%d",
- get_attr_length (debug_insn));
- fprintf (asm_out_file, "] ");
-
- int num = INSN_CODE (debug_insn);
- fprintf (asm_out_file, "%s", insn_data[num].name);
- if (insn_data[num].n_alternatives > 1)
- fprintf (asm_out_file, "/%d", which_alternative);
-
- /* Clear this so only the first assembler insn
- of any rtl insn will get the special comment for -dp. */
- debug_insn = 0;
- }
-}
-
-/* If OP is a REG or MEM and we can find a MEM_EXPR corresponding to it
- or its address, return that expr . Set *PADDRESSP to 1 if the expr
- corresponds to the address of the object and 0 if to the object. */
-
-static tree
-get_mem_expr_from_op (rtx op, int *paddressp)
-{
- tree expr;
- int inner_addressp;
-
- *paddressp = 0;
-
- if (REG_P (op))
- return REG_EXPR (op);
- else if (!MEM_P (op))
- return 0;
-
- if (MEM_EXPR (op) != 0)
- return MEM_EXPR (op);
-
- /* Otherwise we have an address, so indicate it and look at the address. */
- *paddressp = 1;
- op = XEXP (op, 0);
-
- /* First check if we have a decl for the address, then look at the right side
- if it is a PLUS. Otherwise, strip off arithmetic and keep looking.
- But don't allow the address to itself be indirect. */
- if ((expr = get_mem_expr_from_op (op, &inner_addressp)) && ! inner_addressp)
- return expr;
- else if (GET_CODE (op) == PLUS
- && (expr = get_mem_expr_from_op (XEXP (op, 1), &inner_addressp)))
- return expr;
-
- while (UNARY_P (op)
- || GET_RTX_CLASS (GET_CODE (op)) == RTX_BIN_ARITH)
- op = XEXP (op, 0);
-
- expr = get_mem_expr_from_op (op, &inner_addressp);
- return inner_addressp ? 0 : expr;
-}
-
-/* Output operand names for assembler instructions. OPERANDS is the
- operand vector, OPORDER is the order to write the operands, and NOPS
- is the number of operands to write. */
-
-static void
-output_asm_operand_names (rtx *operands, int *oporder, int nops)
-{
- int wrote = 0;
- int i;
-
- for (i = 0; i < nops; i++)
- {
- int addressp;
- rtx op = operands[oporder[i]];
- tree expr = get_mem_expr_from_op (op, &addressp);
-
- fprintf (asm_out_file, "%c%s",
- wrote ? ',' : '\t', wrote ? "" : ASM_COMMENT_START);
- wrote = 1;
- if (expr)
- {
- fprintf (asm_out_file, "%s",
- addressp ? "*" : "");
- print_mem_expr (asm_out_file, expr);
- wrote = 1;
- }
- else if (REG_P (op) && ORIGINAL_REGNO (op)
- && ORIGINAL_REGNO (op) != REGNO (op))
- fprintf (asm_out_file, " tmp%i", ORIGINAL_REGNO (op));
- }
-}
-
-#ifdef ASSEMBLER_DIALECT
-/* Helper function to parse assembler dialects in the asm string.
- This is called from output_asm_insn and asm_fprintf. */
-static const char *
-do_assembler_dialects (const char *p, int *dialect)
-{
- char c = *(p - 1);
-
- switch (c)
- {
- case '{':
- {
- int i;
-
- if (*dialect)
- output_operand_lossage ("nested assembly dialect alternatives");
- else
- *dialect = 1;
-
- /* If we want the first dialect, do nothing. Otherwise, skip
- DIALECT_NUMBER of strings ending with '|'. */
- for (i = 0; i < dialect_number; i++)
- {
- while (*p && *p != '}')
- {
- if (*p == '|')
- {
- p++;
- break;
- }
-
- /* Skip over any character after a percent sign. */
- if (*p == '%')
- p++;
- if (*p)
- p++;
- }
-
- if (*p == '}')
- break;
- }
-
- if (*p == '\0')
- output_operand_lossage ("unterminated assembly dialect alternative");
- }
- break;
-
- case '|':
- if (*dialect)
- {
- /* Skip to close brace. */
- do
- {
- if (*p == '\0')
- {
- output_operand_lossage ("unterminated assembly dialect alternative");
- break;
- }
-
- /* Skip over any character after a percent sign. */
- if (*p == '%' && p[1])
- {
- p += 2;
- continue;
- }
-
- if (*p++ == '}')
- break;
- }
- while (1);
-
- *dialect = 0;
- }
- else
- putc (c, asm_out_file);
- break;
-
- case '}':
- if (! *dialect)
- putc (c, asm_out_file);
- *dialect = 0;
- break;
- default:
- gcc_unreachable ();
- }
-
- return p;
-}
-#endif
-
-/* Output text from TEMPLATE to the assembler output file,
- obeying %-directions to substitute operands taken from
- the vector OPERANDS.
-
- %N (for N a digit) means print operand N in usual manner.
- %lN means require operand N to be a CODE_LABEL or LABEL_REF
- and print the label name with no punctuation.
- %cN means require operand N to be a constant
- and print the constant expression with no punctuation.
- %aN means expect operand N to be a memory address
- (not a memory reference!) and print a reference
- to that address.
- %nN means expect operand N to be a constant
- and print a constant expression for minus the value
- of the operand, with no other punctuation. */
-
-void
-output_asm_insn (const char *templ, rtx *operands)
-{
- const char *p;
- int c;
-#ifdef ASSEMBLER_DIALECT
- int dialect = 0;
-#endif
- int oporder[MAX_RECOG_OPERANDS];
- char opoutput[MAX_RECOG_OPERANDS];
- int ops = 0;
-
- /* An insn may return a null string template
- in a case where no assembler code is needed. */
- if (*templ == 0)
- return;
-
- memset (opoutput, 0, sizeof opoutput);
- p = templ;
- putc ('\t', asm_out_file);
-
-#ifdef ASM_OUTPUT_OPCODE
- ASM_OUTPUT_OPCODE (asm_out_file, p);
-#endif
-
- while ((c = *p++))
- switch (c)
- {
- case '\n':
- if (flag_verbose_asm)
- output_asm_operand_names (operands, oporder, ops);
- if (flag_print_asm_name)
- output_asm_name ();
-
- ops = 0;
- memset (opoutput, 0, sizeof opoutput);
-
- putc (c, asm_out_file);
-#ifdef ASM_OUTPUT_OPCODE
- while ((c = *p) == '\t')
- {
- putc (c, asm_out_file);
- p++;
- }
- ASM_OUTPUT_OPCODE (asm_out_file, p);
-#endif
- break;
-
-#ifdef ASSEMBLER_DIALECT
- case '{':
- case '}':
- case '|':
- p = do_assembler_dialects (p, &dialect);
- break;
-#endif
-
- case '%':
- /* %% outputs a single %. %{, %} and %| print {, } and | respectively
- if ASSEMBLER_DIALECT defined and these characters have a special
- meaning as dialect delimiters.*/
- if (*p == '%'
-#ifdef ASSEMBLER_DIALECT
- || *p == '{' || *p == '}' || *p == '|'
-#endif
- )
- {
- putc (*p, asm_out_file);
- p++;
- }
- /* %= outputs a number which is unique to each insn in the entire
- compilation. This is useful for making local labels that are
- referred to more than once in a given insn. */
- else if (*p == '=')
- {
- p++;
- fprintf (asm_out_file, "%d", insn_counter);
- }
- /* % followed by a letter and some digits
- outputs an operand in a special way depending on the letter.
- Letters `acln' are implemented directly.
- Other letters are passed to `output_operand' so that
- the TARGET_PRINT_OPERAND hook can define them. */
- else if (ISALPHA (*p))
- {
- int letter = *p++;
- unsigned long opnum;
- char *endptr;
-
- opnum = strtoul (p, &endptr, 10);
-
- if (endptr == p)
- output_operand_lossage ("operand number missing "
- "after %%-letter");
- else if (this_is_asm_operands && opnum >= insn_noperands)
- output_operand_lossage ("operand number out of range");
- else if (letter == 'l')
- output_asm_label (operands[opnum]);
- else if (letter == 'a')
- output_address (VOIDmode, operands[opnum]);
- else if (letter == 'c')
- {
- if (CONSTANT_ADDRESS_P (operands[opnum]))
- output_addr_const (asm_out_file, operands[opnum]);
- else
- output_operand (operands[opnum], 'c');
- }
- else if (letter == 'n')
- {
- if (CONST_INT_P (operands[opnum]))
- fprintf (asm_out_file, HOST_WIDE_INT_PRINT_DEC,
- - INTVAL (operands[opnum]));
- else
- {
- putc ('-', asm_out_file);
- output_addr_const (asm_out_file, operands[opnum]);
- }
- }
- else
- output_operand (operands[opnum], letter);
-
- if (!opoutput[opnum])
- oporder[ops++] = opnum;
- opoutput[opnum] = 1;
-
- p = endptr;
- c = *p;
- }
- /* % followed by a digit outputs an operand the default way. */
- else if (ISDIGIT (*p))
- {
- unsigned long opnum;
- char *endptr;
-
- opnum = strtoul (p, &endptr, 10);
- if (this_is_asm_operands && opnum >= insn_noperands)
- output_operand_lossage ("operand number out of range");
- else
- output_operand (operands[opnum], 0);
-
- if (!opoutput[opnum])
- oporder[ops++] = opnum;
- opoutput[opnum] = 1;
-
- p = endptr;
- c = *p;
- }
- /* % followed by punctuation: output something for that
- punctuation character alone, with no operand. The
- TARGET_PRINT_OPERAND hook decides what is actually done. */
- else if (targetm.asm_out.print_operand_punct_valid_p ((unsigned char) *p))
- output_operand (NULL_RTX, *p++);
- else
- output_operand_lossage ("invalid %%-code");
- break;
-
- default:
- putc (c, asm_out_file);
- }
-
- /* Try to keep the asm a bit more readable. */
- if ((flag_verbose_asm || flag_print_asm_name) && strlen (templ) < 9)
- putc ('\t', asm_out_file);
-
- /* Write out the variable names for operands, if we know them. */
- if (flag_verbose_asm)
- output_asm_operand_names (operands, oporder, ops);
- if (flag_print_asm_name)
- output_asm_name ();
-
- putc ('\n', asm_out_file);
-}
-
-/* Output a LABEL_REF, or a bare CODE_LABEL, as an assembler symbol. */
-
-void
-output_asm_label (rtx x)
-{
- char buf[256];
-
- if (GET_CODE (x) == LABEL_REF)
- x = label_ref_label (x);
- if (LABEL_P (x)
- || (NOTE_P (x)
- && NOTE_KIND (x) == NOTE_INSN_DELETED_LABEL))
- ASM_GENERATE_INTERNAL_LABEL (buf, "L", CODE_LABEL_NUMBER (x));
- else
- output_operand_lossage ("'%%l' operand isn't a label");
-
- assemble_name (asm_out_file, buf);
-}
-
-/* Marks SYMBOL_REFs in x as referenced through use of assemble_external. */
-
-void
-mark_symbol_refs_as_used (rtx x)
-{
- subrtx_iterator::array_type array;
- FOR_EACH_SUBRTX (iter, array, x, ALL)
- {
- const_rtx x = *iter;
- if (GET_CODE (x) == SYMBOL_REF)
- if (tree t = SYMBOL_REF_DECL (x))
- assemble_external (t);
- }
-}
-
-/* Print operand X using machine-dependent assembler syntax.
- CODE is a non-digit that preceded the operand-number in the % spec,
- such as 'z' if the spec was `%z3'. CODE is 0 if there was no char
- between the % and the digits.
- When CODE is a non-letter, X is 0.
-
- The meanings of the letters are machine-dependent and controlled
- by TARGET_PRINT_OPERAND. */
-
-void
-output_operand (rtx x, int code ATTRIBUTE_UNUSED)
-{
- if (x && GET_CODE (x) == SUBREG)
- x = alter_subreg (&x, true);
-
- /* X must not be a pseudo reg. */
- if (!targetm.no_register_allocation)
- gcc_assert (!x || !REG_P (x) || REGNO (x) < FIRST_PSEUDO_REGISTER);
-
- targetm.asm_out.print_operand (asm_out_file, x, code);
-
- if (x == NULL_RTX)
- return;
-
- mark_symbol_refs_as_used (x);
-}
-
-/* Print a memory reference operand for address X using
- machine-dependent assembler syntax. */
-
-void
-output_address (machine_mode mode, rtx x)
-{
- bool changed = false;
- walk_alter_subreg (&x, &changed);
- targetm.asm_out.print_operand_address (asm_out_file, mode, x);
-}
-
-/* Print an integer constant expression in assembler syntax.
- Addition and subtraction are the only arithmetic
- that may appear in these expressions. */
-
-void
-output_addr_const (FILE *file, rtx x)
-{
- char buf[256];
-
- restart:
- switch (GET_CODE (x))
- {
- case PC:
- putc ('.', file);
- break;
-
- case SYMBOL_REF:
- if (SYMBOL_REF_DECL (x))
- assemble_external (SYMBOL_REF_DECL (x));
-#ifdef ASM_OUTPUT_SYMBOL_REF
- ASM_OUTPUT_SYMBOL_REF (file, x);
-#else
- assemble_name (file, XSTR (x, 0));
-#endif
- break;
-
- case LABEL_REF:
- x = label_ref_label (x);
- /* Fall through. */
- case CODE_LABEL:
- ASM_GENERATE_INTERNAL_LABEL (buf, "L", CODE_LABEL_NUMBER (x));
-#ifdef ASM_OUTPUT_LABEL_REF
- ASM_OUTPUT_LABEL_REF (file, buf);
-#else
- assemble_name (file, buf);
-#endif
- break;
-
- case CONST_INT:
- fprintf (file, HOST_WIDE_INT_PRINT_DEC, INTVAL (x));
- break;
-
- case CONST:
- /* This used to output parentheses around the expression,
- but that does not work on the 386 (either ATT or BSD assembler). */
- output_addr_const (file, XEXP (x, 0));
- break;
-
- case CONST_WIDE_INT:
- /* We do not know the mode here so we have to use a round about
- way to build a wide-int to get it printed properly. */
- {
- wide_int w = wide_int::from_array (&CONST_WIDE_INT_ELT (x, 0),
- CONST_WIDE_INT_NUNITS (x),
- CONST_WIDE_INT_NUNITS (x)
- * HOST_BITS_PER_WIDE_INT,
- false);
- print_decs (w, file);
- }
- break;
-
- case CONST_DOUBLE:
- if (CONST_DOUBLE_AS_INT_P (x))
- {
- /* We can use %d if the number is one word and positive. */
- if (CONST_DOUBLE_HIGH (x))
- fprintf (file, HOST_WIDE_INT_PRINT_DOUBLE_HEX,
- (unsigned HOST_WIDE_INT) CONST_DOUBLE_HIGH (x),
- (unsigned HOST_WIDE_INT) CONST_DOUBLE_LOW (x));
- else if (CONST_DOUBLE_LOW (x) < 0)
- fprintf (file, HOST_WIDE_INT_PRINT_HEX,
- (unsigned HOST_WIDE_INT) CONST_DOUBLE_LOW (x));
- else
- fprintf (file, HOST_WIDE_INT_PRINT_DEC, CONST_DOUBLE_LOW (x));
- }
- else
- /* We can't handle floating point constants;
- PRINT_OPERAND must handle them. */
- output_operand_lossage ("floating constant misused");
- break;
-
- case CONST_FIXED:
- fprintf (file, HOST_WIDE_INT_PRINT_DEC, CONST_FIXED_VALUE_LOW (x));
- break;
-
- case PLUS:
- /* Some assemblers need integer constants to appear last (eg masm). */
- if (CONST_INT_P (XEXP (x, 0)))
- {
- output_addr_const (file, XEXP (x, 1));
- if (INTVAL (XEXP (x, 0)) >= 0)
- fprintf (file, "+");
- output_addr_const (file, XEXP (x, 0));
- }
- else
- {
- output_addr_const (file, XEXP (x, 0));
- if (!CONST_INT_P (XEXP (x, 1))
- || INTVAL (XEXP (x, 1)) >= 0)
- fprintf (file, "+");
- output_addr_const (file, XEXP (x, 1));
- }
- break;
-
- case MINUS:
- /* Avoid outputting things like x-x or x+5-x,
- since some assemblers can't handle that. */
- x = simplify_subtraction (x);
- if (GET_CODE (x) != MINUS)
- goto restart;
-
- output_addr_const (file, XEXP (x, 0));
- fprintf (file, "-");
- if ((CONST_INT_P (XEXP (x, 1)) && INTVAL (XEXP (x, 1)) >= 0)
- || GET_CODE (XEXP (x, 1)) == PC
- || GET_CODE (XEXP (x, 1)) == SYMBOL_REF)
- output_addr_const (file, XEXP (x, 1));
- else
- {
- fputs (targetm.asm_out.open_paren, file);
- output_addr_const (file, XEXP (x, 1));
- fputs (targetm.asm_out.close_paren, file);
- }
- break;
-
- case ZERO_EXTEND:
- case SIGN_EXTEND:
- case SUBREG:
- case TRUNCATE:
- output_addr_const (file, XEXP (x, 0));
- break;
-
- default:
- if (targetm.asm_out.output_addr_const_extra (file, x))
- break;
-
- output_operand_lossage ("invalid expression as operand");
- }
-}
-
-/* Output a quoted string. */
-
-void
-output_quoted_string (FILE *asm_file, const char *string)
-{
-#ifdef OUTPUT_QUOTED_STRING
- OUTPUT_QUOTED_STRING (asm_file, string);
-#else
- char c;
-
- putc ('\"', asm_file);
- while ((c = *string++) != 0)
- {
- if (ISPRINT (c))
- {
- if (c == '\"' || c == '\\')
- putc ('\\', asm_file);
- putc (c, asm_file);
- }
- else
- fprintf (asm_file, "\\%03o", (unsigned char) c);
- }
- putc ('\"', asm_file);
-#endif
-}
-
-/* Write a HOST_WIDE_INT number in hex form 0x1234, fast. */
-
-void
-fprint_whex (FILE *f, unsigned HOST_WIDE_INT value)
-{
- char buf[2 + CHAR_BIT * sizeof (value) / 4];
- if (value == 0)
- putc ('0', f);
- else
- {
- char *p = buf + sizeof (buf);
- do
- *--p = "0123456789abcdef"[value % 16];
- while ((value /= 16) != 0);
- *--p = 'x';
- *--p = '0';
- fwrite (p, 1, buf + sizeof (buf) - p, f);
- }
-}
-
-/* Internal function that prints an unsigned long in decimal in reverse.
- The output string IS NOT null-terminated. */
-
-static int
-sprint_ul_rev (char *s, unsigned long value)
-{
- int i = 0;
- do
- {
- s[i] = "0123456789"[value % 10];
- value /= 10;
- i++;
- /* alternate version, without modulo */
- /* oldval = value; */
- /* value /= 10; */
- /* s[i] = "0123456789" [oldval - 10*value]; */
- /* i++ */
- }
- while (value != 0);
- return i;
-}
-
-/* Write an unsigned long as decimal to a file, fast. */
-
-void
-fprint_ul (FILE *f, unsigned long value)
-{
- /* python says: len(str(2**64)) == 20 */
- char s[20];
- int i;
-
- i = sprint_ul_rev (s, value);
-
- /* It's probably too small to bother with string reversal and fputs. */
- do
- {
- i--;
- putc (s[i], f);
- }
- while (i != 0);
-}
-
-/* Write an unsigned long as decimal to a string, fast.
- s must be wide enough to not overflow, at least 21 chars.
- Returns the length of the string (without terminating '\0'). */
-
-int
-sprint_ul (char *s, unsigned long value)
-{
- int len = sprint_ul_rev (s, value);
- s[len] = '\0';
-
- std::reverse (s, s + len);
- return len;
-}
-
-/* A poor man's fprintf, with the added features of %I, %R, %L, and %U.
- %R prints the value of REGISTER_PREFIX.
- %L prints the value of LOCAL_LABEL_PREFIX.
- %U prints the value of USER_LABEL_PREFIX.
- %I prints the value of IMMEDIATE_PREFIX.
- %O runs ASM_OUTPUT_OPCODE to transform what follows in the string.
- Also supported are %d, %i, %u, %x, %X, %o, %c, %s and %%.
-
- We handle alternate assembler dialects here, just like output_asm_insn. */
-
-void
-asm_fprintf (FILE *file, const char *p, ...)
-{
- char buf[10];
- char *q, c;
-#ifdef ASSEMBLER_DIALECT
- int dialect = 0;
-#endif
- va_list argptr;
-
- va_start (argptr, p);
-
- buf[0] = '%';
-
- while ((c = *p++))
- switch (c)
- {
-#ifdef ASSEMBLER_DIALECT
- case '{':
- case '}':
- case '|':
- p = do_assembler_dialects (p, &dialect);
- break;
-#endif
-
- case '%':
- c = *p++;
- q = &buf[1];
- while (strchr ("-+ #0", c))
- {
- *q++ = c;
- c = *p++;
- }
- while (ISDIGIT (c) || c == '.')
- {
- *q++ = c;
- c = *p++;
- }
- switch (c)
- {
- case '%':
- putc ('%', file);
- break;
-
- case 'd': case 'i': case 'u':
- case 'x': case 'X': case 'o':
- case 'c':
- *q++ = c;
- *q = 0;
- fprintf (file, buf, va_arg (argptr, int));
- break;
-
- case 'w':
- /* This is a prefix to the 'd', 'i', 'u', 'x', 'X', and
- 'o' cases, but we do not check for those cases. It
- means that the value is a HOST_WIDE_INT, which may be
- either `long' or `long long'. */
- memcpy (q, HOST_WIDE_INT_PRINT, strlen (HOST_WIDE_INT_PRINT));
- q += strlen (HOST_WIDE_INT_PRINT);
- *q++ = *p++;
- *q = 0;
- fprintf (file, buf, va_arg (argptr, HOST_WIDE_INT));
- break;
-
- case 'l':
- *q++ = c;
-#ifdef HAVE_LONG_LONG
- if (*p == 'l')
- {
- *q++ = *p++;
- *q++ = *p++;
- *q = 0;
- fprintf (file, buf, va_arg (argptr, long long));
- }
- else
-#endif
- {
- *q++ = *p++;
- *q = 0;
- fprintf (file, buf, va_arg (argptr, long));
- }
-
- break;
-
- case 's':
- *q++ = c;
- *q = 0;
- fprintf (file, buf, va_arg (argptr, char *));
- break;
-
- case 'O':
-#ifdef ASM_OUTPUT_OPCODE
- ASM_OUTPUT_OPCODE (asm_out_file, p);
-#endif
- break;
-
- case 'R':
-#ifdef REGISTER_PREFIX
- fprintf (file, "%s", REGISTER_PREFIX);
-#endif
- break;
-
- case 'I':
-#ifdef IMMEDIATE_PREFIX
- fprintf (file, "%s", IMMEDIATE_PREFIX);
-#endif
- break;
-
- case 'L':
-#ifdef LOCAL_LABEL_PREFIX
- fprintf (file, "%s", LOCAL_LABEL_PREFIX);
-#endif
- break;
-
- case 'U':
- fputs (user_label_prefix, file);
- break;
-
-#ifdef ASM_FPRINTF_EXTENSIONS
- /* Uppercase letters are reserved for general use by asm_fprintf
- and so are not available to target specific code. In order to
- prevent the ASM_FPRINTF_EXTENSIONS macro from using them then,
- they are defined here. As they get turned into real extensions
- to asm_fprintf they should be removed from this list. */
- case 'A': case 'B': case 'C': case 'D': case 'E':
- case 'F': case 'G': case 'H': case 'J': case 'K':
- case 'M': case 'N': case 'P': case 'Q': case 'S':
- case 'T': case 'V': case 'W': case 'Y': case 'Z':
- break;
-
- ASM_FPRINTF_EXTENSIONS (file, argptr, p)
-#endif
- default:
- gcc_unreachable ();
- }
- break;
-
- default:
- putc (c, file);
- }
- va_end (argptr);
-}
-
-/* Return nonzero if this function has no function calls. */
-
-int
-leaf_function_p (void)
-{
- rtx_insn *insn;
-
- /* Ensure we walk the entire function body. */
- gcc_assert (!in_sequence_p ());
-
- /* Some back-ends (e.g. s390) want leaf functions to stay leaf
- functions even if they call mcount. */
- if (crtl->profile && !targetm.keep_leaf_when_profiled ())
- return 0;
-
- for (insn = get_insns (); insn; insn = NEXT_INSN (insn))
- {
- if (CALL_P (insn)
- && ! SIBLING_CALL_P (insn)
- && ! FAKE_CALL_P (insn))
- return 0;
- if (NONJUMP_INSN_P (insn)
- && GET_CODE (PATTERN (insn)) == SEQUENCE
- && CALL_P (XVECEXP (PATTERN (insn), 0, 0))
- && ! SIBLING_CALL_P (XVECEXP (PATTERN (insn), 0, 0)))
- return 0;
- }
-
- return 1;
-}
-
-/* Return 1 if branch is a forward branch.
- Uses insn_shuid array, so it works only in the final pass. May be used by
- output templates to customary add branch prediction hints.
- */
-int
-final_forward_branch_p (rtx_insn *insn)
-{
- int insn_id, label_id;
-
- gcc_assert (uid_shuid);
- insn_id = INSN_SHUID (insn);
- label_id = INSN_SHUID (JUMP_LABEL (insn));
- /* We've hit some insns that does not have id information available. */
- gcc_assert (insn_id && label_id);
- return insn_id < label_id;
-}
-
-/* On some machines, a function with no call insns
- can run faster if it doesn't create its own register window.
- When output, the leaf function should use only the "output"
- registers. Ordinarily, the function would be compiled to use
- the "input" registers to find its arguments; it is a candidate
- for leaf treatment if it uses only the "input" registers.
- Leaf function treatment means renumbering so the function
- uses the "output" registers instead. */
-
-#ifdef LEAF_REGISTERS
-
-/* Return 1 if this function uses only the registers that can be
- safely renumbered. */
-
-int
-only_leaf_regs_used (void)
-{
- int i;
- const char *const permitted_reg_in_leaf_functions = LEAF_REGISTERS;
-
- for (i = 0; i < FIRST_PSEUDO_REGISTER; i++)
- if ((df_regs_ever_live_p (i) || global_regs[i])
- && ! permitted_reg_in_leaf_functions[i])
- return 0;
-
- if (crtl->uses_pic_offset_table
- && pic_offset_table_rtx != 0
- && REG_P (pic_offset_table_rtx)
- && ! permitted_reg_in_leaf_functions[REGNO (pic_offset_table_rtx)])
- return 0;
-
- return 1;
-}
-
-/* Scan all instructions and renumber all registers into those
- available in leaf functions. */
-
-static void
-leaf_renumber_regs (rtx_insn *first)
-{
- rtx_insn *insn;
-
- /* Renumber only the actual patterns.
- The reg-notes can contain frame pointer refs,
- and renumbering them could crash, and should not be needed. */
- for (insn = first; insn; insn = NEXT_INSN (insn))
- if (INSN_P (insn))
- leaf_renumber_regs_insn (PATTERN (insn));
-}
-
-/* Scan IN_RTX and its subexpressions, and renumber all regs into those
- available in leaf functions. */
-
-void
-leaf_renumber_regs_insn (rtx in_rtx)
-{
- int i, j;
- const char *format_ptr;
-
- if (in_rtx == 0)
- return;
-
- /* Renumber all input-registers into output-registers.
- renumbered_regs would be 1 for an output-register;
- they */
-
- if (REG_P (in_rtx))
- {
- int newreg;
-
- /* Don't renumber the same reg twice. */
- if (in_rtx->used)
- return;
-
- newreg = REGNO (in_rtx);
- /* Don't try to renumber pseudo regs. It is possible for a pseudo reg
- to reach here as part of a REG_NOTE. */
- if (newreg >= FIRST_PSEUDO_REGISTER)
- {
- in_rtx->used = 1;
- return;
- }
- newreg = LEAF_REG_REMAP (newreg);
- gcc_assert (newreg >= 0);
- df_set_regs_ever_live (REGNO (in_rtx), false);
- df_set_regs_ever_live (newreg, true);
- SET_REGNO (in_rtx, newreg);
- in_rtx->used = 1;
- return;
- }
-
- if (INSN_P (in_rtx))
- {
- /* Inside a SEQUENCE, we find insns.
- Renumber just the patterns of these insns,
- just as we do for the top-level insns. */
- leaf_renumber_regs_insn (PATTERN (in_rtx));
- return;
- }
-
- format_ptr = GET_RTX_FORMAT (GET_CODE (in_rtx));
-
- for (i = 0; i < GET_RTX_LENGTH (GET_CODE (in_rtx)); i++)
- switch (*format_ptr++)
- {
- case 'e':
- leaf_renumber_regs_insn (XEXP (in_rtx, i));
- break;
-
- case 'E':
- if (XVEC (in_rtx, i) != NULL)
- for (j = 0; j < XVECLEN (in_rtx, i); j++)
- leaf_renumber_regs_insn (XVECEXP (in_rtx, i, j));
- break;
-
- case 'S':
- case 's':
- case '0':
- case 'i':
- case 'w':
- case 'p':
- case 'n':
- case 'u':
- break;
-
- default:
- gcc_unreachable ();
- }
-}
-#endif
-
-/* Turn the RTL into assembly. */
-static unsigned int
-rest_of_handle_final (void)
-{
- const char *fnname = get_fnname_from_decl (current_function_decl);
-
- /* Turn debug markers into notes if the var-tracking pass has not
- been invoked. */
- if (!flag_var_tracking && MAY_HAVE_DEBUG_MARKER_INSNS)
- delete_vta_debug_insns (false);
-
- assemble_start_function (current_function_decl, fnname);
- rtx_insn *first = get_insns ();
- int seen = 0;
- final_start_function_1 (&first, asm_out_file, &seen, optimize);
- final_1 (first, asm_out_file, seen, optimize);
- if (flag_ipa_ra
- && !lookup_attribute ("noipa", DECL_ATTRIBUTES (current_function_decl))
- /* Functions with naked attributes are supported only with basic asm
- statements in the body, thus for supported use cases the information
- on clobbered registers is not available. */
- && !lookup_attribute ("naked", DECL_ATTRIBUTES (current_function_decl)))
- collect_fn_hard_reg_usage ();
- final_end_function ();
-
- /* The IA-64 ".handlerdata" directive must be issued before the ".endp"
- directive that closes the procedure descriptor. Similarly, for x64 SEH.
- Otherwise it's not strictly necessary, but it doesn't hurt either. */
- output_function_exception_table (crtl->has_bb_partition ? 1 : 0);
-
- assemble_end_function (current_function_decl, fnname);
-
- /* Free up reg info memory. */
- free_reg_info ();
-
- if (! quiet_flag)
- fflush (asm_out_file);
-
- /* Write DBX symbols if requested. */
-
- /* Note that for those inline functions where we don't initially
- know for certain that we will be generating an out-of-line copy,
- the first invocation of this routine (rest_of_compilation) will
- skip over this code by doing a `goto exit_rest_of_compilation;'.
- Later on, wrapup_global_declarations will (indirectly) call
- rest_of_compilation again for those inline functions that need
- to have out-of-line copies generated. During that call, we
- *will* be routed past here. */
-
- timevar_push (TV_SYMOUT);
- if (!DECL_IGNORED_P (current_function_decl))
- debug_hooks->function_decl (current_function_decl);
- timevar_pop (TV_SYMOUT);
-
- /* Release the blocks that are linked to DECL_INITIAL() to free the memory. */
- DECL_INITIAL (current_function_decl) = error_mark_node;
-
- if (DECL_STATIC_CONSTRUCTOR (current_function_decl)
- && targetm.have_ctors_dtors)
- targetm.asm_out.constructor (XEXP (DECL_RTL (current_function_decl), 0),
- decl_init_priority_lookup
- (current_function_decl));
- if (DECL_STATIC_DESTRUCTOR (current_function_decl)
- && targetm.have_ctors_dtors)
- targetm.asm_out.destructor (XEXP (DECL_RTL (current_function_decl), 0),
- decl_fini_priority_lookup
- (current_function_decl));
- return 0;
-}
-
-namespace {
-
-const pass_data pass_data_final =
-{
- RTL_PASS, /* type */
- "final", /* name */
- OPTGROUP_NONE, /* optinfo_flags */
- TV_FINAL, /* tv_id */
- 0, /* properties_required */
- 0, /* properties_provided */
- 0, /* properties_destroyed */
- 0, /* todo_flags_start */
- 0, /* todo_flags_finish */
-};
-
-class pass_final : public rtl_opt_pass
-{
-public:
- pass_final (gcc::context *ctxt)
- : rtl_opt_pass (pass_data_final, ctxt)
- {}
-
- /* opt_pass methods: */
- virtual unsigned int execute (function *) { return rest_of_handle_final (); }
-
-}; // class pass_final
-
-} // anon namespace
-
-rtl_opt_pass *
-make_pass_final (gcc::context *ctxt)
-{
- return new pass_final (ctxt);
-}
-
-
-static unsigned int
-rest_of_handle_shorten_branches (void)
-{
- /* Shorten branches. */
- shorten_branches (get_insns ());
- return 0;
-}
-
-namespace {
-
-const pass_data pass_data_shorten_branches =
-{
- RTL_PASS, /* type */
- "shorten", /* name */
- OPTGROUP_NONE, /* optinfo_flags */
- TV_SHORTEN_BRANCH, /* tv_id */
- 0, /* properties_required */
- 0, /* properties_provided */
- 0, /* properties_destroyed */
- 0, /* todo_flags_start */
- 0, /* todo_flags_finish */
-};
-
-class pass_shorten_branches : public rtl_opt_pass
-{
-public:
- pass_shorten_branches (gcc::context *ctxt)
- : rtl_opt_pass (pass_data_shorten_branches, ctxt)
- {}
-
- /* opt_pass methods: */
- virtual unsigned int execute (function *)
- {
- return rest_of_handle_shorten_branches ();
- }
-
-}; // class pass_shorten_branches
-
-} // anon namespace
-
-rtl_opt_pass *
-make_pass_shorten_branches (gcc::context *ctxt)
-{
- return new pass_shorten_branches (ctxt);
-}
-
-
-static unsigned int
-rest_of_clean_state (void)
-{
- rtx_insn *insn, *next;
- FILE *final_output = NULL;
- int save_unnumbered = flag_dump_unnumbered;
- int save_noaddr = flag_dump_noaddr;
-
- if (flag_dump_final_insns)
- {
- final_output = fopen (flag_dump_final_insns, "a");
- if (!final_output)
- {
- error ("could not open final insn dump file %qs: %m",
- flag_dump_final_insns);
- flag_dump_final_insns = NULL;
- }
- else
- {
- flag_dump_noaddr = flag_dump_unnumbered = 1;
- if (flag_compare_debug_opt || flag_compare_debug)
- dump_flags |= TDF_NOUID | TDF_COMPARE_DEBUG;
- dump_function_header (final_output, current_function_decl,
- dump_flags);
- final_insns_dump_p = true;
-
- for (insn = get_insns (); insn; insn = NEXT_INSN (insn))
- if (LABEL_P (insn))
- INSN_UID (insn) = CODE_LABEL_NUMBER (insn);
- else
- {
- if (NOTE_P (insn))
- set_block_for_insn (insn, NULL);
- INSN_UID (insn) = 0;
- }
- }
- }
-
- /* It is very important to decompose the RTL instruction chain here:
- debug information keeps pointing into CODE_LABEL insns inside the function
- body. If these remain pointing to the other insns, we end up preserving
- whole RTL chain and attached detailed debug info in memory. */
- for (insn = get_insns (); insn; insn = next)
- {
- next = NEXT_INSN (insn);
- SET_NEXT_INSN (insn) = NULL;
- SET_PREV_INSN (insn) = NULL;
-
- rtx_insn *call_insn = insn;
- if (NONJUMP_INSN_P (call_insn)
- && GET_CODE (PATTERN (call_insn)) == SEQUENCE)
- {
- rtx_sequence *seq = as_a <rtx_sequence *> (PATTERN (call_insn));
- call_insn = seq->insn (0);
- }
- if (CALL_P (call_insn))
- {
- rtx note
- = find_reg_note (call_insn, REG_CALL_ARG_LOCATION, NULL_RTX);
- if (note)
- remove_note (call_insn, note);
- }
-
- if (final_output
- && (!NOTE_P (insn)
- || (NOTE_KIND (insn) != NOTE_INSN_VAR_LOCATION
- && NOTE_KIND (insn) != NOTE_INSN_BEGIN_STMT
- && NOTE_KIND (insn) != NOTE_INSN_INLINE_ENTRY
- && NOTE_KIND (insn) != NOTE_INSN_BLOCK_BEG
- && NOTE_KIND (insn) != NOTE_INSN_BLOCK_END
- && NOTE_KIND (insn) != NOTE_INSN_DELETED_DEBUG_LABEL)))
- print_rtl_single (final_output, insn);
- }
-
- if (final_output)
- {
- flag_dump_noaddr = save_noaddr;
- flag_dump_unnumbered = save_unnumbered;
- final_insns_dump_p = false;
-
- if (fclose (final_output))
- {
- error ("could not close final insn dump file %qs: %m",
- flag_dump_final_insns);
- flag_dump_final_insns = NULL;
- }
- }
-
- flag_rerun_cse_after_global_opts = 0;
- reload_completed = 0;
- epilogue_completed = 0;
-#ifdef STACK_REGS
- regstack_completed = 0;
-#endif
-
- /* Clear out the insn_length contents now that they are no
- longer valid. */
- init_insn_lengths ();
-
- /* Show no temporary slots allocated. */
- init_temp_slots ();
-
- free_bb_for_insn ();
-
- if (cfun->gimple_df)
- delete_tree_ssa (cfun);
-
- /* We can reduce stack alignment on call site only when we are sure that
- the function body just produced will be actually used in the final
- executable. */
- if (flag_ipa_stack_alignment
- && decl_binds_to_current_def_p (current_function_decl))
- {
- unsigned int pref = crtl->preferred_stack_boundary;
- if (crtl->stack_alignment_needed > crtl->preferred_stack_boundary)
- pref = crtl->stack_alignment_needed;
- cgraph_node::rtl_info (current_function_decl)
- ->preferred_incoming_stack_boundary = pref;
- }
-
- /* Make sure volatile mem refs aren't considered valid operands for
- arithmetic insns. We must call this here if this is a nested inline
- function, since the above code leaves us in the init_recog state,
- and the function context push/pop code does not save/restore volatile_ok.
-
- ??? Maybe it isn't necessary for expand_start_function to call this
- anymore if we do it here? */
-
- init_recog_no_volatile ();
-
- /* We're done with this function. Free up memory if we can. */
- free_after_parsing (cfun);
- free_after_compilation (cfun);
- return 0;
-}
-
-namespace {
-
-const pass_data pass_data_clean_state =
-{
- RTL_PASS, /* type */
- "*clean_state", /* name */
- OPTGROUP_NONE, /* optinfo_flags */
- TV_FINAL, /* tv_id */
- 0, /* properties_required */
- 0, /* properties_provided */
- PROP_rtl, /* properties_destroyed */
- 0, /* todo_flags_start */
- 0, /* todo_flags_finish */
-};
-
-class pass_clean_state : public rtl_opt_pass
-{
-public:
- pass_clean_state (gcc::context *ctxt)
- : rtl_opt_pass (pass_data_clean_state, ctxt)
- {}
-
- /* opt_pass methods: */
- virtual unsigned int execute (function *)
- {
- return rest_of_clean_state ();
- }
-
-}; // class pass_clean_state
-
-} // anon namespace
-
-rtl_opt_pass *
-make_pass_clean_state (gcc::context *ctxt)
-{
- return new pass_clean_state (ctxt);
-}
-
-/* Return true if INSN is a call to the current function. */
-
-static bool
-self_recursive_call_p (rtx_insn *insn)
-{
- tree fndecl = get_call_fndecl (insn);
- return (fndecl == current_function_decl
- && decl_binds_to_current_def_p (fndecl));
-}
-
-/* Collect hard register usage for the current function. */
-
-static void
-collect_fn_hard_reg_usage (void)
-{
- rtx_insn *insn;
-#ifdef STACK_REGS
- int i;
-#endif
- struct cgraph_rtl_info *node;
- HARD_REG_SET function_used_regs;
-
- /* ??? To be removed when all the ports have been fixed. */
- if (!targetm.call_fusage_contains_non_callee_clobbers)
- return;
-
- /* Be conservative - mark fixed and global registers as used. */
- function_used_regs = fixed_reg_set;
-
-#ifdef STACK_REGS
- /* Handle STACK_REGS conservatively, since the df-framework does not
- provide accurate information for them. */
-
- for (i = FIRST_STACK_REG; i <= LAST_STACK_REG; i++)
- SET_HARD_REG_BIT (function_used_regs, i);
-#endif
-
- for (insn = get_insns (); insn != NULL_RTX; insn = next_insn (insn))
- {
- HARD_REG_SET insn_used_regs;
-
- if (!NONDEBUG_INSN_P (insn))
- continue;
-
- if (CALL_P (insn)
- && !self_recursive_call_p (insn))
- function_used_regs
- |= insn_callee_abi (insn).full_and_partial_reg_clobbers ();
-
- find_all_hard_reg_sets (insn, &insn_used_regs, false);
- function_used_regs |= insn_used_regs;
-
- if (hard_reg_set_subset_p (crtl->abi->full_and_partial_reg_clobbers (),
- function_used_regs))
- return;
- }
-
- /* Mask out fully-saved registers, so that they don't affect equality
- comparisons between function_abis. */
- function_used_regs &= crtl->abi->full_and_partial_reg_clobbers ();
-
- node = cgraph_node::rtl_info (current_function_decl);
- gcc_assert (node != NULL);
-
- node->function_used_regs = function_used_regs;
-}