public inbox for libstdc++-cvs@sourceware.org
help / color / mirror / Atom feed
* [gcc(refs/vendors/redhat/heads/gcc-12-branch)] Merge commit 'r12-6669-g38ec23fafb167ddfe840d7bb22b3e943d8a7d29e' into redhat/gcc-12-branch
@ 2022-01-18 12:42 Jakub Jelinek
  0 siblings, 0 replies; only message in thread
From: Jakub Jelinek @ 2022-01-18 12:42 UTC (permalink / raw)
  To: gcc-cvs, libstdc++-cvs

https://gcc.gnu.org/g:880787aef7a985a80f88a14f830fb554a33b1a87

commit 880787aef7a985a80f88a14f830fb554a33b1a87
Merge: d8c9e50646a 38ec23fafb1
Author: Jakub Jelinek <jakub@redhat.com>
Date:   Tue Jan 18 13:41:24 2022 +0100

    Merge commit 'r12-6669-g38ec23fafb167ddfe840d7bb22b3e943d8a7d29e' into redhat/gcc-12-branch

Diff:

 ChangeLog                                          |     4 +
 MAINTAINERS                                        |    14 +-
 contrib/ChangeLog                                  |    14 +
 contrib/filter-clang-warnings.py                   |    14 +-
 contrib/gcc_update                                 |     6 +-
 contrib/git-backport.py                            |    48 +
 contrib/header-tools/ChangeLog                     |     4 +
 contrib/header-tools/README                        |    34 +-
 contrib/maintainers-verify.sh                      |    45 -
 contrib/paranoia.cc                                |     2 +-
 fixincludes/ChangeLog                              |    18 +
 fixincludes/fixincl.x                              |   180 +-
 fixincludes/inclhack.def                           |   123 +
 fixincludes/tests/base/fcntl.h                     |    33 +
 fixincludes/tests/base/math.h                      |    34 +
 fixincludes/tests/base/time.h                      |    15 +
 gcc/BASE-VER                                       |     2 +-
 gcc/ChangeLog                                      |  2645 +
 gcc/DATESTAMP                                      |     2 +-
 gcc/Makefile.in                                    |   322 +-
 gcc/ada/ChangeLog                                  |   123 +
 gcc/ada/gcc-interface/Make-lang.in                 |     6 +-
 gcc/ada/gcc-interface/config-lang.in               |     2 +-
 gcc/ada/gcc-interface/{cuintp.c => cuintp.cc}      |     0
 gcc/ada/gcc-interface/decl.c                       | 10661 ----
 gcc/ada/gcc-interface/decl.cc                      | 10661 ++++
 gcc/ada/gcc-interface/gigi.h                       |    16 +-
 gcc/ada/gcc-interface/lang-specs.h                 |     2 +-
 gcc/ada/gcc-interface/{misc.c => misc.cc}          |     0
 gcc/ada/gcc-interface/{targtyps.c => targtyps.cc}  |     0
 gcc/ada/gcc-interface/{trans.c => trans.cc}        |     0
 gcc/ada/gcc-interface/utils.c                      |  7156 ---
 gcc/ada/gcc-interface/utils.cc                     |  7156 +++
 gcc/ada/gcc-interface/utils2.c                     |  3050 --
 gcc/ada/gcc-interface/utils2.cc                    |  3050 ++
 gcc/ada/init.c                                     |     2 +-
 gcc/ada/set_targ.ads                               |     4 +-
 gcc/{adjust-alignment.c => adjust-alignment.cc}    |     0
 gcc/{alias.c => alias.cc}                          |     0
 gcc/alias.h                                        |     2 +-
 gcc/{alloc-pool.c => alloc-pool.cc}                |     0
 gcc/analyzer/ChangeLog                             |    39 +
 gcc/analyzer/analyzer.cc                           |     4 +-
 gcc/analyzer/region-model-asm.cc                   |     2 +-
 gcc/analyzer/region.cc                             |     2 +-
 gcc/analyzer/sm-malloc.cc                          |     2 +-
 gcc/analyzer/supergraph.cc                         |     2 +-
 gcc/asan.c                                         |  4692 --
 gcc/asan.cc                                        |  4692 ++
 gcc/{attribs.c => attribs.cc}                      |     0
 gcc/{auto-inc-dec.c => auto-inc-dec.cc}            |     0
 gcc/{auto-profile.c => auto-profile.cc}            |     0
 gcc/auto-profile.h                                 |     2 +-
 gcc/basic-block.h                                  |     2 +-
 gcc/{bb-reorder.c => bb-reorder.cc}                |     0
 gcc/{bitmap.c => bitmap.cc}                        |     0
 gcc/btfout.c                                       |  1133 -
 gcc/btfout.cc                                      |  1133 +
 gcc/builtins.c                                     | 11184 -----
 gcc/builtins.cc                                    | 11184 +++++
 gcc/c-family/ChangeLog                             |    86 +
 gcc/c-family/c-ada-spec.c                          |  3528 --
 gcc/c-family/c-ada-spec.cc                         |  3528 ++
 gcc/c-family/c-ada-spec.h                          |     2 +-
 gcc/c-family/{c-attribs.c => c-attribs.cc}         |     0
 gcc/c-family/c-common.c                            |  9466 ----
 gcc/c-family/c-common.cc                           |  9466 ++++
 gcc/c-family/c-common.h                            |    30 +-
 gcc/c-family/c-cppbuiltin.c                        |  2009 -
 gcc/c-family/c-cppbuiltin.cc                       |  2009 +
 gcc/c-family/{c-dump.c => c-dump.cc}               |     0
 gcc/c-family/c-format.c                            |  5439 ---
 gcc/c-family/c-format.cc                           |  5439 +++
 gcc/c-family/c-gimplify.c                          |   738 -
 gcc/c-family/c-gimplify.cc                         |   738 +
 gcc/c-family/{c-indentation.c => c-indentation.cc} |     0
 gcc/c-family/c-indentation.h                       |     2 +-
 gcc/c-family/{c-lex.c => c-lex.cc}                 |     0
 gcc/c-family/c-objc.h                              |     2 +-
 gcc/c-family/c-omp.c                               |  3265 --
 gcc/c-family/c-omp.cc                              |  3265 ++
 gcc/c-family/c-opts.c                              |  1842 -
 gcc/c-family/c-opts.cc                             |  1842 +
 gcc/c-family/{c-pch.c => c-pch.cc}                 |     0
 gcc/c-family/{c-ppoutput.c => c-ppoutput.cc}       |     0
 gcc/c-family/c-pragma.c                            |  1656 -
 gcc/c-family/c-pragma.cc                           |  1656 +
 .../{c-pretty-print.c => c-pretty-print.cc}        |     0
 gcc/c-family/c-pretty-print.h                      |     2 +-
 gcc/c-family/{c-semantics.c => c-semantics.cc}     |     0
 gcc/c-family/{c-ubsan.c => c-ubsan.cc}             |     0
 gcc/c-family/{c-warn.c => c-warn.cc}               |     0
 gcc/c-family/c.opt                                 |    20 +
 gcc/c-family/{cppspec.c => cppspec.cc}             |     0
 gcc/c-family/{stub-objc.c => stub-objc.cc}         |     0
 gcc/c/ChangeLog                                    |    55 +
 gcc/c/Make-lang.in                                 |    10 +-
 gcc/c/{c-aux-info.c => c-aux-info.cc}              |     0
 gcc/c/c-convert.c                                  |   207 -
 gcc/c/c-convert.cc                                 |   207 +
 gcc/c/c-decl.c                                     | 12469 -----
 gcc/c/c-decl.cc                                    | 12469 +++++
 gcc/c/{c-errors.c => c-errors.cc}                  |     0
 gcc/c/{c-fold.c => c-fold.cc}                      |     0
 gcc/c/{c-lang.c => c-lang.cc}                      |     0
 gcc/c/{c-objc-common.c => c-objc-common.cc}        |     0
 gcc/c/c-objc-common.h                              |     2 +-
 gcc/c/c-parser.c                                   | 23404 ---------
 gcc/c/c-parser.cc                                  | 23404 +++++++++
 gcc/c/c-parser.h                                   |     2 +-
 gcc/c/c-tree.h                                     |    22 +-
 gcc/c/c-typeck.c                                   | 16079 ------
 gcc/c/c-typeck.cc                                  | 16079 ++++++
 gcc/c/config-lang.in                               |     2 +-
 gcc/c/{gccspec.c => gccspec.cc}                    |     0
 gcc/c/{gimple-parser.c => gimple-parser.cc}        |     0
 gcc/caller-save.c                                  |  1400 -
 gcc/caller-save.cc                                 |  1400 +
 gcc/calls.c                                        |  5254 --
 gcc/calls.cc                                       |  5254 ++
 gcc/{ccmp.c => ccmp.cc}                            |     0
 gcc/cfg-flags.def                                  |     6 +-
 gcc/{cfg.c => cfg.cc}                              |     0
 gcc/cfganal.c                                      |  1934 -
 gcc/cfganal.cc                                     |  1934 +
 gcc/{cfgbuild.c => cfgbuild.cc}                    |     0
 gcc/cfgcleanup.c                                   |  3339 --
 gcc/cfgcleanup.cc                                  |  3339 ++
 gcc/cfgexpand.c                                    |  7030 ---
 gcc/cfgexpand.cc                                   |  7030 +++
 gcc/cfghooks.c                                     |  1560 -
 gcc/cfghooks.cc                                    |  1560 +
 gcc/cfghooks.h                                     |     4 +-
 gcc/{cfgloop.c => cfgloop.cc}                      |     0
 gcc/{cfgloopanal.c => cfgloopanal.cc}              |     0
 gcc/{cfgloopmanip.c => cfgloopmanip.cc}            |     0
 gcc/cfgrtl.c                                       |  5366 --
 gcc/cfgrtl.cc                                      |  5366 ++
 gcc/cgraph.c                                       |  4273 --
 gcc/cgraph.cc                                      |  4273 ++
 gcc/cgraph.h                                       |    28 +-
 gcc/{cgraphbuild.c => cgraphbuild.cc}              |     0
 gcc/cgraphclones.c                                 |  1160 -
 gcc/cgraphclones.cc                                |  1160 +
 gcc/cgraphunit.c                                   |  2595 -
 gcc/cgraphunit.cc                                  |  2595 +
 gcc/{collect-utils.c => collect-utils.cc}          |     0
 gcc/collect-utils.h                                |     2 +-
 gcc/{collect2-aix.c => collect2-aix.cc}            |     0
 gcc/collect2-aix.h                                 |     2 +-
 gcc/collect2.c                                     |  3078 --
 gcc/collect2.cc                                    |  3078 ++
 gcc/combine-stack-adj.c                            |   854 -
 gcc/combine-stack-adj.cc                           |   854 +
 gcc/combine.c                                      | 14960 ------
 gcc/combine.cc                                     | 14960 ++++++
 gcc/common.opt                                     |    10 +-
 .../{common-targhooks.c => common-targhooks.cc}    |     0
 gcc/common/config/aarch64/aarch64-common.c         |   551 -
 gcc/common/config/aarch64/aarch64-common.cc        |   551 +
 .../alpha/{alpha-common.c => alpha-common.cc}      |     0
 .../config/arc/{arc-common.c => arc-common.cc}     |     0
 gcc/common/config/arm/arm-common.c                 |  1116 -
 gcc/common/config/arm/arm-common.cc                |  1116 +
 gcc/common/config/avr/avr-common.c                 |   153 -
 gcc/common/config/avr/avr-common.cc                |   153 +
 .../config/bfin/{bfin-common.c => bfin-common.cc}  |     0
 .../config/bpf/{bpf-common.c => bpf-common.cc}     |     0
 .../config/c6x/{c6x-common.c => c6x-common.cc}     |     0
 .../config/cr16/{cr16-common.c => cr16-common.cc}  |     0
 .../config/cris/{cris-common.c => cris-common.cc}  |     0
 .../config/csky/{csky-common.c => csky-common.cc}  |     0
 .../config/{default-common.c => default-common.cc} |     0
 .../{epiphany-common.c => epiphany-common.cc}      |     0
 .../config/fr30/{fr30-common.c => fr30-common.cc}  |     0
 .../config/frv/{frv-common.c => frv-common.cc}     |     0
 .../config/gcn/{gcn-common.c => gcn-common.cc}     |     0
 .../h8300/{h8300-common.c => h8300-common.cc}      |     0
 .../config/i386/{i386-common.c => i386-common.cc}  |     0
 gcc/common/config/i386/i386-isas.h                 |     4 +-
 .../config/ia64/{ia64-common.c => ia64-common.cc}  |     0
 .../iq2000/{iq2000-common.c => iq2000-common.cc}   |     0
 .../config/lm32/{lm32-common.c => lm32-common.cc}  |     0
 .../config/m32r/{m32r-common.c => m32r-common.cc}  |     0
 .../config/m68k/{m68k-common.c => m68k-common.cc}  |     0
 .../mcore/{mcore-common.c => mcore-common.cc}      |     0
 .../{microblaze-common.c => microblaze-common.cc}  |     0
 .../config/mips/{mips-common.c => mips-common.cc}  |     0
 .../config/mmix/{mmix-common.c => mmix-common.cc}  |     0
 .../{mn10300-common.c => mn10300-common.cc}        |     0
 .../msp430/{msp430-common.c => msp430-common.cc}   |     0
 .../nds32/{nds32-common.c => nds32-common.cc}      |     0
 .../nios2/{nios2-common.c => nios2-common.cc}      |     0
 .../nvptx/{nvptx-common.c => nvptx-common.cc}      |     0
 .../config/or1k/{or1k-common.c => or1k-common.cc}  |     0
 gcc/common/config/pa/{pa-common.c => pa-common.cc} |     0
 .../pdp11/{pdp11-common.c => pdp11-common.cc}      |     0
 .../config/pru/{pru-common.c => pru-common.cc}     |     0
 .../riscv/{riscv-common.c => riscv-common.cc}      |     0
 .../rs6000/{rs6000-common.c => rs6000-common.cc}   |     0
 gcc/common/config/rx/{rx-common.c => rx-common.cc} |     0
 .../config/s390/{s390-common.c => s390-common.cc}  |     0
 gcc/common/config/sh/{sh-common.c => sh-common.cc} |     0
 .../sparc/{sparc-common.c => sparc-common.cc}      |     0
 .../tilegx/{tilegx-common.c => tilegx-common.cc}   |     0
 .../{tilepro-common.c => tilepro-common.cc}        |     0
 .../config/v850/{v850-common.c => v850-common.cc}  |     0
 .../config/vax/{vax-common.c => vax-common.cc}     |     0
 .../visium/{visium-common.c => visium-common.cc}   |     0
 .../{xstormy16-common.c => xstormy16-common.cc}    |     0
 .../xtensa/{xtensa-common.c => xtensa-common.cc}   |     0
 gcc/{compare-elim.c => compare-elim.cc}            |     0
 gcc/conditions.h                                   |     2 +-
 gcc/config.gcc                                     |    42 +-
 ...{aarch64-bti-insert.c => aarch64-bti-insert.cc} |     0
 gcc/config/aarch64/aarch64-builtins.c              |  3214 --
 gcc/config/aarch64/aarch64-builtins.cc             |  3214 ++
 gcc/config/aarch64/{aarch64-c.c => aarch64-c.cc}   |     0
 gcc/config/aarch64/{aarch64-d.c => aarch64-d.cc}   |     0
 gcc/config/aarch64/aarch64-protos.h                |     4 +-
 gcc/config/aarch64/aarch64-sve-builtins.cc         |     2 +-
 gcc/config/aarch64/aarch64.c                       | 26861 -----------
 gcc/config/aarch64/aarch64.cc                      | 26862 +++++++++++
 gcc/config/aarch64/aarch64.h                       |     6 +-
 gcc/config/aarch64/cortex-a57-fma-steering.c       |  1096 -
 gcc/config/aarch64/cortex-a57-fma-steering.cc      |  1096 +
 gcc/config/aarch64/driver-aarch64.c                |   470 -
 gcc/config/aarch64/driver-aarch64.cc               |   470 +
 ...oidance.c => falkor-tag-collision-avoidance.cc} |     0
 ...ost-aarch64-darwin.c => host-aarch64-darwin.cc} |     0
 gcc/config/aarch64/t-aarch64                       |    26 +-
 gcc/config/aarch64/x-aarch64                       |     2 +-
 gcc/config/aarch64/x-darwin                        |     2 +-
 gcc/config/alpha/alpha-protos.h                    |     2 +-
 gcc/config/alpha/alpha.c                           | 10058 ----
 gcc/config/alpha/alpha.cc                          | 10058 ++++
 gcc/config/alpha/alpha.h                           |     8 +-
 gcc/config/alpha/alpha.md                          |     4 +-
 gcc/config/alpha/driver-alpha.c                    |   101 -
 gcc/config/alpha/driver-alpha.cc                   |   101 +
 gcc/config/alpha/x-alpha                           |     2 +-
 gcc/config/arc/{arc-c.c => arc-c.cc}               |     0
 gcc/config/arc/arc-protos.h                        |     2 +-
 gcc/config/arc/arc.c                               | 11769 -----
 gcc/config/arc/arc.cc                              | 11769 +++++
 gcc/config/arc/arc.md                              |     8 +-
 gcc/config/arc/builtins.def                        |     4 +-
 gcc/config/arc/{driver-arc.c => driver-arc.cc}     |     0
 gcc/config/arc/t-arc                               |     6 +-
 gcc/config/arm/{aarch-common.c => aarch-common.cc} |     0
 gcc/config/arm/{arm-builtins.c => arm-builtins.cc} |     0
 gcc/config/arm/arm-c.c                             |   505 -
 gcc/config/arm/arm-c.cc                            |   505 +
 gcc/config/arm/{arm-d.c => arm-d.cc}               |     0
 gcc/config/arm/arm-protos.h                        |     8 +-
 gcc/config/arm/arm.c                               | 34143 -------------
 gcc/config/arm/arm.cc                              | 34143 +++++++++++++
 gcc/config/arm/arm.h                               |     8 +-
 gcc/config/arm/arm.md                              |     2 +-
 gcc/config/arm/driver-arm.c                        |   137 -
 gcc/config/arm/driver-arm.cc                       |   137 +
 gcc/config/arm/symbian.h                           |     2 +-
 gcc/config/arm/t-arm                               |    16 +-
 gcc/config/arm/thumb1.md                           |    10 +-
 gcc/config/arm/x-arm                               |     2 +-
 gcc/config/avr/avr-c.c                             |   509 -
 gcc/config/avr/avr-c.cc                            |   509 +
 gcc/config/avr/{avr-devices.c => avr-devices.cc}   |     0
 gcc/config/avr/avr-fixed.md                        |     2 +-
 gcc/config/avr/avr-log.c                           |   325 -
 gcc/config/avr/avr-log.cc                          |   325 +
 gcc/config/avr/avr-mcus.def                        |     2 +-
 gcc/config/avr/avr-modes.def                       |     2 +-
 gcc/config/avr/avr-passes.def                      |     2 +-
 gcc/config/avr/avr-protos.h                        |     4 +-
 gcc/config/avr/avr.c                               | 14717 ------
 gcc/config/avr/avr.cc                              | 14717 ++++++
 gcc/config/avr/avr.h                               |     4 +-
 gcc/config/avr/avr.md                              |     6 +-
 gcc/config/avr/builtins.def                        |     4 +-
 gcc/config/avr/{driver-avr.c => driver-avr.cc}     |     0
 gcc/config/avr/gen-avr-mmcu-specs.c                |   323 -
 gcc/config/avr/gen-avr-mmcu-specs.cc               |   323 +
 gcc/config/avr/gen-avr-mmcu-texi.c                 |   202 -
 gcc/config/avr/gen-avr-mmcu-texi.cc                |   202 +
 gcc/config/avr/t-avr                               |    18 +-
 gcc/config/bfin/bfin.c                             |  5883 ---
 gcc/config/bfin/bfin.cc                            |  5883 +++
 gcc/config/bpf/bpf-protos.h                        |     2 +-
 gcc/config/bpf/{bpf.c => bpf.cc}                   |     0
 gcc/config/bpf/bpf.h                               |     2 +-
 gcc/config/bpf/{coreout.c => coreout.cc}           |     0
 gcc/config/bpf/t-bpf                               |     2 +-
 gcc/config/c6x/c6x-protos.h                        |     4 +-
 gcc/config/c6x/{c6x.c => c6x.cc}                   |     0
 gcc/config/cr16/cr16-protos.h                      |     2 +-
 gcc/config/cr16/{cr16.c => cr16.cc}                |     0
 gcc/config/cris/cris.c                             |  3729 --
 gcc/config/cris/cris.cc                            |  3729 ++
 gcc/config/cris/cris.h                             |     8 +-
 gcc/config/cris/cris.opt                           |     2 +-
 gcc/config/cris/sync.md                            |     2 +-
 gcc/config/csky/csky.c                             |  7329 ---
 gcc/config/csky/csky.cc                            |  7329 +++
 gcc/config/darwin-c.c                              |   889 -
 gcc/config/darwin-c.cc                             |   889 +
 gcc/config/{darwin-d.c => darwin-d.cc}             |     0
 gcc/config/{darwin-driver.c => darwin-driver.cc}   |     0
 gcc/config/darwin-f.c                              |    60 -
 gcc/config/darwin-f.cc                             |    60 +
 gcc/config/darwin-sections.def                     |     8 +-
 gcc/config/darwin.c                                |  3886 --
 gcc/config/darwin.cc                               |  3886 ++
 gcc/config/darwin.h                                |     4 +-
 gcc/config/{default-c.c => default-c.cc}           |     0
 gcc/config/{default-d.c => default-d.cc}           |     0
 gcc/config/{dragonfly-d.c => dragonfly-d.cc}       |     0
 gcc/config/elfos.h                                 |     2 +-
 gcc/config/epiphany/epiphany-sched.md              |     2 +-
 gcc/config/epiphany/epiphany.c                     |  3047 --
 gcc/config/epiphany/epiphany.cc                    |  3047 ++
 gcc/config/epiphany/epiphany.h                     |     6 +-
 gcc/config/epiphany/mode-switch-use.c              |   107 -
 gcc/config/epiphany/mode-switch-use.cc             |   107 +
 gcc/config/epiphany/predicates.md                  |     2 +-
 .../{resolve-sw-modes.c => resolve-sw-modes.cc}    |     0
 gcc/config/epiphany/t-epiphany                     |     4 +-
 gcc/config/fr30/fr30-protos.h                      |     2 +-
 gcc/config/fr30/{fr30.c => fr30.cc}                |     0
 gcc/config/{freebsd-d.c => freebsd-d.cc}           |     0
 gcc/config/frv/frv-protos.h                        |     2 +-
 gcc/config/frv/frv.c                               |  9451 ----
 gcc/config/frv/frv.cc                              |  9451 ++++
 gcc/config/frv/frv.h                               |     2 +-
 gcc/config/ft32/ft32-protos.h                      |     2 +-
 gcc/config/ft32/{ft32.c => ft32.cc}                |     0
 gcc/config/gcn/{driver-gcn.c => driver-gcn.cc}     |     0
 gcc/config/gcn/gcn-hsa.h                           |     2 +-
 gcc/config/gcn/{gcn-run.c => gcn-run.cc}           |     0
 gcc/config/gcn/{gcn-tree.c => gcn-tree.cc}         |     0
 gcc/config/gcn/gcn.c                               |  6672 ---
 gcc/config/gcn/gcn.cc                              |  6672 +++
 gcc/config/gcn/mkoffload.c                         |  1174 -
 gcc/config/gcn/mkoffload.cc                        |  1174 +
 gcc/config/gcn/t-gcn-hsa                           |     8 +-
 gcc/config/gcn/t-omp-device                        |     2 +-
 gcc/config/{glibc-c.c => glibc-c.cc}               |     0
 gcc/config/{glibc-d.c => glibc-d.cc}               |     0
 gcc/config/h8300/h8300-protos.h                    |     4 +-
 gcc/config/h8300/h8300.c                           |  5632 ---
 gcc/config/h8300/h8300.cc                          |  5632 +++
 gcc/config/h8300/h8300.h                           |     6 +-
 gcc/config/{host-darwin.c => host-darwin.cc}       |     0
 gcc/config/{host-hpux.c => host-hpux.cc}           |     0
 gcc/config/{host-linux.c => host-linux.cc}         |     0
 gcc/config/{host-netbsd.c => host-netbsd.cc}       |     0
 gcc/config/{host-openbsd.c => host-openbsd.cc}     |     0
 gcc/config/{host-solaris.c => host-solaris.cc}     |     0
 gcc/config/i386/cygming.h                          |     4 +-
 gcc/config/i386/{djgpp.c => djgpp.cc}              |     0
 gcc/config/i386/djgpp.h                            |     2 +-
 gcc/config/i386/dragonfly.h                        |     2 +-
 gcc/config/i386/driver-i386.c                      |   841 -
 gcc/config/i386/driver-i386.cc                     |   841 +
 .../i386/{driver-mingw32.c => driver-mingw32.cc}   |     0
 gcc/config/i386/freebsd.h                          |     2 +-
 .../i386/{gnu-property.c => gnu-property.cc}       |     0
 gcc/config/i386/{host-cygwin.c => host-cygwin.cc}  |     0
 .../{host-i386-darwin.c => host-i386-darwin.cc}    |     0
 .../i386/{host-mingw32.c => host-mingw32.cc}       |     0
 .../i386/{i386-builtins.c => i386-builtins.cc}     |     0
 gcc/config/i386/i386-c.c                           |   817 -
 gcc/config/i386/i386-c.cc                          |   817 +
 gcc/config/i386/{i386-d.c => i386-d.cc}            |     0
 gcc/config/i386/i386-expand.c                      | 23247 ---------
 gcc/config/i386/i386-expand.cc                     | 23280 +++++++++
 .../i386/{i386-features.c => i386-features.cc}     |     0
 gcc/config/i386/i386-options.c                     |  3863 --
 gcc/config/i386/i386-options.cc                    |  3863 ++
 gcc/config/i386/i386-protos.h                      |    13 +-
 gcc/config/i386/i386.c                             | 24709 ----------
 gcc/config/i386/i386.cc                            | 24709 ++++++++++
 gcc/config/i386/i386.h                             |    18 +-
 gcc/config/i386/i386.md                            |    28 +-
 ...{intelmic-mkoffload.c => intelmic-mkoffload.cc} |     0
 gcc/config/i386/lynx.h                             |     2 +-
 gcc/config/i386/mmx.md                             |     8 +-
 gcc/config/i386/{msformat-c.c => msformat-c.cc}    |     0
 gcc/config/i386/sse.md                             |    87 +-
 gcc/config/i386/subst.md                           |     7 +
 gcc/config/i386/t-cygming                          |    18 +-
 gcc/config/i386/t-djgpp                            |     4 +-
 gcc/config/i386/t-gnu-property                     |     2 +-
 gcc/config/i386/t-i386                             |    20 +-
 gcc/config/i386/t-intelmic                         |     2 +-
 gcc/config/i386/t-omp-device                       |     4 +-
 gcc/config/i386/winnt-cxx.c                        |   177 -
 gcc/config/i386/winnt-cxx.cc                       |   177 +
 gcc/config/i386/{winnt-d.c => winnt-d.cc}          |     0
 gcc/config/i386/{winnt-stubs.c => winnt-stubs.cc}  |     0
 gcc/config/i386/winnt.c                            |  1377 -
 gcc/config/i386/winnt.cc                           |  1377 +
 gcc/config/i386/x-cygwin                           |     4 +-
 gcc/config/i386/x-darwin                           |     2 +-
 gcc/config/i386/x-i386                             |     2 +-
 gcc/config/i386/x-mingw32                          |     6 +-
 ...86-tune-sched-atom.c => x86-tune-sched-atom.cc} |     0
 .../{x86-tune-sched-bd.c => x86-tune-sched-bd.cc}  |     0
 gcc/config/i386/x86-tune-sched-core.c              |   257 -
 gcc/config/i386/x86-tune-sched-core.cc             |   257 +
 .../i386/{x86-tune-sched.c => x86-tune-sched.cc}   |     0
 gcc/config/i386/x86-tune.def                       |    10 +-
 gcc/config/i386/xm-djgpp.h                         |     4 +-
 gcc/config/ia64/freebsd.h                          |     4 +-
 gcc/config/ia64/hpux.h                             |     2 +-
 gcc/config/ia64/{ia64-c.c => ia64-c.cc}            |     0
 gcc/config/ia64/ia64-protos.h                      |     2 +-
 gcc/config/ia64/ia64.c                             | 11927 -----
 gcc/config/ia64/ia64.cc                            | 11927 +++++
 gcc/config/ia64/ia64.h                             |     2 +-
 gcc/config/ia64/ia64.md                            |     4 +-
 gcc/config/ia64/predicates.md                      |     2 +-
 gcc/config/ia64/sysv4.h                            |     4 +-
 gcc/config/ia64/t-ia64                             |     6 +-
 gcc/config/iq2000/{iq2000.c => iq2000.cc}          |     0
 gcc/config/iq2000/iq2000.h                         |     2 +-
 gcc/config/iq2000/iq2000.md                        |     4 +-
 gcc/config/{linux.c => linux.cc}                   |     0
 gcc/config/linux.h                                 |     4 +-
 gcc/config/lm32/{lm32.c => lm32.cc}                |     0
 gcc/config/m32c/{m32c-pragma.c => m32c-pragma.cc}  |     0
 gcc/config/m32c/m32c.c                             |  4506 --
 gcc/config/m32c/m32c.cc                            |  4506 ++
 gcc/config/m32c/m32c.h                             |     2 +-
 gcc/config/m32c/t-m32c                             |     2 +-
 gcc/config/m32r/m32r-protos.h                      |     2 +-
 gcc/config/m32r/m32r.c                             |  2959 --
 gcc/config/m32r/m32r.cc                            |  2959 ++
 gcc/config/m32r/m32r.h                             |     4 +-
 gcc/config/m32r/m32r.md                            |     2 +-
 gcc/config/m68k/m68k-isas.def                      |     2 +-
 gcc/config/m68k/m68k-microarchs.def                |     2 +-
 gcc/config/m68k/m68k-protos.h                      |     6 +-
 gcc/config/m68k/m68k.c                             |  7154 ---
 gcc/config/m68k/m68k.cc                            |  7154 +++
 gcc/config/m68k/m68k.h                             |     4 +-
 gcc/config/m68k/m68k.md                            |     4 +-
 gcc/config/m68k/m68kemb.h                          |     2 +-
 gcc/config/m68k/uclinux.h                          |     2 +-
 gcc/config/mcore/mcore-protos.h                    |     2 +-
 gcc/config/mcore/mcore.c                           |  3290 --
 gcc/config/mcore/mcore.cc                          |  3290 ++
 gcc/config/mcore/mcore.h                           |     4 +-
 gcc/config/mcore/mcore.md                          |     2 +-
 .../microblaze/{microblaze-c.c => microblaze-c.cc} |     0
 gcc/config/microblaze/microblaze-protos.h          |     2 +-
 gcc/config/microblaze/microblaze.c                 |  4070 --
 gcc/config/microblaze/microblaze.cc                |  4070 ++
 gcc/config/microblaze/microblaze.h                 |     2 +-
 gcc/config/microblaze/microblaze.md                |     4 +-
 gcc/config/microblaze/t-microblaze                 |     4 +-
 gcc/config/mips/driver-native.c                    |    91 -
 gcc/config/mips/driver-native.cc                   |    91 +
 .../{frame-header-opt.c => frame-header-opt.cc}    |     0
 gcc/config/mips/loongson2ef.md                     |     2 +-
 gcc/config/mips/{mips-d.c => mips-d.cc}            |     0
 gcc/config/mips/mips-protos.h                      |     2 +-
 gcc/config/mips/mips.c                             | 22925 ---------
 gcc/config/mips/mips.cc                            | 22925 +++++++++
 gcc/config/mips/mips.h                             |     2 +-
 gcc/config/mips/mips.md                            |     2 +-
 gcc/config/mips/t-mips                             |     4 +-
 gcc/config/mips/x-native                           |     2 +-
 gcc/config/mmix/mmix-protos.h                      |     2 +-
 gcc/config/mmix/mmix.c                             |  2872 --
 gcc/config/mmix/mmix.cc                            |  2872 ++
 gcc/config/mmix/mmix.h                             |     2 +-
 gcc/config/mmix/mmix.md                            |     4 +-
 gcc/config/mmix/predicates.md                      |     2 +-
 gcc/config/mn10300/mn10300.c                       |  3423 --
 gcc/config/mn10300/mn10300.cc                      |  3423 ++
 gcc/config/mn10300/mn10300.h                       |     6 +-
 gcc/config/moxie/moxie-protos.h                    |     2 +-
 gcc/config/moxie/{moxie.c => moxie.cc}             |     0
 gcc/config/moxie/uclinux.h                         |     2 +-
 .../msp430/{driver-msp430.c => driver-msp430.cc}   |     0
 gcc/config/msp430/{msp430-c.c => msp430-c.cc}      |     0
 gcc/config/msp430/msp430-devices.c                 |  1110 -
 gcc/config/msp430/msp430-devices.cc                |  1110 +
 gcc/config/msp430/msp430.c                         |  4521 --
 gcc/config/msp430/msp430.cc                        |  4521 ++
 gcc/config/msp430/msp430.h                         |     4 +-
 gcc/config/msp430/t-msp430                         |     6 +-
 gcc/config/nds32/nds32-cost.c                      |   726 -
 gcc/config/nds32/nds32-cost.cc                     |   726 +
 gcc/config/nds32/nds32-doubleword.md               |     2 +-
 .../nds32/{nds32-fp-as-gp.c => nds32-fp-as-gp.cc}  |     0
 .../{nds32-intrinsic.c => nds32-intrinsic.cc}      |     0
 gcc/config/nds32/{nds32-isr.c => nds32-isr.cc}     |     0
 ...{nds32-md-auxiliary.c => nds32-md-auxiliary.cc} |     0
 ...manipulation.c => nds32-memory-manipulation.cc} |     0
 ...es-auxiliary.c => nds32-pipelines-auxiliary.cc} |     0
 .../{nds32-predicates.c => nds32-predicates.cc}    |     0
 .../{nds32-relax-opt.c => nds32-relax-opt.cc}      |     0
 gcc/config/nds32/{nds32-utils.c => nds32-utils.cc} |     0
 gcc/config/nds32/nds32.c                           |  5895 ---
 gcc/config/nds32/nds32.cc                          |  5895 +++
 gcc/config/nds32/nds32.h                           |    10 +-
 gcc/config/nds32/predicates.md                     |    12 +-
 gcc/config/nds32/t-nds32                           |    40 +-
 gcc/config/{netbsd-d.c => netbsd-d.cc}             |     0
 gcc/config/{netbsd.c => netbsd.cc}                 |     0
 gcc/config/nios2/nios2.c                           |  5624 ---
 gcc/config/nios2/nios2.cc                          |  5624 +++
 gcc/config/nvptx/{mkoffload.c => mkoffload.cc}     |     0
 gcc/config/nvptx/{nvptx-c.c => nvptx-c.cc}         |     0
 gcc/config/nvptx/nvptx-protos.h                    |     2 +-
 gcc/config/nvptx/nvptx.c                           |  7011 ---
 gcc/config/nvptx/nvptx.cc                          |  7011 +++
 gcc/config/nvptx/nvptx.h                           |     2 +-
 gcc/config/nvptx/t-nvptx                           |     4 +-
 gcc/config/nvptx/t-omp-device                      |     2 +-
 gcc/config/{openbsd-d.c => openbsd-d.cc}           |     0
 gcc/config/or1k/{or1k.c => or1k.cc}                |     0
 gcc/config/pa/elf.h                                |     2 +-
 gcc/config/pa/{pa-d.c => pa-d.cc}                  |     0
 gcc/config/pa/pa-linux.h                           |     2 +-
 gcc/config/pa/pa-netbsd.h                          |     2 +-
 gcc/config/pa/pa-openbsd.h                         |     2 +-
 gcc/config/pa/pa-protos.h                          |    10 +-
 gcc/config/pa/pa.c                                 | 11080 -----
 gcc/config/pa/pa.cc                                | 11080 +++++
 gcc/config/pa/pa.h                                 |     8 +-
 gcc/config/pa/pa.md                                |     8 +-
 gcc/config/pa/som.h                                |     2 +-
 gcc/config/pa/t-pa                                 |     2 +-
 gcc/config/pdp11/pdp11.c                           |  2417 -
 gcc/config/pdp11/pdp11.cc                          |  2417 +
 gcc/config/pdp11/pdp11.h                           |     2 +-
 gcc/config/pdp11/pdp11.md                          |     2 +-
 gcc/config/pdp11/t-pdp11                           |     2 +-
 gcc/config/pru/{pru-passes.c => pru-passes.cc}     |     0
 gcc/config/pru/{pru-pragma.c => pru-pragma.cc}     |     0
 gcc/config/pru/{pru.c => pru.cc}                   |     0
 gcc/config/pru/pru.md                              |     2 +-
 gcc/config/pru/t-pru                               |     4 +-
 .../riscv/{riscv-builtins.c => riscv-builtins.cc}  |     0
 gcc/config/riscv/{riscv-c.c => riscv-c.cc}         |     0
 gcc/config/riscv/{riscv-d.c => riscv-d.cc}         |     0
 gcc/config/riscv/riscv-protos.h                    |    10 +-
 ...-shorten-memrefs.c => riscv-shorten-memrefs.cc} |     0
 gcc/config/riscv/{riscv-sr.c => riscv-sr.cc}       |     0
 gcc/config/riscv/riscv.c                           |  5783 ---
 gcc/config/riscv/riscv.cc                          |  5783 +++
 gcc/config/riscv/riscv.h                           |     4 +-
 gcc/config/riscv/t-riscv                           |    16 +-
 gcc/config/rl78/{rl78-c.c => rl78-c.cc}            |     0
 gcc/config/rl78/rl78.c                             |  4977 --
 gcc/config/rl78/rl78.cc                            |  4977 ++
 gcc/config/rl78/t-rl78                             |     2 +-
 gcc/config/rs6000/aix.h                            |     4 +-
 gcc/config/rs6000/aix71.h                          |     2 +-
 gcc/config/rs6000/aix72.h                          |     2 +-
 gcc/config/rs6000/aix73.h                          |     2 +-
 gcc/config/rs6000/altivec.md                       |    25 -
 gcc/config/rs6000/darwin.h                         |     6 +-
 gcc/config/rs6000/driver-rs6000.c                  |   638 -
 gcc/config/rs6000/driver-rs6000.cc                 |   638 +
 gcc/config/rs6000/freebsd.h                        |     4 +-
 gcc/config/rs6000/freebsd64.h                      |     4 +-
 .../rs6000/{host-darwin.c => host-darwin.cc}       |     0
 .../{host-ppc64-darwin.c => host-ppc64-darwin.cc}  |     0
 gcc/config/rs6000/lynx.h                           |     2 +-
 gcc/config/rs6000/rbtree.c                         |   242 -
 gcc/config/rs6000/rbtree.cc                        |   242 +
 gcc/config/rs6000/rbtree.h                         |     2 +-
 gcc/config/rs6000/rs6000-c.c                       |  2076 -
 gcc/config/rs6000/rs6000-c.cc                      |  2076 +
 gcc/config/rs6000/rs6000-call.c                    |  6521 ---
 gcc/config/rs6000/rs6000-call.cc                   |  6521 +++
 gcc/config/rs6000/rs6000-cpus.def                  |     2 +-
 gcc/config/rs6000/{rs6000-d.c => rs6000-d.cc}      |     0
 gcc/config/rs6000/rs6000-gen-builtins.c            |  3076 --
 gcc/config/rs6000/rs6000-gen-builtins.cc           |  3076 ++
 gcc/config/rs6000/rs6000-internal.h                |    10 +-
 .../rs6000/{rs6000-linux.c => rs6000-linux.cc}     |     0
 gcc/config/rs6000/rs6000-logue.c                   |  5689 ---
 gcc/config/rs6000/rs6000-logue.cc                  |  5689 +++
 gcc/config/rs6000/rs6000-overload.def              |    10 +-
 gcc/config/rs6000/rs6000-p8swap.c                  |  2788 --
 gcc/config/rs6000/rs6000-p8swap.cc                 |  2788 ++
 .../{rs6000-pcrel-opt.c => rs6000-pcrel-opt.cc}    |     0
 gcc/config/rs6000/rs6000-protos.h                  |     6 +-
 .../rs6000/{rs6000-string.c => rs6000-string.cc}   |     0
 gcc/config/rs6000/rs6000.c                         | 28942 -----------
 gcc/config/rs6000/rs6000.cc                        | 28942 +++++++++++
 gcc/config/rs6000/rs6000.h                         |    16 +-
 gcc/config/rs6000/rs6000.md                        |     2 +-
 gcc/config/rs6000/sysv4.h                          |     2 +-
 gcc/config/rs6000/t-linux                          |     2 +-
 gcc/config/rs6000/t-linux64                        |     2 +-
 gcc/config/rs6000/t-rs6000                         |    34 +-
 gcc/config/rs6000/vsx.md                           |    32 +-
 gcc/config/rs6000/x-darwin                         |     2 +-
 gcc/config/rs6000/x-darwin64                       |     2 +-
 gcc/config/rs6000/x-rs6000                         |     2 +-
 gcc/config/rs6000/xcoff.h                          |     4 +-
 gcc/config/rx/rx.c                                 |  3812 --
 gcc/config/rx/rx.cc                                |  3812 ++
 gcc/config/s390/constraints.md                     |     8 +-
 gcc/config/s390/driver-native.c                    |   189 -
 gcc/config/s390/driver-native.cc                   |   189 +
 gcc/config/s390/htmxlintrin.h                      |     2 +-
 gcc/config/s390/s390-builtins.def                  |     8 +-
 gcc/config/s390/s390-builtins.h                    |     2 +-
 gcc/config/s390/s390-c.c                           |  1100 -
 gcc/config/s390/s390-c.cc                          |  1100 +
 gcc/config/s390/{s390-d.c => s390-d.cc}            |     0
 gcc/config/s390/s390-opts.h                        |     2 +-
 gcc/config/s390/s390-protos.h                      |    10 +-
 gcc/config/s390/s390.c                             | 17478 -------
 gcc/config/s390/s390.cc                            | 17478 +++++++
 gcc/config/s390/s390.h                             |     8 +-
 gcc/config/s390/s390.md                            |     8 +-
 gcc/config/s390/t-s390                             |     6 +-
 gcc/config/s390/vx-builtins.md                     |     2 +-
 gcc/config/s390/x-native                           |     2 +-
 gcc/config/sh/divtab-sh4-300.c                     |    77 -
 gcc/config/sh/divtab-sh4-300.cc                    |    77 +
 gcc/config/sh/divtab-sh4.c                         |    85 -
 gcc/config/sh/divtab-sh4.cc                        |    85 +
 gcc/config/sh/divtab.c                             |   203 -
 gcc/config/sh/divtab.cc                            |   203 +
 gcc/config/sh/elf.h                                |     2 +-
 gcc/config/sh/{sh-c.c => sh-c.cc}                  |     0
 gcc/config/sh/sh-protos.h                          |     2 +-
 gcc/config/sh/sh.c                                 | 12630 -----
 gcc/config/sh/sh.cc                                | 12630 +++++
 gcc/config/sh/sh.h                                 |     8 +-
 gcc/config/sh/t-sh                                 |     4 +-
 gcc/config/{sol2-c.c => sol2-c.cc}                 |     0
 gcc/config/{sol2-cxx.c => sol2-cxx.cc}             |     0
 gcc/config/{sol2-d.c => sol2-d.cc}                 |     0
 gcc/config/sol2-protos.h                           |     6 +-
 gcc/config/{sol2-stubs.c => sol2-stubs.cc}         |     0
 gcc/config/{sol2.c => sol2.cc}                     |     0
 gcc/config/sol2.h                                  |     4 +-
 gcc/config/sparc/driver-sparc.c                    |   169 -
 gcc/config/sparc/driver-sparc.cc                   |   169 +
 gcc/config/sparc/freebsd.h                         |     4 +-
 gcc/config/sparc/{sparc-c.c => sparc-c.cc}         |     0
 gcc/config/sparc/{sparc-d.c => sparc-d.cc}         |     0
 gcc/config/sparc/sparc-protos.h                    |     2 +-
 gcc/config/sparc/sparc.c                           | 13958 ------
 gcc/config/sparc/sparc.cc                          | 13958 ++++++
 gcc/config/sparc/sparc.h                           |     6 +-
 gcc/config/sparc/sparc.md                          |     4 +-
 gcc/config/sparc/t-sparc                           |     4 +-
 gcc/config/sparc/x-sparc                           |     2 +-
 gcc/config/stormy16/stormy16.c                     |  2749 --
 gcc/config/stormy16/stormy16.cc                    |  2749 ++
 gcc/config/t-darwin                                |    10 +-
 gcc/config/t-dragonfly                             |     2 +-
 gcc/config/t-freebsd                               |     2 +-
 gcc/config/t-glibc                                 |     4 +-
 gcc/config/t-linux                                 |     2 +-
 gcc/config/t-netbsd                                |     4 +-
 gcc/config/t-openbsd                               |     2 +-
 gcc/config/t-pnt16-warn                            |     2 +-
 gcc/config/t-sol2                                  |    10 +-
 gcc/config/t-vxworks                               |     4 +-
 gcc/config/t-winnt                                 |     2 +-
 gcc/config/tilegx/{mul-tables.c => mul-tables.cc}  |     0
 gcc/config/tilegx/t-tilegx                         |     6 +-
 gcc/config/tilegx/tilegx-c.c                       |    55 -
 gcc/config/tilegx/tilegx-c.cc                      |    55 +
 gcc/config/tilegx/tilegx-protos.h                  |     2 +-
 gcc/config/tilegx/{tilegx.c => tilegx.cc}          |     0
 gcc/config/tilegx/tilegx.md                        |     2 +-
 gcc/config/tilepro/{mul-tables.c => mul-tables.cc} |     0
 gcc/config/tilepro/t-tilepro                       |     6 +-
 gcc/config/tilepro/tilepro-c.c                     |    54 -
 gcc/config/tilepro/tilepro-c.cc                    |    54 +
 gcc/config/tilepro/{tilepro.c => tilepro.cc}       |     0
 gcc/config/v850/t-v850                             |     4 +-
 gcc/config/v850/{v850-c.c => v850-c.cc}            |     0
 gcc/config/v850/v850-protos.h                      |     2 +-
 gcc/config/v850/v850.c                             |  3343 --
 gcc/config/v850/v850.cc                            |  3343 ++
 gcc/config/v850/v850.h                             |     6 +-
 gcc/config/vax/vax.c                               |  2212 -
 gcc/config/vax/vax.cc                              |  2212 +
 gcc/config/vax/vax.h                               |     2 +-
 gcc/config/vax/vax.md                              |     2 +-
 gcc/config/visium/visium.c                         |  4332 --
 gcc/config/visium/visium.cc                        |  4332 ++
 gcc/config/visium/visium.h                         |     6 +-
 gcc/config/vms/t-vms                               |     6 +-
 gcc/config/vms/{vms-c.c => vms-c.cc}               |     0
 gcc/config/vms/vms-crtlmap.map                     |     2 +-
 gcc/config/vms/{vms-f.c => vms-f.cc}               |     0
 gcc/config/vms/vms-protos.h                        |     4 +-
 gcc/config/vms/{vms.c => vms.cc}                   |     0
 gcc/config/vx-common.h                             |     2 +-
 gcc/config/{vxworks-c.c => vxworks-c.cc}           |     0
 gcc/config/{vxworks.c => vxworks.cc}               |     0
 gcc/config/{winnt-c.c => winnt-c.cc}               |     0
 gcc/config/x-darwin                                |     2 +-
 gcc/config/x-hpux                                  |     4 +-
 gcc/config/x-linux                                 |     2 +-
 gcc/config/x-netbsd                                |     4 +-
 gcc/config/x-openbsd                               |     4 +-
 gcc/config/x-solaris                               |     2 +-
 gcc/config/xtensa/xtensa-protos.h                  |     2 +-
 gcc/config/xtensa/xtensa.c                         |  4489 --
 gcc/config/xtensa/xtensa.cc                        |  4489 ++
 gcc/config/xtensa/xtensa.h                         |     2 +-
 gcc/configure                                      |    14 +-
 gcc/configure.ac                                   |    14 +-
 gcc/context.c                                      |    44 -
 gcc/context.cc                                     |    44 +
 gcc/{convert.c => convert.cc}                      |     0
 gcc/convert.h                                      |     2 +-
 gcc/coretypes.h                                    |     2 +-
 gcc/coverage.c                                     |  1392 -
 gcc/coverage.cc                                    |  1392 +
 gcc/coverage.h                                     |     2 +-
 gcc/cp/ChangeLog                                   |   177 +
 gcc/cp/Make-lang.in                                |     8 +-
 gcc/cp/{call.c => call.cc}                         |     0
 gcc/cp/{class.c => class.cc}                       |     0
 gcc/cp/config-lang.in                              |    34 +-
 gcc/cp/constexpr.c                                 |  9561 ----
 gcc/cp/constexpr.cc                                |  9561 ++++
 gcc/cp/coroutines.cc                               |     2 +-
 gcc/cp/cp-gimplify.c                               |  3280 --
 gcc/cp/cp-gimplify.cc                              |  3285 ++
 gcc/cp/cp-lang.c                                   |   291 -
 gcc/cp/cp-lang.cc                                  |   291 +
 gcc/cp/cp-objcp-common.c                           |   594 -
 gcc/cp/cp-objcp-common.cc                          |   594 +
 gcc/cp/cp-objcp-common.h                           |     4 +-
 gcc/cp/cp-tree.h                                   |    84 +-
 gcc/cp/{cp-ubsan.c => cp-ubsan.cc}                 |     0
 gcc/cp/cvt.c                                       |  2153 -
 gcc/cp/cvt.cc                                      |  2153 +
 gcc/cp/{cxx-pretty-print.c => cxx-pretty-print.cc} |     0
 gcc/cp/decl.c                                      | 18355 -------
 gcc/cp/decl.cc                                     | 18355 +++++++
 gcc/cp/decl2.c                                     |  5992 ---
 gcc/cp/decl2.cc                                    |  5992 +++
 gcc/cp/{dump.c => dump.cc}                         |     0
 gcc/cp/error.c                                     |  4659 --
 gcc/cp/error.cc                                    |  4659 ++
 gcc/cp/{except.c => except.cc}                     |     0
 gcc/cp/{expr.c => expr.cc}                         |     0
 gcc/cp/{friend.c => friend.cc}                     |     0
 gcc/cp/{g++spec.c => g++spec.cc}                   |     0
 gcc/cp/init.c                                      |  5354 --
 gcc/cp/init.cc                                     |  5354 ++
 gcc/cp/{lambda.c => lambda.cc}                     |     0
 gcc/cp/lang-specs.h                                |     2 +-
 gcc/cp/{lex.c => lex.cc}                           |     0
 gcc/cp/{mangle.c => mangle.cc}                     |     0
 gcc/cp/method.c                                    |  3506 --
 gcc/cp/method.cc                                   |  3506 ++
 gcc/cp/module.cc                                   |     4 +-
 gcc/cp/name-lookup.c                               |  8944 ----
 gcc/cp/name-lookup.cc                              |  8944 ++++
 gcc/cp/name-lookup.h                               |     2 +-
 gcc/cp/{optimize.c => optimize.cc}                 |     0
 gcc/cp/parser.c                                    | 48319 -------------------
 gcc/cp/parser.cc                                   | 48319 +++++++++++++++++++
 gcc/cp/parser.h                                    |     2 +-
 gcc/cp/pt.c                                        | 30596 ------------
 gcc/cp/pt.cc                                       | 30596 ++++++++++++
 gcc/cp/{ptree.c => ptree.cc}                       |     0
 gcc/cp/{rtti.c => rtti.cc}                         |     0
 gcc/cp/{search.c => search.cc}                     |     0
 gcc/cp/semantics.c                                 | 12340 -----
 gcc/cp/semantics.cc                                | 12340 +++++
 gcc/cp/tree.c                                      |  6180 ---
 gcc/cp/tree.cc                                     |  6180 +++
 gcc/cp/typeck.c                                    | 11350 -----
 gcc/cp/typeck.cc                                   | 11350 +++++
 gcc/cp/{typeck2.c => typeck2.cc}                   |     0
 gcc/cp/vtable-class-hierarchy.c                    |  1346 -
 gcc/cp/vtable-class-hierarchy.cc                   |  1346 +
 gcc/{cppbuiltin.c => cppbuiltin.cc}                |     0
 gcc/{cppdefault.c => cppdefault.cc}                |     0
 gcc/cppdefault.h                                   |     2 +-
 gcc/cprop.c                                        |  1974 -
 gcc/cprop.cc                                       |  1974 +
 gcc/cse.c                                          |  7736 ---
 gcc/cse.cc                                         |  7736 +++
 gcc/{cselib.c => cselib.cc}                        |     0
 gcc/{ctfc.c => ctfc.cc}                            |     0
 gcc/ctfc.h                                         |     4 +-
 gcc/{ctfout.c => ctfout.cc}                        |     0
 gcc/d/ChangeLog                                    |     6 +
 gcc/d/d-gimplify.cc                                |     2 +-
 gcc/d/d-incpath.cc                                 |     2 +-
 gcc/d/lang-specs.h                                 |     2 +-
 gcc/{data-streamer-in.c => data-streamer-in.cc}    |     0
 gcc/{data-streamer-out.c => data-streamer-out.cc}  |     0
 gcc/{data-streamer.c => data-streamer.cc}          |     0
 gcc/data-streamer.h                                |     6 +-
 gcc/{dbgcnt.c => dbgcnt.cc}                        |     0
 gcc/dbgcnt.def                                     |     2 +-
 gcc/dbxout.c                                       |  3936 --
 gcc/dbxout.cc                                      |  3936 ++
 gcc/dbxout.h                                       |     2 +-
 gcc/{dce.c => dce.cc}                              |     0
 gcc/{ddg.c => ddg.cc}                              |     0
 gcc/{debug.c => debug.cc}                          |     0
 gcc/debug.h                                        |     8 +-
 gcc/df-core.c                                      |  2472 -
 gcc/df-core.cc                                     |  2472 +
 gcc/{df-problems.c => df-problems.cc}              |     0
 gcc/df-scan.c                                      |  4252 --
 gcc/df-scan.cc                                     |  4252 ++
 gcc/df.h                                           |     8 +-
 gcc/dfp.c                                          |   745 -
 gcc/dfp.cc                                         |   745 +
 gcc/diagnostic-color.c                             |   348 -
 gcc/diagnostic-color.cc                            |   348 +
 gcc/diagnostic-event-id.h                          |     2 +-
 gcc/diagnostic-show-locus.c                        |  5703 ---
 gcc/diagnostic-show-locus.cc                       |  5703 +++
 gcc/diagnostic-spec.c                              |   196 -
 gcc/diagnostic-spec.cc                             |   205 +
 gcc/diagnostic-spec.h                              |     6 +-
 gcc/diagnostic.c                                   |  2456 -
 gcc/diagnostic.cc                                  |  2488 +
 gcc/diagnostic.h                                   |     4 +
 gcc/doc/avr-mmcu.texi                              |     4 +-
 gcc/doc/cfg.texi                                   |     2 +-
 gcc/doc/contrib.texi                               |     2 +-
 gcc/doc/cppinternals.texi                          |     6 +-
 gcc/doc/extend.texi                                |     2 +-
 gcc/doc/generic.texi                               |     8 +-
 gcc/doc/gimple.texi                                |     8 +-
 gcc/doc/gty.texi                                   |     8 +-
 gcc/doc/install.texi                               |     2 +-
 gcc/doc/invoke.texi                                |   128 +-
 gcc/doc/loop.texi                                  |     2 +-
 gcc/doc/lto.texi                                   |    40 +-
 gcc/doc/match-and-simplify.texi                    |     2 +-
 gcc/doc/md.texi                                    |    15 +-
 gcc/doc/optinfo.texi                               |     4 +-
 gcc/doc/options.texi                               |     2 +-
 gcc/doc/passes.texi                                |   288 +-
 gcc/doc/plugins.texi                               |     4 +-
 gcc/doc/rtl.texi                                   |    10 +-
 gcc/doc/sourcebuild.texi                           |     6 +-
 gcc/doc/tm.texi                                    |    46 +-
 gcc/doc/tm.texi.in                                 |    28 +-
 gcc/doc/tree-ssa.texi                              |     6 +-
 gcc/dojump.c                                       |  1300 -
 gcc/dojump.cc                                      |  1300 +
 gcc/dojump.h                                       |     2 +-
 gcc/{dominance.c => dominance.cc}                  |     0
 gcc/{domwalk.c => domwalk.cc}                      |     0
 gcc/{double-int.c => double-int.cc}                |     0
 gcc/{dse.c => dse.cc}                              |     0
 gcc/dumpfile.c                                     |  2778 --
 gcc/dumpfile.cc                                    |  2778 ++
 gcc/dumpfile.h                                     |    18 +-
 gcc/dwarf2asm.c                                    |  1162 -
 gcc/dwarf2asm.cc                                   |  1162 +
 gcc/{dwarf2cfi.c => dwarf2cfi.cc}                  |     0
 gcc/{dwarf2ctf.c => dwarf2ctf.cc}                  |     0
 gcc/dwarf2ctf.h                                    |     4 +-
 gcc/dwarf2out.c                                    | 33147 -------------
 gcc/dwarf2out.cc                                   | 33147 +++++++++++++
 gcc/dwarf2out.h                                    |     8 +-
 gcc/{early-remat.c => early-remat.cc}              |     0
 gcc/{edit-context.c => edit-context.cc}            |     0
 gcc/emit-rtl.c                                     |  6596 ---
 gcc/emit-rtl.cc                                    |  6596 +++
 gcc/emit-rtl.h                                     |     6 +-
 gcc/errors.c                                       |   134 -
 gcc/errors.cc                                      |   134 +
 gcc/et-forest.c                                    |   884 -
 gcc/et-forest.cc                                   |   884 +
 gcc/except.c                                       |  3522 --
 gcc/except.cc                                      |  3522 ++
 gcc/explow.c                                       |  2321 -
 gcc/explow.cc                                      |  2321 +
 gcc/explow.h                                       |     2 +-
 gcc/{expmed.c => expmed.cc}                        |     0
 gcc/expmed.h                                       |     2 +-
 gcc/expr.c                                         | 13145 -----
 gcc/expr.cc                                        | 13145 +++++
 gcc/{fibonacci_heap.c => fibonacci_heap.cc}        |     0
 gcc/{file-find.c => file-find.cc}                  |     0
 gcc/file-prefix-map.c                              |   149 -
 gcc/file-prefix-map.cc                             |   149 +
 gcc/final.c                                        |  4662 --
 gcc/final.cc                                       |  4662 ++
 gcc/{fixed-value.c => fixed-value.cc}              |     0
 gcc/fixed-value.h                                  |     2 +-
 gcc/flag-types.h                                   |    20 +-
 gcc/{fold-const-call.c => fold-const-call.cc}      |     0
 gcc/fold-const.c                                   | 16787 -------
 gcc/fold-const.cc                                  | 16787 +++++++
 gcc/fortran/ChangeLog                              |   254 +
 gcc/fortran/{arith.c => arith.cc}                  |     0
 gcc/fortran/{array.c => array.cc}                  |     0
 gcc/fortran/{bbt.c => bbt.cc}                      |     0
 gcc/fortran/check.c                                |  7523 ---
 gcc/fortran/check.cc                               |  7523 +++
 gcc/fortran/class.c                                |  3073 --
 gcc/fortran/class.cc                               |  3073 ++
 gcc/fortran/config-lang.in                         |     2 +-
 gcc/fortran/{constructor.c => constructor.cc}      |     0
 gcc/fortran/{convert.c => convert.cc}              |     0
 gcc/fortran/cpp.c                                  |  1203 -
 gcc/fortran/cpp.cc                                 |  1203 +
 gcc/fortran/data.c                                 |   848 -
 gcc/fortran/data.cc                                |   848 +
 gcc/fortran/decl.c                                 | 11910 -----
 gcc/fortran/decl.cc                                | 11910 +++++
 gcc/fortran/dependency.c                           |  2336 -
 gcc/fortran/dependency.cc                          |  2336 +
 .../{dump-parse-tree.c => dump-parse-tree.cc}      |     0
 gcc/fortran/error.c                                |  1656 -
 gcc/fortran/error.cc                               |  1656 +
 gcc/fortran/expr.c                                 |  6507 ---
 gcc/fortran/expr.cc                                |  6507 +++
 gcc/fortran/f95-lang.c                             |  1306 -
 gcc/fortran/f95-lang.cc                            |  1306 +
 .../{frontend-passes.c => frontend-passes.cc}      |     0
 gcc/fortran/gfc-internals.texi                     |    12 +-
 gcc/fortran/gfortran.h                             |    86 +-
 gcc/fortran/gfortranspec.c                         |   450 -
 gcc/fortran/gfortranspec.cc                        |   450 +
 gcc/fortran/interface.c                            |  5589 ---
 gcc/fortran/interface.cc                           |  5589 +++
 gcc/fortran/intrinsic.c                            |  5503 ---
 gcc/fortran/intrinsic.cc                           |  5503 +++
 gcc/fortran/{io.c => io.cc}                        |     0
 gcc/fortran/iresolve.c                             |  4050 --
 gcc/fortran/iresolve.cc                            |  4050 ++
 gcc/fortran/iso-c-binding.def                      |     2 +-
 gcc/fortran/lang-specs.h                           |     4 +-
 gcc/fortran/libgfortran.h                          |     2 +-
 gcc/fortran/match.c                                |  7264 ---
 gcc/fortran/match.cc                               |  7264 +++
 gcc/fortran/match.h                                |    28 +-
 gcc/fortran/matchexp.c                             |   903 -
 gcc/fortran/matchexp.cc                            |   903 +
 gcc/fortran/mathbuiltins.def                       |     2 +-
 gcc/fortran/{misc.c => misc.cc}                    |     0
 gcc/fortran/module.c                               |  7581 ---
 gcc/fortran/module.cc                              |  7581 +++
 gcc/fortran/openmp.c                               |  9410 ----
 gcc/fortran/openmp.cc                              |  9411 ++++
 gcc/fortran/{options.c => options.cc}              |     0
 gcc/fortran/parse.c                                |  6987 ---
 gcc/fortran/parse.cc                               |  6987 +++
 gcc/fortran/{primary.c => primary.cc}              |     0
 gcc/fortran/resolve.c                              | 17582 -------
 gcc/fortran/resolve.cc                             | 17582 +++++++
 gcc/fortran/{scanner.c => scanner.cc}              |     0
 gcc/fortran/simplify.c                             |  8966 ----
 gcc/fortran/simplify.cc                            |  8966 ++++
 gcc/fortran/{st.c => st.cc}                        |     0
 gcc/fortran/symbol.c                               |  5251 --
 gcc/fortran/symbol.cc                              |  5251 ++
 gcc/fortran/target-memory.c                        |   806 -
 gcc/fortran/target-memory.cc                       |   806 +
 gcc/fortran/target-memory.h                        |     2 +-
 gcc/fortran/trans-array.c                          | 11714 -----
 gcc/fortran/trans-array.cc                         | 11714 +++++
 gcc/fortran/{trans-common.c => trans-common.cc}    |     0
 gcc/fortran/trans-const.c                          |   430 -
 gcc/fortran/trans-const.cc                         |   430 +
 gcc/fortran/trans-decl.c                           |  7956 ---
 gcc/fortran/trans-decl.cc                          |  7956 +++
 gcc/fortran/trans-expr.c                           | 12125 -----
 gcc/fortran/trans-expr.cc                          | 12125 +++++
 gcc/fortran/trans-intrinsic.c                      | 12446 -----
 gcc/fortran/trans-intrinsic.cc                     | 12457 +++++
 gcc/fortran/trans-io.c                             |  2686 --
 gcc/fortran/trans-io.cc                            |  2686 ++
 gcc/fortran/trans-openmp.c                         |  7701 ---
 gcc/fortran/trans-openmp.cc                        |  7701 +++
 gcc/fortran/trans-stmt.c                           |  7468 ---
 gcc/fortran/trans-stmt.cc                          |  7468 +++
 gcc/fortran/trans-stmt.h                           |     8 +-
 gcc/fortran/trans-types.c                          |  3838 --
 gcc/fortran/trans-types.cc                         |  3838 ++
 gcc/fortran/trans-types.h                          |     2 +-
 gcc/fortran/trans.c                                |  2452 -
 gcc/fortran/trans.cc                               |  2452 +
 gcc/fortran/trans.h                                |    14 +-
 gcc/fp-test.c                                      |   251 -
 gcc/fp-test.cc                                     |   251 +
 gcc/{function-tests.c => function-tests.cc}        |     0
 gcc/function.c                                     |  6964 ---
 gcc/function.cc                                    |  6964 +++
 gcc/function.h                                     |    16 +-
 gcc/fwprop.c                                       |  1079 -
 gcc/fwprop.cc                                      |  1079 +
 gcc/{gcc-ar.c => gcc-ar.cc}                        |     0
 gcc/gcc-main.c                                     |    48 -
 gcc/gcc-main.cc                                    |    48 +
 gcc/{gcc-rich-location.c => gcc-rich-location.cc}  |     0
 gcc/gcc-rich-location.h                            |     2 +-
 gcc/gcc-symtab.h                                   |     2 +-
 gcc/gcc.c                                          | 11276 -----
 gcc/gcc.cc                                         | 11276 +++++
 gcc/gcc.h                                          |     6 +-
 gcc/gcov-dump.c                                    |   479 -
 gcc/gcov-dump.cc                                   |   479 +
 gcc/{gcov-io.c => gcov-io.cc}                      |     0
 gcc/{gcov-tool.c => gcov-tool.cc}                  |     0
 gcc/gcov.c                                         |  3262 --
 gcc/gcov.cc                                        |  3262 ++
 gcc/gcse-common.c                                  |   222 -
 gcc/gcse-common.cc                                 |   222 +
 gcc/gcse.c                                         |  4136 --
 gcc/gcse.cc                                        |  4136 ++
 gcc/genattr-common.c                               |   112 -
 gcc/genattr-common.cc                              |   112 +
 gcc/{genattr.c => genattr.cc}                      |     0
 gcc/genattrtab.c                                   |  5417 ---
 gcc/genattrtab.cc                                  |  5417 +++
 gcc/genautomata.c                                  |  9685 ----
 gcc/genautomata.cc                                 |  9685 ++++
 gcc/{gencfn-macros.c => gencfn-macros.cc}          |     0
 gcc/{gencheck.c => gencheck.cc}                    |     0
 gcc/{genchecksum.c => genchecksum.cc}              |     0
 gcc/{gencodes.c => gencodes.cc}                    |     0
 gcc/genconditions.c                                |   252 -
 gcc/genconditions.cc                               |   252 +
 gcc/{genconfig.c => genconfig.cc}                  |     0
 gcc/genconstants.c                                 |   105 -
 gcc/genconstants.cc                                |   105 +
 gcc/genemit.c                                      |   952 -
 gcc/genemit.cc                                     |   952 +
 gcc/{genenums.c => genenums.cc}                    |     0
 gcc/generic-match-head.c                           |   101 -
 gcc/generic-match-head.cc                          |   101 +
 gcc/genextract.c                                   |   507 -
 gcc/genextract.cc                                  |   507 +
 gcc/{genflags.c => genflags.cc}                    |     0
 gcc/gengenrtl.c                                    |   358 -
 gcc/gengenrtl.cc                                   |   358 +
 gcc/gengtype-parse.c                               |  1179 -
 gcc/gengtype-parse.cc                              |  1179 +
 gcc/gengtype-state.c                               |  2661 -
 gcc/gengtype-state.cc                              |  2661 +
 gcc/gengtype.c                                     |  5405 ---
 gcc/gengtype.cc                                    |  5399 +++
 gcc/gengtype.h                                     |     8 +-
 gcc/{genhooks.c => genhooks.cc}                    |     0
 gcc/genmatch.c                                     |  5257 --
 gcc/genmatch.cc                                    |  5257 ++
 gcc/genmddeps.c                                    |    71 -
 gcc/genmddeps.cc                                   |    71 +
 gcc/{genmddump.c => genmddump.cc}                  |     0
 gcc/genmodes.c                                     |  2068 -
 gcc/genmodes.cc                                    |  2068 +
 gcc/{genopinit.c => genopinit.cc}                  |     0
 gcc/{genoutput.c => genoutput.cc}                  |     0
 gcc/genpeep.c                                      |   418 -
 gcc/genpeep.cc                                     |   418 +
 gcc/genpreds.c                                     |  1682 -
 gcc/genpreds.cc                                    |  1682 +
 gcc/genrecog.c                                     |  5447 ---
 gcc/genrecog.cc                                    |  5447 +++
 gcc/gensupport.c                                   |  3316 --
 gcc/gensupport.cc                                  |  3316 ++
 gcc/gensupport.h                                   |    12 +-
 gcc/{gentarget-def.c => gentarget-def.cc}          |     0
 gcc/{genversion.c => genversion.cc}                |     0
 gcc/{ggc-common.c => ggc-common.cc}                |     0
 gcc/ggc-internal.h                                 |     2 +-
 gcc/{ggc-none.c => ggc-none.cc}                    |     0
 gcc/{ggc-page.c => ggc-page.cc}                    |     0
 gcc/{ggc-tests.c => ggc-tests.cc}                  |     0
 gcc/{gimple-builder.c => gimple-builder.cc}        |     0
 gcc/{gimple-expr.c => gimple-expr.cc}              |     0
 gcc/gimple-fold.c                                  |  9123 ----
 gcc/gimple-fold.cc                                 |  9123 ++++
 gcc/gimple-fold.h                                  |     2 +-
 gcc/{gimple-iterator.c => gimple-iterator.cc}      |     0
 gcc/{gimple-laddress.c => gimple-laddress.cc}      |     0
 gcc/{gimple-loop-jam.c => gimple-loop-jam.cc}      |     0
 gcc/gimple-low.c                                   |   947 -
 gcc/gimple-low.cc                                  |   947 +
 gcc/gimple-match-head.c                            |  1394 -
 gcc/gimple-match-head.cc                           |  1394 +
 ...imple-pretty-print.c => gimple-pretty-print.cc} |     0
 gcc/gimple-pretty-print.h                          |     2 +-
 ...imple-ssa-backprop.c => gimple-ssa-backprop.cc} |     0
 ...a-evrp-analyze.c => gimple-ssa-evrp-analyze.cc} |     0
 gcc/{gimple-ssa-evrp.c => gimple-ssa-evrp.cc}      |     0
 ...isolate-paths.c => gimple-ssa-isolate-paths.cc} |     0
 ...ull-compare.c => gimple-ssa-nonnull-compare.cc} |     0
 ...ssa-split-paths.c => gimple-ssa-split-paths.cc} |     0
 gcc/gimple-ssa-sprintf.c                           |  4728 --
 gcc/gimple-ssa-sprintf.cc                          |  4728 ++
 ...store-merging.c => gimple-ssa-store-merging.cc} |     0
 ...eduction.c => gimple-ssa-strength-reduction.cc} |     0
 gcc/gimple-ssa-warn-access.cc                      |   992 +-
 ...ssa-warn-alloca.c => gimple-ssa-warn-alloca.cc} |     0
 ...warn-restrict.c => gimple-ssa-warn-restrict.cc} |     0
 ...{gimple-streamer-in.c => gimple-streamer-in.cc} |     0
 ...imple-streamer-out.c => gimple-streamer-out.cc} |     0
 gcc/gimple-streamer.h                              |     4 +-
 gcc/{gimple-walk.c => gimple-walk.cc}              |     0
 ...e-warn-recursion.c => gimple-warn-recursion.cc} |     0
 gcc/{gimple.c => gimple.cc}                        |     0
 gcc/gimple.h                                       |     4 +-
 gcc/{gimplify-me.c => gimplify-me.cc}              |     0
 gcc/gimplify.c                                     | 16582 -------
 gcc/gimplify.cc                                    | 16582 +++++++
 gcc/go/ChangeLog                                   |    17 +
 gcc/go/config-lang.in                              |     2 +-
 gcc/go/go-backend.c                                |   194 -
 gcc/go/go-backend.cc                               |   194 +
 gcc/go/go-lang.c                                   |   638 -
 gcc/go/go-lang.cc                                  |   638 +
 gcc/go/gospec.c                                    |   466 -
 gcc/go/gospec.cc                                   |   466 +
 gcc/go/lang-specs.h                                |     2 +-
 gcc/{godump.c => godump.cc}                        |     0
 gcc/{graph.c => graph.cc}                          |     0
 gcc/{graphds.c => graphds.cc}                      |     0
 ...phite-dependences.c => graphite-dependences.cc} |     0
 gcc/graphite-isl-ast-to-gimple.c                   |  1556 -
 gcc/graphite-isl-ast-to-gimple.cc                  |  1556 +
 ...ite-optimize-isl.c => graphite-optimize-isl.cc} |     0
 gcc/{graphite-poly.c => graphite-poly.cc}          |     0
 ...scop-detection.c => graphite-scop-detection.cc} |     0
 ...ite-sese-to-poly.c => graphite-sese-to-poly.cc} |     0
 gcc/{graphite.c => graphite.cc}                    |     0
 gcc/haifa-sched.c                                  |  9263 ----
 gcc/haifa-sched.cc                                 |  9263 ++++
 gcc/{hash-map-tests.c => hash-map-tests.cc}        |     0
 gcc/{hash-set-tests.c => hash-set-tests.cc}        |     0
 gcc/{hash-table.c => hash-table.cc}                |     0
 gcc/{hooks.c => hooks.cc}                          |     0
 gcc/{host-default.c => host-default.cc}            |     0
 gcc/{hw-doloop.c => hw-doloop.cc}                  |     0
 gcc/{hwint.c => hwint.cc}                          |     0
 gcc/ifcvt.c                                        |  5694 ---
 gcc/ifcvt.cc                                       |  5694 +++
 gcc/{inchash.c => inchash.cc}                      |     0
 gcc/inchash.h                                      |     2 +-
 gcc/incpath.c                                      |   536 -
 gcc/incpath.cc                                     |   536 +
 gcc/{init-regs.c => init-regs.cc}                  |     0
 gcc/input.c                                        |  3932 --
 gcc/input.cc                                       |  3932 ++
 gcc/input.h                                        |     4 +-
 gcc/internal-fn.c                                  |  4429 --
 gcc/internal-fn.cc                                 |  4451 ++
 gcc/internal-fn.def                                |     3 +
 gcc/internal-fn.h                                  |     1 +
 gcc/{intl.c => intl.cc}                            |     0
 gcc/{ipa-comdats.c => ipa-comdats.cc}              |     0
 gcc/ipa-cp.c                                       |  6639 ---
 gcc/ipa-cp.cc                                      |  6639 +++
 gcc/{ipa-devirt.c => ipa-devirt.cc}                |     0
 gcc/ipa-fnsummary.c                                |  4972 --
 gcc/ipa-fnsummary.cc                               |  4972 ++
 gcc/ipa-fnsummary.h                                |     6 +-
 gcc/ipa-free-lang-data.cc                          |     4 +-
 gcc/{ipa-icf-gimple.c => ipa-icf-gimple.cc}        |     0
 gcc/{ipa-icf.c => ipa-icf.cc}                      |     0
 ...pa-inline-analysis.c => ipa-inline-analysis.cc} |     0
 ...-inline-transform.c => ipa-inline-transform.cc} |     0
 gcc/ipa-inline.c                                   |  3158 --
 gcc/ipa-inline.cc                                  |  3158 ++
 gcc/ipa-inline.h                                   |     6 +-
 gcc/{ipa-modref-tree.c => ipa-modref-tree.cc}      |     0
 gcc/ipa-modref.c                                   |  5509 ---
 gcc/ipa-modref.cc                                  |  5509 +++
 gcc/ipa-param-manipulation.c                       |  2401 -
 gcc/ipa-param-manipulation.cc                      |  2401 +
 ...-polymorphic-call.c => ipa-polymorphic-call.cc} |     0
 gcc/{ipa-predicate.c => ipa-predicate.cc}          |     0
 gcc/{ipa-profile.c => ipa-profile.cc}              |     0
 gcc/ipa-prop.c                                     |  6088 ---
 gcc/ipa-prop.cc                                    |  6088 +++
 gcc/ipa-prop.h                                     |     8 +-
 gcc/{ipa-pure-const.c => ipa-pure-const.cc}        |     0
 gcc/{ipa-ref.c => ipa-ref.cc}                      |     0
 gcc/ipa-reference.c                                |  1341 -
 gcc/ipa-reference.cc                               |  1341 +
 gcc/ipa-reference.h                                |     2 +-
 gcc/ipa-split.c                                    |  1982 -
 gcc/ipa-split.cc                                   |  2000 +
 gcc/ipa-sra.c                                      |  4148 --
 gcc/ipa-sra.cc                                     |  4148 ++
 gcc/{ipa-utils.c => ipa-utils.cc}                  |     0
 gcc/ipa-utils.h                                    |     8 +-
 gcc/{ipa-visibility.c => ipa-visibility.cc}        |     0
 gcc/{ipa.c => ipa.cc}                              |     0
 gcc/ira-build.c                                    |  3568 --
 gcc/ira-build.cc                                   |  3568 ++
 gcc/ira-color.c                                    |  5274 --
 gcc/ira-color.cc                                   |  5274 ++
 gcc/ira-conflicts.c                                |   895 -
 gcc/ira-conflicts.cc                               |   895 +
 gcc/{ira-costs.c => ira-costs.cc}                  |     0
 gcc/{ira-emit.c => ira-emit.cc}                    |     0
 gcc/ira-int.h                                      |    20 +-
 gcc/ira-lives.c                                    |  1765 -
 gcc/ira-lives.cc                                   |  1765 +
 gcc/ira.c                                          |  6132 ---
 gcc/ira.cc                                         |  6132 +++
 gcc/ira.h                                          |     4 +-
 gcc/jit/ChangeLog                                  |   156 +
 gcc/jit/config-lang.in                             |     2 +-
 gcc/jit/docs/_build/texinfo/libgccjit.texi         |    18 +-
 gcc/jit/docs/internals/index.rst                   |    12 +-
 gcc/jit/{dummy-frontend.c => dummy-frontend.cc}    |     0
 gcc/jit/jit-builtins.c                             |   707 -
 gcc/jit/jit-builtins.cc                            |   707 +
 gcc/jit/{jit-logging.c => jit-logging.cc}          |     0
 gcc/jit/jit-playback.c                             |  3618 --
 gcc/jit/jit-playback.cc                            |  3618 ++
 gcc/jit/jit-recording.c                            |  7537 ---
 gcc/jit/jit-recording.cc                           |  7537 +++
 gcc/jit/jit-recording.h                            |     2 +-
 gcc/jit/{jit-result.c => jit-result.cc}            |     0
 gcc/jit/{jit-spec.c => jit-spec.cc}                |     0
 gcc/jit/{jit-tempdir.c => jit-tempdir.cc}          |     0
 gcc/jit/{jit-w32.c => jit-w32.cc}                  |     0
 gcc/jit/libgccjit.c                                |  4172 --
 gcc/jit/libgccjit.cc                               |  4172 ++
 gcc/jit/notes.txt                                  |     6 +-
 gcc/{jump.c => jump.cc}                            |     0
 gcc/langhooks.c                                    |   952 -
 gcc/langhooks.cc                                   |   952 +
 gcc/langhooks.h                                    |    12 +-
 gcc/{lcm.c => lcm.cc}                              |     0
 gcc/libfuncs.h                                     |     2 +-
 gcc/{lists.c => lists.cc}                          |     0
 gcc/loop-doloop.c                                  |   807 -
 gcc/loop-doloop.cc                                 |   807 +
 gcc/loop-init.c                                    |   653 -
 gcc/loop-init.cc                                   |   653 +
 gcc/loop-invariant.c                               |  2322 -
 gcc/loop-invariant.cc                              |  2322 +
 gcc/{loop-iv.c => loop-iv.cc}                      |     0
 gcc/{loop-unroll.c => loop-unroll.cc}              |     0
 gcc/{lower-subreg.c => lower-subreg.cc}            |     0
 gcc/lower-subreg.h                                 |     2 +-
 gcc/{lra-assigns.c => lra-assigns.cc}              |     0
 gcc/{lra-coalesce.c => lra-coalesce.cc}            |     0
 gcc/lra-constraints.c                              |  7380 ---
 gcc/lra-constraints.cc                             |  7380 +++
 gcc/{lra-eliminations.c => lra-eliminations.cc}    |     0
 gcc/lra-int.h                                      |    24 +-
 gcc/{lra-lives.c => lra-lives.cc}                  |     0
 gcc/{lra-remat.c => lra-remat.cc}                  |     0
 gcc/lra-spills.c                                   |   880 -
 gcc/lra-spills.cc                                  |   880 +
 gcc/lra.c                                          |  2523 -
 gcc/lra.cc                                         |  2523 +
 gcc/{lto-cgraph.c => lto-cgraph.cc}                |     0
 gcc/{lto-compress.c => lto-compress.cc}            |     0
 gcc/lto-compress.h                                 |     2 +-
 gcc/{lto-opts.c => lto-opts.cc}                    |     0
 gcc/{lto-section-in.c => lto-section-in.cc}        |     0
 gcc/{lto-section-out.c => lto-section-out.cc}      |     0
 gcc/{lto-streamer-in.c => lto-streamer-in.cc}      |     0
 gcc/lto-streamer-out.c                             |  3363 --
 gcc/lto-streamer-out.cc                            |  3363 ++
 gcc/{lto-streamer.c => lto-streamer.cc}            |     0
 gcc/lto-streamer.h                                 |    22 +-
 gcc/lto-wrapper.c                                  |  2146 -
 gcc/lto-wrapper.cc                                 |  2146 +
 gcc/lto/ChangeLog                                  |    32 +
 gcc/lto/{common.c => common.cc}                    |     0
 gcc/lto/config-lang.in                             |     2 +-
 gcc/lto/lang-specs.h                               |     2 +-
 gcc/lto/lto-common.c                               |  3106 --
 gcc/lto/lto-common.cc                              |  3106 ++
 gcc/lto/lto-common.h                               |     2 +-
 gcc/lto/lto-dump.c                                 |   379 -
 gcc/lto/lto-dump.cc                                |   379 +
 gcc/lto/lto-lang.c                                 |  1490 -
 gcc/lto/lto-lang.cc                                |  1490 +
 gcc/lto/{lto-object.c => lto-object.cc}            |     0
 gcc/lto/{lto-partition.c => lto-partition.cc}      |     0
 gcc/lto/{lto-symtab.c => lto-symtab.cc}            |     0
 gcc/lto/lto.c                                      |   670 -
 gcc/lto/lto.cc                                     |   670 +
 gcc/lto/lto.h                                      |     4 +-
 gcc/machmode.def                                   |     2 +-
 gcc/machmode.h                                     |     4 +-
 gcc/main.c                                         |    45 -
 gcc/main.cc                                        |    45 +
 gcc/match.pd                                       |    16 +-
 gcc/{mcf.c => mcf.cc}                              |     0
 gcc/{mode-switching.c => mode-switching.cc}        |     0
 gcc/{modulo-sched.c => modulo-sched.cc}            |     0
 gcc/{multiple_target.c => multiple_target.cc}      |     0
 gcc/objc/ChangeLog                                 |    36 +
 gcc/objc/Make-lang.in                              |     2 +-
 gcc/objc/config-lang.in                            |     2 +-
 gcc/objc/lang-specs.h                              |     2 +-
 gcc/objc/objc-act.c                                | 10365 ----
 gcc/objc/objc-act.cc                               | 10365 ++++
 gcc/objc/objc-act.h                                |     4 +-
 gcc/objc/{objc-encoding.c => objc-encoding.cc}     |     0
 gcc/objc/objc-gnu-runtime-abi-01.c                 |  2262 -
 gcc/objc/objc-gnu-runtime-abi-01.cc                |  2262 +
 gcc/objc/objc-lang.c                               |    56 -
 gcc/objc/objc-lang.cc                              |    56 +
 gcc/objc/objc-map.c                                |   160 -
 gcc/objc/objc-map.cc                               |   160 +
 gcc/objc/objc-next-runtime-abi-01.c                |  2957 --
 gcc/objc/objc-next-runtime-abi-01.cc               |  2957 ++
 ...untime-abi-02.c => objc-next-runtime-abi-02.cc} |     0
 gcc/objc/objc-runtime-shared-support.c             |   718 -
 gcc/objc/objc-runtime-shared-support.cc            |   718 +
 gcc/objc/objc-runtime-shared-support.h             |     2 +-
 gcc/objcp/ChangeLog                                |    15 +
 gcc/objcp/Make-lang.in                             |    16 +-
 gcc/objcp/config-lang.in                           |    16 +-
 gcc/objcp/lang-specs.h                             |     2 +-
 gcc/objcp/objcp-decl.c                             |   115 -
 gcc/objcp/objcp-decl.cc                            |   115 +
 gcc/objcp/objcp-lang.c                             |    92 -
 gcc/objcp/objcp-lang.cc                            |    92 +
 gcc/omp-builtins.def                               |     4 +-
 gcc/omp-expand.c                                   | 10808 -----
 gcc/omp-expand.cc                                  | 10808 +++++
 gcc/{omp-general.c => omp-general.cc}              |     0
 gcc/omp-low.c                                      | 14777 ------
 gcc/omp-low.cc                                     | 14777 ++++++
 gcc/omp-oacc-neuter-broadcast.cc                   |    12 +-
 gcc/omp-offload.c                                  |  2823 --
 gcc/omp-offload.cc                                 |  2823 ++
 gcc/{omp-simd-clone.c => omp-simd-clone.cc}        |     0
 gcc/{opt-suggestions.c => opt-suggestions.cc}      |     0
 gcc/{optabs-libfuncs.c => optabs-libfuncs.cc}      |     0
 gcc/optabs-query.c                                 |   765 -
 gcc/optabs-query.cc                                |   765 +
 gcc/{optabs-tree.c => optabs-tree.cc}              |     0
 gcc/{optabs.c => optabs.cc}                        |     0
 gcc/optabs.def                                     |     1 +
 gcc/optc-gen.awk                                   |     2 +-
 gcc/optc-save-gen.awk                              |     2 +-
 gcc/optinfo-emit-json.cc                           |     4 +-
 gcc/opts-common.c                                  |  1857 -
 gcc/opts-common.cc                                 |  1857 +
 gcc/{opts-global.c => opts-global.cc}              |     0
 gcc/{opts.c => opts.cc}                            |     0
 gcc/output.h                                       |    16 +-
 gcc/pass_manager.h                                 |     2 +-
 gcc/{passes.c => passes.cc}                        |     0
 gcc/passes.def                                     |     5 +-
 gcc/plugin.c                                       |  1011 -
 gcc/plugin.cc                                      |  1011 +
 gcc/plugin.def                                     |     2 +-
 gcc/plugin.h                                       |     2 +-
 gcc/po/ChangeLog                                   |     4 +
 gcc/po/EXCLUDES                                    |    44 +-
 gcc/pointer-query.cc                               |     2 +-
 gcc/postreload-gcse.c                              |  1466 -
 gcc/postreload-gcse.cc                             |  1466 +
 gcc/{postreload.c => postreload.cc}                |     0
 gcc/{predict.c => predict.cc}                      |     0
 gcc/predict.h                                      |     4 +-
 gcc/{prefix.c => prefix.cc}                        |     0
 gcc/prefix.h                                       |     2 +-
 gcc/{pretty-print.c => pretty-print.cc}            |     0
 ...{print-rtl-function.c => print-rtl-function.cc} |     0
 gcc/{print-rtl.c => print-rtl.cc}                  |     0
 gcc/{print-tree.c => print-tree.cc}                |     0
 gcc/{profile-count.c => profile-count.cc}          |     0
 gcc/{profile.c => profile.cc}                      |     0
 gcc/profile.h                                      |     2 +-
 gcc/read-md.c                                      |  1363 -
 gcc/read-md.cc                                     |  1363 +
 gcc/read-md.h                                      |    10 +-
 gcc/read-rtl-function.c                            |  2230 -
 gcc/read-rtl-function.cc                           |  2230 +
 gcc/read-rtl.c                                     |  2092 -
 gcc/read-rtl.cc                                    |  2092 +
 gcc/real.c                                         |  5560 ---
 gcc/real.cc                                        |  5560 +++
 gcc/real.h                                         |     8 +-
 gcc/{realmpfr.c => realmpfr.cc}                    |     0
 gcc/recog.c                                        |  4625 --
 gcc/recog.cc                                       |  4625 ++
 gcc/recog.h                                        |     8 +-
 gcc/{ree.c => ree.cc}                              |     0
 gcc/reg-notes.def                                  |     2 +-
 gcc/reg-stack.c                                    |  3484 --
 gcc/reg-stack.cc                                   |  3484 ++
 gcc/{regcprop.c => regcprop.cc}                    |     0
 gcc/{reginfo.c => reginfo.cc}                      |     0
 gcc/{regrename.c => regrename.cc}                  |     0
 gcc/regs.h                                         |     2 +-
 gcc/regset.h                                       |     2 +-
 gcc/{regstat.c => regstat.cc}                      |     0
 gcc/reload.c                                       |  7364 ---
 gcc/reload.cc                                      |  7364 +++
 gcc/reload.h                                       |     8 +-
 gcc/reload1.c                                      |  9069 ----
 gcc/reload1.cc                                     |  9069 ++++
 gcc/reorg.c                                        |  3939 --
 gcc/reorg.cc                                       |  3939 ++
 gcc/{resource.c => resource.cc}                    |     0
 gcc/{rtl-error.c => rtl-error.cc}                  |     0
 gcc/{rtl-tests.c => rtl-tests.cc}                  |     0
 gcc/{rtl.c => rtl.cc}                              |     0
 gcc/rtl.def                                        |    12 +-
 gcc/rtl.h                                          |   146 +-
 gcc/rtlanal.c                                      |  6992 ---
 gcc/rtlanal.cc                                     |  6992 +++
 gcc/rtlanal.h                                      |     4 +-
 gcc/{rtlhash.c => rtlhash.cc}                      |     0
 gcc/{rtlhooks.c => rtlhooks.cc}                    |     0
 ...{rtx-vector-builder.c => rtx-vector-builder.cc} |     0
 gcc/run-rtl-passes.c                               |    79 -
 gcc/run-rtl-passes.cc                              |    79 +
 gcc/{sancov.c => sancov.cc}                        |     0
 gcc/sanitizer.def                                  |     6 +-
 gcc/{sanopt.c => sanopt.cc}                        |     0
 gcc/{sbitmap.c => sbitmap.cc}                      |     0
 gcc/sched-deps.c                                   |  4954 --
 gcc/sched-deps.cc                                  |  4954 ++
 gcc/sched-ebb.c                                    |   734 -
 gcc/sched-ebb.cc                                   |   734 +
 gcc/sched-int.h                                    |    28 +-
 gcc/sched-rgn.c                                    |  3956 --
 gcc/sched-rgn.cc                                   |  3956 ++
 gcc/sel-sched-dump.c                               |  1027 -
 gcc/sel-sched-dump.cc                              |  1027 +
 gcc/sel-sched-dump.h                               |     2 +-
 gcc/sel-sched-ir.c                                 |  6461 ---
 gcc/sel-sched-ir.cc                                |  6461 +++
 gcc/sel-sched-ir.h                                 |     8 +-
 gcc/sel-sched.c                                    |  7725 ---
 gcc/sel-sched.cc                                   |  7725 +++
 ...elftest-diagnostic.c => selftest-diagnostic.cc} |     0
 gcc/{selftest-rtl.c => selftest-rtl.cc}            |     0
 gcc/selftest-run-tests.c                           |   135 -
 gcc/selftest-run-tests.cc                          |   135 +
 gcc/{selftest.c => selftest.cc}                    |     0
 gcc/selftest.h                                     |     4 +-
 gcc/{sese.c => sese.cc}                            |     0
 gcc/shrink-wrap.c                                  |  1890 -
 gcc/shrink-wrap.cc                                 |  1890 +
 gcc/shrink-wrap.h                                  |     2 +-
 gcc/simplify-rtx.c                                 |  8471 ----
 gcc/simplify-rtx.cc                                |  8471 ++++
 gcc/{sparseset.c => sparseset.cc}                  |     0
 gcc/{spellcheck-tree.c => spellcheck-tree.cc}      |     0
 gcc/spellcheck-tree.h                              |     2 +-
 gcc/{spellcheck.c => spellcheck.cc}                |     0
 gcc/spellcheck.h                                   |     2 +-
 gcc/{sreal.c => sreal.cc}                          |     0
 gcc/{stack-ptr-mod.c => stack-ptr-mod.cc}          |     0
 gcc/{statistics.c => statistics.cc}                |     0
 gcc/statistics.h                                   |     2 +-
 gcc/stmt.c                                         |  1119 -
 gcc/stmt.cc                                        |  1119 +
 gcc/stmt.h                                         |     2 +-
 gcc/{stor-layout.c => stor-layout.cc}              |     0
 gcc/stor-layout.h                                  |     2 +-
 gcc/{store-motion.c => store-motion.cc}            |     0
 gcc/{streamer-hooks.c => streamer-hooks.cc}        |     0
 gcc/streamer-hooks.h                               |     2 +-
 gcc/{stringpool.c => stringpool.cc}                |     0
 gcc/stringpool.h                                   |     2 +-
 ...ubstring-locations.c => substring-locations.cc} |     0
 gcc/symtab.c                                       |  2586 -
 gcc/symtab.cc                                      |  2586 +
 gcc/{target-globals.c => target-globals.cc}        |     0
 gcc/target.def                                     |    24 +-
 gcc/target.h                                       |     6 +-
 gcc/targhooks.c                                    |  2593 -
 gcc/targhooks.cc                                   |  2593 +
 gcc/testsuite/ChangeLog                            |   325 +
 gcc/testsuite/c-c++-common/Wdangling-pointer-2.c   |   437 +
 gcc/testsuite/c-c++-common/Wdangling-pointer-3.c   |    64 +
 gcc/testsuite/c-c++-common/Wdangling-pointer-4.c   |    73 +
 gcc/testsuite/c-c++-common/Wdangling-pointer-5.c   |    90 +
 gcc/testsuite/c-c++-common/Wdangling-pointer-6.c   |    32 +
 gcc/testsuite/c-c++-common/Wdangling-pointer.c     |   434 +
 gcc/testsuite/c-c++-common/Wuse-after-free-2.c     |   169 +
 gcc/testsuite/c-c++-common/Wuse-after-free-3.c     |    83 +
 gcc/testsuite/c-c++-common/Wuse-after-free-4.c     |   102 +
 gcc/testsuite/c-c++-common/Wuse-after-free-5.c     |   103 +
 gcc/testsuite/c-c++-common/Wuse-after-free-6.c     |   105 +
 gcc/testsuite/c-c++-common/Wuse-after-free-7.c     |   103 +
 gcc/testsuite/c-c++-common/Wuse-after-free.c       |   167 +
 gcc/testsuite/c-c++-common/cpp/line-2.c            |     2 +-
 gcc/testsuite/c-c++-common/cpp/line-3.c            |     2 +-
 gcc/testsuite/g++.dg/cpp1y/pr104031.C              |    23 +
 gcc/testsuite/g++.dg/torture/pr57993-2.C           |    22 +-
 ...nit-pred-loop-1_a.cc => uninit-pred-loop-1_a.C} |     0
 gcc/testsuite/g++.dg/uninit-pred-loop-1_b.C        |    21 +
 gcc/testsuite/g++.dg/uninit-pred-loop-1_b.cc       |    21 -
 gcc/testsuite/g++.dg/uninit-pred-loop-1_c.C        |    23 +
 gcc/testsuite/g++.dg/uninit-pred-loop-1_c.cc       |    23 -
 ...{uninit-pred-loop_1.cc => uninit-pred-loop_1.C} |     0
 gcc/testsuite/g++.dg/warn/Wdangling-pointer-2.C    |    23 +
 gcc/testsuite/g++.dg/warn/Wdangling-pointer.C      |    74 +
 gcc/testsuite/g++.dg/warn/Wfree-nonheap-object-6.C |     4 +-
 gcc/testsuite/g++.dg/warn/Wmismatched-dealloc-3.C  |    70 +
 gcc/testsuite/g++.dg/warn/Wuse-after-free.C        |   158 +
 gcc/testsuite/g++.dg/warn/ref-temp1.C              |     3 +
 gcc/testsuite/g++.old-deja/g++.robertl/eb43.C      |     1 +
 gcc/testsuite/g++.target/i386/pr103973-1.C         |    71 +
 gcc/testsuite/g++.target/i386/pr103973-10.C        |     7 +
 gcc/testsuite/g++.target/i386/pr103973-11.C        |     8 +
 gcc/testsuite/g++.target/i386/pr103973-12.C        |     8 +
 gcc/testsuite/g++.target/i386/pr103973-13.C        |    62 +
 gcc/testsuite/g++.target/i386/pr103973-14.C        |     7 +
 gcc/testsuite/g++.target/i386/pr103973-15.C        |     8 +
 gcc/testsuite/g++.target/i386/pr103973-16.C        |     8 +
 gcc/testsuite/g++.target/i386/pr103973-17.C        |     8 +
 gcc/testsuite/g++.target/i386/pr103973-18.C        |     8 +
 gcc/testsuite/g++.target/i386/pr103973-19.C        |     8 +
 gcc/testsuite/g++.target/i386/pr103973-2.C         |     7 +
 gcc/testsuite/g++.target/i386/pr103973-20.C        |     8 +
 gcc/testsuite/g++.target/i386/pr103973-3.C         |     8 +
 gcc/testsuite/g++.target/i386/pr103973-4.C         |     8 +
 gcc/testsuite/g++.target/i386/pr103973-5.C         |    66 +
 gcc/testsuite/g++.target/i386/pr103973-6.C         |     7 +
 gcc/testsuite/g++.target/i386/pr103973-7.C         |     8 +
 gcc/testsuite/g++.target/i386/pr103973-8.C         |     8 +
 gcc/testsuite/g++.target/i386/pr103973-9.C         |    67 +
 gcc/testsuite/gcc.c-torture/compile/pr101941-1.c   |    50 +
 gcc/testsuite/gcc.dg/Wdangling-pointer-2.c         |    82 +
 gcc/testsuite/gcc.dg/Wdangling-pointer.c           |    75 +
 gcc/testsuite/gcc.dg/Wmismatched-dealloc-2.c       |    13 +-
 gcc/testsuite/gcc.dg/Wmismatched-dealloc-3.c       |     5 +
 gcc/testsuite/gcc.dg/analyzer/file-1.c             |     3 +
 gcc/testsuite/gcc.dg/analyzer/file-2.c             |     3 +
 gcc/testsuite/gcc.dg/attr-alloc_size-6.c           |     2 +-
 gcc/testsuite/gcc.dg/attr-alloc_size-7.c           |     2 +-
 gcc/testsuite/gcc.dg/auto-init-uninit-16.c         |     4 +-
 gcc/testsuite/gcc.dg/auto-init-uninit-34.c         |     8 +-
 gcc/testsuite/gcc.dg/auto-init-uninit-37.c         |    44 +-
 gcc/testsuite/gcc.dg/auto-init-uninit-B.c          |     4 +-
 gcc/testsuite/gcc.dg/tree-ssa/pr101941-1.c         |    53 +
 gcc/testsuite/gcc.dg/uninit-pr50476.c              |     2 +-
 gcc/testsuite/gcc.misc-tests/options.exp           |     2 +-
 gcc/testsuite/gcc.src/maintainers.exp              |    24 +-
 gcc/testsuite/gcc.target/aarch64/pr104005.c        |    17 +
 .../gcc.target/i386/avx2-dest-false-dep-for-glc.c  |    24 +
 .../i386/avx512dq-dest-false-dep-for-glc.c         |    73 +
 .../i386/avx512f-dest-false-dep-for-glc.c          |   103 +
 .../i386/avx512fp16-dest-false-dep-for-glc.c       |    45 +
 .../i386/avx512fp16vl-dest-false-dep-for-glc.c     |    24 +
 .../i386/avx512vl-dest-false-dep-for-glc.c         |    76 +
 gcc/testsuite/gcc.target/i386/pr103973-1.c         |    98 +
 gcc/testsuite/gcc.target/i386/pr103973-10.c        |     7 +
 gcc/testsuite/gcc.target/i386/pr103973-11.c        |     8 +
 gcc/testsuite/gcc.target/i386/pr103973-12.c        |     8 +
 gcc/testsuite/gcc.target/i386/pr103973-13.c        |    76 +
 gcc/testsuite/gcc.target/i386/pr103973-14.c        |     7 +
 gcc/testsuite/gcc.target/i386/pr103973-15.c        |     8 +
 gcc/testsuite/gcc.target/i386/pr103973-16.c        |     8 +
 gcc/testsuite/gcc.target/i386/pr103973-17.c        |     8 +
 gcc/testsuite/gcc.target/i386/pr103973-18.c        |     8 +
 gcc/testsuite/gcc.target/i386/pr103973-19.c        |     8 +
 gcc/testsuite/gcc.target/i386/pr103973-2.c         |     7 +
 gcc/testsuite/gcc.target/i386/pr103973-20.c        |     8 +
 gcc/testsuite/gcc.target/i386/pr103973-3.c         |     8 +
 gcc/testsuite/gcc.target/i386/pr103973-4.c         |     8 +
 gcc/testsuite/gcc.target/i386/pr103973-5.c         |    85 +
 gcc/testsuite/gcc.target/i386/pr103973-6.c         |     7 +
 gcc/testsuite/gcc.target/i386/pr103973-7.c         |     8 +
 gcc/testsuite/gcc.target/i386/pr103973-8.c         |     8 +
 gcc/testsuite/gcc.target/i386/pr103973-9.c         |    89 +
 gcc/testsuite/gcc.target/powerpc/pr103124.c        |    12 +
 gcc/testsuite/gfortran.dg/gomp/allocate-2.f90      |     2 +-
 gcc/testsuite/gfortran.dg/gomp/requires-8.f90      |     2 +-
 gcc/testsuite/gfortran.dg/ieee/ieee_10.f90         |    12 +-
 gcc/testsuite/gfortran.dg/ieee/signaling_1.f90     |     6 +-
 gcc/testsuite/gfortran.dg/ieee/signaling_2.f90     |    72 +
 gcc/testsuite/gfortran.dg/ieee/signaling_2_c.c     |     8 +
 gcc/testsuite/gfortran.dg/index_5.f90              |     2 +
 gcc/testsuite/gfortran.dg/len_trim.f90             |     6 +
 gcc/testsuite/gfortran.dg/maskl_1.f90              |     3 +-
 gcc/testsuite/gfortran.dg/maskr_1.f90              |     3 +-
 gcc/testsuite/gfortran.dg/scan_3.f90               |     5 +-
 gcc/testsuite/gfortran.dg/transfer_char_kind4.f90  |   115 +
 gcc/testsuite/gfortran.dg/verify_3.f90             |     5 +-
 gcc/testsuite/lib/gcov.exp                         |     9 +-
 gcc/testsuite/lib/target-supports.exp              |    36 +
 gcc/{timevar.c => timevar.cc}                      |     0
 gcc/timevar.def                                    |     2 +-
 gcc/timevar.h                                      |     2 +-
 gcc/{toplev.c => toplev.cc}                        |     0
 gcc/toplev.h                                       |    10 +-
 gcc/{tracer.c => tracer.cc}                        |     0
 gcc/trans-mem.c                                    |  5683 ---
 gcc/trans-mem.cc                                   |  5683 +++
 gcc/{tree-affine.c => tree-affine.cc}              |     0
 gcc/tree-call-cdce.c                               |  1240 -
 gcc/tree-call-cdce.cc                              |  1240 +
 gcc/tree-cfg.c                                     | 10214 ----
 gcc/tree-cfg.cc                                    | 10239 ++++
 gcc/tree-cfg.h                                     |     1 +
 gcc/{tree-cfgcleanup.c => tree-cfgcleanup.cc}      |     0
 gcc/tree-cfgcleanup.h                              |     2 +-
 gcc/{tree-chrec.c => tree-chrec.cc}                |     0
 gcc/tree-complex.c                                 |  1956 -
 gcc/tree-complex.cc                                |  1956 +
 gcc/tree-core.h                                    |     6 +-
 gcc/{tree-data-ref.c => tree-data-ref.cc}          |     0
 gcc/{tree-dfa.c => tree-dfa.cc}                    |     0
 gcc/{tree-diagnostic.c => tree-diagnostic.cc}      |     0
 gcc/{tree-dump.c => tree-dump.cc}                  |     0
 gcc/tree-eh.c                                      |  5052 --
 gcc/tree-eh.cc                                     |  5052 ++
 gcc/{tree-emutls.c => tree-emutls.cc}              |     0
 gcc/tree-if-conv.c                                 |  3510 --
 gcc/tree-if-conv.cc                                |  3510 ++
 gcc/tree-inline.c                                  |  6634 ---
 gcc/tree-inline.cc                                 |  6634 +++
 gcc/tree-inline.h                                  |     2 +-
 gcc/{tree-into-ssa.c => tree-into-ssa.cc}          |     0
 gcc/{tree-iterator.c => tree-iterator.cc}          |     0
 ...op-distribution.c => tree-loop-distribution.cc} |     0
 gcc/tree-nested.c                                  |  3755 --
 gcc/tree-nested.cc                                 |  3755 ++
 gcc/{tree-nrv.c => tree-nrv.cc}                    |     0
 gcc/{tree-object-size.c => tree-object-size.cc}    |     0
 gcc/tree-object-size.h                             |     2 +-
 gcc/tree-outof-ssa.c                               |  1329 -
 gcc/tree-outof-ssa.cc                              |  1329 +
 gcc/tree-parloops.c                                |  4241 --
 gcc/tree-parloops.cc                               |  4241 ++
 gcc/{tree-phinodes.c => tree-phinodes.cc}          |     0
 gcc/{tree-predcom.c => tree-predcom.cc}            |     0
 gcc/tree-pretty-print.c                            |  4623 --
 gcc/tree-pretty-print.cc                           |  4623 ++
 gcc/tree-profile.c                                 |   911 -
 gcc/tree-profile.cc                                |   911 +
 ...scalar-evolution.c => tree-scalar-evolution.cc} |     0
 gcc/tree-sra.c                                     |  4794 --
 gcc/tree-sra.cc                                    |  4794 ++
 gcc/tree-ssa-address.c                             |  1213 -
 gcc/tree-ssa-address.cc                            |  1213 +
 gcc/tree-ssa-alias.c                               |  4336 --
 gcc/tree-ssa-alias.cc                              |  4336 ++
 gcc/tree-ssa-alias.h                               |     4 +-
 gcc/tree-ssa-ccp.c                                 |  4640 --
 gcc/tree-ssa-ccp.cc                                |  4640 ++
 gcc/{tree-ssa-coalesce.c => tree-ssa-coalesce.cc}  |     0
 gcc/tree-ssa-coalesce.h                            |     2 +-
 gcc/{tree-ssa-copy.c => tree-ssa-copy.cc}          |     0
 gcc/{tree-ssa-dce.c => tree-ssa-dce.cc}            |     0
 gcc/{tree-ssa-dom.c => tree-ssa-dom.cc}            |     0
 gcc/{tree-ssa-dse.c => tree-ssa-dse.cc}            |     0
 gcc/{tree-ssa-forwprop.c => tree-ssa-forwprop.cc}  |     0
 ...{tree-ssa-ifcombine.c => tree-ssa-ifcombine.cc} |     0
 gcc/tree-ssa-live.c                                |  1633 -
 gcc/tree-ssa-live.cc                               |  1633 +
 gcc/{tree-ssa-loop-ch.c => tree-ssa-loop-ch.cc}    |     0
 gcc/{tree-ssa-loop-im.c => tree-ssa-loop-im.cc}    |     0
 ...ssa-loop-ivcanon.c => tree-ssa-loop-ivcanon.cc} |     0
 ...e-ssa-loop-ivopts.c => tree-ssa-loop-ivopts.cc} |     0
 gcc/tree-ssa-loop-manip.c                          |  1677 -
 gcc/tree-ssa-loop-manip.cc                         |  1677 +
 ...ree-ssa-loop-niter.c => tree-ssa-loop-niter.cc} |     0
 ...a-loop-prefetch.c => tree-ssa-loop-prefetch.cc} |     0
 ...ree-ssa-loop-split.c => tree-ssa-loop-split.cc} |     0
 gcc/tree-ssa-loop-unswitch.c                       |  1042 -
 gcc/tree-ssa-loop-unswitch.cc                      |  1042 +
 gcc/{tree-ssa-loop.c => tree-ssa-loop.cc}          |     0
 gcc/tree-ssa-math-opts.c                           |  4847 --
 gcc/tree-ssa-math-opts.cc                          |  5070 ++
 gcc/tree-ssa-operands.c                            |  1415 -
 gcc/tree-ssa-operands.cc                           |  1415 +
 gcc/tree-ssa-phiopt.c                              |  3879 --
 gcc/tree-ssa-phiopt.cc                             |  3854 ++
 gcc/{tree-ssa-phiprop.c => tree-ssa-phiprop.cc}    |     0
 gcc/tree-ssa-pre.c                                 |  4481 --
 gcc/tree-ssa-pre.cc                                |  4481 ++
 ...{tree-ssa-propagate.c => tree-ssa-propagate.cc} |     0
 gcc/tree-ssa-reassoc.c                             |  7052 ---
 gcc/tree-ssa-reassoc.cc                            |  7052 +++
 gcc/tree-ssa-sccvn.c                               |  8250 ----
 gcc/tree-ssa-sccvn.cc                              |  8250 ++++
 gcc/tree-ssa-sccvn.h                               |     2 +-
 gcc/tree-ssa-scopedtables.c                        |  1201 -
 gcc/tree-ssa-scopedtables.cc                       |  1201 +
 gcc/{tree-ssa-sink.c => tree-ssa-sink.cc}          |     0
 gcc/tree-ssa-strlen.c                              |  5970 ---
 gcc/tree-ssa-strlen.cc                             |  5970 +++
 gcc/tree-ssa-strlen.h                              |     2 +-
 ...e-ssa-structalias.c => tree-ssa-structalias.cc} |     0
 gcc/tree-ssa-tail-merge.c                          |  1818 -
 gcc/tree-ssa-tail-merge.cc                         |  1818 +
 gcc/{tree-ssa-ter.c => tree-ssa-ter.cc}            |     0
 gcc/tree-ssa-ter.h                                 |     2 +-
 ...threadbackward.c => tree-ssa-threadbackward.cc} |     0
 ...ree-ssa-threadedge.c => tree-ssa-threadedge.cc} |     0
 ...ssa-threadupdate.c => tree-ssa-threadupdate.cc} |     0
 gcc/tree-ssa-threadupdate.h                        |     2 +-
 gcc/{tree-ssa-uncprop.c => tree-ssa-uncprop.cc}    |     0
 gcc/tree-ssa-uninit.c                              |  1358 -
 gcc/tree-ssa-uninit.cc                             |  1447 +
 gcc/{tree-ssa.c => tree-ssa.cc}                    |     0
 gcc/{tree-ssanames.c => tree-ssanames.cc}          |     0
 gcc/{tree-stdarg.c => tree-stdarg.cc}              |     0
 gcc/tree-streamer-in.c                             |  1130 -
 gcc/tree-streamer-in.cc                            |  1130 +
 gcc/tree-streamer-out.c                            |  1045 -
 gcc/tree-streamer-out.cc                           |  1045 +
 gcc/{tree-streamer.c => tree-streamer.cc}          |     0
 gcc/tree-streamer.h                                |     6 +-
 ...itch-conversion.c => tree-switch-conversion.cc} |     0
 gcc/{tree-tailcall.c => tree-tailcall.cc}          |     0
 gcc/tree-vect-data-refs.c                          |  6814 ---
 gcc/tree-vect-data-refs.cc                         |  6817 +++
 gcc/{tree-vect-generic.c => tree-vect-generic.cc}  |     0
 ...e-vect-loop-manip.c => tree-vect-loop-manip.cc} |     0
 gcc/{tree-vect-loop.c => tree-vect-loop.cc}        |     0
 gcc/tree-vect-patterns.c                           |  5856 ---
 gcc/tree-vect-patterns.cc                          |  5856 +++
 ...ct-slp-patterns.c => tree-vect-slp-patterns.cc} |     0
 gcc/{tree-vect-slp.c => tree-vect-slp.cc}          |     0
 gcc/tree-vect-stmts.c                              | 12484 -----
 gcc/tree-vect-stmts.cc                             | 12484 +++++
 ...ree-vector-builder.c => tree-vector-builder.cc} |     0
 gcc/tree-vectorizer.c                              |  2026 -
 gcc/tree-vectorizer.cc                             |  2026 +
 gcc/tree-vectorizer.h                              |    20 +-
 gcc/{tree-vrp.c => tree-vrp.cc}                    |     0
 gcc/tree.c                                         | 15221 ------
 gcc/tree.cc                                        | 15221 ++++++
 gcc/tree.def                                       |     2 +-
 gcc/tree.h                                         |    10 +-
 gcc/{tsan.c => tsan.cc}                            |     0
 gcc/{typed-splay-tree.c => typed-splay-tree.cc}    |     0
 gcc/{ubsan.c => ubsan.cc}                          |     0
 gcc/{valtrack.c => valtrack.cc}                    |     0
 gcc/value-prof.c                                   |  1966 -
 gcc/value-prof.cc                                  |  1966 +
 gcc/value-prof.h                                   |     4 +-
 gcc/value-range.cc                                 |     2 +-
 gcc/value-range.h                                  |     2 +-
 gcc/var-tracking.c                                 | 10613 ----
 gcc/var-tracking.cc                                | 10613 ++++
 gcc/varasm.c                                       |  8509 ----
 gcc/varasm.cc                                      |  8509 ++++
 gcc/{varpool.c => varpool.cc}                      |     0
 gcc/{vec-perm-indices.c => vec-perm-indices.cc}    |     0
 gcc/{vec.c => vec.cc}                              |     0
 gcc/vec.h                                          |     2 +-
 gcc/vmsdbgout.c                                    |  1851 -
 gcc/vmsdbgout.cc                                   |  1851 +
 gcc/{vr-values.c => vr-values.cc}                  |     0
 gcc/vtable-verify.c                                |   850 -
 gcc/vtable-verify.cc                               |   850 +
 gcc/vtable-verify.h                                |     2 +-
 gcc/warning-control.cc                             |     3 +-
 gcc/{web.c => web.cc}                              |     0
 gcc/xcoffout.c                                     |   494 -
 gcc/xcoffout.cc                                    |   494 +
 gcc/xcoffout.h                                     |     8 +-
 libcpp/ChangeLog                                   |    80 +
 libcpp/Makefile.in                                 |    10 +-
 libcpp/charset.c                                   |  2510 -
 libcpp/charset.cc                                  |  2510 +
 libcpp/directives.c                                |  2799 --
 libcpp/directives.cc                               |  2799 ++
 libcpp/{errors.c => errors.cc}                     |     0
 libcpp/{expr.c => expr.cc}                         |     0
 libcpp/files.c                                     |  2175 -
 libcpp/files.cc                                    |  2174 +
 libcpp/{identifiers.c => identifiers.cc}           |     0
 libcpp/include/cpplib.h                            |    22 +-
 libcpp/include/line-map.h                          |     6 +-
 libcpp/include/mkdeps.h                            |     2 +-
 libcpp/init.c                                      |   914 -
 libcpp/init.cc                                     |   914 +
 libcpp/internal.h                                  |    32 +-
 libcpp/{lex.c => lex.cc}                           |     0
 libcpp/line-map.c                                  |  2555 -
 libcpp/line-map.cc                                 |  2555 +
 libcpp/{macro.c => macro.cc}                       |     0
 libcpp/{makeucnid.c => makeucnid.cc}               |     0
 libcpp/{mkdeps.c => mkdeps.cc}                     |     0
 libcpp/{pch.c => pch.cc}                           |     0
 libcpp/{symtab.c => symtab.cc}                     |     0
 libcpp/traditional.c                               |  1321 -
 libcpp/traditional.cc                              |  1321 +
 libgcc/ChangeLog                                   |    16 +
 libgcc/config/i386/gthr-win32.c                    |     2 -
 libgcc/config/i386/gthr-win32.h                    |    23 +-
 libgcc/libgcov-driver.c                            |     2 +-
 libgfortran/ChangeLog                              |    30 +
 libgfortran/ieee/ieee_arithmetic.F90               |   284 +-
 libgfortran/ieee/ieee_helper.c                     |    74 +
 libgfortran/mk-kinds-h.sh                          |     7 +
 libgfortran/runtime/environ.c                      |   111 +-
 libgomp/ChangeLog                                  |    21 +
 libgomp/plugin/plugin-gcn.c                        |    82 +-
 .../testsuite/libgomp.oacc-c++/privatized-ref-2.C  |   178 +
 .../testsuite/libgomp.oacc-c++/privatized-ref-3.C  |   212 +
 .../libgomp.oacc-fortran/privatized-ref-1.f95      |   163 +
 libiberty/ChangeLog                                |     4 +
 libiberty/regex.c                                  |     4 +
 libstdc++-v3/ChangeLog                             |   397 +
 libstdc++-v3/Makefile.in                           |     7 +
 libstdc++-v3/acinclude.m4                          |   155 +-
 libstdc++-v3/config.h.in                           |    10 +
 libstdc++-v3/configure                             |   321 +-
 libstdc++-v3/configure.ac                          |     3 +
 libstdc++-v3/doc/Makefile.in                       |     7 +
 libstdc++-v3/doc/html/manual/status.html           |    36 +-
 libstdc++-v3/doc/xml/manual/status_cxx2017.xml     |     8 +-
 libstdc++-v3/doc/xml/manual/status_cxx2020.xml     |    24 +-
 libstdc++-v3/include/Makefile.am                   |     3 +
 libstdc++-v3/include/Makefile.in                   |    10 +
 libstdc++-v3/include/bits/shared_ptr_atomic.h      |   455 +
 libstdc++-v3/include/bits/shared_ptr_base.h        |    17 +
 libstdc++-v3/include/experimental/bits/simd.h      |   389 +-
 .../include/experimental/bits/simd_builtin.h       |    41 +-
 .../include/experimental/bits/simd_detail.h        |    40 +
 .../include/experimental/bits/simd_fixed_size.h    |    39 +-
 libstdc++-v3/include/experimental/bits/simd_math.h |    45 +-
 libstdc++-v3/include/experimental/bits/simd_neon.h |     4 +-
 libstdc++-v3/include/experimental/bits/simd_ppc.h  |     4 +-
 .../include/experimental/bits/simd_scalar.h        |    71 +-
 libstdc++-v3/include/experimental/bits/simd_x86.h  |     4 +-
 libstdc++-v3/include/std/stacktrace                |   672 +
 libstdc++-v3/include/std/version                   |     4 +
 libstdc++-v3/libsupc++/Makefile.in                 |     7 +
 libstdc++-v3/po/Makefile.in                        |     7 +
 libstdc++-v3/python/Makefile.in                    |     7 +
 libstdc++-v3/src/Makefile.am                       |    11 +-
 libstdc++-v3/src/Makefile.in                       |    14 +-
 libstdc++-v3/src/c++11/Makefile.in                 |     7 +
 libstdc++-v3/src/c++17/Makefile.in                 |     7 +
 libstdc++-v3/src/c++17/fast_float/LOCAL_PATCHES    |     4 +
 libstdc++-v3/src/c++17/fast_float/MERGE            |     4 +
 libstdc++-v3/src/c++17/fast_float/README.md        |   218 +
 libstdc++-v3/src/c++17/fast_float/fast_float.h     |  2905 ++
 libstdc++-v3/src/c++17/floating_from_chars.cc      |   397 +
 libstdc++-v3/src/c++20/Makefile.in                 |     7 +
 libstdc++-v3/src/c++98/Makefile.in                 |     7 +
 libstdc++-v3/src/filesystem/Makefile.in            |     7 +
 libstdc++-v3/src/libbacktrace/Makefile.am          |   101 +
 libstdc++-v3/src/libbacktrace/Makefile.in          |   860 +
 libstdc++-v3/src/libbacktrace/backtrace-rename.h   |    41 +
 .../src/libbacktrace/backtrace-supported.h.in      |    61 +
 libstdc++-v3/src/libbacktrace/config.h.in          |   184 +
 .../testsuite/17_intro/headers/c++1998/103650.cc   |    13 +
 libstdc++-v3/testsuite/20_util/from_chars/7.cc     |   152 +
 .../20_util/shared_ptr/atomic/atomic_shared_ptr.cc |   150 +
 libstdc++-v3/testsuite/20_util/stacktrace/entry.cc |    53 +
 .../testsuite/20_util/stacktrace/synopsis.cc       |    46 +
 .../testsuite/20_util/stacktrace/version.cc        |    11 +
 .../testsuite/20_util/weak_ptr/atomic_weak_ptr.cc  |    95 +
 libstdc++-v3/testsuite/Makefile.in                 |     7 +
 libstdc++-v3/testsuite/lib/libstdc++.exp           |     8 +
 1867 files changed, 1663961 insertions(+), 1645562 deletions(-)

diff --cc gcc/config/ia64/ia64.cc
index 00000000000,f9fb681a36c..c68b2ff69bd
mode 000000,100644..100644
--- a/gcc/config/ia64/ia64.cc
+++ b/gcc/config/ia64/ia64.cc
@@@ -1,0 -1,11923 +1,11927 @@@
+ /* Definitions of target machine for GNU compiler.
+    Copyright (C) 1999-2022 Free Software Foundation, Inc.
+    Contributed by James E. Wilson <wilson@cygnus.com> and
+ 		  David Mosberger <davidm@hpl.hp.com>.
+ 
+ This file is part of GCC.
+ 
+ GCC is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 3, or (at your option)
+ any later version.
+ 
+ GCC is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ GNU General Public License for more details.
+ 
+ You should have received a copy of the GNU General Public License
+ along with GCC; see the file COPYING3.  If not see
+ <http://www.gnu.org/licenses/>.  */
+ 
+ #define IN_TARGET_CODE 1
+ 
+ #include "config.h"
+ #include "system.h"
+ #include "coretypes.h"
+ #include "backend.h"
+ #include "target.h"
+ #include "rtl.h"
+ #include "tree.h"
+ #include "memmodel.h"
+ #include "cfghooks.h"
+ #include "df.h"
+ #include "tm_p.h"
+ #include "stringpool.h"
+ #include "attribs.h"
+ #include "optabs.h"
+ #include "regs.h"
+ #include "emit-rtl.h"
+ #include "recog.h"
+ #include "diagnostic-core.h"
+ #include "alias.h"
+ #include "fold-const.h"
+ #include "stor-layout.h"
+ #include "calls.h"
+ #include "varasm.h"
+ #include "output.h"
+ #include "insn-attr.h"
+ #include "flags.h"
+ #include "explow.h"
+ #include "expr.h"
+ #include "cfgrtl.h"
+ #include "libfuncs.h"
+ #include "sched-int.h"
+ #include "common/common-target.h"
+ #include "langhooks.h"
+ #include "gimplify.h"
+ #include "intl.h"
+ #include "debug.h"
+ #include "dbgcnt.h"
+ #include "tm-constrs.h"
+ #include "sel-sched.h"
+ #include "reload.h"
+ #include "opts.h"
+ #include "dumpfile.h"
+ #include "builtins.h"
+ 
+ /* This file should be included last.  */
+ #include "target-def.h"
+ 
+ /* This is used for communication between ASM_OUTPUT_LABEL and
+    ASM_OUTPUT_LABELREF.  */
+ int ia64_asm_output_label = 0;
+ 
+ /* Register names for ia64_expand_prologue.  */
+ static const char * const ia64_reg_numbers[96] =
+ { "r32", "r33", "r34", "r35", "r36", "r37", "r38", "r39",
+   "r40", "r41", "r42", "r43", "r44", "r45", "r46", "r47",
+   "r48", "r49", "r50", "r51", "r52", "r53", "r54", "r55",
+   "r56", "r57", "r58", "r59", "r60", "r61", "r62", "r63",
+   "r64", "r65", "r66", "r67", "r68", "r69", "r70", "r71",
+   "r72", "r73", "r74", "r75", "r76", "r77", "r78", "r79",
+   "r80", "r81", "r82", "r83", "r84", "r85", "r86", "r87",
+   "r88", "r89", "r90", "r91", "r92", "r93", "r94", "r95",
+   "r96", "r97", "r98", "r99", "r100","r101","r102","r103",
+   "r104","r105","r106","r107","r108","r109","r110","r111",
+   "r112","r113","r114","r115","r116","r117","r118","r119",
+   "r120","r121","r122","r123","r124","r125","r126","r127"};
+ 
+ /* ??? These strings could be shared with REGISTER_NAMES.  */
+ static const char * const ia64_input_reg_names[8] =
+ { "in0",  "in1",  "in2",  "in3",  "in4",  "in5",  "in6",  "in7" };
+ 
+ /* ??? These strings could be shared with REGISTER_NAMES.  */
+ static const char * const ia64_local_reg_names[80] =
+ { "loc0", "loc1", "loc2", "loc3", "loc4", "loc5", "loc6", "loc7",
+   "loc8", "loc9", "loc10","loc11","loc12","loc13","loc14","loc15",
+   "loc16","loc17","loc18","loc19","loc20","loc21","loc22","loc23",
+   "loc24","loc25","loc26","loc27","loc28","loc29","loc30","loc31",
+   "loc32","loc33","loc34","loc35","loc36","loc37","loc38","loc39",
+   "loc40","loc41","loc42","loc43","loc44","loc45","loc46","loc47",
+   "loc48","loc49","loc50","loc51","loc52","loc53","loc54","loc55",
+   "loc56","loc57","loc58","loc59","loc60","loc61","loc62","loc63",
+   "loc64","loc65","loc66","loc67","loc68","loc69","loc70","loc71",
+   "loc72","loc73","loc74","loc75","loc76","loc77","loc78","loc79" };
+ 
+ /* ??? These strings could be shared with REGISTER_NAMES.  */
+ static const char * const ia64_output_reg_names[8] =
+ { "out0", "out1", "out2", "out3", "out4", "out5", "out6", "out7" };
+ 
+ /* Variables which are this size or smaller are put in the sdata/sbss
+    sections.  */
+ 
+ unsigned int ia64_section_threshold;
+ 
+ /* The following variable is used by the DFA insn scheduler.  The value is
+    TRUE if we do insn bundling instead of insn scheduling.  */
+ int bundling_p = 0;
+ 
+ enum ia64_frame_regs
+ {
+    reg_fp,
+    reg_save_b0,
+    reg_save_pr,
+    reg_save_ar_pfs,
+    reg_save_ar_unat,
+    reg_save_ar_lc,
+    reg_save_gp,
+    number_of_ia64_frame_regs
+ };
+ 
+ /* Structure to be filled in by ia64_compute_frame_size with register
+    save masks and offsets for the current function.  */
+ 
+ struct ia64_frame_info
+ {
+   HOST_WIDE_INT total_size;	/* size of the stack frame, not including
+ 				   the caller's scratch area.  */
+   HOST_WIDE_INT spill_cfa_off;	/* top of the reg spill area from the cfa.  */
+   HOST_WIDE_INT spill_size;	/* size of the gr/br/fr spill area.  */
+   HOST_WIDE_INT extra_spill_size;  /* size of spill area for others.  */
+   HARD_REG_SET mask;		/* mask of saved registers.  */
+   unsigned int gr_used_mask;	/* mask of registers in use as gr spill
+ 				   registers or long-term scratches.  */
+   int n_spilled;		/* number of spilled registers.  */
+   int r[number_of_ia64_frame_regs];  /* Frame related registers.  */
+   int n_input_regs;		/* number of input registers used.  */
+   int n_local_regs;		/* number of local registers used.  */
+   int n_output_regs;		/* number of output registers used.  */
+   int n_rotate_regs;		/* number of rotating registers used.  */
+ 
+   char need_regstk;		/* true if a .regstk directive needed.  */
+   char initialized;		/* true if the data is finalized.  */
+ };
+ 
+ /* Current frame information calculated by ia64_compute_frame_size.  */
+ static struct ia64_frame_info current_frame_info;
+ /* The actual registers that are emitted.  */
+ static int emitted_frame_related_regs[number_of_ia64_frame_regs];
+ \f
+ static int ia64_first_cycle_multipass_dfa_lookahead (void);
+ static void ia64_dependencies_evaluation_hook (rtx_insn *, rtx_insn *);
+ static void ia64_init_dfa_pre_cycle_insn (void);
+ static rtx ia64_dfa_pre_cycle_insn (void);
+ static int ia64_first_cycle_multipass_dfa_lookahead_guard (rtx_insn *, int);
+ static int ia64_dfa_new_cycle (FILE *, int, rtx_insn *, int, int, int *);
+ static void ia64_h_i_d_extended (void);
+ static void * ia64_alloc_sched_context (void);
+ static void ia64_init_sched_context (void *, bool);
+ static void ia64_set_sched_context (void *);
+ static void ia64_clear_sched_context (void *);
+ static void ia64_free_sched_context (void *);
+ static int ia64_mode_to_int (machine_mode);
+ static void ia64_set_sched_flags (spec_info_t);
+ static ds_t ia64_get_insn_spec_ds (rtx_insn *);
+ static ds_t ia64_get_insn_checked_ds (rtx_insn *);
+ static bool ia64_skip_rtx_p (const_rtx);
+ static int ia64_speculate_insn (rtx_insn *, ds_t, rtx *);
+ static bool ia64_needs_block_p (ds_t);
+ static rtx ia64_gen_spec_check (rtx_insn *, rtx_insn *, ds_t);
+ static int ia64_spec_check_p (rtx);
+ static int ia64_spec_check_src_p (rtx);
+ static rtx gen_tls_get_addr (void);
+ static rtx gen_thread_pointer (void);
+ static int find_gr_spill (enum ia64_frame_regs, int);
+ static int next_scratch_gr_reg (void);
+ static void mark_reg_gr_used_mask (rtx, void *);
+ static void ia64_compute_frame_size (HOST_WIDE_INT);
+ static void setup_spill_pointers (int, rtx, HOST_WIDE_INT);
+ static void finish_spill_pointers (void);
+ static rtx spill_restore_mem (rtx, HOST_WIDE_INT);
+ static void do_spill (rtx (*)(rtx, rtx, rtx), rtx, HOST_WIDE_INT, rtx);
+ static void do_restore (rtx (*)(rtx, rtx, rtx), rtx, HOST_WIDE_INT);
+ static rtx gen_movdi_x (rtx, rtx, rtx);
+ static rtx gen_fr_spill_x (rtx, rtx, rtx);
+ static rtx gen_fr_restore_x (rtx, rtx, rtx);
+ 
+ static void ia64_option_override (void);
+ static bool ia64_can_eliminate (const int, const int);
+ static machine_mode hfa_element_mode (const_tree, bool);
+ static void ia64_setup_incoming_varargs (cumulative_args_t,
+ 					 const function_arg_info &,
+ 					 int *, int);
+ static int ia64_arg_partial_bytes (cumulative_args_t,
+ 				   const function_arg_info &);
+ static rtx ia64_function_arg (cumulative_args_t, const function_arg_info &);
+ static rtx ia64_function_incoming_arg (cumulative_args_t,
+ 				       const function_arg_info &);
+ static void ia64_function_arg_advance (cumulative_args_t,
+ 				       const function_arg_info &);
+ static pad_direction ia64_function_arg_padding (machine_mode, const_tree);
+ static unsigned int ia64_function_arg_boundary (machine_mode,
+ 						const_tree);
+ static bool ia64_function_ok_for_sibcall (tree, tree);
+ static bool ia64_return_in_memory (const_tree, const_tree);
+ static rtx ia64_function_value (const_tree, const_tree, bool);
+ static rtx ia64_libcall_value (machine_mode, const_rtx);
+ static bool ia64_function_value_regno_p (const unsigned int);
+ static int ia64_register_move_cost (machine_mode, reg_class_t,
+                                     reg_class_t);
+ static int ia64_memory_move_cost (machine_mode mode, reg_class_t,
+ 				  bool);
+ static bool ia64_rtx_costs (rtx, machine_mode, int, int, int *, bool);
+ static int ia64_unspec_may_trap_p (const_rtx, unsigned);
+ static void fix_range (const char *);
+ static struct machine_function * ia64_init_machine_status (void);
+ static void emit_insn_group_barriers (FILE *);
+ static void emit_all_insn_group_barriers (FILE *);
+ static void final_emit_insn_group_barriers (FILE *);
+ static void emit_predicate_relation_info (void);
+ static void ia64_reorg (void);
+ static bool ia64_in_small_data_p (const_tree);
+ static void process_epilogue (FILE *, rtx, bool, bool);
+ 
+ static bool ia64_assemble_integer (rtx, unsigned int, int);
+ static void ia64_output_function_prologue (FILE *);
+ static void ia64_output_function_epilogue (FILE *);
+ static void ia64_output_function_end_prologue (FILE *);
+ 
+ static void ia64_print_operand (FILE *, rtx, int);
+ static void ia64_print_operand_address (FILE *, machine_mode, rtx);
+ static bool ia64_print_operand_punct_valid_p (unsigned char code);
+ 
+ static int ia64_issue_rate (void);
+ static int ia64_adjust_cost (rtx_insn *, int, rtx_insn *, int, dw_t);
+ static void ia64_sched_init (FILE *, int, int);
+ static void ia64_sched_init_global (FILE *, int, int);
+ static void ia64_sched_finish_global (FILE *, int);
+ static void ia64_sched_finish (FILE *, int);
+ static int ia64_dfa_sched_reorder (FILE *, int, rtx_insn **, int *, int, int);
+ static int ia64_sched_reorder (FILE *, int, rtx_insn **, int *, int);
+ static int ia64_sched_reorder2 (FILE *, int, rtx_insn **, int *, int);
+ static int ia64_variable_issue (FILE *, int, rtx_insn *, int);
+ 
+ static void ia64_asm_unwind_emit (FILE *, rtx_insn *);
+ static void ia64_asm_emit_except_personality (rtx);
+ static void ia64_asm_init_sections (void);
+ 
+ static enum unwind_info_type ia64_debug_unwind_info (void);
+ 
+ static struct bundle_state *get_free_bundle_state (void);
+ static void free_bundle_state (struct bundle_state *);
+ static void initiate_bundle_states (void);
+ static void finish_bundle_states (void);
+ static int insert_bundle_state (struct bundle_state *);
+ static void initiate_bundle_state_table (void);
+ static void finish_bundle_state_table (void);
+ static int try_issue_nops (struct bundle_state *, int);
+ static int try_issue_insn (struct bundle_state *, rtx);
+ static void issue_nops_and_insn (struct bundle_state *, int, rtx_insn *,
+ 				 int, int);
+ static int get_max_pos (state_t);
+ static int get_template (state_t, int);
+ 
+ static rtx_insn *get_next_important_insn (rtx_insn *, rtx_insn *);
+ static bool important_for_bundling_p (rtx_insn *);
+ static bool unknown_for_bundling_p (rtx_insn *);
+ static void bundling (FILE *, int, rtx_insn *, rtx_insn *);
+ 
+ static void ia64_output_mi_thunk (FILE *, tree, HOST_WIDE_INT,
+ 				  HOST_WIDE_INT, tree);
+ static void ia64_file_start (void);
+ static void ia64_globalize_decl_name (FILE *, tree);
+ 
+ static int ia64_hpux_reloc_rw_mask (void) ATTRIBUTE_UNUSED;
+ static int ia64_reloc_rw_mask (void) ATTRIBUTE_UNUSED;
+ static section *ia64_select_rtx_section (machine_mode, rtx,
+ 					 unsigned HOST_WIDE_INT);
+ static void ia64_output_dwarf_dtprel (FILE *, int, rtx)
+      ATTRIBUTE_UNUSED;
+ static unsigned int ia64_section_type_flags (tree, const char *, int);
++static void ia64_linux_file_end (void)
++     ATTRIBUTE_UNUSED;
+ static void ia64_init_libfuncs (void)
+      ATTRIBUTE_UNUSED;
+ static void ia64_hpux_init_libfuncs (void)
+      ATTRIBUTE_UNUSED;
+ static void ia64_sysv4_init_libfuncs (void)
+      ATTRIBUTE_UNUSED;
+ static void ia64_vms_init_libfuncs (void)
+      ATTRIBUTE_UNUSED;
+ static void ia64_soft_fp_init_libfuncs (void)
+      ATTRIBUTE_UNUSED;
+ static bool ia64_vms_valid_pointer_mode (scalar_int_mode mode)
+      ATTRIBUTE_UNUSED;
+ static tree ia64_vms_common_object_attribute (tree *, tree, tree, int, bool *)
+      ATTRIBUTE_UNUSED;
+ 
+ static bool ia64_attribute_takes_identifier_p (const_tree);
+ static tree ia64_handle_model_attribute (tree *, tree, tree, int, bool *);
+ static tree ia64_handle_version_id_attribute (tree *, tree, tree, int, bool *);
+ static void ia64_encode_section_info (tree, rtx, int);
+ static rtx ia64_struct_value_rtx (tree, int);
+ static tree ia64_gimplify_va_arg (tree, tree, gimple_seq *, gimple_seq *);
+ static bool ia64_scalar_mode_supported_p (scalar_mode mode);
+ static bool ia64_vector_mode_supported_p (machine_mode mode);
+ static bool ia64_legitimate_constant_p (machine_mode, rtx);
+ static bool ia64_legitimate_address_p (machine_mode, rtx, bool);
+ static bool ia64_cannot_force_const_mem (machine_mode, rtx);
+ static const char *ia64_mangle_type (const_tree);
+ static const char *ia64_invalid_conversion (const_tree, const_tree);
+ static const char *ia64_invalid_unary_op (int, const_tree);
+ static const char *ia64_invalid_binary_op (int, const_tree, const_tree);
+ static machine_mode ia64_c_mode_for_suffix (char);
+ static void ia64_trampoline_init (rtx, tree, rtx);
+ static void ia64_override_options_after_change (void);
+ static bool ia64_member_type_forces_blk (const_tree, machine_mode);
+ 
+ static tree ia64_fold_builtin (tree, int, tree *, bool);
+ static tree ia64_builtin_decl (unsigned, bool);
+ 
+ static reg_class_t ia64_preferred_reload_class (rtx, reg_class_t);
+ static fixed_size_mode ia64_get_reg_raw_mode (int regno);
+ static section * ia64_hpux_function_section (tree, enum node_frequency,
+ 					     bool, bool);
+ 
+ static bool ia64_vectorize_vec_perm_const (machine_mode, rtx, rtx, rtx,
+ 					   const vec_perm_indices &);
+ 
+ static unsigned int ia64_hard_regno_nregs (unsigned int, machine_mode);
+ static bool ia64_hard_regno_mode_ok (unsigned int, machine_mode);
+ static bool ia64_modes_tieable_p (machine_mode, machine_mode);
+ static bool ia64_can_change_mode_class (machine_mode, machine_mode,
+ 					reg_class_t);
+ 
+ #define MAX_VECT_LEN	8
+ 
+ struct expand_vec_perm_d
+ {
+   rtx target, op0, op1;
+   unsigned char perm[MAX_VECT_LEN];
+   machine_mode vmode;
+   unsigned char nelt;
+   bool one_operand_p;
+   bool testing_p; 
+ };
+ 
+ static bool ia64_expand_vec_perm_const_1 (struct expand_vec_perm_d *d);
+ 
+ \f
+ /* Table of valid machine attributes.  */
+ static const struct attribute_spec ia64_attribute_table[] =
+ {
+   /* { name, min_len, max_len, decl_req, type_req, fn_type_req,
+        affects_type_identity, handler, exclude } */
+   { "syscall_linkage", 0, 0, false, true,  true,  false, NULL, NULL },
+   { "model",	       1, 1, true, false, false,  false,
+     ia64_handle_model_attribute, NULL },
+ #if TARGET_ABI_OPEN_VMS
+   { "common_object",   1, 1, true, false, false, false,
+     ia64_vms_common_object_attribute, NULL },
+ #endif
+   { "version_id",      1, 1, true, false, false, false,
+     ia64_handle_version_id_attribute, NULL },
+   { NULL,	       0, 0, false, false, false, false, NULL, NULL }
+ };
+ 
+ /* Initialize the GCC target structure.  */
+ #undef TARGET_ATTRIBUTE_TABLE
+ #define TARGET_ATTRIBUTE_TABLE ia64_attribute_table
+ 
+ #undef TARGET_INIT_BUILTINS
+ #define TARGET_INIT_BUILTINS ia64_init_builtins
+ 
+ #undef TARGET_FOLD_BUILTIN
+ #define TARGET_FOLD_BUILTIN ia64_fold_builtin
+ 
+ #undef TARGET_EXPAND_BUILTIN
+ #define TARGET_EXPAND_BUILTIN ia64_expand_builtin
+ 
+ #undef TARGET_BUILTIN_DECL
+ #define TARGET_BUILTIN_DECL ia64_builtin_decl
+ 
+ #undef TARGET_ASM_BYTE_OP
+ #define TARGET_ASM_BYTE_OP "\tdata1\t"
+ #undef TARGET_ASM_ALIGNED_HI_OP
+ #define TARGET_ASM_ALIGNED_HI_OP "\tdata2\t"
+ #undef TARGET_ASM_ALIGNED_SI_OP
+ #define TARGET_ASM_ALIGNED_SI_OP "\tdata4\t"
+ #undef TARGET_ASM_ALIGNED_DI_OP
+ #define TARGET_ASM_ALIGNED_DI_OP "\tdata8\t"
+ #undef TARGET_ASM_UNALIGNED_HI_OP
+ #define TARGET_ASM_UNALIGNED_HI_OP "\tdata2.ua\t"
+ #undef TARGET_ASM_UNALIGNED_SI_OP
+ #define TARGET_ASM_UNALIGNED_SI_OP "\tdata4.ua\t"
+ #undef TARGET_ASM_UNALIGNED_DI_OP
+ #define TARGET_ASM_UNALIGNED_DI_OP "\tdata8.ua\t"
+ #undef TARGET_ASM_INTEGER
+ #define TARGET_ASM_INTEGER ia64_assemble_integer
+ 
+ #undef TARGET_OPTION_OVERRIDE
+ #define TARGET_OPTION_OVERRIDE ia64_option_override
+ 
+ #undef TARGET_ASM_FUNCTION_PROLOGUE
+ #define TARGET_ASM_FUNCTION_PROLOGUE ia64_output_function_prologue
+ #undef TARGET_ASM_FUNCTION_END_PROLOGUE
+ #define TARGET_ASM_FUNCTION_END_PROLOGUE ia64_output_function_end_prologue
+ #undef TARGET_ASM_FUNCTION_EPILOGUE
+ #define TARGET_ASM_FUNCTION_EPILOGUE ia64_output_function_epilogue
+ 
+ #undef TARGET_PRINT_OPERAND
+ #define TARGET_PRINT_OPERAND ia64_print_operand
+ #undef TARGET_PRINT_OPERAND_ADDRESS
+ #define TARGET_PRINT_OPERAND_ADDRESS ia64_print_operand_address
+ #undef TARGET_PRINT_OPERAND_PUNCT_VALID_P
+ #define TARGET_PRINT_OPERAND_PUNCT_VALID_P ia64_print_operand_punct_valid_p
+ 
+ #undef TARGET_IN_SMALL_DATA_P
+ #define TARGET_IN_SMALL_DATA_P  ia64_in_small_data_p
+ 
+ #undef TARGET_SCHED_ADJUST_COST
+ #define TARGET_SCHED_ADJUST_COST ia64_adjust_cost
+ #undef TARGET_SCHED_ISSUE_RATE
+ #define TARGET_SCHED_ISSUE_RATE ia64_issue_rate
+ #undef TARGET_SCHED_VARIABLE_ISSUE
+ #define TARGET_SCHED_VARIABLE_ISSUE ia64_variable_issue
+ #undef TARGET_SCHED_INIT
+ #define TARGET_SCHED_INIT ia64_sched_init
+ #undef TARGET_SCHED_FINISH
+ #define TARGET_SCHED_FINISH ia64_sched_finish
+ #undef TARGET_SCHED_INIT_GLOBAL
+ #define TARGET_SCHED_INIT_GLOBAL ia64_sched_init_global
+ #undef TARGET_SCHED_FINISH_GLOBAL
+ #define TARGET_SCHED_FINISH_GLOBAL ia64_sched_finish_global
+ #undef TARGET_SCHED_REORDER
+ #define TARGET_SCHED_REORDER ia64_sched_reorder
+ #undef TARGET_SCHED_REORDER2
+ #define TARGET_SCHED_REORDER2 ia64_sched_reorder2
+ 
+ #undef TARGET_SCHED_DEPENDENCIES_EVALUATION_HOOK
+ #define TARGET_SCHED_DEPENDENCIES_EVALUATION_HOOK ia64_dependencies_evaluation_hook
+ 
+ #undef TARGET_SCHED_FIRST_CYCLE_MULTIPASS_DFA_LOOKAHEAD
+ #define TARGET_SCHED_FIRST_CYCLE_MULTIPASS_DFA_LOOKAHEAD ia64_first_cycle_multipass_dfa_lookahead
+ 
+ #undef TARGET_SCHED_INIT_DFA_PRE_CYCLE_INSN
+ #define TARGET_SCHED_INIT_DFA_PRE_CYCLE_INSN ia64_init_dfa_pre_cycle_insn
+ #undef TARGET_SCHED_DFA_PRE_CYCLE_INSN
+ #define TARGET_SCHED_DFA_PRE_CYCLE_INSN ia64_dfa_pre_cycle_insn
+ 
+ #undef TARGET_SCHED_FIRST_CYCLE_MULTIPASS_DFA_LOOKAHEAD_GUARD
+ #define TARGET_SCHED_FIRST_CYCLE_MULTIPASS_DFA_LOOKAHEAD_GUARD\
+   ia64_first_cycle_multipass_dfa_lookahead_guard
+ 
+ #undef TARGET_SCHED_DFA_NEW_CYCLE
+ #define TARGET_SCHED_DFA_NEW_CYCLE ia64_dfa_new_cycle
+ 
+ #undef TARGET_SCHED_H_I_D_EXTENDED
+ #define TARGET_SCHED_H_I_D_EXTENDED ia64_h_i_d_extended
+ 
+ #undef TARGET_SCHED_ALLOC_SCHED_CONTEXT
+ #define TARGET_SCHED_ALLOC_SCHED_CONTEXT ia64_alloc_sched_context
+ 
+ #undef TARGET_SCHED_INIT_SCHED_CONTEXT
+ #define TARGET_SCHED_INIT_SCHED_CONTEXT ia64_init_sched_context
+ 
+ #undef TARGET_SCHED_SET_SCHED_CONTEXT
+ #define TARGET_SCHED_SET_SCHED_CONTEXT ia64_set_sched_context
+ 
+ #undef TARGET_SCHED_CLEAR_SCHED_CONTEXT
+ #define TARGET_SCHED_CLEAR_SCHED_CONTEXT ia64_clear_sched_context
+ 
+ #undef TARGET_SCHED_FREE_SCHED_CONTEXT
+ #define TARGET_SCHED_FREE_SCHED_CONTEXT ia64_free_sched_context
+ 
+ #undef TARGET_SCHED_SET_SCHED_FLAGS
+ #define TARGET_SCHED_SET_SCHED_FLAGS ia64_set_sched_flags
+ 
+ #undef TARGET_SCHED_GET_INSN_SPEC_DS
+ #define TARGET_SCHED_GET_INSN_SPEC_DS ia64_get_insn_spec_ds
+ 
+ #undef TARGET_SCHED_GET_INSN_CHECKED_DS
+ #define TARGET_SCHED_GET_INSN_CHECKED_DS ia64_get_insn_checked_ds
+ 
+ #undef TARGET_SCHED_SPECULATE_INSN
+ #define TARGET_SCHED_SPECULATE_INSN ia64_speculate_insn
+ 
+ #undef TARGET_SCHED_NEEDS_BLOCK_P
+ #define TARGET_SCHED_NEEDS_BLOCK_P ia64_needs_block_p
+ 
+ #undef TARGET_SCHED_GEN_SPEC_CHECK
+ #define TARGET_SCHED_GEN_SPEC_CHECK ia64_gen_spec_check
+ 
+ #undef TARGET_SCHED_SKIP_RTX_P
+ #define TARGET_SCHED_SKIP_RTX_P ia64_skip_rtx_p
+ 
+ #undef TARGET_FUNCTION_OK_FOR_SIBCALL
+ #define TARGET_FUNCTION_OK_FOR_SIBCALL ia64_function_ok_for_sibcall
+ #undef TARGET_ARG_PARTIAL_BYTES
+ #define TARGET_ARG_PARTIAL_BYTES ia64_arg_partial_bytes
+ #undef TARGET_FUNCTION_ARG
+ #define TARGET_FUNCTION_ARG ia64_function_arg
+ #undef TARGET_FUNCTION_INCOMING_ARG
+ #define TARGET_FUNCTION_INCOMING_ARG ia64_function_incoming_arg
+ #undef TARGET_FUNCTION_ARG_ADVANCE
+ #define TARGET_FUNCTION_ARG_ADVANCE ia64_function_arg_advance
+ #undef TARGET_FUNCTION_ARG_PADDING
+ #define TARGET_FUNCTION_ARG_PADDING ia64_function_arg_padding
+ #undef TARGET_FUNCTION_ARG_BOUNDARY
+ #define TARGET_FUNCTION_ARG_BOUNDARY ia64_function_arg_boundary
+ 
+ #undef TARGET_ASM_OUTPUT_MI_THUNK
+ #define TARGET_ASM_OUTPUT_MI_THUNK ia64_output_mi_thunk
+ #undef TARGET_ASM_CAN_OUTPUT_MI_THUNK
+ #define TARGET_ASM_CAN_OUTPUT_MI_THUNK hook_bool_const_tree_hwi_hwi_const_tree_true
+ 
+ #undef TARGET_ASM_FILE_START
+ #define TARGET_ASM_FILE_START ia64_file_start
+ 
+ #undef TARGET_ASM_GLOBALIZE_DECL_NAME
+ #define TARGET_ASM_GLOBALIZE_DECL_NAME ia64_globalize_decl_name
+ 
+ #undef TARGET_REGISTER_MOVE_COST
+ #define TARGET_REGISTER_MOVE_COST ia64_register_move_cost
+ #undef TARGET_MEMORY_MOVE_COST
+ #define TARGET_MEMORY_MOVE_COST ia64_memory_move_cost
+ #undef TARGET_RTX_COSTS
+ #define TARGET_RTX_COSTS ia64_rtx_costs
+ #undef TARGET_ADDRESS_COST
+ #define TARGET_ADDRESS_COST hook_int_rtx_mode_as_bool_0
+ 
+ #undef TARGET_UNSPEC_MAY_TRAP_P
+ #define TARGET_UNSPEC_MAY_TRAP_P ia64_unspec_may_trap_p
+ 
+ #undef TARGET_MACHINE_DEPENDENT_REORG
+ #define TARGET_MACHINE_DEPENDENT_REORG ia64_reorg
+ 
+ #undef TARGET_ENCODE_SECTION_INFO
+ #define TARGET_ENCODE_SECTION_INFO ia64_encode_section_info
+ 
+ #undef  TARGET_SECTION_TYPE_FLAGS
+ #define TARGET_SECTION_TYPE_FLAGS  ia64_section_type_flags
+ 
+ #ifdef HAVE_AS_TLS
+ #undef TARGET_ASM_OUTPUT_DWARF_DTPREL
+ #define TARGET_ASM_OUTPUT_DWARF_DTPREL ia64_output_dwarf_dtprel
+ #endif
+ 
+ /* ??? Investigate.  */
+ #if 0
+ #undef TARGET_PROMOTE_PROTOTYPES
+ #define TARGET_PROMOTE_PROTOTYPES hook_bool_tree_true
+ #endif
+ 
+ #undef TARGET_FUNCTION_VALUE
+ #define TARGET_FUNCTION_VALUE ia64_function_value
+ #undef TARGET_LIBCALL_VALUE
+ #define TARGET_LIBCALL_VALUE ia64_libcall_value
+ #undef TARGET_FUNCTION_VALUE_REGNO_P
+ #define TARGET_FUNCTION_VALUE_REGNO_P ia64_function_value_regno_p
+ 
+ #undef TARGET_STRUCT_VALUE_RTX
+ #define TARGET_STRUCT_VALUE_RTX ia64_struct_value_rtx
+ #undef TARGET_RETURN_IN_MEMORY
+ #define TARGET_RETURN_IN_MEMORY ia64_return_in_memory
+ #undef TARGET_SETUP_INCOMING_VARARGS
+ #define TARGET_SETUP_INCOMING_VARARGS ia64_setup_incoming_varargs
+ #undef TARGET_STRICT_ARGUMENT_NAMING
+ #define TARGET_STRICT_ARGUMENT_NAMING hook_bool_CUMULATIVE_ARGS_true
+ #undef TARGET_MUST_PASS_IN_STACK
+ #define TARGET_MUST_PASS_IN_STACK must_pass_in_stack_var_size
+ #undef TARGET_GET_RAW_RESULT_MODE
+ #define TARGET_GET_RAW_RESULT_MODE ia64_get_reg_raw_mode
+ #undef TARGET_GET_RAW_ARG_MODE
+ #define TARGET_GET_RAW_ARG_MODE ia64_get_reg_raw_mode
+ 
+ #undef TARGET_MEMBER_TYPE_FORCES_BLK
+ #define TARGET_MEMBER_TYPE_FORCES_BLK ia64_member_type_forces_blk
+ 
+ #undef TARGET_GIMPLIFY_VA_ARG_EXPR
+ #define TARGET_GIMPLIFY_VA_ARG_EXPR ia64_gimplify_va_arg
+ 
+ #undef TARGET_ASM_UNWIND_EMIT
+ #define TARGET_ASM_UNWIND_EMIT ia64_asm_unwind_emit
+ #undef TARGET_ASM_EMIT_EXCEPT_PERSONALITY
+ #define TARGET_ASM_EMIT_EXCEPT_PERSONALITY  ia64_asm_emit_except_personality
+ #undef TARGET_ASM_INIT_SECTIONS
+ #define TARGET_ASM_INIT_SECTIONS  ia64_asm_init_sections
+ 
+ #undef TARGET_DEBUG_UNWIND_INFO
+ #define TARGET_DEBUG_UNWIND_INFO  ia64_debug_unwind_info
+ 
+ #undef TARGET_SCALAR_MODE_SUPPORTED_P
+ #define TARGET_SCALAR_MODE_SUPPORTED_P ia64_scalar_mode_supported_p
+ #undef TARGET_VECTOR_MODE_SUPPORTED_P
+ #define TARGET_VECTOR_MODE_SUPPORTED_P ia64_vector_mode_supported_p
+ 
+ #undef TARGET_LEGITIMATE_CONSTANT_P
+ #define TARGET_LEGITIMATE_CONSTANT_P ia64_legitimate_constant_p
+ #undef TARGET_LEGITIMATE_ADDRESS_P
+ #define TARGET_LEGITIMATE_ADDRESS_P ia64_legitimate_address_p
+ 
+ #undef TARGET_LRA_P
+ #define TARGET_LRA_P hook_bool_void_false
+ 
+ #undef TARGET_CANNOT_FORCE_CONST_MEM
+ #define TARGET_CANNOT_FORCE_CONST_MEM ia64_cannot_force_const_mem
+ 
+ #undef TARGET_MANGLE_TYPE
+ #define TARGET_MANGLE_TYPE ia64_mangle_type
+ 
+ #undef TARGET_INVALID_CONVERSION
+ #define TARGET_INVALID_CONVERSION ia64_invalid_conversion
+ #undef TARGET_INVALID_UNARY_OP
+ #define TARGET_INVALID_UNARY_OP ia64_invalid_unary_op
+ #undef TARGET_INVALID_BINARY_OP
+ #define TARGET_INVALID_BINARY_OP ia64_invalid_binary_op
+ 
+ #undef TARGET_C_MODE_FOR_SUFFIX
+ #define TARGET_C_MODE_FOR_SUFFIX ia64_c_mode_for_suffix
+ 
+ #undef TARGET_CAN_ELIMINATE
+ #define TARGET_CAN_ELIMINATE ia64_can_eliminate
+ 
+ #undef TARGET_TRAMPOLINE_INIT
+ #define TARGET_TRAMPOLINE_INIT ia64_trampoline_init
+ 
+ #undef TARGET_CAN_USE_DOLOOP_P
+ #define TARGET_CAN_USE_DOLOOP_P can_use_doloop_if_innermost
+ #undef TARGET_INVALID_WITHIN_DOLOOP
+ #define TARGET_INVALID_WITHIN_DOLOOP hook_constcharptr_const_rtx_insn_null
+ 
+ #undef TARGET_OVERRIDE_OPTIONS_AFTER_CHANGE
+ #define TARGET_OVERRIDE_OPTIONS_AFTER_CHANGE ia64_override_options_after_change
+ 
+ #undef TARGET_PREFERRED_RELOAD_CLASS
+ #define TARGET_PREFERRED_RELOAD_CLASS ia64_preferred_reload_class
+ 
+ #undef TARGET_DELAY_SCHED2
+ #define TARGET_DELAY_SCHED2 true
+ 
+ /* Variable tracking should be run after all optimizations which
+    change order of insns.  It also needs a valid CFG.  */
+ #undef TARGET_DELAY_VARTRACK
+ #define TARGET_DELAY_VARTRACK true
+ 
+ #undef TARGET_VECTORIZE_VEC_PERM_CONST
+ #define TARGET_VECTORIZE_VEC_PERM_CONST ia64_vectorize_vec_perm_const
+ 
+ #undef TARGET_ATTRIBUTE_TAKES_IDENTIFIER_P
+ #define TARGET_ATTRIBUTE_TAKES_IDENTIFIER_P ia64_attribute_takes_identifier_p
+ 
+ #undef TARGET_CUSTOM_FUNCTION_DESCRIPTORS
+ #define TARGET_CUSTOM_FUNCTION_DESCRIPTORS 0
+ 
+ #undef TARGET_HARD_REGNO_NREGS
+ #define TARGET_HARD_REGNO_NREGS ia64_hard_regno_nregs
+ #undef TARGET_HARD_REGNO_MODE_OK
+ #define TARGET_HARD_REGNO_MODE_OK ia64_hard_regno_mode_ok
+ 
+ #undef TARGET_MODES_TIEABLE_P
+ #define TARGET_MODES_TIEABLE_P ia64_modes_tieable_p
+ 
+ #undef TARGET_CAN_CHANGE_MODE_CLASS
+ #define TARGET_CAN_CHANGE_MODE_CLASS ia64_can_change_mode_class
+ 
+ #undef TARGET_CONSTANT_ALIGNMENT
+ #define TARGET_CONSTANT_ALIGNMENT constant_alignment_word_strings
+ 
+ struct gcc_target targetm = TARGET_INITIALIZER;
+ \f
+ /* Returns TRUE iff the target attribute indicated by ATTR_ID takes a plain
+    identifier as an argument, so the front end shouldn't look it up.  */
+ 
+ static bool
+ ia64_attribute_takes_identifier_p (const_tree attr_id)
+ {
+   if (is_attribute_p ("model", attr_id))
+     return true;
+ #if TARGET_ABI_OPEN_VMS
+   if (is_attribute_p ("common_object", attr_id))
+     return true;
+ #endif
+   return false;
+ }
+ 
+ typedef enum
+   {
+     ADDR_AREA_NORMAL,	/* normal address area */
+     ADDR_AREA_SMALL	/* addressable by "addl" (-2MB < addr < 2MB) */
+   }
+ ia64_addr_area;
+ 
+ static GTY(()) tree small_ident1;
+ static GTY(()) tree small_ident2;
+ 
+ static void
+ init_idents (void)
+ {
+   if (small_ident1 == 0)
+     {
+       small_ident1 = get_identifier ("small");
+       small_ident2 = get_identifier ("__small__");
+     }
+ }
+ 
+ /* Retrieve the address area that has been chosen for the given decl.  */
+ 
+ static ia64_addr_area
+ ia64_get_addr_area (tree decl)
+ {
+   tree model_attr;
+ 
+   model_attr = lookup_attribute ("model", DECL_ATTRIBUTES (decl));
+   if (model_attr)
+     {
+       tree id;
+ 
+       init_idents ();
+       id = TREE_VALUE (TREE_VALUE (model_attr));
+       if (id == small_ident1 || id == small_ident2)
+ 	return ADDR_AREA_SMALL;
+     }
+   return ADDR_AREA_NORMAL;
+ }
+ 
+ static tree
+ ia64_handle_model_attribute (tree *node, tree name, tree args,
+ 			     int flags ATTRIBUTE_UNUSED, bool *no_add_attrs)
+ {
+   ia64_addr_area addr_area = ADDR_AREA_NORMAL;
+   ia64_addr_area area;
+   tree arg, decl = *node;
+ 
+   init_idents ();
+   arg = TREE_VALUE (args);
+   if (arg == small_ident1 || arg == small_ident2)
+     {
+       addr_area = ADDR_AREA_SMALL;
+     }
+   else
+     {
+       warning (OPT_Wattributes, "invalid argument of %qE attribute",
+ 	       name);
+       *no_add_attrs = true;
+     }
+ 
+   switch (TREE_CODE (decl))
+     {
+     case VAR_DECL:
+       if ((DECL_CONTEXT (decl) && TREE_CODE (DECL_CONTEXT (decl))
+ 	   == FUNCTION_DECL)
+ 	  && !TREE_STATIC (decl))
+ 	{
+ 	  error_at (DECL_SOURCE_LOCATION (decl),
+ 		    "an address area attribute cannot be specified for "
+ 		    "local variables");
+ 	  *no_add_attrs = true;
+ 	}
+       area = ia64_get_addr_area (decl);
+       if (area != ADDR_AREA_NORMAL && addr_area != area)
+ 	{
+ 	  error ("address area of %q+D conflicts with previous "
+ 		 "declaration", decl);
+ 	  *no_add_attrs = true;
+ 	}
+       break;
+ 
+     case FUNCTION_DECL:
+       error_at (DECL_SOURCE_LOCATION (decl),
+ 		"address area attribute cannot be specified for "
+ 		"functions");
+       *no_add_attrs = true;
+       break;
+ 
+     default:
+       warning (OPT_Wattributes, "%qE attribute ignored",
+ 	       name);
+       *no_add_attrs = true;
+       break;
+     }
+ 
+   return NULL_TREE;
+ }
+ 
+ /* Part of the low level implementation of DEC Ada pragma Common_Object which
+    enables the shared use of variables stored in overlaid linker areas
+    corresponding to the use of Fortran COMMON.  */
+ 
+ static tree
+ ia64_vms_common_object_attribute (tree *node, tree name, tree args,
+ 				  int flags ATTRIBUTE_UNUSED,
+ 				  bool *no_add_attrs)
+ {
+     tree decl = *node;
+     tree id;
+ 
+     gcc_assert (DECL_P (decl));
+   
+     DECL_COMMON (decl) = 1;
+     id = TREE_VALUE (args);
+     if (TREE_CODE (id) != IDENTIFIER_NODE && TREE_CODE (id) != STRING_CST)
+       {
+ 	error ("%qE attribute requires a string constant argument", name);
+ 	*no_add_attrs = true;
+ 	return NULL_TREE;
+       }
+     return NULL_TREE;
+ }
+ 
+ /* Part of the low level implementation of DEC Ada pragma Common_Object.  */
+ 
+ void
+ ia64_vms_output_aligned_decl_common (FILE *file, tree decl, const char *name,
+ 				     unsigned HOST_WIDE_INT size,
+ 				     unsigned int align)
+ {
+   tree attr = DECL_ATTRIBUTES (decl);
+ 
+   if (attr)
+     attr = lookup_attribute ("common_object", attr);
+   if (attr)
+     {
+       tree id = TREE_VALUE (TREE_VALUE (attr));
+       const char *name;
+ 
+       if (TREE_CODE (id) == IDENTIFIER_NODE)
+         name = IDENTIFIER_POINTER (id);
+       else if (TREE_CODE (id) == STRING_CST)
+         name = TREE_STRING_POINTER (id);
+       else
+         abort ();
+ 
+       fprintf (file, "\t.vms_common\t\"%s\",", name);
+     }
+   else
+     fprintf (file, "%s", COMMON_ASM_OP);
+ 
+   /*  Code from elfos.h.  */
+   assemble_name (file, name);
+   fprintf (file, "," HOST_WIDE_INT_PRINT_UNSIGNED",%u",
+            size, align / BITS_PER_UNIT);
+ 
+   fputc ('\n', file);
+ }
+ 
+ static void
+ ia64_encode_addr_area (tree decl, rtx symbol)
+ {
+   int flags;
+ 
+   flags = SYMBOL_REF_FLAGS (symbol);
+   switch (ia64_get_addr_area (decl))
+     {
+     case ADDR_AREA_NORMAL: break;
+     case ADDR_AREA_SMALL: flags |= SYMBOL_FLAG_SMALL_ADDR; break;
+     default: gcc_unreachable ();
+     }
+   SYMBOL_REF_FLAGS (symbol) = flags;
+ }
+ 
+ static void
+ ia64_encode_section_info (tree decl, rtx rtl, int first)
+ {
+   default_encode_section_info (decl, rtl, first);
+ 
+   /* Careful not to prod global register variables.  */
+   if (TREE_CODE (decl) == VAR_DECL
+       && GET_CODE (DECL_RTL (decl)) == MEM
+       && GET_CODE (XEXP (DECL_RTL (decl), 0)) == SYMBOL_REF
+       && (TREE_STATIC (decl) || DECL_EXTERNAL (decl)))
+     ia64_encode_addr_area (decl, XEXP (rtl, 0));
+ }
+ \f
+ /* Return 1 if the operands of a move are ok.  */
+ 
+ int
+ ia64_move_ok (rtx dst, rtx src)
+ {
+   /* If we're under init_recog_no_volatile, we'll not be able to use
+      memory_operand.  So check the code directly and don't worry about
+      the validity of the underlying address, which should have been
+      checked elsewhere anyway.  */
+   if (GET_CODE (dst) != MEM)
+     return 1;
+   if (GET_CODE (src) == MEM)
+     return 0;
+   if (register_operand (src, VOIDmode))
+     return 1;
+ 
+   /* Otherwise, this must be a constant, and that either 0 or 0.0 or 1.0.  */
+   if (INTEGRAL_MODE_P (GET_MODE (dst)))
+     return src == const0_rtx;
+   else
+     return satisfies_constraint_G (src);
+ }
+ 
+ /* Return 1 if the operands are ok for a floating point load pair.  */
+ 
+ int
+ ia64_load_pair_ok (rtx dst, rtx src)
+ {
+   /* ??? There is a thinko in the implementation of the "x" constraint and the
+      FP_REGS class.  The constraint will also reject (reg f30:TI) so we must
+      also return false for it.  */
+   if (GET_CODE (dst) != REG
+       || !(FP_REGNO_P (REGNO (dst)) && FP_REGNO_P (REGNO (dst) + 1)))
+     return 0;
+   if (GET_CODE (src) != MEM || MEM_VOLATILE_P (src))
+     return 0;
+   switch (GET_CODE (XEXP (src, 0)))
+     {
+     case REG:
+     case POST_INC:
+       break;
+     case POST_DEC:
+       return 0;
+     case POST_MODIFY:
+       {
+ 	rtx adjust = XEXP (XEXP (XEXP (src, 0), 1), 1);
+ 
+ 	if (GET_CODE (adjust) != CONST_INT
+ 	    || INTVAL (adjust) != GET_MODE_SIZE (GET_MODE (src)))
+ 	  return 0;
+       }
+       break;
+     default:
+       abort ();
+     }
+   return 1;
+ }
+ 
+ int
+ addp4_optimize_ok (rtx op1, rtx op2)
+ {
+   return (basereg_operand (op1, GET_MODE(op1)) !=
+ 	  basereg_operand (op2, GET_MODE(op2)));
+ }
+ 
+ /* Check if OP is a mask suitable for use with SHIFT in a dep.z instruction.
+    Return the length of the field, or <= 0 on failure.  */
+ 
+ int
+ ia64_depz_field_mask (rtx rop, rtx rshift)
+ {
+   unsigned HOST_WIDE_INT op = INTVAL (rop);
+   unsigned HOST_WIDE_INT shift = INTVAL (rshift);
+ 
+   /* Get rid of the zero bits we're shifting in.  */
+   op >>= shift;
+ 
+   /* We must now have a solid block of 1's at bit 0.  */
+   return exact_log2 (op + 1);
+ }
+ 
+ /* Return the TLS model to use for ADDR.  */
+ 
+ static enum tls_model
+ tls_symbolic_operand_type (rtx addr)
+ {
+   enum tls_model tls_kind = TLS_MODEL_NONE;
+ 
+   if (GET_CODE (addr) == CONST)
+     {
+       if (GET_CODE (XEXP (addr, 0)) == PLUS
+ 	  && GET_CODE (XEXP (XEXP (addr, 0), 0)) == SYMBOL_REF)
+         tls_kind = SYMBOL_REF_TLS_MODEL (XEXP (XEXP (addr, 0), 0));
+     }
+   else if (GET_CODE (addr) == SYMBOL_REF)
+     tls_kind = SYMBOL_REF_TLS_MODEL (addr);
+ 
+   return tls_kind;
+ }
+ 
+ /* Returns true if REG (assumed to be a `reg' RTX) is valid for use
+    as a base register.  */
+ 
+ static inline bool
+ ia64_reg_ok_for_base_p (const_rtx reg, bool strict)
+ {
+   if (strict
+       && REGNO_OK_FOR_BASE_P (REGNO (reg)))
+     return true;
+   else if (!strict
+ 	   && (GENERAL_REGNO_P (REGNO (reg))
+ 	       || !HARD_REGISTER_P (reg)))
+     return true;
+   else
+     return false;
+ }
+ 
+ static bool
+ ia64_legitimate_address_reg (const_rtx reg, bool strict)
+ {
+   if ((REG_P (reg) && ia64_reg_ok_for_base_p (reg, strict))
+       || (GET_CODE (reg) == SUBREG && REG_P (XEXP (reg, 0))
+ 	  && ia64_reg_ok_for_base_p (XEXP (reg, 0), strict)))
+     return true;
+ 
+   return false;
+ }
+ 
+ static bool
+ ia64_legitimate_address_disp (const_rtx reg, const_rtx disp, bool strict)
+ {
+   if (GET_CODE (disp) == PLUS
+       && rtx_equal_p (reg, XEXP (disp, 0))
+       && (ia64_legitimate_address_reg (XEXP (disp, 1), strict)
+ 	  || (CONST_INT_P (XEXP (disp, 1))
+ 	      && IN_RANGE (INTVAL (XEXP (disp, 1)), -256, 255))))
+     return true;
+ 
+   return false;
+ }
+ 
+ /* Implement TARGET_LEGITIMATE_ADDRESS_P.  */
+ 
+ static bool
+ ia64_legitimate_address_p (machine_mode mode ATTRIBUTE_UNUSED,
+ 			   rtx x, bool strict)
+ {
+   if (ia64_legitimate_address_reg (x, strict))
+     return true;
+   else if ((GET_CODE (x) == POST_INC || GET_CODE (x) == POST_DEC)
+ 	   && ia64_legitimate_address_reg (XEXP (x, 0), strict)
+ 	   && XEXP (x, 0) != arg_pointer_rtx) 
+     return true;
+   else if (GET_CODE (x) == POST_MODIFY
+ 	   && ia64_legitimate_address_reg (XEXP (x, 0), strict)
+ 	   && XEXP (x, 0) != arg_pointer_rtx
+ 	   && ia64_legitimate_address_disp (XEXP (x, 0), XEXP (x, 1), strict))
+     return true;
+   else
+     return false;
+ }
+ 
+ /* Return true if X is a constant that is valid for some immediate
+    field in an instruction.  */
+ 
+ static bool
+ ia64_legitimate_constant_p (machine_mode mode, rtx x)
+ {
+   switch (GET_CODE (x))
+     {
+     case CONST_INT:
+     case LABEL_REF:
+       return true;
+ 
+     case CONST_DOUBLE:
+       if (GET_MODE (x) == VOIDmode || mode == SFmode || mode == DFmode)
+ 	return true;
+       return satisfies_constraint_G (x);
+ 
+     case CONST:
+     case SYMBOL_REF:
+       /* ??? Short term workaround for PR 28490.  We must make the code here
+ 	 match the code in ia64_expand_move and move_operand, even though they
+ 	 are both technically wrong.  */
+       if (tls_symbolic_operand_type (x) == 0)
+ 	{
+ 	  HOST_WIDE_INT addend = 0;
+ 	  rtx op = x;
+ 
+ 	  if (GET_CODE (op) == CONST
+ 	      && GET_CODE (XEXP (op, 0)) == PLUS
+ 	      && GET_CODE (XEXP (XEXP (op, 0), 1)) == CONST_INT)
+ 	    {
+ 	      addend = INTVAL (XEXP (XEXP (op, 0), 1));
+ 	      op = XEXP (XEXP (op, 0), 0);
+ 	    }
+ 
+           if (any_offset_symbol_operand (op, mode)
+               || function_operand (op, mode))
+             return true;
+ 	  if (aligned_offset_symbol_operand (op, mode))
+ 	    return (addend & 0x3fff) == 0;
+ 	  return false;
+ 	}
+       return false;
+ 
+     case CONST_VECTOR:
+       if (mode == V2SFmode)
+ 	return satisfies_constraint_Y (x);
+ 
+       return (GET_MODE_CLASS (mode) == MODE_VECTOR_INT
+ 	      && GET_MODE_SIZE (mode) <= 8);
+ 
+     default:
+       return false;
+     }
+ }
+ 
+ /* Don't allow TLS addresses to get spilled to memory.  */
+ 
+ static bool
+ ia64_cannot_force_const_mem (machine_mode mode, rtx x)
+ {
+   if (mode == RFmode)
+     return true;
+   return tls_symbolic_operand_type (x) != 0;
+ }
+ 
+ /* Expand a symbolic constant load.  */
+ 
+ bool
+ ia64_expand_load_address (rtx dest, rtx src)
+ {
+   gcc_assert (GET_CODE (dest) == REG);
+ 
+   /* ILP32 mode still loads 64-bits of data from the GOT.  This avoids
+      having to pointer-extend the value afterward.  Other forms of address
+      computation below are also more natural to compute as 64-bit quantities.
+      If we've been given an SImode destination register, change it.  */
+   if (GET_MODE (dest) != Pmode)
+     dest = gen_rtx_REG_offset (dest, Pmode, REGNO (dest),
+ 			       byte_lowpart_offset (Pmode, GET_MODE (dest)));
+ 
+   if (TARGET_NO_PIC)
+     return false;
+   if (small_addr_symbolic_operand (src, VOIDmode))
+     return false;
+ 
+   if (TARGET_AUTO_PIC)
+     emit_insn (gen_load_gprel64 (dest, src));
+   else if (GET_CODE (src) == SYMBOL_REF && SYMBOL_REF_FUNCTION_P (src))
+     emit_insn (gen_load_fptr (dest, src));
+   else if (sdata_symbolic_operand (src, VOIDmode))
+     emit_insn (gen_load_gprel (dest, src));
+   else if (local_symbolic_operand64 (src, VOIDmode))
+     {
+       /* We want to use @gprel rather than @ltoff relocations for local
+ 	 symbols:
+ 	  - @gprel does not require dynamic linker
+ 	  - and does not use .sdata section
+ 	 https://gcc.gnu.org/bugzilla/60465 */
+       emit_insn (gen_load_gprel64 (dest, src));
+     }
+   else
+     {
+       HOST_WIDE_INT addend = 0;
+       rtx tmp;
+ 
+       /* We did split constant offsets in ia64_expand_move, and we did try
+ 	 to keep them split in move_operand, but we also allowed reload to
+ 	 rematerialize arbitrary constants rather than spill the value to
+ 	 the stack and reload it.  So we have to be prepared here to split
+ 	 them apart again.  */
+       if (GET_CODE (src) == CONST)
+ 	{
+ 	  HOST_WIDE_INT hi, lo;
+ 
+ 	  hi = INTVAL (XEXP (XEXP (src, 0), 1));
+ 	  lo = ((hi & 0x3fff) ^ 0x2000) - 0x2000;
+ 	  hi = hi - lo;
+ 
+ 	  if (lo != 0)
+ 	    {
+ 	      addend = lo;
+ 	      src = plus_constant (Pmode, XEXP (XEXP (src, 0), 0), hi);
+ 	    }
+ 	}
+ 
+       tmp = gen_rtx_HIGH (Pmode, src);
+       tmp = gen_rtx_PLUS (Pmode, tmp, pic_offset_table_rtx);
+       emit_insn (gen_rtx_SET (dest, tmp));
+ 
+       tmp = gen_rtx_LO_SUM (Pmode, gen_const_mem (Pmode, dest), src);
+       emit_insn (gen_rtx_SET (dest, tmp));
+ 
+       if (addend)
+ 	{
+ 	  tmp = gen_rtx_PLUS (Pmode, dest, GEN_INT (addend));
+ 	  emit_insn (gen_rtx_SET (dest, tmp));
+ 	}
+     }
+ 
+   return true;
+ }
+ 
+ static GTY(()) rtx gen_tls_tga;
+ static rtx
+ gen_tls_get_addr (void)
+ {
+   if (!gen_tls_tga)
+     gen_tls_tga = init_one_libfunc ("__tls_get_addr");
+   return gen_tls_tga;
+ }
+ 
+ static GTY(()) rtx thread_pointer_rtx;
+ static rtx
+ gen_thread_pointer (void)
+ {
+   if (!thread_pointer_rtx)
+     thread_pointer_rtx = gen_rtx_REG (Pmode, 13);
+   return thread_pointer_rtx;
+ }
+ 
+ static rtx
+ ia64_expand_tls_address (enum tls_model tls_kind, rtx op0, rtx op1,
+ 			 rtx orig_op1, HOST_WIDE_INT addend)
+ {
+   rtx tga_op1, tga_op2, tga_ret, tga_eqv, tmp;
+   rtx_insn *insns;
+   rtx orig_op0 = op0;
+   HOST_WIDE_INT addend_lo, addend_hi;
+ 
+   switch (tls_kind)
+     {
+     case TLS_MODEL_GLOBAL_DYNAMIC:
+       start_sequence ();
+ 
+       tga_op1 = gen_reg_rtx (Pmode);
+       emit_insn (gen_load_dtpmod (tga_op1, op1));
+ 
+       tga_op2 = gen_reg_rtx (Pmode);
+       emit_insn (gen_load_dtprel (tga_op2, op1));
+ 
+       tga_ret = emit_library_call_value (gen_tls_get_addr (), NULL_RTX,
+ 					 LCT_CONST, Pmode,
+ 					 tga_op1, Pmode, tga_op2, Pmode);
+ 
+       insns = get_insns ();
+       end_sequence ();
+ 
+       if (GET_MODE (op0) != Pmode)
+ 	op0 = tga_ret;
+       emit_libcall_block (insns, op0, tga_ret, op1);
+       break;
+ 
+     case TLS_MODEL_LOCAL_DYNAMIC:
+       /* ??? This isn't the completely proper way to do local-dynamic
+ 	 If the call to __tls_get_addr is used only by a single symbol,
+ 	 then we should (somehow) move the dtprel to the second arg
+ 	 to avoid the extra add.  */
+       start_sequence ();
+ 
+       tga_op1 = gen_reg_rtx (Pmode);
+       emit_insn (gen_load_dtpmod (tga_op1, op1));
+ 
+       tga_op2 = const0_rtx;
+ 
+       tga_ret = emit_library_call_value (gen_tls_get_addr (), NULL_RTX,
+ 					 LCT_CONST, Pmode,
+ 					 tga_op1, Pmode, tga_op2, Pmode);
+ 
+       insns = get_insns ();
+       end_sequence ();
+ 
+       tga_eqv = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, const0_rtx),
+ 				UNSPEC_LD_BASE);
+       tmp = gen_reg_rtx (Pmode);
+       emit_libcall_block (insns, tmp, tga_ret, tga_eqv);
+ 
+       if (!register_operand (op0, Pmode))
+ 	op0 = gen_reg_rtx (Pmode);
+       if (TARGET_TLS64)
+ 	{
+ 	  emit_insn (gen_load_dtprel (op0, op1));
+ 	  emit_insn (gen_adddi3 (op0, tmp, op0));
+ 	}
+       else
+ 	emit_insn (gen_add_dtprel (op0, op1, tmp));
+       break;
+ 
+     case TLS_MODEL_INITIAL_EXEC:
+       addend_lo = ((addend & 0x3fff) ^ 0x2000) - 0x2000;
+       addend_hi = addend - addend_lo;
+ 
+       op1 = plus_constant (Pmode, op1, addend_hi);
+       addend = addend_lo;
+ 
+       tmp = gen_reg_rtx (Pmode);
+       emit_insn (gen_load_tprel (tmp, op1));
+ 
+       if (!register_operand (op0, Pmode))
+ 	op0 = gen_reg_rtx (Pmode);
+       emit_insn (gen_adddi3 (op0, tmp, gen_thread_pointer ()));
+       break;
+ 
+     case TLS_MODEL_LOCAL_EXEC:
+       if (!register_operand (op0, Pmode))
+ 	op0 = gen_reg_rtx (Pmode);
+ 
+       op1 = orig_op1;
+       addend = 0;
+       if (TARGET_TLS64)
+ 	{
+ 	  emit_insn (gen_load_tprel (op0, op1));
+ 	  emit_insn (gen_adddi3 (op0, op0, gen_thread_pointer ()));
+ 	}
+       else
+ 	emit_insn (gen_add_tprel (op0, op1, gen_thread_pointer ()));
+       break;
+ 
+     default:
+       gcc_unreachable ();
+     }
+ 
+   if (addend)
+     op0 = expand_simple_binop (Pmode, PLUS, op0, GEN_INT (addend),
+ 			       orig_op0, 1, OPTAB_DIRECT);
+   if (orig_op0 == op0)
+     return NULL_RTX;
+   if (GET_MODE (orig_op0) == Pmode)
+     return op0;
+   return gen_lowpart (GET_MODE (orig_op0), op0);
+ }
+ 
+ rtx
+ ia64_expand_move (rtx op0, rtx op1)
+ {
+   machine_mode mode = GET_MODE (op0);
+ 
+   if (!reload_in_progress && !reload_completed && !ia64_move_ok (op0, op1))
+     op1 = force_reg (mode, op1);
+ 
+   if ((mode == Pmode || mode == ptr_mode) && symbolic_operand (op1, VOIDmode))
+     {
+       HOST_WIDE_INT addend = 0;
+       enum tls_model tls_kind;
+       rtx sym = op1;
+ 
+       if (GET_CODE (op1) == CONST
+ 	  && GET_CODE (XEXP (op1, 0)) == PLUS
+ 	  && GET_CODE (XEXP (XEXP (op1, 0), 1)) == CONST_INT)
+ 	{
+ 	  addend = INTVAL (XEXP (XEXP (op1, 0), 1));
+ 	  sym = XEXP (XEXP (op1, 0), 0);
+ 	}
+ 
+       tls_kind = tls_symbolic_operand_type (sym);
+       if (tls_kind)
+ 	return ia64_expand_tls_address (tls_kind, op0, sym, op1, addend);
+ 
+       if (any_offset_symbol_operand (sym, mode))
+ 	addend = 0;
+       else if (aligned_offset_symbol_operand (sym, mode))
+ 	{
+ 	  HOST_WIDE_INT addend_lo, addend_hi;
+ 	      
+ 	  addend_lo = ((addend & 0x3fff) ^ 0x2000) - 0x2000;
+ 	  addend_hi = addend - addend_lo;
+ 
+ 	  if (addend_lo != 0)
+ 	    {
+ 	      op1 = plus_constant (mode, sym, addend_hi);
+ 	      addend = addend_lo;
+ 	    }
+ 	  else
+ 	    addend = 0;
+ 	}
+       else
+ 	op1 = sym;
+ 
+       if (reload_completed)
+ 	{
+ 	  /* We really should have taken care of this offset earlier.  */
+ 	  gcc_assert (addend == 0);
+ 	  if (ia64_expand_load_address (op0, op1))
+ 	    return NULL_RTX;
+ 	}
+ 
+       if (addend)
+ 	{
+ 	  rtx subtarget = !can_create_pseudo_p () ? op0 : gen_reg_rtx (mode);
+ 
+ 	  emit_insn (gen_rtx_SET (subtarget, op1));
+ 
+ 	  op1 = expand_simple_binop (mode, PLUS, subtarget,
+ 				     GEN_INT (addend), op0, 1, OPTAB_DIRECT);
+ 	  if (op0 == op1)
+ 	    return NULL_RTX;
+ 	}
+     }
+ 
+   return op1;
+ }
+ 
+ /* Split a move from OP1 to OP0 conditional on COND.  */
+ 
+ void
+ ia64_emit_cond_move (rtx op0, rtx op1, rtx cond)
+ {
+   rtx_insn *insn, *first = get_last_insn ();
+ 
+   emit_move_insn (op0, op1);
+ 
+   for (insn = get_last_insn (); insn != first; insn = PREV_INSN (insn))
+     if (INSN_P (insn))
+       PATTERN (insn) = gen_rtx_COND_EXEC (VOIDmode, copy_rtx (cond),
+ 					  PATTERN (insn));
+ }
+ 
+ /* Split a post-reload TImode or TFmode reference into two DImode
+    components.  This is made extra difficult by the fact that we do
+    not get any scratch registers to work with, because reload cannot
+    be prevented from giving us a scratch that overlaps the register
+    pair involved.  So instead, when addressing memory, we tweak the
+    pointer register up and back down with POST_INCs.  Or up and not
+    back down when we can get away with it.
+ 
+    REVERSED is true when the loads must be done in reversed order
+    (high word first) for correctness.  DEAD is true when the pointer
+    dies with the second insn we generate and therefore the second
+    address must not carry a postmodify.
+ 
+    May return an insn which is to be emitted after the moves.  */
+ 
+ static rtx
+ ia64_split_tmode (rtx out[2], rtx in, bool reversed, bool dead)
+ {
+   rtx fixup = 0;
+ 
+   switch (GET_CODE (in))
+     {
+     case REG:
+       out[reversed] = gen_rtx_REG (DImode, REGNO (in));
+       out[!reversed] = gen_rtx_REG (DImode, REGNO (in) + 1);
+       break;
+ 
+     case CONST_INT:
+     case CONST_DOUBLE:
+       /* Cannot occur reversed.  */
+       gcc_assert (!reversed);
+       
+       if (GET_MODE (in) != TFmode)
+ 	split_double (in, &out[0], &out[1]);
+       else
+ 	/* split_double does not understand how to split a TFmode
+ 	   quantity into a pair of DImode constants.  */
+ 	{
+ 	  unsigned HOST_WIDE_INT p[2];
+ 	  long l[4];  /* TFmode is 128 bits */
+ 
+ 	  real_to_target (l, CONST_DOUBLE_REAL_VALUE (in), TFmode);
+ 
+ 	  if (FLOAT_WORDS_BIG_ENDIAN)
+ 	    {
+ 	      p[0] = (((unsigned HOST_WIDE_INT) l[0]) << 32) + l[1];
+ 	      p[1] = (((unsigned HOST_WIDE_INT) l[2]) << 32) + l[3];
+ 	    }
+ 	  else
+ 	    {
+ 	      p[0] = (((unsigned HOST_WIDE_INT) l[1]) << 32) + l[0];
+ 	      p[1] = (((unsigned HOST_WIDE_INT) l[3]) << 32) + l[2];
+ 	    }
+ 	  out[0] = GEN_INT (p[0]);
+ 	  out[1] = GEN_INT (p[1]);
+ 	}
+       break;
+ 
+     case MEM:
+       {
+ 	rtx base = XEXP (in, 0);
+ 	rtx offset;
+ 
+ 	switch (GET_CODE (base))
+ 	  {
+ 	  case REG:
+ 	    if (!reversed)
+ 	      {
+ 		out[0] = adjust_automodify_address
+ 		  (in, DImode, gen_rtx_POST_INC (Pmode, base), 0);
+ 		out[1] = adjust_automodify_address
+ 		  (in, DImode, dead ? 0 : gen_rtx_POST_DEC (Pmode, base), 8);
+ 	      }
+ 	    else
+ 	      {
+ 		/* Reversal requires a pre-increment, which can only
+ 		   be done as a separate insn.  */
+ 		emit_insn (gen_adddi3 (base, base, GEN_INT (8)));
+ 		out[0] = adjust_automodify_address
+ 		  (in, DImode, gen_rtx_POST_DEC (Pmode, base), 8);
+ 		out[1] = adjust_address (in, DImode, 0);
+ 	      }
+ 	    break;
+ 
+ 	  case POST_INC:
+ 	    gcc_assert (!reversed && !dead);
+ 	    
+ 	    /* Just do the increment in two steps.  */
+ 	    out[0] = adjust_automodify_address (in, DImode, 0, 0);
+ 	    out[1] = adjust_automodify_address (in, DImode, 0, 8);
+ 	    break;
+ 
+ 	  case POST_DEC:
+ 	    gcc_assert (!reversed && !dead);
+ 	    
+ 	    /* Add 8, subtract 24.  */
+ 	    base = XEXP (base, 0);
+ 	    out[0] = adjust_automodify_address
+ 	      (in, DImode, gen_rtx_POST_INC (Pmode, base), 0);
+ 	    out[1] = adjust_automodify_address
+ 	      (in, DImode,
+ 	       gen_rtx_POST_MODIFY (Pmode, base,
+ 				    plus_constant (Pmode, base, -24)),
+ 	       8);
+ 	    break;
+ 
+ 	  case POST_MODIFY:
+ 	    gcc_assert (!reversed && !dead);
+ 
+ 	    /* Extract and adjust the modification.  This case is
+ 	       trickier than the others, because we might have an
+ 	       index register, or we might have a combined offset that
+ 	       doesn't fit a signed 9-bit displacement field.  We can
+ 	       assume the incoming expression is already legitimate.  */
+ 	    offset = XEXP (base, 1);
+ 	    base = XEXP (base, 0);
+ 
+ 	    out[0] = adjust_automodify_address
+ 	      (in, DImode, gen_rtx_POST_INC (Pmode, base), 0);
+ 
+ 	    if (GET_CODE (XEXP (offset, 1)) == REG)
+ 	      {
+ 		/* Can't adjust the postmodify to match.  Emit the
+ 		   original, then a separate addition insn.  */
+ 		out[1] = adjust_automodify_address (in, DImode, 0, 8);
+ 		fixup = gen_adddi3 (base, base, GEN_INT (-8));
+ 	      }
+ 	    else
+ 	      {
+ 		gcc_assert (GET_CODE (XEXP (offset, 1)) == CONST_INT);
+ 		if (INTVAL (XEXP (offset, 1)) < -256 + 8)
+ 		  {
+ 		    /* Again the postmodify cannot be made to match,
+ 		       but in this case it's more efficient to get rid
+ 		       of the postmodify entirely and fix up with an
+ 		       add insn.  */
+ 		    out[1] = adjust_automodify_address (in, DImode, base, 8);
+ 		    fixup = gen_adddi3
+ 		      (base, base, GEN_INT (INTVAL (XEXP (offset, 1)) - 8));
+ 		  }
+ 		else
+ 		  {
+ 		    /* Combined offset still fits in the displacement field.
+ 		       (We cannot overflow it at the high end.)  */
+ 		    out[1] = adjust_automodify_address
+ 		      (in, DImode, gen_rtx_POST_MODIFY
+ 		       (Pmode, base, gen_rtx_PLUS
+ 			(Pmode, base,
+ 			 GEN_INT (INTVAL (XEXP (offset, 1)) - 8))),
+ 		       8);
+ 		  }
+ 	      }
+ 	    break;
+ 
+ 	  default:
+ 	    gcc_unreachable ();
+ 	  }
+ 	break;
+       }
+ 
+     default:
+       gcc_unreachable ();
+     }
+ 
+   return fixup;
+ }
+ 
+ /* Split a TImode or TFmode move instruction after reload.
+    This is used by *movtf_internal and *movti_internal.  */
+ void
+ ia64_split_tmode_move (rtx operands[])
+ {
+   rtx in[2], out[2], insn;
+   rtx fixup[2];
+   bool dead = false;
+   bool reversed = false;
+ 
+   /* It is possible for reload to decide to overwrite a pointer with
+      the value it points to.  In that case we have to do the loads in
+      the appropriate order so that the pointer is not destroyed too
+      early.  Also we must not generate a postmodify for that second
+      load, or rws_access_regno will die.  And we must not generate a
+      postmodify for the second load if the destination register 
+      overlaps with the base register.  */
+   if (GET_CODE (operands[1]) == MEM
+       && reg_overlap_mentioned_p (operands[0], operands[1]))
+     {
+       rtx base = XEXP (operands[1], 0);
+       while (GET_CODE (base) != REG)
+ 	base = XEXP (base, 0);
+ 
+       if (REGNO (base) == REGNO (operands[0]))
+ 	reversed = true;
+ 
+       if (refers_to_regno_p (REGNO (operands[0]),
+ 			     REGNO (operands[0])+2,
+ 			     base, 0))
+ 	dead = true;
+     }
+   /* Another reason to do the moves in reversed order is if the first
+      element of the target register pair is also the second element of
+      the source register pair.  */
+   if (GET_CODE (operands[0]) == REG && GET_CODE (operands[1]) == REG
+       && REGNO (operands[0]) == REGNO (operands[1]) + 1)
+     reversed = true;
+ 
+   fixup[0] = ia64_split_tmode (in, operands[1], reversed, dead);
+   fixup[1] = ia64_split_tmode (out, operands[0], reversed, dead);
+ 
+ #define MAYBE_ADD_REG_INC_NOTE(INSN, EXP)				\
+   if (GET_CODE (EXP) == MEM						\
+       && (GET_CODE (XEXP (EXP, 0)) == POST_MODIFY			\
+ 	  || GET_CODE (XEXP (EXP, 0)) == POST_INC			\
+ 	  || GET_CODE (XEXP (EXP, 0)) == POST_DEC))			\
+     add_reg_note (insn, REG_INC, XEXP (XEXP (EXP, 0), 0))
+ 
+   insn = emit_insn (gen_rtx_SET (out[0], in[0]));
+   MAYBE_ADD_REG_INC_NOTE (insn, in[0]);
+   MAYBE_ADD_REG_INC_NOTE (insn, out[0]);
+ 
+   insn = emit_insn (gen_rtx_SET (out[1], in[1]));
+   MAYBE_ADD_REG_INC_NOTE (insn, in[1]);
+   MAYBE_ADD_REG_INC_NOTE (insn, out[1]);
+ 
+   if (fixup[0])
+     emit_insn (fixup[0]);
+   if (fixup[1])
+     emit_insn (fixup[1]);
+ 
+ #undef MAYBE_ADD_REG_INC_NOTE
+ }
+ 
+ /* ??? Fixing GR->FR XFmode moves during reload is hard.  You need to go
+    through memory plus an extra GR scratch register.  Except that you can
+    either get the first from TARGET_SECONDARY_MEMORY_NEEDED or the second
+    from SECONDARY_RELOAD_CLASS, but not both.
+ 
+    We got into problems in the first place by allowing a construct like
+    (subreg:XF (reg:TI)), which we got from a union containing a long double.
+    This solution attempts to prevent this situation from occurring.  When
+    we see something like the above, we spill the inner register to memory.  */
+ 
+ static rtx
+ spill_xfmode_rfmode_operand (rtx in, int force, machine_mode mode)
+ {
+   if (GET_CODE (in) == SUBREG
+       && GET_MODE (SUBREG_REG (in)) == TImode
+       && GET_CODE (SUBREG_REG (in)) == REG)
+     {
+       rtx memt = assign_stack_temp (TImode, 16);
+       emit_move_insn (memt, SUBREG_REG (in));
+       return adjust_address (memt, mode, 0);
+     }
+   else if (force && GET_CODE (in) == REG)
+     {
+       rtx memx = assign_stack_temp (mode, 16);
+       emit_move_insn (memx, in);
+       return memx;
+     }
+   else
+     return in;
+ }
+ 
+ /* Expand the movxf or movrf pattern (MODE says which) with the given
+    OPERANDS, returning true if the pattern should then invoke
+    DONE.  */
+ 
+ bool
+ ia64_expand_movxf_movrf (machine_mode mode, rtx operands[])
+ {
+   rtx op0 = operands[0];
+ 
+   if (GET_CODE (op0) == SUBREG)
+     op0 = SUBREG_REG (op0);
+ 
+   /* We must support XFmode loads into general registers for stdarg/vararg,
+      unprototyped calls, and a rare case where a long double is passed as
+      an argument after a float HFA fills the FP registers.  We split them into
+      DImode loads for convenience.  We also need to support XFmode stores
+      for the last case.  This case does not happen for stdarg/vararg routines,
+      because we do a block store to memory of unnamed arguments.  */
+ 
+   if (GET_CODE (op0) == REG && GR_REGNO_P (REGNO (op0)))
+     {
+       rtx out[2];
+ 
+       /* We're hoping to transform everything that deals with XFmode
+ 	 quantities and GR registers early in the compiler.  */
+       gcc_assert (can_create_pseudo_p ());
+ 
+       /* Struct to register can just use TImode instead.  */
+       if ((GET_CODE (operands[1]) == SUBREG
+ 	   && GET_MODE (SUBREG_REG (operands[1])) == TImode)
+ 	  || (GET_CODE (operands[1]) == REG
+ 	      && GR_REGNO_P (REGNO (operands[1]))))
+ 	{
+ 	  rtx op1 = operands[1];
+ 
+ 	  if (GET_CODE (op1) == SUBREG)
+ 	    op1 = SUBREG_REG (op1);
+ 	  else
+ 	    op1 = gen_rtx_REG (TImode, REGNO (op1));
+ 
+ 	  emit_move_insn (gen_rtx_REG (TImode, REGNO (op0)), op1);
+ 	  return true;
+ 	}
+ 
+       if (GET_CODE (operands[1]) == CONST_DOUBLE)
+ 	{
+ 	  /* Don't word-swap when reading in the constant.  */
+ 	  emit_move_insn (gen_rtx_REG (DImode, REGNO (op0)),
+ 			  operand_subword (operands[1], WORDS_BIG_ENDIAN,
+ 					   0, mode));
+ 	  emit_move_insn (gen_rtx_REG (DImode, REGNO (op0) + 1),
+ 			  operand_subword (operands[1], !WORDS_BIG_ENDIAN,
+ 					   0, mode));
+ 	  return true;
+ 	}
+ 
+       /* If the quantity is in a register not known to be GR, spill it.  */
+       if (register_operand (operands[1], mode))
+ 	operands[1] = spill_xfmode_rfmode_operand (operands[1], 1, mode);
+ 
+       gcc_assert (GET_CODE (operands[1]) == MEM);
+ 
+       /* Don't word-swap when reading in the value.  */
+       out[0] = gen_rtx_REG (DImode, REGNO (op0));
+       out[1] = gen_rtx_REG (DImode, REGNO (op0) + 1);
+ 
+       emit_move_insn (out[0], adjust_address (operands[1], DImode, 0));
+       emit_move_insn (out[1], adjust_address (operands[1], DImode, 8));
+       return true;
+     }
+ 
+   if (GET_CODE (operands[1]) == REG && GR_REGNO_P (REGNO (operands[1])))
+     {
+       /* We're hoping to transform everything that deals with XFmode
+ 	 quantities and GR registers early in the compiler.  */
+       gcc_assert (can_create_pseudo_p ());
+ 
+       /* Op0 can't be a GR_REG here, as that case is handled above.
+ 	 If op0 is a register, then we spill op1, so that we now have a
+ 	 MEM operand.  This requires creating an XFmode subreg of a TImode reg
+ 	 to force the spill.  */
+       if (register_operand (operands[0], mode))
+ 	{
+ 	  rtx op1 = gen_rtx_REG (TImode, REGNO (operands[1]));
+ 	  op1 = gen_rtx_SUBREG (mode, op1, 0);
+ 	  operands[1] = spill_xfmode_rfmode_operand (op1, 0, mode);
+ 	}
+ 
+       else
+ 	{
+ 	  rtx in[2];
+ 
+ 	  gcc_assert (GET_CODE (operands[0]) == MEM);
+ 
+ 	  /* Don't word-swap when writing out the value.  */
+ 	  in[0] = gen_rtx_REG (DImode, REGNO (operands[1]));
+ 	  in[1] = gen_rtx_REG (DImode, REGNO (operands[1]) + 1);
+ 
+ 	  emit_move_insn (adjust_address (operands[0], DImode, 0), in[0]);
+ 	  emit_move_insn (adjust_address (operands[0], DImode, 8), in[1]);
+ 	  return true;
+ 	}
+     }
+ 
+   if (!reload_in_progress && !reload_completed)
+     {
+       operands[1] = spill_xfmode_rfmode_operand (operands[1], 0, mode);
+ 
+       if (GET_MODE (op0) == TImode && GET_CODE (op0) == REG)
+ 	{
+ 	  rtx memt, memx, in = operands[1];
+ 	  if (CONSTANT_P (in))
+ 	    in = validize_mem (force_const_mem (mode, in));
+ 	  if (GET_CODE (in) == MEM)
+ 	    memt = adjust_address (in, TImode, 0);
+ 	  else
+ 	    {
+ 	      memt = assign_stack_temp (TImode, 16);
+ 	      memx = adjust_address (memt, mode, 0);
+ 	      emit_move_insn (memx, in);
+ 	    }
+ 	  emit_move_insn (op0, memt);
+ 	  return true;
+ 	}
+ 
+       if (!ia64_move_ok (operands[0], operands[1]))
+ 	operands[1] = force_reg (mode, operands[1]);
+     }
+ 
+   return false;
+ }
+ 
+ /* Emit comparison instruction if necessary, replacing *EXPR, *OP0, *OP1
+    with the expression that holds the compare result (in VOIDmode).  */
+ 
+ static GTY(()) rtx cmptf_libfunc;
+ 
+ void
+ ia64_expand_compare (rtx *expr, rtx *op0, rtx *op1)
+ {
+   enum rtx_code code = GET_CODE (*expr);
+   rtx cmp;
+ 
+   /* If we have a BImode input, then we already have a compare result, and
+      do not need to emit another comparison.  */
+   if (GET_MODE (*op0) == BImode)
+     {
+       gcc_assert ((code == NE || code == EQ) && *op1 == const0_rtx);
+       cmp = *op0;
+     }
+   /* HPUX TFmode compare requires a library call to _U_Qfcmp, which takes a
+      magic number as its third argument, that indicates what to do.
+      The return value is an integer to be compared against zero.  */
+   else if (TARGET_HPUX && GET_MODE (*op0) == TFmode)
+     {
+       enum qfcmp_magic {
+ 	QCMP_INV = 1,	/* Raise FP_INVALID on NaNs as a side effect.  */
+ 	QCMP_UNORD = 2,
+ 	QCMP_EQ = 4,
+ 	QCMP_LT = 8,
+ 	QCMP_GT = 16
+       };
+       int magic;
+       enum rtx_code ncode;
+       rtx ret;
+       
+       gcc_assert (cmptf_libfunc && GET_MODE (*op1) == TFmode);
+       switch (code)
+ 	{
+ 	  /* 1 = equal, 0 = not equal.  Equality operators do
+ 	     not raise FP_INVALID when given a NaN operand.  */
+ 	case EQ:        magic = QCMP_EQ;                  ncode = NE; break;
+ 	case NE:        magic = QCMP_EQ;                  ncode = EQ; break;
+ 	  /* isunordered() from C99.  */
+ 	case UNORDERED: magic = QCMP_UNORD;               ncode = NE; break;
+ 	case ORDERED:   magic = QCMP_UNORD;               ncode = EQ; break;
+ 	  /* Relational operators raise FP_INVALID when given
+ 	     a NaN operand.  */
+ 	case LT:        magic = QCMP_LT        |QCMP_INV; ncode = NE; break;
+ 	case LE:        magic = QCMP_LT|QCMP_EQ|QCMP_INV; ncode = NE; break;
+ 	case GT:        magic = QCMP_GT        |QCMP_INV; ncode = NE; break;
+ 	case GE:        magic = QCMP_GT|QCMP_EQ|QCMP_INV; ncode = NE; break;
+           /* Unordered relational operators do not raise FP_INVALID
+ 	     when given a NaN operand.  */
+ 	case UNLT:    magic = QCMP_LT        |QCMP_UNORD; ncode = NE; break;
+ 	case UNLE:    magic = QCMP_LT|QCMP_EQ|QCMP_UNORD; ncode = NE; break;
+ 	case UNGT:    magic = QCMP_GT        |QCMP_UNORD; ncode = NE; break;
+ 	case UNGE:    magic = QCMP_GT|QCMP_EQ|QCMP_UNORD; ncode = NE; break;
+ 	  /* Not supported.  */
+ 	case UNEQ:
+ 	case LTGT:
+ 	default: gcc_unreachable ();
+ 	}
+ 
+       start_sequence ();
+ 
+       ret = emit_library_call_value (cmptf_libfunc, 0, LCT_CONST, DImode,
+ 				     *op0, TFmode, *op1, TFmode,
+ 				     GEN_INT (magic), DImode);
+       cmp = gen_reg_rtx (BImode);
+       emit_insn (gen_rtx_SET (cmp, gen_rtx_fmt_ee (ncode, BImode,
+ 						   ret, const0_rtx)));
+ 
+       rtx_insn *insns = get_insns ();
+       end_sequence ();
+ 
+       emit_libcall_block (insns, cmp, cmp,
+ 			  gen_rtx_fmt_ee (code, BImode, *op0, *op1));
+       code = NE;
+     }
+   else
+     {
+       cmp = gen_reg_rtx (BImode);
+       emit_insn (gen_rtx_SET (cmp, gen_rtx_fmt_ee (code, BImode, *op0, *op1)));
+       code = NE;
+     }
+ 
+   *expr = gen_rtx_fmt_ee (code, VOIDmode, cmp, const0_rtx);
+   *op0 = cmp;
+   *op1 = const0_rtx;
+ }
+ 
+ /* Generate an integral vector comparison.  Return true if the condition has
+    been reversed, and so the sense of the comparison should be inverted.  */
+ 
+ static bool
+ ia64_expand_vecint_compare (enum rtx_code code, machine_mode mode,
+ 			    rtx dest, rtx op0, rtx op1)
+ {
+   bool negate = false;
+   rtx x;
+ 
+   /* Canonicalize the comparison to EQ, GT, GTU.  */
+   switch (code)
+     {
+     case EQ:
+     case GT:
+     case GTU:
+       break;
+ 
+     case NE:
+     case LE:
+     case LEU:
+       code = reverse_condition (code);
+       negate = true;
+       break;
+ 
+     case GE:
+     case GEU:
+       code = reverse_condition (code);
+       negate = true;
+       /* FALLTHRU */
+ 
+     case LT:
+     case LTU:
+       code = swap_condition (code);
+       x = op0, op0 = op1, op1 = x;
+       break;
+ 
+     default:
+       gcc_unreachable ();
+     }
+ 
+   /* Unsigned parallel compare is not supported by the hardware.  Play some
+      tricks to turn this into a signed comparison against 0.  */
+   if (code == GTU)
+     {
+       switch (mode)
+ 	{
+ 	case E_V2SImode:
+ 	  {
+ 	    rtx t1, t2, mask;
+ 
+ 	    /* Subtract (-(INT MAX) - 1) from both operands to make
+ 	       them signed.  */
+ 	    mask = gen_int_mode (0x80000000, SImode);
+ 	    mask = gen_const_vec_duplicate (V2SImode, mask);
+ 	    mask = force_reg (mode, mask);
+ 	    t1 = gen_reg_rtx (mode);
+ 	    emit_insn (gen_subv2si3 (t1, op0, mask));
+ 	    t2 = gen_reg_rtx (mode);
+ 	    emit_insn (gen_subv2si3 (t2, op1, mask));
+ 	    op0 = t1;
+ 	    op1 = t2;
+ 	    code = GT;
+ 	  }
+ 	  break;
+ 
+ 	case E_V8QImode:
+ 	case E_V4HImode:
+ 	  /* Perform a parallel unsigned saturating subtraction.  */
+ 	  x = gen_reg_rtx (mode);
+ 	  emit_insn (gen_rtx_SET (x, gen_rtx_US_MINUS (mode, op0, op1)));
+ 
+ 	  code = EQ;
+ 	  op0 = x;
+ 	  op1 = CONST0_RTX (mode);
+ 	  negate = !negate;
+ 	  break;
+ 
+ 	default:
+ 	  gcc_unreachable ();
+ 	}
+     }
+ 
+   x = gen_rtx_fmt_ee (code, mode, op0, op1);
+   emit_insn (gen_rtx_SET (dest, x));
+ 
+   return negate;
+ }
+ 
+ /* Emit an integral vector conditional move.  */
+ 
+ void
+ ia64_expand_vecint_cmov (rtx operands[])
+ {
+   machine_mode mode = GET_MODE (operands[0]);
+   enum rtx_code code = GET_CODE (operands[3]);
+   bool negate;
+   rtx cmp, x, ot, of;
+ 
+   cmp = gen_reg_rtx (mode);
+   negate = ia64_expand_vecint_compare (code, mode, cmp,
+ 				       operands[4], operands[5]);
+ 
+   ot = operands[1+negate];
+   of = operands[2-negate];
+ 
+   if (ot == CONST0_RTX (mode))
+     {
+       if (of == CONST0_RTX (mode))
+ 	{
+ 	  emit_move_insn (operands[0], ot);
+ 	  return;
+ 	}
+ 
+       x = gen_rtx_NOT (mode, cmp);
+       x = gen_rtx_AND (mode, x, of);
+       emit_insn (gen_rtx_SET (operands[0], x));
+     }
+   else if (of == CONST0_RTX (mode))
+     {
+       x = gen_rtx_AND (mode, cmp, ot);
+       emit_insn (gen_rtx_SET (operands[0], x));
+     }
+   else
+     {
+       rtx t, f;
+ 
+       t = gen_reg_rtx (mode);
+       x = gen_rtx_AND (mode, cmp, operands[1+negate]);
+       emit_insn (gen_rtx_SET (t, x));
+ 
+       f = gen_reg_rtx (mode);
+       x = gen_rtx_NOT (mode, cmp);
+       x = gen_rtx_AND (mode, x, operands[2-negate]);
+       emit_insn (gen_rtx_SET (f, x));
+ 
+       x = gen_rtx_IOR (mode, t, f);
+       emit_insn (gen_rtx_SET (operands[0], x));
+     }
+ }
+ 
+ /* Emit an integral vector min or max operation.  Return true if all done.  */
+ 
+ bool
+ ia64_expand_vecint_minmax (enum rtx_code code, machine_mode mode,
+ 			   rtx operands[])
+ {
+   rtx xops[6];
+ 
+   /* These four combinations are supported directly.  */
+   if (mode == V8QImode && (code == UMIN || code == UMAX))
+     return false;
+   if (mode == V4HImode && (code == SMIN || code == SMAX))
+     return false;
+ 
+   /* This combination can be implemented with only saturating subtraction.  */
+   if (mode == V4HImode && code == UMAX)
+     {
+       rtx x, tmp = gen_reg_rtx (mode);
+ 
+       x = gen_rtx_US_MINUS (mode, operands[1], operands[2]);
+       emit_insn (gen_rtx_SET (tmp, x));
+ 
+       emit_insn (gen_addv4hi3 (operands[0], tmp, operands[2]));
+       return true;
+     }
+ 
+   /* Everything else implemented via vector comparisons.  */
+   xops[0] = operands[0];
+   xops[4] = xops[1] = operands[1];
+   xops[5] = xops[2] = operands[2];
+ 
+   switch (code)
+     {
+     case UMIN:
+       code = LTU;
+       break;
+     case UMAX:
+       code = GTU;
+       break;
+     case SMIN:
+       code = LT;
+       break;
+     case SMAX:
+       code = GT;
+       break;
+     default:
+       gcc_unreachable ();
+     }
+   xops[3] = gen_rtx_fmt_ee (code, VOIDmode, operands[1], operands[2]);
+ 
+   ia64_expand_vecint_cmov (xops);
+   return true;
+ }
+ 
+ /* The vectors LO and HI each contain N halves of a double-wide vector.
+    Reassemble either the first N/2 or the second N/2 elements.  */
+ 
+ void
+ ia64_unpack_assemble (rtx out, rtx lo, rtx hi, bool highp)
+ {
+   machine_mode vmode = GET_MODE (lo);
+   unsigned int i, high, nelt = GET_MODE_NUNITS (vmode);
+   struct expand_vec_perm_d d;
+   bool ok;
+ 
+   d.target = gen_lowpart (vmode, out);
+   d.op0 = (TARGET_BIG_ENDIAN ? hi : lo);
+   d.op1 = (TARGET_BIG_ENDIAN ? lo : hi);
+   d.vmode = vmode;
+   d.nelt = nelt;
+   d.one_operand_p = false;
+   d.testing_p = false;
+ 
+   high = (highp ? nelt / 2 : 0);
+   for (i = 0; i < nelt / 2; ++i)
+     {
+       d.perm[i * 2] = i + high;
+       d.perm[i * 2 + 1] = i + high + nelt;
+     }
+ 
+   ok = ia64_expand_vec_perm_const_1 (&d);
+   gcc_assert (ok);
+ }
+ 
+ /* Return a vector of the sign-extension of VEC.  */
+ 
+ static rtx
+ ia64_unpack_sign (rtx vec, bool unsignedp)
+ {
+   machine_mode mode = GET_MODE (vec);
+   rtx zero = CONST0_RTX (mode);
+ 
+   if (unsignedp)
+     return zero;
+   else
+     {
+       rtx sign = gen_reg_rtx (mode);
+       bool neg;
+ 
+       neg = ia64_expand_vecint_compare (LT, mode, sign, vec, zero);
+       gcc_assert (!neg);
+ 
+       return sign;
+     }
+ }
+ 
+ /* Emit an integral vector unpack operation.  */
+ 
+ void
+ ia64_expand_unpack (rtx operands[3], bool unsignedp, bool highp)
+ {
+   rtx sign = ia64_unpack_sign (operands[1], unsignedp);
+   ia64_unpack_assemble (operands[0], operands[1], sign, highp);
+ }
+ 
+ /* Emit an integral vector widening sum operations.  */
+ 
+ void
+ ia64_expand_widen_sum (rtx operands[3], bool unsignedp)
+ {
+   machine_mode wmode;
+   rtx l, h, t, sign;
+ 
+   sign = ia64_unpack_sign (operands[1], unsignedp);
+ 
+   wmode = GET_MODE (operands[0]);
+   l = gen_reg_rtx (wmode);
+   h = gen_reg_rtx (wmode);
+ 
+   ia64_unpack_assemble (l, operands[1], sign, false);
+   ia64_unpack_assemble (h, operands[1], sign, true);
+ 
+   t = expand_binop (wmode, add_optab, l, operands[2], NULL, 0, OPTAB_DIRECT);
+   t = expand_binop (wmode, add_optab, h, t, operands[0], 0, OPTAB_DIRECT);
+   if (t != operands[0])
+     emit_move_insn (operands[0], t);
+ }
+ 
+ /* Emit the appropriate sequence for a call.  */
+ 
+ void
+ ia64_expand_call (rtx retval, rtx addr, rtx nextarg ATTRIBUTE_UNUSED,
+ 		  int sibcall_p)
+ {
+   rtx insn, b0;
+ 
+   addr = XEXP (addr, 0);
+   addr = convert_memory_address (DImode, addr);
+   b0 = gen_rtx_REG (DImode, R_BR (0));
+ 
+   /* ??? Should do this for functions known to bind local too.  */
+   if (TARGET_NO_PIC || TARGET_AUTO_PIC)
+     {
+       if (sibcall_p)
+ 	insn = gen_sibcall_nogp (addr);
+       else if (! retval)
+ 	insn = gen_call_nogp (addr, b0);
+       else
+ 	insn = gen_call_value_nogp (retval, addr, b0);
+       insn = emit_call_insn (insn);
+     }
+   else
+     {
+       if (sibcall_p)
+ 	insn = gen_sibcall_gp (addr);
+       else if (! retval)
+ 	insn = gen_call_gp (addr, b0);
+       else
+ 	insn = gen_call_value_gp (retval, addr, b0);
+       insn = emit_call_insn (insn);
+ 
+       use_reg (&CALL_INSN_FUNCTION_USAGE (insn), pic_offset_table_rtx);
+     }
+ 
+   if (sibcall_p)
+     use_reg (&CALL_INSN_FUNCTION_USAGE (insn), b0);
+ 
+   if (TARGET_ABI_OPEN_VMS)
+     use_reg (&CALL_INSN_FUNCTION_USAGE (insn),
+ 	     gen_rtx_REG (DImode, GR_REG (25)));
+ }
+ 
+ static void
+ reg_emitted (enum ia64_frame_regs r)
+ {
+   if (emitted_frame_related_regs[r] == 0)
+     emitted_frame_related_regs[r] = current_frame_info.r[r];
+   else
+     gcc_assert (emitted_frame_related_regs[r] == current_frame_info.r[r]);
+ }
+ 
+ static int
+ get_reg (enum ia64_frame_regs r)
+ {
+   reg_emitted (r);
+   return current_frame_info.r[r];
+ }
+ 
+ static bool
+ is_emitted (int regno)
+ {
+   unsigned int r;
+ 
+   for (r = reg_fp; r < number_of_ia64_frame_regs; r++)
+     if (emitted_frame_related_regs[r] == regno)
+       return true;
+   return false;
+ }
+ 
+ void
+ ia64_reload_gp (void)
+ {
+   rtx tmp;
+ 
+   if (current_frame_info.r[reg_save_gp])
+     {
+       tmp = gen_rtx_REG (DImode, get_reg (reg_save_gp));
+     }
+   else
+     {
+       HOST_WIDE_INT offset;
+       rtx offset_r;
+ 
+       offset = (current_frame_info.spill_cfa_off
+ 	        + current_frame_info.spill_size);
+       if (frame_pointer_needed)
+         {
+           tmp = hard_frame_pointer_rtx;
+           offset = -offset;
+         }
+       else
+         {
+           tmp = stack_pointer_rtx;
+           offset = current_frame_info.total_size - offset;
+         }
+ 
+       offset_r = GEN_INT (offset);
+       if (satisfies_constraint_I (offset_r))
+         emit_insn (gen_adddi3 (pic_offset_table_rtx, tmp, offset_r));
+       else
+         {
+           emit_move_insn (pic_offset_table_rtx, offset_r);
+           emit_insn (gen_adddi3 (pic_offset_table_rtx,
+ 			         pic_offset_table_rtx, tmp));
+         }
+ 
+       tmp = gen_rtx_MEM (DImode, pic_offset_table_rtx);
+     }
+ 
+   emit_move_insn (pic_offset_table_rtx, tmp);
+ }
+ 
+ void
+ ia64_split_call (rtx retval, rtx addr, rtx retaddr, rtx scratch_r,
+ 		 rtx scratch_b, int noreturn_p, int sibcall_p)
+ {
+   rtx insn;
+   bool is_desc = false;
+ 
+   /* If we find we're calling through a register, then we're actually
+      calling through a descriptor, so load up the values.  */
+   if (REG_P (addr) && GR_REGNO_P (REGNO (addr)))
+     {
+       rtx tmp;
+       bool addr_dead_p;
+ 
+       /* ??? We are currently constrained to *not* use peep2, because
+ 	 we can legitimately change the global lifetime of the GP
+ 	 (in the form of killing where previously live).  This is
+ 	 because a call through a descriptor doesn't use the previous
+ 	 value of the GP, while a direct call does, and we do not
+ 	 commit to either form until the split here.
+ 
+ 	 That said, this means that we lack precise life info for
+ 	 whether ADDR is dead after this call.  This is not terribly
+ 	 important, since we can fix things up essentially for free
+ 	 with the POST_DEC below, but it's nice to not use it when we
+ 	 can immediately tell it's not necessary.  */
+       addr_dead_p = ((noreturn_p || sibcall_p
+ 		      || TEST_HARD_REG_BIT (regs_invalidated_by_call,
+ 					    REGNO (addr)))
+ 		     && !FUNCTION_ARG_REGNO_P (REGNO (addr)));
+ 
+       /* Load the code address into scratch_b.  */
+       tmp = gen_rtx_POST_INC (Pmode, addr);
+       tmp = gen_rtx_MEM (Pmode, tmp);
+       emit_move_insn (scratch_r, tmp);
+       emit_move_insn (scratch_b, scratch_r);
+ 
+       /* Load the GP address.  If ADDR is not dead here, then we must
+ 	 revert the change made above via the POST_INCREMENT.  */
+       if (!addr_dead_p)
+ 	tmp = gen_rtx_POST_DEC (Pmode, addr);
+       else
+ 	tmp = addr;
+       tmp = gen_rtx_MEM (Pmode, tmp);
+       emit_move_insn (pic_offset_table_rtx, tmp);
+ 
+       is_desc = true;
+       addr = scratch_b;
+     }
+ 
+   if (sibcall_p)
+     insn = gen_sibcall_nogp (addr);
+   else if (retval)
+     insn = gen_call_value_nogp (retval, addr, retaddr);
+   else
+     insn = gen_call_nogp (addr, retaddr);
+   emit_call_insn (insn);
+ 
+   if ((!TARGET_CONST_GP || is_desc) && !noreturn_p && !sibcall_p)
+     ia64_reload_gp ();
+ }
+ 
+ /* Expand an atomic operation.  We want to perform MEM <CODE>= VAL atomically.
+ 
+    This differs from the generic code in that we know about the zero-extending
+    properties of cmpxchg, and the zero-extending requirements of ar.ccv.  We
+    also know that ld.acq+cmpxchg.rel equals a full barrier.
+ 
+    The loop we want to generate looks like
+ 
+ 	cmp_reg = mem;
+       label:
+         old_reg = cmp_reg;
+ 	new_reg = cmp_reg op val;
+ 	cmp_reg = compare-and-swap(mem, old_reg, new_reg)
+ 	if (cmp_reg != old_reg)
+ 	  goto label;
+ 
+    Note that we only do the plain load from memory once.  Subsequent
+    iterations use the value loaded by the compare-and-swap pattern.  */
+ 
+ void
+ ia64_expand_atomic_op (enum rtx_code code, rtx mem, rtx val,
+ 		       rtx old_dst, rtx new_dst, enum memmodel model)
+ {
+   machine_mode mode = GET_MODE (mem);
+   rtx old_reg, new_reg, cmp_reg, ar_ccv, label;
+   enum insn_code icode;
+ 
+   /* Special case for using fetchadd.  */
+   if ((mode == SImode || mode == DImode)
+       && (code == PLUS || code == MINUS)
+       && fetchadd_operand (val, mode))
+     {
+       if (code == MINUS)
+ 	val = GEN_INT (-INTVAL (val));
+ 
+       if (!old_dst)
+         old_dst = gen_reg_rtx (mode);
+ 
+       switch (model)
+ 	{
+ 	case MEMMODEL_ACQ_REL:
+ 	case MEMMODEL_SEQ_CST:
+ 	case MEMMODEL_SYNC_SEQ_CST:
+ 	  emit_insn (gen_memory_barrier ());
+ 	  /* FALLTHRU */
+ 	case MEMMODEL_RELAXED:
+ 	case MEMMODEL_ACQUIRE:
+ 	case MEMMODEL_SYNC_ACQUIRE:
+ 	case MEMMODEL_CONSUME:
+ 	  if (mode == SImode)
+ 	    icode = CODE_FOR_fetchadd_acq_si;
+ 	  else
+ 	    icode = CODE_FOR_fetchadd_acq_di;
+ 	  break;
+ 	case MEMMODEL_RELEASE:
+ 	case MEMMODEL_SYNC_RELEASE:
+ 	  if (mode == SImode)
+ 	    icode = CODE_FOR_fetchadd_rel_si;
+ 	  else
+ 	    icode = CODE_FOR_fetchadd_rel_di;
+ 	  break;
+ 
+ 	default:
+ 	  gcc_unreachable ();
+ 	}
+ 
+       emit_insn (GEN_FCN (icode) (old_dst, mem, val));
+ 
+       if (new_dst)
+ 	{
+ 	  new_reg = expand_simple_binop (mode, PLUS, old_dst, val, new_dst,
+ 					 true, OPTAB_WIDEN);
+ 	  if (new_reg != new_dst)
+ 	    emit_move_insn (new_dst, new_reg);
+ 	}
+       return;
+     }
+ 
+   /* Because of the volatile mem read, we get an ld.acq, which is the
+      front half of the full barrier.  The end half is the cmpxchg.rel.
+      For relaxed and release memory models, we don't need this.  But we
+      also don't bother trying to prevent it either.  */
+   gcc_assert (is_mm_relaxed (model) || is_mm_release (model)
+ 	      || MEM_VOLATILE_P (mem));
+ 
+   old_reg = gen_reg_rtx (DImode);
+   cmp_reg = gen_reg_rtx (DImode);
+   label = gen_label_rtx ();
+ 
+   if (mode != DImode)
+     {
+       val = simplify_gen_subreg (DImode, val, mode, 0);
+       emit_insn (gen_extend_insn (cmp_reg, mem, DImode, mode, 1));
+     }
+   else
+     emit_move_insn (cmp_reg, mem);
+ 
+   emit_label (label);
+ 
+   ar_ccv = gen_rtx_REG (DImode, AR_CCV_REGNUM);
+   emit_move_insn (old_reg, cmp_reg);
+   emit_move_insn (ar_ccv, cmp_reg);
+ 
+   if (old_dst)
+     emit_move_insn (old_dst, gen_lowpart (mode, cmp_reg));
+ 
+   new_reg = cmp_reg;
+   if (code == NOT)
+     {
+       new_reg = expand_simple_binop (DImode, AND, new_reg, val, NULL_RTX,
+ 				     true, OPTAB_DIRECT);
+       new_reg = expand_simple_unop (DImode, code, new_reg, NULL_RTX, true);
+     }
+   else
+     new_reg = expand_simple_binop (DImode, code, new_reg, val, NULL_RTX,
+ 				   true, OPTAB_DIRECT);
+ 
+   if (mode != DImode)
+     new_reg = gen_lowpart (mode, new_reg);
+   if (new_dst)
+     emit_move_insn (new_dst, new_reg);
+ 
+   switch (model)
+     {
+     case MEMMODEL_RELAXED:
+     case MEMMODEL_ACQUIRE:
+     case MEMMODEL_SYNC_ACQUIRE:
+     case MEMMODEL_CONSUME:
+       switch (mode)
+ 	{
+ 	case E_QImode: icode = CODE_FOR_cmpxchg_acq_qi;  break;
+ 	case E_HImode: icode = CODE_FOR_cmpxchg_acq_hi;  break;
+ 	case E_SImode: icode = CODE_FOR_cmpxchg_acq_si;  break;
+ 	case E_DImode: icode = CODE_FOR_cmpxchg_acq_di;  break;
+ 	default:
+ 	  gcc_unreachable ();
+ 	}
+       break;
+ 
+     case MEMMODEL_RELEASE:
+     case MEMMODEL_SYNC_RELEASE:
+     case MEMMODEL_ACQ_REL:
+     case MEMMODEL_SEQ_CST:
+     case MEMMODEL_SYNC_SEQ_CST:
+       switch (mode)
+ 	{
+ 	case E_QImode: icode = CODE_FOR_cmpxchg_rel_qi;  break;
+ 	case E_HImode: icode = CODE_FOR_cmpxchg_rel_hi;  break;
+ 	case E_SImode: icode = CODE_FOR_cmpxchg_rel_si;  break;
+ 	case E_DImode: icode = CODE_FOR_cmpxchg_rel_di;  break;
+ 	default:
+ 	  gcc_unreachable ();
+ 	}
+       break;
+ 
+     default:
+       gcc_unreachable ();
+     }
+ 
+   emit_insn (GEN_FCN (icode) (cmp_reg, mem, ar_ccv, new_reg));
+ 
+   emit_cmp_and_jump_insns (cmp_reg, old_reg, NE, NULL, DImode, true, label);
+ }
+ \f
+ /* Begin the assembly file.  */
+ 
+ static void
+ ia64_file_start (void)
+ {
+   default_file_start ();
+   emit_safe_across_calls ();
+ }
+ 
+ void
+ emit_safe_across_calls (void)
+ {
+   unsigned int rs, re;
+   int out_state;
+ 
+   rs = 1;
+   out_state = 0;
+   while (1)
+     {
+       while (rs < 64 && call_used_or_fixed_reg_p (PR_REG (rs)))
+ 	rs++;
+       if (rs >= 64)
+ 	break;
+       for (re = rs + 1;
+ 	   re < 64 && ! call_used_or_fixed_reg_p (PR_REG (re)); re++)
+ 	continue;
+       if (out_state == 0)
+ 	{
+ 	  fputs ("\t.pred.safe_across_calls ", asm_out_file);
+ 	  out_state = 1;
+ 	}
+       else
+ 	fputc (',', asm_out_file);
+       if (re == rs + 1)
+ 	fprintf (asm_out_file, "p%u", rs);
+       else
+ 	fprintf (asm_out_file, "p%u-p%u", rs, re - 1);
+       rs = re + 1;
+     }
+   if (out_state)
+     fputc ('\n', asm_out_file);
+ }
+ 
+ /* Globalize a declaration.  */
+ 
+ static void
+ ia64_globalize_decl_name (FILE * stream, tree decl)
+ {
+   const char *name = XSTR (XEXP (DECL_RTL (decl), 0), 0);
+   tree version_attr = lookup_attribute ("version_id", DECL_ATTRIBUTES (decl));
+   if (version_attr)
+     {
+       tree v = TREE_VALUE (TREE_VALUE (version_attr));
+       const char *p = TREE_STRING_POINTER (v);
+       fprintf (stream, "\t.alias %s#, \"%s{%s}\"\n", name, name, p);
+     }
+   targetm.asm_out.globalize_label (stream, name);
+   if (TREE_CODE (decl) == FUNCTION_DECL)
+     ASM_OUTPUT_TYPE_DIRECTIVE (stream, name, "function");
+ }
+ 
+ /* Helper function for ia64_compute_frame_size: find an appropriate general
+    register to spill some special register to.  SPECIAL_SPILL_MASK contains
+    bits in GR0 to GR31 that have already been allocated by this routine.
+    TRY_LOCALS is true if we should attempt to locate a local regnum.  */
+ 
+ static int
+ find_gr_spill (enum ia64_frame_regs r, int try_locals)
+ {
+   int regno;
+ 
+   if (emitted_frame_related_regs[r] != 0)
+     {
+       regno = emitted_frame_related_regs[r];
+       if (regno >= LOC_REG (0) && regno < LOC_REG (80 - frame_pointer_needed)
+ 	  && current_frame_info.n_local_regs < regno - LOC_REG (0) + 1)
+         current_frame_info.n_local_regs = regno - LOC_REG (0) + 1;
+       else if (crtl->is_leaf
+                && regno >= GR_REG (1) && regno <= GR_REG (31))
+         current_frame_info.gr_used_mask |= 1 << regno;
+ 
+       return regno;
+     }
+ 
+   /* If this is a leaf function, first try an otherwise unused
+      call-clobbered register.  */
+   if (crtl->is_leaf)
+     {
+       for (regno = GR_REG (1); regno <= GR_REG (31); regno++)
+ 	if (! df_regs_ever_live_p (regno)
+ 	    && call_used_or_fixed_reg_p (regno)
+ 	    && ! fixed_regs[regno]
+ 	    && ! global_regs[regno]
+ 	    && ((current_frame_info.gr_used_mask >> regno) & 1) == 0
+             && ! is_emitted (regno))
+ 	  {
+ 	    current_frame_info.gr_used_mask |= 1 << regno;
+ 	    return regno;
+ 	  }
+     }
+ 
+   if (try_locals)
+     {
+       regno = current_frame_info.n_local_regs;
+       /* If there is a frame pointer, then we can't use loc79, because
+ 	 that is HARD_FRAME_POINTER_REGNUM.  In particular, see the
+ 	 reg_name switching code in ia64_expand_prologue.  */
+       while (regno < (80 - frame_pointer_needed))
+ 	if (! is_emitted (LOC_REG (regno++)))
+ 	  {
+ 	    current_frame_info.n_local_regs = regno;
+ 	    return LOC_REG (regno - 1);
+ 	  }
+     }
+ 
+   /* Failed to find a general register to spill to.  Must use stack.  */
+   return 0;
+ }
+ 
+ /* In order to make for nice schedules, we try to allocate every temporary
+    to a different register.  We must of course stay away from call-saved,
+    fixed, and global registers.  We must also stay away from registers
+    allocated in current_frame_info.gr_used_mask, since those include regs
+    used all through the prologue.
+ 
+    Any register allocated here must be used immediately.  The idea is to
+    aid scheduling, not to solve data flow problems.  */
+ 
+ static int last_scratch_gr_reg;
+ 
+ static int
+ next_scratch_gr_reg (void)
+ {
+   int i, regno;
+ 
+   for (i = 0; i < 32; ++i)
+     {
+       regno = (last_scratch_gr_reg + i + 1) & 31;
+       if (call_used_or_fixed_reg_p (regno)
+ 	  && ! fixed_regs[regno]
+ 	  && ! global_regs[regno]
+ 	  && ((current_frame_info.gr_used_mask >> regno) & 1) == 0)
+ 	{
+ 	  last_scratch_gr_reg = regno;
+ 	  return regno;
+ 	}
+     }
+ 
+   /* There must be _something_ available.  */
+   gcc_unreachable ();
+ }
+ 
+ /* Helper function for ia64_compute_frame_size, called through
+    diddle_return_value.  Mark REG in current_frame_info.gr_used_mask.  */
+ 
+ static void
+ mark_reg_gr_used_mask (rtx reg, void *data ATTRIBUTE_UNUSED)
+ {
+   unsigned int regno = REGNO (reg);
+   if (regno < 32)
+     {
+       unsigned int i, n = REG_NREGS (reg);
+       for (i = 0; i < n; ++i)
+ 	current_frame_info.gr_used_mask |= 1 << (regno + i);
+     }
+ }
+ 
+ 
+ /* Returns the number of bytes offset between the frame pointer and the stack
+    pointer for the current function.  SIZE is the number of bytes of space
+    needed for local variables.  */
+ 
+ static void
+ ia64_compute_frame_size (HOST_WIDE_INT size)
+ {
+   HOST_WIDE_INT total_size;
+   HOST_WIDE_INT spill_size = 0;
+   HOST_WIDE_INT extra_spill_size = 0;
+   HOST_WIDE_INT pretend_args_size;
+   HARD_REG_SET mask;
+   int n_spilled = 0;
+   int spilled_gr_p = 0;
+   int spilled_fr_p = 0;
+   unsigned int regno;
+   int min_regno;
+   int max_regno;
+   int i;
+ 
+   if (current_frame_info.initialized)
+     return;
+ 
+   memset (&current_frame_info, 0, sizeof current_frame_info);
+   CLEAR_HARD_REG_SET (mask);
+ 
+   /* Don't allocate scratches to the return register.  */
+   diddle_return_value (mark_reg_gr_used_mask, NULL);
+ 
+   /* Don't allocate scratches to the EH scratch registers.  */
+   if (cfun->machine->ia64_eh_epilogue_sp)
+     mark_reg_gr_used_mask (cfun->machine->ia64_eh_epilogue_sp, NULL);
+   if (cfun->machine->ia64_eh_epilogue_bsp)
+     mark_reg_gr_used_mask (cfun->machine->ia64_eh_epilogue_bsp, NULL);
+ 
+   /* Static stack checking uses r2 and r3.  */
+   if (flag_stack_check == STATIC_BUILTIN_STACK_CHECK
+       || flag_stack_clash_protection)
+     current_frame_info.gr_used_mask |= 0xc;
+ 
+   /* Find the size of the register stack frame.  We have only 80 local
+      registers, because we reserve 8 for the inputs and 8 for the
+      outputs.  */
+ 
+   /* Skip HARD_FRAME_POINTER_REGNUM (loc79) when frame_pointer_needed,
+      since we'll be adjusting that down later.  */
+   regno = LOC_REG (78) + ! frame_pointer_needed;
+   for (; regno >= LOC_REG (0); regno--)
+     if (df_regs_ever_live_p (regno) && !is_emitted (regno))
+       break;
+   current_frame_info.n_local_regs = regno - LOC_REG (0) + 1;
+ 
+   /* For functions marked with the syscall_linkage attribute, we must mark
+      all eight input registers as in use, so that locals aren't visible to
+      the caller.  */
+ 
+   if (cfun->machine->n_varargs > 0
+       || lookup_attribute ("syscall_linkage",
+ 			   TYPE_ATTRIBUTES (TREE_TYPE (current_function_decl))))
+     current_frame_info.n_input_regs = 8;
+   else
+     {
+       for (regno = IN_REG (7); regno >= IN_REG (0); regno--)
+ 	if (df_regs_ever_live_p (regno))
+ 	  break;
+       current_frame_info.n_input_regs = regno - IN_REG (0) + 1;
+     }
+ 
+   for (regno = OUT_REG (7); regno >= OUT_REG (0); regno--)
+     if (df_regs_ever_live_p (regno))
+       break;
+   i = regno - OUT_REG (0) + 1;
+ 
+ #ifndef PROFILE_HOOK
+   /* When -p profiling, we need one output register for the mcount argument.
+      Likewise for -a profiling for the bb_init_func argument.  For -ax
+      profiling, we need two output registers for the two bb_init_trace_func
+      arguments.  */
+   if (crtl->profile)
+     i = MAX (i, 1);
+ #endif
+   current_frame_info.n_output_regs = i;
+ 
+   /* ??? No rotating register support yet.  */
+   current_frame_info.n_rotate_regs = 0;
+ 
+   /* Discover which registers need spilling, and how much room that
+      will take.  Begin with floating point and general registers,
+      which will always wind up on the stack.  */
+ 
+   for (regno = FR_REG (2); regno <= FR_REG (127); regno++)
+     if (df_regs_ever_live_p (regno) && ! call_used_or_fixed_reg_p (regno))
+       {
+ 	SET_HARD_REG_BIT (mask, regno);
+ 	spill_size += 16;
+ 	n_spilled += 1;
+ 	spilled_fr_p = 1;
+       }
+ 
+   for (regno = GR_REG (1); regno <= GR_REG (31); regno++)
+     if (df_regs_ever_live_p (regno) && ! call_used_or_fixed_reg_p (regno))
+       {
+ 	SET_HARD_REG_BIT (mask, regno);
+ 	spill_size += 8;
+ 	n_spilled += 1;
+ 	spilled_gr_p = 1;
+       }
+ 
+   for (regno = BR_REG (1); regno <= BR_REG (7); regno++)
+     if (df_regs_ever_live_p (regno) && ! call_used_or_fixed_reg_p (regno))
+       {
+ 	SET_HARD_REG_BIT (mask, regno);
+ 	spill_size += 8;
+ 	n_spilled += 1;
+       }
+ 
+   /* Now come all special registers that might get saved in other
+      general registers.  */
+ 
+   if (frame_pointer_needed)
+     {
+       current_frame_info.r[reg_fp] = find_gr_spill (reg_fp, 1);
+       /* If we did not get a register, then we take LOC79.  This is guaranteed
+ 	 to be free, even if regs_ever_live is already set, because this is
+ 	 HARD_FRAME_POINTER_REGNUM.  This requires incrementing n_local_regs,
+ 	 as we don't count loc79 above.  */
+       if (current_frame_info.r[reg_fp] == 0)
+ 	{
+ 	  current_frame_info.r[reg_fp] = LOC_REG (79);
+ 	  current_frame_info.n_local_regs = LOC_REG (79) - LOC_REG (0) + 1;
+ 	}
+     }
+ 
+   if (! crtl->is_leaf)
+     {
+       /* Emit a save of BR0 if we call other functions.  Do this even
+ 	 if this function doesn't return, as EH depends on this to be
+ 	 able to unwind the stack.  */
+       SET_HARD_REG_BIT (mask, BR_REG (0));
+ 
+       current_frame_info.r[reg_save_b0] = find_gr_spill (reg_save_b0, 1);
+       if (current_frame_info.r[reg_save_b0] == 0)
+ 	{
+ 	  extra_spill_size += 8;
+ 	  n_spilled += 1;
+ 	}
+ 
+       /* Similarly for ar.pfs.  */
+       SET_HARD_REG_BIT (mask, AR_PFS_REGNUM);
+       current_frame_info.r[reg_save_ar_pfs] = find_gr_spill (reg_save_ar_pfs, 1);
+       if (current_frame_info.r[reg_save_ar_pfs] == 0)
+ 	{
+ 	  extra_spill_size += 8;
+ 	  n_spilled += 1;
+ 	}
+ 
+       /* Similarly for gp.  Note that if we're calling setjmp, the stacked
+ 	 registers are clobbered, so we fall back to the stack.  */
+       current_frame_info.r[reg_save_gp]
+ 	= (cfun->calls_setjmp ? 0 : find_gr_spill (reg_save_gp, 1));
+       if (current_frame_info.r[reg_save_gp] == 0)
+ 	{
+ 	  SET_HARD_REG_BIT (mask, GR_REG (1));
+ 	  spill_size += 8;
+ 	  n_spilled += 1;
+ 	}
+     }
+   else
+     {
+       if (df_regs_ever_live_p (BR_REG (0))
+ 	  && ! call_used_or_fixed_reg_p (BR_REG (0)))
+ 	{
+ 	  SET_HARD_REG_BIT (mask, BR_REG (0));
+ 	  extra_spill_size += 8;
+ 	  n_spilled += 1;
+ 	}
+ 
+       if (df_regs_ever_live_p (AR_PFS_REGNUM))
+ 	{
+ 	  SET_HARD_REG_BIT (mask, AR_PFS_REGNUM);
+  	  current_frame_info.r[reg_save_ar_pfs] 
+             = find_gr_spill (reg_save_ar_pfs, 1);
+ 	  if (current_frame_info.r[reg_save_ar_pfs] == 0)
+ 	    {
+ 	      extra_spill_size += 8;
+ 	      n_spilled += 1;
+ 	    }
+ 	}
+     }
+ 
+   /* Unwind descriptor hackery: things are most efficient if we allocate
+      consecutive GR save registers for RP, PFS, FP in that order. However,
+      it is absolutely critical that FP get the only hard register that's
+      guaranteed to be free, so we allocated it first.  If all three did
+      happen to be allocated hard regs, and are consecutive, rearrange them
+      into the preferred order now.  
+      
+      If we have already emitted code for any of those registers,
+      then it's already too late to change.  */
+   min_regno = MIN (current_frame_info.r[reg_fp],
+ 		   MIN (current_frame_info.r[reg_save_b0],
+ 			current_frame_info.r[reg_save_ar_pfs]));
+   max_regno = MAX (current_frame_info.r[reg_fp],
+ 		   MAX (current_frame_info.r[reg_save_b0],
+ 			current_frame_info.r[reg_save_ar_pfs]));
+   if (min_regno > 0
+       && min_regno + 2 == max_regno
+       && (current_frame_info.r[reg_fp] == min_regno + 1
+ 	  || current_frame_info.r[reg_save_b0] == min_regno + 1
+ 	  || current_frame_info.r[reg_save_ar_pfs] == min_regno + 1)
+       && (emitted_frame_related_regs[reg_save_b0] == 0
+ 	  || emitted_frame_related_regs[reg_save_b0] == min_regno)
+       && (emitted_frame_related_regs[reg_save_ar_pfs] == 0
+ 	  || emitted_frame_related_regs[reg_save_ar_pfs] == min_regno + 1)
+       && (emitted_frame_related_regs[reg_fp] == 0
+ 	  || emitted_frame_related_regs[reg_fp] == min_regno + 2))
+     {
+       current_frame_info.r[reg_save_b0] = min_regno;
+       current_frame_info.r[reg_save_ar_pfs] = min_regno + 1;
+       current_frame_info.r[reg_fp] = min_regno + 2;
+     }
+ 
+   /* See if we need to store the predicate register block.  */
+   for (regno = PR_REG (0); regno <= PR_REG (63); regno++)
+     if (df_regs_ever_live_p (regno) && ! call_used_or_fixed_reg_p (regno))
+       break;
+   if (regno <= PR_REG (63))
+     {
+       SET_HARD_REG_BIT (mask, PR_REG (0));
+       current_frame_info.r[reg_save_pr] = find_gr_spill (reg_save_pr, 1);
+       if (current_frame_info.r[reg_save_pr] == 0)
+ 	{
+ 	  extra_spill_size += 8;
+ 	  n_spilled += 1;
+ 	}
+ 
+       /* ??? Mark them all as used so that register renaming and such
+ 	 are free to use them.  */
+       for (regno = PR_REG (0); regno <= PR_REG (63); regno++)
+ 	df_set_regs_ever_live (regno, true);
+     }
+ 
+   /* If we're forced to use st8.spill, we're forced to save and restore
+      ar.unat as well.  The check for existing liveness allows inline asm
+      to touch ar.unat.  */
+   if (spilled_gr_p || cfun->machine->n_varargs
+       || df_regs_ever_live_p (AR_UNAT_REGNUM))
+     {
+       df_set_regs_ever_live (AR_UNAT_REGNUM, true);
+       SET_HARD_REG_BIT (mask, AR_UNAT_REGNUM);
+       current_frame_info.r[reg_save_ar_unat] 
+         = find_gr_spill (reg_save_ar_unat, spill_size == 0);
+       if (current_frame_info.r[reg_save_ar_unat] == 0)
+ 	{
+ 	  extra_spill_size += 8;
+ 	  n_spilled += 1;
+ 	}
+     }
+ 
+   if (df_regs_ever_live_p (AR_LC_REGNUM))
+     {
+       SET_HARD_REG_BIT (mask, AR_LC_REGNUM);
+       current_frame_info.r[reg_save_ar_lc] 
+         = find_gr_spill (reg_save_ar_lc, spill_size == 0);
+       if (current_frame_info.r[reg_save_ar_lc] == 0)
+ 	{
+ 	  extra_spill_size += 8;
+ 	  n_spilled += 1;
+ 	}
+     }
+ 
+   /* If we have an odd number of words of pretend arguments written to
+      the stack, then the FR save area will be unaligned.  We round the
+      size of this area up to keep things 16 byte aligned.  */
+   if (spilled_fr_p)
+     pretend_args_size = IA64_STACK_ALIGN (crtl->args.pretend_args_size);
+   else
+     pretend_args_size = crtl->args.pretend_args_size;
+ 
++  if (FRAME_GROWS_DOWNWARD)
++    size = IA64_STACK_ALIGN (size);
++
+   total_size = (spill_size + extra_spill_size + size + pretend_args_size
+ 		+ crtl->outgoing_args_size);
+   total_size = IA64_STACK_ALIGN (total_size);
+ 
+   /* We always use the 16-byte scratch area provided by the caller, but
+      if we are a leaf function, there's no one to which we need to provide
+      a scratch area.  However, if the function allocates dynamic stack space,
+      the dynamic offset is computed early and contains STACK_POINTER_OFFSET,
+      so we need to cope.  */
+   if (crtl->is_leaf && !cfun->calls_alloca)
+     total_size = MAX (0, total_size - 16);
+ 
+   current_frame_info.total_size = total_size;
+   current_frame_info.spill_cfa_off = pretend_args_size - 16;
+   current_frame_info.spill_size = spill_size;
+   current_frame_info.extra_spill_size = extra_spill_size;
+   current_frame_info.mask = mask;
+   current_frame_info.n_spilled = n_spilled;
+   current_frame_info.initialized = reload_completed;
+ }
+ 
+ /* Worker function for TARGET_CAN_ELIMINATE.  */
+ 
+ bool
+ ia64_can_eliminate (const int from ATTRIBUTE_UNUSED, const int to)
+ {
+   return (to == BR_REG (0) ? crtl->is_leaf : true);
+ }
+ 
+ /* Compute the initial difference between the specified pair of registers.  */
+ 
+ HOST_WIDE_INT
+ ia64_initial_elimination_offset (int from, int to)
+ {
 -  HOST_WIDE_INT offset;
++  HOST_WIDE_INT offset, size = get_frame_size ();
+ 
 -  ia64_compute_frame_size (get_frame_size ());
++  ia64_compute_frame_size (size);
+   switch (from)
+     {
+     case FRAME_POINTER_REGNUM:
 -      switch (to)
 -	{
 -	case HARD_FRAME_POINTER_REGNUM:
 -	  offset = -current_frame_info.total_size;
 -	  if (!crtl->is_leaf || cfun->calls_alloca)
 -	    offset += 16 + crtl->outgoing_args_size;
 -	  break;
 -
 -	case STACK_POINTER_REGNUM:
 -	  offset = 0;
 -	  if (!crtl->is_leaf || cfun->calls_alloca)
 -	    offset += 16 + crtl->outgoing_args_size;
 -	  break;
 -
 -	default:
 -	  gcc_unreachable ();
 -	}
++      offset = FRAME_GROWS_DOWNWARD ? IA64_STACK_ALIGN (size) : 0;
++      if (!crtl->is_leaf || cfun->calls_alloca)
++	offset += 16 + crtl->outgoing_args_size;
++      if (to == HARD_FRAME_POINTER_REGNUM)
++	offset -= current_frame_info.total_size;
++      else
++	gcc_assert (to == STACK_POINTER_REGNUM);
+       break;
+ 
+     case ARG_POINTER_REGNUM:
+       /* Arguments start above the 16 byte save area, unless stdarg
+ 	 in which case we store through the 16 byte save area.  */
+       switch (to)
+ 	{
+ 	case HARD_FRAME_POINTER_REGNUM:
+ 	  offset = 16 - crtl->args.pretend_args_size;
+ 	  break;
+ 
+ 	case STACK_POINTER_REGNUM:
+ 	  offset = (current_frame_info.total_size
+ 		    + 16 - crtl->args.pretend_args_size);
+ 	  break;
+ 
+ 	default:
+ 	  gcc_unreachable ();
+ 	}
+       break;
+ 
+     default:
+       gcc_unreachable ();
+     }
+ 
+   return offset;
+ }
+ 
+ /* If there are more than a trivial number of register spills, we use
+    two interleaved iterators so that we can get two memory references
+    per insn group.
+ 
+    In order to simplify things in the prologue and epilogue expanders,
+    we use helper functions to fix up the memory references after the
+    fact with the appropriate offsets to a POST_MODIFY memory mode.
+    The following data structure tracks the state of the two iterators
+    while insns are being emitted.  */
+ 
+ struct spill_fill_data
+ {
+   rtx_insn *init_after;		/* point at which to emit initializations */
+   rtx init_reg[2];		/* initial base register */
+   rtx iter_reg[2];		/* the iterator registers */
+   rtx *prev_addr[2];		/* address of last memory use */
+   rtx_insn *prev_insn[2];	/* the insn corresponding to prev_addr */
+   HOST_WIDE_INT prev_off[2];	/* last offset */
+   int n_iter;			/* number of iterators in use */
+   int next_iter;		/* next iterator to use */
+   unsigned int save_gr_used_mask;
+ };
+ 
+ static struct spill_fill_data spill_fill_data;
+ 
+ static void
+ setup_spill_pointers (int n_spills, rtx init_reg, HOST_WIDE_INT cfa_off)
+ {
+   int i;
+ 
+   spill_fill_data.init_after = get_last_insn ();
+   spill_fill_data.init_reg[0] = init_reg;
+   spill_fill_data.init_reg[1] = init_reg;
+   spill_fill_data.prev_addr[0] = NULL;
+   spill_fill_data.prev_addr[1] = NULL;
+   spill_fill_data.prev_insn[0] = NULL;
+   spill_fill_data.prev_insn[1] = NULL;
+   spill_fill_data.prev_off[0] = cfa_off;
+   spill_fill_data.prev_off[1] = cfa_off;
+   spill_fill_data.next_iter = 0;
+   spill_fill_data.save_gr_used_mask = current_frame_info.gr_used_mask;
+ 
+   spill_fill_data.n_iter = 1 + (n_spills > 2);
+   for (i = 0; i < spill_fill_data.n_iter; ++i)
+     {
+       int regno = next_scratch_gr_reg ();
+       spill_fill_data.iter_reg[i] = gen_rtx_REG (DImode, regno);
+       current_frame_info.gr_used_mask |= 1 << regno;
+     }
+ }
+ 
+ static void
+ finish_spill_pointers (void)
+ {
+   current_frame_info.gr_used_mask = spill_fill_data.save_gr_used_mask;
+ }
+ 
+ static rtx
+ spill_restore_mem (rtx reg, HOST_WIDE_INT cfa_off)
+ {
+   int iter = spill_fill_data.next_iter;
+   HOST_WIDE_INT disp = spill_fill_data.prev_off[iter] - cfa_off;
+   rtx disp_rtx = GEN_INT (disp);
+   rtx mem;
+ 
+   if (spill_fill_data.prev_addr[iter])
+     {
+       if (satisfies_constraint_N (disp_rtx))
+ 	{
+ 	  *spill_fill_data.prev_addr[iter]
+ 	    = gen_rtx_POST_MODIFY (DImode, spill_fill_data.iter_reg[iter],
+ 				   gen_rtx_PLUS (DImode,
+ 						 spill_fill_data.iter_reg[iter],
+ 						 disp_rtx));
+ 	  add_reg_note (spill_fill_data.prev_insn[iter],
+ 			REG_INC, spill_fill_data.iter_reg[iter]);
+ 	}
+       else
+ 	{
+ 	  /* ??? Could use register post_modify for loads.  */
+ 	  if (!satisfies_constraint_I (disp_rtx))
+ 	    {
+ 	      rtx tmp = gen_rtx_REG (DImode, next_scratch_gr_reg ());
+ 	      emit_move_insn (tmp, disp_rtx);
+ 	      disp_rtx = tmp;
+ 	    }
+ 	  emit_insn (gen_adddi3 (spill_fill_data.iter_reg[iter],
+ 				 spill_fill_data.iter_reg[iter], disp_rtx));
+ 	}
+     }
+   /* Micro-optimization: if we've created a frame pointer, it's at
+      CFA 0, which may allow the real iterator to be initialized lower,
+      slightly increasing parallelism.  Also, if there are few saves
+      it may eliminate the iterator entirely.  */
+   else if (disp == 0
+ 	   && spill_fill_data.init_reg[iter] == stack_pointer_rtx
+ 	   && frame_pointer_needed)
+     {
+       mem = gen_rtx_MEM (GET_MODE (reg), hard_frame_pointer_rtx);
+       set_mem_alias_set (mem, get_varargs_alias_set ());
+       return mem;
+     }
+   else
+     {
+       rtx seq;
+       rtx_insn *insn;
+ 
+       if (disp == 0)
+ 	seq = gen_movdi (spill_fill_data.iter_reg[iter],
+ 			 spill_fill_data.init_reg[iter]);
+       else
+ 	{
+ 	  start_sequence ();
+ 
+ 	  if (!satisfies_constraint_I (disp_rtx))
+ 	    {
+ 	      rtx tmp = gen_rtx_REG (DImode, next_scratch_gr_reg ());
+ 	      emit_move_insn (tmp, disp_rtx);
+ 	      disp_rtx = tmp;
+ 	    }
+ 
+ 	  emit_insn (gen_adddi3 (spill_fill_data.iter_reg[iter],
+ 				 spill_fill_data.init_reg[iter],
+ 				 disp_rtx));
+ 
+ 	  seq = get_insns ();
+ 	  end_sequence ();
+ 	}
+ 
+       /* Careful for being the first insn in a sequence.  */
+       if (spill_fill_data.init_after)
+ 	insn = emit_insn_after (seq, spill_fill_data.init_after);
+       else
+ 	{
+ 	  rtx_insn *first = get_insns ();
+ 	  if (first)
+ 	    insn = emit_insn_before (seq, first);
+ 	  else
+ 	    insn = emit_insn (seq);
+ 	}
+       spill_fill_data.init_after = insn;
+     }
+ 
+   mem = gen_rtx_MEM (GET_MODE (reg), spill_fill_data.iter_reg[iter]);
+ 
+   /* ??? Not all of the spills are for varargs, but some of them are.
+      The rest of the spills belong in an alias set of their own.  But
+      it doesn't actually hurt to include them here.  */
+   set_mem_alias_set (mem, get_varargs_alias_set ());
+ 
+   spill_fill_data.prev_addr[iter] = &XEXP (mem, 0);
+   spill_fill_data.prev_off[iter] = cfa_off;
+ 
+   if (++iter >= spill_fill_data.n_iter)
+     iter = 0;
+   spill_fill_data.next_iter = iter;
+ 
+   return mem;
+ }
+ 
+ static void
+ do_spill (rtx (*move_fn) (rtx, rtx, rtx), rtx reg, HOST_WIDE_INT cfa_off,
+ 	  rtx frame_reg)
+ {
+   int iter = spill_fill_data.next_iter;
+   rtx mem;
+   rtx_insn *insn;
+ 
+   mem = spill_restore_mem (reg, cfa_off);
+   insn = emit_insn ((*move_fn) (mem, reg, GEN_INT (cfa_off)));
+   spill_fill_data.prev_insn[iter] = insn;
+ 
+   if (frame_reg)
+     {
+       rtx base;
+       HOST_WIDE_INT off;
+ 
+       RTX_FRAME_RELATED_P (insn) = 1;
+ 
+       /* Don't even pretend that the unwind code can intuit its way
+ 	 through a pair of interleaved post_modify iterators.  Just
+ 	 provide the correct answer.  */
+ 
+       if (frame_pointer_needed)
+ 	{
+ 	  base = hard_frame_pointer_rtx;
+ 	  off = - cfa_off;
+ 	}
+       else
+ 	{
+ 	  base = stack_pointer_rtx;
+ 	  off = current_frame_info.total_size - cfa_off;
+ 	}
+ 
+       add_reg_note (insn, REG_CFA_OFFSET,
+ 		    gen_rtx_SET (gen_rtx_MEM (GET_MODE (reg),
+ 					      plus_constant (Pmode,
+ 							     base, off)),
+ 				 frame_reg));
+     }
+ }
+ 
+ static void
+ do_restore (rtx (*move_fn) (rtx, rtx, rtx), rtx reg, HOST_WIDE_INT cfa_off)
+ {
+   int iter = spill_fill_data.next_iter;
+   rtx_insn *insn;
+ 
+   insn = emit_insn ((*move_fn) (reg, spill_restore_mem (reg, cfa_off),
+ 				GEN_INT (cfa_off)));
+   spill_fill_data.prev_insn[iter] = insn;
+ }
+ 
+ /* Wrapper functions that discards the CONST_INT spill offset.  These
+    exist so that we can give gr_spill/gr_fill the offset they need and
+    use a consistent function interface.  */
+ 
+ static rtx
+ gen_movdi_x (rtx dest, rtx src, rtx offset ATTRIBUTE_UNUSED)
+ {
+   return gen_movdi (dest, src);
+ }
+ 
+ static rtx
+ gen_fr_spill_x (rtx dest, rtx src, rtx offset ATTRIBUTE_UNUSED)
+ {
+   return gen_fr_spill (dest, src);
+ }
+ 
+ static rtx
+ gen_fr_restore_x (rtx dest, rtx src, rtx offset ATTRIBUTE_UNUSED)
+ {
+   return gen_fr_restore (dest, src);
+ }
+ 
+ #define PROBE_INTERVAL (1 << STACK_CHECK_PROBE_INTERVAL_EXP)
+ 
+ /* See Table 6.2 of the IA-64 Software Developer Manual, Volume 2.  */
+ #define BACKING_STORE_SIZE(N) ((N) > 0 ? ((N) + (N)/63 + 1) * 8 : 0)
+ 
+ /* Emit code to probe a range of stack addresses from FIRST to FIRST+SIZE,
+    inclusive.  These are offsets from the current stack pointer.  BS_SIZE
+    is the size of the backing store.  ??? This clobbers r2 and r3.  */
+ 
+ static void
+ ia64_emit_probe_stack_range (HOST_WIDE_INT first, HOST_WIDE_INT size,
+ 			     int bs_size)
+ {
+   rtx r2 = gen_rtx_REG (Pmode, GR_REG (2));
+   rtx r3 = gen_rtx_REG (Pmode, GR_REG (3));
+   rtx p6 = gen_rtx_REG (BImode, PR_REG (6));
+ 
+   /* On the IA-64 there is a second stack in memory, namely the Backing Store
+      of the Register Stack Engine.  We also need to probe it after checking
+      that the 2 stacks don't overlap.  */
+   emit_insn (gen_bsp_value (r3));
+   emit_move_insn (r2, GEN_INT (-(first + size)));
+ 
+   /* Compare current value of BSP and SP registers.  */
+   emit_insn (gen_rtx_SET (p6, gen_rtx_fmt_ee (LTU, BImode,
+ 					      r3, stack_pointer_rtx)));
+ 
+   /* Compute the address of the probe for the Backing Store (which grows
+      towards higher addresses).  We probe only at the first offset of
+      the next page because some OS (eg Linux/ia64) only extend the
+      backing store when this specific address is hit (but generate a SEGV
+      on other address).  Page size is the worst case (4KB).  The reserve
+      size is at least 4096 - (96 + 2) * 8 = 3312 bytes, which is enough.
+      Also compute the address of the last probe for the memory stack
+      (which grows towards lower addresses).  */
+   emit_insn (gen_rtx_SET (r3, plus_constant (Pmode, r3, 4095)));
+   emit_insn (gen_rtx_SET (r2, gen_rtx_PLUS (Pmode, stack_pointer_rtx, r2)));
+ 
+   /* Compare them and raise SEGV if the former has topped the latter.  */
+   emit_insn (gen_rtx_COND_EXEC (VOIDmode,
+ 				gen_rtx_fmt_ee (NE, VOIDmode, p6, const0_rtx),
+ 				gen_rtx_SET (p6, gen_rtx_fmt_ee (GEU, BImode,
+ 								 r3, r2))));
+   emit_insn (gen_rtx_SET (gen_rtx_ZERO_EXTRACT (DImode, r3, GEN_INT (12),
+ 						const0_rtx),
+ 			  const0_rtx));
+   emit_insn (gen_rtx_COND_EXEC (VOIDmode,
+ 				gen_rtx_fmt_ee (NE, VOIDmode, p6, const0_rtx),
+ 				gen_rtx_TRAP_IF (VOIDmode, const1_rtx,
+ 						 GEN_INT (11))));
+ 
+   /* Probe the Backing Store if necessary.  */
+   if (bs_size > 0)
+     emit_stack_probe (r3);
+ 
+   /* Probe the memory stack if necessary.  */
+   if (size == 0)
+     ;
+ 
+   /* See if we have a constant small number of probes to generate.  If so,
+      that's the easy case.  */
+   else if (size <= PROBE_INTERVAL)
+     emit_stack_probe (r2);
+ 
+   /* The run-time loop is made up of 9 insns in the generic case while this
+      compile-time loop is made up of 5+2*(n-2) insns for n # of intervals.  */
+   else if (size <= 4 * PROBE_INTERVAL)
+     {
+       HOST_WIDE_INT i;
+ 
+       emit_move_insn (r2, GEN_INT (-(first + PROBE_INTERVAL)));
+       emit_insn (gen_rtx_SET (r2,
+ 			      gen_rtx_PLUS (Pmode, stack_pointer_rtx, r2)));
+       emit_stack_probe (r2);
+ 
+       /* Probe at FIRST + N * PROBE_INTERVAL for values of N from 2 until
+ 	 it exceeds SIZE.  If only two probes are needed, this will not
+ 	 generate any code.  Then probe at FIRST + SIZE.  */
+       for (i = 2 * PROBE_INTERVAL; i < size; i += PROBE_INTERVAL)
+ 	{
+ 	  emit_insn (gen_rtx_SET (r2,
+ 				  plus_constant (Pmode, r2, -PROBE_INTERVAL)));
+ 	  emit_stack_probe (r2);
+ 	}
+ 
+       emit_insn (gen_rtx_SET (r2,
+ 			      plus_constant (Pmode, r2,
+ 					     (i - PROBE_INTERVAL) - size)));
+       emit_stack_probe (r2);
+     }
+ 
+   /* Otherwise, do the same as above, but in a loop.  Note that we must be
+      extra careful with variables wrapping around because we might be at
+      the very top (or the very bottom) of the address space and we have
+      to be able to handle this case properly; in particular, we use an
+      equality test for the loop condition.  */
+   else
+     {
+       HOST_WIDE_INT rounded_size;
+ 
+       emit_move_insn (r2, GEN_INT (-first));
+ 
+ 
+       /* Step 1: round SIZE to the previous multiple of the interval.  */
+ 
+       rounded_size = size & -PROBE_INTERVAL;
+ 
+ 
+       /* Step 2: compute initial and final value of the loop counter.  */
+ 
+       /* TEST_ADDR = SP + FIRST.  */
+       emit_insn (gen_rtx_SET (r2,
+ 			      gen_rtx_PLUS (Pmode, stack_pointer_rtx, r2)));
+ 
+       /* LAST_ADDR = SP + FIRST + ROUNDED_SIZE.  */
+       if (rounded_size > (1 << 21))
+ 	{
+ 	  emit_move_insn (r3, GEN_INT (-rounded_size));
+ 	  emit_insn (gen_rtx_SET (r3, gen_rtx_PLUS (Pmode, r2, r3)));
+ 	}
+       else
+         emit_insn (gen_rtx_SET (r3, gen_rtx_PLUS (Pmode, r2,
+ 						  GEN_INT (-rounded_size))));
+ 
+ 
+       /* Step 3: the loop
+ 
+ 	 do
+ 	   {
+ 	     TEST_ADDR = TEST_ADDR + PROBE_INTERVAL
+ 	     probe at TEST_ADDR
+ 	   }
+ 	 while (TEST_ADDR != LAST_ADDR)
+ 
+ 	 probes at FIRST + N * PROBE_INTERVAL for values of N from 1
+ 	 until it is equal to ROUNDED_SIZE.  */
+ 
+       emit_insn (gen_probe_stack_range (r2, r2, r3));
+ 
+ 
+       /* Step 4: probe at FIRST + SIZE if we cannot assert at compile-time
+ 	 that SIZE is equal to ROUNDED_SIZE.  */
+ 
+       /* TEMP = SIZE - ROUNDED_SIZE.  */
+       if (size != rounded_size)
+ 	{
+ 	  emit_insn (gen_rtx_SET (r2, plus_constant (Pmode, r2,
+ 						     rounded_size - size)));
+ 	  emit_stack_probe (r2);
+ 	}
+     }
+ 
+   /* Make sure nothing is scheduled before we are done.  */
+   emit_insn (gen_blockage ());
+ }
+ 
+ /* Probe a range of stack addresses from REG1 to REG2 inclusive.  These are
+    absolute addresses.  */
+ 
+ const char *
+ output_probe_stack_range (rtx reg1, rtx reg2)
+ {
+   static int labelno = 0;
+   char loop_lab[32];
+   rtx xops[3];
+ 
+   ASM_GENERATE_INTERNAL_LABEL (loop_lab, "LPSRL", labelno++);
+ 
+   /* Loop.  */
+   ASM_OUTPUT_INTERNAL_LABEL (asm_out_file, loop_lab);
+ 
+   /* TEST_ADDR = TEST_ADDR + PROBE_INTERVAL.  */
+   xops[0] = reg1;
+   xops[1] = GEN_INT (-PROBE_INTERVAL);
+   output_asm_insn ("addl %0 = %1, %0", xops);
+   fputs ("\t;;\n", asm_out_file);
+ 
+   /* Probe at TEST_ADDR.  */
+   output_asm_insn ("probe.w.fault %0, 0", xops);
+ 
+   /* Test if TEST_ADDR == LAST_ADDR.  */
+   xops[1] = reg2;
+   xops[2] = gen_rtx_REG (BImode, PR_REG (6));
+   output_asm_insn ("cmp.eq %2, %I2 = %0, %1", xops);
+ 
+   /* Branch.  */
+   fprintf (asm_out_file, "\t(%s) br.cond.dpnt ", reg_names [PR_REG (7)]);
+   assemble_name_raw (asm_out_file, loop_lab);
+   fputc ('\n', asm_out_file);
+ 
+   return "";
+ }
+ 
+ /* Called after register allocation to add any instructions needed for the
+    prologue.  Using a prologue insn is favored compared to putting all of the
+    instructions in output_function_prologue(), since it allows the scheduler
+    to intermix instructions with the saves of the caller saved registers.  In
+    some cases, it might be necessary to emit a barrier instruction as the last
+    insn to prevent such scheduling.
+ 
+    Also any insns generated here should have RTX_FRAME_RELATED_P(insn) = 1
+    so that the debug info generation code can handle them properly.
+ 
+    The register save area is laid out like so:
+    cfa+16
+ 	[ varargs spill area ]
+ 	[ fr register spill area ]
+ 	[ br register spill area ]
+ 	[ ar register spill area ]
+ 	[ pr register spill area ]
+ 	[ gr register spill area ] */
+ 
+ /* ??? Get inefficient code when the frame size is larger than can fit in an
+    adds instruction.  */
+ 
+ void
+ ia64_expand_prologue (void)
+ {
+   rtx_insn *insn;
+   rtx ar_pfs_save_reg, ar_unat_save_reg;
+   int i, epilogue_p, regno, alt_regno, cfa_off, n_varargs;
+   rtx reg, alt_reg;
+ 
+   ia64_compute_frame_size (get_frame_size ());
+   last_scratch_gr_reg = 15;
+ 
+   if (flag_stack_usage_info)
+     current_function_static_stack_size = current_frame_info.total_size;
+ 
+   if (flag_stack_check == STATIC_BUILTIN_STACK_CHECK
+       || flag_stack_clash_protection)
+     {
+       HOST_WIDE_INT size = current_frame_info.total_size;
+       int bs_size = BACKING_STORE_SIZE (current_frame_info.n_input_regs
+ 					  + current_frame_info.n_local_regs);
+ 
+       if (crtl->is_leaf && !cfun->calls_alloca)
+ 	{
+ 	  if (size > PROBE_INTERVAL && size > get_stack_check_protect ())
+ 	    ia64_emit_probe_stack_range (get_stack_check_protect (),
+ 					 size - get_stack_check_protect (),
+ 					 bs_size);
+ 	  else if (size + bs_size > get_stack_check_protect ())
+ 	    ia64_emit_probe_stack_range (get_stack_check_protect (),
+ 					 0, bs_size);
+ 	}
+       else if (size + bs_size > 0)
+ 	ia64_emit_probe_stack_range (get_stack_check_protect (), size, bs_size);
+     }
+ 
+   if (dump_file) 
+     {
+       fprintf (dump_file, "ia64 frame related registers "
+                "recorded in current_frame_info.r[]:\n");
+ #define PRINTREG(a) if (current_frame_info.r[a]) \
+         fprintf(dump_file, "%s = %d\n", #a, current_frame_info.r[a])
+       PRINTREG(reg_fp);
+       PRINTREG(reg_save_b0);
+       PRINTREG(reg_save_pr);
+       PRINTREG(reg_save_ar_pfs);
+       PRINTREG(reg_save_ar_unat);
+       PRINTREG(reg_save_ar_lc);
+       PRINTREG(reg_save_gp);
+ #undef PRINTREG
+     }
+ 
+   /* If there is no epilogue, then we don't need some prologue insns.
+      We need to avoid emitting the dead prologue insns, because flow
+      will complain about them.  */
+   if (optimize)
+     {
+       edge e;
+       edge_iterator ei;
+ 
+       FOR_EACH_EDGE (e, ei, EXIT_BLOCK_PTR_FOR_FN (cfun)->preds)
+ 	if ((e->flags & EDGE_FAKE) == 0
+ 	    && (e->flags & EDGE_FALLTHRU) != 0)
+ 	  break;
+       epilogue_p = (e != NULL);
+     }
+   else
+     epilogue_p = 1;
+ 
+   /* Set the local, input, and output register names.  We need to do this
+      for GNU libc, which creates crti.S/crtn.S by splitting initfini.c in
+      half.  If we use in/loc/out register names, then we get assembler errors
+      in crtn.S because there is no alloc insn or regstk directive in there.  */
+   if (! TARGET_REG_NAMES)
+     {
+       int inputs = current_frame_info.n_input_regs;
+       int locals = current_frame_info.n_local_regs;
+       int outputs = current_frame_info.n_output_regs;
+ 
+       for (i = 0; i < inputs; i++)
+ 	reg_names[IN_REG (i)] = ia64_reg_numbers[i];
+       for (i = 0; i < locals; i++)
+ 	reg_names[LOC_REG (i)] = ia64_reg_numbers[inputs + i];
+       for (i = 0; i < outputs; i++)
+ 	reg_names[OUT_REG (i)] = ia64_reg_numbers[inputs + locals + i];
+     }
+ 
+   /* Set the frame pointer register name.  The regnum is logically loc79,
+      but of course we'll not have allocated that many locals.  Rather than
+      worrying about renumbering the existing rtxs, we adjust the name.  */
+   /* ??? This code means that we can never use one local register when
+      there is a frame pointer.  loc79 gets wasted in this case, as it is
+      renamed to a register that will never be used.  See also the try_locals
+      code in find_gr_spill.  */
+   if (current_frame_info.r[reg_fp])
+     {
+       const char *tmp = reg_names[HARD_FRAME_POINTER_REGNUM];
+       reg_names[HARD_FRAME_POINTER_REGNUM]
+ 	= reg_names[current_frame_info.r[reg_fp]];
+       reg_names[current_frame_info.r[reg_fp]] = tmp;
+     }
+ 
+   /* We don't need an alloc instruction if we've used no outputs or locals.  */
+   if (current_frame_info.n_local_regs == 0
+       && current_frame_info.n_output_regs == 0
+       && current_frame_info.n_input_regs <= crtl->args.info.int_regs
+       && !TEST_HARD_REG_BIT (current_frame_info.mask, AR_PFS_REGNUM))
+     {
+       /* If there is no alloc, but there are input registers used, then we
+ 	 need a .regstk directive.  */
+       current_frame_info.need_regstk = (TARGET_REG_NAMES != 0);
+       ar_pfs_save_reg = NULL_RTX;
+     }
+   else
+     {
+       current_frame_info.need_regstk = 0;
+ 
+       if (current_frame_info.r[reg_save_ar_pfs])
+         {
+ 	  regno = current_frame_info.r[reg_save_ar_pfs];
+ 	  reg_emitted (reg_save_ar_pfs);
+ 	}
+       else
+ 	regno = next_scratch_gr_reg ();
+       ar_pfs_save_reg = gen_rtx_REG (DImode, regno);
+ 
+       insn = emit_insn (gen_alloc (ar_pfs_save_reg,
+ 				   GEN_INT (current_frame_info.n_input_regs),
+ 				   GEN_INT (current_frame_info.n_local_regs),
+ 				   GEN_INT (current_frame_info.n_output_regs),
+ 				   GEN_INT (current_frame_info.n_rotate_regs)));
+       if (current_frame_info.r[reg_save_ar_pfs])
+ 	{
+ 	  RTX_FRAME_RELATED_P (insn) = 1;
+ 	  add_reg_note (insn, REG_CFA_REGISTER,
+ 			gen_rtx_SET (ar_pfs_save_reg,
+ 				     gen_rtx_REG (DImode, AR_PFS_REGNUM)));
+ 	}
+     }
+ 
+   /* Set up frame pointer, stack pointer, and spill iterators.  */
+ 
+   n_varargs = cfun->machine->n_varargs;
+   setup_spill_pointers (current_frame_info.n_spilled + n_varargs,
+ 			stack_pointer_rtx, 0);
+ 
+   if (frame_pointer_needed)
+     {
+       insn = emit_move_insn (hard_frame_pointer_rtx, stack_pointer_rtx);
+       RTX_FRAME_RELATED_P (insn) = 1;
+ 
+       /* Force the unwind info to recognize this as defining a new CFA,
+ 	 rather than some temp register setup.  */
+       add_reg_note (insn, REG_CFA_ADJUST_CFA, NULL_RTX);
+     }
+ 
+   if (current_frame_info.total_size != 0)
+     {
+       rtx frame_size_rtx = GEN_INT (- current_frame_info.total_size);
+       rtx offset;
+ 
+       if (satisfies_constraint_I (frame_size_rtx))
+ 	offset = frame_size_rtx;
+       else
+ 	{
+ 	  regno = next_scratch_gr_reg ();
+ 	  offset = gen_rtx_REG (DImode, regno);
+ 	  emit_move_insn (offset, frame_size_rtx);
+ 	}
+ 
+       insn = emit_insn (gen_adddi3 (stack_pointer_rtx,
+ 				    stack_pointer_rtx, offset));
+ 
+       if (! frame_pointer_needed)
+ 	{
+ 	  RTX_FRAME_RELATED_P (insn) = 1;
+ 	  add_reg_note (insn, REG_CFA_ADJUST_CFA,
+ 			gen_rtx_SET (stack_pointer_rtx,
+ 				     gen_rtx_PLUS (DImode,
+ 						   stack_pointer_rtx,
+ 						   frame_size_rtx)));
+ 	}
+ 
+       /* ??? At this point we must generate a magic insn that appears to
+ 	 modify the stack pointer, the frame pointer, and all spill
+ 	 iterators.  This would allow the most scheduling freedom.  For
+ 	 now, just hard stop.  */
+       emit_insn (gen_blockage ());
+     }
+ 
+   /* Must copy out ar.unat before doing any integer spills.  */
+   if (TEST_HARD_REG_BIT (current_frame_info.mask, AR_UNAT_REGNUM))
+     {
+       if (current_frame_info.r[reg_save_ar_unat])
+         {
+ 	  ar_unat_save_reg
+ 	    = gen_rtx_REG (DImode, current_frame_info.r[reg_save_ar_unat]);
+ 	  reg_emitted (reg_save_ar_unat);
+ 	}
+       else
+ 	{
+ 	  alt_regno = next_scratch_gr_reg ();
+ 	  ar_unat_save_reg = gen_rtx_REG (DImode, alt_regno);
+ 	  current_frame_info.gr_used_mask |= 1 << alt_regno;
+ 	}
+ 
+       reg = gen_rtx_REG (DImode, AR_UNAT_REGNUM);
+       insn = emit_move_insn (ar_unat_save_reg, reg);
+       if (current_frame_info.r[reg_save_ar_unat])
+ 	{
+ 	  RTX_FRAME_RELATED_P (insn) = 1;
+ 	  add_reg_note (insn, REG_CFA_REGISTER, NULL_RTX);
+ 	}
+ 
+       /* Even if we're not going to generate an epilogue, we still
+ 	 need to save the register so that EH works.  */
+       if (! epilogue_p && current_frame_info.r[reg_save_ar_unat])
+ 	emit_insn (gen_prologue_use (ar_unat_save_reg));
+     }
+   else
+     ar_unat_save_reg = NULL_RTX;
+ 
+   /* Spill all varargs registers.  Do this before spilling any GR registers,
+      since we want the UNAT bits for the GR registers to override the UNAT
+      bits from varargs, which we don't care about.  */
+ 
+   cfa_off = -16;
+   for (regno = GR_ARG_FIRST + 7; n_varargs > 0; --n_varargs, --regno)
+     {
+       reg = gen_rtx_REG (DImode, regno);
+       do_spill (gen_gr_spill, reg, cfa_off += 8, NULL_RTX);
+     }
+ 
+   /* Locate the bottom of the register save area.  */
+   cfa_off = (current_frame_info.spill_cfa_off
+ 	     + current_frame_info.spill_size
+ 	     + current_frame_info.extra_spill_size);
+ 
+   /* Save the predicate register block either in a register or in memory.  */
+   if (TEST_HARD_REG_BIT (current_frame_info.mask, PR_REG (0)))
+     {
+       reg = gen_rtx_REG (DImode, PR_REG (0));
+       if (current_frame_info.r[reg_save_pr] != 0)
+ 	{
+ 	  alt_reg = gen_rtx_REG (DImode, current_frame_info.r[reg_save_pr]);
+ 	  reg_emitted (reg_save_pr);
+ 	  insn = emit_move_insn (alt_reg, reg);
+ 
+ 	  /* ??? Denote pr spill/fill by a DImode move that modifies all
+ 	     64 hard registers.  */
+ 	  RTX_FRAME_RELATED_P (insn) = 1;
+ 	  add_reg_note (insn, REG_CFA_REGISTER, NULL_RTX);
+ 
+ 	  /* Even if we're not going to generate an epilogue, we still
+ 	     need to save the register so that EH works.  */
+ 	  if (! epilogue_p)
+ 	    emit_insn (gen_prologue_use (alt_reg));
+ 	}
+       else
+ 	{
+ 	  alt_regno = next_scratch_gr_reg ();
+ 	  alt_reg = gen_rtx_REG (DImode, alt_regno);
+ 	  insn = emit_move_insn (alt_reg, reg);
+ 	  do_spill (gen_movdi_x, alt_reg, cfa_off, reg);
+ 	  cfa_off -= 8;
+ 	}
+     }
+ 
+   /* Handle AR regs in numerical order.  All of them get special handling.  */
+   if (TEST_HARD_REG_BIT (current_frame_info.mask, AR_UNAT_REGNUM)
+       && current_frame_info.r[reg_save_ar_unat] == 0)
+     {
+       reg = gen_rtx_REG (DImode, AR_UNAT_REGNUM);
+       do_spill (gen_movdi_x, ar_unat_save_reg, cfa_off, reg);
+       cfa_off -= 8;
+     }
+ 
+   /* The alloc insn already copied ar.pfs into a general register.  The
+      only thing we have to do now is copy that register to a stack slot
+      if we'd not allocated a local register for the job.  */
+   if (TEST_HARD_REG_BIT (current_frame_info.mask, AR_PFS_REGNUM)
+       && current_frame_info.r[reg_save_ar_pfs] == 0)
+     {
+       reg = gen_rtx_REG (DImode, AR_PFS_REGNUM);
+       do_spill (gen_movdi_x, ar_pfs_save_reg, cfa_off, reg);
+       cfa_off -= 8;
+     }
+ 
+   if (TEST_HARD_REG_BIT (current_frame_info.mask, AR_LC_REGNUM))
+     {
+       reg = gen_rtx_REG (DImode, AR_LC_REGNUM);
+       if (current_frame_info.r[reg_save_ar_lc] != 0)
+ 	{
+ 	  alt_reg = gen_rtx_REG (DImode, current_frame_info.r[reg_save_ar_lc]);
+ 	  reg_emitted (reg_save_ar_lc);
+ 	  insn = emit_move_insn (alt_reg, reg);
+ 	  RTX_FRAME_RELATED_P (insn) = 1;
+ 	  add_reg_note (insn, REG_CFA_REGISTER, NULL_RTX);
+ 
+ 	  /* Even if we're not going to generate an epilogue, we still
+ 	     need to save the register so that EH works.  */
+ 	  if (! epilogue_p)
+ 	    emit_insn (gen_prologue_use (alt_reg));
+ 	}
+       else
+ 	{
+ 	  alt_regno = next_scratch_gr_reg ();
+ 	  alt_reg = gen_rtx_REG (DImode, alt_regno);
+ 	  emit_move_insn (alt_reg, reg);
+ 	  do_spill (gen_movdi_x, alt_reg, cfa_off, reg);
+ 	  cfa_off -= 8;
+ 	}
+     }
+ 
+   /* Save the return pointer.  */
+   if (TEST_HARD_REG_BIT (current_frame_info.mask, BR_REG (0)))
+     {
+       reg = gen_rtx_REG (DImode, BR_REG (0));
+       if (current_frame_info.r[reg_save_b0] != 0)
+ 	{
+           alt_reg = gen_rtx_REG (DImode, current_frame_info.r[reg_save_b0]);
+           reg_emitted (reg_save_b0);
+ 	  insn = emit_move_insn (alt_reg, reg);
+ 	  RTX_FRAME_RELATED_P (insn) = 1;
+ 	  add_reg_note (insn, REG_CFA_REGISTER, gen_rtx_SET (alt_reg, pc_rtx));
+ 
+ 	  /* Even if we're not going to generate an epilogue, we still
+ 	     need to save the register so that EH works.  */
+ 	  if (! epilogue_p)
+ 	    emit_insn (gen_prologue_use (alt_reg));
+ 	}
+       else
+ 	{
+ 	  alt_regno = next_scratch_gr_reg ();
+ 	  alt_reg = gen_rtx_REG (DImode, alt_regno);
+ 	  emit_move_insn (alt_reg, reg);
+ 	  do_spill (gen_movdi_x, alt_reg, cfa_off, reg);
+ 	  cfa_off -= 8;
+ 	}
+     }
+ 
+   if (current_frame_info.r[reg_save_gp])
+     {
+       reg_emitted (reg_save_gp);
+       insn = emit_move_insn (gen_rtx_REG (DImode,
+ 					  current_frame_info.r[reg_save_gp]),
+ 			     pic_offset_table_rtx);
+     }
+ 
+   /* We should now be at the base of the gr/br/fr spill area.  */
+   gcc_assert (cfa_off == (current_frame_info.spill_cfa_off
+ 			  + current_frame_info.spill_size));
+ 
+   /* Spill all general registers.  */
+   for (regno = GR_REG (1); regno <= GR_REG (31); ++regno)
+     if (TEST_HARD_REG_BIT (current_frame_info.mask, regno))
+       {
+ 	reg = gen_rtx_REG (DImode, regno);
+ 	do_spill (gen_gr_spill, reg, cfa_off, reg);
+ 	cfa_off -= 8;
+       }
+ 
+   /* Spill the rest of the BR registers.  */
+   for (regno = BR_REG (1); regno <= BR_REG (7); ++regno)
+     if (TEST_HARD_REG_BIT (current_frame_info.mask, regno))
+       {
+ 	alt_regno = next_scratch_gr_reg ();
+ 	alt_reg = gen_rtx_REG (DImode, alt_regno);
+ 	reg = gen_rtx_REG (DImode, regno);
+ 	emit_move_insn (alt_reg, reg);
+ 	do_spill (gen_movdi_x, alt_reg, cfa_off, reg);
+ 	cfa_off -= 8;
+       }
+ 
+   /* Align the frame and spill all FR registers.  */
+   for (regno = FR_REG (2); regno <= FR_REG (127); ++regno)
+     if (TEST_HARD_REG_BIT (current_frame_info.mask, regno))
+       {
+         gcc_assert (!(cfa_off & 15));
+ 	reg = gen_rtx_REG (XFmode, regno);
+ 	do_spill (gen_fr_spill_x, reg, cfa_off, reg);
+ 	cfa_off -= 16;
+       }
+ 
+   gcc_assert (cfa_off == current_frame_info.spill_cfa_off);
+ 
+   finish_spill_pointers ();
+ }
+ 
+ /* Output the textual info surrounding the prologue.  */
+ 
+ void
+ ia64_start_function (FILE *file, const char *fnname,
+ 		     tree decl ATTRIBUTE_UNUSED)
+ {
+ #if TARGET_ABI_OPEN_VMS
+   vms_start_function (fnname);
+ #endif
+ 
+   fputs ("\t.proc ", file);
+   assemble_name (file, fnname);
+   fputc ('\n', file);
+   ASM_OUTPUT_LABEL (file, fnname);
+ }
+ 
+ /* Called after register allocation to add any instructions needed for the
+    epilogue.  Using an epilogue insn is favored compared to putting all of the
+    instructions in output_function_prologue(), since it allows the scheduler
+    to intermix instructions with the saves of the caller saved registers.  In
+    some cases, it might be necessary to emit a barrier instruction as the last
+    insn to prevent such scheduling.  */
+ 
+ void
+ ia64_expand_epilogue (int sibcall_p)
+ {
+   rtx_insn *insn;
+   rtx reg, alt_reg, ar_unat_save_reg;
+   int regno, alt_regno, cfa_off;
+ 
+   ia64_compute_frame_size (get_frame_size ());
+ 
+   /* If there is a frame pointer, then we use it instead of the stack
+      pointer, so that the stack pointer does not need to be valid when
+      the epilogue starts.  See EXIT_IGNORE_STACK.  */
+   if (frame_pointer_needed)
+     setup_spill_pointers (current_frame_info.n_spilled,
+ 			  hard_frame_pointer_rtx, 0);
+   else
+     setup_spill_pointers (current_frame_info.n_spilled, stack_pointer_rtx,
+ 			  current_frame_info.total_size);
+ 
+   if (current_frame_info.total_size != 0)
+     {
+       /* ??? At this point we must generate a magic insn that appears to
+          modify the spill iterators and the frame pointer.  This would
+ 	 allow the most scheduling freedom.  For now, just hard stop.  */
+       emit_insn (gen_blockage ());
+     }
+ 
+   /* Locate the bottom of the register save area.  */
+   cfa_off = (current_frame_info.spill_cfa_off
+ 	     + current_frame_info.spill_size
+ 	     + current_frame_info.extra_spill_size);
+ 
+   /* Restore the predicate registers.  */
+   if (TEST_HARD_REG_BIT (current_frame_info.mask, PR_REG (0)))
+     {
+       if (current_frame_info.r[reg_save_pr] != 0)
+         {
+ 	  alt_reg = gen_rtx_REG (DImode, current_frame_info.r[reg_save_pr]);
+ 	  reg_emitted (reg_save_pr);
+ 	}
+       else
+ 	{
+ 	  alt_regno = next_scratch_gr_reg ();
+ 	  alt_reg = gen_rtx_REG (DImode, alt_regno);
+ 	  do_restore (gen_movdi_x, alt_reg, cfa_off);
+ 	  cfa_off -= 8;
+ 	}
+       reg = gen_rtx_REG (DImode, PR_REG (0));
+       emit_move_insn (reg, alt_reg);
+     }
+ 
+   /* Restore the application registers.  */
+ 
+   /* Load the saved unat from the stack, but do not restore it until
+      after the GRs have been restored.  */
+   if (TEST_HARD_REG_BIT (current_frame_info.mask, AR_UNAT_REGNUM))
+     {
+       if (current_frame_info.r[reg_save_ar_unat] != 0)
+         {
+           ar_unat_save_reg
+ 	    = gen_rtx_REG (DImode, current_frame_info.r[reg_save_ar_unat]);
+ 	  reg_emitted (reg_save_ar_unat);
+ 	}
+       else
+ 	{
+ 	  alt_regno = next_scratch_gr_reg ();
+ 	  ar_unat_save_reg = gen_rtx_REG (DImode, alt_regno);
+ 	  current_frame_info.gr_used_mask |= 1 << alt_regno;
+ 	  do_restore (gen_movdi_x, ar_unat_save_reg, cfa_off);
+ 	  cfa_off -= 8;
+ 	}
+     }
+   else
+     ar_unat_save_reg = NULL_RTX;
+ 
+   if (current_frame_info.r[reg_save_ar_pfs] != 0)
+     {
+       reg_emitted (reg_save_ar_pfs);
+       alt_reg = gen_rtx_REG (DImode, current_frame_info.r[reg_save_ar_pfs]);
+       reg = gen_rtx_REG (DImode, AR_PFS_REGNUM);
+       emit_move_insn (reg, alt_reg);
+     }
+   else if (TEST_HARD_REG_BIT (current_frame_info.mask, AR_PFS_REGNUM))
+     {
+       alt_regno = next_scratch_gr_reg ();
+       alt_reg = gen_rtx_REG (DImode, alt_regno);
+       do_restore (gen_movdi_x, alt_reg, cfa_off);
+       cfa_off -= 8;
+       reg = gen_rtx_REG (DImode, AR_PFS_REGNUM);
+       emit_move_insn (reg, alt_reg);
+     }
+ 
+   if (TEST_HARD_REG_BIT (current_frame_info.mask, AR_LC_REGNUM))
+     {
+       if (current_frame_info.r[reg_save_ar_lc] != 0)
+         {
+ 	  alt_reg = gen_rtx_REG (DImode, current_frame_info.r[reg_save_ar_lc]);
+           reg_emitted (reg_save_ar_lc);
+ 	}
+       else
+ 	{
+ 	  alt_regno = next_scratch_gr_reg ();
+ 	  alt_reg = gen_rtx_REG (DImode, alt_regno);
+ 	  do_restore (gen_movdi_x, alt_reg, cfa_off);
+ 	  cfa_off -= 8;
+ 	}
+       reg = gen_rtx_REG (DImode, AR_LC_REGNUM);
+       emit_move_insn (reg, alt_reg);
+     }
+ 
+   /* Restore the return pointer.  */
+   if (TEST_HARD_REG_BIT (current_frame_info.mask, BR_REG (0)))
+     {
+       if (current_frame_info.r[reg_save_b0] != 0)
+         {
+          alt_reg = gen_rtx_REG (DImode, current_frame_info.r[reg_save_b0]);
+          reg_emitted (reg_save_b0);
+         }
+       else
+ 	{
+ 	  alt_regno = next_scratch_gr_reg ();
+ 	  alt_reg = gen_rtx_REG (DImode, alt_regno);
+ 	  do_restore (gen_movdi_x, alt_reg, cfa_off);
+ 	  cfa_off -= 8;
+ 	}
+       reg = gen_rtx_REG (DImode, BR_REG (0));
+       emit_move_insn (reg, alt_reg);
+     }
+ 
+   /* We should now be at the base of the gr/br/fr spill area.  */
+   gcc_assert (cfa_off == (current_frame_info.spill_cfa_off
+ 			  + current_frame_info.spill_size));
+ 
+   /* The GP may be stored on the stack in the prologue, but it's
+      never restored in the epilogue.  Skip the stack slot.  */
+   if (TEST_HARD_REG_BIT (current_frame_info.mask, GR_REG (1)))
+     cfa_off -= 8;
+ 
+   /* Restore all general registers.  */
+   for (regno = GR_REG (2); regno <= GR_REG (31); ++regno)
+     if (TEST_HARD_REG_BIT (current_frame_info.mask, regno))
+       {
+ 	reg = gen_rtx_REG (DImode, regno);
+ 	do_restore (gen_gr_restore, reg, cfa_off);
+ 	cfa_off -= 8;
+       }
+ 
+   /* Restore the branch registers.  */
+   for (regno = BR_REG (1); regno <= BR_REG (7); ++regno)
+     if (TEST_HARD_REG_BIT (current_frame_info.mask, regno))
+       {
+ 	alt_regno = next_scratch_gr_reg ();
+ 	alt_reg = gen_rtx_REG (DImode, alt_regno);
+ 	do_restore (gen_movdi_x, alt_reg, cfa_off);
+ 	cfa_off -= 8;
+ 	reg = gen_rtx_REG (DImode, regno);
+ 	emit_move_insn (reg, alt_reg);
+       }
+ 
+   /* Restore floating point registers.  */
+   for (regno = FR_REG (2); regno <= FR_REG (127); ++regno)
+     if (TEST_HARD_REG_BIT (current_frame_info.mask, regno))
+       {
+         gcc_assert (!(cfa_off & 15));
+ 	reg = gen_rtx_REG (XFmode, regno);
+ 	do_restore (gen_fr_restore_x, reg, cfa_off);
+ 	cfa_off -= 16;
+       }
+ 
+   /* Restore ar.unat for real.  */
+   if (TEST_HARD_REG_BIT (current_frame_info.mask, AR_UNAT_REGNUM))
+     {
+       reg = gen_rtx_REG (DImode, AR_UNAT_REGNUM);
+       emit_move_insn (reg, ar_unat_save_reg);
+     }
+ 
+   gcc_assert (cfa_off == current_frame_info.spill_cfa_off);
+ 
+   finish_spill_pointers ();
+ 
+   if (current_frame_info.total_size
+       || cfun->machine->ia64_eh_epilogue_sp
+       || frame_pointer_needed)
+     {
+       /* ??? At this point we must generate a magic insn that appears to
+          modify the spill iterators, the stack pointer, and the frame
+ 	 pointer.  This would allow the most scheduling freedom.  For now,
+ 	 just hard stop.  */
+       emit_insn (gen_blockage ());
+     }
+ 
+   if (cfun->machine->ia64_eh_epilogue_sp)
+     emit_move_insn (stack_pointer_rtx, cfun->machine->ia64_eh_epilogue_sp);
+   else if (frame_pointer_needed)
+     {
+       insn = emit_move_insn (stack_pointer_rtx, hard_frame_pointer_rtx);
+       RTX_FRAME_RELATED_P (insn) = 1;
+       add_reg_note (insn, REG_CFA_ADJUST_CFA, NULL);
+     }
+   else if (current_frame_info.total_size)
+     {
+       rtx offset, frame_size_rtx;
+ 
+       frame_size_rtx = GEN_INT (current_frame_info.total_size);
+       if (satisfies_constraint_I (frame_size_rtx))
+ 	offset = frame_size_rtx;
+       else
+ 	{
+ 	  regno = next_scratch_gr_reg ();
+ 	  offset = gen_rtx_REG (DImode, regno);
+ 	  emit_move_insn (offset, frame_size_rtx);
+ 	}
+ 
+       insn = emit_insn (gen_adddi3 (stack_pointer_rtx, stack_pointer_rtx,
+ 				    offset));
+ 
+       RTX_FRAME_RELATED_P (insn) = 1;
+       add_reg_note (insn, REG_CFA_ADJUST_CFA,
+ 		    gen_rtx_SET (stack_pointer_rtx,
+ 				 gen_rtx_PLUS (DImode,
+ 					       stack_pointer_rtx,
+ 					       frame_size_rtx)));
+     }
+ 
+   if (cfun->machine->ia64_eh_epilogue_bsp)
+     emit_insn (gen_set_bsp (cfun->machine->ia64_eh_epilogue_bsp));
+ 
+   if (! sibcall_p)
+     emit_jump_insn (gen_return_internal (gen_rtx_REG (DImode, BR_REG (0))));
+   else
+     {
+       int fp = GR_REG (2);
+       /* We need a throw away register here, r0 and r1 are reserved,
+ 	 so r2 is the first available call clobbered register.  If
+ 	 there was a frame_pointer register, we may have swapped the
+ 	 names of r2 and HARD_FRAME_POINTER_REGNUM, so we have to make
+ 	 sure we're using the string "r2" when emitting the register
+ 	 name for the assembler.  */
+       if (current_frame_info.r[reg_fp] 
+           && current_frame_info.r[reg_fp] == GR_REG (2))
+ 	fp = HARD_FRAME_POINTER_REGNUM;
+ 
+       /* We must emit an alloc to force the input registers to become output
+ 	 registers.  Otherwise, if the callee tries to pass its parameters
+ 	 through to another call without an intervening alloc, then these
+ 	 values get lost.  */
+       /* ??? We don't need to preserve all input registers.  We only need to
+ 	 preserve those input registers used as arguments to the sibling call.
+ 	 It is unclear how to compute that number here.  */
+       if (current_frame_info.n_input_regs != 0)
+ 	{
+ 	  rtx n_inputs = GEN_INT (current_frame_info.n_input_regs);
+ 
+ 	  insn = emit_insn (gen_alloc (gen_rtx_REG (DImode, fp),
+ 				const0_rtx, const0_rtx,
+ 				n_inputs, const0_rtx));
+ 	  RTX_FRAME_RELATED_P (insn) = 1;
+ 
+ 	  /* ??? We need to mark the alloc as frame-related so that it gets
+ 	     passed into ia64_asm_unwind_emit for ia64-specific unwinding.
+ 	     But there's nothing dwarf2 related to be done wrt the register
+ 	     windows.  If we do nothing, dwarf2out will abort on the UNSPEC;
+ 	     the empty parallel means dwarf2out will not see anything.  */
+ 	  add_reg_note (insn, REG_FRAME_RELATED_EXPR,
+ 			gen_rtx_PARALLEL (VOIDmode, rtvec_alloc (0)));
+ 	}
+     }
+ }
+ 
+ /* Return 1 if br.ret can do all the work required to return from a
+    function.  */
+ 
+ int
+ ia64_direct_return (void)
+ {
+   if (reload_completed && ! frame_pointer_needed)
+     {
+       ia64_compute_frame_size (get_frame_size ());
+ 
+       return (current_frame_info.total_size == 0
+ 	      && current_frame_info.n_spilled == 0
+ 	      && current_frame_info.r[reg_save_b0] == 0
+ 	      && current_frame_info.r[reg_save_pr] == 0
+ 	      && current_frame_info.r[reg_save_ar_pfs] == 0
+ 	      && current_frame_info.r[reg_save_ar_unat] == 0
+ 	      && current_frame_info.r[reg_save_ar_lc] == 0);
+     }
+   return 0;
+ }
+ 
+ /* Return the magic cookie that we use to hold the return address
+    during early compilation.  */
+ 
+ rtx
+ ia64_return_addr_rtx (HOST_WIDE_INT count, rtx frame ATTRIBUTE_UNUSED)
+ {
+   if (count != 0)
+     return NULL;
+   return gen_rtx_UNSPEC (Pmode, gen_rtvec (1, const0_rtx), UNSPEC_RET_ADDR);
+ }
+ 
+ /* Split this value after reload, now that we know where the return
+    address is saved.  */
+ 
+ void
+ ia64_split_return_addr_rtx (rtx dest)
+ {
+   rtx src;
+ 
+   if (TEST_HARD_REG_BIT (current_frame_info.mask, BR_REG (0)))
+     {
+       if (current_frame_info.r[reg_save_b0] != 0)
+         {
+ 	  src = gen_rtx_REG (DImode, current_frame_info.r[reg_save_b0]);
+ 	  reg_emitted (reg_save_b0);
+ 	}
+       else
+ 	{
+ 	  HOST_WIDE_INT off;
+ 	  unsigned int regno;
+ 	  rtx off_r;
+ 
+ 	  /* Compute offset from CFA for BR0.  */
+ 	  /* ??? Must be kept in sync with ia64_expand_prologue.  */
+ 	  off = (current_frame_info.spill_cfa_off
+ 		 + current_frame_info.spill_size);
+ 	  for (regno = GR_REG (1); regno <= GR_REG (31); ++regno)
+ 	    if (TEST_HARD_REG_BIT (current_frame_info.mask, regno))
+ 	      off -= 8;
+ 
+ 	  /* Convert CFA offset to a register based offset.  */
+ 	  if (frame_pointer_needed)
+ 	    src = hard_frame_pointer_rtx;
+ 	  else
+ 	    {
+ 	      src = stack_pointer_rtx;
+ 	      off += current_frame_info.total_size;
+ 	    }
+ 
+ 	  /* Load address into scratch register.  */
+ 	  off_r = GEN_INT (off);
+ 	  if (satisfies_constraint_I (off_r))
+ 	    emit_insn (gen_adddi3 (dest, src, off_r));
+ 	  else
+ 	    {
+ 	      emit_move_insn (dest, off_r);
+ 	      emit_insn (gen_adddi3 (dest, src, dest));
+ 	    }
+ 
+ 	  src = gen_rtx_MEM (Pmode, dest);
+ 	}
+     }
+   else
+     src = gen_rtx_REG (DImode, BR_REG (0));
+ 
+   emit_move_insn (dest, src);
+ }
+ 
+ int
+ ia64_hard_regno_rename_ok (int from, int to)
+ {
+   /* Don't clobber any of the registers we reserved for the prologue.  */
+   unsigned int r;
+ 
+   for (r = reg_fp; r <= reg_save_ar_lc; r++)
+     if (to == current_frame_info.r[r] 
+         || from == current_frame_info.r[r]
+         || to == emitted_frame_related_regs[r]
+         || from == emitted_frame_related_regs[r])
+       return 0;
+ 
+   /* Don't use output registers outside the register frame.  */
+   if (OUT_REGNO_P (to) && to >= OUT_REG (current_frame_info.n_output_regs))
+     return 0;
+ 
+   /* Retain even/oddness on predicate register pairs.  */
+   if (PR_REGNO_P (from) && PR_REGNO_P (to))
+     return (from & 1) == (to & 1);
+ 
+   return 1;
+ }
+ 
+ /* Implement TARGET_HARD_REGNO_NREGS.
+ 
+    ??? We say that BImode PR values require two registers.  This allows us to
+    easily store the normal and inverted values.  We use CCImode to indicate
+    a single predicate register.  */
+ 
+ static unsigned int
+ ia64_hard_regno_nregs (unsigned int regno, machine_mode mode)
+ {
+   if (regno == PR_REG (0) && mode == DImode)
+     return 64;
+   if (PR_REGNO_P (regno) && (mode) == BImode)
+     return 2;
+   if ((PR_REGNO_P (regno) || GR_REGNO_P (regno)) && mode == CCImode)
+     return 1;
+   if (FR_REGNO_P (regno) && mode == XFmode)
+     return 1;
+   if (FR_REGNO_P (regno) && mode == RFmode)
+     return 1;
+   if (FR_REGNO_P (regno) && mode == XCmode)
+     return 2;
+   return CEIL (GET_MODE_SIZE (mode), UNITS_PER_WORD);
+ }
+ 
+ /* Implement TARGET_HARD_REGNO_MODE_OK.  */
+ 
+ static bool
+ ia64_hard_regno_mode_ok (unsigned int regno, machine_mode mode)
+ {
+   if (FR_REGNO_P (regno))
+     return (GET_MODE_CLASS (mode) != MODE_CC
+ 	    && mode != BImode
+ 	    && mode != TFmode);
+ 
+   if (PR_REGNO_P (regno))
+     return mode == BImode || GET_MODE_CLASS (mode) == MODE_CC;
+ 
+   if (GR_REGNO_P (regno))
+     return mode != XFmode && mode != XCmode && mode != RFmode;
+ 
+   if (AR_REGNO_P (regno))
+     return mode == DImode;
+ 
+   if (BR_REGNO_P (regno))
+     return mode == DImode;
+ 
+   return false;
+ }
+ 
+ /* Implement TARGET_MODES_TIEABLE_P.
+ 
+    Don't tie integer and FP modes, as that causes us to get integer registers
+    allocated for FP instructions.  XFmode only supported in FP registers so
+    we can't tie it with any other modes.  */
+ 
+ static bool
+ ia64_modes_tieable_p (machine_mode mode1, machine_mode mode2)
+ {
+   return (GET_MODE_CLASS (mode1) == GET_MODE_CLASS (mode2)
+ 	  && ((mode1 == XFmode || mode1 == XCmode || mode1 == RFmode)
+ 	      == (mode2 == XFmode || mode2 == XCmode || mode2 == RFmode))
+ 	  && (mode1 == BImode) == (mode2 == BImode));
+ }
+ 
+ /* Target hook for assembling integer objects.  Handle word-sized
+    aligned objects and detect the cases when @fptr is needed.  */
+ 
+ static bool
+ ia64_assemble_integer (rtx x, unsigned int size, int aligned_p)
+ {
+   if (size == POINTER_SIZE / BITS_PER_UNIT
+       && !(TARGET_NO_PIC || TARGET_AUTO_PIC)
+       && GET_CODE (x) == SYMBOL_REF
+       && SYMBOL_REF_FUNCTION_P (x))
+     {
+       static const char * const directive[2][2] = {
+ 	  /* 64-bit pointer */  /* 32-bit pointer */
+ 	{ "\tdata8.ua\t@fptr(", "\tdata4.ua\t@fptr("},	/* unaligned */
+ 	{ "\tdata8\t@fptr(",    "\tdata4\t@fptr("}	/* aligned */
+       };
+       fputs (directive[(aligned_p != 0)][POINTER_SIZE == 32], asm_out_file);
+       output_addr_const (asm_out_file, x);
+       fputs (")\n", asm_out_file);
+       return true;
+     }
+   return default_assemble_integer (x, size, aligned_p);
+ }
+ 
+ /* Emit the function prologue.  */
+ 
+ static void
+ ia64_output_function_prologue (FILE *file)
+ {
+   int mask, grsave, grsave_prev;
+ 
+   if (current_frame_info.need_regstk)
+     fprintf (file, "\t.regstk %d, %d, %d, %d\n",
+ 	     current_frame_info.n_input_regs,
+ 	     current_frame_info.n_local_regs,
+ 	     current_frame_info.n_output_regs,
+ 	     current_frame_info.n_rotate_regs);
+ 
+   if (ia64_except_unwind_info (&global_options) != UI_TARGET)
+     return;
+ 
+   /* Emit the .prologue directive.  */
+ 
+   mask = 0;
+   grsave = grsave_prev = 0;
+   if (current_frame_info.r[reg_save_b0] != 0)
+     {
+       mask |= 8;
+       grsave = grsave_prev = current_frame_info.r[reg_save_b0];
+     }
+   if (current_frame_info.r[reg_save_ar_pfs] != 0
+       && (grsave_prev == 0
+ 	  || current_frame_info.r[reg_save_ar_pfs] == grsave_prev + 1))
+     {
+       mask |= 4;
+       if (grsave_prev == 0)
+ 	grsave = current_frame_info.r[reg_save_ar_pfs];
+       grsave_prev = current_frame_info.r[reg_save_ar_pfs];
+     }
+   if (current_frame_info.r[reg_fp] != 0
+       && (grsave_prev == 0
+ 	  || current_frame_info.r[reg_fp] == grsave_prev + 1))
+     {
+       mask |= 2;
+       if (grsave_prev == 0)
+ 	grsave = HARD_FRAME_POINTER_REGNUM;
+       grsave_prev = current_frame_info.r[reg_fp];
+     }
+   if (current_frame_info.r[reg_save_pr] != 0
+       && (grsave_prev == 0
+ 	  || current_frame_info.r[reg_save_pr] == grsave_prev + 1))
+     {
+       mask |= 1;
+       if (grsave_prev == 0)
+ 	grsave = current_frame_info.r[reg_save_pr];
+     }
+ 
+   if (mask && TARGET_GNU_AS)
+     fprintf (file, "\t.prologue %d, %d\n", mask,
+ 	     ia64_dbx_register_number (grsave));
+   else
+     fputs ("\t.prologue\n", file);
+ 
+   /* Emit a .spill directive, if necessary, to relocate the base of
+      the register spill area.  */
+   if (current_frame_info.spill_cfa_off != -16)
+     fprintf (file, "\t.spill %ld\n",
+ 	     (long) (current_frame_info.spill_cfa_off
+ 		     + current_frame_info.spill_size));
+ }
+ 
+ /* Emit the .body directive at the scheduled end of the prologue.  */
+ 
+ static void
+ ia64_output_function_end_prologue (FILE *file)
+ {
+   if (ia64_except_unwind_info (&global_options) != UI_TARGET)
+     return;
+ 
+   fputs ("\t.body\n", file);
+ }
+ 
+ /* Emit the function epilogue.  */
+ 
+ static void
+ ia64_output_function_epilogue (FILE *)
+ {
+   int i;
+ 
+   if (current_frame_info.r[reg_fp])
+     {
+       const char *tmp = reg_names[HARD_FRAME_POINTER_REGNUM];
+       reg_names[HARD_FRAME_POINTER_REGNUM]
+ 	= reg_names[current_frame_info.r[reg_fp]];
+       reg_names[current_frame_info.r[reg_fp]] = tmp;
+       reg_emitted (reg_fp);
+     }
+   if (! TARGET_REG_NAMES)
+     {
+       for (i = 0; i < current_frame_info.n_input_regs; i++)
+ 	reg_names[IN_REG (i)] = ia64_input_reg_names[i];
+       for (i = 0; i < current_frame_info.n_local_regs; i++)
+ 	reg_names[LOC_REG (i)] = ia64_local_reg_names[i];
+       for (i = 0; i < current_frame_info.n_output_regs; i++)
+ 	reg_names[OUT_REG (i)] = ia64_output_reg_names[i];
+     }
+ 
+   current_frame_info.initialized = 0;
+ }
+ 
+ int
+ ia64_dbx_register_number (int regno)
+ {
+   /* In ia64_expand_prologue we quite literally renamed the frame pointer
+      from its home at loc79 to something inside the register frame.  We
+      must perform the same renumbering here for the debug info.  */
+   if (current_frame_info.r[reg_fp])
+     {
+       if (regno == HARD_FRAME_POINTER_REGNUM)
+ 	regno = current_frame_info.r[reg_fp];
+       else if (regno == current_frame_info.r[reg_fp])
+ 	regno = HARD_FRAME_POINTER_REGNUM;
+     }
+ 
+   if (IN_REGNO_P (regno))
+     return 32 + regno - IN_REG (0);
+   else if (LOC_REGNO_P (regno))
+     return 32 + current_frame_info.n_input_regs + regno - LOC_REG (0);
+   else if (OUT_REGNO_P (regno))
+     return (32 + current_frame_info.n_input_regs
+ 	    + current_frame_info.n_local_regs + regno - OUT_REG (0));
+   else
+     return regno;
+ }
+ 
+ /* Implement TARGET_TRAMPOLINE_INIT.
+ 
+    The trampoline should set the static chain pointer to value placed
+    into the trampoline and should branch to the specified routine.
+    To make the normal indirect-subroutine calling convention work,
+    the trampoline must look like a function descriptor; the first
+    word being the target address and the second being the target's
+    global pointer.
+ 
+    We abuse the concept of a global pointer by arranging for it
+    to point to the data we need to load.  The complete trampoline
+    has the following form:
+ 
+ 		+-------------------+ \
+ 	TRAMP:	| __ia64_trampoline | |
+ 		+-------------------+  > fake function descriptor
+ 		| TRAMP+16          | |
+ 		+-------------------+ /
+ 		| target descriptor |
+ 		+-------------------+
+ 		| static link	    |
+ 		+-------------------+
+ */
+ 
+ static void
+ ia64_trampoline_init (rtx m_tramp, tree fndecl, rtx static_chain)
+ {
+   rtx fnaddr = XEXP (DECL_RTL (fndecl), 0);
+   rtx addr, addr_reg, tramp, eight = GEN_INT (8);
+ 
+   /* The Intel assembler requires that the global __ia64_trampoline symbol
+      be declared explicitly */
+   if (!TARGET_GNU_AS)
+     {
+       static bool declared_ia64_trampoline = false;
+ 
+       if (!declared_ia64_trampoline)
+ 	{
+ 	  declared_ia64_trampoline = true;
+ 	  (*targetm.asm_out.globalize_label) (asm_out_file,
+ 					      "__ia64_trampoline");
+ 	}
+     }
+ 
+   /* Make sure addresses are Pmode even if we are in ILP32 mode. */
+   addr = convert_memory_address (Pmode, XEXP (m_tramp, 0));
+   fnaddr = convert_memory_address (Pmode, fnaddr);
+   static_chain = convert_memory_address (Pmode, static_chain);
+ 
+   /* Load up our iterator.  */
+   addr_reg = copy_to_reg (addr);
+   m_tramp = adjust_automodify_address (m_tramp, Pmode, addr_reg, 0);
+ 
+   /* The first two words are the fake descriptor:
+      __ia64_trampoline, ADDR+16.  */
+   tramp = gen_rtx_SYMBOL_REF (Pmode, "__ia64_trampoline");
+   if (TARGET_ABI_OPEN_VMS)
+     {
+       /* HP decided to break the ELF ABI on VMS (to deal with an ambiguity
+ 	 in the Macro-32 compiler) and changed the semantics of the LTOFF22
+ 	 relocation against function symbols to make it identical to the
+ 	 LTOFF_FPTR22 relocation.  Emit the latter directly to stay within
+ 	 strict ELF and dereference to get the bare code address.  */
+       rtx reg = gen_reg_rtx (Pmode);
+       SYMBOL_REF_FLAGS (tramp) |= SYMBOL_FLAG_FUNCTION;
+       emit_move_insn (reg, tramp);
+       emit_move_insn (reg, gen_rtx_MEM (Pmode, reg));
+       tramp = reg;
+    }
+   emit_move_insn (m_tramp, tramp);
+   emit_insn (gen_adddi3 (addr_reg, addr_reg, eight));
+   m_tramp = adjust_automodify_address (m_tramp, VOIDmode, NULL, 8);
+ 
+   emit_move_insn (m_tramp, force_reg (Pmode, plus_constant (Pmode, addr, 16)));
+   emit_insn (gen_adddi3 (addr_reg, addr_reg, eight));
+   m_tramp = adjust_automodify_address (m_tramp, VOIDmode, NULL, 8);
+ 
+   /* The third word is the target descriptor.  */
+   emit_move_insn (m_tramp, force_reg (Pmode, fnaddr));
+   emit_insn (gen_adddi3 (addr_reg, addr_reg, eight));
+   m_tramp = adjust_automodify_address (m_tramp, VOIDmode, NULL, 8);
+ 
+   /* The fourth word is the static chain.  */
+   emit_move_insn (m_tramp, static_chain);
+ }
+ \f
+ /* Do any needed setup for a variadic function.  CUM has not been updated
+    for the last named argument, which is given by ARG.
+ 
+    We generate the actual spill instructions during prologue generation.  */
+ 
+ static void
+ ia64_setup_incoming_varargs (cumulative_args_t cum,
+ 			     const function_arg_info &arg,
+ 			     int *pretend_size,
+ 			     int second_time ATTRIBUTE_UNUSED)
+ {
+   CUMULATIVE_ARGS next_cum = *get_cumulative_args (cum);
+ 
+   /* Skip the current argument.  */
+   ia64_function_arg_advance (pack_cumulative_args (&next_cum), arg);
+ 
+   if (next_cum.words < MAX_ARGUMENT_SLOTS)
+     {
+       int n = MAX_ARGUMENT_SLOTS - next_cum.words;
+       *pretend_size = n * UNITS_PER_WORD;
+       cfun->machine->n_varargs = n;
+     }
+ }
+ 
+ /* Check whether TYPE is a homogeneous floating point aggregate.  If
+    it is, return the mode of the floating point type that appears
+    in all leafs.  If it is not, return VOIDmode.
+ 
+    An aggregate is a homogeneous floating point aggregate is if all
+    fields/elements in it have the same floating point type (e.g,
+    SFmode).  128-bit quad-precision floats are excluded.
+ 
+    Variable sized aggregates should never arrive here, since we should
+    have already decided to pass them by reference.  Top-level zero-sized
+    aggregates are excluded because our parallels crash the middle-end.  */
+ 
+ static machine_mode
+ hfa_element_mode (const_tree type, bool nested)
+ {
+   machine_mode element_mode = VOIDmode;
+   machine_mode mode;
+   enum tree_code code = TREE_CODE (type);
+   int know_element_mode = 0;
+   tree t;
+ 
+   if (!nested && (!TYPE_SIZE (type) || integer_zerop (TYPE_SIZE (type))))
+     return VOIDmode;
+ 
+   switch (code)
+     {
+     case VOID_TYPE:	case INTEGER_TYPE:	case ENUMERAL_TYPE:
+     case BOOLEAN_TYPE:	case POINTER_TYPE:
+     case OFFSET_TYPE:	case REFERENCE_TYPE:	case METHOD_TYPE:
+     case LANG_TYPE:		case FUNCTION_TYPE:
+       return VOIDmode;
+ 
+       /* Fortran complex types are supposed to be HFAs, so we need to handle
+ 	 gcc's COMPLEX_TYPEs as HFAs.  We need to exclude the integral complex
+ 	 types though.  */
+     case COMPLEX_TYPE:
+       if (GET_MODE_CLASS (TYPE_MODE (type)) == MODE_COMPLEX_FLOAT
+ 	  && TYPE_MODE (type) != TCmode)
+ 	return GET_MODE_INNER (TYPE_MODE (type));
+       else
+ 	return VOIDmode;
+ 
+     case REAL_TYPE:
+       /* We want to return VOIDmode for raw REAL_TYPEs, but the actual
+ 	 mode if this is contained within an aggregate.  */
+       if (nested && TYPE_MODE (type) != TFmode)
+ 	return TYPE_MODE (type);
+       else
+ 	return VOIDmode;
+ 
+     case ARRAY_TYPE:
+       return hfa_element_mode (TREE_TYPE (type), 1);
+ 
+     case RECORD_TYPE:
+     case UNION_TYPE:
+     case QUAL_UNION_TYPE:
+       for (t = TYPE_FIELDS (type); t; t = DECL_CHAIN (t))
+ 	{
+ 	  if (TREE_CODE (t) != FIELD_DECL || DECL_FIELD_ABI_IGNORED (t))
+ 	    continue;
+ 
+ 	  mode = hfa_element_mode (TREE_TYPE (t), 1);
+ 	  if (know_element_mode)
+ 	    {
+ 	      if (mode != element_mode)
+ 		return VOIDmode;
+ 	    }
+ 	  else if (GET_MODE_CLASS (mode) != MODE_FLOAT)
+ 	    return VOIDmode;
+ 	  else
+ 	    {
+ 	      know_element_mode = 1;
+ 	      element_mode = mode;
+ 	    }
+ 	}
+       return element_mode;
+ 
+     default:
+       /* If we reach here, we probably have some front-end specific type
+ 	 that the backend doesn't know about.  This can happen via the
+ 	 aggregate_value_p call in init_function_start.  All we can do is
+ 	 ignore unknown tree types.  */
+       return VOIDmode;
+     }
+ 
+   return VOIDmode;
+ }
+ 
+ /* Return the number of words required to hold a quantity of TYPE and MODE
+    when passed as an argument.  */
+ static int
+ ia64_function_arg_words (const_tree type, machine_mode mode)
+ {
+   int words;
+ 
+   if (mode == BLKmode)
+     words = int_size_in_bytes (type);
+   else
+     words = GET_MODE_SIZE (mode);
+ 
+   return (words + UNITS_PER_WORD - 1) / UNITS_PER_WORD;  /* round up */
+ }
+ 
+ /* Return the number of registers that should be skipped so the current
+    argument (described by TYPE and WORDS) will be properly aligned.
+ 
+    Integer and float arguments larger than 8 bytes start at the next
+    even boundary.  Aggregates larger than 8 bytes start at the next
+    even boundary if the aggregate has 16 byte alignment.  Note that
+    in the 32-bit ABI, TImode and TFmode have only 8-byte alignment
+    but are still to be aligned in registers.
+ 
+    ??? The ABI does not specify how to handle aggregates with
+    alignment from 9 to 15 bytes, or greater than 16.  We handle them
+    all as if they had 16 byte alignment.  Such aggregates can occur
+    only if gcc extensions are used.  */
+ static int
+ ia64_function_arg_offset (const CUMULATIVE_ARGS *cum,
+ 			  const_tree type, int words)
+ {
+   /* No registers are skipped on VMS.  */
+   if (TARGET_ABI_OPEN_VMS || (cum->words & 1) == 0)
+     return 0;
+ 
+   if (type
+       && TREE_CODE (type) != INTEGER_TYPE
+       && TREE_CODE (type) != REAL_TYPE)
+     return TYPE_ALIGN (type) > 8 * BITS_PER_UNIT;
+   else
+     return words > 1;
+ }
+ 
+ /* Return rtx for register where argument is passed, or zero if it is passed
+    on the stack.  */
+ /* ??? 128-bit quad-precision floats are always passed in general
+    registers.  */
+ 
+ static rtx
+ ia64_function_arg_1 (cumulative_args_t cum_v, const function_arg_info &arg,
+ 		     bool incoming)
+ {
+   const CUMULATIVE_ARGS *cum = get_cumulative_args (cum_v);
+ 
+   int basereg = (incoming ? GR_ARG_FIRST : AR_ARG_FIRST);
+   int words = ia64_function_arg_words (arg.type, arg.mode);
+   int offset = ia64_function_arg_offset (cum, arg.type, words);
+   machine_mode hfa_mode = VOIDmode;
+ 
+   /* For OPEN VMS, emit the instruction setting up the argument register here,
+      when we know this will be together with the other arguments setup related
+      insns.  This is not the conceptually best place to do this, but this is
+      the easiest as we have convenient access to cumulative args info.  */
+ 
+   if (TARGET_ABI_OPEN_VMS && arg.end_marker_p ())
+     {
+       unsigned HOST_WIDE_INT regval = cum->words;
+       int i;
+ 
+       for (i = 0; i < 8; i++)
+ 	regval |= ((int) cum->atypes[i]) << (i * 3 + 8);
+ 
+       emit_move_insn (gen_rtx_REG (DImode, GR_REG (25)),
+ 		      GEN_INT (regval));
+     }
+ 
+   /* If all argument slots are used, then it must go on the stack.  */
+   if (cum->words + offset >= MAX_ARGUMENT_SLOTS)
+     return 0;
+ 
+   /* On OpenVMS argument is either in Rn or Fn.  */
+   if (TARGET_ABI_OPEN_VMS)
+     {
+       if (FLOAT_MODE_P (arg.mode))
+ 	return gen_rtx_REG (arg.mode, FR_ARG_FIRST + cum->words);
+       else
+ 	return gen_rtx_REG (arg.mode, basereg + cum->words);
+     }
+ 
+   /* Check for and handle homogeneous FP aggregates.  */
+   if (arg.type)
+     hfa_mode = hfa_element_mode (arg.type, 0);
+ 
+   /* Unnamed prototyped hfas are passed as usual.  Named prototyped hfas
+      and unprototyped hfas are passed specially.  */
+   if (hfa_mode != VOIDmode && (! cum->prototype || arg.named))
+     {
+       rtx loc[16];
+       int i = 0;
+       int fp_regs = cum->fp_regs;
+       int int_regs = cum->words + offset;
+       int hfa_size = GET_MODE_SIZE (hfa_mode);
+       int byte_size;
+       int args_byte_size;
+ 
+       /* If prototyped, pass it in FR regs then GR regs.
+ 	 If not prototyped, pass it in both FR and GR regs.
+ 
+ 	 If this is an SFmode aggregate, then it is possible to run out of
+ 	 FR regs while GR regs are still left.  In that case, we pass the
+ 	 remaining part in the GR regs.  */
+ 
+       /* Fill the FP regs.  We do this always.  We stop if we reach the end
+ 	 of the argument, the last FP register, or the last argument slot.  */
+ 
+       byte_size = arg.promoted_size_in_bytes ();
+       args_byte_size = int_regs * UNITS_PER_WORD;
+       offset = 0;
+       for (; (offset < byte_size && fp_regs < MAX_ARGUMENT_SLOTS
+ 	      && args_byte_size < (MAX_ARGUMENT_SLOTS * UNITS_PER_WORD)); i++)
+ 	{
+ 	  loc[i] = gen_rtx_EXPR_LIST (VOIDmode,
+ 				      gen_rtx_REG (hfa_mode, (FR_ARG_FIRST
+ 							      + fp_regs)),
+ 				      GEN_INT (offset));
+ 	  offset += hfa_size;
+ 	  args_byte_size += hfa_size;
+ 	  fp_regs++;
+ 	}
+ 
+       /* If no prototype, then the whole thing must go in GR regs.  */
+       if (! cum->prototype)
+ 	offset = 0;
+       /* If this is an SFmode aggregate, then we might have some left over
+ 	 that needs to go in GR regs.  */
+       else if (byte_size != offset)
+ 	int_regs += offset / UNITS_PER_WORD;
+ 
+       /* Fill in the GR regs.  We must use DImode here, not the hfa mode.  */
+ 
+       for (; offset < byte_size && int_regs < MAX_ARGUMENT_SLOTS; i++)
+ 	{
+ 	  machine_mode gr_mode = DImode;
+ 	  unsigned int gr_size;
+ 
+ 	  /* If we have an odd 4 byte hunk because we ran out of FR regs,
+ 	     then this goes in a GR reg left adjusted/little endian, right
+ 	     adjusted/big endian.  */
+ 	  /* ??? Currently this is handled wrong, because 4-byte hunks are
+ 	     always right adjusted/little endian.  */
+ 	  if (offset & 0x4)
+ 	    gr_mode = SImode;
+ 	  /* If we have an even 4 byte hunk because the aggregate is a
+ 	     multiple of 4 bytes in size, then this goes in a GR reg right
+ 	     adjusted/little endian.  */
+ 	  else if (byte_size - offset == 4)
+ 	    gr_mode = SImode;
+ 
+ 	  loc[i] = gen_rtx_EXPR_LIST (VOIDmode,
+ 				      gen_rtx_REG (gr_mode, (basereg
+ 							     + int_regs)),
+ 				      GEN_INT (offset));
+ 
+ 	  gr_size = GET_MODE_SIZE (gr_mode);
+ 	  offset += gr_size;
+ 	  if (gr_size == UNITS_PER_WORD
+ 	      || (gr_size < UNITS_PER_WORD && offset % UNITS_PER_WORD == 0))
+ 	    int_regs++;
+ 	  else if (gr_size > UNITS_PER_WORD)
+ 	    int_regs += gr_size / UNITS_PER_WORD;
+ 	}
+       return gen_rtx_PARALLEL (arg.mode, gen_rtvec_v (i, loc));
+     }
+   
+   /* Integral and aggregates go in general registers.  If we have run out of
+      FR registers, then FP values must also go in general registers.  This can
+      happen when we have a SFmode HFA.  */
+   else if (arg.mode == TFmode || arg.mode == TCmode
+ 	   || !FLOAT_MODE_P (arg.mode)
+ 	   || cum->fp_regs == MAX_ARGUMENT_SLOTS)
+     {
+       int byte_size = arg.promoted_size_in_bytes ();
+       if (BYTES_BIG_ENDIAN
+ 	  && (arg.mode == BLKmode || arg.aggregate_type_p ())
+ 	  && byte_size < UNITS_PER_WORD
+ 	  && byte_size > 0)
+ 	{
+ 	  rtx gr_reg = gen_rtx_EXPR_LIST (VOIDmode,
+ 					  gen_rtx_REG (DImode,
+ 						       (basereg + cum->words
+ 							+ offset)),
+ 					  const0_rtx);
+ 	  return gen_rtx_PARALLEL (arg.mode, gen_rtvec (1, gr_reg));
+ 	}
+       else
+ 	return gen_rtx_REG (arg.mode, basereg + cum->words + offset);
+ 
+     }
+ 
+   /* If there is a prototype, then FP values go in a FR register when
+      named, and in a GR register when unnamed.  */
+   else if (cum->prototype)
+     {
+       if (arg.named)
+ 	return gen_rtx_REG (arg.mode, FR_ARG_FIRST + cum->fp_regs);
+       /* In big-endian mode, an anonymous SFmode value must be represented
+          as (parallel:SF [(expr_list (reg:DI n) (const_int 0))]) to force
+ 	 the value into the high half of the general register.  */
+       else if (BYTES_BIG_ENDIAN && arg.mode == SFmode)
+ 	return gen_rtx_PARALLEL (arg.mode,
+ 		 gen_rtvec (1,
+                    gen_rtx_EXPR_LIST (VOIDmode,
+ 		     gen_rtx_REG (DImode, basereg + cum->words + offset),
+ 				      const0_rtx)));
+       else
+ 	return gen_rtx_REG (arg.mode, basereg + cum->words + offset);
+     }
+   /* If there is no prototype, then FP values go in both FR and GR
+      registers.  */
+   else
+     {
+       /* See comment above.  */
+       machine_mode inner_mode =
+ 	(BYTES_BIG_ENDIAN && arg.mode == SFmode) ? DImode : arg.mode;
+ 
+       rtx fp_reg = gen_rtx_EXPR_LIST (VOIDmode,
+ 				      gen_rtx_REG (arg.mode, (FR_ARG_FIRST
+ 							  + cum->fp_regs)),
+ 				      const0_rtx);
+       rtx gr_reg = gen_rtx_EXPR_LIST (VOIDmode,
+ 				      gen_rtx_REG (inner_mode,
+ 						   (basereg + cum->words
+ 						    + offset)),
+ 				      const0_rtx);
+ 
+       return gen_rtx_PARALLEL (arg.mode, gen_rtvec (2, fp_reg, gr_reg));
+     }
+ }
+ 
+ /* Implement TARGET_FUNCION_ARG target hook.  */
+ 
+ static rtx
+ ia64_function_arg (cumulative_args_t cum, const function_arg_info &arg)
+ {
+   return ia64_function_arg_1 (cum, arg, false);
+ }
+ 
+ /* Implement TARGET_FUNCION_INCOMING_ARG target hook.  */
+ 
+ static rtx
+ ia64_function_incoming_arg (cumulative_args_t cum,
+ 			    const function_arg_info &arg)
+ {
+   return ia64_function_arg_1 (cum, arg, true);
+ }
+ 
+ /* Return number of bytes, at the beginning of the argument, that must be
+    put in registers.  0 is the argument is entirely in registers or entirely
+    in memory.  */
+ 
+ static int
+ ia64_arg_partial_bytes (cumulative_args_t cum_v, const function_arg_info &arg)
+ {
+   CUMULATIVE_ARGS *cum = get_cumulative_args (cum_v);
+ 
+   int words = ia64_function_arg_words (arg.type, arg.mode);
+   int offset = ia64_function_arg_offset (cum, arg.type, words);
+ 
+   /* If all argument slots are used, then it must go on the stack.  */
+   if (cum->words + offset >= MAX_ARGUMENT_SLOTS)
+     return 0;
+ 
+   /* It doesn't matter whether the argument goes in FR or GR regs.  If
+      it fits within the 8 argument slots, then it goes entirely in
+      registers.  If it extends past the last argument slot, then the rest
+      goes on the stack.  */
+ 
+   if (words + cum->words + offset <= MAX_ARGUMENT_SLOTS)
+     return 0;
+ 
+   return (MAX_ARGUMENT_SLOTS - cum->words - offset) * UNITS_PER_WORD;
+ }
+ 
+ /* Return ivms_arg_type based on machine_mode.  */
+ 
+ static enum ivms_arg_type
+ ia64_arg_type (machine_mode mode)
+ {
+   switch (mode)
+     {
+     case E_SFmode:
+       return FS;
+     case E_DFmode:
+       return FT;
+     default:
+       return I64;
+     }
+ }
+ 
+ /* Update CUM to point after this argument.  This is patterned after
+    ia64_function_arg.  */
+ 
+ static void
+ ia64_function_arg_advance (cumulative_args_t cum_v,
+ 			   const function_arg_info &arg)
+ {
+   CUMULATIVE_ARGS *cum = get_cumulative_args (cum_v);
+   int words = ia64_function_arg_words (arg.type, arg.mode);
+   int offset = ia64_function_arg_offset (cum, arg.type, words);
+   machine_mode hfa_mode = VOIDmode;
+ 
+   /* If all arg slots are already full, then there is nothing to do.  */
+   if (cum->words >= MAX_ARGUMENT_SLOTS)
+     {
+       cum->words += words + offset;
+       return;
+     }
+ 
+   cum->atypes[cum->words] = ia64_arg_type (arg.mode);
+   cum->words += words + offset;
+ 
+   /* On OpenVMS argument is either in Rn or Fn.  */
+   if (TARGET_ABI_OPEN_VMS)
+     {
+       cum->int_regs = cum->words;
+       cum->fp_regs = cum->words;
+       return;
+     }
+ 
+   /* Check for and handle homogeneous FP aggregates.  */
+   if (arg.type)
+     hfa_mode = hfa_element_mode (arg.type, 0);
+ 
+   /* Unnamed prototyped hfas are passed as usual.  Named prototyped hfas
+      and unprototyped hfas are passed specially.  */
+   if (hfa_mode != VOIDmode && (! cum->prototype || arg.named))
+     {
+       int fp_regs = cum->fp_regs;
+       /* This is the original value of cum->words + offset.  */
+       int int_regs = cum->words - words;
+       int hfa_size = GET_MODE_SIZE (hfa_mode);
+       int byte_size;
+       int args_byte_size;
+ 
+       /* If prototyped, pass it in FR regs then GR regs.
+ 	 If not prototyped, pass it in both FR and GR regs.
+ 
+ 	 If this is an SFmode aggregate, then it is possible to run out of
+ 	 FR regs while GR regs are still left.  In that case, we pass the
+ 	 remaining part in the GR regs.  */
+ 
+       /* Fill the FP regs.  We do this always.  We stop if we reach the end
+ 	 of the argument, the last FP register, or the last argument slot.  */
+ 
+       byte_size = arg.promoted_size_in_bytes ();
+       args_byte_size = int_regs * UNITS_PER_WORD;
+       offset = 0;
+       for (; (offset < byte_size && fp_regs < MAX_ARGUMENT_SLOTS
+ 	      && args_byte_size < (MAX_ARGUMENT_SLOTS * UNITS_PER_WORD));)
+ 	{
+ 	  offset += hfa_size;
+ 	  args_byte_size += hfa_size;
+ 	  fp_regs++;
+ 	}
+ 
+       cum->fp_regs = fp_regs;
+     }
+ 
+   /* Integral and aggregates go in general registers.  So do TFmode FP values.
+      If we have run out of FR registers, then other FP values must also go in
+      general registers.  This can happen when we have a SFmode HFA.  */
+   else if (arg.mode == TFmode || arg.mode == TCmode
+            || !FLOAT_MODE_P (arg.mode)
+ 	   || cum->fp_regs == MAX_ARGUMENT_SLOTS)
+     cum->int_regs = cum->words;
+ 
+   /* If there is a prototype, then FP values go in a FR register when
+      named, and in a GR register when unnamed.  */
+   else if (cum->prototype)
+     {
+       if (! arg.named)
+ 	cum->int_regs = cum->words;
+       else
+ 	/* ??? Complex types should not reach here.  */
+ 	cum->fp_regs
+ 	  += (GET_MODE_CLASS (arg.mode) == MODE_COMPLEX_FLOAT ? 2 : 1);
+     }
+   /* If there is no prototype, then FP values go in both FR and GR
+      registers.  */
+   else
+     {
+       /* ??? Complex types should not reach here.  */
+       cum->fp_regs
+ 	+= (GET_MODE_CLASS (arg.mode) == MODE_COMPLEX_FLOAT ? 2 : 1);
+       cum->int_regs = cum->words;
+     }
+ }
+ 
+ /* Arguments with alignment larger than 8 bytes start at the next even
+    boundary.  On ILP32 HPUX, TFmode arguments start on next even boundary
+    even though their normal alignment is 8 bytes.  See ia64_function_arg.  */
+ 
+ static unsigned int
+ ia64_function_arg_boundary (machine_mode mode, const_tree type)
+ {
+   if (mode == TFmode && TARGET_HPUX && TARGET_ILP32)
+     return PARM_BOUNDARY * 2;
+ 
+   if (type)
+     {
+       if (TYPE_ALIGN (type) > PARM_BOUNDARY)
+         return PARM_BOUNDARY * 2;
+       else
+         return PARM_BOUNDARY;
+     }
+ 
+   if (GET_MODE_BITSIZE (mode) > PARM_BOUNDARY)
+     return PARM_BOUNDARY * 2;
+   else
+     return PARM_BOUNDARY;
+ }
+ 
+ /* True if it is OK to do sibling call optimization for the specified
+    call expression EXP.  DECL will be the called function, or NULL if
+    this is an indirect call.  */
+ static bool
+ ia64_function_ok_for_sibcall (tree decl, tree exp ATTRIBUTE_UNUSED)
+ {
+   /* We can't perform a sibcall if the current function has the syscall_linkage
+      attribute.  */
+   if (lookup_attribute ("syscall_linkage",
+ 			TYPE_ATTRIBUTES (TREE_TYPE (current_function_decl))))
+     return false;
+ 
+   /* We must always return with our current GP.  This means we can
+      only sibcall to functions defined in the current module unless
+      TARGET_CONST_GP is set to true.  */
+   return (decl && (*targetm.binds_local_p) (decl)) || TARGET_CONST_GP;
+ }
+ \f
+ 
+ /* Implement va_arg.  */
+ 
+ static tree
+ ia64_gimplify_va_arg (tree valist, tree type, gimple_seq *pre_p,
+ 		      gimple_seq *post_p)
+ {
+   /* Variable sized types are passed by reference.  */
+   if (pass_va_arg_by_reference (type))
+     {
+       tree ptrtype = build_pointer_type (type);
+       tree addr = std_gimplify_va_arg_expr (valist, ptrtype, pre_p, post_p);
+       return build_va_arg_indirect_ref (addr);
+     }
+ 
+   /* Aggregate arguments with alignment larger than 8 bytes start at
+      the next even boundary.  Integer and floating point arguments
+      do so if they are larger than 8 bytes, whether or not they are
+      also aligned larger than 8 bytes.  */
+   if ((TREE_CODE (type) == REAL_TYPE || TREE_CODE (type) == INTEGER_TYPE)
+       ? int_size_in_bytes (type) > 8 : TYPE_ALIGN (type) > 8 * BITS_PER_UNIT)
+     {
+       tree t = fold_build_pointer_plus_hwi (valist, 2 * UNITS_PER_WORD - 1);
+       t = build2 (BIT_AND_EXPR, TREE_TYPE (t), t,
+ 		  build_int_cst (TREE_TYPE (t), -2 * UNITS_PER_WORD));
+       gimplify_assign (unshare_expr (valist), t, pre_p);
+     }
+ 
+   return std_gimplify_va_arg_expr (valist, type, pre_p, post_p);
+ }
+ \f
+ /* Return 1 if function return value returned in memory.  Return 0 if it is
+    in a register.  */
+ 
+ static bool
+ ia64_return_in_memory (const_tree valtype, const_tree fntype ATTRIBUTE_UNUSED)
+ {
+   machine_mode mode;
+   machine_mode hfa_mode;
+   HOST_WIDE_INT byte_size;
+ 
+   mode = TYPE_MODE (valtype);
+   byte_size = GET_MODE_SIZE (mode);
+   if (mode == BLKmode)
+     {
+       byte_size = int_size_in_bytes (valtype);
+       if (byte_size < 0)
+ 	return true;
+     }
+ 
+   /* Hfa's with up to 8 elements are returned in the FP argument registers.  */
+ 
+   hfa_mode = hfa_element_mode (valtype, 0);
+   if (hfa_mode != VOIDmode)
+     {
+       int hfa_size = GET_MODE_SIZE (hfa_mode);
+ 
+       if (byte_size / hfa_size > MAX_ARGUMENT_SLOTS)
+ 	return true;
+       else
+ 	return false;
+     }
+   else if (byte_size > UNITS_PER_WORD * MAX_INT_RETURN_SLOTS)
+     return true;
+   else
+     return false;
+ }
+ 
+ /* Return rtx for register that holds the function return value.  */
+ 
+ static rtx
+ ia64_function_value (const_tree valtype,
+ 		     const_tree fn_decl_or_type,
+ 		     bool outgoing ATTRIBUTE_UNUSED)
+ {
+   machine_mode mode;
+   machine_mode hfa_mode;
+   int unsignedp;
+   const_tree func = fn_decl_or_type;
+ 
+   if (fn_decl_or_type
+       && !DECL_P (fn_decl_or_type))
+     func = NULL;
+   
+   mode = TYPE_MODE (valtype);
+   hfa_mode = hfa_element_mode (valtype, 0);
+ 
+   if (hfa_mode != VOIDmode)
+     {
+       rtx loc[8];
+       int i;
+       int hfa_size;
+       int byte_size;
+       int offset;
+ 
+       hfa_size = GET_MODE_SIZE (hfa_mode);
+       byte_size = ((mode == BLKmode)
+ 		   ? int_size_in_bytes (valtype) : GET_MODE_SIZE (mode));
+       offset = 0;
+       for (i = 0; offset < byte_size; i++)
+ 	{
+ 	  loc[i] = gen_rtx_EXPR_LIST (VOIDmode,
+ 				      gen_rtx_REG (hfa_mode, FR_ARG_FIRST + i),
+ 				      GEN_INT (offset));
+ 	  offset += hfa_size;
+ 	}
+       return gen_rtx_PARALLEL (mode, gen_rtvec_v (i, loc));
+     }
+   else if (FLOAT_TYPE_P (valtype) && mode != TFmode && mode != TCmode)
+     return gen_rtx_REG (mode, FR_ARG_FIRST);
+   else
+     {
+       bool need_parallel = false;
+ 
+       /* In big-endian mode, we need to manage the layout of aggregates
+ 	 in the registers so that we get the bits properly aligned in
+ 	 the highpart of the registers.  */
+       if (BYTES_BIG_ENDIAN
+ 	  && (mode == BLKmode || (valtype && AGGREGATE_TYPE_P (valtype))))
+ 	need_parallel = true;
+ 
+       /* Something like struct S { long double x; char a[0] } is not an
+ 	 HFA structure, and therefore doesn't go in fp registers.  But
+ 	 the middle-end will give it XFmode anyway, and XFmode values
+ 	 don't normally fit in integer registers.  So we need to smuggle
+ 	 the value inside a parallel.  */
+       else if (mode == XFmode || mode == XCmode || mode == RFmode)
+ 	need_parallel = true;
+ 
+       if (need_parallel)
+ 	{
+ 	  rtx loc[8];
+ 	  int offset;
+ 	  int bytesize;
+ 	  int i;
+ 
+ 	  offset = 0;
+ 	  bytesize = int_size_in_bytes (valtype);
+ 	  /* An empty PARALLEL is invalid here, but the return value
+ 	     doesn't matter for empty structs.  */
+ 	  if (bytesize == 0)
+ 	    return gen_rtx_REG (mode, GR_RET_FIRST);
+ 	  for (i = 0; offset < bytesize; i++)
+ 	    {
+ 	      loc[i] = gen_rtx_EXPR_LIST (VOIDmode,
+ 					  gen_rtx_REG (DImode,
+ 						       GR_RET_FIRST + i),
+ 					  GEN_INT (offset));
+ 	      offset += UNITS_PER_WORD;
+ 	    }
+ 	  return gen_rtx_PARALLEL (mode, gen_rtvec_v (i, loc));
+ 	}
+ 
+       mode = promote_function_mode (valtype, mode, &unsignedp,
+                                     func ? TREE_TYPE (func) : NULL_TREE,
+                                     true);
+ 
+       return gen_rtx_REG (mode, GR_RET_FIRST);
+     }
+ }
+ 
+ /* Worker function for TARGET_LIBCALL_VALUE.  */
+ 
+ static rtx
+ ia64_libcall_value (machine_mode mode,
+ 		    const_rtx fun ATTRIBUTE_UNUSED)
+ {
+   return gen_rtx_REG (mode,
+ 		      (((GET_MODE_CLASS (mode) == MODE_FLOAT
+ 			 || GET_MODE_CLASS (mode) == MODE_COMPLEX_FLOAT)
+ 			&& (mode) != TFmode)
+ 		       ? FR_RET_FIRST : GR_RET_FIRST));
+ }
+ 
+ /* Worker function for FUNCTION_VALUE_REGNO_P.  */
+ 
+ static bool
+ ia64_function_value_regno_p (const unsigned int regno)
+ {
+   return ((regno >= GR_RET_FIRST && regno <= GR_RET_LAST)
+           || (regno >= FR_RET_FIRST && regno <= FR_RET_LAST));
+ }
+ 
+ /* This is called from dwarf2out.cc via TARGET_ASM_OUTPUT_DWARF_DTPREL.
+    We need to emit DTP-relative relocations.  */
+ 
+ static void
+ ia64_output_dwarf_dtprel (FILE *file, int size, rtx x)
+ {
+   gcc_assert (size == 4 || size == 8);
+   if (size == 4)
+     fputs ("\tdata4.ua\t@dtprel(", file);
+   else
+     fputs ("\tdata8.ua\t@dtprel(", file);
+   output_addr_const (file, x);
+   fputs (")", file);
+ }
+ 
+ /* Print a memory address as an operand to reference that memory location.  */
+ 
+ /* ??? Do we need this?  It gets used only for 'a' operands.  We could perhaps
+    also call this from ia64_print_operand for memory addresses.  */
+ 
+ static void
+ ia64_print_operand_address (FILE * stream ATTRIBUTE_UNUSED,
+ 			    machine_mode /*mode*/,
+ 			    rtx address ATTRIBUTE_UNUSED)
+ {
+ }
+ 
+ /* Print an operand to an assembler instruction.
+    C	Swap and print a comparison operator.
+    D	Print an FP comparison operator.
+    E    Print 32 - constant, for SImode shifts as extract.
+    e    Print 64 - constant, for DImode rotates.
+    F	A floating point constant 0.0 emitted as f0, or 1.0 emitted as f1, or
+         a floating point register emitted normally.
+    G	A floating point constant.
+    I	Invert a predicate register by adding 1.
+    J    Select the proper predicate register for a condition.
+    j    Select the inverse predicate register for a condition.
+    O	Append .acq for volatile load.
+    P	Postincrement of a MEM.
+    Q	Append .rel for volatile store.
+    R	Print .s .d or nothing for a single, double or no truncation.
+    S	Shift amount for shladd instruction.
+    T	Print an 8-bit sign extended number (K) as a 32-bit unsigned number
+ 	for Intel assembler.
+    U	Print an 8-bit sign extended number (K) as a 64-bit unsigned number
+ 	for Intel assembler.
+    X	A pair of floating point registers.
+    r	Print register name, or constant 0 as r0.  HP compatibility for
+ 	Linux kernel.
+    v    Print vector constant value as an 8-byte integer value.  */
+ 
+ static void
+ ia64_print_operand (FILE * file, rtx x, int code)
+ {
+   const char *str;
+ 
+   switch (code)
+     {
+     case 0:
+       /* Handled below.  */
+       break;
+ 
+     case 'C':
+       {
+ 	enum rtx_code c = swap_condition (GET_CODE (x));
+ 	fputs (GET_RTX_NAME (c), file);
+ 	return;
+       }
+ 
+     case 'D':
+       switch (GET_CODE (x))
+ 	{
+ 	case NE:
+ 	  str = "neq";
+ 	  break;
+ 	case UNORDERED:
+ 	  str = "unord";
+ 	  break;
+ 	case ORDERED:
+ 	  str = "ord";
+ 	  break;
+ 	case UNLT:
+ 	  str = "nge";
+ 	  break;
+ 	case UNLE:
+ 	  str = "ngt";
+ 	  break;
+ 	case UNGT:
+ 	  str = "nle";
+ 	  break;
+ 	case UNGE:
+ 	  str = "nlt";
+ 	  break;
+ 	case UNEQ:
+ 	case LTGT:
+ 	  gcc_unreachable ();
+ 	default:
+ 	  str = GET_RTX_NAME (GET_CODE (x));
+ 	  break;
+ 	}
+       fputs (str, file);
+       return;
+ 
+     case 'E':
+       fprintf (file, HOST_WIDE_INT_PRINT_DEC, 32 - INTVAL (x));
+       return;
+ 
+     case 'e':
+       fprintf (file, HOST_WIDE_INT_PRINT_DEC, 64 - INTVAL (x));
+       return;
+ 
+     case 'F':
+       if (x == CONST0_RTX (GET_MODE (x)))
+ 	str = reg_names [FR_REG (0)];
+       else if (x == CONST1_RTX (GET_MODE (x)))
+ 	str = reg_names [FR_REG (1)];
+       else
+ 	{
+ 	  gcc_assert (GET_CODE (x) == REG);
+ 	  str = reg_names [REGNO (x)];
+ 	}
+       fputs (str, file);
+       return;
+ 
+     case 'G':
+       {
+ 	long val[4];
+ 	real_to_target (val, CONST_DOUBLE_REAL_VALUE (x), GET_MODE (x));
+ 	if (GET_MODE (x) == SFmode)
+ 	  fprintf (file, "0x%08lx", val[0] & 0xffffffff);
+ 	else if (GET_MODE (x) == DFmode)
+ 	  fprintf (file, "0x%08lx%08lx", (WORDS_BIG_ENDIAN ? val[0] : val[1])
+ 					  & 0xffffffff,
+ 					 (WORDS_BIG_ENDIAN ? val[1] : val[0])
+ 					  & 0xffffffff);
+ 	else
+ 	  output_operand_lossage ("invalid %%G mode");
+       }
+       return;
+ 
+     case 'I':
+       fputs (reg_names [REGNO (x) + 1], file);
+       return;
+ 
+     case 'J':
+     case 'j':
+       {
+ 	unsigned int regno = REGNO (XEXP (x, 0));
+ 	if (GET_CODE (x) == EQ)
+ 	  regno += 1;
+ 	if (code == 'j')
+ 	  regno ^= 1;
+         fputs (reg_names [regno], file);
+       }
+       return;
+ 
+     case 'O':
+       if (MEM_VOLATILE_P (x))
+ 	fputs(".acq", file);
+       return;
+ 
+     case 'P':
+       {
+ 	HOST_WIDE_INT value;
+ 
+ 	switch (GET_CODE (XEXP (x, 0)))
+ 	  {
+ 	  default:
+ 	    return;
+ 
+ 	  case POST_MODIFY:
+ 	    x = XEXP (XEXP (XEXP (x, 0), 1), 1);
+ 	    if (GET_CODE (x) == CONST_INT)
+ 	      value = INTVAL (x);
+ 	    else
+ 	      {
+ 		gcc_assert (GET_CODE (x) == REG);
+ 		fprintf (file, ", %s", reg_names[REGNO (x)]);
+ 		return;
+ 	      }
+ 	    break;
+ 
+ 	  case POST_INC:
+ 	    value = GET_MODE_SIZE (GET_MODE (x));
+ 	    break;
+ 
+ 	  case POST_DEC:
+ 	    value = - (HOST_WIDE_INT) GET_MODE_SIZE (GET_MODE (x));
+ 	    break;
+ 	  }
+ 
+ 	fprintf (file, ", " HOST_WIDE_INT_PRINT_DEC, value);
+ 	return;
+       }
+ 
+     case 'Q':
+       if (MEM_VOLATILE_P (x))
+ 	fputs(".rel", file);
+       return;
+ 
+     case 'R':
+       if (x == CONST0_RTX (GET_MODE (x)))
+ 	fputs(".s", file);
+       else if (x == CONST1_RTX (GET_MODE (x)))
+ 	fputs(".d", file);
+       else if (x == CONST2_RTX (GET_MODE (x)))
+ 	;
+       else
+ 	output_operand_lossage ("invalid %%R value");
+       return;
+ 
+     case 'S':
+       fprintf (file, "%d", exact_log2 (INTVAL (x)));
+       return;
+ 
+     case 'T':
+       if (! TARGET_GNU_AS && GET_CODE (x) == CONST_INT)
+ 	{
+ 	  fprintf (file, "0x%x", (int) INTVAL (x) & 0xffffffff);
+ 	  return;
+ 	}
+       break;
+ 
+     case 'U':
+       if (! TARGET_GNU_AS && GET_CODE (x) == CONST_INT)
+ 	{
+ 	  const char *prefix = "0x";
+ 	  if (INTVAL (x) & 0x80000000)
+ 	    {
+ 	      fprintf (file, "0xffffffff");
+ 	      prefix = "";
+ 	    }
+ 	  fprintf (file, "%s%x", prefix, (int) INTVAL (x) & 0xffffffff);
+ 	  return;
+ 	}
+       break;
+ 
+     case 'X':
+       {
+ 	unsigned int regno = REGNO (x);
+ 	fprintf (file, "%s, %s", reg_names [regno], reg_names [regno + 1]);
+       }
+       return;
+ 
+     case 'r':
+       /* If this operand is the constant zero, write it as register zero.
+ 	 Any register, zero, or CONST_INT value is OK here.  */
+       if (GET_CODE (x) == REG)
+ 	fputs (reg_names[REGNO (x)], file);
+       else if (x == CONST0_RTX (GET_MODE (x)))
+ 	fputs ("r0", file);
+       else if (GET_CODE (x) == CONST_INT)
+ 	output_addr_const (file, x);
+       else
+ 	output_operand_lossage ("invalid %%r value");
+       return;
+ 
+     case 'v':
+       gcc_assert (GET_CODE (x) == CONST_VECTOR);
+       x = simplify_subreg (DImode, x, GET_MODE (x), 0);
+       break;
+ 
+     case '+':
+       {
+ 	const char *which;
+ 
+ 	/* For conditional branches, returns or calls, substitute
+ 	   sptk, dptk, dpnt, or spnt for %s.  */
+ 	x = find_reg_note (current_output_insn, REG_BR_PROB, 0);
+ 	if (x)
+ 	  {
+ 	    int pred_val = profile_probability::from_reg_br_prob_note
+ 				 (XINT (x, 0)).to_reg_br_prob_base ();
+ 
+ 	    /* Guess top and bottom 10% statically predicted.  */
+ 	    if (pred_val < REG_BR_PROB_BASE / 50
+ 		&& br_prob_note_reliable_p (x))
+ 	      which = ".spnt";
+ 	    else if (pred_val < REG_BR_PROB_BASE / 2)
+ 	      which = ".dpnt";
+ 	    else if (pred_val < REG_BR_PROB_BASE / 100 * 98
+ 		     || !br_prob_note_reliable_p (x))
+ 	      which = ".dptk";
+ 	    else
+ 	      which = ".sptk";
+ 	  }
+ 	else if (CALL_P (current_output_insn))
+ 	  which = ".sptk";
+ 	else
+ 	  which = ".dptk";
+ 
+ 	fputs (which, file);
+ 	return;
+       }
+ 
+     case ',':
+       x = current_insn_predicate;
+       if (x)
+ 	{
+ 	  unsigned int regno = REGNO (XEXP (x, 0));
+ 	  if (GET_CODE (x) == EQ)
+ 	    regno += 1;
+           fprintf (file, "(%s) ", reg_names [regno]);
+ 	}
+       return;
+ 
+     default:
+       output_operand_lossage ("ia64_print_operand: unknown code");
+       return;
+     }
+ 
+   switch (GET_CODE (x))
+     {
+       /* This happens for the spill/restore instructions.  */
+     case POST_INC:
+     case POST_DEC:
+     case POST_MODIFY:
+       x = XEXP (x, 0);
+       /* fall through */
+ 
+     case REG:
+       fputs (reg_names [REGNO (x)], file);
+       break;
+ 
+     case MEM:
+       {
+ 	rtx addr = XEXP (x, 0);
+ 	if (GET_RTX_CLASS (GET_CODE (addr)) == RTX_AUTOINC)
+ 	  addr = XEXP (addr, 0);
+ 	fprintf (file, "[%s]", reg_names [REGNO (addr)]);
+ 	break;
+       }
+ 
+     default:
+       output_addr_const (file, x);
+       break;
+     }
+ 
+   return;
+ }
+ 
+ /* Worker function for TARGET_PRINT_OPERAND_PUNCT_VALID_P.  */
+ 
+ static bool
+ ia64_print_operand_punct_valid_p (unsigned char code)
+ {
+   return (code == '+' || code == ',');
+ }
+ \f
+ /* Compute a (partial) cost for rtx X.  Return true if the complete
+    cost has been computed, and false if subexpressions should be
+    scanned.  In either case, *TOTAL contains the cost result.  */
+ /* ??? This is incomplete.  */
+ 
+ static bool
+ ia64_rtx_costs (rtx x, machine_mode mode, int outer_code,
+ 		int opno ATTRIBUTE_UNUSED,
+ 		int *total, bool speed ATTRIBUTE_UNUSED)
+ {
+   int code = GET_CODE (x);
+ 
+   switch (code)
+     {
+     case CONST_INT:
+       switch (outer_code)
+         {
+         case SET:
+ 	  *total = satisfies_constraint_J (x) ? 0 : COSTS_N_INSNS (1);
+ 	  return true;
+         case PLUS:
+ 	  if (satisfies_constraint_I (x))
+ 	    *total = 0;
+ 	  else if (satisfies_constraint_J (x))
+ 	    *total = 1;
+ 	  else
+ 	    *total = COSTS_N_INSNS (1);
+ 	  return true;
+         default:
+ 	  if (satisfies_constraint_K (x) || satisfies_constraint_L (x))
+ 	    *total = 0;
+ 	  else
+ 	    *total = COSTS_N_INSNS (1);
+ 	  return true;
+ 	}
+ 
+     case CONST_DOUBLE:
+       *total = COSTS_N_INSNS (1);
+       return true;
+ 
+     case CONST:
+     case SYMBOL_REF:
+     case LABEL_REF:
+       *total = COSTS_N_INSNS (3);
+       return true;
+ 
+     case FMA:
+       *total = COSTS_N_INSNS (4);
+       return true;
+ 
+     case MULT:
+       /* For multiplies wider than HImode, we have to go to the FPU,
+          which normally involves copies.  Plus there's the latency
+          of the multiply itself, and the latency of the instructions to
+          transfer integer regs to FP regs.  */
+       if (FLOAT_MODE_P (mode))
+ 	*total = COSTS_N_INSNS (4);
+       else if (GET_MODE_SIZE (mode) > 2)
+         *total = COSTS_N_INSNS (10);
+       else
+ 	*total = COSTS_N_INSNS (2);
+       return true;
+ 
+     case PLUS:
+     case MINUS:
+       if (FLOAT_MODE_P (mode))
+ 	{
+ 	  *total = COSTS_N_INSNS (4);
+ 	  return true;
+ 	}
+       /* FALLTHRU */
+ 
+     case ASHIFT:
+     case ASHIFTRT:
+     case LSHIFTRT:
+       *total = COSTS_N_INSNS (1);
+       return true;
+ 
+     case DIV:
+     case UDIV:
+     case MOD:
+     case UMOD:
+       /* We make divide expensive, so that divide-by-constant will be
+          optimized to a multiply.  */
+       *total = COSTS_N_INSNS (60);
+       return true;
+ 
+     default:
+       return false;
+     }
+ }
+ 
+ /* Calculate the cost of moving data from a register in class FROM to
+    one in class TO, using MODE.  */
+ 
+ static int
+ ia64_register_move_cost (machine_mode mode, reg_class_t from,
+ 			 reg_class_t to)
+ {
+   /* ADDL_REGS is the same as GR_REGS for movement purposes.  */
+   if (to == ADDL_REGS)
+     to = GR_REGS;
+   if (from == ADDL_REGS)
+     from = GR_REGS;
+ 
+   /* All costs are symmetric, so reduce cases by putting the
+      lower number class as the destination.  */
+   if (from < to)
+     {
+       reg_class_t tmp = to;
+       to = from, from = tmp;
+     }
+ 
+   /* Moving from FR<->GR in XFmode must be more expensive than 2,
+      so that we get secondary memory reloads.  Between FR_REGS,
+      we have to make this at least as expensive as memory_move_cost
+      to avoid spectacularly poor register class preferencing.  */
+   if (mode == XFmode || mode == RFmode)
+     {
+       if (to != GR_REGS || from != GR_REGS)
+         return memory_move_cost (mode, to, false);
+       else
+ 	return 3;
+     }
+ 
+   switch (to)
+     {
+     case PR_REGS:
+       /* Moving between PR registers takes two insns.  */
+       if (from == PR_REGS)
+ 	return 3;
+       /* Moving between PR and anything but GR is impossible.  */
+       if (from != GR_REGS)
+ 	return memory_move_cost (mode, to, false);
+       break;
+ 
+     case BR_REGS:
+       /* Moving between BR and anything but GR is impossible.  */
+       if (from != GR_REGS && from != GR_AND_BR_REGS)
+ 	return memory_move_cost (mode, to, false);
+       break;
+ 
+     case AR_I_REGS:
+     case AR_M_REGS:
+       /* Moving between AR and anything but GR is impossible.  */
+       if (from != GR_REGS)
+ 	return memory_move_cost (mode, to, false);
+       break;
+ 
+     case GR_REGS:
+     case FR_REGS:
+     case FP_REGS:
+     case GR_AND_FR_REGS:
+     case GR_AND_BR_REGS:
+     case ALL_REGS:
+       break;
+ 
+     default:
+       gcc_unreachable ();
+     }
+ 
+   return 2;
+ }
+ 
+ /* Calculate the cost of moving data of MODE from a register to or from
+    memory.  */
+ 
+ static int
+ ia64_memory_move_cost (machine_mode mode ATTRIBUTE_UNUSED,
+ 		       reg_class_t rclass,
+ 		       bool in ATTRIBUTE_UNUSED)
+ {
+   if (rclass == GENERAL_REGS
+       || rclass == FR_REGS
+       || rclass == FP_REGS
+       || rclass == GR_AND_FR_REGS)
+     return 4;
+   else
+     return 10;
+ }
+ 
+ /* Implement TARGET_PREFERRED_RELOAD_CLASS.  Place additional restrictions
+    on RCLASS to use when copying X into that class.  */
+ 
+ static reg_class_t
+ ia64_preferred_reload_class (rtx x, reg_class_t rclass)
+ {
+   switch (rclass)
+     {
+     case FR_REGS:
+     case FP_REGS:
+       /* Don't allow volatile mem reloads into floating point registers.
+ 	 This is defined to force reload to choose the r/m case instead
+ 	 of the f/f case when reloading (set (reg fX) (mem/v)).  */
+       if (MEM_P (x) && MEM_VOLATILE_P (x))
+ 	return NO_REGS;
+       
+       /* Force all unrecognized constants into the constant pool.  */
+       if (CONSTANT_P (x))
+ 	return NO_REGS;
+       break;
+ 
+     case AR_M_REGS:
+     case AR_I_REGS:
+       if (!OBJECT_P (x))
+ 	return NO_REGS;
+       break;
+ 
+     default:
+       break;
+     }
+ 
+   return rclass;
+ }
+ 
+ /* This function returns the register class required for a secondary
+    register when copying between one of the registers in RCLASS, and X,
+    using MODE.  A return value of NO_REGS means that no secondary register
+    is required.  */
+ 
+ enum reg_class
+ ia64_secondary_reload_class (enum reg_class rclass,
+ 			     machine_mode mode ATTRIBUTE_UNUSED, rtx x)
+ {
+   int regno = -1;
+ 
+   if (GET_CODE (x) == REG || GET_CODE (x) == SUBREG)
+     regno = true_regnum (x);
+ 
+   switch (rclass)
+     {
+     case BR_REGS:
+     case AR_M_REGS:
+     case AR_I_REGS:
+       /* ??? BR<->BR register copies can happen due to a bad gcse/cse/global
+ 	 interaction.  We end up with two pseudos with overlapping lifetimes
+ 	 both of which are equiv to the same constant, and both which need
+ 	 to be in BR_REGS.  This seems to be a cse bug.  cse_basic_block_end
+ 	 changes depending on the path length, which means the qty_first_reg
+ 	 check in make_regs_eqv can give different answers at different times.
+ 	 At some point I'll probably need a reload_indi pattern to handle
+ 	 this.
+ 
+ 	 We can also get GR_AND_FR_REGS to BR_REGS/AR_REGS copies, where we
+ 	 wound up with a FP register from GR_AND_FR_REGS.  Extend that to all
+ 	 non-general registers for good measure.  */
+       if (regno >= 0 && ! GENERAL_REGNO_P (regno))
+ 	return GR_REGS;
+ 
+       /* This is needed if a pseudo used as a call_operand gets spilled to a
+ 	 stack slot.  */
+       if (GET_CODE (x) == MEM)
+ 	return GR_REGS;
+       break;
+ 
+     case FR_REGS:
+     case FP_REGS:
+       /* Need to go through general registers to get to other class regs.  */
+       if (regno >= 0 && ! (FR_REGNO_P (regno) || GENERAL_REGNO_P (regno)))
+ 	return GR_REGS;
+ 
+       /* This can happen when a paradoxical subreg is an operand to the
+ 	 muldi3 pattern.  */
+       /* ??? This shouldn't be necessary after instruction scheduling is
+ 	 enabled, because paradoxical subregs are not accepted by
+ 	 register_operand when INSN_SCHEDULING is defined.  Or alternatively,
+ 	 stop the paradoxical subreg stupidity in the *_operand functions
+ 	 in recog.cc.  */
+       if (GET_CODE (x) == MEM
+ 	  && (GET_MODE (x) == SImode || GET_MODE (x) == HImode
+ 	      || GET_MODE (x) == QImode))
+ 	return GR_REGS;
+ 
+       /* This can happen because of the ior/and/etc patterns that accept FP
+ 	 registers as operands.  If the third operand is a constant, then it
+ 	 needs to be reloaded into a FP register.  */
+       if (GET_CODE (x) == CONST_INT)
+ 	return GR_REGS;
+ 
+       /* This can happen because of register elimination in a muldi3 insn.
+ 	 E.g. `26107 * (unsigned long)&u'.  */
+       if (GET_CODE (x) == PLUS)
+ 	return GR_REGS;
+       break;
+ 
+     case PR_REGS:
+       /* ??? This happens if we cse/gcse a BImode value across a call,
+ 	 and the function has a nonlocal goto.  This is because global
+ 	 does not allocate call crossing pseudos to hard registers when
+ 	 crtl->has_nonlocal_goto is true.  This is relatively
+ 	 common for C++ programs that use exceptions.  To reproduce,
+ 	 return NO_REGS and compile libstdc++.  */
+       if (GET_CODE (x) == MEM)
+ 	return GR_REGS;
+ 
+       /* This can happen when we take a BImode subreg of a DImode value,
+ 	 and that DImode value winds up in some non-GR register.  */
+       if (regno >= 0 && ! GENERAL_REGNO_P (regno) && ! PR_REGNO_P (regno))
+ 	return GR_REGS;
+       break;
+ 
+     default:
+       break;
+     }
+ 
+   return NO_REGS;
+ }
+ 
+ \f
+ /* Implement targetm.unspec_may_trap_p hook.  */
+ static int
+ ia64_unspec_may_trap_p (const_rtx x, unsigned flags)
+ {
+   switch (XINT (x, 1))
+     {
+     case UNSPEC_LDA:
+     case UNSPEC_LDS:
+     case UNSPEC_LDSA:
+     case UNSPEC_LDCCLR:
+     case UNSPEC_CHKACLR:
+     case UNSPEC_CHKS:
+       /* These unspecs are just wrappers.  */
+       return may_trap_p_1 (XVECEXP (x, 0, 0), flags);
+     }
+ 
+   return default_unspec_may_trap_p (x, flags);
+ }
+ 
+ \f
+ /* Parse the -mfixed-range= option string.  */
+ 
+ static void
+ fix_range (const char *const_str)
+ {
+   int i, first, last;
+   char *str, *dash, *comma;
+ 
+   /* str must be of the form REG1'-'REG2{,REG1'-'REG} where REG1 and
+      REG2 are either register names or register numbers.  The effect
+      of this option is to mark the registers in the range from REG1 to
+      REG2 as ``fixed'' so they won't be used by the compiler.  This is
+      used, e.g., to ensure that kernel mode code doesn't use f32-f127.  */
+ 
+   i = strlen (const_str);
+   str = (char *) alloca (i + 1);
+   memcpy (str, const_str, i + 1);
+ 
+   while (1)
+     {
+       dash = strchr (str, '-');
+       if (!dash)
+ 	{
+ 	  warning (0, "value of %<-mfixed-range%> must have form REG1-REG2");
+ 	  return;
+ 	}
+       *dash = '\0';
+ 
+       comma = strchr (dash + 1, ',');
+       if (comma)
+ 	*comma = '\0';
+ 
+       first = decode_reg_name (str);
+       if (first < 0)
+ 	{
+ 	  warning (0, "unknown register name: %s", str);
+ 	  return;
+ 	}
+ 
+       last = decode_reg_name (dash + 1);
+       if (last < 0)
+ 	{
+ 	  warning (0, "unknown register name: %s", dash + 1);
+ 	  return;
+ 	}
+ 
+       *dash = '-';
+ 
+       if (first > last)
+ 	{
+ 	  warning (0, "%s-%s is an empty range", str, dash + 1);
+ 	  return;
+ 	}
+ 
+       for (i = first; i <= last; ++i)
+ 	fixed_regs[i] = 1;
+ 
+       if (!comma)
+ 	break;
+ 
+       *comma = ',';
+       str = comma + 1;
+     }
+ }
+ 
+ /* Implement TARGET_OPTION_OVERRIDE.  */
+ 
+ static void
+ ia64_option_override (void)
+ {
+   unsigned int i;
+   cl_deferred_option *opt;
+   vec<cl_deferred_option> *v
+     = (vec<cl_deferred_option> *) ia64_deferred_options;
+ 
+   if (v)
+     FOR_EACH_VEC_ELT (*v, i, opt)
+       {
+ 	switch (opt->opt_index)
+ 	  {
+ 	  case OPT_mfixed_range_:
+ 	    fix_range (opt->arg);
+ 	    break;
+ 
+ 	  default:
+ 	    gcc_unreachable ();
+ 	  }
+       }
+ 
+   if (TARGET_AUTO_PIC)
+     target_flags |= MASK_CONST_GP;
+ 
+   /* Numerous experiment shows that IRA based loop pressure
+      calculation works better for RTL loop invariant motion on targets
+      with enough (>= 32) registers.  It is an expensive optimization.
+      So it is on only for peak performance.  */
+   if (optimize >= 3)
+     flag_ira_loop_pressure = 1;
+ 
+ 
+   ia64_section_threshold = (OPTION_SET_P (g_switch_value)
+ 			    ? g_switch_value
+ 			    : IA64_DEFAULT_GVALUE);
+ 
+   init_machine_status = ia64_init_machine_status;
+ 
+   if (flag_align_functions && !str_align_functions)
+     str_align_functions = "64";
+   if (flag_align_loops && !str_align_loops)
+     str_align_loops = "32";
+   if (TARGET_ABI_OPEN_VMS)
+     flag_no_common = 1;
+ 
+   ia64_override_options_after_change();
+ }
+ 
+ /* Implement targetm.override_options_after_change.  */
+ 
+ static void
+ ia64_override_options_after_change (void)
+ {
+   if (optimize >= 3
+       && !OPTION_SET_P (flag_selective_scheduling)
+       && !OPTION_SET_P (flag_selective_scheduling2))
+     {
+       flag_selective_scheduling2 = 1;
+       flag_sel_sched_pipelining = 1;
+     }
+   if (mflag_sched_control_spec == 2)
+     {
+       /* Control speculation is on by default for the selective scheduler,
+          but not for the Haifa scheduler.  */
+       mflag_sched_control_spec = flag_selective_scheduling2 ? 1 : 0;
+     }
+   if (flag_sel_sched_pipelining && flag_auto_inc_dec)
+     {
+       /* FIXME: remove this when we'd implement breaking autoinsns as
+          a transformation.  */
+       flag_auto_inc_dec = 0;
+     }
+ }
+ 
+ /* Initialize the record of emitted frame related registers.  */
+ 
+ void ia64_init_expanders (void)
+ {
+   memset (&emitted_frame_related_regs, 0, sizeof (emitted_frame_related_regs));
+ }
+ 
+ static struct machine_function *
+ ia64_init_machine_status (void)
+ {
+   return ggc_cleared_alloc<machine_function> ();
+ }
+ \f
+ static enum attr_itanium_class ia64_safe_itanium_class (rtx_insn *);
+ static enum attr_type ia64_safe_type (rtx_insn *);
+ 
+ static enum attr_itanium_class
+ ia64_safe_itanium_class (rtx_insn *insn)
+ {
+   if (recog_memoized (insn) >= 0)
+     return get_attr_itanium_class (insn);
+   else if (DEBUG_INSN_P (insn))
+     return ITANIUM_CLASS_IGNORE;
+   else
+     return ITANIUM_CLASS_UNKNOWN;
+ }
+ 
+ static enum attr_type
+ ia64_safe_type (rtx_insn *insn)
+ {
+   if (recog_memoized (insn) >= 0)
+     return get_attr_type (insn);
+   else
+     return TYPE_UNKNOWN;
+ }
+ \f
+ /* The following collection of routines emit instruction group stop bits as
+    necessary to avoid dependencies.  */
+ 
+ /* Need to track some additional registers as far as serialization is
+    concerned so we can properly handle br.call and br.ret.  We could
+    make these registers visible to gcc, but since these registers are
+    never explicitly used in gcc generated code, it seems wasteful to
+    do so (plus it would make the call and return patterns needlessly
+    complex).  */
+ #define REG_RP		(BR_REG (0))
+ #define REG_AR_CFM	(FIRST_PSEUDO_REGISTER + 1)
+ /* This is used for volatile asms which may require a stop bit immediately
+    before and after them.  */
+ #define REG_VOLATILE	(FIRST_PSEUDO_REGISTER + 2)
+ #define AR_UNAT_BIT_0	(FIRST_PSEUDO_REGISTER + 3)
+ #define NUM_REGS	(AR_UNAT_BIT_0 + 64)
+ 
+ /* For each register, we keep track of how it has been written in the
+    current instruction group.
+ 
+    If a register is written unconditionally (no qualifying predicate),
+    WRITE_COUNT is set to 2 and FIRST_PRED is ignored.
+ 
+    If a register is written if its qualifying predicate P is true, we
+    set WRITE_COUNT to 1 and FIRST_PRED to P.  Later on, the same register
+    may be written again by the complement of P (P^1) and when this happens,
+    WRITE_COUNT gets set to 2.
+ 
+    The result of this is that whenever an insn attempts to write a register
+    whose WRITE_COUNT is two, we need to issue an insn group barrier first.
+ 
+    If a predicate register is written by a floating-point insn, we set
+    WRITTEN_BY_FP to true.
+ 
+    If a predicate register is written by an AND.ORCM we set WRITTEN_BY_AND
+    to true; if it was written by an OR.ANDCM we set WRITTEN_BY_OR to true.  */
+ 
+ #if GCC_VERSION >= 4000
+ #define RWS_FIELD_TYPE __extension__ unsigned short
+ #else
+ #define RWS_FIELD_TYPE unsigned int
+ #endif
+ struct reg_write_state
+ {
+   RWS_FIELD_TYPE write_count : 2;
+   RWS_FIELD_TYPE first_pred : 10;
+   RWS_FIELD_TYPE written_by_fp : 1;
+   RWS_FIELD_TYPE written_by_and : 1;
+   RWS_FIELD_TYPE written_by_or : 1;
+ };
+ 
+ /* Cumulative info for the current instruction group.  */
+ struct reg_write_state rws_sum[NUM_REGS];
+ #if CHECKING_P
+ /* Bitmap whether a register has been written in the current insn.  */
+ unsigned HOST_WIDEST_FAST_INT rws_insn
+   [(NUM_REGS + HOST_BITS_PER_WIDEST_FAST_INT - 1)
+    / HOST_BITS_PER_WIDEST_FAST_INT];
+ 
+ static inline void
+ rws_insn_set (unsigned int regno)
+ {
+   unsigned int elt = regno / HOST_BITS_PER_WIDEST_FAST_INT;
+   unsigned int bit = regno % HOST_BITS_PER_WIDEST_FAST_INT;
+   gcc_assert (!((rws_insn[elt] >> bit) & 1));
+   rws_insn[elt] |= (unsigned HOST_WIDEST_FAST_INT) 1 << bit;
+ }
+ 
+ static inline int
+ rws_insn_test (unsigned int regno)
+ {
+   unsigned int elt = regno / HOST_BITS_PER_WIDEST_FAST_INT;
+   unsigned int bit = regno % HOST_BITS_PER_WIDEST_FAST_INT;
+   return (rws_insn[elt] >> bit) & 1;
+ }
+ #else
+ /* When not checking, track just REG_AR_CFM and REG_VOLATILE.  */
+ unsigned char rws_insn[2];
+ 
+ static inline void
+ rws_insn_set (int regno)
+ {
+   if (regno == REG_AR_CFM)
+     rws_insn[0] = 1;
+   else if (regno == REG_VOLATILE)
+     rws_insn[1] = 1;
+ }
+ 
+ static inline int
+ rws_insn_test (int regno)
+ {
+   if (regno == REG_AR_CFM)
+     return rws_insn[0];
+   if (regno == REG_VOLATILE)
+     return rws_insn[1];
+   return 0;
+ }
+ #endif
+ 
+ /* Indicates whether this is the first instruction after a stop bit,
+    in which case we don't need another stop bit.  Without this,
+    ia64_variable_issue will die when scheduling an alloc.  */
+ static int first_instruction;
+ 
+ /* Misc flags needed to compute RAW/WAW dependencies while we are traversing
+    RTL for one instruction.  */
+ struct reg_flags
+ {
+   unsigned int is_write : 1;	/* Is register being written?  */
+   unsigned int is_fp : 1;	/* Is register used as part of an fp op?  */
+   unsigned int is_branch : 1;	/* Is register used as part of a branch?  */
+   unsigned int is_and : 1;	/* Is register used as part of and.orcm?  */
+   unsigned int is_or : 1;	/* Is register used as part of or.andcm?  */
+   unsigned int is_sibcall : 1;	/* Is this a sibling or normal call?  */
+ };
+ 
+ static void rws_update (int, struct reg_flags, int);
+ static int rws_access_regno (int, struct reg_flags, int);
+ static int rws_access_reg (rtx, struct reg_flags, int);
+ static void update_set_flags (rtx, struct reg_flags *);
+ static int set_src_needs_barrier (rtx, struct reg_flags, int);
+ static int rtx_needs_barrier (rtx, struct reg_flags, int);
+ static void init_insn_group_barriers (void);
+ static int group_barrier_needed (rtx_insn *);
+ static int safe_group_barrier_needed (rtx_insn *);
+ static int in_safe_group_barrier;
+ 
+ /* Update *RWS for REGNO, which is being written by the current instruction,
+    with predicate PRED, and associated register flags in FLAGS.  */
+ 
+ static void
+ rws_update (int regno, struct reg_flags flags, int pred)
+ {
+   if (pred)
+     rws_sum[regno].write_count++;
+   else
+     rws_sum[regno].write_count = 2;
+   rws_sum[regno].written_by_fp |= flags.is_fp;
+   /* ??? Not tracking and/or across differing predicates.  */
+   rws_sum[regno].written_by_and = flags.is_and;
+   rws_sum[regno].written_by_or = flags.is_or;
+   rws_sum[regno].first_pred = pred;
+ }
+ 
+ /* Handle an access to register REGNO of type FLAGS using predicate register
+    PRED.  Update rws_sum array.  Return 1 if this access creates
+    a dependency with an earlier instruction in the same group.  */
+ 
+ static int
+ rws_access_regno (int regno, struct reg_flags flags, int pred)
+ {
+   int need_barrier = 0;
+ 
+   gcc_assert (regno < NUM_REGS);
+ 
+   if (! PR_REGNO_P (regno))
+     flags.is_and = flags.is_or = 0;
+ 
+   if (flags.is_write)
+     {
+       int write_count;
+ 
+       rws_insn_set (regno);
+       write_count = rws_sum[regno].write_count;
+ 
+       switch (write_count)
+ 	{
+ 	case 0:
+ 	  /* The register has not been written yet.  */
+ 	  if (!in_safe_group_barrier)
+ 	    rws_update (regno, flags, pred);
+ 	  break;
+ 
+ 	case 1:
+ 	  /* The register has been written via a predicate.  Treat
+ 	     it like a unconditional write and do not try to check
+ 	     for complementary pred reg in earlier write.  */
+ 	  if (flags.is_and && rws_sum[regno].written_by_and)
+ 	    ;
+ 	  else if (flags.is_or && rws_sum[regno].written_by_or)
+ 	    ;
+ 	  else
+ 	    need_barrier = 1;
+ 	  if (!in_safe_group_barrier)
+ 	    rws_update (regno, flags, pred);
+ 	  break;
+ 
+ 	case 2:
+ 	  /* The register has been unconditionally written already.  We
+ 	     need a barrier.  */
+ 	  if (flags.is_and && rws_sum[regno].written_by_and)
+ 	    ;
+ 	  else if (flags.is_or && rws_sum[regno].written_by_or)
+ 	    ;
+ 	  else
+ 	    need_barrier = 1;
+ 	  if (!in_safe_group_barrier)
+ 	    {
+ 	      rws_sum[regno].written_by_and = flags.is_and;
+ 	      rws_sum[regno].written_by_or = flags.is_or;
+ 	    }
+ 	  break;
+ 
+ 	default:
+ 	  gcc_unreachable ();
+ 	}
+     }
+   else
+     {
+       if (flags.is_branch)
+ 	{
+ 	  /* Branches have several RAW exceptions that allow to avoid
+ 	     barriers.  */
+ 
+ 	  if (REGNO_REG_CLASS (regno) == BR_REGS || regno == AR_PFS_REGNUM)
+ 	    /* RAW dependencies on branch regs are permissible as long
+ 	       as the writer is a non-branch instruction.  Since we
+ 	       never generate code that uses a branch register written
+ 	       by a branch instruction, handling this case is
+ 	       easy.  */
+ 	    return 0;
+ 
+ 	  if (REGNO_REG_CLASS (regno) == PR_REGS
+ 	      && ! rws_sum[regno].written_by_fp)
+ 	    /* The predicates of a branch are available within the
+ 	       same insn group as long as the predicate was written by
+ 	       something other than a floating-point instruction.  */
+ 	    return 0;
+ 	}
+ 
+       if (flags.is_and && rws_sum[regno].written_by_and)
+ 	return 0;
+       if (flags.is_or && rws_sum[regno].written_by_or)
+ 	return 0;
+ 
+       switch (rws_sum[regno].write_count)
+ 	{
+ 	case 0:
+ 	  /* The register has not been written yet.  */
+ 	  break;
+ 
+ 	case 1:
+ 	  /* The register has been written via a predicate, assume we
+ 	     need a barrier (don't check for complementary regs).  */
+ 	  need_barrier = 1;
+ 	  break;
+ 
+ 	case 2:
+ 	  /* The register has been unconditionally written already.  We
+ 	     need a barrier.  */
+ 	  need_barrier = 1;
+ 	  break;
+ 
+ 	default:
+ 	  gcc_unreachable ();
+ 	}
+     }
+ 
+   return need_barrier;
+ }
+ 
+ static int
+ rws_access_reg (rtx reg, struct reg_flags flags, int pred)
+ {
+   int regno = REGNO (reg);
+   int n = REG_NREGS (reg);
+ 
+   if (n == 1)
+     return rws_access_regno (regno, flags, pred);
+   else
+     {
+       int need_barrier = 0;
+       while (--n >= 0)
+ 	need_barrier |= rws_access_regno (regno + n, flags, pred);
+       return need_barrier;
+     }
+ }
+ 
+ /* Examine X, which is a SET rtx, and update the flags, the predicate, and
+    the condition, stored in *PFLAGS, *PPRED and *PCOND.  */
+ 
+ static void
+ update_set_flags (rtx x, struct reg_flags *pflags)
+ {
+   rtx src = SET_SRC (x);
+ 
+   switch (GET_CODE (src))
+     {
+     case CALL:
+       return;
+ 
+     case IF_THEN_ELSE:
+       /* There are four cases here:
+ 	 (1) The destination is (pc), in which case this is a branch,
+ 	 nothing here applies.
+ 	 (2) The destination is ar.lc, in which case this is a
+ 	 doloop_end_internal,
+ 	 (3) The destination is an fp register, in which case this is
+ 	 an fselect instruction.
+ 	 (4) The condition has (unspec [(reg)] UNSPEC_LDC), in which case 
+ 	 this is a check load.
+ 	 In all cases, nothing we do in this function applies.  */
+       return;
+ 
+     default:
+       if (COMPARISON_P (src)
+ 	  && SCALAR_FLOAT_MODE_P (GET_MODE (XEXP (src, 0))))
+ 	/* Set pflags->is_fp to 1 so that we know we're dealing
+ 	   with a floating point comparison when processing the
+ 	   destination of the SET.  */
+ 	pflags->is_fp = 1;
+ 
+       /* Discover if this is a parallel comparison.  We only handle
+ 	 and.orcm and or.andcm at present, since we must retain a
+ 	 strict inverse on the predicate pair.  */
+       else if (GET_CODE (src) == AND)
+ 	pflags->is_and = 1;
+       else if (GET_CODE (src) == IOR)
+ 	pflags->is_or = 1;
+ 
+       break;
+     }
+ }
+ 
+ /* Subroutine of rtx_needs_barrier; this function determines whether the
+    source of a given SET rtx found in X needs a barrier.  FLAGS and PRED
+    are as in rtx_needs_barrier.  COND is an rtx that holds the condition
+    for this insn.  */
+ 
+ static int
+ set_src_needs_barrier (rtx x, struct reg_flags flags, int pred)
+ {
+   int need_barrier = 0;
+   rtx dst;
+   rtx src = SET_SRC (x);
+ 
+   if (GET_CODE (src) == CALL)
+     /* We don't need to worry about the result registers that
+        get written by subroutine call.  */
+     return rtx_needs_barrier (src, flags, pred);
+   else if (SET_DEST (x) == pc_rtx)
+     {
+       /* X is a conditional branch.  */
+       /* ??? This seems redundant, as the caller sets this bit for
+ 	 all JUMP_INSNs.  */
+       if (!ia64_spec_check_src_p (src))
+ 	flags.is_branch = 1;
+       return rtx_needs_barrier (src, flags, pred);
+     }
+ 
+   if (ia64_spec_check_src_p (src))
+     /* Avoid checking one register twice (in condition 
+        and in 'then' section) for ldc pattern.  */
+     {
+       gcc_assert (REG_P (XEXP (src, 2)));
+       need_barrier = rtx_needs_barrier (XEXP (src, 2), flags, pred);
+ 		  
+       /* We process MEM below.  */
+       src = XEXP (src, 1);
+     }
+ 
+   need_barrier |= rtx_needs_barrier (src, flags, pred);
+ 
+   dst = SET_DEST (x);
+   if (GET_CODE (dst) == ZERO_EXTRACT)
+     {
+       need_barrier |= rtx_needs_barrier (XEXP (dst, 1), flags, pred);
+       need_barrier |= rtx_needs_barrier (XEXP (dst, 2), flags, pred);
+     }
+   return need_barrier;
+ }
+ 
+ /* Handle an access to rtx X of type FLAGS using predicate register
+    PRED.  Return 1 if this access creates a dependency with an earlier
+    instruction in the same group.  */
+ 
+ static int
+ rtx_needs_barrier (rtx x, struct reg_flags flags, int pred)
+ {
+   int i, j;
+   int is_complemented = 0;
+   int need_barrier = 0;
+   const char *format_ptr;
+   struct reg_flags new_flags;
+   rtx cond;
+ 
+   if (! x)
+     return 0;
+ 
+   new_flags = flags;
+ 
+   switch (GET_CODE (x))
+     {
+     case SET:
+       update_set_flags (x, &new_flags);
+       need_barrier = set_src_needs_barrier (x, new_flags, pred);
+       if (GET_CODE (SET_SRC (x)) != CALL)
+ 	{
+ 	  new_flags.is_write = 1;
+ 	  need_barrier |= rtx_needs_barrier (SET_DEST (x), new_flags, pred);
+ 	}
+       break;
+ 
+     case CALL:
+       new_flags.is_write = 0;
+       need_barrier |= rws_access_regno (AR_EC_REGNUM, new_flags, pred);
+ 
+       /* Avoid multiple register writes, in case this is a pattern with
+ 	 multiple CALL rtx.  This avoids a failure in rws_access_reg.  */
+       if (! flags.is_sibcall && ! rws_insn_test (REG_AR_CFM))
+ 	{
+ 	  new_flags.is_write = 1;
+ 	  need_barrier |= rws_access_regno (REG_RP, new_flags, pred);
+ 	  need_barrier |= rws_access_regno (AR_PFS_REGNUM, new_flags, pred);
+ 	  need_barrier |= rws_access_regno (REG_AR_CFM, new_flags, pred);
+ 	}
+       break;
+ 
+     case COND_EXEC:
+       /* X is a predicated instruction.  */
+ 
+       cond = COND_EXEC_TEST (x);
+       gcc_assert (!pred);
+       need_barrier = rtx_needs_barrier (cond, flags, 0);
+ 
+       if (GET_CODE (cond) == EQ)
+ 	is_complemented = 1;
+       cond = XEXP (cond, 0);
+       gcc_assert (GET_CODE (cond) == REG
+ 		  && REGNO_REG_CLASS (REGNO (cond)) == PR_REGS);
+       pred = REGNO (cond);
+       if (is_complemented)
+ 	++pred;
+ 
+       need_barrier |= rtx_needs_barrier (COND_EXEC_CODE (x), flags, pred);
+       return need_barrier;
+ 
+     case CLOBBER:
+     case USE:
+       /* Clobber & use are for earlier compiler-phases only.  */
+       break;
+ 
+     case ASM_OPERANDS:
+     case ASM_INPUT:
+       /* We always emit stop bits for traditional asms.  We emit stop bits
+ 	 for volatile extended asms if TARGET_VOL_ASM_STOP is true.  */
+       if (GET_CODE (x) != ASM_OPERANDS
+ 	  || (MEM_VOLATILE_P (x) && TARGET_VOL_ASM_STOP))
+ 	{
+ 	  /* Avoid writing the register multiple times if we have multiple
+ 	     asm outputs.  This avoids a failure in rws_access_reg.  */
+ 	  if (! rws_insn_test (REG_VOLATILE))
+ 	    {
+ 	      new_flags.is_write = 1;
+ 	      rws_access_regno (REG_VOLATILE, new_flags, pred);
+ 	    }
+ 	  return 1;
+ 	}
+ 
+       /* For all ASM_OPERANDS, we must traverse the vector of input operands.
+ 	 We cannot just fall through here since then we would be confused
+ 	 by the ASM_INPUT rtx inside ASM_OPERANDS, which do not indicate
+ 	 traditional asms unlike their normal usage.  */
+ 
+       for (i = ASM_OPERANDS_INPUT_LENGTH (x) - 1; i >= 0; --i)
+ 	if (rtx_needs_barrier (ASM_OPERANDS_INPUT (x, i), flags, pred))
+ 	  need_barrier = 1;
+       break;
+ 
+     case PARALLEL:
+       for (i = XVECLEN (x, 0) - 1; i >= 0; --i)
+ 	{
+ 	  rtx pat = XVECEXP (x, 0, i);
+ 	  switch (GET_CODE (pat))
+ 	    {
+ 	    case SET:
+ 	      update_set_flags (pat, &new_flags);
+ 	      need_barrier |= set_src_needs_barrier (pat, new_flags, pred);
+ 	      break;
+ 
+ 	    case USE:
+ 	    case CALL:
+ 	    case ASM_OPERANDS:
+ 	    case ASM_INPUT:
+ 	      need_barrier |= rtx_needs_barrier (pat, flags, pred);
+ 	      break;
+ 
+ 	    case CLOBBER:
+ 	      if (REG_P (XEXP (pat, 0))
+ 		  && extract_asm_operands (x) != NULL_RTX
+ 		  && REGNO (XEXP (pat, 0)) != AR_UNAT_REGNUM)
+ 		{
+ 		  new_flags.is_write = 1;
+ 		  need_barrier |= rtx_needs_barrier (XEXP (pat, 0),
+ 						     new_flags, pred);
+ 		  new_flags = flags;
+ 		}
+ 	      break;
+ 
+ 	    case RETURN:
+ 	      break;
+ 
+ 	    default:
+ 	      gcc_unreachable ();
+ 	    }
+ 	}
+       for (i = XVECLEN (x, 0) - 1; i >= 0; --i)
+ 	{
+ 	  rtx pat = XVECEXP (x, 0, i);
+ 	  if (GET_CODE (pat) == SET)
+ 	    {
+ 	      if (GET_CODE (SET_SRC (pat)) != CALL)
+ 		{
+ 		  new_flags.is_write = 1;
+ 		  need_barrier |= rtx_needs_barrier (SET_DEST (pat), new_flags,
+ 						     pred);
+ 		}
+ 	    }
+ 	  else if (GET_CODE (pat) == CLOBBER || GET_CODE (pat) == RETURN)
+ 	    need_barrier |= rtx_needs_barrier (pat, flags, pred);
+ 	}
+       break;
+ 
+     case SUBREG:
+       need_barrier |= rtx_needs_barrier (SUBREG_REG (x), flags, pred);
+       break;
+     case REG:
+       if (REGNO (x) == AR_UNAT_REGNUM)
+ 	{
+ 	  for (i = 0; i < 64; ++i)
+ 	    need_barrier |= rws_access_regno (AR_UNAT_BIT_0 + i, flags, pred);
+ 	}
+       else
+ 	need_barrier = rws_access_reg (x, flags, pred);
+       break;
+ 
+     case MEM:
+       /* Find the regs used in memory address computation.  */
+       new_flags.is_write = 0;
+       need_barrier = rtx_needs_barrier (XEXP (x, 0), new_flags, pred);
+       break;
+ 
+     case CONST_INT:   case CONST_DOUBLE:  case CONST_VECTOR:
+     case SYMBOL_REF:  case LABEL_REF:     case CONST:
+       break;
+ 
+       /* Operators with side-effects.  */
+     case POST_INC:    case POST_DEC:
+       gcc_assert (GET_CODE (XEXP (x, 0)) == REG);
+ 
+       new_flags.is_write = 0;
+       need_barrier  = rws_access_reg (XEXP (x, 0), new_flags, pred);
+       new_flags.is_write = 1;
+       need_barrier |= rws_access_reg (XEXP (x, 0), new_flags, pred);
+       break;
+ 
+     case POST_MODIFY:
+       gcc_assert (GET_CODE (XEXP (x, 0)) == REG);
+ 
+       new_flags.is_write = 0;
+       need_barrier  = rws_access_reg (XEXP (x, 0), new_flags, pred);
+       need_barrier |= rtx_needs_barrier (XEXP (x, 1), new_flags, pred);
+       new_flags.is_write = 1;
+       need_barrier |= rws_access_reg (XEXP (x, 0), new_flags, pred);
+       break;
+ 
+       /* Handle common unary and binary ops for efficiency.  */
+     case COMPARE:  case PLUS:    case MINUS:   case MULT:      case DIV:
+     case MOD:      case UDIV:    case UMOD:    case AND:       case IOR:
+     case XOR:      case ASHIFT:  case ROTATE:  case ASHIFTRT:  case LSHIFTRT:
+     case ROTATERT: case SMIN:    case SMAX:    case UMIN:      case UMAX:
+     case NE:       case EQ:      case GE:      case GT:        case LE:
+     case LT:       case GEU:     case GTU:     case LEU:       case LTU:
+       need_barrier = rtx_needs_barrier (XEXP (x, 0), new_flags, pred);
+       need_barrier |= rtx_needs_barrier (XEXP (x, 1), new_flags, pred);
+       break;
+ 
+     case NEG:      case NOT:	        case SIGN_EXTEND:     case ZERO_EXTEND:
+     case TRUNCATE: case FLOAT_EXTEND:   case FLOAT_TRUNCATE:  case FLOAT:
+     case FIX:      case UNSIGNED_FLOAT: case UNSIGNED_FIX:    case ABS:
+     case SQRT:     case FFS:		case POPCOUNT:
+       need_barrier = rtx_needs_barrier (XEXP (x, 0), flags, pred);
+       break;
+ 
+     case VEC_SELECT:
+       /* VEC_SELECT's second argument is a PARALLEL with integers that
+ 	 describe the elements selected.  On ia64, those integers are
+ 	 always constants.  Avoid walking the PARALLEL so that we don't
+ 	 get confused with "normal" parallels and then die.  */
+       need_barrier = rtx_needs_barrier (XEXP (x, 0), flags, pred);
+       break;
+ 
+     case UNSPEC:
+       switch (XINT (x, 1))
+ 	{
+ 	case UNSPEC_LTOFF_DTPMOD:
+ 	case UNSPEC_LTOFF_DTPREL:
+ 	case UNSPEC_DTPREL:
+ 	case UNSPEC_LTOFF_TPREL:
+ 	case UNSPEC_TPREL:
+ 	case UNSPEC_PRED_REL_MUTEX:
+ 	case UNSPEC_PIC_CALL:
+         case UNSPEC_MF:
+         case UNSPEC_FETCHADD_ACQ:
+         case UNSPEC_FETCHADD_REL:
+ 	case UNSPEC_BSP_VALUE:
+ 	case UNSPEC_FLUSHRS:
+ 	case UNSPEC_BUNDLE_SELECTOR:
+           break;
+ 
+ 	case UNSPEC_GR_SPILL:
+ 	case UNSPEC_GR_RESTORE:
+ 	  {
+ 	    HOST_WIDE_INT offset = INTVAL (XVECEXP (x, 0, 1));
+ 	    HOST_WIDE_INT bit = (offset >> 3) & 63;
+ 
+ 	    need_barrier = rtx_needs_barrier (XVECEXP (x, 0, 0), flags, pred);
+ 	    new_flags.is_write = (XINT (x, 1) == UNSPEC_GR_SPILL);
+ 	    need_barrier |= rws_access_regno (AR_UNAT_BIT_0 + bit,
+ 					      new_flags, pred);
+ 	    break;
+ 	  }
+ 
+ 	case UNSPEC_FR_SPILL:
+ 	case UNSPEC_FR_RESTORE:
+ 	case UNSPEC_GETF_EXP:
+ 	case UNSPEC_SETF_EXP:
+         case UNSPEC_ADDP4:
+ 	case UNSPEC_FR_SQRT_RECIP_APPROX:
+ 	case UNSPEC_FR_SQRT_RECIP_APPROX_RES:
+ 	case UNSPEC_LDA:
+ 	case UNSPEC_LDS:
+ 	case UNSPEC_LDS_A:
+ 	case UNSPEC_LDSA:
+ 	case UNSPEC_CHKACLR:
+         case UNSPEC_CHKS:
+ 	  need_barrier = rtx_needs_barrier (XVECEXP (x, 0, 0), flags, pred);
+ 	  break;
+ 
+ 	case UNSPEC_FR_RECIP_APPROX:
+ 	case UNSPEC_SHRP:
+ 	case UNSPEC_COPYSIGN:
+ 	case UNSPEC_FR_RECIP_APPROX_RES:
+ 	  need_barrier = rtx_needs_barrier (XVECEXP (x, 0, 0), flags, pred);
+ 	  need_barrier |= rtx_needs_barrier (XVECEXP (x, 0, 1), flags, pred);
+ 	  break;
+ 
+         case UNSPEC_CMPXCHG_ACQ:
+         case UNSPEC_CMPXCHG_REL:
+ 	  need_barrier = rtx_needs_barrier (XVECEXP (x, 0, 1), flags, pred);
+ 	  need_barrier |= rtx_needs_barrier (XVECEXP (x, 0, 2), flags, pred);
+ 	  break;
+ 
+ 	default:
+ 	  gcc_unreachable ();
+ 	}
+       break;
+ 
+     case UNSPEC_VOLATILE:
+       switch (XINT (x, 1))
+ 	{
+ 	case UNSPECV_ALLOC:
+ 	  /* Alloc must always be the first instruction of a group.
+ 	     We force this by always returning true.  */
+ 	  /* ??? We might get better scheduling if we explicitly check for
+ 	     input/local/output register dependencies, and modify the
+ 	     scheduler so that alloc is always reordered to the start of
+ 	     the current group.  We could then eliminate all of the
+ 	     first_instruction code.  */
+ 	  rws_access_regno (AR_PFS_REGNUM, flags, pred);
+ 
+ 	  new_flags.is_write = 1;
+ 	  rws_access_regno (REG_AR_CFM, new_flags, pred);
+ 	  return 1;
+ 
+ 	case UNSPECV_SET_BSP:
+ 	case UNSPECV_PROBE_STACK_RANGE:
+ 	  need_barrier = 1;
+           break;
+ 
+ 	case UNSPECV_BLOCKAGE:
+ 	case UNSPECV_INSN_GROUP_BARRIER:
+ 	case UNSPECV_BREAK:
+ 	case UNSPECV_PSAC_ALL:
+ 	case UNSPECV_PSAC_NORMAL:
+ 	  return 0;
+ 
+ 	case UNSPECV_PROBE_STACK_ADDRESS:
+ 	  need_barrier = rtx_needs_barrier (XVECEXP (x, 0, 0), flags, pred);
+ 	  break;
+ 
+ 	default:
+ 	  gcc_unreachable ();
+ 	}
+       break;
+ 
+     case RETURN:
+       new_flags.is_write = 0;
+       need_barrier  = rws_access_regno (REG_RP, flags, pred);
+       need_barrier |= rws_access_regno (AR_PFS_REGNUM, flags, pred);
+ 
+       new_flags.is_write = 1;
+       need_barrier |= rws_access_regno (AR_EC_REGNUM, new_flags, pred);
+       need_barrier |= rws_access_regno (REG_AR_CFM, new_flags, pred);
+       break;
+ 
+     default:
+       format_ptr = GET_RTX_FORMAT (GET_CODE (x));
+       for (i = GET_RTX_LENGTH (GET_CODE (x)) - 1; i >= 0; i--)
+ 	switch (format_ptr[i])
+ 	  {
+ 	  case '0':	/* unused field */
+ 	  case 'i':	/* integer */
+ 	  case 'n':	/* note */
+ 	  case 'w':	/* wide integer */
+ 	  case 's':	/* pointer to string */
+ 	  case 'S':	/* optional pointer to string */
+ 	    break;
+ 
+ 	  case 'e':
+ 	    if (rtx_needs_barrier (XEXP (x, i), flags, pred))
+ 	      need_barrier = 1;
+ 	    break;
+ 
+ 	  case 'E':
+ 	    for (j = XVECLEN (x, i) - 1; j >= 0; --j)
+ 	      if (rtx_needs_barrier (XVECEXP (x, i, j), flags, pred))
+ 		need_barrier = 1;
+ 	    break;
+ 
+ 	  default:
+ 	    gcc_unreachable ();
+ 	  }
+       break;
+     }
+   return need_barrier;
+ }
+ 
+ /* Clear out the state for group_barrier_needed at the start of a
+    sequence of insns.  */
+ 
+ static void
+ init_insn_group_barriers (void)
+ {
+   memset (rws_sum, 0, sizeof (rws_sum));
+   first_instruction = 1;
+ }
+ 
+ /* Given the current state, determine whether a group barrier (a stop bit) is
+    necessary before INSN.  Return nonzero if so.  This modifies the state to
+    include the effects of INSN as a side-effect.  */
+ 
+ static int
+ group_barrier_needed (rtx_insn *insn)
+ {
+   rtx pat;
+   int need_barrier = 0;
+   struct reg_flags flags;
+ 
+   memset (&flags, 0, sizeof (flags));
+   switch (GET_CODE (insn))
+     {
+     case NOTE:
+     case DEBUG_INSN:
+       break;
+ 
+     case BARRIER:
+       /* A barrier doesn't imply an instruction group boundary.  */
+       break;
+ 
+     case CODE_LABEL:
+       memset (rws_insn, 0, sizeof (rws_insn));
+       return 1;
+ 
+     case CALL_INSN:
+       flags.is_branch = 1;
+       flags.is_sibcall = SIBLING_CALL_P (insn);
+       memset (rws_insn, 0, sizeof (rws_insn));
+ 
+       /* Don't bundle a call following another call.  */
+       if ((pat = prev_active_insn (insn)) && CALL_P (pat))
+ 	{
+ 	  need_barrier = 1;
+ 	  break;
+ 	}
+ 
+       need_barrier = rtx_needs_barrier (PATTERN (insn), flags, 0);
+       break;
+ 
+     case JUMP_INSN:
+       if (!ia64_spec_check_p (insn))
+ 	flags.is_branch = 1;
+ 
+       /* Don't bundle a jump following a call.  */
+       if ((pat = prev_active_insn (insn)) && CALL_P (pat))
+ 	{
+ 	  need_barrier = 1;
+ 	  break;
+ 	}
+       /* FALLTHRU */
+ 
+     case INSN:
+       if (GET_CODE (PATTERN (insn)) == USE
+ 	  || GET_CODE (PATTERN (insn)) == CLOBBER)
+ 	/* Don't care about USE and CLOBBER "insns"---those are used to
+ 	   indicate to the optimizer that it shouldn't get rid of
+ 	   certain operations.  */
+ 	break;
+ 
+       pat = PATTERN (insn);
+ 
+       /* Ug.  Hack hacks hacked elsewhere.  */
+       switch (recog_memoized (insn))
+ 	{
+ 	  /* We play dependency tricks with the epilogue in order
+ 	     to get proper schedules.  Undo this for dv analysis.  */
+ 	case CODE_FOR_epilogue_deallocate_stack:
+ 	case CODE_FOR_prologue_allocate_stack:
+ 	  pat = XVECEXP (pat, 0, 0);
+ 	  break;
+ 
+ 	  /* The pattern we use for br.cloop confuses the code above.
+ 	     The second element of the vector is representative.  */
+ 	case CODE_FOR_doloop_end_internal:
+ 	  pat = XVECEXP (pat, 0, 1);
+ 	  break;
+ 
+ 	  /* Doesn't generate code.  */
+ 	case CODE_FOR_pred_rel_mutex:
+ 	case CODE_FOR_prologue_use:
+ 	  return 0;
+ 
+ 	default:
+ 	  break;
+ 	}
+ 
+       memset (rws_insn, 0, sizeof (rws_insn));
+       need_barrier = rtx_needs_barrier (pat, flags, 0);
+ 
+       /* Check to see if the previous instruction was a volatile
+ 	 asm.  */
+       if (! need_barrier)
+ 	need_barrier = rws_access_regno (REG_VOLATILE, flags, 0);
+ 
+       break;
+ 
+     default:
+       gcc_unreachable ();
+     }
+ 
+   if (first_instruction && important_for_bundling_p (insn))
+     {
+       need_barrier = 0;
+       first_instruction = 0;
+     }
+ 
+   return need_barrier;
+ }
+ 
+ /* Like group_barrier_needed, but do not clobber the current state.  */
+ 
+ static int
+ safe_group_barrier_needed (rtx_insn *insn)
+ {
+   int saved_first_instruction;
+   int t;
+ 
+   saved_first_instruction = first_instruction;
+   in_safe_group_barrier = 1;
+ 
+   t = group_barrier_needed (insn);
+ 
+   first_instruction = saved_first_instruction;
+   in_safe_group_barrier = 0;
+ 
+   return t;
+ }
+ 
+ /* Scan the current function and insert stop bits as necessary to
+    eliminate dependencies.  This function assumes that a final
+    instruction scheduling pass has been run which has already
+    inserted most of the necessary stop bits.  This function only
+    inserts new ones at basic block boundaries, since these are
+    invisible to the scheduler.  */
+ 
+ static void
+ emit_insn_group_barriers (FILE *dump)
+ {
+   rtx_insn *insn;
+   rtx_insn *last_label = 0;
+   int insns_since_last_label = 0;
+ 
+   init_insn_group_barriers ();
+ 
+   for (insn = get_insns (); insn; insn = NEXT_INSN (insn))
+     {
+       if (LABEL_P (insn))
+ 	{
+ 	  if (insns_since_last_label)
+ 	    last_label = insn;
+ 	  insns_since_last_label = 0;
+ 	}
+       else if (NOTE_P (insn)
+ 	       && NOTE_KIND (insn) == NOTE_INSN_BASIC_BLOCK)
+ 	{
+ 	  if (insns_since_last_label)
+ 	    last_label = insn;
+ 	  insns_since_last_label = 0;
+ 	}
+       else if (NONJUMP_INSN_P (insn)
+ 	       && GET_CODE (PATTERN (insn)) == UNSPEC_VOLATILE
+ 	       && XINT (PATTERN (insn), 1) == UNSPECV_INSN_GROUP_BARRIER)
+ 	{
+ 	  init_insn_group_barriers ();
+ 	  last_label = 0;
+ 	}
+       else if (NONDEBUG_INSN_P (insn))
+ 	{
+ 	  insns_since_last_label = 1;
+ 
+ 	  if (group_barrier_needed (insn))
+ 	    {
+ 	      if (last_label)
+ 		{
+ 		  if (dump)
+ 		    fprintf (dump, "Emitting stop before label %d\n",
+ 			     INSN_UID (last_label));
+ 		  emit_insn_before (gen_insn_group_barrier (GEN_INT (3)), last_label);
+ 		  insn = last_label;
+ 
+ 		  init_insn_group_barriers ();
+ 		  last_label = 0;
+ 		}
+ 	    }
+ 	}
+     }
+ }
+ 
+ /* Like emit_insn_group_barriers, but run if no final scheduling pass was run.
+    This function has to emit all necessary group barriers.  */
+ 
+ static void
+ emit_all_insn_group_barriers (FILE *dump ATTRIBUTE_UNUSED)
+ {
+   rtx_insn *insn;
+ 
+   init_insn_group_barriers ();
+ 
+   for (insn = get_insns (); insn; insn = NEXT_INSN (insn))
+     {
+       if (BARRIER_P (insn))
+ 	{
+ 	  rtx_insn *last = prev_active_insn (insn);
+ 
+ 	  if (! last)
+ 	    continue;
+ 	  if (JUMP_TABLE_DATA_P (last))
+ 	    last = prev_active_insn (last);
+ 	  if (recog_memoized (last) != CODE_FOR_insn_group_barrier)
+ 	    emit_insn_after (gen_insn_group_barrier (GEN_INT (3)), last);
+ 
+ 	  init_insn_group_barriers ();
+ 	}
+       else if (NONDEBUG_INSN_P (insn))
+ 	{
+ 	  if (recog_memoized (insn) == CODE_FOR_insn_group_barrier)
+ 	    init_insn_group_barriers ();
+ 	  else if (group_barrier_needed (insn))
+ 	    {
+ 	      emit_insn_before (gen_insn_group_barrier (GEN_INT (3)), insn);
+ 	      init_insn_group_barriers ();
+ 	      group_barrier_needed (insn);
+ 	    }
+ 	}
+     }
+ }
+ 
+ \f
+ 
+ /* Instruction scheduling support.  */
+ 
+ #define NR_BUNDLES 10
+ 
+ /* A list of names of all available bundles.  */
+ 
+ static const char *bundle_name [NR_BUNDLES] =
+ {
+   ".mii",
+   ".mmi",
+   ".mfi",
+   ".mmf",
+ #if NR_BUNDLES == 10
+   ".bbb",
+   ".mbb",
+ #endif
+   ".mib",
+   ".mmb",
+   ".mfb",
+   ".mlx"
+ };
+ 
+ /* Nonzero if we should insert stop bits into the schedule.  */
+ 
+ int ia64_final_schedule = 0;
+ 
+ /* Codes of the corresponding queried units: */
+ 
+ static int _0mii_, _0mmi_, _0mfi_, _0mmf_;
+ static int _0bbb_, _0mbb_, _0mib_, _0mmb_, _0mfb_, _0mlx_;
+ 
+ static int _1mii_, _1mmi_, _1mfi_, _1mmf_;
+ static int _1bbb_, _1mbb_, _1mib_, _1mmb_, _1mfb_, _1mlx_;
+ 
+ static int pos_1, pos_2, pos_3, pos_4, pos_5, pos_6;
+ 
+ /* The following variable value is an insn group barrier.  */
+ 
+ static rtx_insn *dfa_stop_insn;
+ 
+ /* The following variable value is the last issued insn.  */
+ 
+ static rtx_insn *last_scheduled_insn;
+ 
+ /* The following variable value is pointer to a DFA state used as
+    temporary variable.  */
+ 
+ static state_t temp_dfa_state = NULL;
+ 
+ /* The following variable value is DFA state after issuing the last
+    insn.  */
+ 
+ static state_t prev_cycle_state = NULL;
+ 
+ /* The following array element values are TRUE if the corresponding
+    insn requires to add stop bits before it.  */
+ 
+ static char *stops_p = NULL;
+ 
+ /* The following variable is used to set up the mentioned above array.  */
+ 
+ static int stop_before_p = 0;
+ 
+ /* The following variable value is length of the arrays `clocks' and
+    `add_cycles'. */
+ 
+ static int clocks_length;
+ 
+ /* The following variable value is number of data speculations in progress.  */
+ static int pending_data_specs = 0;
+ 
+ /* Number of memory references on current and three future processor cycles.  */
+ static char mem_ops_in_group[4];
+ 
+ /* Number of current processor cycle (from scheduler's point of view).  */
+ static int current_cycle;
+ 
+ static rtx ia64_single_set (rtx_insn *);
+ static void ia64_emit_insn_before (rtx, rtx_insn *);
+ 
+ /* Map a bundle number to its pseudo-op.  */
+ 
+ const char *
+ get_bundle_name (int b)
+ {
+   return bundle_name[b];
+ }
+ 
+ 
+ /* Return the maximum number of instructions a cpu can issue.  */
+ 
+ static int
+ ia64_issue_rate (void)
+ {
+   return 6;
+ }
+ 
+ /* Helper function - like single_set, but look inside COND_EXEC.  */
+ 
+ static rtx
+ ia64_single_set (rtx_insn *insn)
+ {
+   rtx x = PATTERN (insn), ret;
+   if (GET_CODE (x) == COND_EXEC)
+     x = COND_EXEC_CODE (x);
+   if (GET_CODE (x) == SET)
+     return x;
+ 
+   /* Special case here prologue_allocate_stack and epilogue_deallocate_stack.
+      Although they are not classical single set, the second set is there just
+      to protect it from moving past FP-relative stack accesses.  */
+   switch (recog_memoized (insn))
+     {
+     case CODE_FOR_prologue_allocate_stack:
+     case CODE_FOR_prologue_allocate_stack_pr:
+     case CODE_FOR_epilogue_deallocate_stack:
+     case CODE_FOR_epilogue_deallocate_stack_pr:
+       ret = XVECEXP (x, 0, 0);
+       break;
+ 
+     default:
+       ret = single_set_2 (insn, x);
+       break;
+     }
+ 
+   return ret;
+ }
+ 
+ /* Adjust the cost of a scheduling dependency.
+    Return the new cost of a dependency of type DEP_TYPE or INSN on DEP_INSN.
+    COST is the current cost, DW is dependency weakness.  */
+ static int
+ ia64_adjust_cost (rtx_insn *insn, int dep_type1, rtx_insn *dep_insn,
+ 		  int cost, dw_t dw)
+ {
+   enum reg_note dep_type = (enum reg_note) dep_type1;
+   enum attr_itanium_class dep_class;
+   enum attr_itanium_class insn_class;
+ 
+   insn_class = ia64_safe_itanium_class (insn);
+   dep_class = ia64_safe_itanium_class (dep_insn);
+ 
+   /* Treat true memory dependencies separately.  Ignore apparent true
+      dependence between store and call (call has a MEM inside a SYMBOL_REF).  */
+   if (dep_type == REG_DEP_TRUE
+       && (dep_class == ITANIUM_CLASS_ST || dep_class == ITANIUM_CLASS_STF)
+       && (insn_class == ITANIUM_CLASS_BR || insn_class == ITANIUM_CLASS_SCALL))
+     return 0;
+ 
+   if (dw == MIN_DEP_WEAK)
+     /* Store and load are likely to alias, use higher cost to avoid stall.  */
+     return param_sched_mem_true_dep_cost;
+   else if (dw > MIN_DEP_WEAK)
+     {
+       /* Store and load are less likely to alias.  */
+       if (mflag_sched_fp_mem_deps_zero_cost && dep_class == ITANIUM_CLASS_STF)
+ 	/* Assume there will be no cache conflict for floating-point data.
+ 	   For integer data, L1 conflict penalty is huge (17 cycles), so we
+ 	   never assume it will not cause a conflict.  */
+ 	return 0;
+       else
+ 	return cost;
+     }
+ 
+   if (dep_type != REG_DEP_OUTPUT)
+     return cost;
+ 
+   if (dep_class == ITANIUM_CLASS_ST || dep_class == ITANIUM_CLASS_STF
+       || insn_class == ITANIUM_CLASS_ST || insn_class == ITANIUM_CLASS_STF)
+     return 0;
+ 
+   return cost;
+ }
+ 
+ /* Like emit_insn_before, but skip cycle_display notes.
+    ??? When cycle display notes are implemented, update this.  */
+ 
+ static void
+ ia64_emit_insn_before (rtx insn, rtx_insn *before)
+ {
+   emit_insn_before (insn, before);
+ }
+ 
+ /* The following function marks insns who produce addresses for load
+    and store insns.  Such insns will be placed into M slots because it
+    decrease latency time for Itanium1 (see function
+    `ia64_produce_address_p' and the DFA descriptions).  */
+ 
+ static void
+ ia64_dependencies_evaluation_hook (rtx_insn *head, rtx_insn *tail)
+ {
+   rtx_insn *insn, *next, *next_tail;
+ 
+   /* Before reload, which_alternative is not set, which means that
+      ia64_safe_itanium_class will produce wrong results for (at least)
+      move instructions.  */
+   if (!reload_completed)
+     return;
+ 
+   next_tail = NEXT_INSN (tail);
+   for (insn = head; insn != next_tail; insn = NEXT_INSN (insn))
+     if (INSN_P (insn))
+       insn->call = 0;
+   for (insn = head; insn != next_tail; insn = NEXT_INSN (insn))
+     if (INSN_P (insn)
+ 	&& ia64_safe_itanium_class (insn) == ITANIUM_CLASS_IALU)
+       {
+ 	sd_iterator_def sd_it;
+ 	dep_t dep;
+ 	bool has_mem_op_consumer_p = false;
+ 
+ 	FOR_EACH_DEP (insn, SD_LIST_FORW, sd_it, dep)
+ 	  {
+ 	    enum attr_itanium_class c;
+ 
+ 	    if (DEP_TYPE (dep) != REG_DEP_TRUE)
+ 	      continue;
+ 
+ 	    next = DEP_CON (dep);
+ 	    c = ia64_safe_itanium_class (next);
+ 	    if ((c == ITANIUM_CLASS_ST
+ 		 || c == ITANIUM_CLASS_STF)
+ 		&& ia64_st_address_bypass_p (insn, next))
+ 	      {
+ 		has_mem_op_consumer_p = true;
+ 		break;
+ 	      }
+ 	    else if ((c == ITANIUM_CLASS_LD
+ 		      || c == ITANIUM_CLASS_FLD
+ 		      || c == ITANIUM_CLASS_FLDP)
+ 		     && ia64_ld_address_bypass_p (insn, next))
+ 	      {
+ 		has_mem_op_consumer_p = true;
+ 		break;
+ 	      }
+ 	  }
+ 
+ 	insn->call = has_mem_op_consumer_p;
+       }
+ }
+ 
+ /* We're beginning a new block.  Initialize data structures as necessary.  */
+ 
+ static void
+ ia64_sched_init (FILE *dump ATTRIBUTE_UNUSED,
+ 		 int sched_verbose ATTRIBUTE_UNUSED,
+ 		 int max_ready ATTRIBUTE_UNUSED)
+ {
+   if (flag_checking && !sel_sched_p () && reload_completed)
+     {
+       for (rtx_insn *insn = NEXT_INSN (current_sched_info->prev_head);
+ 	   insn != current_sched_info->next_tail;
+ 	   insn = NEXT_INSN (insn))
+ 	gcc_assert (!SCHED_GROUP_P (insn));
+     }
+   last_scheduled_insn = NULL;
+   init_insn_group_barriers ();
+ 
+   current_cycle = 0;
+   memset (mem_ops_in_group, 0, sizeof (mem_ops_in_group));
+ }
+ 
+ /* We're beginning a scheduling pass.  Check assertion.  */
+ 
+ static void
+ ia64_sched_init_global (FILE *dump ATTRIBUTE_UNUSED,
+                         int sched_verbose ATTRIBUTE_UNUSED,
+                         int max_ready ATTRIBUTE_UNUSED)
+ {  
+   gcc_assert (pending_data_specs == 0);
+ }
+ 
+ /* Scheduling pass is now finished.  Free/reset static variable.  */
+ static void
+ ia64_sched_finish_global (FILE *dump ATTRIBUTE_UNUSED,
+ 			  int sched_verbose ATTRIBUTE_UNUSED)
+ {
+   gcc_assert (pending_data_specs == 0);
+ }
+ 
+ /* Return TRUE if INSN is a load (either normal or speculative, but not a
+    speculation check), FALSE otherwise.  */
+ static bool
+ is_load_p (rtx_insn *insn)
+ {
+   enum attr_itanium_class insn_class = ia64_safe_itanium_class (insn);
+ 
+   return
+    ((insn_class == ITANIUM_CLASS_LD || insn_class == ITANIUM_CLASS_FLD)
+     && get_attr_check_load (insn) == CHECK_LOAD_NO);
+ }
+ 
+ /* If INSN is a memory reference, memoize it in MEM_OPS_IN_GROUP global array
+    (taking account for 3-cycle cache reference postponing for stores: Intel
+    Itanium 2 Reference Manual for Software Development and Optimization,
+    6.7.3.1).  */
+ static void
+ record_memory_reference (rtx_insn *insn)
+ {
+   enum attr_itanium_class insn_class = ia64_safe_itanium_class (insn);
+ 
+   switch (insn_class) {
+     case ITANIUM_CLASS_FLD:
+     case ITANIUM_CLASS_LD:
+       mem_ops_in_group[current_cycle % 4]++;
+       break;
+     case ITANIUM_CLASS_STF:
+     case ITANIUM_CLASS_ST:
+       mem_ops_in_group[(current_cycle + 3) % 4]++;
+       break;
+     default:;
+   }
+ }
+ 
+ /* We are about to being issuing insns for this clock cycle.
+    Override the default sort algorithm to better slot instructions.  */
+ 
+ static int
+ ia64_dfa_sched_reorder (FILE *dump, int sched_verbose, rtx_insn **ready,
+ 			int *pn_ready, int clock_var,
+ 			int reorder_type)
+ {
+   int n_asms;
+   int n_ready = *pn_ready;
+   rtx_insn **e_ready = ready + n_ready;
+   rtx_insn **insnp;
+ 
+   if (sched_verbose)
+     fprintf (dump, "// ia64_dfa_sched_reorder (type %d):\n", reorder_type);
+ 
+   if (reorder_type == 0)
+     {
+       /* First, move all USEs, CLOBBERs and other crud out of the way.  */
+       n_asms = 0;
+       for (insnp = ready; insnp < e_ready; insnp++)
+ 	if (insnp < e_ready)
+ 	  {
+ 	    rtx_insn *insn = *insnp;
+ 	    enum attr_type t = ia64_safe_type (insn);
+ 	    if (t == TYPE_UNKNOWN)
+ 	      {
+ 		if (GET_CODE (PATTERN (insn)) == ASM_INPUT
+ 		    || asm_noperands (PATTERN (insn)) >= 0)
+ 		  {
+ 		    rtx_insn *lowest = ready[n_asms];
+ 		    ready[n_asms] = insn;
+ 		    *insnp = lowest;
+ 		    n_asms++;
+ 		  }
+ 		else
+ 		  {
+ 		    rtx_insn *highest = ready[n_ready - 1];
+ 		    ready[n_ready - 1] = insn;
+ 		    *insnp = highest;
+ 		    return 1;
+ 		  }
+ 	      }
+ 	  }
+ 
+       if (n_asms < n_ready)
+ 	{
+ 	  /* Some normal insns to process.  Skip the asms.  */
+ 	  ready += n_asms;
+ 	  n_ready -= n_asms;
+ 	}
+       else if (n_ready > 0)
+ 	return 1;
+     }
+ 
+   if (ia64_final_schedule)
+     {
+       int deleted = 0;
+       int nr_need_stop = 0;
+ 
+       for (insnp = ready; insnp < e_ready; insnp++)
+ 	if (safe_group_barrier_needed (*insnp))
+ 	  nr_need_stop++;
+ 
+       if (reorder_type == 1 && n_ready == nr_need_stop)
+ 	return 0;
+       if (reorder_type == 0)
+ 	return 1;
+       insnp = e_ready;
+       /* Move down everything that needs a stop bit, preserving
+ 	 relative order.  */
+       while (insnp-- > ready + deleted)
+ 	while (insnp >= ready + deleted)
+ 	  {
+ 	    rtx_insn *insn = *insnp;
+ 	    if (! safe_group_barrier_needed (insn))
+ 	      break;
+ 	    memmove (ready + 1, ready, (insnp - ready) * sizeof (rtx));
+ 	    *ready = insn;
+ 	    deleted++;
+ 	  }
+       n_ready -= deleted;
+       ready += deleted;
+     }
+ 
+   current_cycle = clock_var;
+   if (reload_completed && mem_ops_in_group[clock_var % 4] >= ia64_max_memory_insns)
+     {
+       int moved = 0;
+ 
+       insnp = e_ready;
+       /* Move down loads/stores, preserving relative order.  */
+       while (insnp-- > ready + moved)
+ 	while (insnp >= ready + moved)
+ 	  {
+ 	    rtx_insn *insn = *insnp;
+ 	    if (! is_load_p (insn))
+ 	      break;
+ 	    memmove (ready + 1, ready, (insnp - ready) * sizeof (rtx));
+ 	    *ready = insn;
+ 	    moved++;
+ 	  }
+       n_ready -= moved;
+       ready += moved;
+     }
+ 
+   return 1;
+ }
+ 
+ /* We are about to being issuing insns for this clock cycle.  Override
+    the default sort algorithm to better slot instructions.  */
+ 
+ static int
+ ia64_sched_reorder (FILE *dump, int sched_verbose, rtx_insn **ready,
+ 		    int *pn_ready, int clock_var)
+ {
+   return ia64_dfa_sched_reorder (dump, sched_verbose, ready,
+ 				 pn_ready, clock_var, 0);
+ }
+ 
+ /* Like ia64_sched_reorder, but called after issuing each insn.
+    Override the default sort algorithm to better slot instructions.  */
+ 
+ static int
+ ia64_sched_reorder2 (FILE *dump ATTRIBUTE_UNUSED,
+ 		     int sched_verbose ATTRIBUTE_UNUSED, rtx_insn **ready,
+ 		     int *pn_ready, int clock_var)
+ {
+   return ia64_dfa_sched_reorder (dump, sched_verbose, ready, pn_ready,
+ 				 clock_var, 1);
+ }
+ 
+ /* We are about to issue INSN.  Return the number of insns left on the
+    ready queue that can be issued this cycle.  */
+ 
+ static int
+ ia64_variable_issue (FILE *dump ATTRIBUTE_UNUSED,
+ 		     int sched_verbose ATTRIBUTE_UNUSED,
+ 		     rtx_insn *insn,
+ 		     int can_issue_more ATTRIBUTE_UNUSED)
+ {
+   if (sched_deps_info->generate_spec_deps && !sel_sched_p ())
+     /* Modulo scheduling does not extend h_i_d when emitting
+        new instructions.  Don't use h_i_d, if we don't have to.  */
+     {
+       if (DONE_SPEC (insn) & BEGIN_DATA)
+ 	pending_data_specs++;
+       if (CHECK_SPEC (insn) & BEGIN_DATA)
+ 	pending_data_specs--;
+     }
+ 
+   if (DEBUG_INSN_P (insn))
+     return 1;
+ 
+   last_scheduled_insn = insn;
+   memcpy (prev_cycle_state, curr_state, dfa_state_size);
+   if (reload_completed)
+     {
+       int needed = group_barrier_needed (insn);
+       
+       gcc_assert (!needed);
+       if (CALL_P (insn))
+ 	init_insn_group_barriers ();
+       stops_p [INSN_UID (insn)] = stop_before_p;
+       stop_before_p = 0;
+ 
+       record_memory_reference (insn);
+     }
+   return 1;
+ }
+ 
+ /* We are choosing insn from the ready queue.  Return zero if INSN
+    can be chosen.  */
+ 
+ static int
+ ia64_first_cycle_multipass_dfa_lookahead_guard (rtx_insn *insn, int ready_index)
+ {
+   gcc_assert (insn && INSN_P (insn));
+ 
+   /* Size of ALAT is 32.  As far as we perform conservative
+      data speculation, we keep ALAT half-empty.  */
+   if (pending_data_specs >= 16 && (TODO_SPEC (insn) & BEGIN_DATA))
+     return ready_index == 0 ? -1 : 1;
+ 
+   if (ready_index == 0)
+     return 0;
+ 
+   if ((!reload_completed
+        || !safe_group_barrier_needed (insn))
+       && (!mflag_sched_mem_insns_hard_limit
+ 	  || !is_load_p (insn)
+ 	  || mem_ops_in_group[current_cycle % 4] < ia64_max_memory_insns))
+     return 0;
+ 
+   return 1;
+ }
+ 
+ /* The following variable value is pseudo-insn used by the DFA insn
+    scheduler to change the DFA state when the simulated clock is
+    increased.  */
+ 
+ static rtx_insn *dfa_pre_cycle_insn;
+ 
+ /* Returns 1 when a meaningful insn was scheduled between the last group
+    barrier and LAST.  */
+ static int
+ scheduled_good_insn (rtx_insn *last)
+ {
+   if (last && recog_memoized (last) >= 0)
+     return 1;
+ 
+   for ( ;
+        last != NULL && !NOTE_INSN_BASIC_BLOCK_P (last)
+        && !stops_p[INSN_UID (last)];
+        last = PREV_INSN (last))
+     /* We could hit a NOTE_INSN_DELETED here which is actually outside
+        the ebb we're scheduling.  */
+     if (INSN_P (last) && recog_memoized (last) >= 0)
+       return 1;
+ 
+   return 0;
+ }
+ 
+ /* We are about to being issuing INSN.  Return nonzero if we cannot
+    issue it on given cycle CLOCK and return zero if we should not sort
+    the ready queue on the next clock start.  */
+ 
+ static int
+ ia64_dfa_new_cycle (FILE *dump, int verbose, rtx_insn *insn, int last_clock,
+ 		    int clock, int *sort_p)
+ {
+   gcc_assert (insn && INSN_P (insn));
+ 
+   if (DEBUG_INSN_P (insn))
+     return 0;
+ 
+   /* When a group barrier is needed for insn, last_scheduled_insn
+      should be set.  */
+   gcc_assert (!(reload_completed && safe_group_barrier_needed (insn))
+               || last_scheduled_insn);
+ 
+   if ((reload_completed
+        && (safe_group_barrier_needed (insn)
+ 	   || (mflag_sched_stop_bits_after_every_cycle
+ 	       && last_clock != clock
+ 	       && last_scheduled_insn
+ 	       && scheduled_good_insn (last_scheduled_insn))))
+       || (last_scheduled_insn
+ 	  && (CALL_P (last_scheduled_insn)
+ 	      || unknown_for_bundling_p (last_scheduled_insn))))
+     {
+       init_insn_group_barriers ();
+ 
+       if (verbose && dump)
+ 	fprintf (dump, "//    Stop should be before %d%s\n", INSN_UID (insn),
+ 		 last_clock == clock ? " + cycle advance" : "");
+ 
+       stop_before_p = 1;
+       current_cycle = clock;
+       mem_ops_in_group[current_cycle % 4] = 0;
+ 
+       if (last_clock == clock)
+ 	{
+ 	  state_transition (curr_state, dfa_stop_insn);
+ 	  if (TARGET_EARLY_STOP_BITS)
+ 	    *sort_p = (last_scheduled_insn == NULL_RTX
+ 		       || ! CALL_P (last_scheduled_insn));
+ 	  else
+ 	    *sort_p = 0;
+ 	  return 1;
+ 	}
+ 
+       if (last_scheduled_insn)
+ 	{
+ 	  if (unknown_for_bundling_p (last_scheduled_insn))
+ 	    state_reset (curr_state);
+ 	  else
+ 	    {
+ 	      memcpy (curr_state, prev_cycle_state, dfa_state_size);
+ 	      state_transition (curr_state, dfa_stop_insn);
+ 	      state_transition (curr_state, dfa_pre_cycle_insn);
+ 	      state_transition (curr_state, NULL);
+ 	    }
+ 	}
+     }
+   return 0;
+ }
+ 
+ /* Implement targetm.sched.h_i_d_extended hook.
+    Extend internal data structures.  */
+ static void
+ ia64_h_i_d_extended (void)
+ {
+   if (stops_p != NULL) 
+     {
+       int new_clocks_length = get_max_uid () * 3 / 2;
+       stops_p = (char *) xrecalloc (stops_p, new_clocks_length, clocks_length, 1);
+       clocks_length = new_clocks_length;
+     }
+ }
+ \f
+ 
+ /* This structure describes the data used by the backend to guide scheduling.
+    When the current scheduling point is switched, this data should be saved
+    and restored later, if the scheduler returns to this point.  */
+ struct _ia64_sched_context
+ {
+   state_t prev_cycle_state;
+   rtx_insn *last_scheduled_insn;
+   struct reg_write_state rws_sum[NUM_REGS];
+   struct reg_write_state rws_insn[NUM_REGS];
+   int first_instruction;
+   int pending_data_specs;
+   int current_cycle;
+   char mem_ops_in_group[4];
+ };
+ typedef struct _ia64_sched_context *ia64_sched_context_t;
+ 
+ /* Allocates a scheduling context.  */
+ static void *
+ ia64_alloc_sched_context (void)
+ {
+   return xmalloc (sizeof (struct _ia64_sched_context));
+ }
+ 
+ /* Initializes the _SC context with clean data, if CLEAN_P, and from
+    the global context otherwise.  */
+ static void
+ ia64_init_sched_context (void *_sc, bool clean_p)
+ {
+   ia64_sched_context_t sc = (ia64_sched_context_t) _sc;
+ 
+   sc->prev_cycle_state = xmalloc (dfa_state_size);
+   if (clean_p)
+     {
+       state_reset (sc->prev_cycle_state);
+       sc->last_scheduled_insn = NULL;
+       memset (sc->rws_sum, 0, sizeof (rws_sum));
+       memset (sc->rws_insn, 0, sizeof (rws_insn));
+       sc->first_instruction = 1;
+       sc->pending_data_specs = 0;
+       sc->current_cycle = 0;
+       memset (sc->mem_ops_in_group, 0, sizeof (mem_ops_in_group));
+     }
+   else
+     {
+       memcpy (sc->prev_cycle_state, prev_cycle_state, dfa_state_size);
+       sc->last_scheduled_insn = last_scheduled_insn;
+       memcpy (sc->rws_sum, rws_sum, sizeof (rws_sum));
+       memcpy (sc->rws_insn, rws_insn, sizeof (rws_insn));
+       sc->first_instruction = first_instruction;
+       sc->pending_data_specs = pending_data_specs;
+       sc->current_cycle = current_cycle;
+       memcpy (sc->mem_ops_in_group, mem_ops_in_group, sizeof (mem_ops_in_group));
+     }
+ }
+ 
+ /* Sets the global scheduling context to the one pointed to by _SC.  */
+ static void
+ ia64_set_sched_context (void *_sc)
+ {
+   ia64_sched_context_t sc = (ia64_sched_context_t) _sc;
+ 
+   gcc_assert (sc != NULL);
+ 
+   memcpy (prev_cycle_state, sc->prev_cycle_state, dfa_state_size);
+   last_scheduled_insn = sc->last_scheduled_insn;
+   memcpy (rws_sum, sc->rws_sum, sizeof (rws_sum));
+   memcpy (rws_insn, sc->rws_insn, sizeof (rws_insn));
+   first_instruction = sc->first_instruction;
+   pending_data_specs = sc->pending_data_specs;
+   current_cycle = sc->current_cycle;
+   memcpy (mem_ops_in_group, sc->mem_ops_in_group, sizeof (mem_ops_in_group));
+ }
+ 
+ /* Clears the data in the _SC scheduling context.  */
+ static void
+ ia64_clear_sched_context (void *_sc)
+ {
+   ia64_sched_context_t sc = (ia64_sched_context_t) _sc;
+   
+   free (sc->prev_cycle_state);
+   sc->prev_cycle_state = NULL;
+ }
+ 
+ /* Frees the _SC scheduling context.  */
+ static void
+ ia64_free_sched_context (void *_sc)
+ {
+   gcc_assert (_sc != NULL);
+ 
+   free (_sc);
+ }
+ 
+ typedef rtx (* gen_func_t) (rtx, rtx);
+ 
+ /* Return a function that will generate a load of mode MODE_NO
+    with speculation types TS.  */
+ static gen_func_t
+ get_spec_load_gen_function (ds_t ts, int mode_no)
+ {
+   static gen_func_t gen_ld_[] = {
+     gen_movbi,
+     gen_movqi_internal,
+     gen_movhi_internal,
+     gen_movsi_internal,
+     gen_movdi_internal,
+     gen_movsf_internal,
+     gen_movdf_internal,
+     gen_movxf_internal,
+     gen_movti_internal,
+     gen_zero_extendqidi2,
+     gen_zero_extendhidi2,
+     gen_zero_extendsidi2,
+   };
+ 
+   static gen_func_t gen_ld_a[] = {
+     gen_movbi_advanced,
+     gen_movqi_advanced,
+     gen_movhi_advanced,
+     gen_movsi_advanced,
+     gen_movdi_advanced,
+     gen_movsf_advanced,
+     gen_movdf_advanced,
+     gen_movxf_advanced,
+     gen_movti_advanced,
+     gen_zero_extendqidi2_advanced,
+     gen_zero_extendhidi2_advanced,
+     gen_zero_extendsidi2_advanced,
+   };
+   static gen_func_t gen_ld_s[] = {
+     gen_movbi_speculative,
+     gen_movqi_speculative,
+     gen_movhi_speculative,
+     gen_movsi_speculative,
+     gen_movdi_speculative,
+     gen_movsf_speculative,
+     gen_movdf_speculative,
+     gen_movxf_speculative,
+     gen_movti_speculative,
+     gen_zero_extendqidi2_speculative,
+     gen_zero_extendhidi2_speculative,
+     gen_zero_extendsidi2_speculative,
+   };
+   static gen_func_t gen_ld_sa[] = {
+     gen_movbi_speculative_advanced,
+     gen_movqi_speculative_advanced,
+     gen_movhi_speculative_advanced,
+     gen_movsi_speculative_advanced,
+     gen_movdi_speculative_advanced,
+     gen_movsf_speculative_advanced,
+     gen_movdf_speculative_advanced,
+     gen_movxf_speculative_advanced,
+     gen_movti_speculative_advanced,
+     gen_zero_extendqidi2_speculative_advanced,
+     gen_zero_extendhidi2_speculative_advanced,
+     gen_zero_extendsidi2_speculative_advanced,
+   };
+   static gen_func_t gen_ld_s_a[] = {
+     gen_movbi_speculative_a,
+     gen_movqi_speculative_a,
+     gen_movhi_speculative_a,
+     gen_movsi_speculative_a,
+     gen_movdi_speculative_a,
+     gen_movsf_speculative_a,
+     gen_movdf_speculative_a,
+     gen_movxf_speculative_a,
+     gen_movti_speculative_a,
+     gen_zero_extendqidi2_speculative_a,
+     gen_zero_extendhidi2_speculative_a,
+     gen_zero_extendsidi2_speculative_a,
+   };
+ 
+   gen_func_t *gen_ld;
+ 
+   if (ts & BEGIN_DATA)
+     {
+       if (ts & BEGIN_CONTROL)
+ 	gen_ld = gen_ld_sa;
+       else
+ 	gen_ld = gen_ld_a;
+     }
+   else if (ts & BEGIN_CONTROL)
+     {
+       if ((spec_info->flags & SEL_SCHED_SPEC_DONT_CHECK_CONTROL)
+ 	  || ia64_needs_block_p (ts))
+ 	gen_ld = gen_ld_s;
+       else
+ 	gen_ld = gen_ld_s_a;
+     }
+   else if (ts == 0)
+     gen_ld = gen_ld_;
+   else
+     gcc_unreachable ();
+ 
+   return gen_ld[mode_no];
+ }
+ 
+ /* Constants that help mapping 'machine_mode' to int.  */
+ enum SPEC_MODES
+   {
+     SPEC_MODE_INVALID = -1,
+     SPEC_MODE_FIRST = 0,
+     SPEC_MODE_FOR_EXTEND_FIRST = 1,
+     SPEC_MODE_FOR_EXTEND_LAST = 3,
+     SPEC_MODE_LAST = 8
+   };
+ 
+ enum
+   {
+     /* Offset to reach ZERO_EXTEND patterns.  */
+     SPEC_GEN_EXTEND_OFFSET = SPEC_MODE_LAST - SPEC_MODE_FOR_EXTEND_FIRST + 1
+   };
+ 
+ /* Return index of the MODE.  */
+ static int
+ ia64_mode_to_int (machine_mode mode)
+ {
+   switch (mode)
+     {
+     case E_BImode: return 0; /* SPEC_MODE_FIRST  */
+     case E_QImode: return 1; /* SPEC_MODE_FOR_EXTEND_FIRST  */
+     case E_HImode: return 2;
+     case E_SImode: return 3; /* SPEC_MODE_FOR_EXTEND_LAST  */
+     case E_DImode: return 4;
+     case E_SFmode: return 5;
+     case E_DFmode: return 6;
+     case E_XFmode: return 7;
+     case E_TImode:
+       /* ??? This mode needs testing.  Bypasses for ldfp8 instruction are not
+ 	 mentioned in itanium[12].md.  Predicate fp_register_operand also
+ 	 needs to be defined.  Bottom line: better disable for now.  */
+       return SPEC_MODE_INVALID;
+     default:     return SPEC_MODE_INVALID;
+     }
+ }
+ 
+ /* Provide information about speculation capabilities.  */
+ static void
+ ia64_set_sched_flags (spec_info_t spec_info)
+ {
+   unsigned int *flags = &(current_sched_info->flags);
+ 
+   if (*flags & SCHED_RGN
+       || *flags & SCHED_EBB
+       || *flags & SEL_SCHED)
+     {
+       int mask = 0;
+ 
+       if ((mflag_sched_br_data_spec && !reload_completed && optimize > 0)
+           || (mflag_sched_ar_data_spec && reload_completed))
+ 	{
+ 	  mask |= BEGIN_DATA;
+ 
+ 	  if (!sel_sched_p ()
+ 	      && ((mflag_sched_br_in_data_spec && !reload_completed)
+ 		  || (mflag_sched_ar_in_data_spec && reload_completed)))
+ 	    mask |= BE_IN_DATA;
+ 	}
+       
+       if (mflag_sched_control_spec
+           && (!sel_sched_p ()
+ 	      || reload_completed))
+ 	{
+ 	  mask |= BEGIN_CONTROL;
+ 	  
+ 	  if (!sel_sched_p () && mflag_sched_in_control_spec)
+ 	    mask |= BE_IN_CONTROL;
+ 	}
+ 
+       spec_info->mask = mask;
+ 
+       if (mask)
+ 	{
+ 	  *flags |= USE_DEPS_LIST | DO_SPECULATION;
+ 
+ 	  if (mask & BE_IN_SPEC)
+ 	    *flags |= NEW_BBS;
+ 	  
+ 	  spec_info->flags = 0;
+       
+ 	  if ((mask & CONTROL_SPEC)
+ 	      && sel_sched_p () && mflag_sel_sched_dont_check_control_spec)
+ 	    spec_info->flags |= SEL_SCHED_SPEC_DONT_CHECK_CONTROL;
+ 
+ 	  if (sched_verbose >= 1)
+ 	    spec_info->dump = sched_dump;
+ 	  else
+ 	    spec_info->dump = 0;
+ 	  
+ 	  if (mflag_sched_count_spec_in_critical_path)
+ 	    spec_info->flags |= COUNT_SPEC_IN_CRITICAL_PATH;
+ 	}
+     }
+   else
+     spec_info->mask = 0;
+ }
+ 
+ /* If INSN is an appropriate load return its mode.
+    Return -1 otherwise.  */
+ static int
+ get_mode_no_for_insn (rtx_insn *insn)
+ {
+   rtx reg, mem, mode_rtx;
+   int mode_no;
+   bool extend_p;
+ 
+   extract_insn_cached (insn);
+ 
+   /* We use WHICH_ALTERNATIVE only after reload.  This will
+      guarantee that reload won't touch a speculative insn.  */
+ 
+   if (recog_data.n_operands != 2)
+     return -1;
+ 
+   reg = recog_data.operand[0];
+   mem = recog_data.operand[1];
+ 
+   /* We should use MEM's mode since REG's mode in presence of
+      ZERO_EXTEND will always be DImode.  */
+   if (get_attr_speculable1 (insn) == SPECULABLE1_YES)
+     /* Process non-speculative ld.  */
+     {
+       if (!reload_completed)
+ 	{
+ 	  /* Do not speculate into regs like ar.lc.  */
+ 	  if (!REG_P (reg) || AR_REGNO_P (REGNO (reg)))
+ 	    return -1;
+ 
+ 	  if (!MEM_P (mem))
+ 	    return -1;
+ 
+ 	  {
+ 	    rtx mem_reg = XEXP (mem, 0);
+ 
+ 	    if (!REG_P (mem_reg))
+ 	      return -1;
+ 	  }
+ 
+ 	  mode_rtx = mem;
+ 	}
+       else if (get_attr_speculable2 (insn) == SPECULABLE2_YES)
+ 	{
+ 	  gcc_assert (REG_P (reg) && MEM_P (mem));
+ 	  mode_rtx = mem;
+ 	}
+       else
+ 	return -1;
+     }
+   else if (get_attr_data_speculative (insn) == DATA_SPECULATIVE_YES
+ 	   || get_attr_control_speculative (insn) == CONTROL_SPECULATIVE_YES
+ 	   || get_attr_check_load (insn) == CHECK_LOAD_YES)
+     /* Process speculative ld or ld.c.  */
+     {
+       gcc_assert (REG_P (reg) && MEM_P (mem));
+       mode_rtx = mem;
+     }
+   else
+     {
+       enum attr_itanium_class attr_class = get_attr_itanium_class (insn);
+ 
+       if (attr_class == ITANIUM_CLASS_CHK_A
+ 	  || attr_class == ITANIUM_CLASS_CHK_S_I
+ 	  || attr_class == ITANIUM_CLASS_CHK_S_F)
+ 	/* Process chk.  */
+ 	mode_rtx = reg;
+       else
+ 	return -1;
+     }
+ 
+   mode_no = ia64_mode_to_int (GET_MODE (mode_rtx));
+ 
+   if (mode_no == SPEC_MODE_INVALID)
+     return -1;
+ 
+   extend_p = (GET_MODE (reg) != GET_MODE (mode_rtx));
+ 
+   if (extend_p)
+     {
+       if (!(SPEC_MODE_FOR_EXTEND_FIRST <= mode_no
+ 	    && mode_no <= SPEC_MODE_FOR_EXTEND_LAST))
+ 	return -1;
+ 
+       mode_no += SPEC_GEN_EXTEND_OFFSET;
+     }
+ 
+   return mode_no;
+ }
+ 
+ /* If X is an unspec part of a speculative load, return its code.
+    Return -1 otherwise.  */
+ static int
+ get_spec_unspec_code (const_rtx x)
+ {
+   if (GET_CODE (x) != UNSPEC)
+     return -1;
+ 
+   {
+     int code;
+ 
+     code = XINT (x, 1);
+ 
+     switch (code)
+       {
+       case UNSPEC_LDA:
+       case UNSPEC_LDS:
+       case UNSPEC_LDS_A:
+       case UNSPEC_LDSA:
+ 	return code;
+ 
+       default:
+ 	return -1;
+       }
+   }
+ }
+ 
+ /* Implement skip_rtx_p hook.  */
+ static bool
+ ia64_skip_rtx_p (const_rtx x)
+ {
+   return get_spec_unspec_code (x) != -1;
+ }
+ 
+ /* If INSN is a speculative load, return its UNSPEC code.
+    Return -1 otherwise.  */
+ static int
+ get_insn_spec_code (const_rtx insn)
+ {
+   rtx pat, reg, mem;
+ 
+   pat = PATTERN (insn);
+ 
+   if (GET_CODE (pat) == COND_EXEC)
+     pat = COND_EXEC_CODE (pat);
+ 
+   if (GET_CODE (pat) != SET)
+     return -1;
+ 
+   reg = SET_DEST (pat);
+   if (!REG_P (reg))
+     return -1;
+ 
+   mem = SET_SRC (pat);
+   if (GET_CODE (mem) == ZERO_EXTEND)
+     mem = XEXP (mem, 0);
+ 
+   return get_spec_unspec_code (mem);
+ }
+ 
+ /* If INSN is a speculative load, return a ds with the speculation types.
+    Otherwise [if INSN is a normal instruction] return 0.  */
+ static ds_t
+ ia64_get_insn_spec_ds (rtx_insn *insn)
+ {
+   int code = get_insn_spec_code (insn);
+ 
+   switch (code)
+     {
+     case UNSPEC_LDA:
+       return BEGIN_DATA;
+ 
+     case UNSPEC_LDS:
+     case UNSPEC_LDS_A:
+       return BEGIN_CONTROL;
+ 
+     case UNSPEC_LDSA:
+       return BEGIN_DATA | BEGIN_CONTROL;
+ 
+     default:
+       return 0;
+     }
+ }
+ 
+ /* If INSN is a speculative load return a ds with the speculation types that
+    will be checked.
+    Otherwise [if INSN is a normal instruction] return 0.  */
+ static ds_t
+ ia64_get_insn_checked_ds (rtx_insn *insn)
+ {
+   int code = get_insn_spec_code (insn);
+ 
+   switch (code)
+     {
+     case UNSPEC_LDA:
+       return BEGIN_DATA | BEGIN_CONTROL;
+ 
+     case UNSPEC_LDS:
+       return BEGIN_CONTROL;
+ 
+     case UNSPEC_LDS_A:
+     case UNSPEC_LDSA:
+       return BEGIN_DATA | BEGIN_CONTROL;
+ 
+     default:
+       return 0;
+     }
+ }
+ 
+ /* If GEN_P is true, calculate the index of needed speculation check and return
+    speculative pattern for INSN with speculative mode TS, machine mode
+    MODE_NO and with ZERO_EXTEND (if EXTEND_P is true).
+    If GEN_P is false, just calculate the index of needed speculation check.  */
+ static rtx
+ ia64_gen_spec_load (rtx insn, ds_t ts, int mode_no)
+ {
+   rtx pat, new_pat;
+   gen_func_t gen_load;
+ 
+   gen_load = get_spec_load_gen_function (ts, mode_no);
+ 
+   new_pat = gen_load (copy_rtx (recog_data.operand[0]),
+ 		      copy_rtx (recog_data.operand[1]));
+ 
+   pat = PATTERN (insn);
+   if (GET_CODE (pat) == COND_EXEC)
+     new_pat = gen_rtx_COND_EXEC (VOIDmode, copy_rtx (COND_EXEC_TEST (pat)),
+ 				 new_pat);
+ 
+   return new_pat;
+ }
+ 
+ static bool
+ insn_can_be_in_speculative_p (rtx insn ATTRIBUTE_UNUSED,
+ 			      ds_t ds ATTRIBUTE_UNUSED)
+ {
+   return false;
+ }
+ 
+ /* Implement targetm.sched.speculate_insn hook.
+    Check if the INSN can be TS speculative.
+    If 'no' - return -1.
+    If 'yes' - generate speculative pattern in the NEW_PAT and return 1.
+    If current pattern of the INSN already provides TS speculation,
+    return 0.  */
+ static int
+ ia64_speculate_insn (rtx_insn *insn, ds_t ts, rtx *new_pat)
+ {  
+   int mode_no;
+   int res;
+   
+   gcc_assert (!(ts & ~SPECULATIVE));
+ 
+   if (ia64_spec_check_p (insn))
+     return -1;
+ 
+   if ((ts & BE_IN_SPEC)
+       && !insn_can_be_in_speculative_p (insn, ts))
+     return -1;
+ 
+   mode_no = get_mode_no_for_insn (insn);
+ 
+   if (mode_no != SPEC_MODE_INVALID)
+     {
+       if (ia64_get_insn_spec_ds (insn) == ds_get_speculation_types (ts))
+ 	res = 0;
+       else
+ 	{
+ 	  res = 1;
+ 	  *new_pat = ia64_gen_spec_load (insn, ts, mode_no);
+ 	}
+     }
+   else
+     res = -1;
+ 
+   return res;
+ }
+ 
+ /* Return a function that will generate a check for speculation TS with mode
+    MODE_NO.
+    If simple check is needed, pass true for SIMPLE_CHECK_P.
+    If clearing check is needed, pass true for CLEARING_CHECK_P.  */
+ static gen_func_t
+ get_spec_check_gen_function (ds_t ts, int mode_no,
+ 			     bool simple_check_p, bool clearing_check_p)
+ {
+   static gen_func_t gen_ld_c_clr[] = {
+     gen_movbi_clr,
+     gen_movqi_clr,
+     gen_movhi_clr,
+     gen_movsi_clr,
+     gen_movdi_clr,
+     gen_movsf_clr,
+     gen_movdf_clr,
+     gen_movxf_clr,
+     gen_movti_clr,
+     gen_zero_extendqidi2_clr,
+     gen_zero_extendhidi2_clr,
+     gen_zero_extendsidi2_clr,
+   };
+   static gen_func_t gen_ld_c_nc[] = {
+     gen_movbi_nc,
+     gen_movqi_nc,
+     gen_movhi_nc,
+     gen_movsi_nc,
+     gen_movdi_nc,
+     gen_movsf_nc,
+     gen_movdf_nc,
+     gen_movxf_nc,
+     gen_movti_nc,
+     gen_zero_extendqidi2_nc,
+     gen_zero_extendhidi2_nc,
+     gen_zero_extendsidi2_nc,
+   };
+   static gen_func_t gen_chk_a_clr[] = {
+     gen_advanced_load_check_clr_bi,
+     gen_advanced_load_check_clr_qi,
+     gen_advanced_load_check_clr_hi,
+     gen_advanced_load_check_clr_si,
+     gen_advanced_load_check_clr_di,
+     gen_advanced_load_check_clr_sf,
+     gen_advanced_load_check_clr_df,
+     gen_advanced_load_check_clr_xf,
+     gen_advanced_load_check_clr_ti,
+     gen_advanced_load_check_clr_di,
+     gen_advanced_load_check_clr_di,
+     gen_advanced_load_check_clr_di,
+   };
+   static gen_func_t gen_chk_a_nc[] = {
+     gen_advanced_load_check_nc_bi,
+     gen_advanced_load_check_nc_qi,
+     gen_advanced_load_check_nc_hi,
+     gen_advanced_load_check_nc_si,
+     gen_advanced_load_check_nc_di,
+     gen_advanced_load_check_nc_sf,
+     gen_advanced_load_check_nc_df,
+     gen_advanced_load_check_nc_xf,
+     gen_advanced_load_check_nc_ti,
+     gen_advanced_load_check_nc_di,
+     gen_advanced_load_check_nc_di,
+     gen_advanced_load_check_nc_di,
+   };
+   static gen_func_t gen_chk_s[] = {
+     gen_speculation_check_bi,
+     gen_speculation_check_qi,
+     gen_speculation_check_hi,
+     gen_speculation_check_si,
+     gen_speculation_check_di,
+     gen_speculation_check_sf,
+     gen_speculation_check_df,
+     gen_speculation_check_xf,
+     gen_speculation_check_ti,
+     gen_speculation_check_di,
+     gen_speculation_check_di,
+     gen_speculation_check_di,
+   };
+ 
+   gen_func_t *gen_check;
+ 
+   if (ts & BEGIN_DATA)
+     {
+       /* We don't need recovery because even if this is ld.sa
+ 	 ALAT entry will be allocated only if NAT bit is set to zero.
+ 	 So it is enough to use ld.c here.  */
+ 
+       if (simple_check_p)
+ 	{
+ 	  gcc_assert (mflag_sched_spec_ldc);
+ 
+ 	  if (clearing_check_p)
+ 	    gen_check = gen_ld_c_clr;
+ 	  else
+ 	    gen_check = gen_ld_c_nc;
+ 	}
+       else
+ 	{
+ 	  if (clearing_check_p)
+ 	    gen_check = gen_chk_a_clr;
+ 	  else
+ 	    gen_check = gen_chk_a_nc;
+ 	}
+     }
+   else if (ts & BEGIN_CONTROL)
+     {
+       if (simple_check_p)
+ 	/* We might want to use ld.sa -> ld.c instead of
+ 	   ld.s -> chk.s.  */
+ 	{
+ 	  gcc_assert (!ia64_needs_block_p (ts));
+ 
+ 	  if (clearing_check_p)
+ 	    gen_check = gen_ld_c_clr;
+ 	  else
+ 	    gen_check = gen_ld_c_nc;
+ 	}
+       else
+ 	{
+ 	  gen_check = gen_chk_s;
+ 	}
+     }
+   else
+     gcc_unreachable ();
+ 
+   gcc_assert (mode_no >= 0);
+   return gen_check[mode_no];
+ }
+ 
+ /* Return nonzero, if INSN needs branchy recovery check.  */
+ static bool
+ ia64_needs_block_p (ds_t ts)
+ {
+   if (ts & BEGIN_DATA)
+     return !mflag_sched_spec_ldc;
+ 
+   gcc_assert ((ts & BEGIN_CONTROL) != 0);
+ 
+   return !(mflag_sched_spec_control_ldc && mflag_sched_spec_ldc);
+ }
+ 
+ /* Generate (or regenerate) a recovery check for INSN.  */
+ static rtx
+ ia64_gen_spec_check (rtx_insn *insn, rtx_insn *label, ds_t ds)
+ {
+   rtx op1, pat, check_pat;
+   gen_func_t gen_check;
+   int mode_no;
+ 
+   mode_no = get_mode_no_for_insn (insn);
+   gcc_assert (mode_no >= 0);
+ 
+   if (label)
+     op1 = label;
+   else
+     {
+       gcc_assert (!ia64_needs_block_p (ds));
+       op1 = copy_rtx (recog_data.operand[1]);
+     }
+       
+   gen_check = get_spec_check_gen_function (ds, mode_no, label == NULL_RTX,
+ 					   true);
+ 
+   check_pat = gen_check (copy_rtx (recog_data.operand[0]), op1);
+     
+   pat = PATTERN (insn);
+   if (GET_CODE (pat) == COND_EXEC)
+     check_pat = gen_rtx_COND_EXEC (VOIDmode, copy_rtx (COND_EXEC_TEST (pat)),
+ 				   check_pat);
+ 
+   return check_pat;
+ }
+ 
+ /* Return nonzero, if X is branchy recovery check.  */
+ static int
+ ia64_spec_check_p (rtx x)
+ {
+   x = PATTERN (x);
+   if (GET_CODE (x) == COND_EXEC)
+     x = COND_EXEC_CODE (x);
+   if (GET_CODE (x) == SET)
+     return ia64_spec_check_src_p (SET_SRC (x));
+   return 0;
+ }
+ 
+ /* Return nonzero, if SRC belongs to recovery check.  */
+ static int
+ ia64_spec_check_src_p (rtx src)
+ {
+   if (GET_CODE (src) == IF_THEN_ELSE)
+     {
+       rtx t;
+ 
+       t = XEXP (src, 0);
+       if (GET_CODE (t) == NE)
+ 	{
+ 	  t = XEXP (t, 0);	    
+ 
+ 	  if (GET_CODE (t) == UNSPEC)
+ 	    {
+ 	      int code;
+ 	      
+ 	      code = XINT (t, 1);
+ 	     
+ 	      if (code == UNSPEC_LDCCLR
+ 		  || code == UNSPEC_LDCNC
+ 		  || code == UNSPEC_CHKACLR
+ 		  || code == UNSPEC_CHKANC
+ 		  || code == UNSPEC_CHKS)
+ 		{
+ 		  gcc_assert (code != 0);
+ 		  return code;
+ 		}
+ 	    }
+ 	}
+     }
+   return 0;
+ }
+ \f
+ 
+ /* The following page contains abstract data `bundle states' which are
+    used for bundling insns (inserting nops and template generation).  */
+ 
+ /* The following describes state of insn bundling.  */
+ 
+ struct bundle_state
+ {
+   /* Unique bundle state number to identify them in the debugging
+      output  */
+   int unique_num;
+   rtx_insn *insn; /* corresponding insn, NULL for the 1st and the last state  */
+   /* number nops before and after the insn  */
+   short before_nops_num, after_nops_num;
+   int insn_num; /* insn number (0 - for initial state, 1 - for the 1st
+                    insn */
+   int cost;     /* cost of the state in cycles */
+   int accumulated_insns_num; /* number of all previous insns including
+ 				nops.  L is considered as 2 insns */
+   int branch_deviation; /* deviation of previous branches from 3rd slots  */
+   int middle_bundle_stops; /* number of stop bits in the middle of bundles */
+   struct bundle_state *next;  /* next state with the same insn_num  */
+   struct bundle_state *originator; /* originator (previous insn state)  */
+   /* All bundle states are in the following chain.  */
+   struct bundle_state *allocated_states_chain;
+   /* The DFA State after issuing the insn and the nops.  */
+   state_t dfa_state;
+ };
+ 
+ /* The following is map insn number to the corresponding bundle state.  */
+ 
+ static struct bundle_state **index_to_bundle_states;
+ 
+ /* The unique number of next bundle state.  */
+ 
+ static int bundle_states_num;
+ 
+ /* All allocated bundle states are in the following chain.  */
+ 
+ static struct bundle_state *allocated_bundle_states_chain;
+ 
+ /* All allocated but not used bundle states are in the following
+    chain.  */
+ 
+ static struct bundle_state *free_bundle_state_chain;
+ 
+ 
+ /* The following function returns a free bundle state.  */
+ 
+ static struct bundle_state *
+ get_free_bundle_state (void)
+ {
+   struct bundle_state *result;
+ 
+   if (free_bundle_state_chain != NULL)
+     {
+       result = free_bundle_state_chain;
+       free_bundle_state_chain = result->next;
+     }
+   else
+     {
+       result = XNEW (struct bundle_state);
+       result->dfa_state = xmalloc (dfa_state_size);
+       result->allocated_states_chain = allocated_bundle_states_chain;
+       allocated_bundle_states_chain = result;
+     }
+   result->unique_num = bundle_states_num++;
+   return result;
+ 
+ }
+ 
+ /* The following function frees given bundle state.  */
+ 
+ static void
+ free_bundle_state (struct bundle_state *state)
+ {
+   state->next = free_bundle_state_chain;
+   free_bundle_state_chain = state;
+ }
+ 
+ /* Start work with abstract data `bundle states'.  */
+ 
+ static void
+ initiate_bundle_states (void)
+ {
+   bundle_states_num = 0;
+   free_bundle_state_chain = NULL;
+   allocated_bundle_states_chain = NULL;
+ }
+ 
+ /* Finish work with abstract data `bundle states'.  */
+ 
+ static void
+ finish_bundle_states (void)
+ {
+   struct bundle_state *curr_state, *next_state;
+ 
+   for (curr_state = allocated_bundle_states_chain;
+        curr_state != NULL;
+        curr_state = next_state)
+     {
+       next_state = curr_state->allocated_states_chain;
+       free (curr_state->dfa_state);
+       free (curr_state);
+     }
+ }
+ 
+ /* Hashtable helpers.  */
+ 
+ struct bundle_state_hasher : nofree_ptr_hash <bundle_state>
+ {
+   static inline hashval_t hash (const bundle_state *);
+   static inline bool equal (const bundle_state *, const bundle_state *);
+ };
+ 
+ /* The function returns hash of BUNDLE_STATE.  */
+ 
+ inline hashval_t
+ bundle_state_hasher::hash (const bundle_state *state)
+ {
+   unsigned result, i;
+ 
+   for (result = i = 0; i < dfa_state_size; i++)
+     result += (((unsigned char *) state->dfa_state) [i]
+ 	       << ((i % CHAR_BIT) * 3 + CHAR_BIT));
+   return result + state->insn_num;
+ }
+ 
+ /* The function returns nonzero if the bundle state keys are equal.  */
+ 
+ inline bool
+ bundle_state_hasher::equal (const bundle_state *state1,
+ 			    const bundle_state *state2)
+ {
+   return (state1->insn_num == state2->insn_num
+ 	  && memcmp (state1->dfa_state, state2->dfa_state,
+ 		     dfa_state_size) == 0);
+ }
+ 
+ /* Hash table of the bundle states.  The key is dfa_state and insn_num
+    of the bundle states.  */
+ 
+ static hash_table<bundle_state_hasher> *bundle_state_table;
+ 
+ /* The function inserts the BUNDLE_STATE into the hash table.  The
+    function returns nonzero if the bundle has been inserted into the
+    table.  The table contains the best bundle state with given key.  */
+ 
+ static int
+ insert_bundle_state (struct bundle_state *bundle_state)
+ {
+   struct bundle_state **entry_ptr;
+ 
+   entry_ptr = bundle_state_table->find_slot (bundle_state, INSERT);
+   if (*entry_ptr == NULL)
+     {
+       bundle_state->next = index_to_bundle_states [bundle_state->insn_num];
+       index_to_bundle_states [bundle_state->insn_num] = bundle_state;
+       *entry_ptr = bundle_state;
+       return TRUE;
+     }
+   else if (bundle_state->cost < (*entry_ptr)->cost
+ 	   || (bundle_state->cost == (*entry_ptr)->cost
+ 	       && ((*entry_ptr)->accumulated_insns_num
+ 		   > bundle_state->accumulated_insns_num
+ 		   || ((*entry_ptr)->accumulated_insns_num
+ 		       == bundle_state->accumulated_insns_num
+ 		       && ((*entry_ptr)->branch_deviation
+ 			   > bundle_state->branch_deviation
+ 			   || ((*entry_ptr)->branch_deviation
+ 			       == bundle_state->branch_deviation
+ 			       && (*entry_ptr)->middle_bundle_stops
+ 			       > bundle_state->middle_bundle_stops))))))
+ 
+     {
+       struct bundle_state temp;
+ 
+       temp = **entry_ptr;
+       **entry_ptr = *bundle_state;
+       (*entry_ptr)->next = temp.next;
+       *bundle_state = temp;
+     }
+   return FALSE;
+ }
+ 
+ /* Start work with the hash table.  */
+ 
+ static void
+ initiate_bundle_state_table (void)
+ {
+   bundle_state_table = new hash_table<bundle_state_hasher> (50);
+ }
+ 
+ /* Finish work with the hash table.  */
+ 
+ static void
+ finish_bundle_state_table (void)
+ {
+   delete bundle_state_table;
+   bundle_state_table = NULL;
+ }
+ 
+ \f
+ 
+ /* The following variable is a insn `nop' used to check bundle states
+    with different number of inserted nops.  */
+ 
+ static rtx_insn *ia64_nop;
+ 
+ /* The following function tries to issue NOPS_NUM nops for the current
+    state without advancing processor cycle.  If it failed, the
+    function returns FALSE and frees the current state.  */
+ 
+ static int
+ try_issue_nops (struct bundle_state *curr_state, int nops_num)
+ {
+   int i;
+ 
+   for (i = 0; i < nops_num; i++)
+     if (state_transition (curr_state->dfa_state, ia64_nop) >= 0)
+       {
+ 	free_bundle_state (curr_state);
+ 	return FALSE;
+       }
+   return TRUE;
+ }
+ 
+ /* The following function tries to issue INSN for the current
+    state without advancing processor cycle.  If it failed, the
+    function returns FALSE and frees the current state.  */
+ 
+ static int
+ try_issue_insn (struct bundle_state *curr_state, rtx insn)
+ {
+   if (insn && state_transition (curr_state->dfa_state, insn) >= 0)
+     {
+       free_bundle_state (curr_state);
+       return FALSE;
+     }
+   return TRUE;
+ }
+ 
+ /* The following function tries to issue BEFORE_NOPS_NUM nops and INSN
+    starting with ORIGINATOR without advancing processor cycle.  If
+    TRY_BUNDLE_END_P is TRUE, the function also/only (if
+    ONLY_BUNDLE_END_P is TRUE) tries to issue nops to fill all bundle.
+    If it was successful, the function creates new bundle state and
+    insert into the hash table and into `index_to_bundle_states'.  */
+ 
+ static void
+ issue_nops_and_insn (struct bundle_state *originator, int before_nops_num,
+ 		     rtx_insn *insn, int try_bundle_end_p,
+ 		     int only_bundle_end_p)
+ {
+   struct bundle_state *curr_state;
+ 
+   curr_state = get_free_bundle_state ();
+   memcpy (curr_state->dfa_state, originator->dfa_state, dfa_state_size);
+   curr_state->insn = insn;
+   curr_state->insn_num = originator->insn_num + 1;
+   curr_state->cost = originator->cost;
+   curr_state->originator = originator;
+   curr_state->before_nops_num = before_nops_num;
+   curr_state->after_nops_num = 0;
+   curr_state->accumulated_insns_num
+     = originator->accumulated_insns_num + before_nops_num;
+   curr_state->branch_deviation = originator->branch_deviation;
+   curr_state->middle_bundle_stops = originator->middle_bundle_stops;
+   gcc_assert (insn);
+   if (INSN_CODE (insn) == CODE_FOR_insn_group_barrier)
+     {
+       gcc_assert (GET_MODE (insn) != TImode);
+       if (!try_issue_nops (curr_state, before_nops_num))
+ 	return;
+       if (!try_issue_insn (curr_state, insn))
+ 	return;
+       memcpy (temp_dfa_state, curr_state->dfa_state, dfa_state_size);
+       if (curr_state->accumulated_insns_num % 3 != 0)
+ 	curr_state->middle_bundle_stops++;
+       if (state_transition (temp_dfa_state, dfa_pre_cycle_insn) >= 0
+ 	  && curr_state->accumulated_insns_num % 3 != 0)
+ 	{
+ 	  free_bundle_state (curr_state);
+ 	  return;
+ 	}
+     }
+   else if (GET_MODE (insn) != TImode)
+     {
+       if (!try_issue_nops (curr_state, before_nops_num))
+ 	return;
+       if (!try_issue_insn (curr_state, insn))
+ 	return;
+       curr_state->accumulated_insns_num++;
+       gcc_assert (!unknown_for_bundling_p (insn));
+ 
+       if (ia64_safe_type (insn) == TYPE_L)
+ 	curr_state->accumulated_insns_num++;
+     }
+   else
+     {
+       /* If this is an insn that must be first in a group, then don't allow
+ 	 nops to be emitted before it.  Currently, alloc is the only such
+ 	 supported instruction.  */
+       /* ??? The bundling automatons should handle this for us, but they do
+ 	 not yet have support for the first_insn attribute.  */
+       if (before_nops_num > 0 && get_attr_first_insn (insn) == FIRST_INSN_YES)
+ 	{
+ 	  free_bundle_state (curr_state);
+ 	  return;
+ 	}
+ 
+       state_transition (curr_state->dfa_state, dfa_pre_cycle_insn);
+       state_transition (curr_state->dfa_state, NULL);
+       curr_state->cost++;
+       if (!try_issue_nops (curr_state, before_nops_num))
+ 	return;
+       if (!try_issue_insn (curr_state, insn))
+ 	return;
+       curr_state->accumulated_insns_num++;
+       if (unknown_for_bundling_p (insn))
+ 	{
+ 	  /* Finish bundle containing asm insn.  */
+ 	  curr_state->after_nops_num
+ 	    = 3 - curr_state->accumulated_insns_num % 3;
+ 	  curr_state->accumulated_insns_num
+ 	    += 3 - curr_state->accumulated_insns_num % 3;
+ 	}
+       else if (ia64_safe_type (insn) == TYPE_L)
+ 	curr_state->accumulated_insns_num++;
+     }
+   if (ia64_safe_type (insn) == TYPE_B)
+     curr_state->branch_deviation
+       += 2 - (curr_state->accumulated_insns_num - 1) % 3;
+   if (try_bundle_end_p && curr_state->accumulated_insns_num % 3 != 0)
+     {
+       if (!only_bundle_end_p && insert_bundle_state (curr_state))
+ 	{
+ 	  state_t dfa_state;
+ 	  struct bundle_state *curr_state1;
+ 	  struct bundle_state *allocated_states_chain;
+ 
+ 	  curr_state1 = get_free_bundle_state ();
+ 	  dfa_state = curr_state1->dfa_state;
+ 	  allocated_states_chain = curr_state1->allocated_states_chain;
+ 	  *curr_state1 = *curr_state;
+ 	  curr_state1->dfa_state = dfa_state;
+ 	  curr_state1->allocated_states_chain = allocated_states_chain;
+ 	  memcpy (curr_state1->dfa_state, curr_state->dfa_state,
+ 		  dfa_state_size);
+ 	  curr_state = curr_state1;
+ 	}
+       if (!try_issue_nops (curr_state,
+ 			   3 - curr_state->accumulated_insns_num % 3))
+ 	return;
+       curr_state->after_nops_num
+ 	= 3 - curr_state->accumulated_insns_num % 3;
+       curr_state->accumulated_insns_num
+ 	+= 3 - curr_state->accumulated_insns_num % 3;
+     }
+   if (!insert_bundle_state (curr_state))
+     free_bundle_state (curr_state);
+   return;
+ }
+ 
+ /* The following function returns position in the two window bundle
+    for given STATE.  */
+ 
+ static int
+ get_max_pos (state_t state)
+ {
+   if (cpu_unit_reservation_p (state, pos_6))
+     return 6;
+   else if (cpu_unit_reservation_p (state, pos_5))
+     return 5;
+   else if (cpu_unit_reservation_p (state, pos_4))
+     return 4;
+   else if (cpu_unit_reservation_p (state, pos_3))
+     return 3;
+   else if (cpu_unit_reservation_p (state, pos_2))
+     return 2;
+   else if (cpu_unit_reservation_p (state, pos_1))
+     return 1;
+   else
+     return 0;
+ }
+ 
+ /* The function returns code of a possible template for given position
+    and state.  The function should be called only with 2 values of
+    position equal to 3 or 6.  We avoid generating F NOPs by putting
+    templates containing F insns at the end of the template search
+    because undocumented anomaly in McKinley derived cores which can
+    cause stalls if an F-unit insn (including a NOP) is issued within a
+    six-cycle window after reading certain application registers (such
+    as ar.bsp).  Furthermore, power-considerations also argue against
+    the use of F-unit instructions unless they're really needed.  */
+ 
+ static int
+ get_template (state_t state, int pos)
+ {
+   switch (pos)
+     {
+     case 3:
+       if (cpu_unit_reservation_p (state, _0mmi_))
+ 	return 1;
+       else if (cpu_unit_reservation_p (state, _0mii_))
+ 	return 0;
+       else if (cpu_unit_reservation_p (state, _0mmb_))
+ 	return 7;
+       else if (cpu_unit_reservation_p (state, _0mib_))
+ 	return 6;
+       else if (cpu_unit_reservation_p (state, _0mbb_))
+ 	return 5;
+       else if (cpu_unit_reservation_p (state, _0bbb_))
+ 	return 4;
+       else if (cpu_unit_reservation_p (state, _0mmf_))
+ 	return 3;
+       else if (cpu_unit_reservation_p (state, _0mfi_))
+ 	return 2;
+       else if (cpu_unit_reservation_p (state, _0mfb_))
+ 	return 8;
+       else if (cpu_unit_reservation_p (state, _0mlx_))
+ 	return 9;
+       else
+ 	gcc_unreachable ();
+     case 6:
+       if (cpu_unit_reservation_p (state, _1mmi_))
+ 	return 1;
+       else if (cpu_unit_reservation_p (state, _1mii_))
+ 	return 0;
+       else if (cpu_unit_reservation_p (state, _1mmb_))
+ 	return 7;
+       else if (cpu_unit_reservation_p (state, _1mib_))
+ 	return 6;
+       else if (cpu_unit_reservation_p (state, _1mbb_))
+ 	return 5;
+       else if (cpu_unit_reservation_p (state, _1bbb_))
+ 	return 4;
+       else if (_1mmf_ >= 0 && cpu_unit_reservation_p (state, _1mmf_))
+ 	return 3;
+       else if (cpu_unit_reservation_p (state, _1mfi_))
+ 	return 2;
+       else if (cpu_unit_reservation_p (state, _1mfb_))
+ 	return 8;
+       else if (cpu_unit_reservation_p (state, _1mlx_))
+ 	return 9;
+       else
+ 	gcc_unreachable ();
+     default:
+       gcc_unreachable ();
+     }
+ }
+ 
+ /* True when INSN is important for bundling.  */
+ 
+ static bool
+ important_for_bundling_p (rtx_insn *insn)
+ {
+   return (INSN_P (insn)
+ 	  && ia64_safe_itanium_class (insn) != ITANIUM_CLASS_IGNORE
+ 	  && GET_CODE (PATTERN (insn)) != USE
+ 	  && GET_CODE (PATTERN (insn)) != CLOBBER);
+ }
+ 
+ /* The following function returns an insn important for insn bundling
+    followed by INSN and before TAIL.  */
+ 
+ static rtx_insn *
+ get_next_important_insn (rtx_insn *insn, rtx_insn *tail)
+ {
+   for (; insn && insn != tail; insn = NEXT_INSN (insn))
+     if (important_for_bundling_p (insn))
+       return insn;
+   return NULL;
+ }
+ 
+ /* True when INSN is unknown, but important, for bundling.  */
+ 
+ static bool
+ unknown_for_bundling_p (rtx_insn *insn)
+ {
+   return (INSN_P (insn)
+ 	  && ia64_safe_itanium_class (insn) == ITANIUM_CLASS_UNKNOWN
+ 	  && GET_CODE (PATTERN (insn)) != USE
+ 	  && GET_CODE (PATTERN (insn)) != CLOBBER);
+ }
+ 
+ /* Add a bundle selector TEMPLATE0 before INSN.  */
+ 
+ static void
+ ia64_add_bundle_selector_before (int template0, rtx_insn *insn)
+ {
+   rtx b = gen_bundle_selector (GEN_INT (template0));
+ 
+   ia64_emit_insn_before (b, insn);
+ #if NR_BUNDLES == 10
+   if ((template0 == 4 || template0 == 5)
+       && ia64_except_unwind_info (&global_options) == UI_TARGET)
+     {
+       int i;
+       rtx note = NULL_RTX;
+ 
+       /* In .mbb and .bbb bundles, check if CALL_INSN isn't in the
+ 	 first or second slot.  If it is and has REG_EH_NOTE set, copy it
+ 	 to following nops, as br.call sets rp to the address of following
+ 	 bundle and therefore an EH region end must be on a bundle
+ 	 boundary.  */
+       insn = PREV_INSN (insn);
+       for (i = 0; i < 3; i++)
+ 	{
+ 	  do
+ 	    insn = next_active_insn (insn);
+ 	  while (NONJUMP_INSN_P (insn)
+ 		 && get_attr_empty (insn) == EMPTY_YES);
+ 	  if (CALL_P (insn))
+ 	    note = find_reg_note (insn, REG_EH_REGION, NULL_RTX);
+ 	  else if (note)
+ 	    {
+ 	      int code;
+ 
+ 	      gcc_assert ((code = recog_memoized (insn)) == CODE_FOR_nop
+ 			  || code == CODE_FOR_nop_b);
+ 	      if (find_reg_note (insn, REG_EH_REGION, NULL_RTX))
+ 		note = NULL_RTX;
+ 	      else
+ 		add_reg_note (insn, REG_EH_REGION, XEXP (note, 0));
+ 	    }
+ 	}
+     }
+ #endif
+ }
+ 
+ /* The following function does insn bundling.  Bundling means
+    inserting templates and nop insns to fit insn groups into permitted
+    templates.  Instruction scheduling uses NDFA (non-deterministic
+    finite automata) encoding informations about the templates and the
+    inserted nops.  Nondeterminism of the automata permits follows
+    all possible insn sequences very fast.
+ 
+    Unfortunately it is not possible to get information about inserting
+    nop insns and used templates from the automata states.  The
+    automata only says that we can issue an insn possibly inserting
+    some nops before it and using some template.  Therefore insn
+    bundling in this function is implemented by using DFA
+    (deterministic finite automata).  We follow all possible insn
+    sequences by inserting 0-2 nops (that is what the NDFA describe for
+    insn scheduling) before/after each insn being bundled.  We know the
+    start of simulated processor cycle from insn scheduling (insn
+    starting a new cycle has TImode).
+ 
+    Simple implementation of insn bundling would create enormous
+    number of possible insn sequences satisfying information about new
+    cycle ticks taken from the insn scheduling.  To make the algorithm
+    practical we use dynamic programming.  Each decision (about
+    inserting nops and implicitly about previous decisions) is described
+    by structure bundle_state (see above).  If we generate the same
+    bundle state (key is automaton state after issuing the insns and
+    nops for it), we reuse already generated one.  As consequence we
+    reject some decisions which cannot improve the solution and
+    reduce memory for the algorithm.
+ 
+    When we reach the end of EBB (extended basic block), we choose the
+    best sequence and then, moving back in EBB, insert templates for
+    the best alternative.  The templates are taken from querying
+    automaton state for each insn in chosen bundle states.
+ 
+    So the algorithm makes two (forward and backward) passes through
+    EBB.  */
+ 
+ static void
+ bundling (FILE *dump, int verbose, rtx_insn *prev_head_insn, rtx_insn *tail)
+ {
+   struct bundle_state *curr_state, *next_state, *best_state;
+   rtx_insn *insn, *next_insn;
+   int insn_num;
+   int i, bundle_end_p, only_bundle_end_p, asm_p;
+   int pos = 0, max_pos, template0, template1;
+   rtx_insn *b;
+   enum attr_type type;
+ 
+   insn_num = 0;
+   /* Count insns in the EBB.  */
+   for (insn = NEXT_INSN (prev_head_insn);
+        insn && insn != tail;
+        insn = NEXT_INSN (insn))
+     if (INSN_P (insn))
+       insn_num++;
+   if (insn_num == 0)
+     return;
+   bundling_p = 1;
+   dfa_clean_insn_cache ();
+   initiate_bundle_state_table ();
+   index_to_bundle_states = XNEWVEC (struct bundle_state *, insn_num + 2);
+   /* First (forward) pass -- generation of bundle states.  */
+   curr_state = get_free_bundle_state ();
+   curr_state->insn = NULL;
+   curr_state->before_nops_num = 0;
+   curr_state->after_nops_num = 0;
+   curr_state->insn_num = 0;
+   curr_state->cost = 0;
+   curr_state->accumulated_insns_num = 0;
+   curr_state->branch_deviation = 0;
+   curr_state->middle_bundle_stops = 0;
+   curr_state->next = NULL;
+   curr_state->originator = NULL;
+   state_reset (curr_state->dfa_state);
+   index_to_bundle_states [0] = curr_state;
+   insn_num = 0;
+   /* Shift cycle mark if it is put on insn which could be ignored.  */
+   for (insn = NEXT_INSN (prev_head_insn);
+        insn != tail;
+        insn = NEXT_INSN (insn))
+     if (INSN_P (insn)
+ 	&& !important_for_bundling_p (insn)
+ 	&& GET_MODE (insn) == TImode)
+       {
+ 	PUT_MODE (insn, VOIDmode);
+ 	for (next_insn = NEXT_INSN (insn);
+ 	     next_insn != tail;
+ 	     next_insn = NEXT_INSN (next_insn))
+ 	  if (important_for_bundling_p (next_insn)
+ 	      && INSN_CODE (next_insn) != CODE_FOR_insn_group_barrier)
+ 	    {
+ 	      PUT_MODE (next_insn, TImode);
+ 	      break;
+ 	    }
+       }
+   /* Forward pass: generation of bundle states.  */
+   for (insn = get_next_important_insn (NEXT_INSN (prev_head_insn), tail);
+        insn != NULL_RTX;
+        insn = next_insn)
+     {
+       gcc_assert (important_for_bundling_p (insn));
+       type = ia64_safe_type (insn);
+       next_insn = get_next_important_insn (NEXT_INSN (insn), tail);
+       insn_num++;
+       index_to_bundle_states [insn_num] = NULL;
+       for (curr_state = index_to_bundle_states [insn_num - 1];
+ 	   curr_state != NULL;
+ 	   curr_state = next_state)
+ 	{
+ 	  pos = curr_state->accumulated_insns_num % 3;
+ 	  next_state = curr_state->next;
+ 	  /* We must fill up the current bundle in order to start a
+ 	     subsequent asm insn in a new bundle.  Asm insn is always
+ 	     placed in a separate bundle.  */
+ 	  only_bundle_end_p
+ 	    = (next_insn != NULL_RTX
+ 	       && INSN_CODE (insn) == CODE_FOR_insn_group_barrier
+ 	       && unknown_for_bundling_p (next_insn));
+ 	  /* We may fill up the current bundle if it is the cycle end
+ 	     without a group barrier.  */
+ 	  bundle_end_p
+ 	    = (only_bundle_end_p || next_insn == NULL_RTX
+ 	       || (GET_MODE (next_insn) == TImode
+ 		   && INSN_CODE (insn) != CODE_FOR_insn_group_barrier));
+ 	  if (type == TYPE_F || type == TYPE_B || type == TYPE_L
+ 	      || type == TYPE_S)
+ 	    issue_nops_and_insn (curr_state, 2, insn, bundle_end_p,
+ 				 only_bundle_end_p);
+ 	  issue_nops_and_insn (curr_state, 1, insn, bundle_end_p,
+ 			       only_bundle_end_p);
+ 	  issue_nops_and_insn (curr_state, 0, insn, bundle_end_p,
+ 			       only_bundle_end_p);
+ 	}
+       gcc_assert (index_to_bundle_states [insn_num]);
+       for (curr_state = index_to_bundle_states [insn_num];
+ 	   curr_state != NULL;
+ 	   curr_state = curr_state->next)
+ 	if (verbose >= 2 && dump)
+ 	  {
+ 	    /* This structure is taken from generated code of the
+ 	       pipeline hazard recognizer (see file insn-attrtab.cc).
+ 	       Please don't forget to change the structure if a new
+ 	       automaton is added to .md file.  */
+ 	    struct DFA_chip
+ 	    {
+ 	      unsigned short one_automaton_state;
+ 	      unsigned short oneb_automaton_state;
+ 	      unsigned short two_automaton_state;
+ 	      unsigned short twob_automaton_state;
+ 	    };
+ 
+ 	    fprintf
+ 	      (dump,
+ 	       "//    Bundle state %d (orig %d, cost %d, nops %d/%d, insns %d, branch %d, mid.stops %d state %d) for %d\n",
+ 	       curr_state->unique_num,
+ 	       (curr_state->originator == NULL
+ 		? -1 : curr_state->originator->unique_num),
+ 	       curr_state->cost,
+ 	       curr_state->before_nops_num, curr_state->after_nops_num,
+ 	       curr_state->accumulated_insns_num, curr_state->branch_deviation,
+ 	       curr_state->middle_bundle_stops,
+ 	       ((struct DFA_chip *) curr_state->dfa_state)->twob_automaton_state,
+ 	       INSN_UID (insn));
+ 	  }
+     }
+   
+   /* We should find a solution because the 2nd insn scheduling has
+      found one.  */
+   gcc_assert (index_to_bundle_states [insn_num]);
+   /* Find a state corresponding to the best insn sequence.  */
+   best_state = NULL;
+   for (curr_state = index_to_bundle_states [insn_num];
+        curr_state != NULL;
+        curr_state = curr_state->next)
+     /* We are just looking at the states with fully filled up last
+        bundle.  The first we prefer insn sequences with minimal cost
+        then with minimal inserted nops and finally with branch insns
+        placed in the 3rd slots.  */
+     if (curr_state->accumulated_insns_num % 3 == 0
+ 	&& (best_state == NULL || best_state->cost > curr_state->cost
+ 	    || (best_state->cost == curr_state->cost
+ 		&& (curr_state->accumulated_insns_num
+ 		    < best_state->accumulated_insns_num
+ 		    || (curr_state->accumulated_insns_num
+ 			== best_state->accumulated_insns_num
+ 			&& (curr_state->branch_deviation
+ 			    < best_state->branch_deviation
+ 			    || (curr_state->branch_deviation
+ 				== best_state->branch_deviation
+ 				&& curr_state->middle_bundle_stops
+ 				< best_state->middle_bundle_stops)))))))
+       best_state = curr_state;
+   /* Second (backward) pass: adding nops and templates.  */
+   gcc_assert (best_state);
+   insn_num = best_state->before_nops_num;
+   template0 = template1 = -1;
+   for (curr_state = best_state;
+        curr_state->originator != NULL;
+        curr_state = curr_state->originator)
+     {
+       insn = curr_state->insn;
+       asm_p = unknown_for_bundling_p (insn);
+       insn_num++;
+       if (verbose >= 2 && dump)
+ 	{
+ 	  struct DFA_chip
+ 	  {
+ 	    unsigned short one_automaton_state;
+ 	    unsigned short oneb_automaton_state;
+ 	    unsigned short two_automaton_state;
+ 	    unsigned short twob_automaton_state;
+ 	  };
+ 
+ 	  fprintf
+ 	    (dump,
+ 	     "//    Best %d (orig %d, cost %d, nops %d/%d, insns %d, branch %d, mid.stops %d, state %d) for %d\n",
+ 	     curr_state->unique_num,
+ 	     (curr_state->originator == NULL
+ 	      ? -1 : curr_state->originator->unique_num),
+ 	     curr_state->cost,
+ 	     curr_state->before_nops_num, curr_state->after_nops_num,
+ 	     curr_state->accumulated_insns_num, curr_state->branch_deviation,
+ 	     curr_state->middle_bundle_stops,
+ 	     ((struct DFA_chip *) curr_state->dfa_state)->twob_automaton_state,
+ 	     INSN_UID (insn));
+ 	}
+       /* Find the position in the current bundle window.  The window can
+ 	 contain at most two bundles.  Two bundle window means that
+ 	 the processor will make two bundle rotation.  */
+       max_pos = get_max_pos (curr_state->dfa_state);
+       if (max_pos == 6
+ 	  /* The following (negative template number) means that the
+ 	     processor did one bundle rotation.  */
+ 	  || (max_pos == 3 && template0 < 0))
+ 	{
+ 	  /* We are at the end of the window -- find template(s) for
+ 	     its bundle(s).  */
+ 	  pos = max_pos;
+ 	  if (max_pos == 3)
+ 	    template0 = get_template (curr_state->dfa_state, 3);
+ 	  else
+ 	    {
+ 	      template1 = get_template (curr_state->dfa_state, 3);
+ 	      template0 = get_template (curr_state->dfa_state, 6);
+ 	    }
+ 	}
+       if (max_pos > 3 && template1 < 0)
+ 	/* It may happen when we have the stop inside a bundle.  */
+ 	{
+ 	  gcc_assert (pos <= 3);
+ 	  template1 = get_template (curr_state->dfa_state, 3);
+ 	  pos += 3;
+ 	}
+       if (!asm_p)
+ 	/* Emit nops after the current insn.  */
+ 	for (i = 0; i < curr_state->after_nops_num; i++)
+ 	  {
+ 	    rtx nop_pat = gen_nop ();
+ 	    rtx_insn *nop = emit_insn_after (nop_pat, insn);
+ 	    pos--;
+ 	    gcc_assert (pos >= 0);
+ 	    if (pos % 3 == 0)
+ 	      {
+ 		/* We are at the start of a bundle: emit the template
+ 		   (it should be defined).  */
+ 		gcc_assert (template0 >= 0);
+ 		ia64_add_bundle_selector_before (template0, nop);
+ 		/* If we have two bundle window, we make one bundle
+ 		   rotation.  Otherwise template0 will be undefined
+ 		   (negative value).  */
+ 		template0 = template1;
+ 		template1 = -1;
+ 	      }
+ 	  }
+       /* Move the position backward in the window.  Group barrier has
+ 	 no slot.  Asm insn takes all bundle.  */
+       if (INSN_CODE (insn) != CODE_FOR_insn_group_barrier
+ 	  && !unknown_for_bundling_p (insn))
+ 	pos--;
+       /* Long insn takes 2 slots.  */
+       if (ia64_safe_type (insn) == TYPE_L)
+ 	pos--;
+       gcc_assert (pos >= 0);
+       if (pos % 3 == 0
+ 	  && INSN_CODE (insn) != CODE_FOR_insn_group_barrier
+ 	  && !unknown_for_bundling_p (insn))
+ 	{
+ 	  /* The current insn is at the bundle start: emit the
+ 	     template.  */
+ 	  gcc_assert (template0 >= 0);
+ 	  ia64_add_bundle_selector_before (template0, insn);
+ 	  b = PREV_INSN (insn);
+ 	  insn = b;
+ 	  /* See comment above in analogous place for emitting nops
+ 	     after the insn.  */
+ 	  template0 = template1;
+ 	  template1 = -1;
+ 	}
+       /* Emit nops after the current insn.  */
+       for (i = 0; i < curr_state->before_nops_num; i++)
+ 	{
+ 	  rtx nop_pat = gen_nop ();
+ 	  ia64_emit_insn_before (nop_pat, insn);
+ 	  rtx_insn *nop = PREV_INSN (insn);
+ 	  insn = nop;
+ 	  pos--;
+ 	  gcc_assert (pos >= 0);
+ 	  if (pos % 3 == 0)
+ 	    {
+ 	      /* See comment above in analogous place for emitting nops
+ 		 after the insn.  */
+ 	      gcc_assert (template0 >= 0);
+ 	      ia64_add_bundle_selector_before (template0, insn);
+ 	      b = PREV_INSN (insn);
+ 	      insn = b;
+ 	      template0 = template1;
+ 	      template1 = -1;
+ 	    }
+ 	}
+     }
+ 
+   if (flag_checking)
+     {
+       /* Assert right calculation of middle_bundle_stops.  */
+       int num = best_state->middle_bundle_stops;
+       bool start_bundle = true, end_bundle = false;
+ 
+       for (insn = NEXT_INSN (prev_head_insn);
+ 	   insn && insn != tail;
+ 	   insn = NEXT_INSN (insn))
+ 	{
+ 	  if (!INSN_P (insn))
+ 	    continue;
+ 	  if (recog_memoized (insn) == CODE_FOR_bundle_selector)
+ 	    start_bundle = true;
+ 	  else
+ 	    {
+ 	      rtx_insn *next_insn;
+ 
+ 	      for (next_insn = NEXT_INSN (insn);
+ 		   next_insn && next_insn != tail;
+ 		   next_insn = NEXT_INSN (next_insn))
+ 		if (INSN_P (next_insn)
+ 		    && (ia64_safe_itanium_class (next_insn)
+ 			!= ITANIUM_CLASS_IGNORE
+ 			|| recog_memoized (next_insn)
+ 			== CODE_FOR_bundle_selector)
+ 		    && GET_CODE (PATTERN (next_insn)) != USE
+ 		    && GET_CODE (PATTERN (next_insn)) != CLOBBER)
+ 		  break;
+ 
+ 	      end_bundle = next_insn == NULL_RTX
+ 		|| next_insn == tail
+ 		|| (INSN_P (next_insn)
+ 		    && recog_memoized (next_insn) == CODE_FOR_bundle_selector);
+ 	      if (recog_memoized (insn) == CODE_FOR_insn_group_barrier
+ 		  && !start_bundle && !end_bundle
+ 		  && next_insn
+ 		  && !unknown_for_bundling_p (next_insn))
+ 		num--;
+ 
+ 	      start_bundle = false;
+ 	    }
+ 	}
+ 
+       gcc_assert (num == 0);
+     }
+ 
+   free (index_to_bundle_states);
+   finish_bundle_state_table ();
+   bundling_p = 0;
+   dfa_clean_insn_cache ();
+ }
+ 
+ /* The following function is called at the end of scheduling BB or
+    EBB.  After reload, it inserts stop bits and does insn bundling.  */
+ 
+ static void
+ ia64_sched_finish (FILE *dump, int sched_verbose)
+ {
+   if (sched_verbose)
+     fprintf (dump, "// Finishing schedule.\n");
+   if (!reload_completed)
+     return;
+   if (reload_completed)
+     {
+       final_emit_insn_group_barriers (dump);
+       bundling (dump, sched_verbose, current_sched_info->prev_head,
+ 		current_sched_info->next_tail);
+       if (sched_verbose && dump)
+ 	fprintf (dump, "//    finishing %d-%d\n",
+ 		 INSN_UID (NEXT_INSN (current_sched_info->prev_head)),
+ 		 INSN_UID (PREV_INSN (current_sched_info->next_tail)));
+ 
+       return;
+     }
+ }
+ 
+ /* The following function inserts stop bits in scheduled BB or EBB.  */
+ 
+ static void
+ final_emit_insn_group_barriers (FILE *dump ATTRIBUTE_UNUSED)
+ {
+   rtx_insn *insn;
+   int need_barrier_p = 0;
+   int seen_good_insn = 0;
+ 
+   init_insn_group_barriers ();
+ 
+   for (insn = NEXT_INSN (current_sched_info->prev_head);
+        insn != current_sched_info->next_tail;
+        insn = NEXT_INSN (insn))
+     {
+       if (BARRIER_P (insn))
+ 	{
+ 	  rtx_insn *last = prev_active_insn (insn);
+ 
+ 	  if (! last)
+ 	    continue;
+ 	  if (JUMP_TABLE_DATA_P (last))
+ 	    last = prev_active_insn (last);
+ 	  if (recog_memoized (last) != CODE_FOR_insn_group_barrier)
+ 	    emit_insn_after (gen_insn_group_barrier (GEN_INT (3)), last);
+ 
+ 	  init_insn_group_barriers ();
+ 	  seen_good_insn = 0;
+ 	  need_barrier_p = 0;
+ 	}
+       else if (NONDEBUG_INSN_P (insn))
+ 	{
+ 	  if (recog_memoized (insn) == CODE_FOR_insn_group_barrier)
+ 	    {
+ 	      init_insn_group_barriers ();
+ 	      seen_good_insn = 0;
+ 	      need_barrier_p = 0;
+ 	    }
+ 	  else if (need_barrier_p || group_barrier_needed (insn)
+ 		   || (mflag_sched_stop_bits_after_every_cycle
+ 		       && GET_MODE (insn) == TImode
+ 		       && seen_good_insn))
+ 	    {
+ 	      if (TARGET_EARLY_STOP_BITS)
+ 		{
+ 		  rtx_insn *last;
+ 
+ 		  for (last = insn;
+ 		       last != current_sched_info->prev_head;
+ 		       last = PREV_INSN (last))
+ 		    if (INSN_P (last) && GET_MODE (last) == TImode
+ 			&& stops_p [INSN_UID (last)])
+ 		      break;
+ 		  if (last == current_sched_info->prev_head)
+ 		    last = insn;
+ 		  last = prev_active_insn (last);
+ 		  if (last
+ 		      && recog_memoized (last) != CODE_FOR_insn_group_barrier)
+ 		    emit_insn_after (gen_insn_group_barrier (GEN_INT (3)),
+ 				     last);
+ 		  init_insn_group_barriers ();
+ 		  for (last = NEXT_INSN (last);
+ 		       last != insn;
+ 		       last = NEXT_INSN (last))
+ 		    if (INSN_P (last))
+ 		      {
+ 			group_barrier_needed (last);
+ 			if (recog_memoized (last) >= 0
+ 			    && important_for_bundling_p (last))
+ 			  seen_good_insn = 1;
+ 		      }
+ 		}
+ 	      else
+ 		{
+ 		  emit_insn_before (gen_insn_group_barrier (GEN_INT (3)),
+ 				    insn);
+ 		  init_insn_group_barriers ();
+ 		  seen_good_insn = 0;
+ 		}
+ 	      group_barrier_needed (insn);
+ 	      if (recog_memoized (insn) >= 0
+ 		  && important_for_bundling_p (insn))
+ 		seen_good_insn = 1;
+ 	    }
+ 	  else if (recog_memoized (insn) >= 0
+ 		   && important_for_bundling_p (insn))
+ 	    seen_good_insn = 1;
+ 	  need_barrier_p = (CALL_P (insn) || unknown_for_bundling_p (insn));
+ 	}
+     }
+ }
+ 
+ \f
+ 
+ /* If the following function returns TRUE, we will use the DFA
+    insn scheduler.  */
+ 
+ static int
+ ia64_first_cycle_multipass_dfa_lookahead (void)
+ {
+   return (reload_completed ? 6 : 4);
+ }
+ 
+ /* The following function initiates variable `dfa_pre_cycle_insn'.  */
+ 
+ static void
+ ia64_init_dfa_pre_cycle_insn (void)
+ {
+   if (temp_dfa_state == NULL)
+     {
+       dfa_state_size = state_size ();
+       temp_dfa_state = xmalloc (dfa_state_size);
+       prev_cycle_state = xmalloc (dfa_state_size);
+     }
+   dfa_pre_cycle_insn = make_insn_raw (gen_pre_cycle ());
+   SET_PREV_INSN (dfa_pre_cycle_insn) = SET_NEXT_INSN (dfa_pre_cycle_insn) = NULL_RTX;
+   recog_memoized (dfa_pre_cycle_insn);
+   dfa_stop_insn = make_insn_raw (gen_insn_group_barrier (GEN_INT (3)));
+   SET_PREV_INSN (dfa_stop_insn) = SET_NEXT_INSN (dfa_stop_insn) = NULL_RTX;
+   recog_memoized (dfa_stop_insn);
+ }
+ 
+ /* The following function returns the pseudo insn DFA_PRE_CYCLE_INSN
+    used by the DFA insn scheduler.  */
+ 
+ static rtx
+ ia64_dfa_pre_cycle_insn (void)
+ {
+   return dfa_pre_cycle_insn;
+ }
+ 
+ /* The following function returns TRUE if PRODUCER (of type ilog or
+    ld) produces address for CONSUMER (of type st or stf). */
+ 
+ int
+ ia64_st_address_bypass_p (rtx_insn *producer, rtx_insn *consumer)
+ {
+   rtx dest, reg, mem;
+ 
+   gcc_assert (producer && consumer);
+   dest = ia64_single_set (producer);
+   gcc_assert (dest);
+   reg = SET_DEST (dest);
+   gcc_assert (reg);
+   if (GET_CODE (reg) == SUBREG)
+     reg = SUBREG_REG (reg);
+   gcc_assert (GET_CODE (reg) == REG);
+   
+   dest = ia64_single_set (consumer);
+   gcc_assert (dest);
+   mem = SET_DEST (dest);
+   gcc_assert (mem && GET_CODE (mem) == MEM);
+   return reg_mentioned_p (reg, mem);
+ }
+ 
+ /* The following function returns TRUE if PRODUCER (of type ilog or
+    ld) produces address for CONSUMER (of type ld or fld). */
+ 
+ int
+ ia64_ld_address_bypass_p (rtx_insn *producer, rtx_insn *consumer)
+ {
+   rtx dest, src, reg, mem;
+ 
+   gcc_assert (producer && consumer);
+   dest = ia64_single_set (producer);
+   gcc_assert (dest);
+   reg = SET_DEST (dest);
+   gcc_assert (reg);
+   if (GET_CODE (reg) == SUBREG)
+     reg = SUBREG_REG (reg);
+   gcc_assert (GET_CODE (reg) == REG);
+   
+   src = ia64_single_set (consumer);
+   gcc_assert (src);
+   mem = SET_SRC (src);
+   gcc_assert (mem);
+  
+   if (GET_CODE (mem) == UNSPEC && XVECLEN (mem, 0) > 0)
+     mem = XVECEXP (mem, 0, 0);
+   else if (GET_CODE (mem) == IF_THEN_ELSE)
+     /* ??? Is this bypass necessary for ld.c?  */
+     {
+       gcc_assert (XINT (XEXP (XEXP (mem, 0), 0), 1) == UNSPEC_LDCCLR);
+       mem = XEXP (mem, 1);
+     }
+      
+   while (GET_CODE (mem) == SUBREG || GET_CODE (mem) == ZERO_EXTEND)
+     mem = XEXP (mem, 0);
+ 
+   if (GET_CODE (mem) == UNSPEC)
+     {
+       int c = XINT (mem, 1);
+ 
+       gcc_assert (c == UNSPEC_LDA || c == UNSPEC_LDS || c == UNSPEC_LDS_A
+ 		  || c == UNSPEC_LDSA);
+       mem = XVECEXP (mem, 0, 0);
+     }
+ 
+   /* Note that LO_SUM is used for GOT loads.  */
+   gcc_assert (GET_CODE (mem) == LO_SUM || GET_CODE (mem) == MEM);
+ 
+   return reg_mentioned_p (reg, mem);
+ }
+ 
+ /* The following function returns TRUE if INSN produces address for a
+    load/store insn.  We will place such insns into M slot because it
+    decreases its latency time.  */
+ 
+ int
+ ia64_produce_address_p (rtx insn)
+ {
+   return insn->call;
+ }
+ 
+ \f
+ /* Emit pseudo-ops for the assembler to describe predicate relations.
+    At present this assumes that we only consider predicate pairs to
+    be mutex, and that the assembler can deduce proper values from
+    straight-line code.  */
+ 
+ static void
+ emit_predicate_relation_info (void)
+ {
+   basic_block bb;
+ 
+   FOR_EACH_BB_REVERSE_FN (bb, cfun)
+     {
+       int r;
+       rtx_insn *head = BB_HEAD (bb);
+ 
+       /* We only need such notes at code labels.  */
+       if (! LABEL_P (head))
+ 	continue;
+       if (NOTE_INSN_BASIC_BLOCK_P (NEXT_INSN (head)))
+ 	head = NEXT_INSN (head);
+ 
+       /* Skip p0, which may be thought to be live due to (reg:DI p0)
+ 	 grabbing the entire block of predicate registers.  */
+       for (r = PR_REG (2); r < PR_REG (64); r += 2)
+ 	if (REGNO_REG_SET_P (df_get_live_in (bb), r))
+ 	  {
+ 	    rtx p = gen_rtx_REG (BImode, r);
+ 	    rtx_insn *n = emit_insn_after (gen_pred_rel_mutex (p), head);
+ 	    if (head == BB_END (bb))
+ 	      BB_END (bb) = n;
+ 	    head = n;
+ 	  }
+     }
+ 
+   /* Look for conditional calls that do not return, and protect predicate
+      relations around them.  Otherwise the assembler will assume the call
+      returns, and complain about uses of call-clobbered predicates after
+      the call.  */
+   FOR_EACH_BB_REVERSE_FN (bb, cfun)
+     {
+       rtx_insn *insn = BB_HEAD (bb);
+ 
+       while (1)
+ 	{
+ 	  if (CALL_P (insn)
+ 	      && GET_CODE (PATTERN (insn)) == COND_EXEC
+ 	      && find_reg_note (insn, REG_NORETURN, NULL_RTX))
+ 	    {
+ 	      rtx_insn *b =
+ 		emit_insn_before (gen_safe_across_calls_all (), insn);
+ 	      rtx_insn *a = emit_insn_after (gen_safe_across_calls_normal (), insn);
+ 	      if (BB_HEAD (bb) == insn)
+ 		BB_HEAD (bb) = b;
+ 	      if (BB_END (bb) == insn)
+ 		BB_END (bb) = a;
+ 	    }
+ 
+ 	  if (insn == BB_END (bb))
+ 	    break;
+ 	  insn = NEXT_INSN (insn);
+ 	}
+     }
+ }
+ 
+ /* Perform machine dependent operations on the rtl chain INSNS.  */
+ 
+ static void
+ ia64_reorg (void)
+ {
+   /* We are freeing block_for_insn in the toplev to keep compatibility
+      with old MDEP_REORGS that are not CFG based.  Recompute it now.  */
+   compute_bb_for_insn ();
+ 
+   /* If optimizing, we'll have split before scheduling.  */
+   if (optimize == 0)
+     split_all_insns ();
+ 
+   if (optimize && flag_schedule_insns_after_reload
+       && dbg_cnt (ia64_sched2))
+     {
+       basic_block bb;
+       timevar_push (TV_SCHED2);
+       ia64_final_schedule = 1;
+ 
+       /* We can't let modulo-sched prevent us from scheduling any bbs,
+ 	 since we need the final schedule to produce bundle information.  */
+       FOR_EACH_BB_FN (bb, cfun)
+ 	bb->flags &= ~BB_DISABLE_SCHEDULE;
+ 
+       initiate_bundle_states ();
+       ia64_nop = make_insn_raw (gen_nop ());
+       SET_PREV_INSN (ia64_nop) = SET_NEXT_INSN (ia64_nop) = NULL_RTX;
+       recog_memoized (ia64_nop);
+       clocks_length = get_max_uid () + 1;
+       stops_p = XCNEWVEC (char, clocks_length);
+ 
+       if (ia64_tune == PROCESSOR_ITANIUM2)
+ 	{
+ 	  pos_1 = get_cpu_unit_code ("2_1");
+ 	  pos_2 = get_cpu_unit_code ("2_2");
+ 	  pos_3 = get_cpu_unit_code ("2_3");
+ 	  pos_4 = get_cpu_unit_code ("2_4");
+ 	  pos_5 = get_cpu_unit_code ("2_5");
+ 	  pos_6 = get_cpu_unit_code ("2_6");
+ 	  _0mii_ = get_cpu_unit_code ("2b_0mii.");
+ 	  _0mmi_ = get_cpu_unit_code ("2b_0mmi.");
+ 	  _0mfi_ = get_cpu_unit_code ("2b_0mfi.");
+ 	  _0mmf_ = get_cpu_unit_code ("2b_0mmf.");
+ 	  _0bbb_ = get_cpu_unit_code ("2b_0bbb.");
+ 	  _0mbb_ = get_cpu_unit_code ("2b_0mbb.");
+ 	  _0mib_ = get_cpu_unit_code ("2b_0mib.");
+ 	  _0mmb_ = get_cpu_unit_code ("2b_0mmb.");
+ 	  _0mfb_ = get_cpu_unit_code ("2b_0mfb.");
+ 	  _0mlx_ = get_cpu_unit_code ("2b_0mlx.");
+ 	  _1mii_ = get_cpu_unit_code ("2b_1mii.");
+ 	  _1mmi_ = get_cpu_unit_code ("2b_1mmi.");
+ 	  _1mfi_ = get_cpu_unit_code ("2b_1mfi.");
+ 	  _1mmf_ = get_cpu_unit_code ("2b_1mmf.");
+ 	  _1bbb_ = get_cpu_unit_code ("2b_1bbb.");
+ 	  _1mbb_ = get_cpu_unit_code ("2b_1mbb.");
+ 	  _1mib_ = get_cpu_unit_code ("2b_1mib.");
+ 	  _1mmb_ = get_cpu_unit_code ("2b_1mmb.");
+ 	  _1mfb_ = get_cpu_unit_code ("2b_1mfb.");
+ 	  _1mlx_ = get_cpu_unit_code ("2b_1mlx.");
+ 	}
+       else
+ 	{
+ 	  pos_1 = get_cpu_unit_code ("1_1");
+ 	  pos_2 = get_cpu_unit_code ("1_2");
+ 	  pos_3 = get_cpu_unit_code ("1_3");
+ 	  pos_4 = get_cpu_unit_code ("1_4");
+ 	  pos_5 = get_cpu_unit_code ("1_5");
+ 	  pos_6 = get_cpu_unit_code ("1_6");
+ 	  _0mii_ = get_cpu_unit_code ("1b_0mii.");
+ 	  _0mmi_ = get_cpu_unit_code ("1b_0mmi.");
+ 	  _0mfi_ = get_cpu_unit_code ("1b_0mfi.");
+ 	  _0mmf_ = get_cpu_unit_code ("1b_0mmf.");
+ 	  _0bbb_ = get_cpu_unit_code ("1b_0bbb.");
+ 	  _0mbb_ = get_cpu_unit_code ("1b_0mbb.");
+ 	  _0mib_ = get_cpu_unit_code ("1b_0mib.");
+ 	  _0mmb_ = get_cpu_unit_code ("1b_0mmb.");
+ 	  _0mfb_ = get_cpu_unit_code ("1b_0mfb.");
+ 	  _0mlx_ = get_cpu_unit_code ("1b_0mlx.");
+ 	  _1mii_ = get_cpu_unit_code ("1b_1mii.");
+ 	  _1mmi_ = get_cpu_unit_code ("1b_1mmi.");
+ 	  _1mfi_ = get_cpu_unit_code ("1b_1mfi.");
+ 	  _1mmf_ = get_cpu_unit_code ("1b_1mmf.");
+ 	  _1bbb_ = get_cpu_unit_code ("1b_1bbb.");
+ 	  _1mbb_ = get_cpu_unit_code ("1b_1mbb.");
+ 	  _1mib_ = get_cpu_unit_code ("1b_1mib.");
+ 	  _1mmb_ = get_cpu_unit_code ("1b_1mmb.");
+ 	  _1mfb_ = get_cpu_unit_code ("1b_1mfb.");
+ 	  _1mlx_ = get_cpu_unit_code ("1b_1mlx.");
+ 	}
+ 
+       if (flag_selective_scheduling2
+ 	  && !maybe_skip_selective_scheduling ())
+         run_selective_scheduling ();
+       else
+ 	schedule_ebbs ();
+ 
+       /* Redo alignment computation, as it might gone wrong.  */
+       compute_alignments ();
+ 
+       /* We cannot reuse this one because it has been corrupted by the
+ 	 evil glat.  */
+       finish_bundle_states ();
+       free (stops_p);
+       stops_p = NULL;
+       emit_insn_group_barriers (dump_file);
+ 
+       ia64_final_schedule = 0;
+       timevar_pop (TV_SCHED2);
+     }
+   else
+     emit_all_insn_group_barriers (dump_file);
+ 
+   df_analyze ();
+  
+   /* A call must not be the last instruction in a function, so that the
+      return address is still within the function, so that unwinding works
+      properly.  Note that IA-64 differs from dwarf2 on this point.  */
+   if (ia64_except_unwind_info (&global_options) == UI_TARGET)
+     {
+       rtx_insn *insn;
+       int saw_stop = 0;
+ 
+       insn = get_last_insn ();
+       if (! INSN_P (insn))
+         insn = prev_active_insn (insn);
+       if (insn)
+ 	{
+ 	  /* Skip over insns that expand to nothing.  */
+ 	  while (NONJUMP_INSN_P (insn)
+ 		 && get_attr_empty (insn) == EMPTY_YES)
+ 	    {
+ 	      if (GET_CODE (PATTERN (insn)) == UNSPEC_VOLATILE
+ 		  && XINT (PATTERN (insn), 1) == UNSPECV_INSN_GROUP_BARRIER)
+ 		saw_stop = 1;
+ 	      insn = prev_active_insn (insn);
+ 	    }
+ 	  if (CALL_P (insn))
+ 	    {
+ 	      if (! saw_stop)
+ 		emit_insn (gen_insn_group_barrier (GEN_INT (3)));
+ 	      emit_insn (gen_break_f ());
+ 	      emit_insn (gen_insn_group_barrier (GEN_INT (3)));
+ 	    }
+ 	}
+     }
+ 
+   emit_predicate_relation_info ();
+ 
+   if (flag_var_tracking)
+     {
+       timevar_push (TV_VAR_TRACKING);
+       variable_tracking_main ();
+       timevar_pop (TV_VAR_TRACKING);
+     }
+   df_finish_pass (false);
+ }
+ \f
+ /* Return true if REGNO is used by the epilogue.  */
+ 
+ int
+ ia64_epilogue_uses (int regno)
+ {
+   switch (regno)
+     {
+     case R_GR (1):
+       /* With a call to a function in another module, we will write a new
+ 	 value to "gp".  After returning from such a call, we need to make
+ 	 sure the function restores the original gp-value, even if the
+ 	 function itself does not use the gp anymore.  */
+       return !(TARGET_AUTO_PIC || TARGET_NO_PIC);
+ 
+     case IN_REG (0): case IN_REG (1): case IN_REG (2): case IN_REG (3):
+     case IN_REG (4): case IN_REG (5): case IN_REG (6): case IN_REG (7):
+       /* For functions defined with the syscall_linkage attribute, all
+ 	 input registers are marked as live at all function exits.  This
+ 	 prevents the register allocator from using the input registers,
+ 	 which in turn makes it possible to restart a system call after
+ 	 an interrupt without having to save/restore the input registers.
+ 	 This also prevents kernel data from leaking to application code.  */
+       return lookup_attribute ("syscall_linkage",
+ 	   TYPE_ATTRIBUTES (TREE_TYPE (current_function_decl))) != NULL;
+ 
+     case R_BR (0):
+       /* Conditional return patterns can't represent the use of `b0' as
+          the return address, so we force the value live this way.  */
+       return 1;
+ 
+     case AR_PFS_REGNUM:
+       /* Likewise for ar.pfs, which is used by br.ret.  */
+       return 1;
+ 
+     default:
+       return 0;
+     }
+ }
+ 
+ /* Return true if REGNO is used by the frame unwinder.  */
+ 
+ int
+ ia64_eh_uses (int regno)
+ {
+   unsigned int r;
+ 
+   if (! reload_completed)
+     return 0;
+ 
+   if (regno == 0)
+     return 0;
+ 
+   for (r = reg_save_b0; r <= reg_save_ar_lc; r++)
+     if (regno == current_frame_info.r[r]
+        || regno == emitted_frame_related_regs[r])
+       return 1;
+ 
+   return 0;
+ }
+ \f
+ /* Return true if this goes in small data/bss.  */
+ 
+ /* ??? We could also support own long data here.  Generating movl/add/ld8
+    instead of addl,ld8/ld8.  This makes the code bigger, but should make the
+    code faster because there is one less load.  This also includes incomplete
+    types which can't go in sdata/sbss.  */
+ 
+ static bool
+ ia64_in_small_data_p (const_tree exp)
+ {
+   if (TARGET_NO_SDATA)
+     return false;
+ 
+   /* We want to merge strings, so we never consider them small data.  */
+   if (TREE_CODE (exp) == STRING_CST)
+     return false;
+ 
+   /* Functions are never small data.  */
+   if (TREE_CODE (exp) == FUNCTION_DECL)
+     return false;
+ 
+   if (TREE_CODE (exp) == VAR_DECL && DECL_SECTION_NAME (exp))
+     {
+       const char *section = DECL_SECTION_NAME (exp);
+ 
+       if (strcmp (section, ".sdata") == 0
+ 	  || startswith (section, ".sdata.")
+ 	  || startswith (section, ".gnu.linkonce.s.")
+ 	  || strcmp (section, ".sbss") == 0
+ 	  || startswith (section, ".sbss.")
+ 	  || startswith (section, ".gnu.linkonce.sb."))
+ 	return true;
+     }
+   else
+     {
+       HOST_WIDE_INT size = int_size_in_bytes (TREE_TYPE (exp));
+ 
+       /* If this is an incomplete type with size 0, then we can't put it
+ 	 in sdata because it might be too big when completed.  */
+       if (size > 0 && size <= ia64_section_threshold)
+ 	return true;
+     }
+ 
+   return false;
+ }
+ \f
+ /* Output assembly directives for prologue regions.  */
+ 
+ /* The current basic block number.  */
+ 
+ static bool last_block;
+ 
+ /* True if we need a copy_state command at the start of the next block.  */
+ 
+ static bool need_copy_state;
+ 
+ #ifndef MAX_ARTIFICIAL_LABEL_BYTES
+ # define MAX_ARTIFICIAL_LABEL_BYTES 30
+ #endif
+ 
+ /* The function emits unwind directives for the start of an epilogue.  */
+ 
+ static void
+ process_epilogue (FILE *out_file, rtx insn ATTRIBUTE_UNUSED,
+ 		  bool unwind, bool frame ATTRIBUTE_UNUSED)
+ {
+   /* If this isn't the last block of the function, then we need to label the
+      current state, and copy it back in at the start of the next block.  */
+ 
+   if (!last_block)
+     {
+       if (unwind)
+ 	fprintf (out_file, "\t.label_state %d\n",
+ 		 ++cfun->machine->state_num);
+       need_copy_state = true;
+     }
+ 
+   if (unwind)
+     fprintf (out_file, "\t.restore sp\n");
+ }
+ 
+ /* This function processes a SET pattern for REG_CFA_ADJUST_CFA.  */
+ 
+ static void
+ process_cfa_adjust_cfa (FILE *out_file, rtx pat, rtx insn,
+ 			bool unwind, bool frame)
+ {
+   rtx dest = SET_DEST (pat);
+   rtx src = SET_SRC (pat);
+ 
+   if (dest == stack_pointer_rtx)
+     {
+       if (GET_CODE (src) == PLUS)
+ 	{
+ 	  rtx op0 = XEXP (src, 0);
+ 	  rtx op1 = XEXP (src, 1);
+ 	  
+ 	  gcc_assert (op0 == dest && GET_CODE (op1) == CONST_INT);
+ 	  
+ 	  if (INTVAL (op1) < 0)
+ 	    {
+ 	      gcc_assert (!frame_pointer_needed);
+ 	      if (unwind)
+ 		fprintf (out_file,
+ 			 "\t.fframe " HOST_WIDE_INT_PRINT_DEC"\n",
+ 			 -INTVAL (op1));
+ 	    }
+ 	  else
+ 	    process_epilogue (out_file, insn, unwind, frame);
+ 	}
+       else
+ 	{
+ 	  gcc_assert (src == hard_frame_pointer_rtx);
+ 	  process_epilogue (out_file, insn, unwind, frame);
+ 	}
+     }
+   else if (dest == hard_frame_pointer_rtx)
+     {
+       gcc_assert (src == stack_pointer_rtx);
+       gcc_assert (frame_pointer_needed);
+ 
+       if (unwind)
+ 	fprintf (out_file, "\t.vframe r%d\n",
+ 		 ia64_dbx_register_number (REGNO (dest)));
+     }
+   else
+     gcc_unreachable ();
+ }
+ 
+ /* This function processes a SET pattern for REG_CFA_REGISTER.  */
+ 
+ static void
+ process_cfa_register (FILE *out_file, rtx pat, bool unwind)
+ {
+   rtx dest = SET_DEST (pat);
+   rtx src = SET_SRC (pat);
+   int dest_regno = REGNO (dest);
+   int src_regno;
+ 
+   if (src == pc_rtx)
+     {
+       /* Saving return address pointer.  */
+       if (unwind)
+ 	fprintf (out_file, "\t.save rp, r%d\n",
+ 		 ia64_dbx_register_number (dest_regno));
+       return;
+     }
+ 
+   src_regno = REGNO (src);
+ 
+   switch (src_regno)
+     {
+     case PR_REG (0):
+       gcc_assert (dest_regno == current_frame_info.r[reg_save_pr]);
+       if (unwind)
+ 	fprintf (out_file, "\t.save pr, r%d\n",
+ 		 ia64_dbx_register_number (dest_regno));
+       break;
+ 
+     case AR_UNAT_REGNUM:
+       gcc_assert (dest_regno == current_frame_info.r[reg_save_ar_unat]);
+       if (unwind)
+ 	fprintf (out_file, "\t.save ar.unat, r%d\n",
+ 		 ia64_dbx_register_number (dest_regno));
+       break;
+ 
+     case AR_LC_REGNUM:
+       gcc_assert (dest_regno == current_frame_info.r[reg_save_ar_lc]);
+       if (unwind)
+ 	fprintf (out_file, "\t.save ar.lc, r%d\n",
+ 		 ia64_dbx_register_number (dest_regno));
+       break;
+ 
+     default:
+       /* Everything else should indicate being stored to memory.  */
+       gcc_unreachable ();
+     }
+ }
+ 
+ /* This function processes a SET pattern for REG_CFA_OFFSET.  */
+ 
+ static void
+ process_cfa_offset (FILE *out_file, rtx pat, bool unwind)
+ {
+   rtx dest = SET_DEST (pat);
+   rtx src = SET_SRC (pat);
+   int src_regno = REGNO (src);
+   const char *saveop;
+   HOST_WIDE_INT off;
+   rtx base;
+ 
+   gcc_assert (MEM_P (dest));
+   if (GET_CODE (XEXP (dest, 0)) == REG)
+     {
+       base = XEXP (dest, 0);
+       off = 0;
+     }
+   else
+     {
+       gcc_assert (GET_CODE (XEXP (dest, 0)) == PLUS
+ 		  && GET_CODE (XEXP (XEXP (dest, 0), 1)) == CONST_INT);
+       base = XEXP (XEXP (dest, 0), 0);
+       off = INTVAL (XEXP (XEXP (dest, 0), 1));
+     }
+ 
+   if (base == hard_frame_pointer_rtx)
+     {
+       saveop = ".savepsp";
+       off = - off;
+     }
+   else
+     {
+       gcc_assert (base == stack_pointer_rtx);
+       saveop = ".savesp";
+     }
+ 
+   src_regno = REGNO (src);
+   switch (src_regno)
+     {
+     case BR_REG (0):
+       gcc_assert (!current_frame_info.r[reg_save_b0]);
+       if (unwind)
+ 	fprintf (out_file, "\t%s rp, " HOST_WIDE_INT_PRINT_DEC "\n",
+ 		 saveop, off);
+       break;
+ 
+     case PR_REG (0):
+       gcc_assert (!current_frame_info.r[reg_save_pr]);
+       if (unwind)
+ 	fprintf (out_file, "\t%s pr, " HOST_WIDE_INT_PRINT_DEC "\n",
+ 		 saveop, off);
+       break;
+ 
+     case AR_LC_REGNUM:
+       gcc_assert (!current_frame_info.r[reg_save_ar_lc]);
+       if (unwind)
+ 	fprintf (out_file, "\t%s ar.lc, " HOST_WIDE_INT_PRINT_DEC "\n",
+ 		 saveop, off);
+       break;
+ 
+     case AR_PFS_REGNUM:
+       gcc_assert (!current_frame_info.r[reg_save_ar_pfs]);
+       if (unwind)
+ 	fprintf (out_file, "\t%s ar.pfs, " HOST_WIDE_INT_PRINT_DEC "\n",
+ 		 saveop, off);
+       break;
+ 
+     case AR_UNAT_REGNUM:
+       gcc_assert (!current_frame_info.r[reg_save_ar_unat]);
+       if (unwind)
+ 	fprintf (out_file, "\t%s ar.unat, " HOST_WIDE_INT_PRINT_DEC "\n",
+ 		 saveop, off);
+       break;
+ 
+     case GR_REG (4):
+     case GR_REG (5):
+     case GR_REG (6):
+     case GR_REG (7):
+       if (unwind)
+ 	fprintf (out_file, "\t.save.g 0x%x\n",
+ 		 1 << (src_regno - GR_REG (4)));
+       break;
+ 
+     case BR_REG (1):
+     case BR_REG (2):
+     case BR_REG (3):
+     case BR_REG (4):
+     case BR_REG (5):
+       if (unwind)
+ 	fprintf (out_file, "\t.save.b 0x%x\n",
+ 		 1 << (src_regno - BR_REG (1)));
+       break;
+ 
+     case FR_REG (2):
+     case FR_REG (3):
+     case FR_REG (4):
+     case FR_REG (5):
+       if (unwind)
+ 	fprintf (out_file, "\t.save.f 0x%x\n",
+ 		 1 << (src_regno - FR_REG (2)));
+       break;
+ 
+     case FR_REG (16): case FR_REG (17): case FR_REG (18): case FR_REG (19):
+     case FR_REG (20): case FR_REG (21): case FR_REG (22): case FR_REG (23):
+     case FR_REG (24): case FR_REG (25): case FR_REG (26): case FR_REG (27):
+     case FR_REG (28): case FR_REG (29): case FR_REG (30): case FR_REG (31):
+       if (unwind)
+ 	fprintf (out_file, "\t.save.gf 0x0, 0x%x\n",
+ 		 1 << (src_regno - FR_REG (12)));
+       break;
+ 
+     default:
+       /* ??? For some reason we mark other general registers, even those
+ 	 we can't represent in the unwind info.  Ignore them.  */
+       break;
+     }
+ }
+ 
+ /* This function looks at a single insn and emits any directives
+    required to unwind this insn.  */
+ 
+ static void
+ ia64_asm_unwind_emit (FILE *out_file, rtx_insn *insn)
+ {
+   bool unwind = ia64_except_unwind_info (&global_options) == UI_TARGET;
+   bool frame = dwarf2out_do_frame ();
+   rtx note, pat;
+   bool handled_one;
+ 
+   if (!unwind && !frame)
+     return;
+ 
+   if (NOTE_INSN_BASIC_BLOCK_P (insn))
+     {
+       last_block = NOTE_BASIC_BLOCK (insn)->next_bb
+      == EXIT_BLOCK_PTR_FOR_FN (cfun);
+ 
+       /* Restore unwind state from immediately before the epilogue.  */
+       if (need_copy_state)
+ 	{
+ 	  if (unwind)
+ 	    {
+ 	      fprintf (out_file, "\t.body\n");
+ 	      fprintf (out_file, "\t.copy_state %d\n",
+ 		       cfun->machine->state_num);
+ 	    }
+ 	  need_copy_state = false;
+ 	}
+     }
+ 
+   if (NOTE_P (insn) || ! RTX_FRAME_RELATED_P (insn))
+     return;
+ 
+   /* Look for the ALLOC insn.  */
+   if (INSN_CODE (insn) == CODE_FOR_alloc)
+     {
+       rtx dest = SET_DEST (XVECEXP (PATTERN (insn), 0, 0));
+       int dest_regno = REGNO (dest);
+ 
+       /* If this is the final destination for ar.pfs, then this must
+ 	 be the alloc in the prologue.  */
+       if (dest_regno == current_frame_info.r[reg_save_ar_pfs])
+ 	{
+ 	  if (unwind)
+ 	    fprintf (out_file, "\t.save ar.pfs, r%d\n",
+ 		     ia64_dbx_register_number (dest_regno));
+ 	}
+       else
+ 	{
+ 	  /* This must be an alloc before a sibcall.  We must drop the
+ 	     old frame info.  The easiest way to drop the old frame
+ 	     info is to ensure we had a ".restore sp" directive
+ 	     followed by a new prologue.  If the procedure doesn't
+ 	     have a memory-stack frame, we'll issue a dummy ".restore
+ 	     sp" now.  */
+ 	  if (current_frame_info.total_size == 0 && !frame_pointer_needed)
+ 	    /* if haven't done process_epilogue() yet, do it now */
+ 	    process_epilogue (out_file, insn, unwind, frame);
+ 	  if (unwind)
+ 	    fprintf (out_file, "\t.prologue\n");
+ 	}
+       return;
+     }
+ 
+   handled_one = false;
+   for (note = REG_NOTES (insn); note; note = XEXP (note, 1))
+     switch (REG_NOTE_KIND (note))
+       {
+       case REG_CFA_ADJUST_CFA:
+ 	pat = XEXP (note, 0);
+ 	if (pat == NULL)
+ 	  pat = PATTERN (insn);
+ 	process_cfa_adjust_cfa (out_file, pat, insn, unwind, frame);
+ 	handled_one = true;
+ 	break;
+ 
+       case REG_CFA_OFFSET:
+ 	pat = XEXP (note, 0);
+ 	if (pat == NULL)
+ 	  pat = PATTERN (insn);
+ 	process_cfa_offset (out_file, pat, unwind);
+ 	handled_one = true;
+ 	break;
+ 
+       case REG_CFA_REGISTER:
+ 	pat = XEXP (note, 0);
+ 	if (pat == NULL)
+ 	  pat = PATTERN (insn);
+ 	process_cfa_register (out_file, pat, unwind);
+ 	handled_one = true;
+ 	break;
+ 
+       case REG_FRAME_RELATED_EXPR:
+       case REG_CFA_DEF_CFA:
+       case REG_CFA_EXPRESSION:
+       case REG_CFA_RESTORE:
+       case REG_CFA_SET_VDRAP:
+ 	/* Not used in the ia64 port.  */
+ 	gcc_unreachable ();
+ 
+       default:
+ 	/* Not a frame-related note.  */
+ 	break;
+       }
+ 
+   /* All REG_FRAME_RELATED_P insns, besides ALLOC, are marked with the
+      explicit action to take.  No guessing required.  */
+   gcc_assert (handled_one);
+ }
+ 
+ /* Implement TARGET_ASM_EMIT_EXCEPT_PERSONALITY.  */
+ 
+ static void
+ ia64_asm_emit_except_personality (rtx personality)
+ {
+   fputs ("\t.personality\t", asm_out_file);
+   output_addr_const (asm_out_file, personality);
+   fputc ('\n', asm_out_file);
+ }
+ 
+ /* Implement TARGET_ASM_INITIALIZE_SECTIONS.  */
+ 
+ static void
+ ia64_asm_init_sections (void)
+ {
+   exception_section = get_unnamed_section (0, output_section_asm_op,
+ 					   "\t.handlerdata");
+ }
+ 
+ /* Implement TARGET_DEBUG_UNWIND_INFO.  */
+ 
+ static enum unwind_info_type
+ ia64_debug_unwind_info (void)
+ {
+   return UI_TARGET;
+ }
+ \f
+ enum ia64_builtins
+ {
+   IA64_BUILTIN_BSP,
+   IA64_BUILTIN_COPYSIGNQ,
+   IA64_BUILTIN_FABSQ,
+   IA64_BUILTIN_FLUSHRS,
+   IA64_BUILTIN_INFQ,
+   IA64_BUILTIN_HUGE_VALQ,
+   IA64_BUILTIN_NANQ,
+   IA64_BUILTIN_NANSQ,
+   IA64_BUILTIN_max
+ };
+ 
+ static GTY(()) tree ia64_builtins[(int) IA64_BUILTIN_max];
+ 
+ void
+ ia64_init_builtins (void)
+ {
+   tree fpreg_type;
+   tree float80_type;
+   tree decl;
+ 
+   /* The __fpreg type.  */
+   fpreg_type = make_node (REAL_TYPE);
+   TYPE_PRECISION (fpreg_type) = 82;
+   layout_type (fpreg_type);
+   (*lang_hooks.types.register_builtin_type) (fpreg_type, "__fpreg");
+ 
+   /* The __float80 type.  */
+   if (float64x_type_node != NULL_TREE
+       && TYPE_MODE (float64x_type_node) == XFmode)
+     float80_type = float64x_type_node;
+   else
+     {
+       float80_type = make_node (REAL_TYPE);
+       TYPE_PRECISION (float80_type) = 80;
+       layout_type (float80_type);
+     }
+   (*lang_hooks.types.register_builtin_type) (float80_type, "__float80");
+ 
+   /* The __float128 type.  */
+   if (!TARGET_HPUX)
+     {
+       tree ftype;
+       tree const_string_type
+ 	= build_pointer_type (build_qualified_type
+ 			      (char_type_node, TYPE_QUAL_CONST));
+ 
+       (*lang_hooks.types.register_builtin_type) (float128_type_node,
+ 						 "__float128");
+ 
+       /* TFmode support builtins.  */
+       ftype = build_function_type_list (float128_type_node, NULL_TREE);
+       decl = add_builtin_function ("__builtin_infq", ftype,
+ 				   IA64_BUILTIN_INFQ, BUILT_IN_MD,
+ 				   NULL, NULL_TREE);
+       ia64_builtins[IA64_BUILTIN_INFQ] = decl;
+ 
+       decl = add_builtin_function ("__builtin_huge_valq", ftype,
+ 				   IA64_BUILTIN_HUGE_VALQ, BUILT_IN_MD,
+ 				   NULL, NULL_TREE);
+       ia64_builtins[IA64_BUILTIN_HUGE_VALQ] = decl;
+ 
+       ftype = build_function_type_list (float128_type_node,
+ 					const_string_type,
+ 					NULL_TREE);
+       decl = add_builtin_function ("__builtin_nanq", ftype,
+ 				   IA64_BUILTIN_NANQ, BUILT_IN_MD,
+ 				   "nanq", NULL_TREE);
+       TREE_READONLY (decl) = 1;
+       ia64_builtins[IA64_BUILTIN_NANQ] = decl;
+ 
+       decl = add_builtin_function ("__builtin_nansq", ftype,
+ 				   IA64_BUILTIN_NANSQ, BUILT_IN_MD,
+ 				   "nansq", NULL_TREE);
+       TREE_READONLY (decl) = 1;
+       ia64_builtins[IA64_BUILTIN_NANSQ] = decl;
+ 
+       ftype = build_function_type_list (float128_type_node,
+ 					float128_type_node,
+ 					NULL_TREE);
+       decl = add_builtin_function ("__builtin_fabsq", ftype,
+ 				   IA64_BUILTIN_FABSQ, BUILT_IN_MD,
+ 				   "__fabstf2", NULL_TREE);
+       TREE_READONLY (decl) = 1;
+       ia64_builtins[IA64_BUILTIN_FABSQ] = decl;
+ 
+       ftype = build_function_type_list (float128_type_node,
+ 					float128_type_node,
+ 					float128_type_node,
+ 					NULL_TREE);
+       decl = add_builtin_function ("__builtin_copysignq", ftype,
+ 				   IA64_BUILTIN_COPYSIGNQ, BUILT_IN_MD,
+ 				   "__copysigntf3", NULL_TREE);
+       TREE_READONLY (decl) = 1;
+       ia64_builtins[IA64_BUILTIN_COPYSIGNQ] = decl;
+     }
+   else
+     /* Under HPUX, this is a synonym for "long double".  */
+     (*lang_hooks.types.register_builtin_type) (long_double_type_node,
+ 					       "__float128");
+ 
+   /* Fwrite on VMS is non-standard.  */
+ #if TARGET_ABI_OPEN_VMS
+   vms_patch_builtins ();
+ #endif
+ 
+ #define def_builtin(name, type, code)					\
+   add_builtin_function ((name), (type), (code), BUILT_IN_MD,	\
+ 		       NULL, NULL_TREE)
+ 
+   decl = def_builtin ("__builtin_ia64_bsp",
+ 		      build_function_type_list (ptr_type_node, NULL_TREE),
+ 		      IA64_BUILTIN_BSP);
+   ia64_builtins[IA64_BUILTIN_BSP] = decl;
+ 
+   decl = def_builtin ("__builtin_ia64_flushrs",
+ 		      build_function_type_list (void_type_node, NULL_TREE),
+ 		      IA64_BUILTIN_FLUSHRS);
+   ia64_builtins[IA64_BUILTIN_FLUSHRS] = decl;
+ 
+ #undef def_builtin
+ 
+   if (TARGET_HPUX)
+     {
+       if ((decl = builtin_decl_explicit (BUILT_IN_FINITE)) != NULL_TREE)
+ 	set_user_assembler_name (decl, "_Isfinite");
+       if ((decl = builtin_decl_explicit (BUILT_IN_FINITEF)) != NULL_TREE)
+ 	set_user_assembler_name (decl, "_Isfinitef");
+       if ((decl = builtin_decl_explicit (BUILT_IN_FINITEL)) != NULL_TREE)
+ 	set_user_assembler_name (decl, "_Isfinitef128");
+     }
+ }
+ 
+ static tree
+ ia64_fold_builtin (tree fndecl, int n_args ATTRIBUTE_UNUSED,
+ 		   tree *args, bool ignore ATTRIBUTE_UNUSED)
+ {
+   if (DECL_BUILT_IN_CLASS (fndecl) == BUILT_IN_MD)
+     {
+       enum ia64_builtins fn_code
+ 	= (enum ia64_builtins) DECL_MD_FUNCTION_CODE (fndecl);
+       switch (fn_code)
+ 	{
+ 	case IA64_BUILTIN_NANQ:
+ 	case IA64_BUILTIN_NANSQ:
+ 	  {
+ 	    tree type = TREE_TYPE (TREE_TYPE (fndecl));
+ 	    const char *str = c_getstr (*args);
+ 	    int quiet = fn_code == IA64_BUILTIN_NANQ;
+ 	    REAL_VALUE_TYPE real;
+ 
+ 	    if (str && real_nan (&real, str, quiet, TYPE_MODE (type)))
+ 	      return build_real (type, real);
+ 	    return NULL_TREE;
+ 	  }
+ 
+ 	default:
+ 	  break;
+ 	}
+     }
+ 
+ #ifdef SUBTARGET_FOLD_BUILTIN
+   return SUBTARGET_FOLD_BUILTIN (fndecl, n_args, args, ignore);
+ #endif
+ 
+   return NULL_TREE;
+ }
+ 
+ rtx
+ ia64_expand_builtin (tree exp, rtx target, rtx subtarget ATTRIBUTE_UNUSED,
+ 		     machine_mode mode ATTRIBUTE_UNUSED,
+ 		     int ignore ATTRIBUTE_UNUSED)
+ {
+   tree fndecl = TREE_OPERAND (CALL_EXPR_FN (exp), 0);
+   unsigned int fcode = DECL_MD_FUNCTION_CODE (fndecl);
+ 
+   switch (fcode)
+     {
+     case IA64_BUILTIN_BSP:
+       if (! target || ! register_operand (target, DImode))
+ 	target = gen_reg_rtx (DImode);
+       emit_insn (gen_bsp_value (target));
+ #ifdef POINTERS_EXTEND_UNSIGNED
+       target = convert_memory_address (ptr_mode, target);
+ #endif
+       return target;
+ 
+     case IA64_BUILTIN_FLUSHRS:
+       emit_insn (gen_flushrs ());
+       return const0_rtx;
+ 
+     case IA64_BUILTIN_INFQ:
+     case IA64_BUILTIN_HUGE_VALQ:
+       {
+         machine_mode target_mode = TYPE_MODE (TREE_TYPE (exp));
+ 	REAL_VALUE_TYPE inf;
+ 	rtx tmp;
+ 
+ 	real_inf (&inf);
+ 	tmp = const_double_from_real_value (inf, target_mode);
+ 
+ 	tmp = validize_mem (force_const_mem (target_mode, tmp));
+ 
+ 	if (target == 0)
+ 	  target = gen_reg_rtx (target_mode);
+ 
+ 	emit_move_insn (target, tmp);
+ 	return target;
+       }
+ 
+     case IA64_BUILTIN_NANQ:
+     case IA64_BUILTIN_NANSQ:
+     case IA64_BUILTIN_FABSQ:
+     case IA64_BUILTIN_COPYSIGNQ:
+       return expand_call (exp, target, ignore);
+ 
+     default:
+       gcc_unreachable ();
+     }
+ 
+   return NULL_RTX;
+ }
+ 
+ /* Return the ia64 builtin for CODE.  */
+ 
+ static tree
+ ia64_builtin_decl (unsigned code, bool initialize_p ATTRIBUTE_UNUSED)
+ {
+   if (code >= IA64_BUILTIN_max)
+     return error_mark_node;
+ 
+   return ia64_builtins[code];
+ }
+ 
+ /* Implement TARGET_FUNCTION_ARG_PADDING.
+ 
+    For the HP-UX IA64 aggregate parameters are passed stored in the
+    most significant bits of the stack slot.  */
+ 
+ static pad_direction
+ ia64_function_arg_padding (machine_mode mode, const_tree type)
+ {
+   /* Exception to normal case for structures/unions/etc.  */
+   if (TARGET_HPUX
+       && type
+       && AGGREGATE_TYPE_P (type)
+       && int_size_in_bytes (type) < UNITS_PER_WORD)
+     return PAD_UPWARD;
+ 
+   /* Fall back to the default.  */
+   return default_function_arg_padding (mode, type);
+ }
+ 
+ /* Emit text to declare externally defined variables and functions, because
+    the Intel assembler does not support undefined externals.  */
+ 
+ void
+ ia64_asm_output_external (FILE *file, tree decl, const char *name)
+ {
+   /* We output the name if and only if TREE_SYMBOL_REFERENCED is
+      set in order to avoid putting out names that are never really
+      used. */
+   if (TREE_SYMBOL_REFERENCED (DECL_ASSEMBLER_NAME (decl)))
+     {
+       /* maybe_assemble_visibility will return 1 if the assembler
+ 	 visibility directive is output.  */
+       int need_visibility = ((*targetm.binds_local_p) (decl)
+ 			     && maybe_assemble_visibility (decl));
+ 
+       /* GNU as does not need anything here, but the HP linker does
+ 	 need something for external functions.  */
+       if ((TARGET_HPUX_LD || !TARGET_GNU_AS)
+ 	  && TREE_CODE (decl) == FUNCTION_DECL)
+ 	  (*targetm.asm_out.globalize_decl_name) (file, decl);
+       else if (need_visibility && !TARGET_GNU_AS)
+ 	(*targetm.asm_out.globalize_label) (file, name);
+     }
+ }
+ 
+ /* Set SImode div/mod functions, init_integral_libfuncs only initializes
+    modes of word_mode and larger.  Rename the TFmode libfuncs using the
+    HPUX conventions. __divtf3 is used for XFmode. We need to keep it for
+    backward compatibility. */
+ 
+ static void
+ ia64_init_libfuncs (void)
+ {
+   set_optab_libfunc (sdiv_optab, SImode, "__divsi3");
+   set_optab_libfunc (udiv_optab, SImode, "__udivsi3");
+   set_optab_libfunc (smod_optab, SImode, "__modsi3");
+   set_optab_libfunc (umod_optab, SImode, "__umodsi3");
+ 
+   set_optab_libfunc (add_optab, TFmode, "_U_Qfadd");
+   set_optab_libfunc (sub_optab, TFmode, "_U_Qfsub");
+   set_optab_libfunc (smul_optab, TFmode, "_U_Qfmpy");
+   set_optab_libfunc (sdiv_optab, TFmode, "_U_Qfdiv");
+   set_optab_libfunc (neg_optab, TFmode, "_U_Qfneg");
+ 
+   set_conv_libfunc (sext_optab, TFmode, SFmode, "_U_Qfcnvff_sgl_to_quad");
+   set_conv_libfunc (sext_optab, TFmode, DFmode, "_U_Qfcnvff_dbl_to_quad");
+   set_conv_libfunc (sext_optab, TFmode, XFmode, "_U_Qfcnvff_f80_to_quad");
+   set_conv_libfunc (trunc_optab, SFmode, TFmode, "_U_Qfcnvff_quad_to_sgl");
+   set_conv_libfunc (trunc_optab, DFmode, TFmode, "_U_Qfcnvff_quad_to_dbl");
+   set_conv_libfunc (trunc_optab, XFmode, TFmode, "_U_Qfcnvff_quad_to_f80");
+ 
+   set_conv_libfunc (sfix_optab, SImode, TFmode, "_U_Qfcnvfxt_quad_to_sgl");
+   set_conv_libfunc (sfix_optab, DImode, TFmode, "_U_Qfcnvfxt_quad_to_dbl");
+   set_conv_libfunc (sfix_optab, TImode, TFmode, "_U_Qfcnvfxt_quad_to_quad");
+   set_conv_libfunc (ufix_optab, SImode, TFmode, "_U_Qfcnvfxut_quad_to_sgl");
+   set_conv_libfunc (ufix_optab, DImode, TFmode, "_U_Qfcnvfxut_quad_to_dbl");
+ 
+   set_conv_libfunc (sfloat_optab, TFmode, SImode, "_U_Qfcnvxf_sgl_to_quad");
+   set_conv_libfunc (sfloat_optab, TFmode, DImode, "_U_Qfcnvxf_dbl_to_quad");
+   set_conv_libfunc (sfloat_optab, TFmode, TImode, "_U_Qfcnvxf_quad_to_quad");
+   /* HP-UX 11.23 libc does not have a function for unsigned
+      SImode-to-TFmode conversion.  */
+   set_conv_libfunc (ufloat_optab, TFmode, DImode, "_U_Qfcnvxuf_dbl_to_quad");
+ }
+ 
+ /* Rename all the TFmode libfuncs using the HPUX conventions.  */
+ 
+ static void
+ ia64_hpux_init_libfuncs (void)
+ {
+   ia64_init_libfuncs ();
+ 
+   /* The HP SI millicode division and mod functions expect DI arguments.
+      By turning them off completely we avoid using both libgcc and the
+      non-standard millicode routines and use the HP DI millicode routines
+      instead.  */
+ 
+   set_optab_libfunc (sdiv_optab, SImode, 0);
+   set_optab_libfunc (udiv_optab, SImode, 0);
+   set_optab_libfunc (smod_optab, SImode, 0);
+   set_optab_libfunc (umod_optab, SImode, 0);
+ 
+   set_optab_libfunc (sdiv_optab, DImode, "__milli_divI");
+   set_optab_libfunc (udiv_optab, DImode, "__milli_divU");
+   set_optab_libfunc (smod_optab, DImode, "__milli_remI");
+   set_optab_libfunc (umod_optab, DImode, "__milli_remU");
+ 
+   /* HP-UX libc has TF min/max/abs routines in it.  */
+   set_optab_libfunc (smin_optab, TFmode, "_U_Qfmin");
+   set_optab_libfunc (smax_optab, TFmode, "_U_Qfmax");
+   set_optab_libfunc (abs_optab, TFmode, "_U_Qfabs");
+ 
+   /* ia64_expand_compare uses this.  */
+   cmptf_libfunc = init_one_libfunc ("_U_Qfcmp");
+ 
+   /* These should never be used.  */
+   set_optab_libfunc (eq_optab, TFmode, 0);
+   set_optab_libfunc (ne_optab, TFmode, 0);
+   set_optab_libfunc (gt_optab, TFmode, 0);
+   set_optab_libfunc (ge_optab, TFmode, 0);
+   set_optab_libfunc (lt_optab, TFmode, 0);
+   set_optab_libfunc (le_optab, TFmode, 0);
+ }
+ 
+ /* Rename the division and modulus functions in VMS.  */
+ 
+ static void
+ ia64_vms_init_libfuncs (void)
+ {
+   set_optab_libfunc (sdiv_optab, SImode, "OTS$DIV_I");
+   set_optab_libfunc (sdiv_optab, DImode, "OTS$DIV_L");
+   set_optab_libfunc (udiv_optab, SImode, "OTS$DIV_UI");
+   set_optab_libfunc (udiv_optab, DImode, "OTS$DIV_UL");
+   set_optab_libfunc (smod_optab, SImode, "OTS$REM_I");
+   set_optab_libfunc (smod_optab, DImode, "OTS$REM_L");
+   set_optab_libfunc (umod_optab, SImode, "OTS$REM_UI");
+   set_optab_libfunc (umod_optab, DImode, "OTS$REM_UL");
+ #ifdef MEM_LIBFUNCS_INIT
+   MEM_LIBFUNCS_INIT;
+ #endif
+ }
+ 
+ /* Rename the TFmode libfuncs available from soft-fp in glibc using
+    the HPUX conventions.  */
+ 
+ static void
+ ia64_sysv4_init_libfuncs (void)
+ {
+   ia64_init_libfuncs ();
+ 
+   /* These functions are not part of the HPUX TFmode interface.  We
+      use them instead of _U_Qfcmp, which doesn't work the way we
+      expect.  */
+   set_optab_libfunc (eq_optab, TFmode, "_U_Qfeq");
+   set_optab_libfunc (ne_optab, TFmode, "_U_Qfne");
+   set_optab_libfunc (gt_optab, TFmode, "_U_Qfgt");
+   set_optab_libfunc (ge_optab, TFmode, "_U_Qfge");
+   set_optab_libfunc (lt_optab, TFmode, "_U_Qflt");
+   set_optab_libfunc (le_optab, TFmode, "_U_Qfle");
+ 
+   /* We leave out _U_Qfmin, _U_Qfmax and _U_Qfabs since soft-fp in
+      glibc doesn't have them.  */
+ }
+ 
+ /* Use soft-fp.  */
+ 
+ static void
+ ia64_soft_fp_init_libfuncs (void)
+ {
+ }
+ 
+ static bool
+ ia64_vms_valid_pointer_mode (scalar_int_mode mode)
+ {
+   return (mode == SImode || mode == DImode);
+ }
+ \f
+ /* For HPUX, it is illegal to have relocations in shared segments.  */
+ 
+ static int
+ ia64_hpux_reloc_rw_mask (void)
+ {
+   return 3;
+ }
+ 
+ /* For others, relax this so that relocations to local data goes in
+    read-only segments, but we still cannot allow global relocations
+    in read-only segments.  */
+ 
+ static int
+ ia64_reloc_rw_mask (void)
+ {
+   return flag_pic ? 3 : 2;
+ }
+ 
+ /* Return the section to use for X.  The only special thing we do here
+    is to honor small data.  */
+ 
+ static section *
+ ia64_select_rtx_section (machine_mode mode, rtx x,
+ 			 unsigned HOST_WIDE_INT align)
+ {
+   if (GET_MODE_SIZE (mode) > 0
+       && GET_MODE_SIZE (mode) <= ia64_section_threshold
+       && !TARGET_NO_SDATA)
+     return sdata_section;
+   else
+     return default_elf_select_rtx_section (mode, x, align);
+ }
+ 
+ static unsigned int
+ ia64_section_type_flags (tree decl, const char *name, int reloc)
+ {
+   unsigned int flags = 0;
+ 
+   if (strcmp (name, ".sdata") == 0
+       || startswith (name, ".sdata.")
+       || startswith (name, ".gnu.linkonce.s.")
+       || startswith (name, ".sdata2.")
+       || startswith (name, ".gnu.linkonce.s2.")
+       || strcmp (name, ".sbss") == 0
+       || startswith (name, ".sbss.")
+       || startswith (name, ".gnu.linkonce.sb."))
+     flags = SECTION_SMALL;
+ 
+   flags |= default_section_type_flags (decl, name, reloc);
+   return flags;
+ }
+ 
+ /* Returns true if FNTYPE (a FUNCTION_TYPE or a METHOD_TYPE) returns a
+    structure type and that the address of that type should be passed
+    in out0, rather than in r8.  */
+ 
+ static bool
+ ia64_struct_retval_addr_is_first_parm_p (tree fntype)
+ {
+   tree ret_type = TREE_TYPE (fntype);
+ 
+   /* The Itanium C++ ABI requires that out0, rather than r8, be used
+      as the structure return address parameter, if the return value
+      type has a non-trivial copy constructor or destructor.  It is not
+      clear if this same convention should be used for other
+      programming languages.  Until G++ 3.4, we incorrectly used r8 for
+      these return values.  */
+   return (abi_version_at_least (2)
+ 	  && ret_type
+ 	  && TYPE_MODE (ret_type) == BLKmode 
+ 	  && TREE_ADDRESSABLE (ret_type)
+ 	  && lang_GNU_CXX ());
+ }
+ 
+ /* Output the assembler code for a thunk function.  THUNK_DECL is the
+    declaration for the thunk function itself, FUNCTION is the decl for
+    the target function.  DELTA is an immediate constant offset to be
+    added to THIS.  If VCALL_OFFSET is nonzero, the word at
+    *(*this + vcall_offset) should be added to THIS.  */
+ 
+ static void
+ ia64_output_mi_thunk (FILE *file, tree thunk ATTRIBUTE_UNUSED,
+ 		      HOST_WIDE_INT delta, HOST_WIDE_INT vcall_offset,
+ 		      tree function)
+ {
+   const char *fnname = IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (thunk));
+   rtx this_rtx, funexp;
+   rtx_insn *insn;
+   unsigned int this_parmno;
+   unsigned int this_regno;
+   rtx delta_rtx;
+ 
+   reload_completed = 1;
+   epilogue_completed = 1;
+ 
+   /* Set things up as ia64_expand_prologue might.  */
+   last_scratch_gr_reg = 15;
+ 
+   memset (&current_frame_info, 0, sizeof (current_frame_info));
+   current_frame_info.spill_cfa_off = -16;
+   current_frame_info.n_input_regs = 1;
+   current_frame_info.need_regstk = (TARGET_REG_NAMES != 0);
+ 
+   /* Mark the end of the (empty) prologue.  */
+   emit_note (NOTE_INSN_PROLOGUE_END);
+ 
+   /* Figure out whether "this" will be the first parameter (the
+      typical case) or the second parameter (as happens when the
+      virtual function returns certain class objects).  */
+   this_parmno
+     = (ia64_struct_retval_addr_is_first_parm_p (TREE_TYPE (thunk))
+        ? 1 : 0);
+   this_regno = IN_REG (this_parmno);
+   if (!TARGET_REG_NAMES)
+     reg_names[this_regno] = ia64_reg_numbers[this_parmno];
+ 
+   this_rtx = gen_rtx_REG (Pmode, this_regno);
+ 
+   /* Apply the constant offset, if required.  */
+   delta_rtx = GEN_INT (delta);
+   if (TARGET_ILP32)
+     {
+       rtx tmp = gen_rtx_REG (ptr_mode, this_regno);
+       REG_POINTER (tmp) = 1;
+       if (delta && satisfies_constraint_I (delta_rtx))
+ 	{
+ 	  emit_insn (gen_ptr_extend_plus_imm (this_rtx, tmp, delta_rtx));
+ 	  delta = 0;
+ 	}
+       else
+ 	emit_insn (gen_ptr_extend (this_rtx, tmp));
+     }
+   if (delta)
+     {
+       if (!satisfies_constraint_I (delta_rtx))
+ 	{
+ 	  rtx tmp = gen_rtx_REG (Pmode, 2);
+ 	  emit_move_insn (tmp, delta_rtx);
+ 	  delta_rtx = tmp;
+ 	}
+       emit_insn (gen_adddi3 (this_rtx, this_rtx, delta_rtx));
+     }
+ 
+   /* Apply the offset from the vtable, if required.  */
+   if (vcall_offset)
+     {
+       rtx vcall_offset_rtx = GEN_INT (vcall_offset);
+       rtx tmp = gen_rtx_REG (Pmode, 2);
+ 
+       if (TARGET_ILP32)
+ 	{
+ 	  rtx t = gen_rtx_REG (ptr_mode, 2);
+ 	  REG_POINTER (t) = 1;
+ 	  emit_move_insn (t, gen_rtx_MEM (ptr_mode, this_rtx));
+ 	  if (satisfies_constraint_I (vcall_offset_rtx))
+ 	    {
+ 	      emit_insn (gen_ptr_extend_plus_imm (tmp, t, vcall_offset_rtx));
+ 	      vcall_offset = 0;
+ 	    }
+ 	  else
+ 	    emit_insn (gen_ptr_extend (tmp, t));
+ 	}
+       else
+ 	emit_move_insn (tmp, gen_rtx_MEM (Pmode, this_rtx));
+ 
+       if (vcall_offset)
+ 	{
+ 	  if (!satisfies_constraint_J (vcall_offset_rtx))
+ 	    {
+ 	      rtx tmp2 = gen_rtx_REG (Pmode, next_scratch_gr_reg ());
+ 	      emit_move_insn (tmp2, vcall_offset_rtx);
+ 	      vcall_offset_rtx = tmp2;
+ 	    }
+ 	  emit_insn (gen_adddi3 (tmp, tmp, vcall_offset_rtx));
+ 	}
+ 
+       if (TARGET_ILP32)
+ 	emit_insn (gen_zero_extendsidi2 (tmp, gen_rtx_MEM (ptr_mode, tmp)));
+       else
+ 	emit_move_insn (tmp, gen_rtx_MEM (Pmode, tmp));
+ 
+       emit_insn (gen_adddi3 (this_rtx, this_rtx, tmp));
+     }
+ 
+   /* Generate a tail call to the target function.  */
+   if (! TREE_USED (function))
+     {
+       assemble_external (function);
+       TREE_USED (function) = 1;
+     }
+   funexp = XEXP (DECL_RTL (function), 0);
+   funexp = gen_rtx_MEM (FUNCTION_MODE, funexp);
+   ia64_expand_call (NULL_RTX, funexp, NULL_RTX, 1);
+   insn = get_last_insn ();
+   SIBLING_CALL_P (insn) = 1;
+ 
+   /* Code generation for calls relies on splitting.  */
+   reload_completed = 1;
+   epilogue_completed = 1;
+   try_split (PATTERN (insn), insn, 0);
+ 
+   emit_barrier ();
+ 
+   /* Run just enough of rest_of_compilation to get the insns emitted.
+      There's not really enough bulk here to make other passes such as
+      instruction scheduling worth while.  */
+ 
+   emit_all_insn_group_barriers (NULL);
+   insn = get_insns ();
+   shorten_branches (insn);
+   assemble_start_function (thunk, fnname);
+   final_start_function (insn, file, 1);
+   final (insn, file, 1);
+   final_end_function ();
+   assemble_end_function (thunk, fnname);
+ 
+   reload_completed = 0;
+   epilogue_completed = 0;
+ }
+ 
+ /* Worker function for TARGET_STRUCT_VALUE_RTX.  */
+ 
+ static rtx
+ ia64_struct_value_rtx (tree fntype,
+ 		       int incoming ATTRIBUTE_UNUSED)
+ {
+   if (TARGET_ABI_OPEN_VMS ||
+       (fntype && ia64_struct_retval_addr_is_first_parm_p (fntype)))
+     return NULL_RTX;
+   return gen_rtx_REG (Pmode, GR_REG (8));
+ }
+ 
+ static bool
+ ia64_scalar_mode_supported_p (scalar_mode mode)
+ {
+   switch (mode)
+     {
+     case E_QImode:
+     case E_HImode:
+     case E_SImode:
+     case E_DImode:
+     case E_TImode:
+       return true;
+ 
+     case E_SFmode:
+     case E_DFmode:
+     case E_XFmode:
+     case E_RFmode:
+       return true;
+ 
+     case E_TFmode:
+       return true;
+ 
+     default:
+       return false;
+     }
+ }
+ 
+ static bool
+ ia64_vector_mode_supported_p (machine_mode mode)
+ {
+   switch (mode)
+     {
+     case E_V8QImode:
+     case E_V4HImode:
+     case E_V2SImode:
+       return true;
+ 
+     case E_V2SFmode:
+       return true;
+ 
+     default:
+       return false;
+     }
+ }
+ 
+ /* Implement the FUNCTION_PROFILER macro.  */
+ 
+ void
+ ia64_output_function_profiler (FILE *file, int labelno)
+ {
+   bool indirect_call;
+ 
+   /* If the function needs a static chain and the static chain
+      register is r15, we use an indirect call so as to bypass
+      the PLT stub in case the executable is dynamically linked,
+      because the stub clobbers r15 as per 5.3.6 of the psABI.
+      We don't need to do that in non canonical PIC mode.  */
+ 
+   if (cfun->static_chain_decl && !TARGET_NO_PIC && !TARGET_AUTO_PIC)
+     {
+       gcc_assert (STATIC_CHAIN_REGNUM == 15);
+       indirect_call = true;
+     }
+   else
+     indirect_call = false;
+ 
+   if (TARGET_GNU_AS)
+     fputs ("\t.prologue 4, r40\n", file);
+   else
+     fputs ("\t.prologue\n\t.save ar.pfs, r40\n", file);
+   fputs ("\talloc out0 = ar.pfs, 8, 0, 4, 0\n", file);
+ 
+   if (NO_PROFILE_COUNTERS)
+     fputs ("\tmov out3 = r0\n", file);
+   else
+     {
+       char buf[20];
+       ASM_GENERATE_INTERNAL_LABEL (buf, "LP", labelno);
+ 
+       if (TARGET_AUTO_PIC)
+ 	fputs ("\tmovl out3 = @gprel(", file);
+       else
+ 	fputs ("\taddl out3 = @ltoff(", file);
+       assemble_name (file, buf);
+       if (TARGET_AUTO_PIC)
+ 	fputs (")\n", file);
+       else
+ 	fputs ("), r1\n", file);
+     }
+ 
+   if (indirect_call)
+     fputs ("\taddl r14 = @ltoff(@fptr(_mcount)), r1\n", file);
+   fputs ("\t;;\n", file);
+ 
+   fputs ("\t.save rp, r42\n", file);
+   fputs ("\tmov out2 = b0\n", file);
+   if (indirect_call)
+     fputs ("\tld8 r14 = [r14]\n\t;;\n", file);
+   fputs ("\t.body\n", file);
+   fputs ("\tmov out1 = r1\n", file);
+   if (indirect_call)
+     {
+       fputs ("\tld8 r16 = [r14], 8\n\t;;\n", file);
+       fputs ("\tmov b6 = r16\n", file);
+       fputs ("\tld8 r1 = [r14]\n", file);
+       fputs ("\tbr.call.sptk.many b0 = b6\n\t;;\n", file);
+     }
+   else
+     fputs ("\tbr.call.sptk.many b0 = _mcount\n\t;;\n", file);
+ }
+ 
+ static GTY(()) rtx mcount_func_rtx;
+ static rtx
+ gen_mcount_func_rtx (void)
+ {
+   if (!mcount_func_rtx)
+     mcount_func_rtx = init_one_libfunc ("_mcount");
+   return mcount_func_rtx;
+ }
+ 
+ void
+ ia64_profile_hook (int labelno)
+ {
+   rtx label, ip;
+ 
+   if (NO_PROFILE_COUNTERS)
+     label = const0_rtx;
+   else
+     {
+       char buf[30];
+       const char *label_name;
+       ASM_GENERATE_INTERNAL_LABEL (buf, "LP", labelno);
+       label_name = ggc_strdup ((*targetm.strip_name_encoding) (buf));
+       label = gen_rtx_SYMBOL_REF (Pmode, label_name);
+       SYMBOL_REF_FLAGS (label) = SYMBOL_FLAG_LOCAL;
+     }
+   ip = gen_reg_rtx (Pmode);
+   emit_insn (gen_ip_value (ip));
+   emit_library_call (gen_mcount_func_rtx (), LCT_NORMAL,
+                      VOIDmode,
+ 		     gen_rtx_REG (Pmode, BR_REG (0)), Pmode,
+ 		     ip, Pmode,
+ 		     label, Pmode);
+ }
+ 
+ /* Return the mangling of TYPE if it is an extended fundamental type.  */
+ 
+ static const char *
+ ia64_mangle_type (const_tree type)
+ {
+   type = TYPE_MAIN_VARIANT (type);
+ 
+   if (TREE_CODE (type) != VOID_TYPE && TREE_CODE (type) != BOOLEAN_TYPE
+       && TREE_CODE (type) != INTEGER_TYPE && TREE_CODE (type) != REAL_TYPE)
+     return NULL;
+ 
+   /* On HP-UX, "long double" is mangled as "e" so __float128 is
+      mangled as "e".  */
+   if (!TARGET_HPUX && TYPE_MODE (type) == TFmode)
+     return "g";
+   /* On HP-UX, "e" is not available as a mangling of __float80 so use
+      an extended mangling.  Elsewhere, "e" is available since long
+      double is 80 bits.  */
+   if (TYPE_MODE (type) == XFmode)
+     return TARGET_HPUX ? "u9__float80" : "e";
+   if (TYPE_MODE (type) == RFmode)
+     return "u7__fpreg";
+   return NULL;
+ }
+ 
+ /* Return the diagnostic message string if conversion from FROMTYPE to
+    TOTYPE is not allowed, NULL otherwise.  */
+ static const char *
+ ia64_invalid_conversion (const_tree fromtype, const_tree totype)
+ {
+   /* Reject nontrivial conversion to or from __fpreg.  */
+   if (TYPE_MODE (fromtype) == RFmode
+       && TYPE_MODE (totype) != RFmode
+       && TYPE_MODE (totype) != VOIDmode)
+     return N_("invalid conversion from %<__fpreg%>");
+   if (TYPE_MODE (totype) == RFmode
+       && TYPE_MODE (fromtype) != RFmode)
+     return N_("invalid conversion to %<__fpreg%>");
+   return NULL;
+ }
+ 
+ /* Return the diagnostic message string if the unary operation OP is
+    not permitted on TYPE, NULL otherwise.  */
+ static const char *
+ ia64_invalid_unary_op (int op, const_tree type)
+ {
+   /* Reject operations on __fpreg other than unary + or &.  */
+   if (TYPE_MODE (type) == RFmode
+       && op != CONVERT_EXPR
+       && op != ADDR_EXPR)
+     return N_("invalid operation on %<__fpreg%>");
+   return NULL;
+ }
+ 
+ /* Return the diagnostic message string if the binary operation OP is
+    not permitted on TYPE1 and TYPE2, NULL otherwise.  */
+ static const char *
+ ia64_invalid_binary_op (int op ATTRIBUTE_UNUSED, const_tree type1, const_tree type2)
+ {
+   /* Reject operations on __fpreg.  */
+   if (TYPE_MODE (type1) == RFmode || TYPE_MODE (type2) == RFmode)
+     return N_("invalid operation on %<__fpreg%>");
+   return NULL;
+ }
+ 
+ /* HP-UX version_id attribute.
+    For object foo, if the version_id is set to 1234 put out an alias
+    of '.alias foo "foo{1234}"  We can't use "foo{1234}" in anything
+    other than an alias statement because it is an illegal symbol name.  */
+ 
+ static tree
+ ia64_handle_version_id_attribute (tree *node ATTRIBUTE_UNUSED,
+                                  tree name ATTRIBUTE_UNUSED,
+                                  tree args,
+                                  int flags ATTRIBUTE_UNUSED,
+                                  bool *no_add_attrs)
+ {
+   tree arg = TREE_VALUE (args);
+ 
+   if (TREE_CODE (arg) != STRING_CST)
+     {
+       error("version attribute is not a string");
+       *no_add_attrs = true;
+       return NULL_TREE;
+     }
+   return NULL_TREE;
+ }
+ 
+ /* Target hook for c_mode_for_suffix.  */
+ 
+ static machine_mode
+ ia64_c_mode_for_suffix (char suffix)
+ {
+   if (suffix == 'q')
+     return TFmode;
+   if (suffix == 'w')
+     return XFmode;
+ 
+   return VOIDmode;
+ }
+ 
+ static GTY(()) rtx ia64_dconst_0_5_rtx;
+ 
+ rtx
+ ia64_dconst_0_5 (void)
+ {
+   if (! ia64_dconst_0_5_rtx)
+     {
+       REAL_VALUE_TYPE rv;
+       real_from_string (&rv, "0.5");
+       ia64_dconst_0_5_rtx = const_double_from_real_value (rv, DFmode);
+     }
+   return ia64_dconst_0_5_rtx;
+ }
+ 
+ static GTY(()) rtx ia64_dconst_0_375_rtx;
+ 
+ rtx
+ ia64_dconst_0_375 (void)
+ {
+   if (! ia64_dconst_0_375_rtx)
+     {
+       REAL_VALUE_TYPE rv;
+       real_from_string (&rv, "0.375");
+       ia64_dconst_0_375_rtx = const_double_from_real_value (rv, DFmode);
+     }
+   return ia64_dconst_0_375_rtx;
+ }
+ 
+ static fixed_size_mode
+ ia64_get_reg_raw_mode (int regno)
+ {
+   if (FR_REGNO_P (regno))
+     return XFmode;
+   return default_get_reg_raw_mode(regno);
+ }
+ 
+ /* Implement TARGET_MEMBER_TYPE_FORCES_BLK.  ??? Might not be needed
+    anymore.  */
+ 
+ bool
+ ia64_member_type_forces_blk (const_tree, machine_mode mode)
+ {
+   return TARGET_HPUX && mode == TFmode;
+ }
+ 
+ /* Always default to .text section until HP-UX linker is fixed.  */
+ 
+ ATTRIBUTE_UNUSED static section *
+ ia64_hpux_function_section (tree decl ATTRIBUTE_UNUSED,
+ 			    enum node_frequency freq ATTRIBUTE_UNUSED,
+ 			    bool startup ATTRIBUTE_UNUSED,
+ 			    bool exit ATTRIBUTE_UNUSED)
+ {
+   return NULL;
+ }
+ \f
+ /* Construct (set target (vec_select op0 (parallel perm))) and
+    return true if that's a valid instruction in the active ISA.  */
+ 
+ static bool
+ expand_vselect (rtx target, rtx op0, const unsigned char *perm, unsigned nelt)
+ {
+   rtx rperm[MAX_VECT_LEN], x;
+   unsigned i;
+ 
+   for (i = 0; i < nelt; ++i)
+     rperm[i] = GEN_INT (perm[i]);
+ 
+   x = gen_rtx_PARALLEL (VOIDmode, gen_rtvec_v (nelt, rperm));
+   x = gen_rtx_VEC_SELECT (GET_MODE (target), op0, x);
+   x = gen_rtx_SET (target, x);
+ 
+   rtx_insn *insn = emit_insn (x);
+   if (recog_memoized (insn) < 0)
+     {
+       remove_insn (insn);
+       return false;
+     }
+   return true;
+ }
+ 
+ /* Similar, but generate a vec_concat from op0 and op1 as well.  */
+ 
+ static bool
+ expand_vselect_vconcat (rtx target, rtx op0, rtx op1,
+ 			const unsigned char *perm, unsigned nelt)
+ {
+   machine_mode v2mode;
+   rtx x;
+ 
+   if (!GET_MODE_2XWIDER_MODE (GET_MODE (op0)).exists (&v2mode))
+     return false;
+   x = gen_rtx_VEC_CONCAT (v2mode, op0, op1);
+   return expand_vselect (target, x, perm, nelt);
+ }
+ 
+ /* Try to expand a no-op permutation.  */
+ 
+ static bool
+ expand_vec_perm_identity (struct expand_vec_perm_d *d)
+ {
+   unsigned i, nelt = d->nelt;
+ 
+   for (i = 0; i < nelt; ++i)
+     if (d->perm[i] != i)
+       return false;
+ 
+   if (!d->testing_p)
+     emit_move_insn (d->target, d->op0);
+ 
+   return true;
+ }
+ 
+ /* Try to expand D via a shrp instruction.  */
+ 
+ static bool
+ expand_vec_perm_shrp (struct expand_vec_perm_d *d)
+ {
+   unsigned i, nelt = d->nelt, shift, mask;
+   rtx tmp, hi, lo;
+ 
+   /* ??? Don't force V2SFmode into the integer registers.  */
+   if (d->vmode == V2SFmode)
+     return false;
+ 
+   mask = (d->one_operand_p ? nelt - 1 : 2 * nelt - 1);
+ 
+   shift = d->perm[0];
+   if (BYTES_BIG_ENDIAN && shift > nelt)
+     return false;
+ 
+   for (i = 1; i < nelt; ++i)
+     if (d->perm[i] != ((shift + i) & mask))
+       return false;
+ 
+   if (d->testing_p)
+     return true;
+ 
+   hi = shift < nelt ? d->op1 : d->op0;
+   lo = shift < nelt ? d->op0 : d->op1;
+ 
+   shift %= nelt;
+ 
+   shift *= GET_MODE_UNIT_SIZE (d->vmode) * BITS_PER_UNIT;
+ 
+   /* We've eliminated the shift 0 case via expand_vec_perm_identity.  */
+   gcc_assert (IN_RANGE (shift, 1, 63));
+ 
+   /* Recall that big-endian elements are numbered starting at the top of
+      the register.  Ideally we'd have a shift-left-pair.  But since we
+      don't, convert to a shift the other direction.  */
+   if (BYTES_BIG_ENDIAN)
+     shift = 64 - shift;
+ 
+   tmp = gen_reg_rtx (DImode);
+   hi = gen_lowpart (DImode, hi);
+   lo = gen_lowpart (DImode, lo);
+   emit_insn (gen_shrp (tmp, hi, lo, GEN_INT (shift)));
+ 
+   emit_move_insn (d->target, gen_lowpart (d->vmode, tmp));
+   return true;
+ }
+ 
+ /* Try to instantiate D in a single instruction.  */
+ 
+ static bool
+ expand_vec_perm_1 (struct expand_vec_perm_d *d)
+ {     
+   unsigned i, nelt = d->nelt;
+   unsigned char perm2[MAX_VECT_LEN];
+ 
+   /* Try single-operand selections.  */
+   if (d->one_operand_p)
+     {
+       if (expand_vec_perm_identity (d))
+ 	return true;
+       if (expand_vselect (d->target, d->op0, d->perm, nelt))
+ 	return true;
+     }
+ 
+   /* Try two operand selections.  */
+   if (expand_vselect_vconcat (d->target, d->op0, d->op1, d->perm, nelt))
+     return true;
+ 
+   /* Recognize interleave style patterns with reversed operands.  */
+   if (!d->one_operand_p)
+     {
+       for (i = 0; i < nelt; ++i)
+ 	{
+ 	  unsigned e = d->perm[i];
+ 	  if (e >= nelt)
+ 	    e -= nelt;
+ 	  else
+ 	    e += nelt;
+ 	  perm2[i] = e;
+ 	}
+ 
+       if (expand_vselect_vconcat (d->target, d->op1, d->op0, perm2, nelt))
+ 	return true;
+     }
+ 
+   if (expand_vec_perm_shrp (d))
+     return true;
+ 
+   /* ??? Look for deposit-like permutations where most of the result 
+      comes from one vector unchanged and the rest comes from a 
+      sequential hunk of the other vector.  */
+ 
+   return false;
+ }
+ 
+ /* Pattern match broadcast permutations.  */
+ 
+ static bool
+ expand_vec_perm_broadcast (struct expand_vec_perm_d *d)
+ {
+   unsigned i, elt, nelt = d->nelt;
+   unsigned char perm2[2];
+   rtx temp;
+   bool ok;
+ 
+   if (!d->one_operand_p)
+     return false;
+ 
+   elt = d->perm[0];
+   for (i = 1; i < nelt; ++i)
+     if (d->perm[i] != elt)
+       return false;
+ 
+   switch (d->vmode)
+     {
+     case E_V2SImode:
+     case E_V2SFmode:
+       /* Implementable by interleave.  */
+       perm2[0] = elt;
+       perm2[1] = elt + 2;
+       ok = expand_vselect_vconcat (d->target, d->op0, d->op0, perm2, 2);
+       gcc_assert (ok);
+       break;
+ 
+     case E_V8QImode:
+       /* Implementable by extract + broadcast.  */
+       if (BYTES_BIG_ENDIAN)
+ 	elt = 7 - elt;
+       elt *= BITS_PER_UNIT;
+       temp = gen_reg_rtx (DImode);
+       emit_insn (gen_extzv (temp, gen_lowpart (DImode, d->op0),
+ 			    GEN_INT (8), GEN_INT (elt)));
+       emit_insn (gen_mux1_brcst_qi (d->target, gen_lowpart (QImode, temp)));
+       break;
+ 
+     case E_V4HImode:
+       /* Should have been matched directly by vec_select.  */
+     default:
+       gcc_unreachable ();
+     }
+ 
+   return true;
+ }
+ 
+ /* A subroutine of ia64_expand_vec_perm_const_1.  Try to simplify a
+    two vector permutation into a single vector permutation by using
+    an interleave operation to merge the vectors.  */
+ 
+ static bool
+ expand_vec_perm_interleave_2 (struct expand_vec_perm_d *d)
+ {
+   struct expand_vec_perm_d dremap, dfinal;
+   unsigned char remap[2 * MAX_VECT_LEN];
+   unsigned contents, i, nelt, nelt2;
+   unsigned h0, h1, h2, h3;
+   rtx_insn *seq;
+   bool ok;
+ 
+   if (d->one_operand_p)
+     return false;
+ 
+   nelt = d->nelt;
+   nelt2 = nelt / 2;
+ 
+   /* Examine from whence the elements come.  */
+   contents = 0;
+   for (i = 0; i < nelt; ++i)
+     contents |= 1u << d->perm[i];
+ 
+   memset (remap, 0xff, sizeof (remap));
+   dremap = *d;
+ 
+   h0 = (1u << nelt2) - 1;
+   h1 = h0 << nelt2;
+   h2 = h0 << nelt;
+   h3 = h0 << (nelt + nelt2);
+   
+   if ((contents & (h0 | h2)) == contents)	/* punpck even halves */
+     {
+       for (i = 0; i < nelt; ++i)
+ 	{
+ 	  unsigned which = i / 2 + (i & 1 ? nelt : 0);
+ 	  remap[which] = i;
+ 	  dremap.perm[i] = which;
+ 	}
+     }
+   else if ((contents & (h1 | h3)) == contents)	/* punpck odd halves */
+     {
+       for (i = 0; i < nelt; ++i)
+ 	{
+ 	  unsigned which = i / 2 + nelt2 + (i & 1 ? nelt : 0);
+ 	  remap[which] = i;
+ 	  dremap.perm[i] = which;
+ 	}
+     }
+   else if ((contents & 0x5555) == contents)	/* mix even elements */
+     {
+       for (i = 0; i < nelt; ++i)
+ 	{
+ 	  unsigned which = (i & ~1) + (i & 1 ? nelt : 0);
+ 	  remap[which] = i;
+ 	  dremap.perm[i] = which;
+ 	}
+     }
+   else if ((contents & 0xaaaa) == contents)	/* mix odd elements */
+     {
+       for (i = 0; i < nelt; ++i)
+ 	{
+ 	  unsigned which = (i | 1) + (i & 1 ? nelt : 0);
+ 	  remap[which] = i;
+ 	  dremap.perm[i] = which;
+ 	}
+     }
+   else if (floor_log2 (contents) - ctz_hwi (contents) < (int)nelt) /* shrp */
+     {
+       unsigned shift = ctz_hwi (contents);
+       for (i = 0; i < nelt; ++i)
+ 	{
+ 	  unsigned which = (i + shift) & (2 * nelt - 1);
+ 	  remap[which] = i;
+ 	  dremap.perm[i] = which;
+ 	}
+     }
+   else
+     return false;
+ 
+   /* Use the remapping array set up above to move the elements from their
+      swizzled locations into their final destinations.  */
+   dfinal = *d;
+   for (i = 0; i < nelt; ++i)
+     {
+       unsigned e = remap[d->perm[i]];
+       gcc_assert (e < nelt);
+       dfinal.perm[i] = e;
+     }
+   if (d->testing_p)
+     dfinal.op0 = gen_raw_REG (dfinal.vmode, LAST_VIRTUAL_REGISTER + 1);
+   else
+     dfinal.op0 = gen_reg_rtx (dfinal.vmode);
+   dfinal.op1 = dfinal.op0;
+   dfinal.one_operand_p = true;
+   dremap.target = dfinal.op0;
+ 
+   /* Test if the final remap can be done with a single insn.  For V4HImode
+      this *will* succeed.  For V8QImode or V2SImode it may not.  */
+   start_sequence ();
+   ok = expand_vec_perm_1 (&dfinal);
+   seq = get_insns ();
+   end_sequence ();
+   if (!ok)
+     return false;
+   if (d->testing_p)
+     return true;
+ 
+   ok = expand_vec_perm_1 (&dremap);
+   gcc_assert (ok);
+ 
+   emit_insn (seq);
+   return true;
+ }
+ 
+ /* A subroutine of ia64_expand_vec_perm_const_1.  Emit a full V4HImode
+    constant permutation via two mux2 and a merge.  */
+ 
+ static bool
+ expand_vec_perm_v4hi_5 (struct expand_vec_perm_d *d)
+ {
+   unsigned char perm2[4];
+   rtx rmask[4];
+   unsigned i;
+   rtx t0, t1, mask, x;
+   bool ok;
+ 
+   if (d->vmode != V4HImode || d->one_operand_p)
+     return false;
+   if (d->testing_p)
+     return true;
+ 
+   for (i = 0; i < 4; ++i)
+     {
+       perm2[i] = d->perm[i] & 3;
+       rmask[i] = (d->perm[i] & 4 ? const0_rtx : constm1_rtx);
+     }
+   mask = gen_rtx_CONST_VECTOR (V4HImode, gen_rtvec_v (4, rmask));
+   mask = force_reg (V4HImode, mask);
+ 
+   t0 = gen_reg_rtx (V4HImode);
+   t1 = gen_reg_rtx (V4HImode);
+ 
+   ok = expand_vselect (t0, d->op0, perm2, 4);
+   gcc_assert (ok);
+   ok = expand_vselect (t1, d->op1, perm2, 4);
+   gcc_assert (ok);
+ 
+   x = gen_rtx_AND (V4HImode, mask, t0);
+   emit_insn (gen_rtx_SET (t0, x));
+ 
+   x = gen_rtx_NOT (V4HImode, mask);
+   x = gen_rtx_AND (V4HImode, x, t1);
+   emit_insn (gen_rtx_SET (t1, x));
+ 
+   x = gen_rtx_IOR (V4HImode, t0, t1);
+   emit_insn (gen_rtx_SET (d->target, x));
+ 
+   return true;
+ }
+ 
+ /* The guts of ia64_expand_vec_perm_const, also used by the ok hook.
+    With all of the interface bits taken care of, perform the expansion
+    in D and return true on success.  */
+ 
+ static bool
+ ia64_expand_vec_perm_const_1 (struct expand_vec_perm_d *d)
+ {
+   if (expand_vec_perm_1 (d))
+     return true;
+   if (expand_vec_perm_broadcast (d))
+     return true;
+   if (expand_vec_perm_interleave_2 (d))
+     return true;
+   if (expand_vec_perm_v4hi_5 (d))
+     return true;
+   return false;
+ }
+ 
+ /* Implement TARGET_VECTORIZE_VEC_PERM_CONST.  */
+ 
+ static bool
+ ia64_vectorize_vec_perm_const (machine_mode vmode, rtx target, rtx op0,
+ 			       rtx op1, const vec_perm_indices &sel)
+ {
+   struct expand_vec_perm_d d;
+   unsigned char perm[MAX_VECT_LEN];
+   unsigned int i, nelt, which;
+ 
+   d.target = target;
+   if (op0)
+     {
+       rtx nop0 = force_reg (vmode, op0);
+       if (op0 == op1)
+         op1 = nop0;
+       op0 = nop0;
+     }
+   if (op1)
+     op1 = force_reg (vmode, op1);
+   d.op0 = op0;
+   d.op1 = op1;
+ 
+   d.vmode = vmode;
+   gcc_assert (VECTOR_MODE_P (d.vmode));
+   d.nelt = nelt = GET_MODE_NUNITS (d.vmode);
+   d.testing_p = !target;
+ 
+   gcc_assert (sel.length () == nelt);
+   gcc_checking_assert (sizeof (d.perm) == sizeof (perm));
+ 
+   for (i = which = 0; i < nelt; ++i)
+     {
+       unsigned int ei = sel[i] & (2 * nelt - 1);
+ 
+       which |= (ei < nelt ? 1 : 2);
+       d.perm[i] = ei;
+       perm[i] = ei;
+     }
+ 
+   switch (which)
+     {
+     default:
+       gcc_unreachable();
+ 
+     case 3:
+       if (d.testing_p || !rtx_equal_p (d.op0, d.op1))
+ 	{
+ 	  d.one_operand_p = false;
+ 	  break;
+ 	}
+ 
+       /* The elements of PERM do not suggest that only the first operand
+ 	 is used, but both operands are identical.  Allow easier matching
+ 	 of the permutation by folding the permutation into the single
+ 	 input vector.  */
+       for (i = 0; i < nelt; ++i)
+ 	if (d.perm[i] >= nelt)
+ 	  d.perm[i] -= nelt;
+       /* FALLTHRU */
+ 
+     case 1:
+       d.op1 = d.op0;
+       d.one_operand_p = true;
+       break;
+ 
+     case 2:
+       for (i = 0; i < nelt; ++i)
+         d.perm[i] -= nelt;
+       d.op0 = d.op1;
+       d.one_operand_p = true;
+       break;
+     }
+ 
+   if (d.testing_p)
+     {
+       /* We have to go through the motions and see if we can
+ 	 figure out how to generate the requested permutation.  */
+       d.target = gen_raw_REG (d.vmode, LAST_VIRTUAL_REGISTER + 1);
+       d.op1 = d.op0 = gen_raw_REG (d.vmode, LAST_VIRTUAL_REGISTER + 2);
+       if (!d.one_operand_p)
+ 	d.op1 = gen_raw_REG (d.vmode, LAST_VIRTUAL_REGISTER + 3);
+ 
+       start_sequence ();
+       bool ret = ia64_expand_vec_perm_const_1 (&d);
+       end_sequence ();
+ 
+       return ret;
+     }
+ 
+   if (ia64_expand_vec_perm_const_1 (&d))
+     return true;
+ 
+   /* If the mask says both arguments are needed, but they are the same,
+      the above tried to expand with one_operand_p true.  If that didn't
+      work, retry with one_operand_p false, as that's what we used in _ok.  */
+   if (which == 3 && d.one_operand_p)
+     {
+       memcpy (d.perm, perm, sizeof (perm));
+       d.one_operand_p = false;
+       return ia64_expand_vec_perm_const_1 (&d);
+     }
+ 
+   return false;
+ }
+ 
+ void
+ ia64_expand_vec_setv2sf (rtx operands[3])
+ {
+   struct expand_vec_perm_d d;
+   unsigned int which;
+   bool ok;
+   
+   d.target = operands[0];
+   d.op0 = operands[0];
+   d.op1 = gen_reg_rtx (V2SFmode);
+   d.vmode = V2SFmode;
+   d.nelt = 2;
+   d.one_operand_p = false;
+   d.testing_p = false;
+ 
+   which = INTVAL (operands[2]);
+   gcc_assert (which <= 1);
+   d.perm[0] = 1 - which;
+   d.perm[1] = which + 2;
+ 
+   emit_insn (gen_fpack (d.op1, operands[1], CONST0_RTX (SFmode)));
+ 
+   ok = ia64_expand_vec_perm_const_1 (&d);
+   gcc_assert (ok);
+ }
+ 
+ void
+ ia64_expand_vec_perm_even_odd (rtx target, rtx op0, rtx op1, int odd)
+ {
+   struct expand_vec_perm_d d;
+   machine_mode vmode = GET_MODE (target);
+   unsigned int i, nelt = GET_MODE_NUNITS (vmode);
+   bool ok;
+ 
+   d.target = target;
+   d.op0 = op0;
+   d.op1 = op1;
+   d.vmode = vmode;
+   d.nelt = nelt;
+   d.one_operand_p = false;
+   d.testing_p = false;
+ 
+   for (i = 0; i < nelt; ++i)
+     d.perm[i] = i * 2 + odd;
+ 
+   ok = ia64_expand_vec_perm_const_1 (&d);
+   gcc_assert (ok);
+ }
+ 
+ /* Implement TARGET_CAN_CHANGE_MODE_CLASS.
+ 
+    In BR regs, we can't change the DImode at all.
+    In FP regs, we can't change FP values to integer values and vice versa,
+    but we can change e.g. DImode to SImode, and V2SFmode into DImode.  */
+ 
+ static bool
+ ia64_can_change_mode_class (machine_mode from, machine_mode to,
+ 			    reg_class_t rclass)
+ {
+   if (reg_classes_intersect_p (rclass, BR_REGS))
+     return from == to;
+   if (SCALAR_FLOAT_MODE_P (from) != SCALAR_FLOAT_MODE_P (to))
+     return !reg_classes_intersect_p (rclass, FR_REGS);
+   return true;
+ }
+ 
++static void
++ia64_linux_file_end (void)
++{
++  int saved_trampolines_created = trampolines_created;
++  trampolines_created = 0;
++  file_end_indicate_exec_stack ();
++  trampolines_created = saved_trampolines_created;
++}
++
+ #include "gt-ia64.h"
diff --cc gcc/config/rs6000/rs6000.cc
index 00000000000,7a4ef5e6c0a..3b21fdc8bb0
mode 000000,100644..100644
--- a/gcc/config/rs6000/rs6000.cc
+++ b/gcc/config/rs6000/rs6000.cc
@@@ -1,0 -1,28925 +1,28942 @@@
+ // SPDX-License-Identifier: GPL-3.0-or-later
+ /* Subroutines used for code generation on IBM RS/6000.
+    Copyright (C) 1991-2022 Free Software Foundation, Inc.
+    Contributed by Richard Kenner (kenner@vlsi1.ultra.nyu.edu)
+ 
+    This file is part of GCC.
+ 
+    GCC is free software; you can redistribute it and/or modify it
+    under the terms of the GNU General Public License as published
+    by the Free Software Foundation; either version 3, or (at your
+    option) any later version.
+ 
+    GCC is distributed in the hope that it will be useful, but WITHOUT
+    ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+    or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public
+    License for more details.
+ 
+    You should have received a copy of the GNU General Public License
+    along with GCC; see the file COPYING3.  If not see
+    <http://www.gnu.org/licenses/>.  */
+ 
+ #define IN_TARGET_CODE 1
+ 
+ #include "config.h"
+ #include "system.h"
+ #include "coretypes.h"
+ #include "backend.h"
+ #include "rtl.h"
+ #include "tree.h"
+ #include "memmodel.h"
+ #include "gimple.h"
+ #include "cfghooks.h"
+ #include "cfgloop.h"
+ #include "df.h"
+ #include "tm_p.h"
+ #include "stringpool.h"
+ #include "expmed.h"
+ #include "optabs.h"
+ #include "regs.h"
+ #include "ira.h"
+ #include "recog.h"
+ #include "cgraph.h"
+ #include "diagnostic-core.h"
+ #include "insn-attr.h"
+ #include "flags.h"
+ #include "alias.h"
+ #include "fold-const.h"
+ #include "attribs.h"
+ #include "stor-layout.h"
+ #include "calls.h"
+ #include "print-tree.h"
+ #include "varasm.h"
+ #include "explow.h"
+ #include "expr.h"
+ #include "output.h"
+ #include "common/common-target.h"
+ #include "langhooks.h"
+ #include "reload.h"
+ #include "sched-int.h"
+ #include "gimplify.h"
+ #include "gimple-fold.h"
+ #include "gimple-iterator.h"
+ #include "gimple-walk.h"
+ #include "ssa.h"
+ #include "tree-vectorizer.h"
+ #include "tree-ssa-propagate.h"
+ #include "intl.h"
+ #include "tm-constrs.h"
+ #include "target-globals.h"
+ #include "builtins.h"
+ #include "tree-vector-builder.h"
+ #include "context.h"
+ #include "tree-pass.h"
+ #include "symbol-summary.h"
+ #include "ipa-prop.h"
+ #include "ipa-fnsummary.h"
+ #include "except.h"
+ #if TARGET_XCOFF
+ #include "xcoffout.h"  /* get declarations of xcoff_*_section_name */
+ #endif
+ #include "case-cfn-macros.h"
+ #include "ppc-auxv.h"
+ #include "rs6000-internal.h"
+ #include "opts.h"
+ 
+ /* This file should be included last.  */
+ #include "target-def.h"
+ 
+   /* Set -mabi=ieeelongdouble on some old targets.  In the future, power server
+      systems will also set long double to be IEEE 128-bit.  AIX and Darwin
+      explicitly redefine TARGET_IEEEQUAD and TARGET_IEEEQUAD_DEFAULT to 0, so
+      those systems will not pick up this default.  This needs to be after all
+      of the include files, so that POWERPC_LINUX and POWERPC_FREEBSD are
+      properly defined.  */
+ #ifndef TARGET_IEEEQUAD_DEFAULT
+ #if !defined (POWERPC_LINUX) && !defined (POWERPC_FREEBSD)
+ #define TARGET_IEEEQUAD_DEFAULT 1
+ #else
+ #define TARGET_IEEEQUAD_DEFAULT 0
+ #endif
+ #endif
+ 
+ /* Don't enable PC-relative addressing if the target does not support it.  */
+ #ifndef PCREL_SUPPORTED_BY_OS
+ #define PCREL_SUPPORTED_BY_OS	0
+ #endif
+ 
+ /* Support targetm.vectorize.builtin_mask_for_load.  */
+ tree altivec_builtin_mask_for_load;
+ 
+ #ifdef USING_ELFOS_H
+ /* Counter for labels which are to be placed in .fixup.  */
+ int fixuplabelno = 0;
+ #endif
+ 
+ /* Whether to use variant of AIX ABI for PowerPC64 Linux.  */
+ int dot_symbols;
+ 
+ /* Specify the machine mode that pointers have.  After generation of rtl, the
+    compiler makes no further distinction between pointers and any other objects
+    of this machine mode.  */
+ scalar_int_mode rs6000_pmode;
+ 
+ #if TARGET_ELF
+ /* Note whether IEEE 128-bit floating point was passed or returned, either as
+    the __float128/_Float128 explicit type, or when long double is IEEE 128-bit
+    floating point.  We changed the default C++ mangling for these types and we
+    may want to generate a weak alias of the old mangling (U10__float128) to the
+    new mangling (u9__ieee128).  */
+ bool rs6000_passes_ieee128 = false;
+ #endif
+ 
+ /* Track use of r13 in 64bit AIX TLS.  */
+ static bool xcoff_tls_exec_model_detected = false;
+ 
+ /* Generate the manged name (i.e. U10__float128) used in GCC 8.1, and not the
+    name used in current releases (i.e. u9__ieee128).  */
+ static bool ieee128_mangling_gcc_8_1;
+ 
+ /* Width in bits of a pointer.  */
+ unsigned rs6000_pointer_size;
+ 
+ #ifdef HAVE_AS_GNU_ATTRIBUTE
+ # ifndef HAVE_LD_PPC_GNU_ATTR_LONG_DOUBLE
+ # define HAVE_LD_PPC_GNU_ATTR_LONG_DOUBLE 0
+ # endif
+ /* Flag whether floating point values have been passed/returned.
+    Note that this doesn't say whether fprs are used, since the
+    Tag_GNU_Power_ABI_FP .gnu.attributes value this flag controls
+    should be set for soft-float values passed in gprs and ieee128
+    values passed in vsx registers.  */
+ bool rs6000_passes_float = false;
+ bool rs6000_passes_long_double = false;
+ /* Flag whether vector values have been passed/returned.  */
+ bool rs6000_passes_vector = false;
+ /* Flag whether small (<= 8 byte) structures have been returned.  */
+ bool rs6000_returns_struct = false;
+ #endif
+ 
+ /* Value is TRUE if register/mode pair is acceptable.  */
+ static bool rs6000_hard_regno_mode_ok_p
+   [NUM_MACHINE_MODES][FIRST_PSEUDO_REGISTER];
+ 
+ /* Maximum number of registers needed for a given register class and mode.  */
+ unsigned char rs6000_class_max_nregs[NUM_MACHINE_MODES][LIM_REG_CLASSES];
+ 
+ /* How many registers are needed for a given register and mode.  */
+ unsigned char rs6000_hard_regno_nregs[NUM_MACHINE_MODES][FIRST_PSEUDO_REGISTER];
+ 
+ /* Map register number to register class.  */
+ enum reg_class rs6000_regno_regclass[FIRST_PSEUDO_REGISTER];
+ 
+ static int dbg_cost_ctrl;
+ 
+ /* Built in types.  */
+ tree rs6000_builtin_types[RS6000_BTI_MAX];
+ 
+ /* Flag to say the TOC is initialized */
+ int toc_initialized, need_toc_init;
+ char toc_label_name[10];
+ 
+ /* Cached value of rs6000_variable_issue. This is cached in
+    rs6000_variable_issue hook and returned from rs6000_sched_reorder2.  */
+ static short cached_can_issue_more;
+ 
+ static GTY(()) section *read_only_data_section;
+ static GTY(()) section *private_data_section;
+ static GTY(()) section *tls_data_section;
+ static GTY(()) section *tls_private_data_section;
+ static GTY(()) section *read_only_private_data_section;
+ static GTY(()) section *sdata2_section;
+ 
+ section *toc_section = 0;
+ 
+ /* Describe the vector unit used for modes.  */
+ enum rs6000_vector rs6000_vector_unit[NUM_MACHINE_MODES];
+ enum rs6000_vector rs6000_vector_mem[NUM_MACHINE_MODES];
+ 
+ /* Register classes for various constraints that are based on the target
+    switches.  */
+ enum reg_class rs6000_constraints[RS6000_CONSTRAINT_MAX];
+ 
+ /* Describe the alignment of a vector.  */
+ int rs6000_vector_align[NUM_MACHINE_MODES];
+ 
+ /* Map selected modes to types for builtins.  */
+ tree builtin_mode_to_type[MAX_MACHINE_MODE][2];
+ 
+ /* What modes to automatically generate reciprocal divide estimate (fre) and
+    reciprocal sqrt (frsqrte) for.  */
+ unsigned char rs6000_recip_bits[MAX_MACHINE_MODE];
+ 
+ /* Masks to determine which reciprocal esitmate instructions to generate
+    automatically.  */
+ enum rs6000_recip_mask {
+   RECIP_SF_DIV		= 0x001,	/* Use divide estimate */
+   RECIP_DF_DIV		= 0x002,
+   RECIP_V4SF_DIV	= 0x004,
+   RECIP_V2DF_DIV	= 0x008,
+ 
+   RECIP_SF_RSQRT	= 0x010,	/* Use reciprocal sqrt estimate.  */
+   RECIP_DF_RSQRT	= 0x020,
+   RECIP_V4SF_RSQRT	= 0x040,
+   RECIP_V2DF_RSQRT	= 0x080,
+ 
+   /* Various combination of flags for -mrecip=xxx.  */
+   RECIP_NONE		= 0,
+   RECIP_ALL		= (RECIP_SF_DIV | RECIP_DF_DIV | RECIP_V4SF_DIV
+ 			   | RECIP_V2DF_DIV | RECIP_SF_RSQRT | RECIP_DF_RSQRT
+ 			   | RECIP_V4SF_RSQRT | RECIP_V2DF_RSQRT),
+ 
+   RECIP_HIGH_PRECISION	= RECIP_ALL,
+ 
+   /* On low precision machines like the power5, don't enable double precision
+      reciprocal square root estimate, since it isn't accurate enough.  */
+   RECIP_LOW_PRECISION	= (RECIP_ALL & ~(RECIP_DF_RSQRT | RECIP_V2DF_RSQRT))
+ };
+ 
+ /* -mrecip options.  */
+ static struct
+ {
+   const char *string;		/* option name */
+   unsigned int mask;		/* mask bits to set */
+ } recip_options[] = {
+   { "all",	 RECIP_ALL },
+   { "none",	 RECIP_NONE },
+   { "div",	 (RECIP_SF_DIV | RECIP_DF_DIV | RECIP_V4SF_DIV
+ 		  | RECIP_V2DF_DIV) },
+   { "divf",	 (RECIP_SF_DIV | RECIP_V4SF_DIV) },
+   { "divd",	 (RECIP_DF_DIV | RECIP_V2DF_DIV) },
+   { "rsqrt",	 (RECIP_SF_RSQRT | RECIP_DF_RSQRT | RECIP_V4SF_RSQRT
+ 		  | RECIP_V2DF_RSQRT) },
+   { "rsqrtf",	 (RECIP_SF_RSQRT | RECIP_V4SF_RSQRT) },
+   { "rsqrtd",	 (RECIP_DF_RSQRT | RECIP_V2DF_RSQRT) },
+ };
+ 
+ /* On PowerPC, we have a limited number of target clones that we care about
+    which means we can use an array to hold the options, rather than having more
+    elaborate data structures to identify each possible variation.  Order the
+    clones from the default to the highest ISA.  */
+ enum {
+   CLONE_DEFAULT		= 0,		/* default clone.  */
+   CLONE_ISA_2_05,			/* ISA 2.05 (power6).  */
+   CLONE_ISA_2_06,			/* ISA 2.06 (power7).  */
+   CLONE_ISA_2_07,			/* ISA 2.07 (power8).  */
+   CLONE_ISA_3_00,			/* ISA 3.0 (power9).  */
+   CLONE_ISA_3_1,			/* ISA 3.1 (power10).  */
+   CLONE_MAX
+ };
+ 
+ /* Map compiler ISA bits into HWCAP names.  */
+ struct clone_map {
+   HOST_WIDE_INT isa_mask;	/* rs6000_isa mask */
+   const char *name;		/* name to use in __builtin_cpu_supports.  */
+ };
+ 
+ static const struct clone_map rs6000_clone_map[CLONE_MAX] = {
+   { 0,				"" },		/* Default options.  */
+   { OPTION_MASK_CMPB,		"arch_2_05" },	/* ISA 2.05 (power6).  */
+   { OPTION_MASK_POPCNTD,	"arch_2_06" },	/* ISA 2.06 (power7).  */
+   { OPTION_MASK_P8_VECTOR,	"arch_2_07" },	/* ISA 2.07 (power8).  */
+   { OPTION_MASK_P9_VECTOR,	"arch_3_00" },	/* ISA 3.0 (power9).  */
+   { OPTION_MASK_POWER10,	"arch_3_1" },	/* ISA 3.1 (power10).  */
+ };
+ 
+ 
+ /* Newer LIBCs explicitly export this symbol to declare that they provide
+    the AT_PLATFORM and AT_HWCAP/AT_HWCAP2 values in the TCB.  We emit a
+    reference to this symbol whenever we expand a CPU builtin, so that
+    we never link against an old LIBC.  */
+ const char *tcb_verification_symbol = "__parse_hwcap_and_convert_at_platform";
+ 
+ /* True if we have expanded a CPU builtin.  */
+ bool cpu_builtin_p = false;
+ 
+ /* Pointer to function (in rs6000-c.cc) that can define or undefine target
+    macros that have changed.  Languages that don't support the preprocessor
+    don't link in rs6000-c.cc, so we can't call it directly.  */
+ void (*rs6000_target_modify_macros_ptr) (bool, HOST_WIDE_INT, HOST_WIDE_INT);
+ 
+ /* Simplfy register classes into simpler classifications.  We assume
+    GPR_REG_TYPE - FPR_REG_TYPE are ordered so that we can use a simple range
+    check for standard register classes (gpr/floating/altivec/vsx) and
+    floating/vector classes (float/altivec/vsx).  */
+ 
+ enum rs6000_reg_type {
+   NO_REG_TYPE,
+   PSEUDO_REG_TYPE,
+   GPR_REG_TYPE,
+   VSX_REG_TYPE,
+   ALTIVEC_REG_TYPE,
+   FPR_REG_TYPE,
+   SPR_REG_TYPE,
+   CR_REG_TYPE
+ };
+ 
+ /* Map register class to register type.  */
+ static enum rs6000_reg_type reg_class_to_reg_type[N_REG_CLASSES];
+ 
+ /* First/last register type for the 'normal' register types (i.e. general
+    purpose, floating point, altivec, and VSX registers).  */
+ #define IS_STD_REG_TYPE(RTYPE) IN_RANGE(RTYPE, GPR_REG_TYPE, FPR_REG_TYPE)
+ 
+ #define IS_FP_VECT_REG_TYPE(RTYPE) IN_RANGE(RTYPE, VSX_REG_TYPE, FPR_REG_TYPE)
+ 
+ 
+ /* Register classes we care about in secondary reload or go if legitimate
+    address.  We only need to worry about GPR, FPR, and Altivec registers here,
+    along an ANY field that is the OR of the 3 register classes.  */
+ 
+ enum rs6000_reload_reg_type {
+   RELOAD_REG_GPR,			/* General purpose registers.  */
+   RELOAD_REG_FPR,			/* Traditional floating point regs.  */
+   RELOAD_REG_VMX,			/* Altivec (VMX) registers.  */
+   RELOAD_REG_ANY,			/* OR of GPR, FPR, Altivec masks.  */
+   N_RELOAD_REG
+ };
+ 
+ /* For setting up register classes, loop through the 3 register classes mapping
+    into real registers, and skip the ANY class, which is just an OR of the
+    bits.  */
+ #define FIRST_RELOAD_REG_CLASS	RELOAD_REG_GPR
+ #define LAST_RELOAD_REG_CLASS	RELOAD_REG_VMX
+ 
+ /* Map reload register type to a register in the register class.  */
+ struct reload_reg_map_type {
+   const char *name;			/* Register class name.  */
+   int reg;				/* Register in the register class.  */
+ };
+ 
+ static const struct reload_reg_map_type reload_reg_map[N_RELOAD_REG] = {
+   { "Gpr",	FIRST_GPR_REGNO },	/* RELOAD_REG_GPR.  */
+   { "Fpr",	FIRST_FPR_REGNO },	/* RELOAD_REG_FPR.  */
+   { "VMX",	FIRST_ALTIVEC_REGNO },	/* RELOAD_REG_VMX.  */
+   { "Any",	-1 },			/* RELOAD_REG_ANY.  */
+ };
+ 
+ /* Mask bits for each register class, indexed per mode.  Historically the
+    compiler has been more restrictive which types can do PRE_MODIFY instead of
+    PRE_INC and PRE_DEC, so keep track of sepaate bits for these two.  */
+ typedef unsigned char addr_mask_type;
+ 
+ #define RELOAD_REG_VALID	0x01	/* Mode valid in register..  */
+ #define RELOAD_REG_MULTIPLE	0x02	/* Mode takes multiple registers.  */
+ #define RELOAD_REG_INDEXED	0x04	/* Reg+reg addressing.  */
+ #define RELOAD_REG_OFFSET	0x08	/* Reg+offset addressing. */
+ #define RELOAD_REG_PRE_INCDEC	0x10	/* PRE_INC/PRE_DEC valid.  */
+ #define RELOAD_REG_PRE_MODIFY	0x20	/* PRE_MODIFY valid.  */
+ #define RELOAD_REG_AND_M16	0x40	/* AND -16 addressing.  */
+ #define RELOAD_REG_QUAD_OFFSET	0x80	/* quad offset is limited.  */
+ 
+ /* Register type masks based on the type, of valid addressing modes.  */
+ struct rs6000_reg_addr {
+   enum insn_code reload_load;		/* INSN to reload for loading. */
+   enum insn_code reload_store;		/* INSN to reload for storing.  */
+   enum insn_code reload_fpr_gpr;	/* INSN to move from FPR to GPR.  */
+   enum insn_code reload_gpr_vsx;	/* INSN to move from GPR to VSX.  */
+   enum insn_code reload_vsx_gpr;	/* INSN to move from VSX to GPR.  */
+   addr_mask_type addr_mask[(int)N_RELOAD_REG]; /* Valid address masks.  */
+   bool scalar_in_vmx_p;			/* Scalar value can go in VMX.  */
+ };
+ 
+ static struct rs6000_reg_addr reg_addr[NUM_MACHINE_MODES];
+ 
+ /* Helper function to say whether a mode supports PRE_INC or PRE_DEC.  */
+ static inline bool
+ mode_supports_pre_incdec_p (machine_mode mode)
+ {
+   return ((reg_addr[mode].addr_mask[RELOAD_REG_ANY] & RELOAD_REG_PRE_INCDEC)
+ 	  != 0);
+ }
+ 
+ /* Helper function to say whether a mode supports PRE_MODIFY.  */
+ static inline bool
+ mode_supports_pre_modify_p (machine_mode mode)
+ {
+   return ((reg_addr[mode].addr_mask[RELOAD_REG_ANY] & RELOAD_REG_PRE_MODIFY)
+ 	  != 0);
+ }
+ 
+ /* Return true if we have D-form addressing in altivec registers.  */
+ static inline bool
+ mode_supports_vmx_dform (machine_mode mode)
+ {
+   return ((reg_addr[mode].addr_mask[RELOAD_REG_VMX] & RELOAD_REG_OFFSET) != 0);
+ }
+ 
+ /* Return true if we have D-form addressing in VSX registers.  This addressing
+    is more limited than normal d-form addressing in that the offset must be
+    aligned on a 16-byte boundary.  */
+ static inline bool
+ mode_supports_dq_form (machine_mode mode)
+ {
+   return ((reg_addr[mode].addr_mask[RELOAD_REG_ANY] & RELOAD_REG_QUAD_OFFSET)
+ 	  != 0);
+ }
+ 
+ /* Given that there exists at least one variable that is set (produced)
+    by OUT_INSN and read (consumed) by IN_INSN, return true iff
+    IN_INSN represents one or more memory store operations and none of
+    the variables set by OUT_INSN is used by IN_INSN as the address of a
+    store operation.  If either IN_INSN or OUT_INSN does not represent
+    a "single" RTL SET expression (as loosely defined by the
+    implementation of the single_set function) or a PARALLEL with only
+    SETs, CLOBBERs, and USEs inside, this function returns false.
+ 
+    This rs6000-specific version of store_data_bypass_p checks for
+    certain conditions that result in assertion failures (and internal
+    compiler errors) in the generic store_data_bypass_p function and
+    returns false rather than calling store_data_bypass_p if one of the
+    problematic conditions is detected.  */
+ 
+ int
+ rs6000_store_data_bypass_p (rtx_insn *out_insn, rtx_insn *in_insn)
+ {
+   rtx out_set, in_set;
+   rtx out_pat, in_pat;
+   rtx out_exp, in_exp;
+   int i, j;
+ 
+   in_set = single_set (in_insn);
+   if (in_set)
+     {
+       if (MEM_P (SET_DEST (in_set)))
+ 	{
+ 	  out_set = single_set (out_insn);
+ 	  if (!out_set)
+ 	    {
+ 	      out_pat = PATTERN (out_insn);
+ 	      if (GET_CODE (out_pat) == PARALLEL)
+ 		{
+ 		  for (i = 0; i < XVECLEN (out_pat, 0); i++)
+ 		    {
+ 		      out_exp = XVECEXP (out_pat, 0, i);
+ 		      if ((GET_CODE (out_exp) == CLOBBER)
+ 			  || (GET_CODE (out_exp) == USE))
+ 			continue;
+ 		      else if (GET_CODE (out_exp) != SET)
+ 			return false;
+ 		    }
+ 		}
+ 	    }
+ 	}
+     }
+   else
+     {
+       in_pat = PATTERN (in_insn);
+       if (GET_CODE (in_pat) != PARALLEL)
+ 	return false;
+ 
+       for (i = 0; i < XVECLEN (in_pat, 0); i++)
+ 	{
+ 	  in_exp = XVECEXP (in_pat, 0, i);
+ 	  if ((GET_CODE (in_exp) == CLOBBER) || (GET_CODE (in_exp) == USE))
+ 	    continue;
+ 	  else if (GET_CODE (in_exp) != SET)
+ 	    return false;
+ 
+ 	  if (MEM_P (SET_DEST (in_exp)))
+ 	    {
+ 	      out_set = single_set (out_insn);
+ 	      if (!out_set)
+ 		{
+ 		  out_pat = PATTERN (out_insn);
+ 		  if (GET_CODE (out_pat) != PARALLEL)
+ 		    return false;
+ 		  for (j = 0; j < XVECLEN (out_pat, 0); j++)
+ 		    {
+ 		      out_exp = XVECEXP (out_pat, 0, j);
+ 		      if ((GET_CODE (out_exp) == CLOBBER)
+ 			  || (GET_CODE (out_exp) == USE))
+ 			continue;
+ 		      else if (GET_CODE (out_exp) != SET)
+ 			return false;
+ 		    }
+ 		}
+ 	    }
+ 	}
+     }
+   return store_data_bypass_p (out_insn, in_insn);
+ }
+ 
+ \f
+ /* Processor costs (relative to an add) */
+ 
+ const struct processor_costs *rs6000_cost;
+ 
+ /* Instruction size costs on 32bit processors.  */
+ static const
+ struct processor_costs size32_cost = {
+   COSTS_N_INSNS (1),    /* mulsi */
+   COSTS_N_INSNS (1),    /* mulsi_const */
+   COSTS_N_INSNS (1),    /* mulsi_const9 */
+   COSTS_N_INSNS (1),    /* muldi */
+   COSTS_N_INSNS (1),    /* divsi */
+   COSTS_N_INSNS (1),    /* divdi */
+   COSTS_N_INSNS (1),    /* fp */
+   COSTS_N_INSNS (1),    /* dmul */
+   COSTS_N_INSNS (1),    /* sdiv */
+   COSTS_N_INSNS (1),    /* ddiv */
+   32,			/* cache line size */
+   0,			/* l1 cache */
+   0,			/* l2 cache */
+   0,			/* streams */
+   0,			/* SF->DF convert */
+ };
+ 
+ /* Instruction size costs on 64bit processors.  */
+ static const
+ struct processor_costs size64_cost = {
+   COSTS_N_INSNS (1),    /* mulsi */
+   COSTS_N_INSNS (1),    /* mulsi_const */
+   COSTS_N_INSNS (1),    /* mulsi_const9 */
+   COSTS_N_INSNS (1),    /* muldi */
+   COSTS_N_INSNS (1),    /* divsi */
+   COSTS_N_INSNS (1),    /* divdi */
+   COSTS_N_INSNS (1),    /* fp */
+   COSTS_N_INSNS (1),    /* dmul */
+   COSTS_N_INSNS (1),    /* sdiv */
+   COSTS_N_INSNS (1),    /* ddiv */
+   128,			/* cache line size */
+   0,			/* l1 cache */
+   0,			/* l2 cache */
+   0,			/* streams */
+   0,			/* SF->DF convert */
+ };
+ 
+ /* Instruction costs on RS64A processors.  */
+ static const
+ struct processor_costs rs64a_cost = {
+   COSTS_N_INSNS (20),   /* mulsi */
+   COSTS_N_INSNS (12),   /* mulsi_const */
+   COSTS_N_INSNS (8),    /* mulsi_const9 */
+   COSTS_N_INSNS (34),   /* muldi */
+   COSTS_N_INSNS (65),   /* divsi */
+   COSTS_N_INSNS (67),   /* divdi */
+   COSTS_N_INSNS (4),    /* fp */
+   COSTS_N_INSNS (4),    /* dmul */
+   COSTS_N_INSNS (31),   /* sdiv */
+   COSTS_N_INSNS (31),   /* ddiv */
+   128,			/* cache line size */
+   128,			/* l1 cache */
+   2048,			/* l2 cache */
+   1,			/* streams */
+   0,			/* SF->DF convert */
+ };
+ 
+ /* Instruction costs on MPCCORE processors.  */
+ static const
+ struct processor_costs mpccore_cost = {
+   COSTS_N_INSNS (2),    /* mulsi */
+   COSTS_N_INSNS (2),    /* mulsi_const */
+   COSTS_N_INSNS (2),    /* mulsi_const9 */
+   COSTS_N_INSNS (2),    /* muldi */
+   COSTS_N_INSNS (6),    /* divsi */
+   COSTS_N_INSNS (6),    /* divdi */
+   COSTS_N_INSNS (4),    /* fp */
+   COSTS_N_INSNS (5),    /* dmul */
+   COSTS_N_INSNS (10),   /* sdiv */
+   COSTS_N_INSNS (17),   /* ddiv */
+   32,			/* cache line size */
+   4,			/* l1 cache */
+   16,			/* l2 cache */
+   1,			/* streams */
+   0,			/* SF->DF convert */
+ };
+ 
+ /* Instruction costs on PPC403 processors.  */
+ static const
+ struct processor_costs ppc403_cost = {
+   COSTS_N_INSNS (4),    /* mulsi */
+   COSTS_N_INSNS (4),    /* mulsi_const */
+   COSTS_N_INSNS (4),    /* mulsi_const9 */
+   COSTS_N_INSNS (4),    /* muldi */
+   COSTS_N_INSNS (33),   /* divsi */
+   COSTS_N_INSNS (33),   /* divdi */
+   COSTS_N_INSNS (11),   /* fp */
+   COSTS_N_INSNS (11),   /* dmul */
+   COSTS_N_INSNS (11),   /* sdiv */
+   COSTS_N_INSNS (11),   /* ddiv */
+   32,			/* cache line size */
+   4,			/* l1 cache */
+   16,			/* l2 cache */
+   1,			/* streams */
+   0,			/* SF->DF convert */
+ };
+ 
+ /* Instruction costs on PPC405 processors.  */
+ static const
+ struct processor_costs ppc405_cost = {
+   COSTS_N_INSNS (5),    /* mulsi */
+   COSTS_N_INSNS (4),    /* mulsi_const */
+   COSTS_N_INSNS (3),    /* mulsi_const9 */
+   COSTS_N_INSNS (5),    /* muldi */
+   COSTS_N_INSNS (35),   /* divsi */
+   COSTS_N_INSNS (35),   /* divdi */
+   COSTS_N_INSNS (11),   /* fp */
+   COSTS_N_INSNS (11),   /* dmul */
+   COSTS_N_INSNS (11),   /* sdiv */
+   COSTS_N_INSNS (11),   /* ddiv */
+   32,			/* cache line size */
+   16,			/* l1 cache */
+   128,			/* l2 cache */
+   1,			/* streams */
+   0,			/* SF->DF convert */
+ };
+ 
+ /* Instruction costs on PPC440 processors.  */
+ static const
+ struct processor_costs ppc440_cost = {
+   COSTS_N_INSNS (3),    /* mulsi */
+   COSTS_N_INSNS (2),    /* mulsi_const */
+   COSTS_N_INSNS (2),    /* mulsi_const9 */
+   COSTS_N_INSNS (3),    /* muldi */
+   COSTS_N_INSNS (34),   /* divsi */
+   COSTS_N_INSNS (34),   /* divdi */
+   COSTS_N_INSNS (5),    /* fp */
+   COSTS_N_INSNS (5),    /* dmul */
+   COSTS_N_INSNS (19),   /* sdiv */
+   COSTS_N_INSNS (33),   /* ddiv */
+   32,			/* cache line size */
+   32,			/* l1 cache */
+   256,			/* l2 cache */
+   1,			/* streams */
+   0,			/* SF->DF convert */
+ };
+ 
+ /* Instruction costs on PPC476 processors.  */
+ static const
+ struct processor_costs ppc476_cost = {
+   COSTS_N_INSNS (4),    /* mulsi */
+   COSTS_N_INSNS (4),    /* mulsi_const */
+   COSTS_N_INSNS (4),    /* mulsi_const9 */
+   COSTS_N_INSNS (4),    /* muldi */
+   COSTS_N_INSNS (11),   /* divsi */
+   COSTS_N_INSNS (11),   /* divdi */
+   COSTS_N_INSNS (6),    /* fp */
+   COSTS_N_INSNS (6),    /* dmul */
+   COSTS_N_INSNS (19),   /* sdiv */
+   COSTS_N_INSNS (33),   /* ddiv */
+   32,			/* l1 cache line size */
+   32,			/* l1 cache */
+   512,			/* l2 cache */
+   1,			/* streams */
+   0,			/* SF->DF convert */
+ };
+ 
+ /* Instruction costs on PPC601 processors.  */
+ static const
+ struct processor_costs ppc601_cost = {
+   COSTS_N_INSNS (5),    /* mulsi */
+   COSTS_N_INSNS (5),    /* mulsi_const */
+   COSTS_N_INSNS (5),    /* mulsi_const9 */
+   COSTS_N_INSNS (5),    /* muldi */
+   COSTS_N_INSNS (36),   /* divsi */
+   COSTS_N_INSNS (36),   /* divdi */
+   COSTS_N_INSNS (4),    /* fp */
+   COSTS_N_INSNS (5),    /* dmul */
+   COSTS_N_INSNS (17),   /* sdiv */
+   COSTS_N_INSNS (31),   /* ddiv */
+   32,			/* cache line size */
+   32,			/* l1 cache */
+   256,			/* l2 cache */
+   1,			/* streams */
+   0,			/* SF->DF convert */
+ };
+ 
+ /* Instruction costs on PPC603 processors.  */
+ static const
+ struct processor_costs ppc603_cost = {
+   COSTS_N_INSNS (5),    /* mulsi */
+   COSTS_N_INSNS (3),    /* mulsi_const */
+   COSTS_N_INSNS (2),    /* mulsi_const9 */
+   COSTS_N_INSNS (5),    /* muldi */
+   COSTS_N_INSNS (37),   /* divsi */
+   COSTS_N_INSNS (37),   /* divdi */
+   COSTS_N_INSNS (3),    /* fp */
+   COSTS_N_INSNS (4),    /* dmul */
+   COSTS_N_INSNS (18),   /* sdiv */
+   COSTS_N_INSNS (33),   /* ddiv */
+   32,			/* cache line size */
+   8,			/* l1 cache */
+   64,			/* l2 cache */
+   1,			/* streams */
+   0,			/* SF->DF convert */
+ };
+ 
+ /* Instruction costs on PPC604 processors.  */
+ static const
+ struct processor_costs ppc604_cost = {
+   COSTS_N_INSNS (4),    /* mulsi */
+   COSTS_N_INSNS (4),    /* mulsi_const */
+   COSTS_N_INSNS (4),    /* mulsi_const9 */
+   COSTS_N_INSNS (4),    /* muldi */
+   COSTS_N_INSNS (20),   /* divsi */
+   COSTS_N_INSNS (20),   /* divdi */
+   COSTS_N_INSNS (3),    /* fp */
+   COSTS_N_INSNS (3),    /* dmul */
+   COSTS_N_INSNS (18),   /* sdiv */
+   COSTS_N_INSNS (32),   /* ddiv */
+   32,			/* cache line size */
+   16,			/* l1 cache */
+   512,			/* l2 cache */
+   1,			/* streams */
+   0,			/* SF->DF convert */
+ };
+ 
+ /* Instruction costs on PPC604e processors.  */
+ static const
+ struct processor_costs ppc604e_cost = {
+   COSTS_N_INSNS (2),    /* mulsi */
+   COSTS_N_INSNS (2),    /* mulsi_const */
+   COSTS_N_INSNS (2),    /* mulsi_const9 */
+   COSTS_N_INSNS (2),    /* muldi */
+   COSTS_N_INSNS (20),   /* divsi */
+   COSTS_N_INSNS (20),   /* divdi */
+   COSTS_N_INSNS (3),    /* fp */
+   COSTS_N_INSNS (3),    /* dmul */
+   COSTS_N_INSNS (18),   /* sdiv */
+   COSTS_N_INSNS (32),   /* ddiv */
+   32,			/* cache line size */
+   32,			/* l1 cache */
+   1024,			/* l2 cache */
+   1,			/* streams */
+   0,			/* SF->DF convert */
+ };
+ 
+ /* Instruction costs on PPC620 processors.  */
+ static const
+ struct processor_costs ppc620_cost = {
+   COSTS_N_INSNS (5),    /* mulsi */
+   COSTS_N_INSNS (4),    /* mulsi_const */
+   COSTS_N_INSNS (3),    /* mulsi_const9 */
+   COSTS_N_INSNS (7),    /* muldi */
+   COSTS_N_INSNS (21),   /* divsi */
+   COSTS_N_INSNS (37),   /* divdi */
+   COSTS_N_INSNS (3),    /* fp */
+   COSTS_N_INSNS (3),    /* dmul */
+   COSTS_N_INSNS (18),   /* sdiv */
+   COSTS_N_INSNS (32),   /* ddiv */
+   128,			/* cache line size */
+   32,			/* l1 cache */
+   1024,			/* l2 cache */
+   1,			/* streams */
+   0,			/* SF->DF convert */
+ };
+ 
+ /* Instruction costs on PPC630 processors.  */
+ static const
+ struct processor_costs ppc630_cost = {
+   COSTS_N_INSNS (5),    /* mulsi */
+   COSTS_N_INSNS (4),    /* mulsi_const */
+   COSTS_N_INSNS (3),    /* mulsi_const9 */
+   COSTS_N_INSNS (7),    /* muldi */
+   COSTS_N_INSNS (21),   /* divsi */
+   COSTS_N_INSNS (37),   /* divdi */
+   COSTS_N_INSNS (3),    /* fp */
+   COSTS_N_INSNS (3),    /* dmul */
+   COSTS_N_INSNS (17),   /* sdiv */
+   COSTS_N_INSNS (21),   /* ddiv */
+   128,			/* cache line size */
+   64,			/* l1 cache */
+   1024,			/* l2 cache */
+   1,			/* streams */
+   0,			/* SF->DF convert */
+ };
+ 
+ /* Instruction costs on Cell processor.  */
+ /* COSTS_N_INSNS (1) ~ one add.  */
+ static const
+ struct processor_costs ppccell_cost = {
+   COSTS_N_INSNS (9/2)+2,    /* mulsi */
+   COSTS_N_INSNS (6/2),    /* mulsi_const */
+   COSTS_N_INSNS (6/2),    /* mulsi_const9 */
+   COSTS_N_INSNS (15/2)+2,   /* muldi */
+   COSTS_N_INSNS (38/2),   /* divsi */
+   COSTS_N_INSNS (70/2),   /* divdi */
+   COSTS_N_INSNS (10/2),   /* fp */
+   COSTS_N_INSNS (10/2),   /* dmul */
+   COSTS_N_INSNS (74/2),   /* sdiv */
+   COSTS_N_INSNS (74/2),   /* ddiv */
+   128,			/* cache line size */
+   32,			/* l1 cache */
+   512,			/* l2 cache */
+   6,			/* streams */
+   0,			/* SF->DF convert */
+ };
+ 
+ /* Instruction costs on PPC750 and PPC7400 processors.  */
+ static const
+ struct processor_costs ppc750_cost = {
+   COSTS_N_INSNS (5),    /* mulsi */
+   COSTS_N_INSNS (3),    /* mulsi_const */
+   COSTS_N_INSNS (2),    /* mulsi_const9 */
+   COSTS_N_INSNS (5),    /* muldi */
+   COSTS_N_INSNS (17),   /* divsi */
+   COSTS_N_INSNS (17),   /* divdi */
+   COSTS_N_INSNS (3),    /* fp */
+   COSTS_N_INSNS (3),    /* dmul */
+   COSTS_N_INSNS (17),   /* sdiv */
+   COSTS_N_INSNS (31),   /* ddiv */
+   32,			/* cache line size */
+   32,			/* l1 cache */
+   512,			/* l2 cache */
+   1,			/* streams */
+   0,			/* SF->DF convert */
+ };
+ 
+ /* Instruction costs on PPC7450 processors.  */
+ static const
+ struct processor_costs ppc7450_cost = {
+   COSTS_N_INSNS (4),    /* mulsi */
+   COSTS_N_INSNS (3),    /* mulsi_const */
+   COSTS_N_INSNS (3),    /* mulsi_const9 */
+   COSTS_N_INSNS (4),    /* muldi */
+   COSTS_N_INSNS (23),   /* divsi */
+   COSTS_N_INSNS (23),   /* divdi */
+   COSTS_N_INSNS (5),    /* fp */
+   COSTS_N_INSNS (5),    /* dmul */
+   COSTS_N_INSNS (21),   /* sdiv */
+   COSTS_N_INSNS (35),   /* ddiv */
+   32,			/* cache line size */
+   32,			/* l1 cache */
+   1024,			/* l2 cache */
+   1,			/* streams */
+   0,			/* SF->DF convert */
+ };
+ 
+ /* Instruction costs on PPC8540 processors.  */
+ static const
+ struct processor_costs ppc8540_cost = {
+   COSTS_N_INSNS (4),    /* mulsi */
+   COSTS_N_INSNS (4),    /* mulsi_const */
+   COSTS_N_INSNS (4),    /* mulsi_const9 */
+   COSTS_N_INSNS (4),    /* muldi */
+   COSTS_N_INSNS (19),   /* divsi */
+   COSTS_N_INSNS (19),   /* divdi */
+   COSTS_N_INSNS (4),    /* fp */
+   COSTS_N_INSNS (4),    /* dmul */
+   COSTS_N_INSNS (29),   /* sdiv */
+   COSTS_N_INSNS (29),   /* ddiv */
+   32,			/* cache line size */
+   32,			/* l1 cache */
+   256,			/* l2 cache */
+   1,			/* prefetch streams /*/
+   0,			/* SF->DF convert */
+ };
+ 
+ /* Instruction costs on E300C2 and E300C3 cores.  */
+ static const
+ struct processor_costs ppce300c2c3_cost = {
+   COSTS_N_INSNS (4),    /* mulsi */
+   COSTS_N_INSNS (4),    /* mulsi_const */
+   COSTS_N_INSNS (4),    /* mulsi_const9 */
+   COSTS_N_INSNS (4),    /* muldi */
+   COSTS_N_INSNS (19),   /* divsi */
+   COSTS_N_INSNS (19),   /* divdi */
+   COSTS_N_INSNS (3),    /* fp */
+   COSTS_N_INSNS (4),    /* dmul */
+   COSTS_N_INSNS (18),   /* sdiv */
+   COSTS_N_INSNS (33),   /* ddiv */
+   32,
+   16,			/* l1 cache */
+   16,			/* l2 cache */
+   1,			/* prefetch streams /*/
+   0,			/* SF->DF convert */
+ };
+ 
+ /* Instruction costs on PPCE500MC processors.  */
+ static const
+ struct processor_costs ppce500mc_cost = {
+   COSTS_N_INSNS (4),    /* mulsi */
+   COSTS_N_INSNS (4),    /* mulsi_const */
+   COSTS_N_INSNS (4),    /* mulsi_const9 */
+   COSTS_N_INSNS (4),    /* muldi */
+   COSTS_N_INSNS (14),   /* divsi */
+   COSTS_N_INSNS (14),   /* divdi */
+   COSTS_N_INSNS (8),    /* fp */
+   COSTS_N_INSNS (10),   /* dmul */
+   COSTS_N_INSNS (36),   /* sdiv */
+   COSTS_N_INSNS (66),   /* ddiv */
+   64,			/* cache line size */
+   32,			/* l1 cache */
+   128,			/* l2 cache */
+   1,			/* prefetch streams /*/
+   0,			/* SF->DF convert */
+ };
+ 
+ /* Instruction costs on PPCE500MC64 processors.  */
+ static const
+ struct processor_costs ppce500mc64_cost = {
+   COSTS_N_INSNS (4),    /* mulsi */
+   COSTS_N_INSNS (4),    /* mulsi_const */
+   COSTS_N_INSNS (4),    /* mulsi_const9 */
+   COSTS_N_INSNS (4),    /* muldi */
+   COSTS_N_INSNS (14),   /* divsi */
+   COSTS_N_INSNS (14),   /* divdi */
+   COSTS_N_INSNS (4),    /* fp */
+   COSTS_N_INSNS (10),   /* dmul */
+   COSTS_N_INSNS (36),   /* sdiv */
+   COSTS_N_INSNS (66),   /* ddiv */
+   64,			/* cache line size */
+   32,			/* l1 cache */
+   128,			/* l2 cache */
+   1,			/* prefetch streams /*/
+   0,			/* SF->DF convert */
+ };
+ 
+ /* Instruction costs on PPCE5500 processors.  */
+ static const
+ struct processor_costs ppce5500_cost = {
+   COSTS_N_INSNS (5),    /* mulsi */
+   COSTS_N_INSNS (5),    /* mulsi_const */
+   COSTS_N_INSNS (4),    /* mulsi_const9 */
+   COSTS_N_INSNS (5),    /* muldi */
+   COSTS_N_INSNS (14),   /* divsi */
+   COSTS_N_INSNS (14),   /* divdi */
+   COSTS_N_INSNS (7),    /* fp */
+   COSTS_N_INSNS (10),   /* dmul */
+   COSTS_N_INSNS (36),   /* sdiv */
+   COSTS_N_INSNS (66),   /* ddiv */
+   64,			/* cache line size */
+   32,			/* l1 cache */
+   128,			/* l2 cache */
+   1,			/* prefetch streams /*/
+   0,			/* SF->DF convert */
+ };
+ 
+ /* Instruction costs on PPCE6500 processors.  */
+ static const
+ struct processor_costs ppce6500_cost = {
+   COSTS_N_INSNS (5),    /* mulsi */
+   COSTS_N_INSNS (5),    /* mulsi_const */
+   COSTS_N_INSNS (4),    /* mulsi_const9 */
+   COSTS_N_INSNS (5),    /* muldi */
+   COSTS_N_INSNS (14),   /* divsi */
+   COSTS_N_INSNS (14),   /* divdi */
+   COSTS_N_INSNS (7),    /* fp */
+   COSTS_N_INSNS (10),   /* dmul */
+   COSTS_N_INSNS (36),   /* sdiv */
+   COSTS_N_INSNS (66),   /* ddiv */
+   64,			/* cache line size */
+   32,			/* l1 cache */
+   128,			/* l2 cache */
+   1,			/* prefetch streams /*/
+   0,			/* SF->DF convert */
+ };
+ 
+ /* Instruction costs on AppliedMicro Titan processors.  */
+ static const
+ struct processor_costs titan_cost = {
+   COSTS_N_INSNS (5),    /* mulsi */
+   COSTS_N_INSNS (5),    /* mulsi_const */
+   COSTS_N_INSNS (5),    /* mulsi_const9 */
+   COSTS_N_INSNS (5),    /* muldi */
+   COSTS_N_INSNS (18),   /* divsi */
+   COSTS_N_INSNS (18),   /* divdi */
+   COSTS_N_INSNS (10),   /* fp */
+   COSTS_N_INSNS (10),   /* dmul */
+   COSTS_N_INSNS (46),   /* sdiv */
+   COSTS_N_INSNS (72),   /* ddiv */
+   32,			/* cache line size */
+   32,			/* l1 cache */
+   512,			/* l2 cache */
+   1,			/* prefetch streams /*/
+   0,			/* SF->DF convert */
+ };
+ 
+ /* Instruction costs on POWER4 and POWER5 processors.  */
+ static const
+ struct processor_costs power4_cost = {
+   COSTS_N_INSNS (3),    /* mulsi */
+   COSTS_N_INSNS (2),    /* mulsi_const */
+   COSTS_N_INSNS (2),    /* mulsi_const9 */
+   COSTS_N_INSNS (4),    /* muldi */
+   COSTS_N_INSNS (18),   /* divsi */
+   COSTS_N_INSNS (34),   /* divdi */
+   COSTS_N_INSNS (3),    /* fp */
+   COSTS_N_INSNS (3),    /* dmul */
+   COSTS_N_INSNS (17),   /* sdiv */
+   COSTS_N_INSNS (17),   /* ddiv */
+   128,			/* cache line size */
+   32,			/* l1 cache */
+   1024,			/* l2 cache */
+   8,			/* prefetch streams /*/
+   0,			/* SF->DF convert */
+ };
+ 
+ /* Instruction costs on POWER6 processors.  */
+ static const
+ struct processor_costs power6_cost = {
+   COSTS_N_INSNS (8),    /* mulsi */
+   COSTS_N_INSNS (8),    /* mulsi_const */
+   COSTS_N_INSNS (8),    /* mulsi_const9 */
+   COSTS_N_INSNS (8),    /* muldi */
+   COSTS_N_INSNS (22),   /* divsi */
+   COSTS_N_INSNS (28),   /* divdi */
+   COSTS_N_INSNS (3),    /* fp */
+   COSTS_N_INSNS (3),    /* dmul */
+   COSTS_N_INSNS (13),   /* sdiv */
+   COSTS_N_INSNS (16),   /* ddiv */
+   128,			/* cache line size */
+   64,			/* l1 cache */
+   2048,			/* l2 cache */
+   16,			/* prefetch streams */
+   0,			/* SF->DF convert */
+ };
+ 
+ /* Instruction costs on POWER7 processors.  */
+ static const
+ struct processor_costs power7_cost = {
+   COSTS_N_INSNS (2),	/* mulsi */
+   COSTS_N_INSNS (2),	/* mulsi_const */
+   COSTS_N_INSNS (2),	/* mulsi_const9 */
+   COSTS_N_INSNS (2),	/* muldi */
+   COSTS_N_INSNS (18),	/* divsi */
+   COSTS_N_INSNS (34),	/* divdi */
+   COSTS_N_INSNS (3),	/* fp */
+   COSTS_N_INSNS (3),	/* dmul */
+   COSTS_N_INSNS (13),	/* sdiv */
+   COSTS_N_INSNS (16),	/* ddiv */
+   128,			/* cache line size */
+   32,			/* l1 cache */
+   256,			/* l2 cache */
+   12,			/* prefetch streams */
+   COSTS_N_INSNS (3),	/* SF->DF convert */
+ };
+ 
+ /* Instruction costs on POWER8 processors.  */
+ static const
+ struct processor_costs power8_cost = {
+   COSTS_N_INSNS (3),	/* mulsi */
+   COSTS_N_INSNS (3),	/* mulsi_const */
+   COSTS_N_INSNS (3),	/* mulsi_const9 */
+   COSTS_N_INSNS (3),	/* muldi */
+   COSTS_N_INSNS (19),	/* divsi */
+   COSTS_N_INSNS (35),	/* divdi */
+   COSTS_N_INSNS (3),	/* fp */
+   COSTS_N_INSNS (3),	/* dmul */
+   COSTS_N_INSNS (14),	/* sdiv */
+   COSTS_N_INSNS (17),	/* ddiv */
+   128,			/* cache line size */
+   32,			/* l1 cache */
+   512,			/* l2 cache */
+   12,			/* prefetch streams */
+   COSTS_N_INSNS (3),	/* SF->DF convert */
+ };
+ 
+ /* Instruction costs on POWER9 processors.  */
+ static const
+ struct processor_costs power9_cost = {
+   COSTS_N_INSNS (3),	/* mulsi */
+   COSTS_N_INSNS (3),	/* mulsi_const */
+   COSTS_N_INSNS (3),	/* mulsi_const9 */
+   COSTS_N_INSNS (3),	/* muldi */
+   COSTS_N_INSNS (8),	/* divsi */
+   COSTS_N_INSNS (12),	/* divdi */
+   COSTS_N_INSNS (3),	/* fp */
+   COSTS_N_INSNS (3),	/* dmul */
+   COSTS_N_INSNS (13),	/* sdiv */
+   COSTS_N_INSNS (18),	/* ddiv */
+   128,			/* cache line size */
+   32,			/* l1 cache */
+   512,			/* l2 cache */
+   8,			/* prefetch streams */
+   COSTS_N_INSNS (3),	/* SF->DF convert */
+ };
+ 
+ /* Instruction costs on POWER10 processors.  */
+ static const
+ struct processor_costs power10_cost = {
+   COSTS_N_INSNS (2),	/* mulsi */
+   COSTS_N_INSNS (2),	/* mulsi_const */
+   COSTS_N_INSNS (2),	/* mulsi_const9 */
+   COSTS_N_INSNS (2),	/* muldi */
+   COSTS_N_INSNS (6),	/* divsi */
+   COSTS_N_INSNS (6),	/* divdi */
+   COSTS_N_INSNS (2),	/* fp */
+   COSTS_N_INSNS (2),	/* dmul */
+   COSTS_N_INSNS (11),	/* sdiv */
+   COSTS_N_INSNS (13),	/* ddiv */
+   128,			/* cache line size */
+   32,			/* l1 cache */
+   512,			/* l2 cache */
+   16,			/* prefetch streams */
+   COSTS_N_INSNS (2),	/* SF->DF convert */
+ };
+ 
+ /* Instruction costs on POWER A2 processors.  */
+ static const
+ struct processor_costs ppca2_cost = {
+   COSTS_N_INSNS (16),    /* mulsi */
+   COSTS_N_INSNS (16),    /* mulsi_const */
+   COSTS_N_INSNS (16),    /* mulsi_const9 */
+   COSTS_N_INSNS (16),   /* muldi */
+   COST[...]

[diff truncated at 524288 bytes]


^ permalink raw reply	[flat|nested] only message in thread

only message in thread, other threads:[~2022-01-18 12:42 UTC | newest]

Thread overview: (only message) (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2022-01-18 12:42 [gcc(refs/vendors/redhat/heads/gcc-12-branch)] Merge commit 'r12-6669-g38ec23fafb167ddfe840d7bb22b3e943d8a7d29e' into redhat/gcc-12-branch Jakub Jelinek

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).